4. 报价策略设计:对称报价与非对称报价、报价宽度与市场波动率的关系、动态调整报价
做市商的核心工作,说白了就是「报价」。你报什么价,决定了你能不能赚钱,也决定了你会不会亏钱。这一章我重点聊聊报价策略的设计,包括对称与非对称报价、报价宽度怎么跟波动率挂钩,以及如何动态调整。
我个人习惯把报价策略分成三个层次:基础形态(对称 vs 非对称)、宽度控制(跟波动率的关系)、动态调整(实时响应市场)。咱们一个一个来拆。
4.1 对称报价与非对称报价
先讲最基础的概念。对称报价,就是买价和卖价相对于中间价是对称的。比如中间价是100,你报买价99.5,卖价100.5,两边各0.5的价差。非对称报价,就是两边不对称,比如买价99.3,卖价100.5,买侧收窄,卖侧放宽。
什么时候用对称?什么时候用非对称?我总结了几条经验:
- 市场中性时用对称:当市场没有明显方向,波动率稳定,对称报价最省心。你不需要判断方向,只需要赚取买卖价差。我在做ETF做市时,大部分时间都用对称报价,省去了方向判断的麻烦。
- 有库存偏向时用非对称:如果你手里库存太多,想减仓,那就把卖价报低一点,买价报高一点,说白了就是「想卖就降价,想买就提价」。我曾经在某个币种上库存积压严重,硬扛对称报价,结果市场一跌,亏损惨重。后来改成非对称报价,主动调整库存,效果好了很多。
- 信息不对称时用非对称:如果你觉得市场即将有重大消息,或者你比对手方更了解某个品种的真实价值,可以主动调整报价偏向。但这里要小心,别把自己玩进去。
举个例子,假设你持有大量某股票,想逐步减仓。你的报价策略可以这样设计:
# 非对称报价示例
mid_price = 100.0
inventory_skew = 0.2 # 库存偏向系数,正值表示偏向卖出
bid_price = mid_price - spread/2 - inventory_skew
ask_price = mid_price + spread/2 - inventory_skew
# 结果:买价更低,卖价也更低,整体偏向卖出侧
嗯,这里要注意:非对称报价不是随便调的。调得太狠,容易被套利者盯上。我见过有人把买价调得特别高,结果被高频交易者疯狂砸单,瞬间亏掉一大笔。
4.2 报价宽度与市场波动率的关系
报价宽度,就是买卖价差。这个宽度怎么定?最核心的变量就是波动率。
道理很简单:波动率越高,价格跳动的风险越大。你报一个窄价差,万一价格瞬间跳过去,你就亏了。所以波动率越高,价差应该越宽。
我常用的一个公式是:
spread = k * sigma * sqrt(T)
其中:
- sigma:波动率(年化)
- T:持仓时间(通常用秒或毫秒)
- k:调整系数(通常1.5~3.0)
这个公式来自期权定价的灵感。你想想看,做市商本质上是在卖期权——你提供流动性,相当于卖了一个跨式期权。价差就是你的期权费。
我在实际项目中,会把波动率分成几个档位:
| 波动率水平 | 年化波动率 | 建议价差(相对于中间价) | 备注 |
|---|---|---|---|
| 低波动 | < 10% | 0.05% - 0.1% | 适合高频做市 |
| 中等波动 | 10% - 30% | 0.1% - 0.3% | 最常见的情况 |
| 高波动 | 30% - 60% | 0.3% - 0.8% | 需要谨慎 |
| 极端波动 | > 60% | > 0.8% | 建议暂停做市 |
这个表格是我自己总结的,不一定适用于所有品种。但核心逻辑是:波动率翻倍,价差至少翻倍。别想着在波动率高的时候赚更多,风险控制永远是第一位的。
4.3 动态调整报价
静态报价策略是死路一条。市场在变,你的报价也必须跟着变。动态调整的核心,就是根据实时市场数据,自动调整报价参数。
我一般把动态调整分成三个维度:
- 基于波动率的调整:实时计算滚动波动率,动态调整价差。比如用过去5分钟的1秒K线计算波动率,每10秒更新一次。
- 基于库存的调整:监控当前库存水平,如果偏离目标库存,就调整报价偏向。比如库存超过上限,就主动降价卖出。
- 基于订单簿的调整:观察对手方的订单簿深度,如果某个价位有大量挂单,可以适当调整自己的报价位置。
下面是一个简单的动态调整框架:
class DynamicMarketMaker:
def __init__(self, target_inventory=100):
self.target_inventory = target_inventory
self.current_inventory = 0
self.volatility = 0.0
def update_volatility(self, price_history):
# 计算滚动波动率
returns = np.diff(np.log(price_history))
self.volatility = np.std(returns) * np.sqrt(252 * 24 * 3600)
def calculate_spread(self):
# 基础价差
base_spread = 1.5 * self.volatility * 0.01
# 库存调整
inventory_deviation = (self.current_inventory - self.target_inventory) / self.target_inventory
inventory_adjustment = 0.2 * inventory_deviation
# 最终价差
spread = base_spread * (1 + abs(inventory_adjustment))
return spread, inventory_adjustment
def get_quotes(self, mid_price):
spread, skew = self.calculate_spread()
bid = mid_price - spread/2 - skew
ask = mid_price + spread/2 - skew
return bid, ask
这个代码很粗糙,但核心思想都在里面了。实际生产环境中,你还需要考虑:
- 更新频率:别太频繁,否则容易产生大量废单。我一般用100ms~500ms的更新间隔。
- 平滑处理:参数变化不要太剧烈,加个指数移动平均。
- 异常检测:如果某个参数突然跳变,先暂停,检查一下数据源。
4.4 知识体系总览
为了让你更直观地理解这一章的内容,我画了一张图,把报价策略的核心逻辑串起来:
这张图展示了报价策略的完整流程:市场数据进来后,经过波动率、库存、订单簿三个维度的分析,最终决定采用对称还是非对称报价。注意那个反馈循环——成交数据会反过来影响参数,形成一个闭环。
核心要点回顾:
- 对称报价适合市场中性环境,非对称报价用于库存管理或信息优势
- 报价宽度与波动率正相关,波动率翻倍,价差至少翻倍
- 动态调整需要同时考虑波动率、库存、订单簿三个维度
- 别忘了加保护机制:最小价差、异常检测、平滑处理
这一章的内容就到这里。报价策略是门手艺活,光看理论没用,得在实际交易中不断打磨。我建议你从模拟盘开始,把对称报价跑熟了,再慢慢加入非对称和动态调整。别一上来就想搞复杂的策略,容易翻车。