建AI Agent自動交易系統(tǒng):從模擬到實盤全實踐)
做量化交易的人通常都有這種體會模擬盤跑得再順心里也始終懸著一塊石頭畢竟模擬和實盤永遠(yuǎn)隔著一堵看不見的墻。我這個項目最開始就是想讓一個 AI Agent 自己去看行情、自己決策、自己在模擬盤里下單同時把每一次買賣和理由同步到飛書像帶了一個能實時匯報的交易助理。整套系統(tǒng)基于 OpenClaw 這個開源 Agent 執(zhí)行框架加上飛書開放平臺的自定義機(jī)器人應(yīng)用我把從零到模擬盤跑通、再到為實盤做準(zhǔn)備的全過程完整走了一遍踩了不少坑也總結(jié)了一套可以復(fù)用的搭建方法。這篇文章就是把這段經(jīng)歷原原本本記錄下來適合對自動化交易系統(tǒng)、Agent 工具調(diào)用、飛書機(jī)器人開發(fā)感興趣的開發(fā)者參考。先說明白這套系統(tǒng)本身不構(gòu)成任何投資建議代碼和參數(shù)完全用于技術(shù)驗證。尤其是“實盤”部分我只講對接思路和風(fēng)控準(zhǔn)備不會勸任何人把真錢交給 AI 去管。1. 項目設(shè)計思路這套架構(gòu)到底在解決什么問題我先把你可能最關(guān)心的問題放最前面為什么偏偏用 OpenClaw 加飛書 Agent 這個組合而不是直接寫一個 Python 定時腳本原因在于傳統(tǒng)定時腳本解決的是“到點執(zhí)行”而 AI 自主系統(tǒng)要解決的是“根據(jù)當(dāng)前狀態(tài)自主判斷下一步做什么”。OpenClaw 的核心價值是把大語言模型變成一個可以調(diào)用外部工具的執(zhí)行體你要做的不是把每一步都寫死而是給它注冊好工具、設(shè)定好目標(biāo)讓它自己決定在什么條件下調(diào)用買入、賣出、查詢、通知這些動作。飛書 Agent 則解決人機(jī)協(xié)作的問題——Agent 在后臺再怎么自主運(yùn)行你也不可能一直盯著終端看把它接進(jìn)飛書之后每個決策、每筆模擬成交、每日持倉匯總都會以消息形式推送到你的手機(jī)你只需要在群里做最終確認(rèn)和干預(yù)。這套系統(tǒng)的整體架構(gòu)可以拆成四層每一層都有明確邊界交互層飛書機(jī)器人應(yīng)用負(fù)責(zé)接收用戶指令、推送交易報告和預(yù)警消息。決策層OpenClaw 運(yùn)行時中的 Agent 核心負(fù)責(zé)調(diào)用策略模塊、讀取行情、判斷買賣信號。撮合層自建的模擬交易引擎用虛擬資金模擬真實交易中的手續(xù)費(fèi)、印花稅、持倉成本和成交邏輯。數(shù)據(jù)層免費(fèi)或低成本的行情數(shù)據(jù)接口提供 K 線、實時報價和賬戶快照。1.1 OpenClaw 在系統(tǒng)里扮演的角色OpenClaw 在這套系統(tǒng)里相當(dāng)于“管事的那個大腦”但它本身不內(nèi)置炒股知識它更像一個調(diào)度中樞。你要做的事情是把數(shù)據(jù)源、策略判斷、模擬下單、消息推送這些能力做成一個個具名的工具函數(shù)注冊進(jìn) OpenClaw 的工具列表里然后給 Agent 一段總目標(biāo) Prompt告訴它“你是一個模擬交易助手負(fù)責(zé)監(jiān)控這幾只標(biāo)的遵循策略模塊給出的信號執(zhí)行操作并把關(guān)鍵動作匯報到飛書”。這種設(shè)計最直接的好處是邏輯邊界非常清楚。行情獲取、策略計算、下單撮合這些偏重邏輯的事情用傳統(tǒng)代碼實現(xiàn)而什么時候該看盤、遇到異常怎么處理、如何組織匯報語言這些偏重判斷的事情交給大模型去完成。OpenClaw 跑起來之后每一次周期循環(huán)就是一輪標(biāo)準(zhǔn)的 Agent 工作流讀取工具狀態(tài) → 調(diào)用工具獲取數(shù)據(jù) → 根據(jù)模型輸出決定動作 → 執(zhí)行動作 → 寫日志 → 進(jìn)入下一輪。我自己沒有把 OpenClaw 魔改成什么很復(fù)雜的東西因為它的收益恰恰來自克制。工具只注冊了四個核心函數(shù)查詢行情、執(zhí)行模擬買入、執(zhí)行模擬賣出、推送飛書消息。Agent 能做的事再大最終也要落到這四個函數(shù)上。1.2 飛書 Agent 解決的人機(jī)協(xié)作問題把系統(tǒng)接入飛書是我覺得整個項目里影響體驗最關(guān)鍵的一步。早期我用最簡單的方式調(diào)試也就是把日志寫到文件里等想起來再去看一眼。后來發(fā)現(xiàn)系統(tǒng)自主運(yùn)行的時候決策理由、執(zhí)行結(jié)果、賬戶權(quán)益這些信息如果不在第一時間推送到手邊你根本沒法判斷它是不是在正常工作。飛書這邊我有兩種接入方式可以用兩者的定位差別很明顯自定義機(jī)器人應(yīng)用走飛書開放平臺注冊一個企業(yè)自建應(yīng)用拿到 App ID 和 App Secret通過接口主動發(fā)消息給群聊。能力更完整可以接收消息回調(diào)、支持復(fù)雜交互適合做正式的 Agent 交互窗口。群自定義機(jī)器人 Webhook在飛書群里添加一個自定義機(jī)器人提供一個 Webhook 地址用 HTTP POST 就能把消息推到群里。實現(xiàn)成本最低適合快速驗證消息鏈路。第二個方案雖然簡單但它只能發(fā)消息不能收消息對于“人工干預(yù)指令”這種需求支持有限。我在項目正式跑起來之后換成了第一種方案因為我還需要能在飛書群里直接發(fā)一句“暫停交易”或“清倉”讓 Agent 響應(yīng)這些指令。1.3 模擬盤與實盤的邊界標(biāo)題里寫了“從零到實盤”但我必須把模擬和實盤這兩個階段說清楚因為它們對應(yīng)的系統(tǒng)要求完全不同。模擬盤階段你的賬戶資金是假的行情是真實的目標(biāo)是驗證策略邏輯、Agent 決策質(zhì)量、消息鏈路穩(wěn)定性和故障恢復(fù)能力。這個階段可以放開手腳讓 Agent 每天自動跑跑得越久暴露的問題越充分。實盤階段資金變成真的這時候系統(tǒng)要求會發(fā)生質(zhì)變接口穩(wěn)定性、鑒權(quán)安全、交易額度限制、異常中斷恢復(fù)、人工熔斷機(jī)制每一個都是硬指標(biāo)。當(dāng)時我把這套系統(tǒng)連接到真實券商賬戶之前實際上在模擬盤上連續(xù)跑了幾周確認(rèn)了兩件事一是 Agent 的每次操作都有完整可追溯的日志二是所有操作在極端行情下也不會出現(xiàn)明顯超出風(fēng)控參數(shù)的交易。即便這樣實盤真正上線時我也只放了極小的一筆資金而且保留了隨時人工接管的權(quán)利。把這套系統(tǒng)完整做完之后我最大的感受是架構(gòu)本身不難難的是把每一個細(xì)節(jié)都擺到它該在的位置上。下面我先講環(huán)境搭建和基礎(chǔ)接入過程。2. 前期準(zhǔn)備飛書機(jī)器人、OpenClaw 運(yùn)行環(huán)境和行情源第一步不是寫核心代碼而是把地基打好。這一階段我花了大約兩天時間主要精力在飛書應(yīng)用配置和行情接口的穩(wěn)定性測試上。2.1 OpenClaw 運(yùn)行環(huán)境搭建OpenClaw 是一個以 Python 為主的 Agent 執(zhí)行框架。我是在一臺云服務(wù)器上部署的配置不需要太高2 核 4G 內(nèi)存足夠跑起來因為真正消耗資源的大模型推理走的是 API 調(diào)用本地只負(fù)責(zé)邏輯編排和工具執(zhí)行。環(huán)境準(zhǔn)備工作包括安裝 Python 3.10建議用虛擬環(huán)境隔離依賴。通過 Git Clone 拉取項目之后把環(huán)境變量文件拷貝一份在里面配置大模型 API 地址和模型參數(shù)。確認(rèn)網(wǎng)絡(luò)能正常訪問行情接口和飛書開放平臺接口這兩者都是標(biāo)準(zhǔn) HTTPS 請求沒有特殊要求。用官方自帶的 demo 跑一遍工具調(diào)用流程確認(rèn) Agent 能成功執(zhí)行一次簡單的函數(shù)調(diào)用。這一步其實不用搞得很復(fù)雜。OpenClaw 本身提供了工具注冊的接口你只需要把自定義函數(shù)通過裝飾器或者配置表掛上去就能被 Agent 看到。初次跑 demo 時我犯過一個低級錯誤把模型 API 的地址填成了局域網(wǎng)地址導(dǎo)致 Agent 一直處于等待響應(yīng)的狀態(tài)日志看起來像卡死實際是網(wǎng)絡(luò)不通。2.2 創(chuàng)建飛書自定義機(jī)器人應(yīng)用飛書這邊的完整步驟我一步步記錄一下因為配置過程中容易漏掉回調(diào)地址的校驗。登錄飛書開放平臺進(jìn)入開發(fā)者后臺創(chuàng)建一個“企業(yè)自建應(yīng)用”。在應(yīng)用能力里開啟“機(jī)器人”能力這樣應(yīng)用在群里表現(xiàn)得像一個普通機(jī)器人。在“憑證與基礎(chǔ)信息”頁面拿到 App ID 和 App Secret這兩個值后面代碼里要用。在“事件訂閱”里配置請求地址選擇監(jiān)聽消息事件。注意飛書會先發(fā)送一個 URL 驗證請求你需要讓服務(wù)端正確響應(yīng) challenge 字段否則配置保存不了。發(fā)布應(yīng)用版本等待管理員審核通過。對于僅推送消息的場景其實拿到 App ID 和 App Secret 之后就能調(diào)接口了。核心邏輯是先用憑證換取一個tenant_access_token再用這個 token 調(diào)消息發(fā)送接口把消息以機(jī)器人身份發(fā)送到指定群聊。這里有個細(xì)節(jié)飛書的 token 有有效期一般是兩小時所以代碼里最好做一層緩存不要每次發(fā)消息都重新請求。我自己的實現(xiàn)里寫了一個簡單的飛書客戶端把獲取 token 和發(fā)送消息封裝成兩個函數(shù)token 快過期時才自動刷新。這樣 Agent 在調(diào)用推送工具時不需要關(guān)心底層憑證的邏輯。2.3 行情數(shù)據(jù)接入免費(fèi)源就能跑起來行情數(shù)據(jù)是整個系統(tǒng)決策的依據(jù)這一步我建議優(yōu)先考慮免費(fèi)開源數(shù)據(jù)源因為模擬盤階段對行情實時性的要求并沒有想象中那么高。我用的方案是 Python 的開源數(shù)據(jù)接口庫通過它把 A 股的歷史日線數(shù)據(jù)和實時行情都拿到本地。它支持滬深京三地股票也支持指數(shù)和基金基本覆蓋了我們常見的需求。對于更專業(yè)的分鐘級數(shù)據(jù)也可以申請一些數(shù)據(jù)平臺的測試 token但免費(fèi)額度通常有限做模擬盤夠用了。行情模塊只需要封裝三個底層能力獲取單只標(biāo)的的最新價格獲取單只標(biāo)的最近一段時間的日 K 數(shù)據(jù)獲取整個監(jiān)控列表的行情快照。為了讓 Agent 調(diào)用更順手我把這三個能力封裝成一個統(tǒng)一函數(shù)入?yún)⑹枪善贝a返回一個包含最新價、漲跌幅、近五日收盤價的字典。Agent 只關(guān)心“這個標(biāo)的價格是多少、趨勢怎么樣”這類語義化的問題數(shù)據(jù)獲取的技術(shù)細(xì)節(jié)被完全屏蔽在函數(shù)內(nèi)部。這里要注意免費(fèi)數(shù)據(jù)接口在盤中請求頻率過高容易被臨時限制訪問。我自己踩過這個坑Agent 循環(huán)間隔設(shè)得太短每分鐘去拉一次全列表行情結(jié)果跑了一個多小時數(shù)據(jù)源就返回空數(shù)據(jù)了。后面把輪詢間隔拉長到五分鐘并為接口加了一組備用源切換邏輯是主源返回空數(shù)據(jù)或者連續(xù)超時的時候自動切換。3. 核心模塊一個一個寫模擬撮合、決策循環(huán)和消息推送地基搭好之后就可以開始把系統(tǒng)的五臟六腑填充起來了。這一部分是整個項目工作量最大的地方也是讓我覺得最有收獲的地方。3.1 模擬撮合引擎虛擬資金先跑起來模擬撮合引擎的核心職責(zé)就是讓買賣操作在虛擬資金池里產(chǎn)生真實的成本和盈虧。它不需要跟真實券商系統(tǒng)對接但一定要盡量貼近實際交易的費(fèi)用規(guī)則。我用一個 Python 類實現(xiàn)了最簡版本的模擬券商from dataclasses import dataclass, field from typing import Dict dataclass class Position: symbol: str shares: int avg_cost: float dataclass class MockAccount: cash: float positions: Dict[str, Position] field(default_factorydict) trade_log: list field(default_factorylist) class MockBroker: def __init__(self, initial_cash: float 100000.0): # 初始資金默認(rèn)10萬元純虛擬 self.account MockAccount(cashinitial_cash) def market_buy(self, symbol: str, shares: int, price: float): cost price * shares # 傭金按萬2.5計算不足5元按5元收取 commission max(cost * 0.00025, 5) total_cost cost commission if self.account.cash total_cost: raise RuntimeError(f現(xiàn)金不足無法買入 {symbol}) self.account.cash - total_cost if symbol in self.account.positions: pos self.account.positions[symbol] new_total_shares pos.shares shares # 移動加權(quán)平均成本 pos.avg_cost (pos.avg_cost * pos.shares cost) / new_total_shares pos.shares new_total_shares else: self.account.positions[symbol] Position(symbol, shares, price) self.account.trade_log.append( (買入, symbol, shares, price, commission, 0) ) def market_sell(self, symbol: str, shares: int, price: float): pos self.account.positions.get(symbol) if not pos or pos.shares shares: raise RuntimeError(f持倉不足無法賣出 {symbol}) proceeds price * shares commission max(proceeds * 0.00025, 5) # 印花稅按賣出金額的千分之0.5計算 stamp_tax proceeds * 0.0005 net_proceeds proceeds - commission - stamp_tax self.account.cash net_proceeds pos.shares - shares if pos.shares 0: del self.account.positions[symbol] self.account.trade_log.append( (賣出, symbol, shares, price, commission, stamp_tax) ) def total_assets(self, price_map: Dict[str, float]) - float: stock_value sum( pos.shares * price_map.get(symbol, pos.avg_cost) for symbol, pos in self.account.positions.items() ) return self.account.cash stock_value這個引擎把幾個關(guān)鍵規(guī)則都覆蓋了買入時計算傭金賣出時額外計算印花稅持倉成本用移動加權(quán)平均法計算賬戶權(quán)益等于現(xiàn)金加持倉市值。模擬盤的成本結(jié)構(gòu)和真實交易已經(jīng)非常接近得出的收益曲線也更有參考價值。在真實代碼里我會把交易日志同時寫入一個 CSV 文件保證 Agent 崩潰重啟后還能通過日志恢復(fù)賬戶狀態(tài)。這是模擬盤階段容易被忽略、實盤階段卻非常致命的問題。3.2 決策模塊規(guī)則策略怎么接入 Agent決策模塊是整個系統(tǒng)里最符合“策略”二字的部分。我沒有在一開始就設(shè)計很復(fù)雜的模型而是先用一個基于均線關(guān)系的規(guī)則策略跑通全鏈路。原因很簡單復(fù)雜模型出錯了你很難判斷是策略問題還是系統(tǒng)問題簡單策略則可以讓所有異常都暴露在可解釋的邏輯里。這個策略的邏輯非常樸素對每個監(jiān)控標(biāo)的計算近 5 日均線和近 20 日均線當(dāng) 5 日均線上穿 20 日均線時產(chǎn)生買入信號當(dāng) 5 日均線下穿 20 日均線時產(chǎn)生賣出信號其他情況保持當(dāng)前狀態(tài)不變。def make_decision(kline_list, position_shares): kline_list: 按時間升序排列的收盤價列表 position_shares: 當(dāng)前持倉股數(shù) if len(kline_list) 20: return hold, 數(shù)據(jù)不足 closes [k[close] for k in kline_list] short_ma sum(closes[-5:]) / 5 long_ma sum(closes[-20:]) / 20 if short_ma long_ma and position_shares 0: return buy, f5日均線{short_ma:.2f}上穿20日均線{long_ma:.2f} if short_ma long_ma and position_shares 0: return sell, f5日均線{short_ma:.2f}下穿20日均線{long_ma:.2f} return hold, f均線狀態(tài)無變化short{short_ma:.2f}, long{long_ma:.2f}為什么要把決策邏輯放到一個普通函數(shù)里而不是直接讓大模型自己算均線因為大模型不擅長精確數(shù)值計算讓它算均線既慢又容易出錯。正確的分工是數(shù)值計算交給代碼判斷和調(diào)度交給模型。Agent 的職責(zé)是調(diào)用 make_decision 獲取信號然后把買入或賣出信號翻譯成一次 mock_buy 或 mock_sell 調(diào)用。這個經(jīng)驗是項目中的一個重要轉(zhuǎn)折點。最初我試著讓 Agent 自己做技術(shù)指標(biāo)計算和信號判斷結(jié)果十次里有三次方向是反的而且給出錯誤信號后它還會一本正經(jīng)地生成一段解釋顯得自己特別有道理。后來我把所有需要精確計算的部分全部下沉為工具函數(shù)Agent 只做動作選擇整個系統(tǒng)的可靠性一下子提升了一個臺階。3.3 OpenClaw 任務(wù)循環(huán)讓它自己跑起來OpenClaw 的任務(wù)循環(huán)是這套系統(tǒng)的發(fā)動機(jī)。為了讓 Agent 真正“自主”我們得給它注冊好工具再設(shè)定一個大目標(biāo)讓它在這個目標(biāo)框架內(nèi)循環(huán)決策。工具注冊的關(guān)鍵代碼大致長這樣# 在 OpenClaw 中注冊自定義工具 def register_stock_tools(claw): claw.register_tool( nameget_quote, description獲取指定股票的實時價格和近期K線數(shù)據(jù), parameters{ symbol: {type: string, description: 股票代碼例如 600000} }, funcget_quote, ) claw.register_tool( namemock_buy, description在模擬賬戶中買入指定股票傳入股票代碼和股數(shù), parameters{ symbol: {type: string}, shares: {type: integer, description: 買入股數(shù)必須是100的整數(shù)倍}, }, funcmock_buy, ) claw.register_tool( namemock_sell, description在模擬賬戶中賣出指定股票傳入股票代碼和股數(shù), parameters{ symbol: {type: string}, shares: {type: integer, description: 賣出股數(shù)不能超過當(dāng)前持倉}, }, funcmock_sell, ) claw.register_tool( namepush_feishu, description推送文本消息到飛書群聊, parameters{ text: {type: string, description: 要推送的文本內(nèi)容}, }, funcpush_feishu, )注冊好之后給 Agent 設(shè)置一個總目標(biāo) Prompt。我用的是這個方向的描述“你是一個自主模擬炒股助手。你擁有查詢行情、模擬買入、模擬賣出、推送飛書消息四個工具。你的任務(wù)是每隔一段時間檢查監(jiān)控列表中的標(biāo)的根據(jù)工具返回的數(shù)據(jù)調(diào)用決策函數(shù)判斷買賣信號。每次執(zhí)行買賣后必須調(diào)用推送飛書消息工具把操作內(nèi)容和原因發(fā)送到群里。如果賬戶現(xiàn)金不足或者持倉不足不要重試超過兩次直接把異常信息推送至飛書?!边@個 Prompt 有三個關(guān)鍵設(shè)計明確告訴 Agent 有哪些工具可用避免它自己臆造不存在的函數(shù)。明確要求它“每次執(zhí)行買賣后必須推送消息”用機(jī)制保證可觀測性。明確異常處理方式避免 Agent 陷入無意義的死循環(huán)。OpenClaw 的調(diào)度頻率我是通過外部定時任務(wù)控制的比如每隔 10 分鐘觸發(fā)一次 Agent 運(yùn)行。這是因為大模型 API 調(diào)用本身有延遲和費(fèi)用你不可能讓 Agent 像高頻交易系統(tǒng)一樣每秒跑一次也沒有必要。3.4 飛書消息推送的實現(xiàn)飛書消息推送這塊我前面提到有兩個方案正式版我采用了自定義機(jī)器人應(yīng)用。核心代碼其實就是兩步換 token 和發(fā)消息import requests import time class FeishuClient: def __init__(self, app_id: str, app_secret: str): self.app_id app_id self.app_secret app_secret self.token None self.token_expire_at 0 def _get_token(self) - str: # token 兩小時有效在有效期內(nèi)直接復(fù)用 if self.token and time.time() self.token_expire_at: return self.token resp requests.post( https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal, json{app_id: self.app_id, app_secret: self.app_secret}, timeout10, ) data resp.json() self.token data[tenant_access_token] self.token_expire_at time.time() data.get(expire, 7200) - 60 return self.token def send_text(self, chat_id: str, text: str): token self._get_token() resp requests.post( fhttps://open.feishu.cn/open-apis/im/v1/messages?receive_id_typechat_id, headers{Authorization: fBearer {token}}, json{ receive_id: chat_id, msg_type: text, content: json.dumps({text: text}), }, timeout10, ) return resp.json()這里有一個飛書 API 的細(xì)節(jié)content 字段必須是一個字符串化的 JSON直接傳字典會被接口拒絕。我第一次接入時在這里卡了快二十分鐘一直報參數(shù)錯誤后來仔細(xì)查文檔才發(fā)現(xiàn)這個坑。把推送功能接好后我讓 Agent 在消息里用固定格式輸出比如【模擬交易】買入 600000 浦發(fā)銀行 200股 成交價格10.25 觸發(fā)原因5日均線上穿20日均線 賬戶剩余現(xiàn)金98620.50固定格式好處非常多它讓歷史記錄更容易追溯而且你掃一眼飛書消息就能判斷 Agent 行為是否正常不需要逐行翻日志。4. 從模擬盤到實盤我踩過的坑和過渡清單模擬盤和實盤之間的距離比大多數(shù)人想象中要遠(yuǎn)得多。模擬盤里跑出的漂亮收益曲線換成實盤后可能會因為各種微小差異而面目全非。我把自己一路從模擬切到實盤的過程整理成下面幾個要點。4.1 模擬盤驗證的重點指標(biāo)模擬盤階段最重要的事情不是看收益有多高而是驗證系統(tǒng)在長時間運(yùn)行下能不能保持穩(wěn)定。我給自己定了四個核心驗證指標(biāo)連續(xù)運(yùn)行時長系統(tǒng)是否能連續(xù)運(yùn)行一兩周不崩潰、不卡死。Agent 框架、數(shù)據(jù)源接口、消息推送任何一個環(huán)節(jié)掉鏈子都會中斷自主交易。操作可追溯性每一筆模擬交易的觸發(fā)原因、成交價格、費(fèi)用明細(xì)是否完整記錄。不可追溯的操作等于沒有發(fā)生。信號執(zhí)行一致性Agent 是否嚴(yán)格按決策模塊的信號執(zhí)行有沒有出現(xiàn)信號是買入、結(jié)果卻變成賣出的情況。異常自恢復(fù)能力數(shù)據(jù)源超時、接口限流、飛書 token 過期這類常見故障發(fā)生后系統(tǒng)能否自動恢復(fù)并在下個周期繼續(xù)正常工作。模擬盤階段如果把這四個指標(biāo)練扎實了切換實盤時心里會稍微有底一些。4.2 實盤接入的注意事項實盤接入并不是簡單地?fù)Q一個真實賬戶接口就完事了。它涉及券商選擇、接口權(quán)限申請、資金劃轉(zhuǎn)、風(fēng)控參數(shù)配置等一系列環(huán)節(jié)。首先任何實盤操作都必須通過券商官方提供的量化交易接口或者合法合規(guī)的交易軟件進(jìn)行。個人開發(fā)者對接實盤時優(yōu)先找支持這種接入方式的券商開戶的時候直接咨詢量化接口的開通條件。我這邊最終用的是一個支持 Python 接口的量化柜臺申請通過后券商提供一個獨(dú)立的資金賬號這個賬號和你平時用的交易賬號隔離可以單獨(dú)設(shè)置交易權(quán)限和資金上限。其次安全方面有一個容易忽視的細(xì)節(jié)API 密鑰和賬號信息絕對不能寫在代碼里或者提交到代碼倉庫。我自己專門在服務(wù)器上配置了一個環(huán)境變量文件權(quán)限設(shè)置為只有運(yùn)行用戶可讀程序啟動時從環(huán)境變量加載賬號信息。實盤下單前還有一個必須做的動作在券商的客戶端里手動設(shè)置風(fēng)控參數(shù)包括單筆最大委托金額、單日最大委托次數(shù)、最大持倉數(shù)量等。這些限制是資金安全的最后一道防線萬一 Agent 或代碼出現(xiàn)邏輯失控券商的系統(tǒng)會自動攔截異常委托。4.3 風(fēng)控清單我把實盤階段必須做到的風(fēng)控項做成了一份清單每次調(diào)整系統(tǒng)后我都會對著清單過一遍資金額度實盤賬戶只放總資金的一小部分比例設(shè)定到即使全部虧完也不會影響生活的水平。人工熔斷開關(guān)在飛書群里預(yù)留一個指令比如“緊急暫?!盇gent 收到后立即停止所有后續(xù)操作。這個功能對 Agent 來說是一種安全繩。操作限額在模擬撮合引擎之外再加一層實盤專用的參數(shù)校驗任何單筆金額超過設(shè)定上限的委托都會直接拒絕。盯盤閾值設(shè)置一個最大單日虧損百分比觸發(fā)后自動停止當(dāng)日后續(xù)交易。賬號隔離實盤賬戶和測試賬戶的憑據(jù)嚴(yán)格分開避免誤操作把測試代碼發(fā)到實盤。日志備份每一筆實盤委托和回報都同步寫入數(shù)據(jù)庫且每 5 分鐘做一次增量備份。這個清單不是萬能的但它能把最壞情況造成的損失控制在可接受范圍內(nèi)。5. 常見問題與排查思路實錄整個項目開發(fā)和運(yùn)行期間我記錄了一批典型問題。我把它們整理成一份問題速查表形式方便你直接對照排查?,F(xiàn)象可能原因排查步驟與解決方案Agent 長時間無響應(yīng)大模型 API 網(wǎng)絡(luò)不通或配置錯誤先手動調(diào)用一次模型接口確認(rèn)連通性再查看 Agent 日志中最后一次請求的狀態(tài)碼飛書機(jī)器人發(fā)不出消息token 過期或 chat_id 錯誤檢查 token 刷新邏輯用飛書 Open API 調(diào)試工具手工發(fā)一條消息定位問題行情數(shù)據(jù)突然為空免費(fèi)數(shù)據(jù)源被限流或網(wǎng)絡(luò)異常檢查接口返回的字段切換備用數(shù)據(jù)源并適當(dāng)降低請求頻率Agent 重復(fù)執(zhí)行同一買入操作狀態(tài)記錄缺失導(dǎo)致重復(fù)決策檢查賬戶狀態(tài)是否持久化確保 Agent 每次讀到的都是最新持倉模擬賬戶現(xiàn)金變成負(fù)數(shù)買入前未檢查可用資金在 mock_buy 里增加資金校驗并在異常時通過推送通知人工處理實盤委托被券商拒絕超出券商設(shè)置的風(fēng)控閾值查看券商客戶端內(nèi)的委托拒單原因調(diào)整 Agent 參數(shù)或券商風(fēng)控配置還有幾個排查經(jīng)驗比較瑣碎但對效率影響很大。第一日志必須帶時間戳和工具名。Agent 執(zhí)行鏈路長沒有時間戳的日志在排障時幾乎是廢的。我自己后來在 OpenClaw 里給每個工具調(diào)用都包了一層裝飾器自動記錄調(diào)用時間、入?yún)ⅰ⒊鰠⒑秃臅r。第二異常不要靜默吞掉。最初我在一些接口調(diào)用上用了 try except 加 pass結(jié)果系統(tǒng)看起來一切正常實際上已經(jīng)好幾天沒有執(zhí)行任何交易了。正確的做法是任何異常都要推送飛書即使不影響主流程也要讓你知道系統(tǒng)發(fā)生了異常。第三模擬盤數(shù)據(jù)輸出格式要穩(wěn)定。行情接口偶爾會返回缺失字段如果程序直接拋異?;蜉敵龈袷絹y七八糟Agent 的決策質(zhì)量會急劇劣化。解決方案是寫一個統(tǒng)一的數(shù)據(jù)清洗函數(shù)所有數(shù)據(jù)源返回后先過清洗邏輯再交給 Agent。第四升級代碼前一定要備份當(dāng)前狀態(tài)。模擬盤階段還好實盤階段任何一個代碼變更都要先在測試環(huán)境完整跑一遍確認(rèn)沒有副作用后再部署到實盤。我在實盤系統(tǒng)上線前的最后一次演練是把所有異常情況都主動觸發(fā)了一遍斷掉行情接口、偽造飛書 token 過期、給模擬引擎造資金不足的假數(shù)據(jù)然后記錄了系統(tǒng)每個環(huán)節(jié)的反應(yīng)。這套故障演練方法比修好任何一個具體 bug 都更有價值因為它能驗證整個系統(tǒng)的韌性。最后再分享一點個人體會。做 AI 自主交易系統(tǒng)最容易踩的坑是過分崇拜 Agent 的能力。大模型確實擅長理解和生成但它完全不擅長精確計算和紀(jì)律執(zhí)行而交易系統(tǒng)偏偏對精確和紀(jì)律要求極高。把這兩者的優(yōu)勢結(jié)合起來讓模型負(fù)責(zé)判斷和交互讓代碼負(fù)責(zé)計算和執(zhí)行這套系統(tǒng)才能走得遠(yuǎn)。我現(xiàn)在每天還是會翻一遍飛書群里的交易記錄看看 Agent 的行為是否合乎預(yù)期。這不是不信任它而是作為系統(tǒng)的負(fù)責(zé)人你永遠(yuǎn)需要保留對系統(tǒng)行為的最終解釋權(quán)和掌控權(quán)。