大盤半年線(MA120)/年線(MA240)乖離率 Integration Guide — Frontend
Backend branch: feat/daily-market-ma120-ma240-bias → cortex/dev
API base: 公開端點(與既有 /api/daily-market/* 同)
生效時間:merge 後 cortex-api 自動 reload 即生效;無 migration、無資料回補(快照表已有全歷史值)
Consumer:cortex-web 大盤儀表板(讀 /latest 的 index.moving_averages 與 /range、/index-range 的 daily[])。
1. 欄位改名對照表(Breaking)
無。純 additive;既有 5/20/60 日欄位的名稱、值、null 規則一律不變。
2. 新增欄位
| 端點 | 位置 | 新欄位 | 型別 |
|---|---|---|---|
GET /api/daily-market/range |
daily[] |
bias_rate_ma120_pct、bias_rate_ma240_pct |
number \| null |
GET /api/daily-market/index-range |
daily[] |
bias_rate_ma120_pct、bias_rate_ma240_pct |
number \| null |
GET /api/daily-market/latest(及 /{trade_date}) |
index.moving_averages |
ma120、ma240、distance_to_ma120_pct、distance_to_ma240_pct、bias_rate_ma120_pct、bias_rate_ma240_pct |
number \| null |
bias_rate_ma{N}_pct 與 distance_to_ma{N}_pct 同值(與既有 5/20/60 一樣,兩個名字並存)。/range 與 /index-range 同一交易日的兩欄逐欄相等。
3. 計算與 null 規則
bias_rate_maN_pct = (收盤 − MAN) ÷ MAN × 100,四位小數。- 收盤與均線都取同一交易日的
^TWII技術快照(daily_technical_snapshot),和 5/20/60 日乖離率出自同一個收盤價。 - 下列情況回
null,不以前一日均線補值:同日快照不存在、該均線仍在暖機期(MA120 需 120 根、MA240 需 240 根 K 棒;目前資料 MA120 自 2018-07-03、MA240 自 2018-12-21 起有值)、MAN = 0。 - 前端不可把
null當 0 顯示。 - 收盤價來源差異:同一列的
market_index_close來自官方大盤日資料,乖離率用的是技術快照收盤。2021 年起兩者逐日相同;2018-07-24~2020-01-14 有 53 天不同(多數為官方資料source_error,market_index_close為null但 5/20/60/120 日乖離率有值,MA240 乖離率在 2018-12-21 前仍因暖機為null;其餘差 0.01–0.04 點)。請直接使用乖離率欄位,不要用market_index_close自行重算。
4. 範例(本 branch 程式碼打 live DB 實測輸出)
GET /api/daily-market/index-range?start_date=2026-11-03&end_date=2026-11-03
{
"market": "taiwan",
"start_date": "2026-11-03",
"end_date": "2026-11-03",
"count": 1,
"daily": [
{
"trade_date": "2026-11-03",
"market_index_close": 43307.54,
"market_trade_value_amount": 1002035660990,
"bias_rate_ma5_pct": -4.5431,
"bias_rate_ma20_pct": -8.4856,
"bias_rate_ma60_pct": -6.9963,
"bias_rate_ma120_pct": -4.5121,
"bias_rate_ma240_pct": 12.0097
}
]
}
GET /api/daily-market/latest → index.moving_averages(2026-11-03)
{
"ma5": 45368.684,
"ma20": 47323.2115,
"ma60": 46565.3745,
"ma120": 45353.972,
"ma240": 38664.0883,
"distance_to_ma5_pct": -4.5431,
"distance_to_ma20_pct": -8.4856,
"distance_to_ma60_pct": -6.9963,
"distance_to_ma120_pct": -4.5121,
"distance_to_ma240_pct": 12.0097,
"bias_rate_ma5_pct": -4.5431,
"bias_rate_ma20_pct": -8.4856,
"bias_rate_ma60_pct": -6.9963,
"bias_rate_ma120_pct": -4.5121,
"bias_rate_ma240_pct": 12.0097,
"benchmark_ticker": "^TWII",
"source": "daily_technical_snapshot",
"date": "2026-11-03",
"status": "available"
}
暖機期範例(index-range,2018-12-20):"bias_rate_ma120_pct": -7.2016, "bias_rate_ma240_pct": null。
與需求範例的差異:需求範例寫 2026-11-03 bias_rate_ma120_pct = -4.5110,以同範例的 ma120 = 45353.972、收盤 43307.54 代公式為 -4.5121;後端以公式值為準(2026-11-03 使用者確認)。前端若有寫死 -4.5110 的測試請改成 -4.5121。
5. 前端改法(cortex-web)
src/types/daily-market.ts:/range與/index-range的daily[]型別加bias_rate_ma120_pct: number | null、bias_rate_ma240_pct: number | null;moving_averages型別加上表六欄(皆number | null)。- 讀取端照既有 5/20/60 的寫法並列 120/240,
null顯示為無資料。
6. 驗證
curl -s "http://localhost:8000/api/daily-market/index-range?start_date=2026-11-03&end_date=2026-11-03" | jq '.daily[0] | {bias_rate_ma120_pct, bias_rate_ma240_pct}'
預期:{"bias_rate_ma120_pct": -4.5121, "bias_rate_ma240_pct": 12.0097}。