撮合引擎開(kāi)發(fā):開(kāi)篇


撮合引擎開(kāi)發(fā):開(kāi)篇
撮合引擎開(kāi)發(fā):MVP版本
撮合引擎開(kāi)發(fā):數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)
撮合引擎開(kāi)發(fā):對(duì)接黑箱
撮合引擎開(kāi)發(fā):解密黑箱流程


前言

自從有人在微信群里開(kāi)價(jià)5萬(wàn)求購(gòu)Golang版的撮合引擎之后源哩,我就想自己開(kāi)發(fā)一款怎虫,畢竟,以我的經(jīng)驗(yàn)來(lái)說(shuō),開(kāi)發(fā)個(gè)高性能的撮合引擎并沒(méi)什么難度舷蒲。

說(shuō)干就干裳凸,于是犀盟,利用業(yè)余時(shí)間慢慢開(kāi)發(fā)出了一款Golang版的高性能撮合引擎螃征,前前后后花了大概一個(gè)月的時(shí)間。再想想自己好久沒(méi)更新文章了略步,我的個(gè)人IP都已經(jīng)生銹了描扯,也應(yīng)該發(fā)大招磨一磨了。因此決定趟薄,干脆就以連載的方式绽诚,分享下我是如何設(shè)計(jì)與實(shí)現(xiàn)這款價(jià)值超5萬(wàn)的撮合引擎的。

本來(lái)竟趾,想發(fā)成掘金小冊(cè)憔购,收點(diǎn)稿費(fèi)宫峦,畢竟這是個(gè)具有很大商業(yè)價(jià)值的軟件岔帽,但問(wèn)了掘金的人員,他們目前不接收這類(lèi)主題导绷。最終決定免費(fèi)發(fā)布犀勒,還可以多發(fā)幾個(gè)渠道,說(shuō)不定還能給我多帶來(lái)些關(guān)注量妥曲。

好了贾费,下面開(kāi)始進(jìn)入撮合引擎系列的正題。

撮合引擎簡(jiǎn)介

撮合引擎是所有撮合交易系統(tǒng)的核心組件檐盟,不管是股票交易系統(tǒng)——包括現(xiàn)貨交易褂萧、期貨交易、期權(quán)交易等葵萎,還是數(shù)字貨幣交易系統(tǒng)——包括幣幣交易导犹、合約交易、杠桿交易等羡忘,以及各種不同的貴金屬交易系統(tǒng)谎痢、大宗商品交易系統(tǒng)等,雖然各種不同交易系統(tǒng)的交易標(biāo)的不同卷雕,但只要都是采用撮合交易模式节猿,都離不開(kāi)撮合引擎。

撮合引擎是可以具有通用性的漫雕,一套具有通用性的撮合引擎實(shí)現(xiàn)理論上可以應(yīng)用到任何撮合交易系統(tǒng)中滨嘱,而無(wú)需做任何代碼上的調(diào)整峰鄙。即是說(shuō),同一套撮合引擎實(shí)現(xiàn)太雨,既可以應(yīng)用在股票交易系統(tǒng)先馆,也可以應(yīng)用在數(shù)字貨幣交易系統(tǒng),可以用于現(xiàn)貨交易躺彬,也可以用于合約交易等煤墙。

