高频量化交易系统 是一个基于 C++20 实现的量化交易系统模拟项目,主要面向低延迟交易场景,完整模拟了量化交易系统中客户端与交易所之间的核心交互流程。系统整体由**交易所端(Exchange)和交易客户端端(Trading)**两大部分组成,涵盖了行情接收、策略决策、订单管理、风控校验、订单发送、撮合成交、订单响应以及市场行情回传等关键环节。
系统运行过程中,客户端首先接收市场行情,并根据策略决定是否下单或撤单;在正式发单前,请求会先经过 OrderManager 和 RiskManager 完成订单管理与风控检查;通过校验后,订单通过 TCP 发送至交易所端,由交易所完成订单接收、订单簿维护和撮合处理。撮合结果一方面以订单响应的形式返回客户端,另一方面以市场行情更新的形式继续发布,客户端再根据新的订单状态和市场状态进入下一轮决策,从而形成完整的交易闭环。
在技术实现上,项目采用现代 C++20 标准,结合多线程、无锁队列、TCP 通信、多播通信、内存优化等高性能设计手段,提升了系统的消息处理效率与整体吞吐能力。该项目体现了量化交易系统从行情驱动到撮合反馈的完整业务链路。
- 高性能: 使用无锁队列、内存池等技术确保低延迟
- 多线程: 各主要组件在独立线程中运行,充分利用多核处理器
- 网络通信: 支持TCP和多播通信,实现高效的数据传输
- 模块化设计: 系统各组件高度模块化,便于扩展和维护
- 风险管理: 内置风险控制机制,保障交易安全
- 多种交易策略: 支持做市商(Market Maker)和流动性接受者(Liquidity Taker)等不同策略
- 现代C++: 采用C++20标准,利用现代C++特性提高代码质量和性能
系统分为以下几个主要模块:
提供了整个系统所需的基础设施和工具类:
- 无锁队列 (lf_queue): 用于组件间的高性能通信
- 内存池 (mem_pool): 高效的内存管理
- 日志系统 (logging): 系统日志记录
- 网络通信: 支持TCP和多播通信
- 线程工具: 线程管理和同步
- 时间工具: 高精度时间管理
模拟了一个完整的交易所系统,包括:
- 匹配引擎: 处理订单匹配和执行
- 市场数据: 生成和发布市场数据
- 订单服务器: 处理客户端订单请求
实现了交易策略和订单管理:
- 交易引擎: 交易系统的核心,协调各组件工作
- 市场数据消费者: 接收和处理市场数据
- 订单网关: 发送订单到交易所
- 策略组件: 包括市场做市商、流动性提供者、订单管理、风险管理、持仓管理和特征引擎
包含用于测试系统各组件性能的基准测试工具。
- Linux操作系统(推荐Ubuntu 20.04或更高版本)
- GCC 10.0或更高版本(支持C++20)
- CMake 3.16或更高版本
补充:我们提供的源码是在 windows下以压缩包的形式,如何将 windows 中的文件和 Linux 中的文件共享。
对于**.tar.gz的压缩包如何解压**
tar -xzvf fileName.tar.gz如何打包并压缩
tar -czvf fileName.tar.gz fileName
c创建
v显示过程(可不要)
f指定文件名
-
进入项目目录
cd cppquant -
创建并进入构建目录
mkdir build cd build -
配置和编译项目
cmake .. make -j4
-
运行测试(可选)
ctest
./exchange_main交易所程序启动后,把“撮合引擎、订单服务器、行情发布、快照模块、各自的日志线程”全都创建好了,并打印了线程的 CPU 绑定信息(线程名称,已经线程ID);
当前 to -1 表示不固定绑核,由系统调度。
scripts/ 项目启动与测试脚本
├── build.sh 完整构建脚本(含 clean)
├── no_clean_build.sh 项目构建脚本,作用是:分别编译 Release 和 Debug 两个版本
├── run_exchange_and_clients.sh 一键启动交易所与客户端
├── run_clients.sh 启动交易客户端(可以批量启用多个,详解看脚本具体实现)
└── run_benchmarks.sh 执行性能测试脚本cd scripts
# 运行脚本
bash run_exchange_and_clients.sh可运行提供的脚本run_clients.sh 。
./trading_main CLIENT_ID ALGO_TYPE [CLIP_1 THRESH_1 MAX_ORDER_SIZE_1 MAX_POS_1 MAX_LOSS_1] [CLIP_2 THRESH_2 MAX_ORDER_SIZE_2 MAX_POS_2 MAX_LOSS_2] ...
# 示例
/*
启动 1 号交易客户端,并让它用 MAKER 做市策略运行;后面每 5 个数字是一组参数,给一个交易标的配置策略参数和风控参数。
./trading_main 1 MAKER \
100 0.6 150 300 -100 \
60 0.6 150 300 -100 \
150 0.5 250 600 -100 \
200 0.4 500 3000 -100 \
1000 0.9 5000 4000 -100 \
300 0.8 1500 3000 -100 \
50 0.7 150 300 -100 \
100 0.3 250 300 -100
*/
#启动客户端5 , RANDOM 的作用就是主动往市场里打一些随机订单。
./trading_main 5 RANDOM参数说明:
CLIENT_ID: 客户端标识符ALGO_TYPE: 算法类型(MAKER/TAKER/RANDOM)- 后续参数以组为单位,每组包含5个参数,对应一个交易工具的配置:
CLIP_N: 价格剪裁参数,用于限制订单价格偏离市场价格的范围THRESH_N: 阈值参数,用于决定交易策略的触发条件MAX_ORDER_SIZE_N: 最大订单大小,用于风险控制MAX_POS_N: 最大仓位大小,用于风险控制MAX_LOSS_N: 最大允许损失,用于风险控制
5 号客户端已经成功启动,并且其核心业务线程和日志线程均已创建完成。后续操作是自动的,不需要我们继续进行输入。
- 1.
MarketDataConsumer自动接收交易所发布的行情; - 2.
TradeEngine自动根据行情更新本地状态; - 3.
MAKER策略自动判断是否下单/撤单; - 4.
OrderManager和RiskManager自动做订单管理与风控检查; - 5.
OrderGateway自动把订单发给交易所; - 6.交易所自动撮合并返回响应;
- 7.客户端再根据新行情和新订单状态继续下一轮决策;
交易所、客户端运行之后,各个核心模块各自输出运行日志。
简单说明
├── exchange_main.log # 交易所端日志,记录交易所主程序本身的启动信息,主线程的基本运行信息
├── exchange_market_data_publisher.log # 记录交易所发布市场行情的过程,记录哪些盘口变化、成交信息被广播出去
├── exchange_matching_engine.log # 订单有没有进入撮合引擎,撮合引擎有没有真正处理订单
├── exchange_order_server.log # 客户端和交易所之间的订单通信是否正常
└── exchange_snapshot_synthesizer.log # 记录市场快照生成过程,主要是给客户端做行情恢复用的
└── trading_main_5.log # 记录 client_id = 5 这个客户端的启动信息
└── trading_engine_5.log # 记录客户端交易引擎的核心处理流程,记录接收到的市场更新等
└── trading_market_data_consumer_5.log # 客户端有没有正常收行情,行情链路是不是稳定
└── trading_order_gateway_5.log # 订单通信日志
# 为什么有些日志后面带 _5
因为源码里客户端日志文件名是按 client_id 拼出来的1.先看客户端有没有把单发出去trading_order_gateway_5.log
最早的:
Sending cid:5 seq:1 ... type:NEW client:5 ticker:1 ...
/home/xiaosu/project/cppquant/trading/order_gw/order_gateway.cpp:63 run() 17:22:58.502417495 Sending cid:5 seq:1 MEClientRequest [type:NEW client:5 ticker:1 oid:5000 side:SELL qty:28 price:167]
17:22:58.502437689 RDTSC Trading_TCPSocket_send 1698
17:22:58.502441093 TTT T12_OrderGateway_TCP_write 1774516978502441057
/home/xiaosu/project/cppquant/common/tcp_socket.cpp:71 sendAndRecv() 17:22:58.502488872 send socket:6 len:38
/home/xiaosu/project/cppquant/common/tcp_socket.cpp:63 sendAndRecv() 17:22:58.515416045 read socket:6 len:50 utime:1774516978515415929 ktime:1774516978512628000 diff:2787929
17:22:58.515433096 TTT T7t_OrderGateway_TCP_read 1774516978515433054
/home/xiaosu/project/cppquant/trading/order_gw/order_gateway.cpp:105 recvCallback() 17:22:58.515441216 Received socket:6 len:50 1774516978512628000
/home/xiaosu/project/cppquant/trading/order_gw/order_gateway.cpp:111 recvCallback() 17:22:58.515453676 Received OMClientResponse [seq:1 MEClientResponse [type:ACCEPTED client:5 ticker:1 coid:5000 moid:1 side:SELL exec_qty:0 leaves_qty:28 price:167]]
17:22:58.515461959 TTT T8t_OrderGateway_LFQueue_write 1774516978515461927
17:22:58.515464235 RDTSC Trading_OrderGateway_recvCallback 84894
17:22:58.522429026 TTT T11_OrderGateway_LFQueue_read 17745169785224289462.看交易所有没有收到并处理exchange_order_server.log
- Received OMClientRequest [seq:1 ... type:NEW client:5 ...]
- 随后写入 FIFO 并返回响应
- 还能看到撮合引擎真正处理了这些请求,Processing MEClientRequest [type:NEW client:5 ...]
/home/xiaosu/project/cppquant/exchange/order_server/order_server.h:89 run() 17:22:32.703349585
/home/xiaosu/project/cppquant/common/tcp_server.cpp:77 poll() 17:22:44.526736070 EPOLLIN listener_socket:11
/home/xiaosu/project/cppquant/common/tcp_server.cpp:105 poll() 17:22:44.526778787 have_new_connection
/home/xiaosu/project/cppquant/common/tcp_server.cpp:116 poll() 17:22:44.526825044 accepted socket:12
/home/xiaosu/project/cppquant/common/tcp_server.cpp:105 poll() 17:22:44.864972428 have_new_connection
/home/xiaosu/project/cppquant/common/tcp_socket.cpp:63 sendAndRecv() 17:22:58.506419127 read socket:12 len:38 utime:1774516978506418952 ktime:1774516978502471000 diff:3947952
17:22:58.506439355 TTT T1_OrderServer_TCP_read 1774516978506439316
/home/xiaosu/project/cppquant/exchange/order_server/order_server.h:149 recvCallback() 17:22:58.506442266 Received socket:12 len:38 rx:1774516978502471000
/home/xiaosu/project/cppquant/exchange/order_server/order_server.h:160 recvCallback() 17:22:58.506460697 Received OMClientRequest [seq:1 MEClientRequest [type:NEW client:5 ticker:1 oid:5000 side:SELL qty:28 price:167]]
17:22:58.506548775 RDTSC Exchange_FIFOSequencer_addClientRequest 1224
/home/xiaosu/project/cppquant/exchange/order_server/fifo_sequencer.h:93 sequenceAndPublish() 17:22:58.506553152 Processing 1 requests.
/home/xiaosu/project/cppquant/exchange/order_server/fifo_sequencer.h:103 sequenceAndPublish() 17:22:58.506559887 Writing RX:1774516978502471000 Req:MEClientRequest [type:NEW client:5 ticker:1 oid:5000 side:SELL qty:28 price:167] to FIFO.
17:22:58.508444770 TTT T2_OrderServer_LFQueue_write 1774516978508444725
17:22:58.508455699 RDTSC Exchange_FIFOSequencer_sequenceAndPublish 7013452
17:22:58.512563569 TTT T5t_OrderServer_LFQueue_read 17745169785125635213.客户端网关日志trading_order_gateway_5.log,交易所日志exchange_matching_engine.log看到 FILLED
- Received OMClientResponse [ ... type:FILLED client:5 ... ]
/home/xiaosu/project/cppquant/trading/order_gw/order_gateway.cpp:63 run() 17:22:58.991968976 Sending cid:5 seq:25 MEClientRequest [type:NEW client:5 ticker:3 oid:5012 side:SELL qty:92 price:173]
17:22:58.991976725 RDTSC Trading_TCPSocket_send 1328
17:22:58.991979843 TTT T12_OrderGateway_TCP_write 1774516978991979811
/home/xiaosu/project/cppquant/common/tcp_socket.cpp:71 sendAndRecv() 17:22:58.992006400 send socket:6 len:38
/home/xiaosu/project/cppquant/common/tcp_socket.cpp:63 sendAndRecv() 17:22:58.999213469 read socket:6 len:150 utime:1774516978999213415 ktime:1774516978996578000 diff:2635415
17:22:58.999225555 TTT T7t_OrderGateway_TCP_read 1774516978999225516
/home/xiaosu/project/cppquant/trading/order_gw/order_gateway.cpp:105 recvCallback() 17:22:58.999228252 Received socket:6 len:150 1774516978996578000
/home/xiaosu/project/cppquant/trading/order_gw/order_gateway.cpp:111 recvCallback() 17:22:58.999240541 Received OMClientResponse [seq:25 MEClientResponse [type:ACCEPTED client:5 ticker:3 coid:5012 moid:2 side:SELL exec_qty:0 leaves_qty:92 price:173]]
17:22:58.999248915 TTT T8t_OrderGateway_LFQueue_write 1774516978999248880
/home/xiaosu/project/cppquant/trading/order_gw/order_gateway.cpp:111 recvCallback() 17:22:58.999252849 Received OMClientResponse [seq:26 MEClientResponse [type:FILLED client:5 ticker:3 coid:5012 moid:2 side:SELL exec_qty:44 leaves_qty:48 price:182]]
17:22:58.999259671 TTT T8t_OrderGateway_LFQueue_write 1774516978999259641
/home/xiaosu/project/cppquant/trading/order_gw/order_gateway.cpp:111 recvCallback() 17:22:58.999263724 Received OMClientResponse [seq:27 MEClientResponse [type:FILLED client:5 ticker:3 coid:5010 moid:1 side:BUY exec_qty:44 leaves_qty:0 price:182]]
17:22:58.999270570 TTT T8t_OrderGateway_LFQueue_write 1774516978999270532
17:22:58.999272824 RDTSC Trading_OrderGateway_recvCallback 164338
17:22:59.014959603 TTT T11_OrderGateway_LFQueue_read 17745169790149595174.客户端持仓有没有更新仓位trading_engine_5.log
- onOrderUpdate() ... type:FILLED ...
- position_keeper.h:155 addFill() ... Position{...}
/home/xiaosu/project/cppquant/trading/strategy/trade_engine.cpp:262 onOrderUpdate() 17:22:59.006686493 MEClientResponse [type:FILLED client:5 ticker:3 coid:5012 moid:2 side:SELL exec_qty:44 leaves_qty:48 price:182]
/home/xiaosu/project/cppquant/trading/strategy/position_keeper.h:156 addFill() 17:22:59.006740983 Position{pos:-44 u-pnl:0 r-pnl:0 t-pnl:0 vol:44 vwaps:[0X182] BBO{INVALID@INVALIDXINVALID@INVALID}} MEClientResponse [type:FILLED client:5 ticker:3 coid:5012 moid:2 side:SELL exec_qty:44 leaves_qty:48 price:182]./logger_benchmark # 测试日志系统性能
./hash_benchmark # 测试哈希表性能
./release_benchmark # 测试内存池性能系统使用无锁队列进行组件间的高效通信:
-
订单流程:
- 交易客户端通过OrderGateway发送订单请求
- 交易所的OrderServer接收请求并转发给MatchingEngine
- MatchingEngine处理订单并生成响应
- 响应通过OrderServer返回给客户端的OrderGateway
-
市场数据流程:
- MatchingEngine生成市场数据更新
- MarketDataPublisher发布市场数据
- 客户端的MarketDataConsumer接收市场数据
- TradeEngine根据市场数据更新内部状态并可能生成新的订单
详细的系统架构和设计文档位于 docs/ 目录下:


