iT邦幫忙

2026 iThome 鐵人賽

DAY 28
0

本篇階段:Prj#5 股票分析

使用介面:Claude Code(via VS Code)


前情

五天下來,這套東西每天自己跑。今天回頭看它跑成什麼樣子,順便把幾件一直欠著的事講完:金鑰分級、額度、失敗通知,以及那套加密到底擋得住什麼。

日 K 可以事後回補,FRED 的序列也可以。今天回頭抓 9 月 4 日的收盤,跟 9 月 4 日當天抓,拿到的是同一個數字。所以價格這條線的「五天」,隨時可以補出來。

補不回來的只有兩樣:當天那一版程式算出的評分快照,以及管線自己的執行紀錄。9 月 4 日那天的分數是用當時那一版程式、那一版價格算的;程式改過之後再算一次,會得到不同的數字,而且沒有辦法還原。

所以這篇回顧的主體不是價格,是評分序列跟 run log。


重要說明:本文所有數字與敘述僅為個人技術實作紀錄,不構成投資建議


1. 兩個市場的五天,不是同一組日期

市場 五個交易日
台股 9/4(五)、9/7(一)、9/8(二)、9/9(三)、9/10(四)
美股 9/3(四)、9/4(五)、9/8(二)、9/9(三)、9/10(四)

9 月 7 日是 2026 年九月的第一個星期一,美國勞動節,NYSE 不開盤,台股照常。所以台股的五天回推到 9/4 就滿了,美股得回推到 9/3。

兩組錯開一天,中間缺一天。

這件事在 9 月 7 日當天就被動驗到了。那天早上九點的美股排程沒跑(機器在睡),下午醒來後自動補跑,抓回來的筆數跟前一天一模一樣:那天美股根本沒開盤。

「資料沒變就不更新」這個決定,在那一刻自己證明了自己。我沒有為勞動節寫任何一行特判,它就被吃掉了。明年、後年、颱風假、任何我沒想到的休市,處置都一樣。

還有一個更容易錯的:對照分析時,台股 9/8 面對的是美股 9/4 的收盤。

不是 9/7(那天沒開),也不是 9/8(台股 13:30 收盤時,美股 9/8 那一場還沒開始)。台股某一天面對的,是嚴格早於它的那一場美股收盤。

任何「一天對一天」的假設在這裡就會錯位,而且錯得很安靜,會產出一組看起來完全合理的對照數字。所以這條寫成了測試:

def test_last_five_sessions_us_reaches_further_back():
    """美股少了 9/7,所以同樣五天要回推到 9/3。"""
    assert windows.last_n_sessions(US_SESSIONS, 5) == [
        D(2026, 9, 3), D(2026, 9, 4), D(2026, 9, 8), D(2026, 9, 9), D(2026, 9, 10)
    ]


def test_the_two_windows_are_not_the_same_dates():
    """這一條就是那個坑本身 —— 拿日期直接對齊會錯位。"""
    tw = windows.last_n_sessions(TW_SESSIONS, 5)
    us = windows.last_n_sessions(US_SESSIONS, 5)
    assert len(tw) == len(us) == 5
    assert tw != us
    assert set(tw) - set(us) == {D(2026, 9, 7)}
    assert set(us) - set(tw) == {D(2026, 9, 3)}

第二個測試斷言的是「這兩組不相等」,而且把差集也寫死了。任何一次重構如果不小心讓兩邊對齊了,這條就會紅。

last_n_sessions 的輸入是資料裡實際存在的日期,不是一份交易日曆。這是刻意的:交易日就是「資料裡有這一天」,所以勞動節、颱風假、任何我沒想到的休市都不需要特判。少維護一份會過期的清單,換來的是這個函式永遠不會因為「日曆沒更新」而算錯。

另外那個「台股 9/8 對到美股 9/4」的規則,在程式裡是一個叫嚴格早於的判定:不是「早於或等於」。差一個等號,9/8 就會對到 9/8,而那在台股收盤時根本還沒開始。

不過這個坑還有第二層,是寫完上面那兩條測試之後、9 月 11 日晚上才撞到的。

同一個市場裡,兩個標的的五天也可能不是同一組日期。

今晚重跑評分,^TWII 拿到的視窗是 9/4 到 9/10,0050.TW006208.TW 卻回推到 9/3 到 9/9。差別不在程式,在資料:那兩檔 9/10 那一根日 K,在來源那邊還沒出現。同一次抓、同一個市場,指數有,ETF 沒有。

