online gambling singapore online gambling singapore online slot malaysia online slot malaysia mega888 malaysia slot gacor live casino malaysia online betting malaysia mega888 mega888 mega888 mega888 mega888 mega888 mega888 mega888 mega888 閒扯比特幣套利交易系統的設計

摘要: 關於比特幣套利交易的文章,坊間一搜一大堆,尤以2014,2015為甚。那時交易所間價差相當可觀,套利的機會很多,躺著賺錢並非難事。如今,套利區間收窄,留在沙場上的估計只剩下大玩家,想要不費力氣躺贏機會渺茫。...

 


閒扯比特幣套利交易系統的設計

 

關於比特幣套利交易的文章,坊間一搜一大堆,尤以2014,2015 為甚。那時交易所間價差相當可觀,套利的機會很多,躺著賺錢並非難事。如今,套利區間收窄,留在沙場上的估計只剩下大玩家,想要不費力氣躺贏機會渺茫。最近幫朋友牽線尋找幣圈量化交易的機會,本欲做個打醬油的中間人,事了拂衣去,安安靜靜做個三河市微胖界扛把子,誰料還是一時技癢,不小心昨夜搭進去六七個小時。
 
關於如何做套利交易,我就不贅述,大家可以看這篇文章,有內容有故事:https://daily.zhihu.com/story/4831821。
 
本文沒有故事,只有技術和產品上的分析。
 
既然要做可行性分析,那麼第一步就是觀察交易數據。國內的交易市場雖然在政策要求下清場出局,國外的交易市場還算紅火。從bitfinex,kraken 一路到bithumb,korbit 等,都提供rest API,少量提供websocket 接口。雖然文檔欠缺,但這些接口都很簡單,上手並不困難。
 
用nodejs 小試牛刀後,我決定全面使用elixir 重寫。
 
這麼做有幾個原因:
單就數據抓取來說,需要一些內部的micro service。比如bithumb / korbit 的報價是韓元,而其他都是美元。如果用美元統一,那勢必要有一個穩定的內部service 提供這種轉換。erlang / OTP 的結構,天然呆萌,阿不,天然鬆散,各個GenServer 自成一體,很適合這樣的需求。
 
數據的抓取和數據的處理我想分開來做。在定期從各個交易市場拿到數據後,我們可以使用pubsub 結構把數據publish 出去,然後讓各個子系統去subscribe —— 找交易機會的去算交易機會,做持久化的去寫數據庫,以後想到什麼新的消費數據的姿勢,隨時可加入新的subscriber。如果用別的語言,少不了再引入ZeroMQ 這樣的依賴(引入複雜性和其他問題)。erlang / OTP 有process group,適合pubsub,而phoenix_pubsub 對此已精巧封裝,開箱即用。
 
erlang / OTP 的容錯和並發/並行能力能讓效率大大提高。
because I can - Insider Man (2006)。
數據抓取出來後,可算出一些隨著時間變化的,理論上的套利空間(真正做是另一回事),但數據本身太抽象,不足以打動自己,打動別人。比如說,過去1 小時有10 個大於0.5% 的套利機會(扣除雙邊的手續費也就剩不到0.1%),這樣的機會究竟可行性如何,長得什麼樣,無從得知。
 
廣東十大傑出青年方世玉他媽苗翠花說:行走江湖,最重要的就是一個「顏」字。乾癟的數字,枯燥的理論如同一具具骷髏,即便切中要害,也很難在產品汪和商務喵身上找到共鳴。所謂無圖不丈夫,不搞點UI,整些可視化,金礦也會被掩埋在黃土之下。《奮鬥》裡陸濤他爹怕他對三十萬元這樣一個數字沒有概念,叫人取出現銀,裝一大紙袋裡給他,這就是可視化。
 
但構建一套擴展性好的可視化UI 豈非一日之功?你好不容易整個chart 支持line / bar / area 和multiple series,做著做著可能又要在兩個series 之間做四則運算,之後可能需要更加複雜的操作。本來塗脂抹粉裝個大家閨秀就是個權宜之計,結果一入前端深似海,從此變更永纏身。所以,不到萬不得已,別自己做可視化。我試過幾個比特幣套利交易的開源代碼,UI 相當一般,擴展性很差,吃力不討好。
 
不自己做,那誰來做?
平日里我工作,接觸多的是datadog。datadog 是做性能監控的,我們只管打點,存儲和可視化交給datadog。雖然它和量化交易八竿子打不著,但如果我們卻可以把這顏值擔當交給datadog 來試試看。
 
