閱讀185 返回首頁    go 技術社區[雲棲]


回形針換別墅 - openBarter (古人的物物交換市場) 泛撮合交易係統

標簽

PostgreSQL , 物物交換 , 無貨幣時代 , openBarter , 交易係統 , 撮合交易 , 證券 , limit order , market order , central limit order book (CLOB)


背景

很久以前有一則這樣的新聞:一個男孩用一個回形針,換回了一套別墅,他是怎麼做到的呢?

pic

先不管他是怎麼做到的,這讓我聯想到了古人物物交換的場景,沒錯古人還沒有發明貨幣之前,都是通過物物交換的方式來得到其他人的東西的。(但是這樣效率實在太低了)。另外,現在的證券交易也與之類似,隻是更加的簡化了的交換係統。

撮合交易是證券交易係統最頻繁,也是非常複雜的一個業務。撮合交易是咋回事呢:

https://baike.baidu.com/item/%E6%92%AE%E5%90%88%E6%88%90%E4%BA%A4%E4%BB%B7

概述

什麼是撮合成交價?

當買入價等於賣出價時,成交價就是買入價或賣出價,這一點大家是不會有疑義的。問題是當買入價大於賣出價時成交價應該如何確定?

舉例說明

計算機在撮合時實際上是依據前一筆成交價而定出最新成交價的。如果前一筆成交價低於或等於賣出價,則最新成交價就是賣出價;如果前一筆成交價高於或等於買入價,則最新成交價就是買入價;如果前一筆成交價在賣出價與買入價之間,則最新成交價就是前一筆的成交價。下麵不妨以例明之。

買方出價1399點,賣方出價是1397點。如果前一筆成交價為1397或1397點以下,最新成交價就是1397點;如果前一筆成交價為1399或1399點以上,則最新成交價就是1399點;如果前一筆成交價是1398點,則最新成交價就是1398點。

這種撮合方法的好處是既顯示了公平性,又使成交價格具有相對連續性,避免了不必要的無規律跳躍。

(也就是說:用戶可能賣到比委托價更高的價格,而買家則可能買到比委托價更低的價格。 關鍵看上一次交易的價格,以及用戶委托的賣出和買入價。)

撮合成交原則

中金所計算機交易係統在撮合成交時,基本原則按價格優先、時間優先的原則進行(有的情況下為了控製風險的需要,會采取在價格相同情況下,平倉單優先)。

該原則的完整解釋是:買家出價高的優先,賣家出價低的優先,如果出價相同則掛單時間最早的優先。

舉例說明:

例如,某交易者賣出3月滬深300指數期貨10手,掛出價格為1400點,交易者甲掛出10手買單,報價為1398點;隨後,交易者乙也想買10手,掛價為1399點,由於乙的價格比甲高,按照價格優先原則,乙的單子排在甲的前麵;後來,丙也掛出10手買單,價格同樣為1399點,由於掛價與乙相同,按照時間優先原則,隻能排在乙的後麵,但仍在甲之前。假如這時有一個交易者以1397點賣出10手,買方優先成交者就是乙。

回到古代 - 沒有貨幣的物物交換

相對撮合交易係統,還有一個更古老、更複雜的係統,物物交換係統,因為在古代還沒有貨幣的時候,人們要像得到其他人生產的東西,必須以交換的形式進行。

例如:

A生產棉花,B生產玉米,C生產小麥。

A需要小麥,B需要棉花,C需要玉米。

怎麼交易呢?

A和B更換,然後A和C換,然後B和C換。

商品越多,換法可能會更加複雜。

openBarter

openBarter是一個物物交換係統插件,撮合物物交換的交易。

原理詳見:

https://olivierch.github.io/openBarter/

https://api.pgxn.org/src/openbarter/openbarter-0.8.2/doc/doc-ob.pdf

https://api.pgxn.org/src/openbarter/openbarter-0.7.0/doc/barterUtopia.pdf

1、openBarter用到了4張表 (torder, tstack, tmvt, towner):

The order book stored in a table torder

a stack accepting orders as input tstack

a stack tmvt storing movements to be consumed.

A table towner is used to store names of owners of the orders of the order book。

2、通過UDF實現的接口:

報價:

Interactions with the order book can be submissions of orders to be executed or administrative tasks.

Orders submitted are recorded in a table tstack representing a stack.

The stack is consumed to execute orders.

撮合交易:

Results of interactions are recorded in the table tmvt.

Records of this table represent movements for barter orders, a barter order producing several movements.

A record of this table can also represent the result of other interactions.

小結

1、證券交易,由於存在委托買賣價格不一致的情況,實際上需要根據上一比交易的價格,以及委托價來定,所以並不是絕對隻接受委托價。為了撮合交易,滿足買低不買高,賣高不賣低的原則,需要記錄每個股票上一比交易的成交價(撮合價)。同時還需要滿足時間優先、價格優先的原則。