那么,一套具有通用性的撮合引擎應(yīng)該具備哪些功能呢宪拥?確定該問(wèn)題的答案之前仿野,我們先簡(jiǎn)單梳理一下一個(gè)完整的交易流程是怎樣的?一般會(huì)包括以下步驟:

  1. 系統(tǒng)開(kāi)放某個(gè)交易標(biāo)的的交易功能她君。
  2. 用戶(hù)提交該交易標(biāo)的的買(mǎi)賣(mài)申報(bào)脚作,即委托單
  3. 系統(tǒng)驗(yàn)證委托單是否有效缔刹,包括交易標(biāo)的是否處于可交易的狀態(tài)球涛、訂單的價(jià)格和數(shù)量是否符合要求等。
  4. 確定該委托單的掛單(Maker)費(fèi)率和吃單(Taker)費(fèi)率校镐。
  5. 檢查用戶(hù)的資產(chǎn)賬戶(hù)情況亿扁,包括賬戶(hù)狀態(tài)是否交易受限,是否有足夠資金用于下單等鸟廓。
  6. 將詳細(xì)的委托單數(shù)據(jù)持久化到數(shù)據(jù)庫(kù)从祝,并凍結(jié)用戶(hù)賬戶(hù)中相應(yīng)數(shù)量的資金。
  7. 將委托單進(jìn)行撮合處理引谜,即在交易委托賬本(OrderBook)中尋找能與該委托單匹配成交的訂單牍陌,匹配的結(jié)果可能是:全部成交、部分成交或無(wú)匹配员咽。全部成交或部分成交時(shí)毒涧,可能在交易委托賬本中存在一個(gè)或多個(gè)匹配的訂單,即會(huì)產(chǎn)生一條或多條成交記錄贝室。當(dāng)無(wú)匹配或部分成交時(shí)契讲,委托單的部分?jǐn)?shù)據(jù)包括剩余未成交的數(shù)量會(huì)暫時(shí)保存到交易委托賬本中,等待與后續(xù)的委托單匹配撮合档玻。
  8. 將撮合產(chǎn)生的成交記錄持久化到數(shù)據(jù)庫(kù)怀泊,并根據(jù)歷史成交記錄生成市場(chǎng)數(shù)據(jù),如K線(xiàn)數(shù)據(jù)误趴、今日漲跌幅等霹琼。
  9. 更新數(shù)據(jù)庫(kù)中所有成交訂單的委托單數(shù)據(jù),以及更新訂單用戶(hù)的資產(chǎn)賬戶(hù)余額。
  10. 將更新的訂單數(shù)據(jù)枣申、市場(chǎng)數(shù)據(jù)等發(fā)送給到前臺(tái)售葡。

整個(gè)交易流程中涉及到多個(gè)服務(wù),包括用戶(hù)服務(wù)忠藤、賬戶(hù)服務(wù)挟伙、訂單服務(wù)、撮合服務(wù)模孩、市場(chǎng)數(shù)據(jù)服務(wù)等尖阔。其中,只有第7步是撮合引擎處理的榨咐。從單一職責(zé)原則來(lái)說(shuō)介却,撮合引擎就應(yīng)該只做一件事,那就是負(fù)責(zé)撮合訂單块茁。撮合之前的委托單持久化齿坷、凍結(jié)資金等,以及撮合之后生成K線(xiàn)數(shù)據(jù)等数焊,都不應(yīng)該屬于撮合引擎的職責(zé)永淌。

撮合競(jìng)價(jià)方式

撮合競(jìng)價(jià)方式一般有兩種,一是集合競(jìng)價(jià)佩耳,二是連續(xù)競(jìng)價(jià)遂蛀。股票交易系統(tǒng)一般會(huì)在不同交易時(shí)間段采用不同的競(jìng)價(jià)方式,比如在開(kāi)盤(pán)或收盤(pán)時(shí)采用集合競(jìng)價(jià)蚕愤,從而產(chǎn)生開(kāi)盤(pán)價(jià)收盤(pán)價(jià)答恶,其余時(shí)間采用連續(xù)競(jìng)價(jià)。而大多數(shù)字貨幣交易系統(tǒng)則沒(méi)有集合競(jìng)價(jià)萍诱,只有連續(xù)競(jìng)價(jià),開(kāi)盤(pán)價(jià)一般是在開(kāi)始交易之前就設(shè)定好的污呼。

集合競(jìng)價(jià)

