库存风险管理:库存计价方法、库存对冲策略、库存限制与调整

做市策略里,库存风险是个绕不开的话题。说白了,你手里拿着货,价格一波动,账面就跟着抖。我刚开始做回测时,总觉得只要策略信号准就行,库存管理随便搞搞。结果有一次回测曲线漂亮得很,实盘一跑,三天就亏回去了。为什么?库存计价方法没选对,对冲也没跟上。

今天咱们就把这块掰开揉碎。库存风险管理,核心就三件事:怎么算库存价值、怎么对冲风险、怎么控制仓位上限。

库存计价方法

库存计价,听起来像会计活,但在量化交易里,它直接影响你的盈亏计算和风控决策。不同的计价方法,算出来的浮盈浮亏天差地别。

我个人习惯用以下三种方法:

  • 先进先出(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次

库存调整,不是你想调就调的。我习惯用「阶梯调整法」:

  1. 当库存超过上限的80%,发出预警,但不操作。
  2. 超过100%,强制减仓一半。
  3. 超过120%,全部清仓,暂停做市。

为什么要留预警线?因为市场流动性不是无限的。你一下子砸出去,滑点能把利润全吃掉。预警线给了你缓冲时间,可以分批出货。

注意: 库存调整时,一定要考虑市场深度。我曾经在流动性差的币种上强行减仓,结果把价格砸穿了,自己成了砸盘元凶。后来我加了一条规则:单次调整量不超过最近5分钟平均成交量的10%。

下面是我用的一张库存管理流程图,帮你理清整体逻辑:

库存管理开始 选择计价方法:FIFO / 加权平均 / 市价 库存是否超限? (单品种/总库存) 继续做市 触发对冲/减仓 执行调整 (分批/限价/考虑深度) 正常状态 风险状态 执行调整 虚线:循环监控

这张图的核心逻辑是:先计价,再判断是否超限,超限了就触发对冲或减仓,然后回到监控循环。嗯,这里要注意,调整完不是就完事了,得继续监控,因为市场在变,你的库存风险也在变。

最后说一句,库存管理没有银弹。不同市场、不同品种,参数都得调。我建议你回测时多跑几种参数组合,找到最适合自己策略的那一套。别偷懒,这个功夫省不得。

专注资料整理