库存风险管理:库存计价方法、库存对冲策略、库存限制与调整
做市策略里,库存风险是个绕不开的话题。说白了,你手里拿着货,价格一波动,账面就跟着抖。我刚开始做回测时,总觉得只要策略信号准就行,库存管理随便搞搞。结果有一次回测曲线漂亮得很,实盘一跑,三天就亏回去了。为什么?库存计价方法没选对,对冲也没跟上。
今天咱们就把这块掰开揉碎。库存风险管理,核心就三件事:怎么算库存价值、怎么对冲风险、怎么控制仓位上限。
库存计价方法
库存计价,听起来像会计活,但在量化交易里,它直接影响你的盈亏计算和风控决策。不同的计价方法,算出来的浮盈浮亏天差地别。
我个人习惯用以下三种方法:
- 先进先出(FIFO):最早买入的库存最先卖出。适合趋势行情,能真实反映持仓成本变化。
- 加权平均成本:所有库存按买入均价计算。波动大时更平滑,不容易被极端价格干扰。
- 市价计价(Mark-to-Market):按当前市场价格重新估值。这是实盘最常用的,也是监管要求的。
你可能会问,回测时该用哪个?我建议回测用加权平均成本,实盘用市价计价。为什么?回测时你没法精确模拟每笔成交的滑点,加权平均能减少噪声。实盘就不一样了,你得实时知道自己的风险敞口。
重要提醒: 计价方法一旦选定,不要频繁切换。我见过有人回测用FIFO,实盘用市价,结果策略表现对不上,白白浪费了三个月优化时间。
来看一段简单的库存计价代码:
class InventoryManager:
def __init__(self, method='weighted_avg'):
self.method = method
self.positions = [] # (price, quantity)
def add_position(self, price, qty):
self.positions.append((price, qty))
def remove_position_fifo(self, qty):
removed = []
while qty > 0 and self.positions:
price, available = self.positions[0]
take = min(qty, available)
removed.append((price, take))
qty -= take
if take == available:
self.positions.pop(0)
else:
self.positions[0] = (price, available - take)
return removed
def get_market_value(self, current_price):
if self.method == 'weighted_avg':
total_qty = sum(p[1] for p in self.positions)
total_cost = sum(p[0]*p[1] for p in self.positions)
avg_cost = total_cost / total_qty if total_qty else 0
return (current_price - avg_cost) * total_qty
elif self.method == 'fifo':
value = 0
for price, qty in self.positions:
value += (current_price - price) * qty
return value
这段代码虽然简单,但核心逻辑都在了。我在实盘系统里,还会加上时间戳和交易对手信息,方便审计。
库存对冲策略
库存对冲,说白了就是不让单边风险吃掉你的利润。做市商赚的是买卖价差,不是赌方向。所以,对冲是必修课。
常见的对冲策略有几种:
- Delta中性对冲:通过期货或期权,让库存的Delta趋近于零。适合高流动性市场。
- 跨品种对冲:比如做市BTC,用ETH期货对冲。相关性高但又不完全一样,需要动态调整。
- 时间分散对冲:分批对冲,避免一次性冲击市场。我习惯用VWAP算法执行。
我曾经在回测里忽略了一个细节:对冲成本。你以为对冲能完美保护库存,但每次对冲都有手续费和滑点。回测时如果不算这笔账,实盘就会被打脸。
我的经验: 对冲频率不要太高。每笔订单都去对冲,手续费会吃掉所有利润。我一般设置一个阈值,比如库存价值超过总资金的5%才触发对冲。
来看一个简单的Delta对冲逻辑:
def hedge_delta(inventory_value, futures_price, hedge_ratio=1.0):
"""
inventory_value: 当前库存市值
futures_price: 期货价格
hedge_ratio: 对冲比例,0.8表示对冲80%风险
"""
target_hedge = inventory_value * hedge_ratio
current_hedge = get_current_futures_position()
delta = target_hedge - current_hedge
if abs(delta) > MIN_HEDGE_THRESHOLD:
# 执行对冲
place_futures_order(delta / futures_price)
print(f'对冲执行: {delta:.2f} USD')
else:
print(f'未触发对冲阈值,当前delta: {delta:.2f}')
这里有个坑:对冲比例不是越高越好。你想想看,如果市场突然反转,你完全对冲了,那库存的浮亏是锁住了,但潜在收益也没了。做市商的核心是赚流动性,不是赚方向。所以,我一般把对冲比例设在0.6到0.8之间,留点敞口吃波动。
库存限制与调整
库存限制,就是给仓位设个天花板。没有限制,一次黑天鹅就能让你归零。我见过太多人,策略回测年化50%,实盘一把亏光,就是因为库存管理失控。
库存限制通常分三个维度:
| 维度 | 说明 | 我的建议值 |
|---|---|---|
| 单品种上限 | 单个币种/股票的最大持仓 | 总资金的10%-20% |
| 总库存上限 | 所有库存的总市值上限 | 总资金的50%-70% |
| 日内调整次数 | 每天最多调整几次库存 | 不超过5次 |
库存调整,不是你想调就调的。我习惯用「阶梯调整法」:
- 当库存超过上限的80%,发出预警,但不操作。
- 超过100%,强制减仓一半。
- 超过120%,全部清仓,暂停做市。
为什么要留预警线?因为市场流动性不是无限的。你一下子砸出去,滑点能把利润全吃掉。预警线给了你缓冲时间,可以分批出货。
注意: 库存调整时,一定要考虑市场深度。我曾经在流动性差的币种上强行减仓,结果把价格砸穿了,自己成了砸盘元凶。后来我加了一条规则:单次调整量不超过最近5分钟平均成交量的10%。
下面是我用的一张库存管理流程图,帮你理清整体逻辑:
这张图的核心逻辑是:先计价,再判断是否超限,超限了就触发对冲或减仓,然后回到监控循环。嗯,这里要注意,调整完不是就完事了,得继续监控,因为市场在变,你的库存风险也在变。
最后说一句,库存管理没有银弹。不同市场、不同品种,参数都得调。我建议你回测时多跑几种参数组合,找到最适合自己策略的那一套。别偷懒,这个功夫省不得。