Python 做高頻交易系統適合哪個級別的延遲?
latency指tick to trade. 可以容許少數核心函數用cython或直接c來實現。
我對 Python 不算熟,不過可以提供一些思路。
首先做一個最基本的測試,連續取兩次系統時間,精度在納秒,看看延遲如何。先來看一段純 C 代碼:#include &
uint64_t nanotime(const struct timespec *ts)
{
return (ts-&>tv_sec * kT_ns_in_s) + (ts-&>tv_nsec);
}
uint64_t n=50000;
uint64_t sum=0;
uint64_t latency=0;
for (i = 0; i &< n; i++) { clock_gettime(CLOCK_REALTIME, start); clock_gettime(CLOCK_REALTIME, end); sum += nanotime(end) - nanotime(start); } printf("Latency: %d ns ", sum / n);
這段代碼在我的一個小弱 EC2 雲主機上跑出來的結果是:
Latency: 1101 ns
這個結果給我們提供了一個基準線,作為在這個硬體配置下的最優值。它說明取一次系統時間大概需要1101納秒,即1.1微秒。這個值是對50000次運算取平均的結果,這樣做是為了避免一些隨機的干擾(比如進程切換之類)。
現在來看看 Python 的表現。我使用 nanotime 這個模塊來取納秒級的時間。首先看普通版 Python:
-&> % python
Python 2.6.6 (r266:84292, Sep 11 2012, 08:34:23)[GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2Type "help", "copyright", "credits" or "license" for more information.
&>&>&> def test(i):
... start = nanotime.now()
... return((nanotime.now() - start).nanoseconds())
...
&>&>&> sum(map(test,range(50000)))/50000
5708
同樣的演算法,得到結果是5708納秒,即5.7微秒。比純 C 版本慢了 500%。
這個結果不算出乎意外,我們知道 Python 是運行在虛擬機上,中間夾了一層位元組碼,必然損失一些效率。對這種情況,要追求性能就需要祭出大殺器 JIT,Python 世界的代表是 PyPy,它的性能數據可以在這裡看到:PyPy"s Speed Center: Timeline。遺憾的是沒有提供高精度的納秒級測試。我們用上面的程序來簡單測試一下:
-&> % pypy
Python 2.7.3 (f66246c46ca30b26a5c73e4cc95dd6235c966b8f, Jul 30 2013, 09:27:06)[PyPy 2.0.2 with GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2Type "help", "copyright", "credits" or "license" for more information.
&>&>&> def test(i):
... start = nanotime.now()
... return((nanotime.now() - start).nanoseconds())
...
&>&>&> sum(map(test,range(50000)))/50000
3614
有了很大改進,得到3614納秒(3.6微秒),但比起純 C 仍有很大不足。
以上是一個非常簡單的小測試,可以看到沒有涉及任何複雜的操作,得到的數據給我們的感覺是 Python 大概比純 C 慢 2~3 倍。如果這個測試中沒有特別嚴重的原則問題,那麼可以推斷核心函數用 CPython 或純 C 來編寫並不會帶來更進一步的性能提升。目前江湖傳言,如果換成高配置的實體主機,純軟體的 C/C++/Java 實現(不涉及 FPGA 等定製硬體),一般 Tick-To-Trade 可以做到10微秒以下的延遲水平。以此估算,Python 應該至少能夠做到30~40微秒的水平。
當然,受限於我的 Python 水平,這是一個非常粗糙的估算。歡迎對 Python 性能調優有經驗的朋友指正。
對性能有重要影響的還有內存模型。Python 也是自動管理內存,需要 GC 的語言,對延遲敏感的話需要做這方面的工作。另外為了能精確控制內存結構,還需要能直接讀取內存的方法(Direct Memory Access)。簡單的調查之後,以下的一些資料應該會有幫助:
Python Garbage CollectionAccess memory address in python - Stack Overflow
DMAPython: Direct Memory Access Parsing for PythonFast I/O and compact data with python / numpy"s memmapPythonSpeed/PerformanceTips綜上,我的結論是,Python 做到幾十微秒級的延遲應為問題不大。但這個數據對於真正的 HFT 來說是遠遠不夠的,另外考慮到系統複雜度增加以後,Python 語言本身的特性(弱類型,Scope等)會給高性能演算法的編寫埋下很多隱患,所以不推薦使用 Python 做低延遲系統的開發。玩個時間遊戲也這麼多學問,一年有5季?還是一季有4個月?還是一個月有5周期?一個周期有6個交易日?一個交易日有25小時?等。。。量化價變,時間不變。
Python 是腳本語言,效率和穩定性都不合適用來做高實時性系統的解決方案。C還是首選,但成本高。腳本語言容易學,成本低。
推薦閱讀:
※為什麼 Python 中列表的 sort 方法一定要返回 None 而不是排序後的列表?
※已有C++基礎,python入門書籍推薦?
※在windows7中python3.4下如何升級pip?
※Python是最好的編程語言嗎?
※python buildin 中的一些類中為什麼方法的內容都是pass?