做市策略核心算法:定价模型、库存管理与风险控制
做市策略的核心,说白了就是回答三个问题:报什么价?报多少量?什么时候改价? 这三个问题环环相扣,任何一个环节出问题,轻则亏钱,重则爆仓。今天我就把这套逻辑拆开揉碎了讲清楚。
核心公式:做市商利润 = 买卖价差收入 - 库存风险成本 - 交易损耗
定价模型解决「价差收入」,库存管理解决「库存风险」,报价频率解决「交易损耗」。
3.1 Avellaneda-Stoikov 定价模型
这个模型是我个人最常用的基准模型。为什么?因为它把做市问题转化成了一个数学上可解的最优控制问题。
模型的核心思想很简单:你的报价应该围绕「合理价格」上下浮动,浮动幅度取决于你的库存和风险偏好。
具体来说,假设当前市场中间价为 S,你的库存为 q(正数表示多头,负数表示空头),风险厌恶系数为 γ,那么你的最优买价和卖价分别是:
# 伪代码示例
mid_price = get_market_mid_price()
inventory = get_current_inventory() # 正数=多头,负数=空头
gamma = 0.1 # 风险厌恶系数,越大越保守
sigma = 0.02 # 波动率
T = 1.0 # 剩余时间(年化)
# 库存偏移量
inventory_skew = -gamma * sigma^2 * T * inventory
# 最优报价
bid_price = mid_price + inventory_skew - spread/2
ask_price = mid_price + inventory_skew + spread/2
嗯,这里要注意:inventory_skew 是负的。也就是说,当你持有多头(q > 0)时,你的买价和卖价都会向下偏移。为什么?因为你手里已经有很多货了,你更想卖出去而不是继续买。反过来,空头时报价向上偏移。
我的经验: 我在实盘中发现,γ 这个参数特别敏感。设大了,报价偏移太猛,成交率低;设小了,库存风险控制不住。我一般先用历史数据回滚优化,上线后再用在线学习慢慢调。
3.2 库存管理:别让库存绑架你
定价模型告诉你报什么价,但库存管理告诉你什么时候该强制平仓。
我个人习惯把库存管理分成三层:
- 目标库存区间:比如 [-100, 100] 张合约。在这个区间内,正常做市,靠定价模型自动调节。
- 警戒线:比如 [-300, 300]。一旦触及,启动「库存消化模式」——缩小价差、主动往不利方向报价,加速平仓。
- 硬止损线:比如 [-500, 500]。到了这个位置,别犹豫,直接市价平仓。亏钱总比爆仓强。
我曾经吃过一次大亏。那次行情剧烈波动,库存瞬间冲到警戒线以上,我还在犹豫要不要调参数,结果继续往不利方向走了几十个tick。嗯,从那以后我写死了硬止损逻辑,程序自动执行,不给人犹豫的机会。
# 库存管理逻辑示例
def manage_inventory(current_inventory):
HARD_LIMIT = 500
WARN_LIMIT = 300
TARGET_LIMIT = 100
if abs(current_inventory) >= HARD_LIMIT:
# 强制市价平仓
market_order(-current_inventory)
return "FORCED_LIQUIDATION"
elif abs(current_inventory) >= WARN_LIMIT:
# 缩小价差,加速平仓
set_spread_multiplier(0.5)
return "AGGRESSIVE"
elif abs(current_inventory) >= TARGET_LIMIT:
# 正常做市,但略微偏向平仓方向
set_spread_multiplier(1.0)
return "NORMAL"
else:
# 完全正常做市
return "COMFORT"
3.3 风险控制:不止是止损
很多人以为风控就是设个止损线。其实远不止这些。我总结了三道防线:
| 防线 | 内容 | 触发条件 |
|---|---|---|
| 第一道 | 报价合理性检查 | 报价偏离市场中间价超过N个标准差 |
| 第二道 | 库存限额 | 库存绝对值超过阈值 |
| 第三道 | 总亏损限额 | 当日累计亏损超过设定值 |
第一道防线很多人会忽略。你想想看,如果行情数据出现异常(比如交易所的撮合引擎抽风),你的定价模型可能会算出离谱的报价。我曾经遇到过,某次数据源推送了一个错误的价格,我的模型瞬间报出了低于市场价10%的买单。还好报价合理性检查拦截了,不然那一单吃进去,够我喝一壶的。
避坑指南: 风控逻辑一定要独立于交易逻辑运行。别把风控写在主循环里,万一主循环卡住了,风控也跟着失效。我习惯单独开一个线程跑风控监控,心跳检测,5秒没收到心跳就自动断开所有连接。
3.4 报价更新频率:快与稳的平衡
报价频率这个问题,其实没有标准答案。你想想看,频率太高,容易给交易所造成压力,还可能被判定为「过度报价」;频率太低,你的报价可能已经过时了,被市场甩在后面。
我个人建议分场景处理:
- 正常行情:每 100-500 毫秒更新一次报价。这个频率足够应对大部分行情变化,又不会给系统太大负担。
- 剧烈波动:缩短到 50-100 毫秒。行情变化快,你的报价也得跟上。
- 盘整行情:可以延长到 1-2 秒。没必要频繁更新,省点计算资源。
怎么判断行情状态?我一般用波动率指标。当波动率超过某个阈值时,自动切换到高频模式。
# 报价频率自适应逻辑
def get_update_interval():
current_volatility = calculate_volatility(window=20)
if current_volatility > HIGH_VOL_THRESHOLD:
return 50 # 毫秒
elif current_volatility > MED_VOL_THRESHOLD:
return 200
else:
return 1000
我的经验: 别把报价更新和策略计算放在同一个循环里。我习惯用两个独立的定时器:一个负责计算最优报价(可以慢一点,比如每秒一次),另一个负责把算好的报价发到交易所(可以快一点,比如每100毫秒一次)。这样即使计算偶尔延迟,报价也能保持更新。
3.5 知识体系总览
下面这张图把今天讲的内容串起来了。你可以看到,定价模型、库存管理、风险控制、报价频率这四个模块是相互影响的。
你看,这四个模块不是孤立的。定价模型算出来的报价,要经过库存管理的偏移修正,再经过风险控制的合规检查,最后按照合适的频率发出去。任何一个环节出问题,整个系统都会受影响。
好了,这一章的内容就到这里。定价模型、库存管理、风险控制、报价频率,这四个点你吃透了,做市策略的核心算法就算入门了。剩下的就是不断优化参数、积累经验。