4. 库存状态监控:实时库存计算、库存变化率、库存阈值设定
做市商最怕什么?怕库存失控。
我见过太多新手,策略跑得挺漂亮,但库存监控没做好,一夜回到解放前。说白了,库存就是你的命根子。你想想看,一个做市商手里拿着大量现货,价格突然暴跌,那画面太美我不敢看。
这一章,我们就来聊聊怎么把库存盯死、算准、控住。
4.1 实时库存计算:别让数据骗了你
实时库存计算,听起来简单?不就是「初始库存 + 买入 - 卖出」吗?
嗯,理论上是这样。但实际项目中,坑多得很。
我记得有一次,交易所的成交回报延迟了200毫秒,我的库存计算器直接算错了,导致重复下单。那次教训让我明白:库存计算必须考虑「已提交未成交」的订单。
来看一个我常用的实时库存计算模型:
class InventoryTracker:
def __init__(self, initial_inventory: dict):
# 实际持仓(已成交)
self.actual = initial_inventory.copy()
# 挂单中的买卖量
self.pending_buy = defaultdict(float)
self.pending_sell = defaultdict(float)
# 时间戳
self.last_update = time.time()
def on_order_submitted(self, symbol: str, side: str, qty: float):
"""订单提交时,先记入挂单"""
if side == 'buy':
self.pending_buy[symbol] += qty
else:
self.pending_sell[symbol] += qty
def on_trade(self, symbol: str, side: str, qty: float):
"""成交时,更新实际持仓,并扣除挂单"""
if side == 'buy':
self.actual[symbol] += qty
self.pending_buy[symbol] -= qty
else:
self.actual[symbol] -= qty
self.pending_sell[symbol] -= qty
def get_effective_inventory(self, symbol: str) -> float:
"""有效库存 = 实际持仓 + 挂单买入 - 挂单卖出"""
return (self.actual[symbol]
+ self.pending_buy[symbol]
- self.pending_sell[symbol])
核心要点:有效库存才是你决策的依据。只看实际持仓,你会被挂单「吃掉」的流动性坑死。
4.2 库存变化率:发现异常的第一道防线
库存变化率,说白了就是「库存变动的速度」。为什么重要?
你想想看,如果库存突然加速变化,说明什么?要么市场在剧烈波动,要么你的策略出了问题。
我个人习惯用滑动窗口法来计算变化率。窗口大小选多少?这得看你的交易频率。
- 高频做市:窗口选 1-5 秒
- 中频做市:窗口选 30-60 秒
- 低频做市:窗口选 5-15 分钟
来看代码实现:
class InventoryChangeRate:
def __init__(self, window_seconds: int = 60):
self.window = window_seconds
self.snapshots = [] # (timestamp, inventory)
def add_snapshot(self, inventory: float):
now = time.time()
self.snapshots.append((now, inventory))
# 清理过期数据
cutoff = now - self.window
self.snapshots = [(t, inv) for t, inv in self.snapshots
if t >= cutoff]
def get_change_rate(self) -> float:
"""返回每秒库存变化率(正数表示增加,负数表示减少)"""
if len(self.snapshots) < 2:
return 0.0
first = self.snapshots[0]
last = self.snapshots[-1]
time_diff = last[0] - first[0]
if time_diff < 0.001:
return 0.0
return (last[1] - first[1]) / time_diff
避坑指南:我曾经遇到过数据采样频率不一致的问题。交易所的行情是100ms推送一次,但我的库存更新是50ms一次。结果变化率算出来全是毛刺。后来我加了「时间戳对齐」逻辑,才把问题解决。
4.3 库存阈值设定:给库存上「紧箍咒」
库存阈值,就是给库存设个上下限。超过上限,你得主动卖出;低于下限,你得主动买入。
但阈值怎么设?拍脑袋?不行。
我一般用动态阈值,基于以下几个因素:
| 因素 | 说明 | 典型值 |
|---|---|---|
| 账户总资产 | 库存不能超过总资产的一定比例 | 20%-50% |
| 日均成交量 | 库存不能超过日均成交量的倍数 | 5-20倍 |
| 波动率 | 波动越大,阈值越紧 | 动态调整 |
| 流动性 | 流动性越差,阈值越紧 | 动态调整 |
来看一个动态阈值计算器:
class DynamicThreshold:
def __init__(self, base_ratio: float = 0.3):
self.base_ratio = base_ratio # 基础库存比例
def calculate_threshold(self,
total_asset: float,
avg_daily_volume: float,
volatility: float,
liquidity_score: float) -> dict:
"""计算动态阈值"""
# 基于总资产的阈值
asset_limit = total_asset * self.base_ratio
# 基于成交量的阈值
volume_limit = avg_daily_volume * 0.1 # 10%的日均成交量
# 波动率调整因子(波动越大,阈值越小)
vol_factor = max(0.5, 1.0 - volatility * 10)
# 流动性调整因子(流动性越差,阈值越小)
liq_factor = min(1.0, liquidity_score)
# 综合阈值
combined_limit = min(asset_limit, volume_limit) * vol_factor * liq_factor
return {
'upper': combined_limit,
'lower': -combined_limit,
'warning_upper': combined_limit * 0.8,
'warning_lower': -combined_limit * 0.8
}
警告:阈值不是设了就完事了。我见过有人设了阈值,但市场波动一上来,阈值完全失效。记住:阈值必须动态调整,至少每5分钟重新计算一次。
4.4 实战中的库存监控架构
好了,把上面三个模块串起来,就是一个完整的库存监控系统。
我习惯用三层架构:
- 数据层:实时采集成交、挂单、行情数据
- 计算层:实时库存、变化率、阈值计算
- 告警层:超阈值触发告警,自动执行风控动作
来看一个完整的监控循环:
class InventoryMonitor:
def __init__(self, initial_inventory: dict):
self.tracker = InventoryTracker(initial_inventory)
self.rate_calc = InventoryChangeRate(window_seconds=60)
self.threshold = DynamicThreshold(base_ratio=0.3)
# 告警回调
self.on_warning = None
self.on_critical = None
def update(self,
symbol: str,
trade_qty: float,
trade_side: str,
total_asset: float,
avg_volume: float,
volatility: float,
liquidity: float):
"""每次成交或行情更新时调用"""
# 1. 更新库存
self.tracker.on_trade(symbol, trade_side, trade_qty)
# 2. 计算有效库存
effective = self.tracker.get_effective_inventory(symbol)
# 3. 记录库存快照
self.rate_calc.add_snapshot(effective)
# 4. 计算变化率
rate = self.rate_calc.get_change_rate()
# 5. 计算阈值
limits = self.threshold.calculate_threshold(
total_asset, avg_volume, volatility, liquidity
)
# 6. 检查是否超阈值
if effective > limits['upper']:
self._trigger_alert('critical', f'库存超上限: {effective}')
elif effective > limits['warning_upper']:
self._trigger_alert('warning', f'库存接近上限: {effective}')
elif effective < limits['lower']:
self._trigger_alert('critical', f'库存超下限: {effective}')
elif effective < limits['warning_lower']:
self._trigger_alert('warning', f'库存接近下限: {effective}')
def _trigger_alert(self, level: str, msg: str):
"""触发告警"""
if level == 'critical' and self.on_critical:
self.on_critical(msg)
elif level == 'warning' and self.on_warning:
self.on_warning(msg)
最后说一句:库存监控不是摆设。我见过太多人,阈值设了,告警也配了,但告警来了不管。结果呢?爆仓。记住:告警来了,要么手动干预,要么自动执行。别犹豫。
嗯,这一章就到这里。下一章我们聊聊「库存对冲策略」,那才是真正考验功力的地方。