翻了每天存下來的稽核副本才發現這件事一直在發生。9 月 9 日抓回來的序列缺 9/8、9 月 10 日抓回來的缺 9/9、9 月 11 日抓回來的缺 9/10。缺的永遠是前一個交易日,隔一天就自己補上。9/10 那一根現在還空著,只是因為它排在隊伍的最後面。

而「五個交易日」是從資料裡數出來的,不是從日曆上數出來的。少一根 K 不會報錯,視窗只是安靜地往前挪一天。這是不維護交易日曆的代價:分不出「這天沒開盤」與「這天的資料還沒到」。


2. 哪幾天是觀測的,哪幾天是回補的

實作是在 9 月 6 日(星期日)就開始做的,五篇文章是每天拆開來寫的。所以要老實標清楚:

東西 9/3–9/6 的部分 9/7–9/10 的部分
價格序列 回補(事後抓的,完整) 活的管線觀測到的
評分快照 回補計算(用 9/6 那一版程式算的) 當天那一版程式當天算的
run log 從 9/6 建置日起有 完整

這張表看起來很囉唆,但它是這篇唯一誠實的方式。如果只寫「連續觀測五天」,讀者會以為那五天的每一個數字都是當天產生的,而前半段不是。

表上還少了一格。ETF 那兩檔 9/10 的收盤,來源現在沒有,本機有:9 月 10 日 18:00 那一份稽核副本裡,0050.TW 的 9/10 收盤 108.60 好端端地躺著。它補得回來,前提是當初有人抄了一份下來。

評分序列的數字補齊了。文章這一側只印指數,具名的那幾檔 ETF 留在加了鎖的頁面上,理由 Day 26 講過:

台股交易日 ^TWII 美股交易日 ^GSPC
9/4 100.0 9/3 100.0
9/7 80.0(布林通道) 9/4 100.0
9/8 100.0 9/8 100.0
9/9 100.0 9/9 100.0
9/10 100.0 9/10 100.0

^TWII 簡單平均 96.0、加權平均 97.0,^GSPC 兩個平均都是 100.0。

五個點裡只有一格不是滿分,這組數字說明不了任何事,它只說明五天就是這麼短。比較有內容的是那五個 100 分裡的最後一格。

9 月 9、10、11 三個早上的美股班次,run log 都留了同一句:「SPY: 1 格缺值,已保留前一日值並標 stale」。最新那一根沒拿到,程式照規則把前一天的收盤補上去、標記 stale,然後繼續算。分數算得出來,頁面也顯示得出來。

今晚跑全量比對,這格終於對上了原本的樣子:本機的 SPY 9/10 收盤 762.40(從 9/9 抄過來的),來源現在給 757.83,差 0.60%;VOO 是 700.87 對 696.65,差 0.61%。

所以「對不上」有兩種意思,一種是來源回頭改寫了歷史,一種是遲到的資料終於到了。這次是後者。

照著比對程式印的建議去跑重抓,它回「重疊 250 天,0 格與本機不同,不寫紀錄」。**重抓看不見那一格。**比對函式會跳過自己標成 stale 的列,註解寫著「那格本來就是保留前一日值,比了只會製造假警報」。話沒錯,但副作用是補位值變成重抓永遠碰不到的死角。而喊出問題的那支工具用的是另一套比法,兩邊對同一格的判斷不一樣。

最後是整批重抓那條路把它蓋掉的:日常排程那支不比對、不修補,它就是把一整年重寫一次,於是 9/10 那格直接變回 757.83,stale 旗標消失,全量比對歸零。


3. run log 說了什麼

到 9 月 11 日深夜為止,2026-09.jsonl 有 80 筆。

狀態 筆數
ok 76
partial 4

partial 的意思是「跑完了,但有東西沒抓到」,不是失敗。四筆裡三筆是總經的失敗演練(故意打壞 FRED,見第 5 節),一筆是籌碼面的融資融券還沒公布。

任務分布最多的是 publish_mb(16 次),接著是 macroscores_index 各 9 次、daily_us 8 次、daily_twchips_tw 各 7 次。

publish_mb 那十六次裡有三次是「明文沒變,docs/ 一個字都沒動」,那也記一筆,狀態 ok,counts 裡有 skipped_unchanged「什麼都沒做」也是一次執行,不記的話 run log 就會出現一段空白,而空白分不出是「跳過了」還是「根本沒跑」。

