185
技術社區[雲棲]
回形針換別墅 - openBarter (古人的物物交換市場) 泛撮合交易係統
標簽
PostgreSQL , 物物交換 , 無貨幣時代 , openBarter , 交易係統 , 撮合交易 , 證券 , limit order , market order , central limit order book (CLOB)
背景
很久以前有一則這樣的新聞:一個男孩用一個回形針,換回了一套別墅,他是怎麼做到的呢?
先不管他是怎麼做到的,這讓我聯想到了古人物物交換的場景,沒錯古人還沒有發明貨幣之前,都是通過物物交換的方式來得到其他人的東西的。(但是這樣效率實在太低了)。另外,現在的證券交易也與之類似,隻是更加的簡化了的交換係統。
撮合交易是證券交易係統最頻繁,也是非常複雜的一個業務。撮合交易是咋回事呢:
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,你一定能搞定的,有空閑時間會繼續思考這個場景,非常有意思。
參考
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