C++ 與虛擬機語言在高頻金融中的表現
我認為 C/C++ 與 C#/Java 性能問題已經很好地解決了,這意味著我已經閱讀了足夠多的證據表明 VM 語言不一定比“接近矽”的語言慢。主要是因為 JIT 編譯器可以做靜態編譯語言不能做的優化。
然而,我最近收到了一個人的簡歷,他聲稱基於 Java 的高頻交易總是被 C++ 擊敗,而且他曾經遇到過這種情況。
快速瀏覽求職網站確實表明 HFT 申請人需要 C++ 知識,並且查看Wilmott論壇顯示所有從業者都在談論 C++。
有什麼特別的原因導致這種情況嗎?我原以為現代金融業務有點複雜,具有類型安全、託管記憶體和豐富庫的 VM 語言將是首選。這樣生產率會更高。另外,JIT 編譯器越來越好。他們可以在程序執行時進行優化,因此您會認為他們使用該執行時資訊來擊敗非託管程序的性能。
也許這些人正在用 C++ 編寫關鍵位並從託管環境(P/Invoke 等)中呼叫它們?那可能嗎?
最後,有沒有人對這個中心問題有經驗,這就是為什麼在這個領域中,非託管程式碼無疑比託管程式碼更受歡迎?
據我所知,高頻交易人員需要盡可能快地對傳入的市場數據做出反應,但這並不一定是硬實時要求。如果你很慢,你的情況會更糟,這是肯定的,但你不需要保證每次響應都有一定的速度,你只需要一個快速的平均值。
編輯
是的,到目前為止,有幾個很好的答案,但很籠統(廣為人知)。讓我指定 HFT 人員將執行什麼樣的程序。
主要標準是反應能力。當訂單進入市場時,您希望成為第一個能夠對其做出反應的人。如果你遲到了,其他人可能會先於你,但每家公司的策略略有不同,所以如果一個迭代有點慢,你可能會沒事。
該程序整天執行,幾乎沒有使用者干預。無論處理每條新市場數據的功能如何,每秒都會執行數十次(甚至數百次)。
這些公司通常對硬體的價格沒有限制。
首先,1 ms 在 HFT 中是永恆的。如果您認為不是,那麼最好多閱讀有關該域的內容。(就像距離交易所 100 英里一樣。)吞吐量和延遲是緊密交織在一起的,任何基本排隊理論教科書中的公式都會告訴你。相同的公式將顯示抖動值(如果網路結構正確並且您沒有配置足夠多的核心,則通常由 CPU 隊列延遲的標準偏差決定)。
高頻交易套利的問題之一是,一旦您決定擷取價差,就有兩條腿(或更多條腿)來實現利潤。如果你沒有打完所有的腿,你可能會得到一個你真的不想要的頭寸(以及隨後的損失)——畢竟你是在套利而不是投資。
你不想要頭寸,除非你的策略是預測(非常近期!!!)未來(不管你信不信,這件事做得非常成功)。如果您離交易所還有 1 毫秒的時間,那麼您的大部分訂單將不會被執行,而您想要的東西將會被取走。最有可能已經執行了一條腿的人最終會失敗,或者至少不會盈利。
無論你的策略是為了爭論,讓我們說它最終的贏/輸率是 55%/45%。即使是贏/輸比率的微小變化也可能導致盈利能力發生巨大變化。
回复:“執行數十個(甚至數百個)”似乎相差幾個數量級即使每秒查看 20000 個滴答聲似乎也很低,儘管這可能是他正在查看的儀器組一整天的平均值。
在任何給定的秒內看到的速率都有很大的可變性。我舉個例子。在我的一些測試中,我在一天中間查看了 7 支場外交易股票(CSCO、GOOG、MSFT、EBAY、AAPL、INTC、DELL),該流的每秒速率可以從 0 mps(非常非常罕見)到每個峰值秒幾乎有近 2000 個報價和交易。(看看為什麼我認為上面的 20000 很低。)
我為這個領域建構了基礎設施和測量軟體,我們談論的數字是每秒 100000 和數百萬。我有 C++ 生產者/消費者基礎設施庫,可以在生產者和消費者(32 位,2.4 GHz 核心)之間推送幾乎 5000000(500 萬)條消息/秒。這些是 64 字節的消息,在生產者端具有新的、構造的、入隊的、同步的、****同步的、出隊的、觸摸每個字節的、執行虛擬解構子的、免費的在消費者方面。現在誠然,這是一個沒有 Socket IO 的簡單基準測試(並且套接字 IO 可能很難看),就像在端點管道階段的端點一樣。它是所有自定義同步類,僅在空時同步,自定義分配器,自定義無鎖隊列和列表,偶爾的 STL(帶有自定義分配器)但更常見的是自定義侵入式集合(其中我有一個重要的庫)。我不止一次地為這個領域的供應商提供了四倍(甚至更多)的吞吐量,而沒有增加套接字端點的批處理。
我有 OrderBook 和 OrderBook::Universe 類,當平均超過 22000 個儀器時,新、插入、查找、部分填充、查找、第二次填充、擦除、刪除序列所需的時間不到 2us。該基准在插入第一次填充和最後一次填充之間連續迭代所有 22000 個儀器,因此不涉及廉價的記憶體技巧。對同一本書的操作被 22000 本書的訪問分開。這些都不是真實數據的記憶體特性。真實數據在時間上更加本地化,連續交易經常出現在同一本書中。
所有這些工作都涉及仔細考慮所用集合的任何算法成本中的常量和記憶體特性。(有時,K O(n) K O(n*log n) 等中的 K 似乎被忽略了一點太圓滑了)
我從事市場數據基礎設施方面的工作。甚至想到使用 java 或託管環境來完成這項工作都是不可思議的。當您可以使用 C++ 獲得這種性能時,我認為在託管環境中獲得百萬以上/mps 的性能是相當困難的)我無法想像任何重要的投資銀行或對沖基金(他們的薪水為 250000 美元)一流的 C++ 程序員什麼都不是)不會使用 C++。
有人真的從託管環境中獲得 2000000+/mps 的性能嗎?我在這個領域認識一些人,但從來沒有人向我吹噓過。而且我認為託管環境中的 2mm 會有一些吹牛的權利。
我知道一位主要參與者的 FIX 順序解碼器每秒進行 12000000 場解碼。(3Ghz CPU)它是 C++,編寫它的人幾乎向任何人提出了挑戰,要在託管環境中提出甚至是該速度一半的東西。
從技術上講,這是一個有趣的領域,有很多有趣的性能挑戰。考慮當基礎證券發生變化時的期權市場——可能會出現 6 個具有 3 或 4 個不同到期日的未償價格點。現在每筆交易可能有 10-20 個報價。這些報價可以觸發期權的價格變化。因此,對於每筆交易,期權報價可能會有 100 或 200 次變化。這只是大量的數據——不是大型強子對撞機碰撞檢測器般的數據量,但仍然有點挑戰。這與處理擊鍵有點不同。
甚至關於 FPGA 的爭論也在繼續。許多人認為執行在 3GHZ 商品硬體上的編碼良好的解析器可以擊敗 500MHz FPGA。但即使稍微慢一點(不是說它們慢),基於 FPGA 的系統也往往具有更緊密的延遲分佈。(閱讀“趨向”——這不是一個籠統的陳述)當然,如果你有一個很棒的 C++ 解析器,你可以通過 Cfront 推送,然後通過 FPGA 圖像生成器推送它……但那是另一場辯論……