第二章:自动化交易系统基础
做市商系统,说白了就是一台高速运转的印钞机——前提是你得把它的骨架搭对。今天咱们聊聊交易系统的四个核心模块:架构概览、订单管理、行情数据接入、风控模块。这些是我在实际项目中反复踩坑后总结出来的经验。
2.1 交易系统架构概览
我个人习惯把交易系统拆成三层:接入层、逻辑层、执行层。你想想看,行情数据从交易所过来,先到接入层做初步清洗,然后送到逻辑层做策略判断,最后通过执行层把订单发出去。这个流程听起来简单,但每一层都有坑。
我在项目中遇到过最头疼的事:行情数据延迟导致策略误判。后来我强制要求所有模块都用同一套时钟源,才把问题压下去。
核心架构要点:
- 接入层:负责行情解码、协议转换、数据缓存
- 逻辑层:策略计算、订单生成、风险检查
- 执行层:订单路由、交易所对接、状态同步
下面这张图是我自己画的,能帮你快速理解整体流程:
2.2 订单管理
订单管理是交易系统的核心。我见过不少团队把订单状态机画得特别复杂,结果上线后各种状态对不上。其实核心就几个状态:新单、部分成交、完全成交、已撤销、已拒绝。
我的经验:订单ID一定要用全局唯一ID,别用自增ID。曾经有个团队用自增ID,结果两个交易所的订单ID冲突了,查问题查了三天。
订单管理模块需要处理的事情:
- 订单生成:根据策略信号生成限价单或市价单
- 订单路由:把订单发到正确的交易所
- 状态跟踪:实时更新订单状态,处理成交回报
- 订单撤销:支持手动和自动撤销
代码示例(伪代码):
class OrderManager:
def __init__(self):
self.orders = {} # order_id -> Order对象
def create_order(self, symbol, side, price, quantity):
order_id = generate_uuid()
order = Order(order_id, symbol, side, price, quantity)
self.orders[order_id] = order
return order_id
def on_fill(self, order_id, fill_price, fill_qty):
order = self.orders[order_id]
order.filled_qty += fill_qty
if order.filled_qty >= order.quantity:
order.status = 'FILLED'
else:
order.status = 'PARTIAL_FILLED'
2.3 行情数据接入
行情数据是交易系统的血液。接入方式主要有三种:FIX协议、WebSocket、交易所自研二进制协议。我个人最推荐用WebSocket,延迟低且容易维护。
我曾经踩过一个坑:行情数据的时间戳精度不够。交易所给的是毫秒级,但我们的策略需要微秒级。后来我加了个硬件时间戳,才把精度提上去。
注意:行情数据一定要做去重和排序。同一个tick可能从多个通道收到,顺序乱了会导致策略算错。
行情数据接入的关键指标:
| 指标 | 说明 | 建议值 |
|---|---|---|
| 延迟 | 从交易所发出到系统收到的时间 | < 1ms |
| 吞吐量 | 每秒能处理的行情条数 | > 10000条/秒 |
| 数据完整性 | 是否有丢包或重复 | 99.99% |
2.4 风控模块
风控模块是交易系统的刹车。没有风控,赚再多钱也可能一把亏光。我见过最惨的案例:一个做市商团队忘了设最大持仓限制,结果市场波动时爆仓了。
风控模块需要检查的内容:
- 资金检查:账户余额是否足够
- 仓位检查:当前持仓是否超过限制
- 频率检查:每秒下单次数是否超标
- 价格检查:订单价格是否在合理范围内
核心原则:风控模块必须独立于策略模块运行。不能因为策略出bug就把风控带崩了。我习惯把风控做成一个单独的进程,通过IPC通信。
风控模块的典型实现:
class RiskController:
def __init__(self, max_position, max_order_rate):
self.max_position = max_position
self.max_order_rate = max_order_rate
self.order_count = 0
self.last_reset_time = time.time()
def check_order(self, order):
# 检查仓位
if self.current_position + order.quantity > self.max_position:
return False, "仓位超限"
# 检查频率
if time.time() - self.last_reset_time > 1:
self.order_count = 0
self.last_reset_time = time.time()
if self.order_count >= self.max_order_rate:
return False, "下单频率超限"
self.order_count += 1
return True, "通过"
嗯,这里要注意:风控规则不能写死。市场环境变了,规则也要跟着调。我建议把规则做成可配置的,用配置文件或数据库存储。
最后说一句:自动化交易系统不是搭完就完事了。你得持续监控、持续优化。行情数据延迟高了、订单状态对不上了、风控误报了——这些都是家常便饭。保持敬畏心,别觉得自己写的代码不会出bug。
公众号:蓝海资料掘金营,微信deep3321