所謂集合競(jìng)價(jià)裕坊,是指對(duì)一段時(shí)間內(nèi)接收的買(mǎi)賣(mài)委托單一次性集中撮合的競(jìng)價(jià)方式。以深滬的股票交易系統(tǒng)為例燕酷,在每個(gè)交易日的 9:15~9:25 期間是集合競(jìng)價(jià)時(shí)間籍凝。在該時(shí)間段內(nèi),系統(tǒng)陸續(xù)接收到的委托單不會(huì)即時(shí)成交苗缩,而是先將所有委托單按照價(jià)格優(yōu)先饵蒂、時(shí)間優(yōu)先的原則排序,并在此基礎(chǔ)上酱讶,找出一個(gè)基準(zhǔn)價(jià)格退盯,使它能同時(shí)滿(mǎn)足以下三個(gè)條件:

  1. 可實(shí)現(xiàn)最大成交量的價(jià)格;
  2. 高于該價(jià)格的買(mǎi)單與低于該價(jià)格的賣(mài)單能全部成交的價(jià)格;
  3. 與該價(jià)格相同的買(mǎi)方或賣(mài)方至少有一方全部成交的價(jià)格渊迁。

在 9:25 分結(jié)束的時(shí)候慰照,該基準(zhǔn)價(jià)格就被確定為成交價(jià)格,所有高于該價(jià)格的買(mǎi)單與低于該價(jià)格的賣(mài)單都將以該價(jià)格成交琉朽。未能成交的委托單毒租,則自動(dòng)轉(zhuǎn)入連續(xù)競(jìng)價(jià)。

不過(guò)箱叁,如果滿(mǎn)足以上三個(gè)條件的價(jià)格存在兩個(gè)或兩個(gè)以上呢墅垮?對(duì)此,深交所和上交所的處理方案有所不同耕漱,深交所會(huì)取距前收盤(pán)價(jià)最近的價(jià)格為成交價(jià)噩斟,而上交所則取使未成交量最小的價(jià)格為成交價(jià),如果未成交量最小的價(jià)格仍不止一個(gè)孤个,則取中間價(jià)為成交價(jià)剃允。

集合競(jìng)價(jià)的主要目的就是為了確定開(kāi)盤(pán)價(jià)或收盤(pán)價(jià)。

連續(xù)競(jìng)價(jià)

所謂連續(xù)競(jìng)價(jià)齐鲤,也是我們所熟悉的競(jìng)價(jià)方式斥废,是指對(duì)買(mǎi)賣(mài)委托單逐筆連續(xù)撮合的競(jìng)價(jià)方式。用戶(hù)的掛單给郊,只要滿(mǎn)足成交條件牡肉,就能即時(shí)成交。而集合競(jìng)價(jià)淆九,則要等到最后一刻才會(huì)成交统锤。

連續(xù)競(jìng)價(jià)時(shí),依然要滿(mǎn)足價(jià)格優(yōu)先炭庙、時(shí)間優(yōu)先的成交原則:

  1. 價(jià)格優(yōu)先:買(mǎi)單則價(jià)格較高者能優(yōu)先成交饲窿,賣(mài)單則是價(jià)格較低者能優(yōu)先成交。
  2. 時(shí)間優(yōu)先:買(mǎi)賣(mài)方向和價(jià)格相同的委托單焕蹄,先申報(bào)的委托單會(huì)比后申報(bào)的委托單優(yōu)先成交逾雄。

另外,買(mǎi)入價(jià)必須大于或等于賣(mài)出價(jià)才能撮合成交腻脏。當(dāng)買(mǎi)入價(jià)等于賣(mài)出價(jià)時(shí)鸦泳,成交價(jià)就是買(mǎi)入價(jià)或賣(mài)出價(jià)。當(dāng)買(mǎi)入價(jià)大于賣(mài)出價(jià)時(shí)永品,則還要參考前一筆成交價(jià)來(lái)確定最新成交價(jià)做鹰。假設(shè)買(mǎi)入價(jià)為 B,賣(mài)出價(jià)為 S鼎姐,前一筆成交價(jià)為 P钾麸,最新成交價(jià)為 N更振,那么:

  • 如果 P >= B,則 N = B
  • 如果 P <= S喂走,則 N = S
  • 如果 B > P > S殃饿,則 N = P

