如何從5000美金到20萬美金?手把手構建一隻機器學習交易系統
- 2019 年 12 月 21 日
- 筆記
機器學習還能用來構建交易系統?
不僅有人這麼做了,還做得挺好!tradientblog有人就構建了這麼一個交易系統,該系統能夠在一年內利用5000美金的投資產生20萬美金的稅前收益,並且大部分收益是在市場中性產生,即不依賴於市場的漲跌。
狀況最好時,四個月內每天都在持續增長,其間確實會存在短期的下跌,但極少出現一天的整體趨勢是下跌的狀況。

作者還根據自己的經驗和遇到的問題,盡量做到既能夠分享有用的資訊又不透露具體的實現方法。
以下是全文,趕快和文摘菌一起來康康吧!
最近我開始了為加密市場構建自動交易系統的副業。但說實話,相比於主業,我可能花了更多的時間在這項副業上,因此稱其為副業可能並不完全準確。
網路上,有太多人時刻準備著向你灌輸交易知識。其中大部分都只是在推銷產品,並且許多產品還會誤人子弟。
從事軟體工程領域相關研究的我嘗試忽略掉缺乏科學準確性的知識,比如技術分析或者任何類似市場營銷學本科課程的知識。
市場可以被預測嗎?
人們經常會誤解,認為市場是不能被預測的,甚至認為對沖基金經理還不如丟飛鏢的猴子。許多學術研究的文章中還通過數據來支援這一不成熟的觀點。其理由僅僅是在某些實驗場景下無法預測某些市場,例如每日的股票交易。但這並不意味著在任何情況下都無法預測市場。首先,需要對預測市場的含義有一個直觀的了解。為此,我們必須清楚市場的參與者有哪些。
- 散戶投資者:普通人。他(她)可能因為朋友的推薦購買比特幣,或者將挖來的比特幣賣掉變現。
- 機構投資者:機構或進行大額交易的高凈值群體。他們會影響市場的動向。
- 專業交易員:這部分人正在積極嘗試跑贏市場。他們可能會基於新聞、技術分析指標組合或直覺進行交易。
- 演算法:交易演算法能夠自動接收市場數據,做出決策並生成訂單。
一般人都會認為散戶投資者和機構投資者的投資行為是隨機的。比特幣礦工可能正在套現,或者有人通過內部消息正在購買大量比特幣。這樣我們就無法預測市場了。但對於我們而言,這只是隨機雜訊。當這種隨機行為導致價格波動時,有時我們會很幸運地成為市場中獲益的一方,但有時也會成為損失的一方。但從長遠角度來看,這些波動導致的凈值為零。
我們更感興趣的是專業交易員和演算法交易。他們本質上是相同的,因為他們都是遵循一定的規則來進行決策。因此,會在數據中遺留決策的痕迹。如果我們知道其中的規則,就很容易能夠從中牟取暴利。舉一個例子,當我們知道某種演算法在MACD訊號(一種無用卻被廣泛使用的技術分析指標)達到閾值時會購買X數量的產品,那我們只需在演算法執行前稍微調整購買參數,然後在演算法推高其購買價格後賣出。當然這只是一個極簡化的例子。大多數演算法更加複雜,例如基於機器學習的模型。並且在上述例子中忽略了流動性、延遲時間、交易費用等其他因素。關鍵點在於只要我們知道其中的規則,就可以發現那些利用某種規則做決策的市場參與者。
另外一個要點是時間尺度。從每日的價格波動來看,市場行為要比以秒為單位的數據更為隨機。原因很直觀,在較長的時間範圍內(例如幾天或幾周),市場活動是政治新聞、法律裁決、公眾輿論、社會炒作、商業決策等綜合作用的結果。機構投資者產生的大量隨機交易也是一個重要因素,但這種情況並不經常發生。這些不是可以模擬或被演算法利用的。我們沒有黑天鵝事件的相關數據,因此無法運用演算法進行模擬和預測。但是,如果我們將市場活動放大為一小時,一分鐘或一秒鐘,就可以窺見其中的規則。這些規則是基於演算法規則交易的結果。我們的目標就是利用這些規則來創造收益。
換句話說,與其去思考如何跑贏市場,不如通過利用大量其他的市場參與者來獲利。
優勢在哪裡?
買賣交易在兩個或多個市場參與者之間發生,為了使我們自己獲利,就一定會使得其他人虧損。那麼,是什麼使我們能夠比其他交易者獲得更多的收益呢?在貿易中,競爭優勢會體現在各個方面:
- 低延遲:我們連接交易所的速度更快。這意味著我們能夠更快的分析新數據並先於其他人提交訂單。在金融市場中,機構會花費數百萬美元來最大程度地減少與交易所連接的延遲。
- 基礎架構:我們的基礎架構比競爭者更具容錯能力,有更好的性能,並能夠更好的處理特殊情況。
- 數據:我們有品質更高的數據,主要體現在我們的數據來源於不同的API,更加可靠,數據中斷少,並且我們對數據的清洗和後處理更加細緻。
- 模型:我們可以基於數據中隱藏的規則構建更好的預測模型。因為我們使用了更加複雜的深度學習技術,具備更好的優化函數(具體見下文),更好的特徵以及不同的訓練演算法。
- 市場准入:我們能夠進入並非所有人都能進行交易的市場。例如,某些韓國的交易所要求是韓國公民才能進入。許多國際交易所為避免與美國國家稅務局打交道,而不接受身份為美國公民的用戶。
一個常見的錯誤就是專註於模型本身。通過與很多嘗試利用複雜深度學習演算法和(或)強化學習演算法(目前已商品化)建立交易系統的人溝通後發現,他們中的大多數都失敗了。原因在於,他們堅信他們的優勢取決於模型而忽視了其他因素。他們不去優化伺服器配置,並使用開源軟體生成訂單、收集數據,使用易於訪問的公共數據集進行模型訓練。他們的模型本身可能的確具備一定的優勢,但這並不足以彌補其他決策失誤帶來的損失。
很難具體指出本系統的優勢來自何處。可能是以上所有因素的結合。並且我確實使用了一些複雜的機器學習模型,但是最大的優勢可能還是來源於構建基礎架構過程中付出的努力。幾乎所有與交易相關的開源軟體都不是最理想的。這些開源軟體對於學習很有用,但不適用於實際使用。我最開始也是使用開源的組件,但多次嘗試後,我還是選擇為每一部分構建其自定義組件,包括實時數據收集和清洗組件,回測組件,模擬組件,訂單管理組件和標準化、監控以及實時交易組件。
選擇市場
市場是指在特定交易所進行資產交易。例如,在幣安上交易比特幣/泰達幣就是一個市場。在Coinbase上交易比特幣/美元也是一個市場。目前存在數百個不同的加密貨幣交易所,每個交易所可交易數十種資產。那麼,我們如何選擇在哪裡交易呢?理想的市場具備高流動性,低交易費,提供快速可靠的API,並且有安全保障。
首先來談談市場流動性。很多書整本都是關於定義和衡量流動性,但是我們可以將它粗略的理解為在不顯著影響市場價格的情況下可以交易的數量。流動市場的點差和滑點很小。他們提供低交易成本的同時允許我們進行大批量交易。交易量是易於衡量流動性的替代指標。具有高交易量的市場通常(並非總是)具備高流動性。
由於交易量是決策中常用的指標,因此許多加密貨幣交易所會使用偽造的數值來使自己的市場看起來比實際情況好。不幸的是,即使存在諸如cer.live嘗試對市場進行排名的網站,但目前仍然沒有可靠的公開排名。如果只看CMC交易所排名就錯了,這種依靠交易所支付廣告費維護運營的網站提供的排名結果毫無參考價值。最終導致,任何公開可用的排名都容易被交易所玩弄於股掌之中,要麼直接賄賂維護者,要麼操縱其數據。因此,每當交易所排名被大多數人認可時,交易所早晚都會為提高排名而賄賂網站所有者(其中許多都是現金交易)。最重要的是,交易所排名網站並不在乎其數據的準確性。他們不會基於自己的數據進行交易,他們只是市場機器。
因此,評估市場唯一可靠的方法就是自己收集和分析數據。那麼,訂單是什麼樣的?交易是真實的還是虛假的?點差和滑點分布是什麼?儘管某些交易所會公然使用演算法來偽造交易數據,但還有一些交易所會利用更複雜的演算法來使數據看起來真實。在這種情況下,我們不會發現我們是在處理虛假的數據,直到我們開始在該交易所進行交易。
理解交易成本
為了盈利,我們的交易獲利必須足夠抵消所有的交易成本。對大多數人來說,交易手續費是直觀易見的成本。而諸如價格滑動成本之類的其它成本,實際也很重要卻往往被忽略。假設我們購買了一定量的比特幣(縮寫:BTC),並在一段時間後出售。以下是我們將支付的凈交易成本:
trade_cost(qty) = (2 * qty * exchange_fee) + (qty * spread) + slippage_buy(qty) + slippage_sell(qty)
(2 * qty * exchange_fee)是交易手續費。例如,交易所可能對每筆交易收取0.01%的交易費。既然我們是買賣,我們就做兩次交易,付兩次費用。
(qty*spread)是我們在買賣時支付的買賣價差。即使市場完全不發生變動,我們仍然以略高於賣出價的價格買進。價差隨著時間的推移而變化,將其納入我們的交易決策至關重要。如果我們是在Binance上交易BTC/USDT,那麼單日的價差分布可能如下圖所示,大部分時間低於1美元,但非流通時間可達5美元以上。