2、快速匹配,消除訂單是物物交換係統、證券交易撮合委托交易的核心訴求。

3、幾個股票交易相關的術語

https://www.zhihu.com/question/24118706

作者:放開那個獼猴桃

鏈接:https://www.zhihu.com/question/24118706/answer/30372783

來源:知乎

著作權歸作者所有。商業轉載請聯係作者獲得授權,非商業轉載請注明出處。

Market Order: 市價訂單。就是如果你下單後,基本上會馬上執行的,該訂單價格就是下單後的市場價格。

Limit order: 限價訂單。這個也容易理解,就是限定一個價格買入和賣出。比如某股票市價可能是15,你希望大跌後買入,你想設定10刀,這時候就用limit order,買入價格就是10刀。偶爾可能有一點點的不同,比如9.99這樣。如果你是買入,實際買入價格應該和你設定的limit price一樣或略低,如果你是賣出,實際賣出價格應該和你設定的limit price一樣或略高,

Stop order(stop-loss order): 通常用來止損或者鎖定利潤。和limit order最大的差別是, Limit order在你下單後你的券商是馬上將這個訂單推送到市場。但是stop order不是,提交stop order後,這個訂單在券商這裏,拿下跌止損來說,比如當前股價是15,你希望如果股價下跌,最多損失5刀每股,你設定stop order price是10,隻有當股票大跌的時候並且跌穿10刀的時候,這時候券商會將訂單推向市場,成為一個market order, 以低於10刀的價格盡快賣出。但是券商無法保證賣出價格是多少。

stop limit order: 可以這麼理解stop order是一個trigger,觸發條件, limit order是你嚴格限製的價格,券商隻能按照你設置的limit price來買賣(可能會有微小差異,可以忽略)。所以stop limit order就是給你更多的控製權,你設定2個價格stop price和limit price,當達到stop price的時候,這時候這個stop limit order 就成為了一個limit order,接下來的行為和limit order一樣了.比如你15買入一隻股票,股票在下跌途中,你想在10刀止損,但是不想股票跌到10刀就馬上止損,因為股票下跌過程中也是波動的,如果跌到10刀馬上反彈了呢,止損止在最低點怎麼辦?你可以設定stop price,比如9.5刀,隻有跌穿9.5刀後,然後才執行limit order。

PS:stop order不是在券商手裏,而是在market maker手裏,券商已經將stop order route到市場中了,給了做市商。

4、撮合係統和交易係統不同,買賣雙方是需要撮合的,撮合係統類似紅娘,牽線搭橋。

一個簡單的設計如下:

買方報價,為了提高並發度,每個股票代碼一張表:

create table buy_000001 (  -- 每個股票代碼一個表    
  uid int,          -- 用戶ID    
  bucket int,       -- 報價數量    
  price numeric,    -- 報價    
  ts timestamp,     -- 時間    
  order_type int2   -- 報價類別(限價、市價等)    
);    

賣方報價,為了提高並發度,每個股票代碼一張表:

create table sell_000001 (  -- 每個股票代碼一個表    
  uid int,          -- 用戶ID    
  bucket int,       -- 報價數量    
  price numeric,    -- 報價    
  ts timestamp,     -- 時間    
  order_type int2   -- 報價類別(限價、市價等)    
);    

撮合:

do language plpgsql $$    
declare    
  聲明 遊標1 buy order by ts    
  聲明 遊標2 sell order by ts    
begin    
  loop 遊標1    
    loop 遊標2    
      邏輯    
      更新、刪除 複合條件的 遊標1、遊標2 的current tuple.    
      符合條件後退出loop遊標2(例如該筆BUY已撮合完成)    
    end loop;    
    符合條件後退出loop遊標1(例如sell遊標已沒有數據)    
  end loop;    
end;    
$$;    

每隻股票的交易量也是驚人的,每分鍾交易百萬筆是很常見的,要做好撮合係統,還需要繼續探索和良好的設計,加油PostgreSQL,你一定能搞定的,有空閑時間會繼續思考這個場景,非常有意思。

pic

參考

https://baike.baidu.com/item/%E6%92%AE%E5%90%88%E6%88%90%E4%BA%A4%E4%BB%B7

https://www.zhihu.com/question/24118706

https://olivierch.github.io/openBarter/

https://api.pgxn.org/src/openbarter/openbarter-0.8.2/doc/doc-ob.pdf

https://api.pgxn.org/src/openbarter/openbarter-0.7.0/doc/barterUtopia.pdf

最後更新:2017-09-18 00:04:37

  上一篇:go  使用 Eureka 實現服務注冊與發現
  下一篇:go  海量用戶實時定位和圈人 - 團圓社會公益係統(位置尋人\圈人)