一套通用的撮合引擎應(yīng)該兩種競(jìng)價(jià)方式都支持,但對(duì)于同一交易標(biāo)的來(lái)說(shuō)芋肠,兩種競(jìng)價(jià)方式不能同時(shí)進(jìn)行乎芳,因此設(shè)計(jì)上需要考慮如何在兩種競(jìng)價(jià)方式之間切換,具體的實(shí)現(xiàn)思路在后續(xù)章節(jié)我們?cè)僬归_(kāi)來(lái)講帖池。

質(zhì)量需求

我們的撮合引擎除了要滿(mǎn)足以上所說(shuō)的功能需求奈惑,還應(yīng)該滿(mǎn)足一些質(zhì)量需求,尤其對(duì)可用性睡汹、可伸縮性性能的要求較高肴甸。另外,為了達(dá)到通用囚巴,也要滿(mǎn)足可復(fù)用性的需求原在。

先說(shuō)下可復(fù)用性,我們期望的是該撮合引擎既能用于股票交易系統(tǒng)彤叉,也能用于數(shù)字貨幣交易系統(tǒng)庶柿,既能用于幣幣交易,也能用于合約交易秽浇。因此浮庐,該撮合引擎要避免引入與具體系統(tǒng)強(qiáng)相關(guān)的業(yè)務(wù)邏輯,以加強(qiáng)它的可復(fù)用性柬焕。

再看看性能审残,要衡量一個(gè)撮合引擎的性能,就看它處理每個(gè)交易對(duì)的 TPS 有多高斑举,即每秒鐘能處理多少筆相同交易對(duì)的委托單搅轿。以前,基于數(shù)據(jù)庫(kù)的撮合技術(shù)懂昂,TPS 一般只有10筆/秒介时。而現(xiàn)在基本都是采用內(nèi)存撮合技術(shù),TPS 很容易就能達(dá)到1000筆/秒凌彬,如果使用獨(dú)占的高性能服務(wù)器,1萬(wàn)筆/秒甚至更高的 TPS 都不難達(dá)到循衰。

接著談?wù)効缮炜s性铲敛,我們的每一個(gè)撮合引擎既可以同時(shí)處理多個(gè)交易標(biāo)的,也可以只處理單個(gè)交易標(biāo)的会钝。當(dāng)交易標(biāo)的和并發(fā)量增多的時(shí)候伐蒋,可以增加服務(wù)器工三,部署成撮合引擎集群,分別用來(lái)處理不同的交易標(biāo)的先鱼,從而能夠?qū)崿F(xiàn)負(fù)載均衡俭正。

最后聊聊可用性,高可用主要體現(xiàn)在兩點(diǎn)焙畔,一是故障率要低掸读,二是對(duì)故障維修的時(shí)間要短。要降低故障率宏多,那撮合引擎就需要有較高的健壯性儿惫,對(duì)于可能導(dǎo)致引擎出故障的各種異常情況要考慮好并設(shè)計(jì)好解決方案。另外伸但,還可以采用多機(jī)熱備份技術(shù)來(lái)提高可用性肾请,而且要保證互備服務(wù)器之間的數(shù)據(jù)一致,那就需要引入內(nèi)存狀態(tài)機(jī)復(fù)制方案更胖,實(shí)現(xiàn)上會(huì)復(fù)雜很多铛铁。

不過(guò),我們并非一下子就要達(dá)到很高的質(zhì)量要求却妨,因?yàn)橐笤礁叨穑浼軜?gòu)和實(shí)現(xiàn)會(huì)越復(fù)雜。我們可以先從簡(jiǎn)單的版本開(kāi)始管呵,然后不斷升級(jí)迭代梳毙。

小結(jié)

我們目的是實(shí)現(xiàn)一套通用的撮合引擎,要支持集合競(jìng)價(jià)和連續(xù)競(jìng)價(jià)捐下,還要實(shí)現(xiàn)一些質(zhì)量需求账锹,提高系統(tǒng)的可復(fù)用性、性能坷襟、可伸縮性奸柬、可用性等。后續(xù)章節(jié)會(huì)對(duì)這些需求不斷深入探討其設(shè)計(jì)與實(shí)現(xiàn)婴程。另外廓奕,我們將采用不斷升級(jí)迭代的方式來(lái)設(shè)計(jì)和實(shí)現(xiàn)多個(gè)版本的撮合引擎。

