態(tài)敞口控制的加密貨幣自動(dòng)對(duì)沖系統(tǒng)設(shè)計(jì)與實(shí)戰(zhàn))
做量化或者做合約交易的朋友應(yīng)該都體會(huì)過那種感覺行情方向看對(duì)了持倉也賺到了錢但中間那一波深V回調(diào)直接把人震出局或者現(xiàn)貨拿著重倉心里明明知道接下來可能有大波動(dòng)卻不知道怎么在不賣掉幣的前提下降低風(fēng)險(xiǎn)。我開發(fā) AutoHedge 這套自動(dòng)對(duì)沖工具就是為了解決這類持倉風(fēng)險(xiǎn)管理的痛點(diǎn)。它在每個(gè)交易周期自動(dòng)計(jì)算當(dāng)前賬戶的凈敞口當(dāng)風(fēng)險(xiǎn)超過設(shè)定閾值時(shí)直接在合約市場建立反向頭寸來對(duì)沖現(xiàn)貨波動(dòng)整個(gè)過程不需要人工盯盤代碼跑起來之后會(huì)自動(dòng)執(zhí)行、自動(dòng)調(diào)整、自動(dòng)記錄。今天想把它從策略設(shè)計(jì)到落地部署的完整過程寫出來算是給自己做個(gè)階段性復(fù)盤也給正在琢磨自動(dòng)對(duì)沖這套玩法的朋友提供一個(gè)可以直接抄作業(yè)的參考。市面上講“對(duì)沖”的文章不少但大多停留在概念層面真正把系統(tǒng)架構(gòu)、參數(shù)調(diào)優(yōu)、異常處理這些工程細(xì)節(jié)講透的不多。這篇文章會(huì)從策略原理講起一直聊到代碼實(shí)現(xiàn)、回測驗(yàn)證、上線部署以及我在調(diào)試過程中踩過的坑。無論你是剛接觸量化交易的新手還是已經(jīng)在手工做對(duì)沖但想自動(dòng)化的交易者相信都能從中找到有用的一塊。1. 先說說為什么我會(huì)做 AutoHedge 這個(gè)東西1.1 每個(gè)交易者都會(huì)碰到的“過山車”問題我在很長一段時(shí)間里都是純手工交易現(xiàn)貨拿著幣偶爾開一點(diǎn)合約空單來做保護(hù)。最典型的場景是這樣的賬戶里持有 10 個(gè)比特幣成本大概是 6 萬附近行情一路上行到 6.8 萬浮盈很舒服可某天一根大陰線直接砸到 6.2 萬利潤回吐大半。這時(shí)候我面臨一個(gè)艱難選擇賣掉現(xiàn)貨可能后面反彈踏空不賣吧又怕繼續(xù)跌。于是我想著開個(gè)空單對(duì)沖結(jié)果等我把合約賬戶打開、計(jì)算好數(shù)量、掛單成交行情已經(jīng)又拉回去了。這種滯后讓我非常沮喪。手工對(duì)沖最大的痛點(diǎn)就是“反應(yīng)太慢”。人需要盯盤、判斷、下單整個(gè)流程下來至少一兩分鐘而對(duì)加密貨幣這種波動(dòng)率極高的市場五分鐘之內(nèi)完全可能走完一波幾千美金的行情。更麻煩的是對(duì)沖之后還需要根據(jù)行情變化不斷調(diào)整空單數(shù)量比如現(xiàn)貨漲了空單虧錢要及時(shí)止損或加倉這個(gè)過程特別消耗精力幾乎等于全職盯盤。1.2 為什么手工對(duì)沖總是做不好很多人以為對(duì)沖就是“開個(gè)空單”那么簡單但實(shí)際操作里問題一堆。第一數(shù)量怎么定傳統(tǒng)教科書里說 1:1 對(duì)沖我有 10 個(gè)比特幣現(xiàn)貨那就開 10 個(gè)比特幣的空單。但在實(shí)際行情里現(xiàn)貨和合約之間往往存在基差也就是現(xiàn)貨價(jià)格和合約價(jià)格不完全同步如果完全按 1:1 來很可能過度對(duì)沖或者對(duì)沖不足。第二什么時(shí)機(jī)對(duì)沖有人選擇在跌破某個(gè)支撐位時(shí)對(duì)沖有人選擇在市場波動(dòng)率突然飆升時(shí)對(duì)沖但人工判斷情緒化因素太重容易猶豫容易“等再看一眼”。第三對(duì)沖之后怎么退出行情恢復(fù)了要不要平掉空單這個(gè)問題不同人做法差異極大很多人的對(duì)沖單最后從“保險(xiǎn)”變成了一個(gè)虧損頭寸。我把這些問題反復(fù)想了很多遍結(jié)論是既然對(duì)沖的邏輯可以完全用規(guī)則描述那么規(guī)則就可以寫成代碼。市場開了多少倉位、賬戶里有多少現(xiàn)貨、最近的波動(dòng)率是多少、資金費(fèi)率是不是有異常這些數(shù)據(jù)都可以通過交易所 API 實(shí)時(shí)獲取。只要設(shè)定好規(guī)則機(jī)器執(zhí)行一定比人可靠得多。這個(gè)念頭就是 AutoHedge 的起點(diǎn)。1.3 AutoHedge 的整體定位AutoHedge 說白了就是一個(gè)運(yùn)行在云端服務(wù)器上的自動(dòng)化風(fēng)險(xiǎn)管理引擎專門負(fù)責(zé)一件事讓賬戶總敞口始終保持在一個(gè)可容忍的范圍內(nèi)。它的工作流程不復(fù)雜定時(shí)讀取交易所的資產(chǎn)余額、持倉信息、行情價(jià)格然后根據(jù)預(yù)設(shè)的策略模型計(jì)算當(dāng)前的風(fēng)險(xiǎn)敞口如果敞口超過安全閾值就自動(dòng)在合約市場下單對(duì)沖如果敞口回到安全范圍內(nèi)就自動(dòng)平掉多余的對(duì)沖倉位。整個(gè)過程不需要人工干預(yù)。這個(gè)工具適合兩類人一類是手里拿著大量現(xiàn)貨、又不想整天盯盤的長期持有者希望通過自動(dòng)對(duì)沖來降低回撤另一類是正在做量化策略、但策略本身不對(duì)沖市場風(fēng)險(xiǎn)的人可以把 AutoHedge 當(dāng)作一個(gè)獨(dú)立的風(fēng)控模塊掛在旁邊。我自己顯然屬于第一類后面會(huì)詳細(xì)講我是怎么配置參數(shù)、怎么驗(yàn)證效果的。2. 自動(dòng)對(duì)沖到底在做什么策略原理與設(shè)計(jì)思路2.1 對(duì)沖策略的三種主流玩法在設(shè)計(jì) AutoHedge 之前我把市面上常見的對(duì)沖策略梳理了一遍總結(jié)下來主要有三條路線。第一種是期貨套保也就是現(xiàn)貨持有者在合約市場持有相反方向的頭寸。假設(shè)我持有 10 個(gè) BTC 現(xiàn)貨那么在合約市場開 10 個(gè) BTC 空單無論價(jià)格上漲還是下跌現(xiàn)貨和合約兩邊一虧一賺總資產(chǎn)基本恒定。這種方式最簡單但缺點(diǎn)也很明顯完全對(duì)沖等于放棄了上漲收益在牛市中你會(huì)非常痛苦所以實(shí)際應(yīng)用中很少人做 100% 對(duì)沖而是做部分對(duì)沖。第二種是期權(quán)對(duì)沖通過購買看跌期權(quán)來為現(xiàn)貨提供下跌保護(hù)只要支付一筆權(quán)利金就能在下行時(shí)獲得賠償同時(shí)保留上行收益。這個(gè)思路理論最優(yōu)但加密市場的期權(quán)流動(dòng)性還不夠好尤其是一些山寨幣幾乎沒有像樣的期權(quán)市場。第三種是資金費(fèi)率套利也稱永續(xù)合約套利。永續(xù)合約有個(gè)資金費(fèi)率機(jī)制每 8 小時(shí)多空雙方互相支付一次費(fèi)用。當(dāng)市場極度看多時(shí)資金費(fèi)率為正多頭給空頭付錢這時(shí)候現(xiàn)貨持幣加合約做空相當(dāng)于既對(duì)沖了價(jià)格波動(dòng)又能賺取資金費(fèi)。這套策略在趨勢性上漲行情里相當(dāng)舒服。權(quán)衡了實(shí)現(xiàn)難度和我的實(shí)際需求后AutoHedge 核心采用第一種思路也就是“動(dòng)態(tài)比率期貨對(duì)沖”并吸收了一部分資金費(fèi)率判斷邏輯把它做成一個(gè)調(diào)節(jié)信號(hào)而不是獨(dú)立的盈利策略。2.2 我選擇的核心算法動(dòng)態(tài)敞口控制系統(tǒng)最核心的算法可以用一條非常簡單的公式來描述對(duì)沖數(shù)量 現(xiàn)貨持倉數(shù)量 × 目標(biāo)對(duì)沖比例 × 當(dāng)前價(jià)差修正系數(shù)其中目標(biāo)對(duì)沖比例是整個(gè)系統(tǒng)的“靈魂”。它不是一個(gè)固定值而是會(huì)根據(jù)市場狀態(tài)自動(dòng)變化。我的設(shè)計(jì)思路是這樣的市場處于正常波動(dòng)狀態(tài)時(shí)只做 40% 左右的部分對(duì)沖給行情留出足夠的上行空間當(dāng)檢測到波動(dòng)率顯著放大時(shí)比如近 7 天的日均振幅超過前 30 天日均振幅的 1.5 倍時(shí)系統(tǒng)會(huì)把對(duì)沖比例自動(dòng)上調(diào)到 70%先保住本金再說如果行情穩(wěn)定下來波動(dòng)率回落對(duì)沖比例再逐步降回去。這套邏輯后來被我用一個(gè)簡單的配置項(xiàng)實(shí)現(xiàn)了核心是base_hedge_ratio和vol_adjust_factor兩個(gè)參數(shù)。為什么要做動(dòng)態(tài)而不是固定比例對(duì)沖我拿歷史數(shù)據(jù)做過對(duì)比測試。假設(shè)在 2023 年的一段震蕩行情里如果用固定 50% 對(duì)沖整段收益基本是橫盤雖然沒虧但也沒賺資金利用率很差而動(dòng)態(tài)策略因?yàn)槟茈S著波動(dòng)率升高而加大保護(hù)、隨著行情重新走強(qiáng)而降低對(duì)沖比例最后還跑出了比純現(xiàn)貨略高一截的收益同時(shí)最大回撤明顯低于純現(xiàn)貨。這個(gè)對(duì)比讓我下定決心一定要做動(dòng)態(tài)調(diào)節(jié)而不是偷懶用一個(gè)固定值。2.3 關(guān)鍵參數(shù)解讀與計(jì)算邏輯AutoHedge 的配置參數(shù)里有四個(gè)參數(shù)是決定系統(tǒng)性格的關(guān)鍵我逐個(gè)說一下我的取值邏輯。target_delta表示期望的賬戶貝塔敞口也就是你希望賬戶凈值對(duì)市場價(jià)格變化有多敏感。你如果希望完全中性這個(gè)值設(shè)為 0如果你希望保留一點(diǎn)看漲屬性可以設(shè)為 0.3。我的經(jīng)驗(yàn)是長期持有現(xiàn)貨的人都舍不得完全放棄上漲收益建議設(shè)一個(gè) 0.2 到 0.4 的值。hedge_freq_minutes是對(duì)沖檢查頻率默認(rèn) 15 分鐘。這個(gè)值不是越短越好因?yàn)榻灰姿?API 調(diào)用有頻率限制而且過于頻繁地對(duì)沖會(huì)產(chǎn)生大量手續(xù)費(fèi)和滑點(diǎn)損耗。我實(shí)測 5 分鐘頻率和 15 分鐘頻率在保護(hù)效果上幾乎無差別但手續(xù)費(fèi)累計(jì)差別很大所以最終取了 15 分鐘。trigger_threshold是觸發(fā)閾值也就是實(shí)際敞口與目標(biāo)敞口的偏差超過多少時(shí)系統(tǒng)才行動(dòng)。我默認(rèn)設(shè)為 0.05意思是只有當(dāng)偏差達(dá)到 5% 以上時(shí)才會(huì)調(diào)整對(duì)沖倉位。這個(gè)值設(shè)得太小會(huì)頻繁操作太大保護(hù)不及時(shí)5% 是我回測后覺得比較平衡的點(diǎn)。vol_lookback_days是波動(dòng)率計(jì)算的回看窗口默認(rèn) 30 天。計(jì)算方式是取過去 30 天每日收益率的標(biāo)準(zhǔn)差再乘以 sqrt(365) 年化用來衡量當(dāng)前市場整體的波動(dòng)水平。有了這個(gè)值系統(tǒng)才能決定要不要上調(diào)對(duì)沖比例。參數(shù)這塊我用了一個(gè)很接地氣的類比來理解如果把賬戶比作花園target_delta 是花園的日照時(shí)間hedge_freq_minutes 是澆水頻率trigger_threshold 是澆水的水量下限vol_lookback_days 則是你觀察天氣的天數(shù)。四者配合得好花園才既能長得快又不會(huì)被曬死。3. 系統(tǒng)架構(gòu)與核心技術(shù)選型3.1 整體模塊劃分AutoHedge 的代碼結(jié)構(gòu)我把它分成了四個(gè)相對(duì)獨(dú)立的模塊行情采集模塊、策略計(jì)算模塊、訂單執(zhí)行模塊和風(fēng)控模塊。每個(gè)模塊之間通過隊(duì)列傳遞 JSON 消息模塊崩了會(huì)自動(dòng)重啟不會(huì)影響其他模塊運(yùn)行。行情采集模塊負(fù)責(zé)從交易所拉取實(shí)時(shí)行情、持倉、資產(chǎn)余額等信息。策略計(jì)算模塊拿到行情后套用上一章講的敞口計(jì)算公式輸出“開空多少張”“平空多少張”的指令。訂單執(zhí)行模塊負(fù)責(zé)把指令拆成具體訂單發(fā)到交易所同時(shí)處理撤單、重試、部分成交等異常情況。風(fēng)控模塊則像一個(gè)監(jiān)督者每輪操作前都會(huì)檢查當(dāng)前整體倉位、委托單數(shù)量、資金使用率是否在安全范圍內(nèi)一旦發(fā)現(xiàn)異常會(huì)直接凍結(jié)所有交易只允許平倉不允許開倉。這四個(gè)模塊用 Python 語言實(shí)現(xiàn)Python 的數(shù)據(jù)處理和回測生態(tài)非常成熟寫起原型來很快生產(chǎn)環(huán)境上我用了 asyncio 并發(fā)框架保證多個(gè)交易所請(qǐng)求可以并行發(fā)出不需要等待前一個(gè)回來才發(fā)下一個(gè)。3.2 行情與執(zhí)行層為什么選 WebSocket 而不是輪詢這是我在開發(fā)過程中一個(gè)比較關(guān)鍵的選型。最早我做了一個(gè)最簡單的輪詢版每 15 秒調(diào)用一次 REST API 獲取行情發(fā)現(xiàn)兩個(gè)問題一是延遲高行情變化和代碼感知之間存在好幾秒的間隔這在波動(dòng)劇烈的時(shí)刻非常被動(dòng)二是會(huì)被交易所限頻很多交易所的 REST API 接口有每秒 10 次的硬限制輪詢頻率稍微調(diào)上去就容易觸發(fā) 429 錯(cuò)誤。后來我把行情模塊整體改成 WebSocket 連接。WebSocket 是長連接模式服務(wù)器主動(dòng)往客戶端推送數(shù)據(jù)行情一來就能立刻收到延遲降到毫秒級(jí)而且不需要頻繁發(fā)起請(qǐng)求根本不占 REST API 額度。這個(gè)改動(dòng)對(duì)系統(tǒng)整體體驗(yàn)提升非常明顯行情推送過來的響應(yīng)速度快了策略計(jì)算的時(shí)延自然就低了。執(zhí)行層下單則仍然使用 REST API因?yàn)橄聠涡袨楸旧硎堑皖l的15 分鐘才一次不需要實(shí)時(shí)長連接。而且 REST 下單有明確的請(qǐng)求響應(yīng)出了錯(cuò)誤容易定位回執(zhí)清晰適合對(duì)可靠性要求高的場景。我的原則是讀數(shù)據(jù)走 WebSocket寫操作用 REST兩者各司其職。3.3 風(fēng)險(xiǎn)控制層的三道閘門很多做量化的人早期都吃過“策略失控”的虧我讓 AutoHedge 只負(fù)責(zé)對(duì)沖但風(fēng)控方面一點(diǎn)也不省。風(fēng)控模塊里我設(shè)計(jì)了三道防線這一塊值得單獨(dú)拿出來說。第一道閘門是最大下單數(shù)量限制任何一次對(duì)沖指令的合約數(shù)量不得大于當(dāng)前現(xiàn)貨持倉的 120%。這個(gè)限制主要是防止策略計(jì)算出現(xiàn) bug 時(shí)系統(tǒng)一次性把倉位開到超出本身需要的量。第二道閘門是資金費(fèi)率監(jiān)控每次下單前檢查當(dāng)前永續(xù)合約的資金費(fèi)率如果資金費(fèi)率突然出現(xiàn)超過 0.3% 的極端值系統(tǒng)會(huì)暫停對(duì)沖操作并彈出告警。因?yàn)闃O端資金費(fèi)率通常意味著市場情緒過熱或異常這時(shí)候按常規(guī)邏輯操作容易接到市場的反向一巴掌。第三道閘門是熔斷機(jī)制如果連續(xù) 5 次下單都失敗比如交易所接口超時(shí)、余額不足或網(wǎng)絡(luò)故障系統(tǒng)會(huì)停止所有新訂單操作進(jìn)入手動(dòng)恢復(fù)模式并且通過飛書或 Telegram 機(jī)器人把詳細(xì)錯(cuò)誤日志推送給我。這三道閘門讓我敢在睡覺時(shí)讓系統(tǒng)開著不擔(dān)心半夜突然失控。值得一提的是風(fēng)控模塊和策略模塊在進(jìn)程級(jí)別做了隔離即使策略模塊崩潰風(fēng)控模塊依然能獨(dú)立地監(jiān)控賬戶情況。4. 實(shí)操從零部署一套 AutoHedge4.1 環(huán)境準(zhǔn)備與交易所 API 對(duì)接先說一下部署環(huán)境。我用的是海外云服務(wù)器系統(tǒng)選 Ubuntu 22.042 核 4G 內(nèi)存跑 AutoHedge 完全夠用。Python 版本要求 3.9 以上依賴庫主要有ccxt、pandas、numpy、websockets、asyncio。ccxt 這個(gè)庫強(qiáng)烈推薦給所有做加密量化的人它統(tǒng)一封裝了上百家交易所的 API 接口寫法完全一致?lián)Q交易所只需要改一行配置。交易所 API 對(duì)接有幾個(gè)安全習(xí)慣必須養(yǎng)成第一API Key 只開“現(xiàn)貨交易”和“合約交易”權(quán)限千萬別開“提現(xiàn)”權(quán)限第二為了限制風(fēng)險(xiǎn)最好在交易所后臺(tái)綁定 IP 白名單只允許部署 AutoHedge 的服務(wù)器 IP 訪問第三API Key 的密鑰要放在環(huán)境變量或獨(dú)立配置文件里不能硬編碼在代碼中更不要把密鑰提交到 Git 倉庫。配置這里再多說一句很多人會(huì)把密鑰寫在.env文件里然后不小心把.env提交到公開倉庫。我見過不少因此被搬走資金的例子所以項(xiàng)目一初始化就應(yīng)該在.gitignore里加上.env最好再對(duì)密鑰做一次加密存儲(chǔ)運(yùn)行時(shí)解密加載。4.2 配置文件的含義與推薦參數(shù)AutoHedge 的主配置采用 YAML 格式我把核心配置項(xiàng)列一下每個(gè)都附上說明和推薦值配置項(xiàng)含義推薦值exchange_id交易所名稱binance_usdt示例symbol交易對(duì)BTC/USDTtarget_delta目標(biāo)賬戶貝塔敞口0.25base_hedge_ratio基礎(chǔ)對(duì)沖比例0.45trigger_threshold觸發(fā)調(diào)整的偏差閾值0.05hedge_freq_minutes對(duì)沖檢查間隔15max_order_ratio單次最大下單占比0.3vol_lookback_days波動(dòng)率回看天數(shù)30market_score_limit風(fēng)險(xiǎn)評(píng)分上限80notify_channel告警渠道telegram這些參數(shù)里market_score_limit是我比較得意的一個(gè)設(shè)計(jì)。系統(tǒng)會(huì)綜合當(dāng)前賬戶浮虧比例、波動(dòng)率、資金費(fèi)率這三個(gè)維度打出一個(gè) 0 到 100 的市場風(fēng)險(xiǎn)評(píng)分平時(shí)策略正常滾不需要管但一旦評(píng)分超過 80系統(tǒng)就會(huì)進(jìn)入防御模式把所有對(duì)沖比例強(qiáng)制拉到 80%寧可少賺不可大虧。這個(gè)評(píng)分機(jī)制讓我不用實(shí)時(shí)盯盤只需要在收到告警時(shí)看一眼發(fā)生了什么。4.3 回測流程與真實(shí)數(shù)據(jù)驗(yàn)證上線之前我做了一個(gè)比較完整的回測。數(shù)據(jù)源用的是交易所的歷史 1 分鐘 K 線回測區(qū)間覆蓋了一段明顯的上漲周期、一段下跌周期和一段震蕩周期大致是 2023 年 10 月到 2024 年 2 月差不多五個(gè)月。這個(gè)區(qū)間的行情形態(tài)非常全面很適合驗(yàn)證動(dòng)態(tài)對(duì)沖邏輯?;販y的代碼邏輯不復(fù)雜核心就是按每分鐘步進(jìn)讀取當(dāng)前價(jià)格和數(shù)據(jù)計(jì)算當(dāng)前組合的市值判斷是否需要調(diào)整對(duì)沖倉位記錄每一次調(diào)倉記錄。最終輸出凈值曲線和各項(xiàng)績效指標(biāo)。我的回測結(jié)果大致如下指標(biāo)純現(xiàn)貨策略固定 50% 對(duì)沖AutoHedge 動(dòng)態(tài)對(duì)沖總收益率35.8%18.2%29.6%最大回撤22.4%9.8%7.6%夏普比率1.421.111.89交易次數(shù)01237從表里能看出一個(gè)很有意思的事實(shí)固定 50% 對(duì)沖策略雖然把最大回撤從 22.4% 降到了 9.8%但收益幾乎砍半而 AutoHedge 動(dòng)態(tài)對(duì)沖把回撤控制在了 7.6% 的最低水平同時(shí)收益只比純現(xiàn)貨少 6 個(gè)點(diǎn)。代價(jià)是交易次數(shù)變多產(chǎn)生了更多手續(xù)費(fèi)但這 37 次交易按本金比例折算手續(xù)費(fèi)總成本不到 1%換來 15 個(gè)點(diǎn)的回撤改善我認(rèn)為完全值得?;販y中我也發(fā)現(xiàn)動(dòng)態(tài)策略在“單邊快速上漲行情”里收益會(huì)明顯跑輸純現(xiàn)貨因?yàn)樵谶@樣的行情里系統(tǒng)總是保留一部分對(duì)沖空單這部分空單會(huì)不斷虧損拖累凈值。但這就是對(duì)沖的本質(zhì)用一部分潛在收益換取安全性。想清楚了這一點(diǎn)就不會(huì)在行情大漲時(shí)抱怨“我怎么少賺了”。5. 踩坑實(shí)錄與常見問題排查5.1 我踩過的五個(gè)坑AutoHedge 從代碼寫完到穩(wěn)定運(yùn)行中間大概經(jīng)歷了兩個(gè)多月的調(diào)試期踩過的坑能列一長串。我挑五個(gè)最有代表性的說說希望能幫有同樣想法的朋友繞開。第一個(gè)坑是精度問題。交易所的合約數(shù)量和價(jià)格都有精度限制例如 BTC 合約數(shù)量最小變動(dòng) 0.001 張價(jià)格最小變動(dòng) 0.1 USDT。我在算法里算出要開空 0.2357 張直接下單到交易所就會(huì)被拒絕提示精度不對(duì)。后來做了精度對(duì)齊函數(shù)下單前先把數(shù)量向下取整到合法精度再把超出部分算入下一次調(diào)整。這個(gè)坑非?;A(chǔ)但新手十有八九會(huì)踩。第二個(gè)坑是未實(shí)現(xiàn)盈虧的計(jì)算方式。最開始我根據(jù)合約數(shù)量和標(biāo)記價(jià)格估算組合的總資產(chǎn)但發(fā)現(xiàn)回測和實(shí)盤對(duì)不上。后來才意識(shí)到合約賬戶有未實(shí)現(xiàn)盈虧、保證金、持倉均價(jià)這些概念精確的總資產(chǎn)應(yīng)該是“現(xiàn)貨市值 合約賬戶權(quán)益”而合約賬戶權(quán)益 錢包余額 未實(shí)現(xiàn)盈虧。把這個(gè)模型修正后計(jì)算才準(zhǔn)確起來。第三個(gè)坑是 API 返回的時(shí)間戳和本地時(shí)間不同步。有一度系統(tǒng)在整點(diǎn)附近的下單邏輯總是出現(xiàn)偏差排查了很久發(fā)現(xiàn)交易所返回的時(shí)間戳是 UTC而本地服務(wù)器在東八區(qū)整整差了 8 個(gè)小時(shí)。這個(gè)問題直接導(dǎo)致部分行情對(duì)齊邏輯錯(cuò)亂。解決辦法很簡單統(tǒng)一約定所有內(nèi)部數(shù)據(jù)都用 UTC 時(shí)間展示給用戶時(shí)才轉(zhuǎn)成本地時(shí)間。第四個(gè)坑是回調(diào)函數(shù)的異常吞噬。WebSocket 連接在極端情況會(huì)靜默斷開斷線后如果沒有重連機(jī)制系統(tǒng)會(huì)一直卡在“以為連接還在”的狀態(tài)行情不再更新策略自然也就失效。后來我實(shí)現(xiàn)了一個(gè)心跳檢測機(jī)制每 30 秒檢測一次連接狀態(tài)發(fā)現(xiàn)異常自動(dòng)重連并補(bǔ)拉斷線期間的歷史數(shù)據(jù)這個(gè)問題才徹底解決。第五個(gè)坑是下單后沒有做“成交檢測”。接入初期我下單成功后直接登記狀態(tài)但有些時(shí)候訂單可能未能成交比如價(jià)格快速偏離導(dǎo)致掛單被動(dòng)掛起。系統(tǒng)以為已經(jīng)完成對(duì)沖實(shí)際上倉位根本沒建起來風(fēng)險(xiǎn)提示自然失真。后來我在下單后增加了一個(gè)輪詢確認(rèn)步驟最多等 3 秒如果未成交就撤單改以市價(jià)單重新執(zhí)行。5.2 常見錯(cuò)誤碼與排查速查表為了方便排障我把 AutoHedge 運(yùn)行中出現(xiàn)的典型錯(cuò)誤碼整理成了一張速查表這一張表在我調(diào)試期幫了大忙錯(cuò)誤碼含義解決方法E1001行情連接超時(shí)檢查網(wǎng)絡(luò)確認(rèn) WebSocket 地址是否需要代接E1002持倉余額查詢失敗檢查 API Key 權(quán)限重啟行情模塊E2001參數(shù)校驗(yàn)失敗檢查配置項(xiàng)數(shù)值范圍如 ratio 超出 0~1E2005波動(dòng)率計(jì)算失敗檢查歷史數(shù)據(jù)是否為空K 線獲取接口是否受限E3001下單精度錯(cuò)誤調(diào)用精度對(duì)齊函數(shù)向下取整E3003訂單未成交撤單后轉(zhuǎn)用市價(jià)單確認(rèn)保證金充足E4001觸發(fā)熔斷保護(hù)檢查日志里的連續(xù)失敗原因修復(fù)后手動(dòng)恢復(fù)排查這些問題時(shí)我建議所有運(yùn)行日志都要帶時(shí)間戳和上下文參數(shù)比如下單失敗時(shí)要把當(dāng)時(shí)的合約數(shù)量、價(jià)格、賬戶余額全部打出來。否則出了錯(cuò)誤還要人肉猜測現(xiàn)場情況排查效率極低。AutoHedge 的日志記錄部分是整個(gè)項(xiàng)目里代碼量最多的模塊但絕對(duì)是值得的。5.3 上線穩(wěn)定運(yùn)行的一個(gè)小技巧系統(tǒng)上線穩(wěn)定運(yùn)行之后我養(yǎng)成了每天定時(shí)查看運(yùn)行報(bào)告的習(xí)慣相當(dāng)于給系統(tǒng)做一次“體檢”。每天零點(diǎn)AutoHedge 會(huì)把當(dāng)天的凈值變化、對(duì)沖操作次數(shù)、手續(xù)費(fèi)消耗、風(fēng)險(xiǎn)評(píng)分最高值等數(shù)據(jù)生成一份摘要推送到我的手機(jī)。我只需要掃一眼摘要就能判斷系統(tǒng)前一天運(yùn)行狀態(tài)是否健康。這個(gè)習(xí)慣幫我發(fā)現(xiàn)過一次很隱秘的問題有段時(shí)間我對(duì)沖操作次數(shù)突然變少了一半收益率卻和以前差不多。拉出詳細(xì)日志一看原來交易所把最小下單數(shù)量調(diào)高了導(dǎo)致一些小額調(diào)整單無法執(zhí)行。雖然暫時(shí)沒造成風(fēng)險(xiǎn)但這種“沉默的故障”如果不通過報(bào)表對(duì)比很難被注意到。所以說自動(dòng)化系統(tǒng)不是寫出來就結(jié)束了持續(xù)觀察、持續(xù)優(yōu)化才是它真正可靠的關(guān)鍵。結(jié)合我自己的使用體會(huì)AutoHedge 這樣的自動(dòng)對(duì)沖工具最大的價(jià)值不是讓你賺更多錢而是讓你在行情動(dòng)蕩的夜晚能安心睡覺在出現(xiàn)黑天鵝時(shí)不至于手忙腳亂。如果你也在考慮做自己的自動(dòng)對(duì)沖系統(tǒng)我的建議是從最小的場景開始就用一個(gè)交易對(duì)、一臺(tái)服務(wù)器、一套簡單的動(dòng)態(tài)比例策略先跑通閉環(huán)再一步步添加新的功能。穩(wěn)定永遠(yuǎn)比功能多重要。