檔案格式是 JSONL 而不是一份 JSON 陣列:一行一筆、append 就好,寫到一半斷電只會壞掉最後一行,前面的都還在。用 JSON 陣列的話每次都要讀進來、改完再整份寫回去,而那份檔案正是用來記錄「執行出了什麼事」的東西,它自己不該有一個寫壞就全毀的失效模式。

補跑那一筆長這樣2026-09-07T15:38:27 daily_us ok。排定時間是 09:00,機器那時在睡,15:34 醒來,四分鐘後工作排程器自動把它跑起來,回傳碼 0。

這是活的觀察,不是受控實驗。沒有調系統時間,也沒有刻意關機。


4. 總經:按更新頻率自動掃

總經那二十四條序列的更新頻率差很多:利差與初領每週或每天、CPI 與非農每月、GDP 每季、央行重貼現率不定期。

用頻率當節拍器,不是用固定間隔。 CPI 每月出一次,每小時去問它二十四次不會讓它早一點出現,只會把額度花在必定落空的請求上。

判定分成四種狀態,而不是「有沒有變」這個二分:

狀態 意思
ON_TIME 還沒到下次公布時間,沒更新是正常的
OVERDUE 早該公布了還沒動,這是「真的沒更新」
UNEXPECTED 不該公布的時候動了,這是「突然更新了」
NO_DATA 從來沒抓到過,跟「早該更新沒更新」是兩回事

驗收句要求「能證明『真的沒更新』與『突然更新了』是兩種不同的判定,各給一個實例」。

真的沒更新:一條日頻序列停在兩週前 → OVERDUE,理由寫「已經 18 天沒有新的(容忍 10 天)」。

突然更新了:央行重貼現率停在 2024-03-22、903 天沒動,如果它今天動了 → UNEXPECTED,理由是「距上一次 903 天」。對一條兩年沒動的序列來說,動本身就是事件。

不定期永遠不會 OVERDUE。這一條特別重要:政策就是沒動,那不是故障。之前那個「拿值去比會永遠亮燈」的坑就是這條規則的來源:一條兩年沒動的序列,用值去判斷會天天被讀成「沒更新」。

判定函式本身沒什麼玄機,值得看的是它需要哪些輸入:

def assess(
    freq: str,
    data_date: dt.date | None,
    today: dt.date,
    previous_data_date: dt.date | None = None,
    key: str = "",
) -> Freshness:
    """判定一條序列的新鮮度。

    `previous_data_date` 是**上一次**的資料日期。
    沒有它就分不出「這條序列本來就是這個節奏」與「它剛剛動了」。
    """

那個 previous_data_date 是整個判定的關鍵。只知道「現在停在哪一天」,最多算得出 OVERDUE;要判 UNEXPECTED,必須知道上一次是哪一天,才能算出這次的間隔跟平常比是不是異常。一條每月序列突然隔 5 天就出一筆,那多半是修正發布或抓錯了,兩種都需要有人看一眼。

容忍天數則是一組刻意放寬的值:

TOLERANCE_DAYS = {"每日": 10, "每週": 21, "每月": 75, "每季": 200}

日頻放到 10 天,是因為連假加上資料延遲很容易疊到一週以上。誤報一次的代價比晚三天發現高:一條天天亮紅燈的通知,第二週就沒有人會看了。這是這套東西裡少數幾個「寧可鈍一點」的地方。(但之後可能會做調整)


5. 失敗通知與重試

5.1 演練

驗收句是:「故意讓一個資料源失敗,其他格照常更新、失敗那格標 stale 並顯示停在哪一天,通知有送出」。

演練腳本把 FRED 的端點換成一個不存在的主機,其餘來源不動,跑一次總經管線。結果:

  • 失敗的七條序列全部保留舊值,沒有被清成 None 或 0
  • 其他十七條照常更新
  • 通知寫進 alerts.jsonl 與一個顯眼的 ALERT.md

通知的內容長這樣:

7 條序列沒有更新:
- t10y2y:端點連不上(演練)(停在 2026-09-04)
- cpi:端點連不上(演練)(停在 2026-07-01)
- unrate:端點連不上(演練)(停在 2026-08-01)
- phlfed:端點連不上(演練)(停在 2026-08-01)
- fedfunds:端點連不上(演練)(停在 2026-09-07)
- claims:端點連不上(演練)(停在 2026-08-29)
- payrolls:端點連不上(演練)(停在 2026-08-01)

