AI預測開發筆記:我使用了 LLM 做股票預測

Stock analytics dashboard displaying AI sentiment score, predicted movement, market trend graphs, key drivers, and prediction accuracy for AAPL

Leveraging Large Language Models for Stock Market Prediction

在開發輔助股票決策工具的過程中,我最初的規劃是建構一個完全以大型語言模型(LLM)為核心的股票分析系統。想法很直觀:想利用 LLM 語意理解強大的特性,去組合一群虛擬的財經專家(包含技術派、財報派、總經派),並透過多智能體(Multi-Agent)每日會議的架構,讓這些虛擬大師依序發言並進行交叉辯論,期望能產出機構級的閉門會議戰報。

然而,在實際投入運作並觀察多個交易日後,我發現這個版本產出的結果並不符合預期,LLM 生成的專家意見流於空泛,缺乏實質的決策貢獻

技術盲點的發現:語言模型類神經模型的本質差異

在明志科技大學碩專修讀 AI 相關課程時,透過對機器學習、類神經網路以及 Transformer 架構的深入探討,我才確切了解問題的底層原因。
LLM 的強項在於語意脈絡的推演與邏輯框架的建構,但其底層本質上是基於概率的文字接龍,數學計算與精確的量化回測從來都不是 LLM 的強項。當系統需要針對 PE 比率、營收增長率、股價歷史均線或法人建倉成本進行精確評估時,純 LLM 架構極易產生幻覺,或給出前後矛盾的推論。
如技術派可能因為價格上升建議購買,但財報派和總經派卻在未充分考量庫存限制的情況下給出持有的最終裁決,導致共識分數不具備客觀參考價值。

2.0 版的股票分析系統架構與資料爬蟲管線

為了修正純 LLM 的數值盲點,我將系統改為「語意決策」與「量化計算」解耦的模組化平台設計。在 main_2.pyai_engine_2.py 的架構中,我實作了以下硬體數據管線,作為 AI 開會前的「資料護城河」:

  • 量化籌碼與成本估算: 系統利用 FinMind API 自動抓取三大法人(外資、投信、自營商)的即時買賣超數據,並在底層透過 Python 動態計算「近三日法人估算均價」,將其轉化為客觀的數值限制。
  • 量價防錯掃描(WASH 系統): 透過 yfinance 撈取 10 日價量數據,自行編寫演算法計算「今日成交量 ÷ 過去 5 日均量」的量增比,藉此定義出「極致縮量價穩(WASH)」或「爆量跌破(DANGER)」等洗盤籌碼狀態。
  • 異質情報清洗歸檔: 整合 Gmail API 爬取訂閱的財經情報,利用正則表達式過濾掉無用的 URL 與訂閱資訊,清洗出明確的股票代碼與機構目標價,存入知識庫;並配合 SerpApi 在開會前自動抓取最新的 Google 新聞情報。

專家會議中的「硬限制」注入

在重構後的 2.0 版中,運作流程不再讓 AI 天馬行空地瞎掰。在啟動 Llama 3 (8B) 技術派、Mixtral (8x7B) 財報派、Llama 3 (70B) 總經派以及 Gemini 總審核官的閃電會議前,底層的量化引擎會先將真實的庫存水位、帳面損益與風險配置,轉化為「不可違背的鐵律」注入 Prompt 中

  • 設一個條件: 若該標的投入成本未達 15 萬台幣,屬小額試單,系統強制限制絕對禁止喊 SELL,強迫以時間換空間。不然一直要我停損賠賣。
  • 資產考慮: 若全局資產總損益為正,代表強勢股利潤足夠覆蓋弱勢虧損,系統需給予弱勢股更寬容的觀察期。
  • 法人被套牢限制: 若市場現價低於近三日法人成本,代表主力隨時可能自救拉抬,同樣限制禁止喊 SELL。

最終由 Gemini 擔任總審核官進行「盲點打假」,檢查前三回合的專家分析是否違反上述硬性風控指標,並給出最終裁決

系統現存的程序缺失

雖然 2.0 版引入了數據分流,但從代碼審視,仍存在幾項明顯的缺失:

  • 量能預估算法過於線性:_calc_wash_est_volume 中,系統使用當前成交量依時間比例進行線性放大(curr_vol / elapsed * 270)。然而市場成交量多呈現開盤與尾盤爆量的 U 型分佈,線性推估極易在盤中造成洗盤警示的誤判。
  • 維護成本高與 API 依賴: 股票中文正名(_force_update_names)採用了大量的硬編碼(Hardcode)字典。且系統高度依賴 yfinance、SerpApi 等第三方免費資源,缺乏自有數據源的容錯能力。
  • 風控模型過於靜態: 系統升級模組中的停損停利計算(Tab 9)仍停留在固定的百分比滑桿控制,尚未引入動態的 ATR(真實活動幅度)或移動停利演算,無法因應大盤極端震盪時的變局。

我後來重新拆解的,不是 Prompt,而是整個判斷流程

停下來回看 2.0 到 6.0 的修改,我發現問題不只出在模型選得不夠好,也不是 Prompt 寫得還不夠細。

