c 量化交易 從零架構乙個交易框架(一)

2021-10-14 10:56:11 字數 2547 閱讀 4262

最近同時在操作**和美股,使用的是同乙個策略,只是在引數上有一些不一樣,但現在遇到了乙個問題就是兩邊的框架是不一樣的,在**這邊用的是tqsdk,而美股是用的 backtrader,所以這就導致了很麻煩的乙個事情就是如果策略只要有一點改動,就得把同乙個邏輯在不同的框架上都進行修改一次,也因此萌生了自己開發一套輕量的統一交易框架的想法。

當然也是先重新調研了一下現在最常見的幾個綜合框架,包括 vnpy 和 quantaxis,還有一些基於web的服務比方說三大礦。具體的 vnpy 和 quantaxis 的區別我之前有寫文章對比。總的來說還是不太符合我的需求。

概括說一下我的有差異的需求主要集中在這幾點:

輕量,易理解。

架構易擴充套件,容易快速開發嘗試,在未來可支援毫秒級別高頻策略

服務穩定、健壯,當然架構的清晰與簡潔是服務穩定的一大前提,另一方面就是這套服務應該可以很容易地最終部署在 linux 機器上,服務應該採用 web 開發的原則就是盡可能無狀態,任何乙個模組遇到問題都應該可以隨時重啟服務就可恢復

那麼我們就來分析一下這個交易框架的架構應該怎麼實現。首先關於第一點是很主觀的,所以我們從第二點出發來分析:

這就注定了肯定是 c++ 或者 golang 的邏輯,但有乙個問題在於無論是 c++ 還是 golang 它們都不容易快速開發嘗試,主要原因在於現在有關財經、數學的第三方的庫都基本上是基於 matlab、r、python的,更不用說機器學習這方面的了。所以如果我們需要為高頻策略做規劃的話,那這裡肯定會涉及到多語言的變遷與支援。也許現階段在開發的時候以python為主,未來需要某個模組更高效了,就把對應的模組用更有效率的語言做替換。所以就不可避免地需要考慮rpc的選擇。

關於 rpc 框架其實分了兩部分,乙個是序列化與反序列化,另乙個是連線層選型。

序列化與反序列化主要指標在於打包之後的資料大小、打包解包的時間消耗,次要指標在於能方便快捷地debug排查問題,然後加上之前的經驗,備選的框架有 msgpack、protobuf、flatbuffers。在網上找到很多資料之後大概的選項排名是 flatbuffers > msgpack > protobuf,有時間我再專門去親自測試一下,到時再發一篇對比文章上來。現在本著快速開發的思路先以網上資料為主。

第二個是連線層選型,看上去有很多選項,其實並不多。我們可以考慮的有 http(websocket), zeromq, 以及各種mq。但我們會發現在這些mq 和 http 的選項都太重了,為了一小段**需要啟動乙個完整的服務協議出來,無論是邏輯還是效率都不夠好。而 zeromq 的優勢在於它是乙個很靈活(並且高效)的框架,在開發階段可以採用inproc的方式在同一程序內實現通訊,在部署中低頻策略的時候可以採用tcp的連線方式,如果需要做高頻策略的話,還可以用本機的 ipc的方式,甚至回歸為 inproc 的連線,而且這些切換只需要改個配置位址就可以了,很是方便,同時還可以無縫地支援廣播模式來實現各種mq的功能。

而對於同為 zeromq 的親兄弟 nanomq 給我的感覺是缺乏開發與維護,並不像 zeromq 一樣積極地去迭代。因此不予考慮。

最後我很幸運地發現了這麼一些已經做好封裝的 python rpc的框架: mprpc, zerorpc, msgpack-rpc-python,對比一下:

mprpc 效能最高,採用的是原始 tcp + msgpack,為了高效使用的是c語言的封裝

zerorpc 效能最差,採用的是 zeromq + msgpack,它的特點是框架已經實現了 heartbeat,並且支援 generator 的呼叫封裝

msgpack-rpc-python 效能居中,tornado 的 tcp部分 + msgpack,沒啥別的特點

讓人感到很差異的是 zerorpc的效能不是一般的差。採用mprpc裡的 benchmark **:

(tmp) ➜  mprpc git:(master) ✗ python benchmarks/benchmark.py 

call: 10261 qps

call_using_connection_pool: 16305 qps

(tmp) ➜ mprpc git:(master) ✗ python benchmarks/benchmark_msgpackrpc_official.py

call: 6295 qps

(tmp) ➜ mprpc git:(master) ✗ python benchmarks/benchmark_zerorpc.py

call: 1567 qps

這完全不是 msgpack 和 zeromq 組合應有的表現。但最後基於心跳協議的完整性,以及 generator 的支援,還是選擇 zerorpc這個框架。原因在於在乙個專案的早期,要考慮的不是最終的表現,而是快速試錯。而我們只需要保證選型的可擴充套件性就可以了。因為我們對 zeromq 和 msgpack 的組合有信心,所以在早期我們可以快速迭代重要的部分,而到了後期真的遇到瓶頸了,我們就只是換掉 zerorpc 這個封裝,自己再去實現乙個高效的 zeromq + msgpack 的庫就可以了。

因此,在專案早期,我們的rpc選型就採用 zerorpc

劉敬思:從零架構乙個交易框架(二)——**資料​zhuanlan.zhihu.com

**也來了,歡迎 star fork 提 issue

從零寫乙個Java WEB框架(一)

從乙個簡單的servlet專案開始起步。對每一層進行優化,然後形成乙個輕量級的框架。每一篇,都是針對專案的不足點進行優化的。專案已放上github 乙個非常基礎的servlet專案。基本功能是 對資料表 客戶表進行資料處理。例如 客戶的資料獲取 controller 層 獲取客戶端的資料 思路 通過...

從零寫乙個Java WEB框架(一)

從乙個簡單的servlet專案開始起步。對每一層進行優化,然後形成乙個輕量級的框架。每一篇,都是針對專案的不足點進行優化的。專案已放上github 乙個非常基礎的servlet專案。基本功能是 例如 客戶的資料獲取 controller 層 獲取客戶端的資料 思路 server 層中的獲取所有客戶資...

x86架構的乙個瑕疵 可執行保護

很久以前,曾經寫過一篇關於如何保護棧不可執行的文章 棧的保護 windows和linux 文章的最後談到了一種很好的方式,就是不用段式保護機制而使用頁式保護機制,在頁表項中做文章,但是這種方式有乙個前提就是頁表項必須支援可執行位,傳統的x86 是不支援的,也就是說傳統的x86處理器僅僅支援讀寫保護,...