slippage_buy(qty)和slippage_sell(qty)是市場流通性不足導致的價格滑動。我們的交易量越大,支付的價格滑動成本就越高,因為我們無法以最佳價格交易全部數量。對於Binance上的BTC/USDT交易,滑動成本分布如下圖所示。每一行對應於一個特定的貿易規模,範圍從0.1到2 BTC,X軸顯示成本占交易價格的百分比。如下圖所示,在流通性較低的時期進行交易,意味著滑動成本很容易超過交易手續費和買賣價差。

這些費用有多重要?這要看具體情況。如果我們每天僅交易一次,我們更關注大盤的大幅波動,而忽略大部分交易費用。畢竟當大盤價格波動超過10%的時候,0.5%的交易費用幾乎可以忽略不計。但如果我們的交易頻次越高,交易費用就會越重要。市場在幾秒鐘內一般很難出現大幅波動,這時交易費用就非常重要,因為它可能會抹平你的所有利潤。另一個重要因素是我們的交易量。數量越大意味著利潤越高,交易費用也會越高。交易手續費和買賣價差與交易量成線性關係,但價格滑動成本卻不是。使用限價訂單而不是市場訂單,是保護自己不受價格滑動成本影響的一種方法,但需要額外的基礎設施來管理訂單。同樣,我們交易頻次越高,每次交易抵消成本後的獲利就越少。
時間維度
我們是選擇高頻次的交易還是每天一次的交易?讓我們先分析一下兩種極端情況。
在極短的時間內,比如幾毫秒,市場不會出現大幅波動。每筆交易只能獲取微薄的利潤,但我們可以通過提高交易頻次來提升利潤總和。不過,如之前提到的,高昂的交易成本可能會抹平我們所有的利潤。即使我們能完美地預測市場的毫秒級波動,這樣的模型也非常雞肋。向交易中心發送HTTP交易請求並等待交易中心的匹配引擎進行處理,通常需要幾十到幾百毫秒。當處理完畢時,市場已經發生變化,我們之前的預測已經過時了。
另一種極端情況是基於每日價格的交易。市場間隔一天的波動足以讓我們忽略交易成本,微小的時間延遲也變得不重要。然而,這種較長時間的市場波動可能是由複雜的現實世界互動(如新聞和社會行為)或其他隨機事件(如機構投資者活動)驅動的。如果我們依賴於純粹的模式匹配(機器學習),我們很難做出良好的預測。我們也沒有大量的數據,幾百個例子不足以訓練任何現代演算法。數據少、噪音多,我們也不能可靠地測試和評估演算法,這樣的測試過程就像扔飛鏢一樣不靠譜。
這意味著我們需要在回報率、足夠大的數據集和模式識別能力之間找到平衡點。時間尺度越小,模式和樣本就會越多,但交易成本和交易延遲就會變得越發重要,而這又取決於市場流通性和交易中心提供api的低延遲性能。
除了使用自然時鐘(秒)做間隔外,我們也可以使用其他度量的間隔,如成交量。舉個例子,我們可以將間隔定義為1.0 BTC,而不是1秒,這可能在一秒鐘或一分鐘內完成,具體取決於市場的繁忙程度。我們希望在高峰期(高成交量)更頻繁地交易,而在低峰期(低成交量)減少交易。基於成交量的數據聚合也使得特徵和標籤數據分布更加規範與合理,這有助於ML演算法的訓練。不過這種方法也有缺點,當根據成交量進行交易時可能已經為時過晚。例如,在成交量飆升後才下單意味著已經錯過最佳時機。理想情況下,我們希望在搶其他市場參與者之前下單,即在成交量回升之前下單。
總得來說,時間尺度和如何定義時間間隔是非常重要的參數,必須根據具體市場情況進行優化。一個高流通性、低交易費用和低API延遲的市場,才能讓我們在高頻次的交易中獲得更多利潤。
優化函數
為了基於市場數據訓練機器學習模型,我們需要選擇一個優化指標。基於原始價格數據訓練回歸模型,是一個最簡單直觀的選擇。但價格不是靜態不變的數據,而絕大多數現代機器學習都需要使用不會隨時間而改變分布特徵的靜態數據,才能取得以理想的演算法效果。這就是為什麼在金融領域,我們通常對收益而不是價格進行建模,其中時間t的收益r(t)定義為:
r(t) = (p(t) / p(t-1)) – 1
這是一個根據價格變動而計算出的簡化版回報率公式。回報率大於0意味著價格上漲,回報率小於0意味著價格下跌。你可以根據自己的需要定義時間維度t,如前一節所述,你可以計算每分種的回報率、每天的回報率或者基於成交量的回報率。
一個更優的指標是將收益做對數化處理。它和收益是同樣的指標,但更接近正態分布,也更有利於機器學習的訓練:
logr(t) = log(p(t)) – log(p(t-1))
基於固定時間尺度的對數化收益指標來訓練回歸模型,是一個標準選擇。但我們還有其它選擇。例如,在《金融機器學習》中,作者討論了如何選取合理的閾值,並將數據轉換成分類預測問題。
上面公式中的p(t),我們有多種方式來定義它。對於BTC,它通常指是中間價。然而,中間價是一個合成量,不是我們可以直接交易的價格。在買進時,我們的價格會高於中間價。在賣出時,我們的價格低於中間價。如前所述,我們還會根據訂單數量支付價格滑動成本。因此,價格實際上是時間、交易(買或賣)和交易量的函數:p(t,s,q)。上面的公式應該是這樣的:
logr(t, quantity) = log(p(t, BUY, quantity)) – log(p(t-1, SELL, quantity))
我們還可以選擇其它的價格定義來進行建模,如微價格。選擇一個準確的價格定義有多重要?這同樣取決於時間尺度和市場流通性。在流通性強、滑動成本較低的市場中,基於中間價的模型收益可能足夠好,但在流通性差的市場中則完全無用。
相關報道:
https://www.tradientblog.com/2019/11/lessons-learned-building-an-ml-trading-system-that-turned-5k-into-200k/