每一行都說「停在哪一天」。 只寫「vix 失敗」沒有用,看不出是今天剛壞還是壞了三週沒人發現。

而且七條壞掉是一則通知,不是七則。一次跑壞七條就送七則,第二天就沒有人會看通知了。

5.2 演練本身也出了一次錯

第一次跑演練,run log 裡的失敗訊息是這樣:

t10y2y(美債 10Y-2Y 利差): 'series'

'series' 四個字。完全查不出發生了什麼事。

原因是我把假網址的佔位字串寫成 {series},而正本是 {sid},所以它死在字串格式化而不是死在連線,演練也就變成「我把網址打錯了」,不是「資料源掛掉」。

'series'str(KeyError) 的結果。順手把非 FetchError 的例外加上型別名之後,訊息才變成看得懂的東西。

演練的價值有一半在這裡:它讓錯誤訊息本身被檢驗了一次。

5.3 重試

重試上限一次、固定退避三秒。刻意不做指數退避、不做多次重試。

def retry_once(fn, backoff: float = 3.0, clock=None):
    """重試上限 1 次、固定退避。

    刻意不做指數退避、不做多次重試:排程每天跑,今天失敗明天會再試,
    在這裡纏鬥只會多消耗別人的額度。
    """
    c = clock or REAL_CLOCK
    try:
        return fn()
    except (RateLimitError, FetchError):
        c.sleep(backoff)
        return fn()

理由:排程每天跑,今天失敗明天會再試。在那裡纏鬥只會多消耗別人的額度,而且會把一次暫時性的網路問題放大成一串請求。

通知失敗絕不能拖垮管線。 這一層的每個錯誤路徑都吞掉例外:為了送不出一則通知而讓當天的資料整批沒抓到,是本末倒置。連本機檔案都寫不進去的時候也不丟例外,只誠實回報「沒寫成功」。


6. 金鑰分級

兩把金鑰不是同一個等級的東西:

FRED Shioaji
能做什麼 唯讀,抓經濟數據 有下單能力
掉了會怎樣 別人多抓一點資料 別人可以用我的帳戶交易
撤銷成本 網站上重發一把 要處理的事情多得多
沒有它能不能跑 ,退回免金鑰端點,額度從 120 降到 30 台股不做交叉比對,其餘照跑

處置因此完全不同。

FRED 那把放在 repo 底下一個 Key/ 資料夾,被 .gitignore 擋著。程式找得到就走官方 API、找不到就退回免金鑰的 CSV 端點。沒有它整套照樣跑,只是慢一點。

Shioaji 那把不放明文,用機器綁定的加密存在資料層:金鑰由主機名稱、使用者、MAC 位址衍生,換一台機器就解不開。解不開的時候回空字串觸發重新輸入,不會靜默地用錯的值。

兩把都不進 CI。 這是「排程放本機、Actions 只部署」那個決定的直接後果:CI 不抓資料,就完全不需要任何祕密。有一支測試掃過每一個 workflow 檔,出現 secrets. 就讓測試失敗。

接上這把金鑰的時候還撞到一件事。官方 API 把金鑰放在 query string 裡(?api_key=...),而 requests 的例外訊息會把整個 URL 回顯出來。

什麼都不做的話,一次連線失敗就會把金鑰寫進 run log、寫進 ALERT.md、印在終端機上。而 run log 正是要貼進這篇文章的東西。

所以那支 adapter 裡所有對外的字串都先過一個 redact()

def redact(text: str) -> str:
    """把 `api_key=<金鑰>` 換成 `api_key=***`。

    對外的每一個字串都要過這裡:例外訊息、run log 的 note、通知內容。
    只遮金鑰那一段,其他 query 參數留著 —— 全部遮掉的話錯誤訊息就沒用了。
    """
    return re.sub(r"(api_key=)[A-Za-z0-9]+", r"\1***", text)

一行正規表示式,重點在它遮得剛剛好。整個 URL 都遮掉的話,錯誤訊息就變成「連不上某個地方」,那跟沒有訊息一樣;series_idsort_orderlimit 這些參數留著,才看得出是哪一條序列、用什麼參數失敗的。