打點很簡單,寫個subscriber,監聽爬下來的數據,然後這麼寫入datadog:
abt.xchg.btc.bid:4182|h|#bitfinex
abt.xchg.dsh.bid:344.38|h|#bitfinex
abt.xchg.eth.bid:301.93|h|#bitfinex
abt.xchg.xmr.bid:97.762|h|#bitfinex
abt.xchg.xrp.bid:0.2023|h|#bitfinex
abt.xchg.zec.bid:299.22|h|#bitfinex
abt.xchg.btc.bid:4009.071877180739|h|#bithumb
abt.xchg.dsh.bid:330.42568039078856|h|#bithumb
abt.xchg.eth.bid:288.8171667829728|h|#bithumb
abt.xchg.xmr.bid:93.35310537334263|h|#bithumb
abt.xchg.xrp.bid:0.1936496859734822|h|#bithumb
...
我們為每個幣種提供一個metrics,以交易所的名字做tag,一個batch 把同一時間獲取的數據push 到datadog。這樣,我們就可以可視化出這樣的結果:
 

 
很明顯,就比特幣來說,bitfinex 和bithumb 間有足夠的套利機會:
 

 
這個圖是將兩個series 相減,其差異換算成百分比得到的,所以縱軸是百分之幾。datadog 深耕於APM 市場多年,對此在UI 上已有支持,我們直接可以編輯操作,暖不暖心?
 

 
《讓子彈飛》裡張麻子問:什麼TMD 是以圖服人?方世玉他媽的親家公答:我這就是以圖服人。現在套利的區間一路了然。我們看所有幣種的機會:
 

 
機會有,但有沒有可能兌現,是另一回事,不在本文討論之列。而且目前只有少量的數據,還不充分。
 
看到這裡我們再梳理一下這個系統的架構:
 
 

 
系統有四個Application,Exchanges負責抓取數據並publish,Catcher負責持久化數據(寫入datadog或influxdb),Simulator負責模擬交易(目前僅考慮實時數據的模擬交易,以後應該考慮對歷史數據模擬交易) ,Trader則真正把一個個合適的機會轉化為交易Exchanges和Catcher已經基本實現,Simulator考慮實現,Trader再說Simulator可以根據一些配置的條件動態生成交易員(有點像遊戲中的NPC),接受實時數據並尋找各自的交易機會(使用真實的交易手續費,以及模擬各種延遲),每當產生交易,交易的數據和交易後的總市值會push到datadog,最後可以在datadog裡生成一個實時群芳譜,看看Ada,Bella,Clare,Daisy一干人等究竟誰牛系統的容錯性不錯,理論上任何部分crash都會自我修復,不會有致命影響(比如publisher掛掉,當前時刻沒法出去的數據會丟,可能丟失一些交易機會 
 
下圖是exchanges_app 的skeleton:
 

 
在Catcher 裡,我們除了把數據寫入datadog,還打算寫入influxdb,這是為何?我雖然很喜歡datadog,但它的專長是APM,數據的發送有很長的延時(默認20s),也就是說你一個batch 寫進去的數據,先本地UDP 給到了datadog agent,agent 悠哉悠哉晾你一下,覺著差不多了,再發送給datadoghq。這個延時對事後分析來說無傷大雅,但如果盯盤,就不那麼舒服了。而influxdb 完全由我們自己控制,不存在這個問題。這是其一。
 
我上次使用influxdb / grafana 已是一年前,最近聽人說起grafana 也引入alarm 的功能,正好這個項目可以把它們拾起來好好研究。influxdb / grafana 實時性比較好,可以讓一些操作直接在grafana 裡完成,比如用查詢語句尋找交易機會,然後trigger 一個alarm,alarm 的endpoint 是一個webhook,在webhook 裡進行交易。這樣的話,發現交易機會的公式只要可以用query 寫出來,就不必寫代碼,大大增強系統的靈活性和可擴展性。這是其二。
 
目前總共撰寫近700 行代碼,大約花費五六個小時。一些感悟:
善用工具。有些工具,就像本文中的datadog,從另一個角度去使用它,會有意想不到的收穫。
我們的時間真的彈性很大,與其說「沒有時間」,不如說「我沒興趣」,或者說「它不重要」。昨晚從7:30 算起,到凌晨1點多我睡,中間我有半個小時1:1,以及一個多小時的new hire training。平日里我如果花上兩個小時和同事開會或者探討問題,那麼那晚我就會累得什麼都不想做,早早上床休息。然而昨夜我硬是擠出時間精神高度集中地寫代碼。

 

合適的挑戰可以勾起一個人的興趣,然後一切就可以自然流動。

 

轉貼自: 煉數成金


留下你的回應

以訪客張貼回應

0

在此對話中的人們