第26章:基差交易系统搭建

系统架构设计、数据模块、策略模块、风控模块、执行模块——这五个词,说白了就是一套交易系统的五脏六腑。我做了这么多年量化,见过太多人一上来就写策略代码,结果数据源断了、风控没拦住、执行滑点大,最后亏得莫名其妙。今天咱们就把这套系统拆开揉碎了讲清楚。

一、系统架构设计:别让代码变成一团乱麻

我个人习惯,先把系统分成三层:数据层、策略层、执行层。每一层只干自己的事,别越界。你想想看,如果数据清洗和策略逻辑混在一起,改一个地方就得动全局,那维护成本就太高了。

核心原则:高内聚、低耦合。每个模块独立部署,通过消息队列或API通信。

举个例子,我早期做的一个基差套利系统,数据模块用Python写,策略模块用C++,执行模块直接对接CTP。它们之间通过Redis传递信号。这样哪怕数据模块挂了,策略模块还能用缓存数据撑一会儿。

架构图如下:

基差交易系统架构图 数据模块 行情数据接入 数据清洗与存储 基差计算引擎 策略模块 信号生成 仓位管理 参数优化 风控模块 事前风控检查 事中监控 事后归因 执行模块 订单路由 滑点控制 成交反馈 数据库 MySQL + Redis 监控告警 邮件/微信/短信

二、数据模块:地基不牢,地动山摇

数据模块是整个系统的命根子。我见过最惨的一次,是数据源突然断流,策略还在傻乎乎地发信号,结果全仓做反了方向。嗯,这里要注意:数据模块必须做三件事——接入、清洗、存储。

2.1 行情数据接入

基差交易需要两类数据:期货价格和现货价格。期货数据从交易所API拿,现货数据得找资讯商。我个人习惯用CTP接口拿期货行情,用Wind或Bloomberg拿现货数据。

# 伪代码示例:数据接入
class DataFeed:
    def __init__(self):
        self.future_api = CTPApi()
        self.spot_api = WindApi()
    
    def get_basis(self, symbol):
        future_price = self.future_api.get_last_price(symbol)
        spot_price = self.spot_api.get_index_price(symbol)
        return future_price - spot_price

小技巧:数据频率要匹配。做日内基差就用1分钟线,做跨期就用日线。别拿tick数据算日频基差,那纯粹是给自己找麻烦。

2.2 数据清洗与存储

数据进来之后,第一件事不是算基差,而是清洗。我曾经遇到过某天现货数据突然跳空,算出来的基差直接爆表,策略差点开仓。后来我加了三道防线:

  • 异常值检测:价格超过3倍标准差就标记
  • 时间戳对齐:期货和现货的时间戳必须精确到毫秒
  • 缺失值处理:用前向填充,别用插值

三、策略模块:核心逻辑,但别太复杂

策略模块说白了就是两件事:什么时候开仓,什么时候平仓。基差交易的核心逻辑其实很简单——基差偏离均值太多就进场,回归了就离场。但执行起来,细节多得吓人。

3.1 信号生成

我常用的方法是滚动窗口的Z-score。当基差的Z-score超过2.5时,认为偏离过度,准备开仓。低于-2.5时反向开仓。但这里有个坑:窗口长度怎么选?

窗口长度 适用场景 缺点
20个交易日 短期均值回归 噪音多,假信号多
60个交易日 中期趋势交易 反应慢,容易错过行情
120个交易日 长期套利 对结构变化不敏感

我个人习惯用60日窗口,再叠加一个20日窗口做辅助判断。两个窗口同时发出信号,我才进场。这样能过滤掉不少噪音。

3.2 仓位管理

仓位管理比信号生成更重要。我见过太多人信号对了,但仓位太重,一波回调就爆仓。我的原则是:每笔交易的风险不超过总资金的2%。

# 仓位计算示例
def calculate_position(basis, z_score, capital):
    risk_per_trade = capital * 0.02
    # 基差每偏离1个点,亏损多少
    point_value = 10  # 假设每点10元
    stop_loss = 5     # 止损5个点
    position = risk_per_trade / (stop_loss * point_value)
    return int(position)

注意:别用凯利公式算仓位。凯利公式在连续亏损时会让你下重注,这在基差交易里是致命的。我吃过这个亏,后来改用固定比例法。

四、风控模块:保命用的,别当摆设

风控模块是系统的最后一道防线。我把它分成三层:事前、事中、事后。

4.1 事前风控

开仓前检查三件事:

  • 资金是否充足:保证金占用不超过70%
  • 持仓是否超限:单品种持仓不超过总资金的30%
  • 关联品种检查:如果已经持有螺纹钢多单,就别再开热卷多单

4.2 事中风控

持仓过程中,实时监控两个指标:

  • 最大回撤:当日回撤超过5%就强制平仓
  • 基差偏离:基差超过3倍标准差,立即检查数据源

4.3 事后风控

每天收盘后,跑一遍归因分析。看看今天的盈亏是来自基差变动,还是来自方向性风险。如果方向性风险占比太高,说明策略可能跑偏了。

避坑指南:我曾经把风控阈值设得太宽松,结果一次黑天鹅事件直接亏了15%。后来我把所有阈值都收紧了一半,虽然信号少了,但活得久了。

五、执行模块:最后一公里,别掉链子

执行模块负责把策略信号变成真实的成交。这里最大的敌人是滑点。基差交易本身利润就薄,滑点一多,直接亏钱。

5.1 订单路由

我一般用限价单,不追单。如果限价单5秒内没成交,就撤单重发。价格稍微调高或调低0.5个tick。这样既能控制滑点,又不会错过行情。

5.2 滑点控制

滑点控制的核心是流动性判断。如果当前盘口的买卖价差超过正常值的2倍,我就暂停交易,等流动性恢复再说。

# 滑点控制示例
def check_spread(symbol):
    bid, ask = get_market_depth(symbol)
    spread = ask - bid
    normal_spread = get_normal_spread(symbol)
    if spread > normal_spread * 2:
        return False  # 流动性不足,暂停交易
    return True

5.3 成交反馈

每笔成交后,系统要立即更新持仓和资金。我习惯用事件驱动的方式,成交回报一来,就触发风控检查和策略状态更新。别用轮询,太慢了。

个人经验:执行模块最好单独部署在一台低延迟的服务器上。别跟策略模块混在一起,否则策略计算卡顿的时候,执行也跟着遭殃。

好了,以上就是基差交易系统的五个核心模块。每个模块单独看都不复杂,但组合起来,就是一个能稳定盈利的系统。记住:系统搭建不是一蹴而就的事,边跑边改,慢慢优化,才是正道。


公众号:蓝海资料掘金营,微信deep3321