真正的問題是,我一開始把太多事情交給 LLM 處理。

我希望它讀新聞、看技術線圖、理解法人籌碼、判斷市場情緒、考慮風險,最後還要給出一個看似明確的買賣結論。這種架構看起來很完整,實際上卻把不同性質的問題混在一起。

歷史價格、成交量、波動率、法人買賣超,這些是結構化資料,應該交給可以訓練、回測與量化比較的模型處理。新聞、產業訊息、公司事件與市場敘事,才比較適合讓 LLM 協助整理。

於是我沒有再繼續替多智能體會議加角色,也沒有再要求模型把話講得更像投資專家。我重新把整個系統拆成三個部分:技術、資金流向與事件。

技術面由 LightGBM 處理。模型使用價格相對變化、相對成交量、60 日高點距離、MACD、RSI、ATR 等特徵,避免直接拿不同股價級距的數字混在一起訓練。訓練資料也改用時間序列切分,讓較早期的資料負責訓練,較晚期的資料用來驗證,盡量減少未來資訊滲入歷史回測的問題。

籌碼與市場趨勢則回到明確的規則。台股會看外資、投信與自營商的連續買賣方向,搭配融資變化與量能;美股缺乏台股這種集中且可取得的法人買賣資料,因此改以大盤、費城半導體指數與量價狀態作為市場環境代理訊號。

LLM 留在它相對擅長的位置:分析事件。

它會先讀取最新新聞,判斷消息偏多或偏空、影響力有多高、屬於基本面事件、總體敘事,還是短期傳聞與地緣風險。只是這次我不再讓它自己決定一切。新聞超過兩天,影響力會被系統壓低;超過五天,則只保留為背景。不同事件類型也有不同的分數上限,避免一則模糊的市場傳聞,被放大成足以改變整體判斷的訊號。

這套新版系統,我暫時叫它「準準準」。

名字聽起來有點直接,背後其實是在提醒自己:預測系統不該因為模型講得很有道理,就假設它很準。真正要驗證的,是高分候選是否真的比低分候選有更高的命中率;系統排在前面的標的,是否比隨機挑選更有鑑別力;市場走勢改變時,模型是否知道該收斂,而不是繼續給出過度樂觀的答案。

因此,新架構不只輸出一個 AI 分數,也開始建立回填與校準機制。

每一筆預測會以二十個交易日作為觀察週期,並以超額報酬檢查結果。台股不只看個股有沒有上漲,也會扣除同期大盤或 0050 的表現,避免大盤全面上漲時,系統把任何正報酬都誤認成自己預測成功。

我也開始把預測分數切成區間,回頭檢查不同分數帶的實際命中率。假如 70 分以上的候選,長期表現沒有比 60 分區間更好,那代表這個分數只是看起來精細,沒有真正的校準意義。另一個會持續追蹤的指標是 Precision@K:每天排序後的前 3、前 5、前 10 名,是否真的比全部候選更值得優先觀察。

新版系統目前還不能宣稱有穩定的預測能力。

AI_Prob 的排序鑑別力仍在累積資料驗證,部分結果開始出現正向訊號,卻還不夠穩定。預估價格區間偏高、事件分類文字過於嚴格、自動掃描與手動觀察頁面的事件分數邏輯不一致,也都還在待修正清單裡。

但我覺得這樣反而比較接近我原本想做的事。

我不是要做一個每天替我喊買進或賣出的黑盒子,也不想讓 LLM 假裝成全知的投資大師。我想做的是一套能持續留下紀錄、看得見假設、能回頭驗證、知道自己何時不可靠的輔助決策系統。

在這個架構裡,量化模型負責處理數字與歷史規律,規則引擎負責限制風險,LLM 則協助閱讀市場資訊、整理事件脈絡。它們不需要搶著扮演最後的決策者,而是各自把自己擅長的部分做好。

我決定刪掉重來

這個以 LLM 為主的預測系統,我一路從 2.0 版陸續優化、調整、疊代修改到了 6.0 版。經過長時間的實測與數據對照,我發現單純在語言模型的 promoter 框架或多智能體代理人文字遊戲上進行微調,依舊無法從根本上解決 LLM 缺乏嚴謹數值邏輯的先天缺陷,系統依然無法達到預期的實戰精準度。

我決定停止在舊架構上的無腦優化。我將重新思考整個預測引擎的底層邏輯,並著手重寫全新的 7.0 版,應該以量化給予類神經網路模型與傳統機器學習在數值預測上的權重, LLM 就回歸其擅長的語意彙整角色來做資料彙整。

更多文章…
AI 股票預測實驗 Day 1|AI 多模型融合預測
為什麼越來越多人提起開源 AI?是趨勢嗎?
AI 多模型融合研究:如何設計可重現的融合實驗、評估指標與結果校準(含 blending / stacking / gating)
QQCDR AI Engine 是什麼?多模型融合 AI 決策系統解析


探索更多來自 YinOnMars 的內容

訂閱即可透過電子郵件收到最新文章。

發表迴響

探索更多來自 YinOnMars 的內容

立即訂閱即可持續閱讀,還能取得所有封存文章。

繼續閱讀