為股票和加密貨幣交易構建規則引擎 - ksred

banq發表於2022-04-12

我建立了一個平臺和市場來建立、測試和執行股票和加密貨幣的交易策略。

至少在過去的十年裡,我對金融和API有著濃厚的興趣,這促使我建立了像BVNK這樣的初創公司和像COVID19API這樣的產品。我對投資也有積極的興趣,作為一名軟體工程師,我對技術如何為某項任務帶來更多的價值很感興趣。

在閱讀了一些關於交易策略的書籍後,我決定嘗試實施這些策略,看看它們是否有效。當時有幾個選項可以做到這一點,比如Quantopian(RIP),Trading View和Meta Trader平臺。然而,這些軟體要麼學習曲線很陡,涉及我不熟悉的語言(Python和MQL),要麼過於簡單,只提供一些子集的功能。

對於一個特定的交易策略,我對以下內容感興趣。
  • 股票的價格應該低於某個值
  • 股票的市值應低於某一數值
  • 在一定時期內,該股票應該有一定數量的內幕交易報告
  • 在一定時期內,股票的交易量應該有一定比例的增長
  • 在一定時期內,SMA20應跨越SMA50
  • 市盈率應低於某一數值

我發現沒有一個平臺能夠輕鬆做到這一點,既能進行回溯測試,又能進行日常執行,因此我決定建立一個平臺來實現這一點。

注意:雖然我在這篇文章中只提到了股票,但一切都與貨幣有關,當然,有些標準並不適用。

啟動專案
我以前曾試圖建立這個專案,並使其正常工作,但後來把自己編進了一個洞。它變得太複雜了,無法修改,如果不進行重大的重構,就無法測試。我還沒有準備好放棄這個想法,所以決定重新開始,這次要好好做。

從第一天開始,我就使用了測試驅動開發,以確保程式碼能夠被維護下去。在這個應用程式的構建過程中,這絕對是一個救命稻草,而且令人驚訝的是,它並沒有減慢開發速度。我發現,當我脫離了TDD的習慣("讓我快速完成這個任務"),花在除錯和修復上的時間比一開始做TDD的時間還多。

不過TDD並不能自動帶來好的架構,所以在開始開發後不久,我就花時間設計平臺的整體架構。當我通過預期的結果工作時,我意識到這比我預期的要複雜得多。

隱藏的複雜性
我們的願望是:能夠建立一個具有N個進入標準和N個退出標準的方法論。這些標準在內部應該是同一型別的,所以我利用Go的介面來實現一個良好的模式。

注意:介面對於在Go中使用TDD並確保獲得良好的覆蓋率至關重要,所以我建議使用大量的介面和大量的嘲弄。

現在有幾種型別需要實現:標準型別("你在測試什麼"),標準狀態型別("你在測試什麼"),以及方向("高於或低於")。為了達到這一點,我花了很多時間,但在實現了這個基礎後,我有了一個東西,a)可以工作,b)可以隨著我在整個系統中增加更多的型別而擴充套件。

標準型別的例子有:目標、名義增長、百分比增長和交叉。
標準狀態型別的例子有:成交量、價格、pe比率、指標、內部交易、目標等。

我能夠得到的最好的工作方式是,你建立一個具有相關欄位和資料點的標準物件,然後在評估過程中,你使用switch語句將標準指向一個可以最終完成評估的特定函式。

如果所有的標準點都被滿足,則標準被標記為滿足。如果所有標準都滿足,那麼相關的交易就會被執行(開倉或平倉)。

處理指標一直是特別困難的,主要是由於欄位的數量不同和資料型別不同。一種方法是將每個指標作為一個物件在程式碼中建立,這比較容易,但會導致大量的程式碼。另一種方法是建立一個更通用的指標物件,它可以有一個相關的型別,並且欄位和功能根據型別的不同而不同。我選擇了後者,因為前期的設計將在未來節省很多時間(例如,如果你想給所有的指標新增一個欄位,或者改變所有指標的行為)。

去耦合
通過TDD開發,你最終會得到漂亮的、解耦的程式碼。這使得改變變得更加容易,因為你可以確定這些改變不會產生意想不到的效果(大部分時間)。然而,在處理頂級領域型別的流程時,它確實會引起一些頭痛。

在我的案例中,領域流程是一個“方法論”。( banq:DDD聚合根?)
“方法論”持有所有的標準和相關的交易,以及與特定使用者的連結,還有一些後設資料。
物件中不包括一些關鍵元素:股票本身,圍繞股票的價格資料,以及跨方法論執行的交易。

我們的想法是,股票應該被傳遞給“方法論”,並且只是執行,而方法論不應該關心或知道股票的情況。但是,因為方法論不知道股票,所以價格也沒有聯絡。為了清楚起見,流程如下。

  • 方法論被執行,所有標準被檢查
  • 方法論返回標準狀態,然後開啟交易。

因為標準是靈活的,而且因為我們檢查標準時,沒有可用的價格資訊。
你可以對方法論進行過載,新增一個定價欄位和一個股票欄位,但這與方法論物件沒有聯絡--這是影響它的東西。我像躲避那場瘟疫一樣躲避汙染,因為它總是以淚水收場。

相反,為了解決這個問題,當交易需要開啟時,我們獲取股票的相關價格。我在這裡說 "相關 "是因為我們也在進行回測,所以我們不能只取最新的價格,我們需要取一個有一定偏移量的價格。

資料管理
我正在使用IEX雲作為資料來源,正如任何與金融資料打交道的人所知道的,成本會迅速增加。我只想在我需要的時候獲取資料,而且只在我需要的時候獲取。

這發生在幾個地方:當執行回測和請求資料時。因此,當這些事件發生時,我做以下檢查。

  • 獲取最新的資料記錄(價格、公司統計、內幕交易,等等)
  • 如果有一個記錄,檢查日期。如果沒有記錄,就把日期設定為UTC 0
  • 將日期傳送到一個函式,以返回要獲取多少資料。如果我們落後5天,就獲取1個月的資料(最小的增量),如果我們落後40天,獲取3個月的資料,等等。另外,確保檢查你是否在週末附近,並作出相應的調整。
  • 取出資料並儲存,然後返回資料

由於後面的測試都使用了這些相同的函式,因此必須根據我們想要的資料來切割所得到的片斷。如果我們想要60個時期以前的資料,我們就需要只返回到那個時候的資料。

上述資料的獲取在直接通過API請求資料時也是有效的,而且令人驚訝的是根本不需要花費太長時間。例如,當請求3個月的資料時,我們從IEX獲取資料,儲存它,並在500ms左右返回。隨後的呼叫要快得多,儲存資料時<200ms,快取資料時<100ms。

目前的狀況
我在這個專案上花了六個月的時間(大概350個小時),寫了23000行程式碼,最終的程式碼覆蓋率將達到90%。這是一種愛的勞動,也是一種巨大的回報。

在向公眾釋出之前,該應用程式需要進行一些小的調整和進一步的測試,但它目前正在執行我的方法論中的大部分標準,每天大約有3000只股票。我將在短期內進行前端工作,並應在1月底前推出一些初始版本。我還向YCombinator申請了投資,讓我們看看會發生什麼。
 

相關文章