而「所有對外字串都要過這裡」這句話本身是靠測試守的,不是靠記性:test_fred_key.py 會拿一把假金鑰組出各種失敗情境,斷言它不出現在任何輸出裡。

實測:故意打一個不存在的主機,錯誤訊息 381 個字元,金鑰沒有出現。9 月 8 日那次演練的紀錄還留在 run log 裡,那一行長這樣:...url: /fred/series/observations?series_id=T10Y2Y&api_key=***&file_t...series_id 看得見,金鑰是三顆星。

這支 adapter 的 User-Agent 用的是 requests 的預設值,沒有偽裝成瀏覽器:實測過,偽裝 Mozilla 反而因為 TLS 指紋跟宣稱的瀏覽器對不上而被擋掉,用預設 UA 才放行。這種事沒踩過不會知道,所以直接寫成註解留在程式碼裡。

「金鑰只放在本機」除了不要 commit,也不能把它印出來。


7. 額度、成本與限制

到 9 月 11 日深夜為止,本月各來源的請求數:

來源 本月請求數 官方限制 本專案規範
yfinance 241 無官方數字 批次間 sleep 1 秒,禁用多執行緒
期交所 154 無官方數字 間隔 ≥ 0.6 秒 + 整檔快取
證交所 124 無官方數字 同上
FRED 60 有金鑰 120 req/min 固定節流 1 秒/次(用一半)
國發會 8 無公布 同輪共用一次下載
主計總處 8 無公布 同上
央行 8 無公布 同上
美國能源資訊署 4 無公布 同上

這張表的數字不是估的。每一支 adapter 在真的送出請求之前都會先撞一下同一個 module-level 的計數器:

def _get(url: str) -> str:
    _THROTTLE.wait()
    COUNTER.bump(SOURCE)
    ...

節流器與計數器都做成 module-level 的單一實例,任何呼叫路徑都繞不過去:呼叫端不必記得要 sleep、也不必記得要計數。這比「在每個呼叫點加一行」可靠,因為新增一支 adapter 的時候,忘記加那一行不會有任何症狀,只會讓統計悄悄少算。計數結果每次執行結束寫進 run log 的 quota_json,所以額度是一筆一筆累出來的,不是回頭推估的。

體積:會進 git 的程式碼 0.65 MB、docs/ 密文頁面 0.06 MB、本機資料層 5.35 MB(不進 git)。五天長了 2.6 MB,長的全在不進 git 的那一邊。

一天一次部署、每次不到 0.1 MB,一年約 20 MB。Pages 的軟上限是 1 GB、每月 100 GB 流量,離很遠。Actions 分鐘在 public repo 免費不計費。

GitHub API 未認證額度 60 req/hr 這個數字標記為待確認,沒有實際打到限制過,是文件上讀來的。

有一格是空的:本月的 run log 沒有記到 Shioaji 的 remaining_bytes

這是一個真的缺口,不是漏寫。程式有那段邏輯,但這幾天的執行裡沒有成功記到值。

它為什麼重要:Shioaji 超流量的後果不是報錯,是行情查詢直接回空值。 程式會以為「那天沒資料」,然後照著「沒資料就保留前一日、標 stale」的規則走下去,一切看起來都很正常,只是資料停在某一天。

這一格空著就等於不知道離上限還有多遠。五天過去,它還是空的。待補。


8. 這套加密擋得住什麼、擋不住什麼

這一節得誠實寫,因為它是整個專案裡最容易被自己說服的地方。

門在這裡打開,昨天說今天講的就是這個:

https://ycy1997alex.github.io/market-barometer/
密碼:iThome!2026%alexyu

輸入之後,解鎖狀態只留在當下那個分頁,關掉就沒了,開新分頁得再輸入一次。那是 sessionStorage 的行為,不是壞掉。

8.1 機制

信封加密:內容只加密一次,再用每組密碼各自把那把內容金鑰包一次。解開之後,sessionStorage 裡存的是內容金鑰不是密碼,關掉分頁就沒了。

8.2 擋得住的

  • F12:開發者工具裡只看得到 salt、IV、密文。
  • 搜尋引擎:頁面有 noindex, nofollow,而且內容本來就是密文。
  • 隨手逛到的人:沒有密碼就是一個輸入框。

8.3 擋不住的

離線爆破。

密文放在 public repo,任何人可以下載後慢慢猜。沒有速率限制、沒有鎖定、沒有人會知道有人在猜。

