



收稿日期:2023-06-28
DOI:10.19850/j.cnki.2096-4706.2024.03.011
摘" 要:行情數據特別是高頻數據是量化交易和研究的發動機,然而目前國內高頻量化交易處于起步階段,機構的業務人員大多缺乏IT專業能力,只有一些Python語言基礎。但是市場上的高頻行情數據SDK一般都是C++或Java語言開發的,暫無支持高頻行情的Python-SDK。針對市場亟需一款能夠處理高頻數據的Python-SDK的痛點,方案提出的高性能Python-SDK,采用C++和Python混合編程的方式,既保留了Python語言特性,便于業務人員獲取行情數據和對接量化交易,又兼顧了高頻行情的性能要求,能達到15萬TPS的處理性能,比純Python實現的SDK性能提升近10倍,比Java和Python混合編程實現的SDK性能提升5倍,滿足高頻行情的處理需求。
關鍵詞:Python-SDK;高性能;高頻行情;混合編程
中圖分類號:TP311" " 文獻標識碼:A" " 文章編號:2096-4706(2024)03-0050-04
High Performance Data Communication Method Based on Hybrid Programming
DING Jiao
(Key Laboratory of Radar Imaging and Microwave Photonics Technology, Ministry of Education (Nanjing University of Aeronautics and Astronautics), Nanjing" 210016, China)
Abstract: Market data, especially high-frequency data, is the engine for quantitative trading and research. However, at present, high-frequency quantitative trading in China is in its early stages, and most of the business personnel of institutions lack IT professional skills, with only some Python language foundation. But the high-frequency market data SDK in the market is generally developed in C++ or Java language, and there is currently no Python-SDK that supports high-frequency market data. In response to the urgent need for a Python-SDK capable of processing high-frequency data in the market, this solution proposes a high-performance Python SDK that adopts a hybrid programming method of C++ and Python. It not only retains the characteristics of the Python language, making it easy for business personnel to obtain market data and engage in quantitative trading, but also takes into account the performance requirements of high-frequency market. It can achieve processing performance of 15w TPS, which is nearly 10 times better than the SDK performance implemented in pure Python, and improves 5 times compared to SDK performance implemented by Java and Python hybrid programming. It meets the processing needs of high-frequency market.
Keywords: Python SDK; high performance; high frequency market; hybrid programming
0" 引" 言
國外量化金融領域發展日趨成熟,程序化交易便占據了市場交易量的70%以上。由西蒙斯創辦的文藝復興科技公司依靠量化交易,在金融危機的浪潮中,年收益高達80%。隨著人工智能及數字經濟的發展,國內大量的金融機構開始從傳統的證券投資向量化交易轉型。作為量化交易的發動機,行情數據的質量與時效性對量化策略的執行效果有著決定性作用。由于高頻行情頻次更新快,可提供更豐富的行情數據,是大部分量化策略的首選數據源[1]。
市場上通常以SDK的形式為用戶提供行情推送服務;由于高頻行情數據量大,而且量化交易對行情延遲非常敏感,因此市場上的SDK一般都是C++和Java語言。然而,C++、C#、Java等編譯型計算機編程語言性能突出,但對使用者的計算機能力要求高;而Python作為一種腳本語言,入門難度低,同時集成了大量的量化算法庫,則是量化研究人員的首選語言。因此,高性能的Python-SDK一直是量化研究人員非常迫切的需求。
Python實現的純Python的SDK(以下簡稱Python版SDK),和Python與Java的混合編程實現的Python的SDK(以下簡稱Java版SDK),前者由于Python的GIL和垃圾回收等先天缺陷,甚至無法實時處理全市場行情切片數據;后者雖然底層的網絡通信、解壓、序列化等操作均由Java實現,但由于Python的運行時環境與Java的運行時環境相互獨立,在數據交互的時候采用進程間通信的方式處理,會產生較多耗時,因此仍無法處理逐筆數據,并且在脈沖式數據爆發階段延時過高,無法滿足實時性需求。
本方案提出的Python-SDK,是在現有C++SDK的基礎上自研的一版基于混合編程的高性能Python行情接收SDK。該版本的Python-SDK能夠滿足用戶對高頻行情的處理需求,相較于純Python版SDK的TPS提升了500%,平均數據處理耗時減少了40%;為了提升Python-SDK的用戶體驗,基于mypy為Protoc生成的Python文件提供了類型注釋[2]。除此之外,本方案的混合編程方式,還非常便于后續的維護和升級。
1" 技術實現
Python-SDK性能提升策略的主要邏輯是軟件架構的分層設計,網絡層和數據層通過編譯型語言提升性能,表示層通過腳本型語言優化交互,簡化使用。如何減少編譯型語言與腳本語言之間的數據交互耗時,以及語言之間非兼容特性之間的協調與轉化是本次策略的主要技術難點。
1.1" 數據底層交互與零延時傳遞
行情接收SDK需要對高頻海量數據進行實時網絡接收、解碼、解壓縮、反序列化等一系列復雜處理,對程序的高并發處理能力提出了考驗。同時,由于行情數據與交易強相關,在使用中不允許出現數據丟失現象,但用戶解析處理行情的速度往往慢于后臺接收速度,這就要求SDK內部有一個高性能的緩沖隊列。
但純Python版SDK在復雜計算時的效率略低于常見的編譯型語言。并且在高性能無鎖隊列方面,Python目前沒有成熟的解決方案。在使用Python原生隊列同時進行讀寫操作時,峰值TPS僅10萬次/秒[3],遠遠無法滿足全市場行情的處理需求。
考慮到Python本身就是一個C庫,真正的Python實體在動態鏈接庫中實現,這就意味著Python程序可以與C++程序共用內存空間。利用已有的C++SDK動態鏈接庫處理耗時過程,在C++SDK中回調Python程序中的函數。通過這種方式,行情數據作為一段內存在C++程序與Python程序中共享,在實現后臺處理與前端應用分離的同時,實現數據的零延時傳遞。
1.2" 參數及接口封裝
由于C++ SDK參數類型與接口邏輯復雜,涉及STL容器類型、二維指針、引用、Protobuf對象等數據傳遞,以及回調函數、繼承等接口處理[4]。需要對原有C++SDK進行數據轉換及接口封裝,并對語言轉換工具進行調整及拓展。
1.2.1" STL容器類型
由于C++和Python對于容器的實現邏輯是不一致的,且存在大量的類函數,無法通過類型轉換或者指針強轉來實現數據傳遞。為了與C++SDK接口對齊,要求Python-SDK能夠使用并傳遞部分STL容器類型數據。
以Maplt;std::string,intgt;為例,首先需要對其進行重命名處理:template(StrIntMap)std::maplt;std::string,intgt;。在C++端創建對應的靜態指針,其次,實現對Map的基本功能函數進行封裝,如圖1所示,以Add函數為例。
1.2.2" Protobuf數據傳遞與回調函數封裝
在C++ SDK中,網絡層接收數據并進行解碼解壓后會形成一個Protobuf對象,將該Protobuf對象通過回調函數傳給用戶使用,這就導致在Python與C++交互時存在兩個問題,第一Python無法識別Protobuf數據結構,第二由于回調函數是在C++內中作為成員函數實現,Python并沒有方式能夠實現調用類指針來進行函數回調[5]。
對于Python無法識別Protobuf數據結構的問題,在處理中首先在C++SDK中利用Protobuf進行序列化,在Python中對數據流進行反序列化處理。但由于C++中的String類型與Python中的Byte數據并不能兼容,需要對Protobuf序列化后的String數據進行截取并分段傳遞[6],在Python中分段接收,在收取完畢后再進行發序列化操作。
對于Python無法通過類指針回調成員函數的問題,以數據回調成員函數為例,回調函數的封裝邏輯如圖2所示。
C++中回調Python中的類成員函數的底層邏輯是參考C++特有的虛函數表實現的。對于C++層,實現一個SwigDirector_Callback類,這個類繼承CallbackInterface接口和Swig工具中的Director類。SwigDirector_Callback類維護一個虛函數表,C++的調用方通過預先設定的索引值來動態獲取注冊在虛函數表中的函數指針,進行實現對應的函數回調。在Python層,對虛函數表進行一層封裝[7],如果PythonCallbackClassInterface存在子類,那么將回調子類函數,否則回調父類函數。
1.3" 基于mypy的Python類型注釋
C++ SDK底層統一采用Protobuf進行網絡傳輸,既高效又方便。然而,由于Python是動態強類型語言,通過Protoc生成的Python對象文件沒有靜態類型注釋信息,從而導致生成的Proto對象沒有屬性提示信息,用戶往往需要對照Proto文件說明,才能理解Proto對象含義,非常不便于使用[8]。因此,我們使用mypy為Protobuf的Python函數聲明添加類型注釋,在生成Proto文件對應的*_Protobuf2.py文件時,自動在獨立文件(“*_Protobuf2.pyi文件”)中生成類型注解。mypy使用“函數注釋”這個Python 3的語法指定類型簽名,從而檢查程序類型的正確性[9]。而且,這些類型注解只會在運行類型檢測時提示,實際運行的時候不會發生作用,因此,程序不會有運行時的類型檢查開銷,從而在不改變Python動態類型的本質和解釋器行為的前提下,讓Python獲得靜態類型系統所帶來的好處。
2" 效果評價
2.1" 性能效果評價
我們通過壓力測試,純Python版SDK的處理性能大約在1.5萬次/秒,無法滿足高頻行情的訂閱速度;Java版的Python-SDK能達到3萬次/秒的TPS性能,能夠滿足一般情況下的行情訂閱,但不能支持高頻行情的峰值性能要求;而Python-SDK能達到15萬次/秒的處理性能,能夠支持目前高頻行情的訂閱[10]。在盤中Java版Python-SDK、Python-SDK和C++ SDK訂閱全市場高頻行情的平均行情延遲對比,其中橫坐標為09:30~15:00的每分鐘時間,縱坐標為這一分鐘內的平均延遲時間,由于時鐘偏差和交易所行情延遲波動,此處行情延遲并不代表SDK的絕對行情延遲,只作為相對行情延遲比較如圖3所示。(由于純Python版SDK不能支持全市場的高頻行情訂閱,故未參與本次比較)。可以看出,Java版Python-SDK行情延遲較大;而Python-SDK的延遲則明顯低于Java版Python-SDK[11],只略低于C++ SDK。各版本行情SDK的處理速度和相對延遲情況統計,如表1所示。
表1" 各版本行情SDK處理速度和延遲
行情SDK名稱 處理速度/(萬次/秒) 平均延遲/ ms
純Python版SDK 1.5
Java版Python-SDK 3 2 586
Python-SDK 15 1 017
C++ SDK 20 1 016
2.2" 開發和維護效果評價
Python-SDK底層由C++ SDK實現,C++層不僅實現了用戶登錄鑒權、訂閱和回測等復雜的業務邏輯,而且解決了序列化和高性能無鎖隊列等多個性能問題。因此,在Python-SDK開發過程中,節省了重復處理業務邏輯和優化性能的3~4個月的工作,而只需要花費3~4周生成Python調用接口和封裝Python的用戶調用邏輯。并且,我們為這部分生成調用接口和封裝用戶邏輯的步驟編寫了自動化腳本,從而后續升級時,能夠在完成C++ SDK后,快速完成Python-SDK的升級操作,不僅高效,而且保證了與C++SDK功能的一致性[12]。
3" 結" 論
Python作為量化交易主流的語言,有著較大的群眾基礎,其語法簡單,開發效率較高,量化交易生態完善,但是作為解釋性語言運行效率較低,其處理效率不足以支撐種類眾多的海量行情數據,依賴C++SDK靜態類型語言提速。本方案的Python-SDK為C++轉Python的技術創新方案,為支持高性能處理的Python用戶提供了很好的解決方案,在控制開發和維護成本的基礎上,使用新的開發語言實現的復雜業務邏輯和性能要求,彌補了業內Python語言的高性能SDK行情產品的缺失。
參考文獻:
[1] 董剛.銀行網點財務檢查環節中的Python應用 [J].金融科技時代,2023,31(9):73-78.
[2] 李婧,熊澤明,王斌.Python程序設計基礎教程 [M].成都:電子科技大學出版社,2020.
[3] 楊凱利,山美娟.基于Phython的數據可視化 [J].現代信息科技,2019,3(5):30-31+34.
[4] 于彤彤,基于人工智能和可視化技術的股票量化交易策略分析 [J].智庫時代,2020(9):49-50.
[5] 周迪民,歐嵬.基于大數據的計算機數據分析管理系統設計 [J].湖南科技學院學報,2020,41(5):64-66.
[6] 屈新懷,高萬里,丁必榮,等.基于聚類數和初始值的K-means算法改進研究 [J].組合機床與自動化加工技術,2011(4):42-46.
[7] 王春麗,劉光,王齊.多因子量化選股模型與擇時策略 [J].東北財經大學學報,2018(5):81-87.
[8] 顧綿雪,孫鴻宇,韓丹,等.基于深度學習的軟件安全漏洞挖掘 [J].計算機研究與發展,2021,58(10):2140-2162.
[9] 曾武序,錢文彬,王映龍,等.一種基于Python和BP神經網絡的股票預測方法 [J].計算機時代,2018(6):72-75+80.
[10] 孫睿陽,方信昀.基于PyEcharts的計量測試數據可視化初探 [J].中國計量,2021(3):111-115.
[11] 余本國,劉寧,李春報.Python大數據分析與應用實戰 [M].北京:電子工業出版社,2021.
[12] 楊迎.基于Python語言的Web數據挖掘與分析研究 [J].現代信息科技,2019,3(23):63-65.
作者簡介:丁嬌(1988—),女,漢族,江蘇南京人,實驗師,碩士,主要研究方向:雷達成像與微波光子技術教育部重點實驗室、電子信息工程學院實驗中心的管理與教學。