前高 story:完整歷史的最近已確認高點
Issue #1746 的前高修正僅影響 technical new_high_breakout 與
volume_breakout_confirmation 的前高分支。52 週新高與通道突破分支保留。
前高採完整可用行情中,日期最近的已確認局部高點。該根 high 必須
嚴格高於兩側各 5 根 K 線,右側確認完成當日
才可使用;同價平台不成立。新高點尚未確認時保留上一個已確認高點。
沒有 60 日或其他到期窗口。突破使用 close > 前高,相等不算突破。
這包含四項明確的語意差異,不只是移除日期窗口:
| 項目 | 原共用前高事件 | 這兩個 story 的前高分支 |
|---|---|---|
| 搜尋範圍 | 20/60 日窗口 | 完整可用行情,無到期限制 |
| 選點 | 窗口內價格最高的局部高點 | 日期最近的已確認局部高點 |
| 確認 | 20 日分支左右各 3 根;60 日分支各 5 根 | 一律左右各 5 根 |
| 同價平台 | high == max(window) 可接受同價 |
必須嚴格高於左右鄰點,同價平台不成立 |
例如較早高點 120、較近且已確認高點 100,收盤 105 時,story 前高分支 以 100 判定突破;不要求超過 120。僅左右各 3 根成立、尚未通過 5 根 確認的短波高點不能取代前高。這些差異都不回寫原共用 20/60 日指標。
Story 以同一組還原價 OHLC 計算前高及比較收盤價。無效、缺少或非正值 的 OHLC 保留為確認缺口;缺少指定交易日或已確認高點時,前高分支不成立。 不以較早交易日的值冒充缺少的指定交易日。
資料只經由 story_price_context 傳入 story 層。它不是共用 event,
不加入 event refs 或偽造事件關聯;可追溯至原本的價格訊號。
Technical latest cache 以專屬規則版本失效舊 story;新版快取命中時直接
使用,不讀取完整行情。快取失效時才載入 story context 並重算,維持
既有衝突處理及顯示筆數限制。Signals/events 與其他領域快取版本不變。
冷查詢與 full view 分批載入行情,每批最多 128 個代碼;處理後釋放
該批歷史,只保留當日 context。單檔/日期優先的歷史重播則在 DB session
內保留已計算序列,避免每日重查:2,613 檔約需 200 MB,應使用短生命週期
的工作 session,完成後關閉;不要用 LRU 逐出造成每日反覆讀取全史。
條件 evidence 明列 basis: adjusted。API 的 story description 從
sesi_names.yaml 讀取,說明還原價前高與 52 週/通道等替代分支;
規則說明不放入 badge 或舊版 action_hints,也不偽造共用事件。
若價格投影所需的 factor lineage
缺少或衝突,API 保持 fail-closed,不使用此分支,並記錄
story_context_unavailable/price_projection_unavailable,附日期及代碼。
此時 latest cache 狀態為 invalid,不能解讀為「已檢查但沒有突破」。
本修正不改資料庫 schema、OHLC、個股指標、原 20/60 日前高、 支撐壓力、停損、共用 signal/event 或籌碼/財務/跨面 story 規則。 前低由 PR #1721 獨立處理。
部署順序(開放流量前必須完成)
- 在維護窗口部署同一版 API 與 scheduler,並重啟
cortex-scheduler。 Scheduler 長期持有已匯入的 daily 模組,僅替換檔案不會更新既有 process; 未重啟會在下次排程以舊規則覆寫快取。 - 使用新版 backend 執行下列 technical cache-only 重建,等待成功完成。
舊
ses-storage-v7technical 快取會全部失效;重建是必要部署步驟, 不能把全市場冷查詢成本留給第一位使用者。
python -m scripts.refresh_latest_ses_snapshot --domain technical --cache-only
- 核對版本分布與重建結果,technical 列應全部使用
ses-storage-v7:previous-wave-high-v1;確認無失敗列,且當日快照有對應 快取,再以 summary API smoke check 確認快取命中後開放流量。
SELECT rule_version, count(*)
FROM taiwan.latest_ses_snapshot
WHERE domain = 'technical'
GROUP BY rule_version;
這一步沿用原 signal/event 規則,只更新 technical compact cache; 歷史 story 修復可在後續批次窗口執行。無需 migration。
歷史修復
下列指令須在部署後、已設定資料庫連線的 backend 環境執行。修復預設
唯讀;--apply 才寫入。它只更新上述兩種 story 的歷史列,不更新
snapshot、event、coverage 或 latest cache,不需要 migration。
python -m scripts.backfill_story_swing_high
python -m scripts.backfill_story_swing_high --apply
可先建立每行一個台股代碼的名單,分批 dry-run,再以相同名單套用。
接受裸碼或 .TW/.TWO,忽略空行及 # 註解、去除重複;空名單或
無效代碼會停止,不會擴大為全市場。--ticker-file 與 --ticker 互斥。
python -m scripts.backfill_story_swing_high --ticker-file batch-01.txt
python -m scripts.backfill_story_swing_high --ticker-file batch-01.txt --apply
--start-date/--end-date 只限制要修復的 story 日期;前高輸入仍讀取
完整歷史。--ticker 2330.TW 可限制單一個股。每檔為一個 transaction,
失敗整檔回滾並回報代碼;同樣參數可重試,相同結果不重寫。
每 10 檔及批次結束記錄進度、成功/失敗數與經過秒數。將最後的失敗
代碼區塊存成 retry.txt,使用相同日期範圍及 --ticker-file retry.txt
重跑;任何檔案失敗時程式以非零狀態結束。
Claude 對優化前版本實測每檔 2,121 日期約 15.4–19.2 秒。依 2,613 檔 估算,每次 dry-run/apply 各約 11.2–13.9 小時;這是容量規劃估算, 不是此次優化後的全市場回填實測。應先跑代表性小批次估時並安排窗口。 原實測每檔約 134–207 個 story key 變動,全市場可能有數十萬筆。 Apply 的實際 story 變更會透過既有 writer 將 Story Strategy 各已追蹤 版本從最早變更日期標記 dirty,需完成後續 Story Strategy 刷新/parity 核對;dry-run 及無變更的冪等重跑不標記 dirty。這不改寫個股或籌碼資料。 本次開發沒有對既有環境執行上述寫入、部署或重啟。
驗證資料
Claude review 後,以相同資料庫的 2026-09-18 全市場冷 summary 查詢進行 唯讀 A/B 實測,2,361 筆完整回應的 SHA-256 相同。原逐檔 loader 為 202.132 秒,優化後 87.926 秒;story context 部分 146.994 → 43.609 秒, OHLC 查詢 2,361 → 19 次。這是單次本機實測,仍須完成部署快取預熱。 另以 2,200 根含缺口行情測量計算本身:15.596 → 5.560 ms,結果逐列相同。
使用 2026-09-18 的 2,362 檔名冊,行情範圍 2018-01-02 至 2026-09-18,共 4,116,042 筆。獨立 rolling-window oracle 對原始價及 還原價逐列確認前高價格與日期一致。還原價中有 18,477 筆突破的前高 已超過 60 個交易日,仍保留有效。
同名冊的實際 technical、chip、financial 快照以修正前後規則比較:
共用 signal/event 與 chip、financial、cross-domain story 完全一致。
new_high_breakout 當日筆數 336 → 322,volume_breakout_confirmation
130 → 127:前者新增 52/移除 66,後者新增 10/移除 13。當日 322 筆
前高突破中,5 筆的已確認高點超過 60 個交易日;因此整體差異不能全部
歸因於撤掉窗口,也包含上述選點、確認根數及同價平台的語意修正。
例如 00953B 使用 83 個交易日前的 2026-05-22 高點 9.4203,當日還原
收盤 9.57;00685L 使用較近的 2026-08-14 高點 12.05,收盤 12.42,
不再被較早的 12.59/13.10 窗內高點擋住。
其他 technical story 的名單與分數一致;3 檔的同組
volume_price_zscore_surge_up_story 僅衝突顯示 metadata 改變。
行情擷取 SHA-256:
fdf4d563d0ea55a2f0524fa91a4703eb2442d66fb5b2b13d04bf77f1e2c07d1d。
這是前高算法全史驗收與當日完整 story 比對,不代表完整交易策略回測。