<essential_principles>
Divergence event definition:
- Price rises:
price_return >= min_price_return_pct(e.g., +15%) - Inventory declines:
inventory_change <= -min_inventory_drawdown_pct(e.g., -10%) - Occur simultaneously: both are satisfied within the same window period (e.g., 180 days)
When price and inventory move in the same direction (both rise or both fall), it is normal;when inverse(price rises while inventory falls), vigilance is needed.
A decline in inventory cannot be directly interpreted as "physical goods being snapped up"; cross-validation is required:
| Hypothesis | Supporting conditions | Refuting conditions |
|---|---|---|
| Physical tightness | COMEX/LBMA declines, backwardation, lease rates rise, retail premiums expand | Other inventories stable, contango, premiums stable |
| Capital flows/redemptions | ETF outflows but exchange inventories stable, futures structure not tight | Multiple inventories decline simultaneously |
Output two interpretations and let the user judge which one better matches the current data.
This skill prioritizes:
- ETF official website inventory: Selenium simulates human browser behavior for scraping (to avoid API restrictions)
- Yahoo Finance:
yfinancepackage to obtain spot/futures prices - Cross-validation: public data such as COMEX inventories and futures structure
The script is located in the scripts/ directory and follows references/data-sources.md 's anti-detection strategy.
stress_score = 100 × min(1.0,
0.6 × divergence_severity + # 背離嚴重度
0.2 × decade_low_bonus + # 十年低點加成
0.2 × ratio_extreme_bonus # 比值極端加成
)
| Score range | Interpretation |
|---|---|
| 0-30 | Normal, no obvious divergence |
| 30-60 | Mild divergence, worth watching |
| 60-80 | Moderate divergence, further verification recommended |
| 80-100 | Severe divergence, high alert |
</essential_principles>
- Detect divergence: price rises but ETF inventory declines
- Assess severity: calculate divergence degree, ten-year low, extreme ratio
- Cross-validation: use indicators such as COMEX, futures structure, retail premiums
- Generate insights: provide two opposing hypotheses to avoid single-narrative bias
Output: divergence status, pressure score, cross-validation results, recommended next checks.
<quick_start>
Fastest way: check SLV divergence status
cd skills/monitor-etf-holdings-drawdown-risk
pip install pandas numpy yfinance selenium webdriver-manager beautifulsoup4 matplotlib # 首次使用
python scripts/divergence_detector.py --etf SLV --quick
Example output:
{
"asof": "2026-01-20",
"divergence": false,
"price_return_window": 1.92,
"inventory_change_window": 0.15,
"inventory_decade_low": false,
"stress_score_0_100": 20.0,
"interpretations": ["Physical Tightness", "ETF Flow Hypothesis"]
}
Full analysis + visualization report:
# 1. 執行背離偵測
python scripts/divergence_detector.py \
--etf SLV \
--start 2010-01-01 \
--end 2026-01-20 \
--output result.json
# 2. 生成視覺化報告
python scripts/visualize_divergence.py \
--result result.json \
--output ../../../output/
Output:
- JSON analysis results:
result.json - Visualization report:
output/SLV_divergence_report_20260120.png - PDF report:
output/SLV_divergence_report_20260120.pdf
</quick_start>
- Quick check - View the specified ETF's current divergence status and pressure score
- Full analysis - Run a complete historical divergence analysis
- Cross-validation - Use multiple indicators to verify the authenticity of the divergence signal
- Monitoring mode - Set up continuous monitoring and divergence alerts
- Methodology learning - Understand divergence detection and dual-hypothesis logic
Please select or directly provide analysis parameters (such as ETF ticker).
After routing, read the corresponding document and execute.
<directory_structure>
monitor-etf-holdings-drawdown-risk/
├── SKILL.md # 本文件(路由器)
├── skill.yaml # 前端展示元數據
├── manifest.json # 技能元數據
├── workflows/
│ ├── analyze.md # 完整背離分析工作流
│ ├── monitor.md # 持續監控工作流
│ └── cross-validate.md # 交叉驗證工作流
├── references/
│ ├── data-sources.md # ETF 庫存與價格資料來源
│ ├── methodology.md # 背離偵測方法論
│ └── input-schema.md # 完整輸入參數定義
├── templates/
│ ├── output-json.md # JSON 輸出模板
│ └── output-markdown.md # Markdown 報告模板
└── scripts/
├── divergence_detector.py # 主偵測腳本
├── fetch_etf_holdings.py # ETF 庫存抓取(Selenium)
└── fetch_prices.py # 價格數據抓取
</directory_structure>
<reference_index>
Methodology: references/methodology.md
- Divergence detection logic
- Dual Hypothesis Validation Framework
- Pressure Score Calculation
Data Sources: references/data-sources.md
- ETF Official Website Holdings Scraping (Selenium)
- Yahoo Finance Price Data
- Cross-Validation Data Sources (COMEX, LBMA)
Input Parameters: references/input-schema.md
- Complete Parameter Definitions
- Default Values and Recommended Ranges
</reference_index>
<workflows_index>
| Workflow | Purpose | When to Use |
|---|---|---|
| analyze.md | Complete Divergence Analysis | When full historical analysis is needed |
| monitor.md | Continuous Monitoring Status | Daily monitoring or alerts |
| cross-validate.md | Cross-Validate Divergence Signals | When confirming divergence authenticity |
| </workflows_index> |
<templates_index>
| Template | Purpose |
|---|---|
| output-json.md | JSON Output Structure Definition |
| output-markdown.md | Markdown Report Template |
| </templates_index> |
<scripts_index>
| Script | Command | Purpose |
|---|---|---|
| divergence_detector.py | --etf SLV --quick |
Quickly check divergence status |
| divergence_detector.py | --start DATE --end DATE --output FILE |
Complete historical analysis |
| visualize_divergence.py | --result result.json --output DIR |
Generate visualization report |
| fetch_etf_holdings.py | --etf SLV --output holdings.csv |
Scrape ETF holdings |
| fetch_prices.py | --symbol SI=F --output prices.csv |
Scrape commodity prices |
| </scripts_index> |
<input_schema_summary>
Core Parameters
| Parameter | Type | Default Value | Description |
|---|---|---|---|
| etf_ticker | string | (Required) | ETF/Trust ticker (e.g., SLV) |
| commodity_price_symbol | string | (Required) | Commodity price ticker (e.g., XAGUSD) |
| start_date | string | 10Y ago | Analysis start date |
| end_date | string | today | Analysis end date |
Divergence Parameters
| Parameter | Type | Default Value | Description |
|---|---|---|---|
| divergence_window_days | int | 180 | Divergence calculation window (days) |
| decade_low_window_days | int | 3650 | Ten-year low window (days) |
| min_price_return_pct | float | 0.15 | Price increase threshold |
| min_inventory_drawdown_pct | float | 0.10 | Inventory decline threshold |
For complete parameter definitions see references/input-schema.md。
</input_schema_summary>
<output_schema_summary>
{
"skill": "monitor-etf-holdings-drawdown-risk",
"asof": "2026-01-16",
"inputs": {
"etf_ticker": "SLV",
"commodity_price_symbol": "XAGUSD"
},
"result": {
"divergence": true,
"price_return_window": 0.32,
"inventory_change_window": -0.18,
"inventory_decade_low": true,
"inventory_to_price_ratio_z": -2.4,
"stress_score_0_100": 78.5
},
"interpretations": [...],
"next_checks": [...]
}
For complete output structure see templates/output-json.md。
</output_schema_summary>
<success_criteria> Successful execution should produce:
- Divergence status determination (divergence: true/false)
- Price change and inventory change values
- Ten-year low determination
- Inventory/price ratio Z-score
- Pressure score (0-100)
- Two opposing hypothesis explanations
- Next-step validation recommendation list </success_criteria>