# PyXchange #
Simulator of limit orderbook written in **Python** and **C++14**, using **Twisted** framework and **Boost** libraries, namely **boost::python** and **boost::multi_index** container.
The project is participating on *WOOD & Company Coding Challenge* [http://codingchallenge.wood.cz/]
## Main features ###
Matching engine implements simple limit orderbook with price/time priority matching algorithm.
Messaging protocol uses python dictionaries or JSON objects
The library can be used in two ways:
* as python package for scripting
* as a standalone TCP server
The TCP server is single thread, asynchronous, event driven. The server listens on three interfaces:
1. **Trading** interface for managing limit orders and market orders
2. **Extended trading** interface (**additional feature**: trader's orders are canceled, when the trader disconnects)
3. **Market data** interface, which is read-only
### Supported message types on trading interface ###
* `ping`/`pong` (heartbeat)
* `createOrder`
* `marketOrder`
* `cancelOrder`
* `cancelAll`
### Supported message types on market data interface ###
* `orderbook` (price level aggregated summary)
* `trade`
## Requirements ##
* Twisted framework
* Python 2.7 headers
* Boost libraries
* GCC with C++14 suport
* CMake
## Installation ##
### Build with CMake ###
```
$ mkdir build
$ cd build
$ cmake ..
$ make -j4
$ make install
```
### Creating `deb` package with CMake ###
```
$ make package
$ dpkg -i ./pyxchange-0.1.0-Linux.deb
```
### Build with Distutils ###
```
$ python setup.py build
$ python setup.py install
```
### Creating `rpm` package ###
```
$ python setup.py bdist_rpm
$ rpm -ivh ./dist/pyxchange-0.1.0-1.x86_64.rpm
```
## Introduction to scripting API ##
### Creating `Matcher` instance
Matcher holds orderbook with orders. It also holds list of connected traders and clients as well.
```
>>> import logging
>>> logging.basicConfig(level=logging.DEBUG)
>>> from pyxchange import engine
>>> matcher = engine.Matcher()
INFO:pyxchange:OrderBook is ready
INFO:pyxchange:Matcher is ready
>>> matcher
<pyxchange.engine.Matcher object at 0x7f1be6ff2050>
>>>
```
### Creating `Trader` instance and sending heartbeat messages (ping/pong)
```
>>> from pyxchange import utils
>>> t1 = utils.DequeHandler()
>>> trader1 = engine.Trader(matcher, 'trader1', t1)
INFO:pyxchange:trader1 connected
>>> trader1
<pyxchange.engine.Trader object at 0x7f1be6ff20a8>
>>> trader1.ping()
>>> t1.messages.popleft()
{'message': 'pong'}
>>>
```
### Creating new order ###
OrderId must be unique within trader and bid/ask orders.
Side is `BUY` or `SELL`, price is positive integer, quantity is positive integer.
```
>>> trader1.createOrder({ 'side': 'BUY', 'price': 100, 'quantity': 10, 'orderId': 1 })
DEBUG:pyxchange:trader1 added order bid:10@100
>>> t1.messages.popleft()
{'report': 'NEW', 'orderId': 1, 'message': 'executionReport', 'quantity': 10}
```
### Triggering a match event ###
Trader2 creates sell order, which is matched with order of trader1.
Remaining quantity is inserted to the orderbook.
```
>>> t2 = utils.DequeHandler()
>>> trader2 = engine.Trader(matcher, 'trader2', t2)
INFO:pyxchange:trader2 connected
>>> trader2
<pyxchange.engine.Trader object at 0x7f1be50dc3c0>
>>> trader2.createOrder({ 'side': 'SELL', 'price': 90, 'quantity': 20, 'orderId': 1 })
DEBUG:pyxchange:Execution 10@100
DEBUG:pyxchange:trader2 added order ask:10@90
>>> t2.messages.popleft()
{'report': 'FILL', 'orderId': 1, 'message': 'executionReport', 'price': 100, 'quantity': 10}
>>> t2.messages.popleft()
{'report': 'NEW', 'orderId': 1, 'message': 'executionReport', 'quantity': 10}
>>>
```
### Canceling order ###
```
>>> trader2.cancelOrder({ 'side': 'SELL', 'orderId': 1 })
DEBUG:pyxchange:trader2 cancelled order ask:10@90
>>> t2.messages.popleft()
{'report': 'CANCELED', 'orderId': 1, 'message': 'executionReport', 'quantity': 10}
>>> trader1.cancelAll()
>>>
```
### Creating market order ###
```
>>> trader1.createOrder({ 'side': 'BUY', 'price': 100, 'quantity': 10, 'orderId': 2 })
DEBUG:pyxchange:trader1 added order bid:10@100
>>> trader1.createOrder({ 'side': 'BUY', 'price': 150, 'quantity': 20, 'orderId': 3 })
DEBUG:pyxchange:trader1 added order bid:20@150
>>> trader2.marketOrder({ 'side': 'SELL', 'price': 150, 'quantity': 15 })
DEBUG:pyxchange:trader2 added market order ask:15
DEBUG:pyxchange:Execution 15@150
>>>
```
### Connecting market-data client ###
New client receives complete price level aggregated data from actual orderbook.
Later it receives only updates on individual price levels and trade summaries.
In case more clients connected to matching engine, they will be notified in random order.
```
>>> c1 = utils.DequeHandler()
>>> client1 = engine.Client(matcher, 'client1', c1)
INFO:pyxchange:client1 connected
>>> client1
<pyxchange.engine.Client object at 0x7f1be50dc520>
>>> c1.messages
deque([{'price': 150, 'type': 'orderbook', 'side': 'bid', 'quantity': 5},
{'price': 100, 'type': 'orderbook', 'side': 'bid', 'quantity': 10}])
>>>
```
## Introduction to standalone TCP server ##
### Running the server ###
```
$ pyxchange_server.py
2016-06-20 19:40:29,516 pyxchange INFO OrderBook is ready
2016-06-20 19:40:29,516 pyxchange INFO Matcher is ready
2016-06-20 19:40:29,518 pyxchange INFO Listeting on *:7000 (ext trading)
2016-06-20 19:40:29,518 pyxchange INFO Listeting on *:7001 (trading)
2016-06-20 19:40:29,519 pyxchange INFO Listeting on *:7002 (market-data)
```
### Connecting the trader ###
```
$ telnet localhost 7001
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
{"message": "ping"}
{"message": "pong"}
{"message": "createOrder", "side": "BUY", "price": 100, "quantity": 20, "orderId": 1 }
{"report": "NEW", "orderId": 1, "message": "executionReport", "quantity": 20}
```
### Connecting the client (market data) ###
```
$ telnet localhost 7002
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
{"price": 100, "type": "orderbook", "side": "bid", "quantity": 20}
```
### More options of the server ###
```
$ pyxchange_server.py --help
Usage: pyxchange_server.py [options]
Options:
-h, --help show this help message and exit
--listen-private-ext=ip:port
Listen on extended private (trading) interface
--listen-private=ip:port
Listen on private (trading) interface
--listen-public=ip:port
Listen on public (market-data) interface
--log=file Log filename
--format=format Log format
-d, --debug Enable debug level
```
### Performance ###
Twisted -based server is very fast, however because the event-loop is single threaded, the performance is limited to the performance of single CPU.
The design of matching engine is trying to get the best from single CPU. The memory usage is as low as possibble.
On author's older workstation, matching engine is able to process 100k random `createOrder` messages in ~27 seconds (some of them trigger trades).
More traders and clients connected will naturally cause performance decrease of matching engine.
The performance test can be run from tests/ directory:
```
$ time python tests/performance_test.py -n 100000
real 0m26.724s
user 0m7.996s
sys 0m0.152s
```
## Implementation details ##
**Boost::python** is powerful framework for exposing C++ code to Python. The library exposes three classes to Python: Matcher, Trader and Client.
From Python side, instances of Matcher, Trader and Client are managed by shared pointers (`std::shared_ptr`).
Matcher controls creating of Clients, validation and dispatch of (JSON) messages.
OrderBook object within Matcher contains two **boost::multi_index** containers:
1. *BidOrderContainer* - greatest price first, lowest price last
2. *AskOrderContainer* - lowest price first, greatest price last
Both containers are very similar. They are indexed by multip
没有合适的资源?快使用搜索试试~ 我知道了~
以Python和C++编写的限制订单簿和匹配引擎.zip
共41个文件
cpp:14个
hpp:14个
py:8个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 107 浏览量
2023-03-31
22:45:40
上传
评论
收藏 41KB ZIP 举报
温馨提示
使用Twisted、boostpython和boostmulti_index以Python和C++编写的限制订单簿和匹配引擎
资源推荐
资源详情
资源评论
收起资源包目录
使用Twisted、boostpython和boostmulti_index以Python和C++编写的限制订单簿和匹配引擎.zip (41个子文件)
PyXchange-master
CMakeLists.txt 3KB
setup.py 2KB
src
order
Order.cpp 5KB
Order.hpp 1KB
PyXchange.cpp 2KB
client
BaseClient.cpp 2KB
Client.hpp 1KB
Trader.cpp 2KB
Client.cpp 3KB
BaseClient.hpp 1KB
Trader.hpp 915B
order_container
OrderContainerFwd.hpp 2KB
OrderContainer.hpp 3KB
utils
Constants.hpp 4KB
Exception.hpp 3KB
Side.hpp 2KB
Json.hpp 1KB
logger
Logger.hpp 3KB
Logger.cpp 975B
orderbook
OrderBookAggr.cpp 2KB
OrderBook.cpp 3KB
OrderBook.hpp 2KB
OrderBookCancelAll.cpp 2KB
OrderBookCancel.cpp 2KB
OrderBookExec.cpp 3KB
OrderBookAggrAll.cpp 2KB
OrderBookInsert.cpp 2KB
matcher
Matcher.cpp 6KB
Matcher.hpp 2KB
PyXchange.hpp 2KB
LICENSE 1KB
tests
unit_test.py 12KB
performance_test.py 4KB
examples
pyxchange_example.py 2KB
bin
pyxchange_server.py 3KB
MANIFEST.in 284B
.gitignore 115B
pyxchange
utils.py 4KB
__init__.py 203B
server.py 3KB
README.md 9KB
共 41 条
- 1
资源评论
快撑死的鱼
- 粉丝: 1w+
- 资源: 9154
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 电子设计竞赛的单相不间断电源设计
- cutcamera1715961370938.png
- 基于MATLAB的图像处理课程设计报告.doc
- tensorflow-gpu-2.6.0-cp38-cp38-manylinux2010-x86-64.whl
- mmexport1715960553858.png
- tensorflow-gpu-2.6.0-cp37-cp37m-manylinux2010-x86-64.whl
- 通过 .NET 应用程序中的源代码查找 SQL 注入
- 电子设计竞赛2007年B题 无线识别装置.doc
- Wox全局搜索工具,一款win下的全局搜索软件
- 使用高级集群管理 (ACM) 模板来管理用户、组和命名空间
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功