留兩個(gè)思考題:

  1. 集合競(jìng)價(jià)結(jié)束的時(shí)候档叔,如果不存在符合那三個(gè)條件的基準(zhǔn)價(jià)格桌粉,那開(kāi)盤(pán)價(jià)又將如何確定?
  2. 對(duì)于單個(gè)交易對(duì)衙四,是否可通過(guò)橫向增加服務(wù)器的方式提高其性能铃肯?

作者的個(gè)人博客

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市传蹈,隨后出現(xiàn)的幾起案子押逼,更是在濱河造成了極大的恐慌步藕,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挑格,死亡現(xiàn)場(chǎng)離奇詭異咙冗,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)漂彤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)雾消,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人显歧,你說(shuō)我怎么就攤上這事仪或。” “怎么了士骤?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵范删,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我拷肌,道長(zhǎng)到旦,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任巨缘,我火速辦了婚禮添忘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘若锁。我一直安慰自己搁骑,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布又固。 她就那樣靜靜地躺著仲器,像睡著了一般。 火紅的嫁衣襯著肌膚如雪仰冠。 梳的紋絲不亂的頭發(fā)上乏冀,一...
    開(kāi)封第一講書(shū)人閱讀 51,727評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音洋只,去河邊找鬼辆沦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛识虚,可吹牛的內(nèi)容都是我干的肢扯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼担锤,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼鹃彻!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起妻献,我...
    開(kāi)封第一講書(shū)人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蛛株,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后育拨,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體谨履,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年熬丧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了笋粟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡析蝴,死狀恐怖害捕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情闷畸,我是刑警寧澤尝盼,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站佑菩,受9級(jí)特大地震影響盾沫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜殿漠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一赴精、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧绞幌,春花似錦蕾哟、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至菇夸,卻和暖如春琼富,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背庄新。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工鞠眉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人择诈。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓械蹋,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親羞芍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哗戈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 撮合引擎開(kāi)發(fā):開(kāi)篇撮合引擎開(kāi)發(fā):MVP版本撮合引擎開(kāi)發(fā):數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)撮合引擎開(kāi)發(fā):對(duì)接黑箱撮合引擎開(kāi)發(fā):解密黑箱流...
    Keegan小鋼閱讀 921評(píng)論 0 50
  • 撮合系統(tǒng)設(shè)計(jì) 撮合技術(shù) 摘要: 撮合技術(shù)主要是從數(shù)據(jù)庫(kù)撮合技術(shù)向內(nèi)存撮合技術(shù)發(fā)展,這是因?yàn)閿?shù)據(jù)庫(kù)撮合技術(shù)越來(lái)越無(wú)法...
    elva123閱讀 5,682評(píng)論 1 10
  • 來(lái)源:實(shí)戰(zhàn)財(cái)經(jīng) 轉(zhuǎn)自 優(yōu)維金融空間 導(dǎo)讀:包含銀行系金融知識(shí)和基金證券類(lèi)知識(shí)大全荷科。 目錄 第一部分:銀行系金融知識(shí)...
    1e662a7de34a閱讀 9,924評(píng)論 0 9
  • 轉(zhuǎn)載自:https://yq.aliyun.com/articles/60653 摘要:撮合技術(shù)主要是從數(shù)據(jù)庫(kù)撮合...
    神仙蘇醒閱讀 8,012評(píng)論 1 25
  • 在我們的鄉(xiāng)土社會(huì)唯咬,親密社群的團(tuán)結(jié)性就倚賴(lài)于大家之間都相互的拖欠著未了的人情纱注。朋友之間搶著回賬,意思是要對(duì)方欠自己一...
    飯團(tuán)兒Funcy閱讀 14,149評(píng)論 0 0