WebCrypto 裡唯一可用的 KDF 是 PBKDF2(沒有 Argon2、沒有 scrypt),而它只吃 CPU、攻擊者用的是 GPU,並行度差好幾個數量級。把迭代數再往上調只是常數倍的改善,還會讓每個正常訪客多等好幾秒,換不到結構性的差別。

真正決定安不安全的是密碼本身。以單張高階 GPU 估算,「字典詞 + 年份 + 符號」這種結構大概分鐘到小時就破得掉;四個隨機單字(diceware)那種才會拉到千年以上。字元數不是重點,結構才是

8.4 所以

不要宣稱它是「私密」的。對外一律說「加了鎖的公開頁面」。

這也是為什麼挑戰內容這一側從頭到尾不放買賣建議:那條線不能押在鎖的強度上。加密降低了「對不特定人」的成分,但降低不等於消除,尤其當密碼本身是分鐘級可破的時候。

所以合規性押在內容本身:不生成建議,輸出層有 lint 擋著。鎖只是門禁。


9. 資料授權與免責

原始價格序列不進任何 repo,連加密的也不放。

yfinance 抓的是 Yahoo 的前端端點,條款不允許再散布。所以 repo 裡只有程式碼與密文頁面,價格序列全部留在本機的資料層。

這也順便解決了體積問題:資料層會持續長大,repo 不會。


10. 明確寫出沒做的

這一節可能比前面九節都重要。

沒有即時報價。 全部是日線收盤,最快也是收盤後幾小時。

沒有自動下單。 Shioaji 有這功能但我沒有開啟。

沒有真正的回測。 五個交易日不是回測,是五個點。真的回測需要幾年的資料、要處理存活者偏差、要算交易成本與滑價,而且需要一組事先定義好的進出規則,那組規則正是這個專案刻意不產生的東西。

沒有預測。 這套東西輸出的是「現在的讀數」,不是「接下來會怎樣」。

評分權重沒有最佳化。 全部是等權,門檻是慣例值或直覺值。每一個數字旁邊都寫了「為什麼是這個」,而理由誠實地寫著「這是慣例」之類的。


小結

五天做完,最想留下的是開頭那件事:補得回來的東西,跟補不回來的東西,要分清楚。

價格可以回補,所以「連續五天的價格」這句話很容易說。評分快照跟 run log 補不回來,所以那兩樣才是真正只能靠時間累積的東西。而它們也剛好是最不起眼的兩樣:一個是幾行數字,一個是 80 筆 JSON。

所以最後還是同一件事。值可以重來,時間不行。

同一個道理套在別的地方也成立。這五天裡我做過最多的判斷不是「怎麼算」,是「這個算不出來的時候要說什麼」。SPCX 的中長期評分、ETF 的內扣費用、融資維持率、Shioaji 的剩餘流量、黃金跟大盤的關係,五個都是「沒有」,五個都可以硬掰一個看起來合理的數字出來。

沒掰的那五格,大概是這個專案裡我最有把握的部分。

參考資料

資料來源

工具與規格

其他參考


註一:文中所有執行紀錄、請求數與體積皆為 2026 年 9 月 6 日至 9 月 11 日深夜的實際數字,五個交易日只有五個點,一律屬於定性觀察,不是統計證據。

註二:GitHub API 未認證額度 60 req/hr 為文件數字,作者未實際打到限制驗證,標為待確認。

註三:第 8.3 節的破解時間量級為一般性估算,非作者實測,僅供理解密碼結構的重要性;實際時間依硬體與攻擊方法差異極大。

註四:本專案沒有即時報價、沒有自動下單、沒有真正的回測、沒有預測功能,評分權重未經最佳化。

註五:0050.TW006208.TW 的 9/10 日 K,截至 9 月 11 日深夜仍未在資料來源出現,文中該值取自 9 月 10 日 18:00 存下的稽核副本。SPYVOO 的 9/10 那一格已於當晚重跑每日排程時覆寫為真實收盤,全量比對的差異歸零。


重要說明:本文所有數字與敘述僅為個人技術實作紀錄,不構成投資建議


上一篇
Day 27|從能跑到能發布:用測試守住架構,打造可部署的股票分析工具
下一篇
Day 29|AI 不只是聊天機器人:我試著把 AI 講給爸媽聽
系列文
三個介面,一套工作流?30 天 Claude 跨領域實戰:從 claude.ai、Claude Desktop 到 Claude Code30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言