<essential_principles>
US Treasury Yield Spread as a leading indicator:
spread_t = short_yield_t - long_yield_t
= US02Y_t - US10Y_t
The higher the spread: the short end is relatively higher (curve more inverted/tighter) The lower the spread(or from negative back to 0, turning positive): the curve "normalizes/steepens"
This spread is considered to lead and reflect:
- Economic cycle expectations (inversion → recession expectations)
- Risk appetite shifts (curve steepening → risk appetite recovery)
Relative strength ratio (Ratio):
ratio_t = risk_asset_t / defensive_asset_t
= QQQ_t / XLV_t
ratio rises: growth stocks (Nasdaq) are relatively stronger ratio falls: defensive stocks (Healthcare) are relatively stronger (XLV outperforms)
The prediction target is the "log relative return over the next H months":
future_rel_return = log(ratio(t+H) / ratio(t))
Positive → Nasdaq outperforms, negative → XLV outperforms
Chart time alignment logic:
- Shift the spread forward by lead_months months
- The goal is to check:Whether spread(t) can explain ratio(t + H)
Engineering implementation:
X = spread(t)
Y = future_rel_return(t, H) = log(ratio(t+H) / ratio(t))
Then perform correlation/regression/cross-correlation scans to find the "best lead period."
Avoid directly using the ratio level for regression(there are trend/non-stationarity issues), use log returns instead.
Three things need to be answered:
-
Does a stable lead relationship really exist?
- Scan multiple leads (6, 12, 18, 24, 30 months)
- See under which lead corr(spread, future_rel_return) is most stable and significant
- Cross-subsample validation (first half vs second half)
-
The forecast direction corresponding to the current scenario
- Recent spread level, rate of change
- Model forecast E[future_rel_return]
- Quantile interval (e.g., 80% confidence interval)
-
Translate the forecast into intuitive language
- Convert future_rel_return back to a percentage:
exp(future_rel_return) - 1 - "Over the next 24 months, XLV versus QQQ win rate X%, median return Y%"
- Convert future_rel_return back to a percentage:
- Frequency choice: weekly frequency reduces noise, 1wk is recommended
- Smoothing window: optional 13-week or 26-week moving average
- Backtest length: at least cover 1-2 full business cycles (e.g., 2007-present)
Yield source: FRED (DGS2, DGS10) Asset price source: Yahoo Finance (QQQ, XLV)
</essential_principles>
- Data integration: obtain yields (FRED) and asset prices (yfinance)
- Spread calculation: calculate spread = short_yield - long_yield
- Relative return calculation: calculate future_rel_return = log(ratio(t+H) / ratio(t))
- Lead relationship validation: scan multiple leads to find the best correlation and stability
- Scenario forecast: produce a future relative return forecast interval based on the current spread
- Output report: validation conclusion, forecast direction, risk warnings
Output: lead relationship validation, current forecast, interval estimates, historical analogies, risk warnings.
<quick_start>
Fastest way: run the default scenario analysis
cd skills/forecast-sector-relative-return-from-yield-spread
pip install pandas numpy yfinance matplotlib statsmodels requests # 首次使用
python scripts/spread_forecaster.py --quick
Full analysis (including lead scan and stability validation)
python scripts/spread_forecaster.py \
--risk-ticker QQQ \
--defensive-ticker XLV \
--lead-months 24 \
--lookback-years 12 \
--output result.json
Generate Bloomberg-style visualization charts
python scripts/plot_bloomberg_style.py --quick --output output/yield_spread_forecast_$(date +%Y-%m-%d).png
Full version charts (custom parameters)
python scripts/plot_bloomberg_style.py \
--lookback-years 18 \
--lead-months 24 \
--risk-ticker QQQ \
--defensive-ticker XLV \
--output output/yield_spread_analysis.png
Output example:
{
"skill": "forecast_sector_relative_return_from_yield_spread",
"signal_name": "US02Y_minus_US10Y_leads_QQQ_over_XLV",
"lead_months": 24,
"current_spread": -0.35,
"model": {
"type": "lagged_regression",
"alpha": 0.02,
"beta": -0.45,
"corr_x_y": -0.32
},
"forecast": {
"future_24m_relative_return_pct": -0.077,
"interval_pct_80": [-0.22, 0.04],
"interpretation": "若此關係維持,未來24個月QQQ相對XLV期望報酬為-7.7%,XLV較可能跑贏。"
}
}
</quick_start>
- Quick analysis - Calculate current forecast using default parameters (QQQ/XLV, 24-month lead)
- Full analysis - Validate lead relationships and scenario forecasts with custom parameters
- Lead scan - Scan multiple lead periods (6-30 months) to find the best correlation
- Visualization charts - Generate aligned charts of spread and relative returns
- Stability validation - Check the consistency of lead relationships across different subsamples
- Methodology learning - Understand the logic and calculation method of lead relationships
Please select or directly provide analysis parameters.
After routing, read the corresponding document and execute.
<directory_structure>
forecast-sector-relative-return-from-yield-spread/
├── SKILL.md # 本文件(路由器)
├── skill.yaml # 前端展示元數據
├── manifest.json # 技能元數據
├── workflows/
│ ├── analyze.md # 完整分析工作流
│ └── data-research.md # 數據源研究與替代方案
├── references/
│ ├── methodology.md # 方法論與計算邏輯
│ ├── input-schema.md # 完整輸入參數定義
│ └── data-sources.md # 數據來源與獲取方式
├── templates/
│ ├── output-json.md # JSON 輸出模板
│ └── output-markdown.md # Markdown 報告模板
├── scripts/
│ ├── spread_forecaster.py # 主計算腳本
│ ├── plot_bloomberg_style.py # Bloomberg 風格視覺化(推薦)
│ └── spread_plotter.py # 基本版圖表腳本(備用)
└── examples/
└── sample-output.json # 範例輸出
</directory_structure>
<reference_index>
Methodology: references/methodology.md
- Definition of lead-lag relationships
- Relative return calculation
- Regression model specification
- Interval estimation method
- Stability validation
Data sources: references/data-sources.md
- Yield proxies (FRED DGS2/DGS10)
- Asset price proxies (QQQ/XLV)
- Data alignment principles
Input parameters: references/input-schema.md
- Full parameter definitions
- Default values and recommended ranges
</reference_index>
<workflows_index>
| Workflow | Purpose | When to use |
|---|---|---|
| analyze.md | Full scenario analysis | Need custom parameters to validate lead relationships and forecasts |
| data-research.md | Data source research | Learn how to obtain or substitute yield/asset data |
| </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 |
|---|---|---|
| spread_forecaster.py | --quick |
Quick analysis QQQ/XLV, 24m lead |
| spread_forecaster.py | --lead-months 12 --lookback-years 15 |
Custom lead period and backtest length |
| spread_forecaster.py | --lead-scan --scan-range 6,12,18,24,30,36 |
Lead period scan |
| plot_bloomberg_style.py | --quick --output output/chart.png |
Bloomberg-style quick charts |
| plot_bloomberg_style.py | --lookback-years 18 --lead-months 24 |
Full version charts (including lead scan + stability) |
| spread_plotter.py | --quick --output-dir output/ |
Basic version charts (backup) |
| </scripts_index> |
<input_schema_summary>
Core parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
| risk_ticker | string | QQQ | Instrument representing growth stocks |
| defensive_ticker | string | XLV | Instrument representing defensive stocks |
| short_tenor | string | 2Y | Short-end yield tenor |
| long_tenor | string | 10Y | Long-end yield tenor |
| lead_months | int | 24 | Lead period (months) |
| lookback_years | int | 12 | Backtest/estimation history in years |
Advanced parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
| freq | string | weekly | Data frequency (daily/weekly/monthly) |
| smoothing_window | int | 13 | Smoothing window (weeks) |
| return_horizon_months | int | 24 | Forecast relative return window |
| model_type | string | lagged_regression | Model type |
| confidence_level | float | 0.80 | Interval estimation confidence level |
See full parameter definitions in references/input-schema.md。
</input_schema_summary>
<output_schema_summary>
{
"skill": "forecast_sector_relative_return_from_yield_spread",
"inputs": {
"risk_ticker": "QQQ",
"defensive_ticker": "XLV",
"lead_months": 24,
"lookback_years": 18
},
"signal_name": "DGS2_minus_DGS10_leads_QQQ_over_XLV",
"current_state": {
"spread": -0.61,
"spread_percentile": 61.1,
"spread_trend": "steepening"
},
"model": {
"type": "lagged_regression",
"coefficients": { "alpha": 0.19, "beta": 0.087 },
"fit_quality": {
"corr_x_y": 0.484,
"r_squared": 0.234,
"notes": "正 beta 意味 spread 越低(曲線正常)→ 未來 QQQ 相對 XLV 越強"
}
},
"forecast": {
"horizon_months": 24,
"future_relative_return_pct": 0.148,
"interval_pct_80": [-0.05, 0.36],
"expected_winner": "QQQ"
},
"diagnostics": {
"lead_scan": {
"best_lead_months": 36,
"correlation_by_lead": {"6": 0.233, "12": 0.360, "18": 0.405, "24": 0.484, "30": 0.502, "36": 0.509}
},
"stability_checks": {
"first_half_corr": -0.087,
"second_half_corr": 0.663,
"consistency": "low"
}
},
"notes": [
"領先關係反映的是『歷史統計規律』,不保證未來成立。",
"子樣本一致性低:前半段(2007-2015)為負相關,後半段(2015-2024)為正相關。",
"這意味著此領先關係可能只是 2015 後 QE 時代的特有現象。",
"建議搭配:景氣指標、估值分位、資金流向做交叉驗證。"
]
}
See full output structure in templates/output-json.md。
Important findings (2026-01-27 validation results):
- Lead relationship exists, but subsample consistency is low(negative correlation in the first half vs positive correlation in the second half)
- The best lead period is 30-36 months (not 24 months), but 24 months also has a correlation of 0.484
- R² = 23.4%, the spread explains only about one quarter of the relative return variation </output_schema_summary>
<success_criteria> Successful execution should produce:
- Current US Treasury yield spread level
- Lead relationship correlation and regression coefficients
- Future relative return forecast (point estimate and interval)
- Lead period scan results (if executed)
- Stability verification (subsample consistency)
- Results output in the specified format (JSON or Markdown)
- Visualization chart output (if needed)
- Risk warnings and suggestions for further research </success_criteria>