📊 天气做市 — 仓位管理策略


作者: Spark ⚡ | 2026-04-26 | 基于 weather_quotes.py + weather_mm_runner.py 实际代码



一、核心思路


做市系统不只是单向押注方向,而是在有持仓后自动变成双边做市——低买高卖,赚取预测 edge 对应的价差。



无持仓:  预测方向 → 单向挂单(积累仓位)
有持仓:  预测方向 + 反向挂单(吃价差)



二、仓位生命周期


阶段 1: 无持仓 → 信号触发



Edge = fair_price - market_price = 30%
→ mode = buy_biased
→ BUY  @ best_bid + 1 tick(积极买入,tick 通过 CLOB API 获取)
→ SELL @ best_ask(被动,不指望成交)

目标: 在市场低估时积累仓位。


阶段 2: 买入成交 → 持有 YES



check_fill: BUY 限价 ≥ market_ask → 按 market_ask 成交
→ yes_tokens += size
→ total_cost += price × size

此时持仓变化:

  • yes_tokens: 0 → 20
  • total_cost: $0 → $10.02
  • avg_entry: $0.501

  • 阶段 3: 有持仓 + Edge 仍在 → 双边做市


    
    Edge 仍 > 0, yes_tokens > 0
    → mode = buy_biased_holding
    
    BUY  @ best_bid + 1 tick(继续吸筹)
    SELL @ market_ask - 1 tick(对价减最小单位,成为新卖一)
          但不低于 avg_cost + 1¢(绝不亏本卖)
    

    定价对比:


    无持仓 (buy_biased)有持仓 (buy_biased_holding)
    BUY 价0.5010.501 (不变)
    BUY 量30 份30 份 (不变)
    SELL 价0.550 (被动)max(0.549, 0.56) = 0.56
    SELL 量5 份 (象征性)10 份 (有意义)

    定价规则:

  • SELL = market_ask - 1 tick (对价减最小单位)
  • 但如果 avg_cost + 1¢ 更高 → 用 avg_cost + 1¢(不亏本卖)
  • 例: 成本 0.55, market_ask=0.55 → SELL @ 0.56 (赚 1 分)

  • 阶段 4: Edge 反转 → 平仓


    
    Edge 翻负 (市场高估了)
    → mode = sell_biased
    → 检测到 yes_tokens > 0
    → close_size = min(ask_size, yes_tokens)
    → 只平仓,不开新空
    

    阶段 5: 合约结算


    
    午夜 HKO 发布 Absolute Daily Max
    → 28°C 命中 → YES = $1.00 → 利润
    → 29°C 未中 → YES = $0.00 → 亏损
    



    三、模式决策矩阵


    
                         Edge > 20%        Edge < -20%       |Edge| < 20%
    ─────────────────────────────────────────────────────────────────────
    无持仓               buy_biased        sell_biased       symmetric
                        BUY积极/SELL被动    SELL积极/BUY被动   双边对称
    
    持有 YES             buy_biased_       sell_biased       symmetric
    (之前买入的)          holding           (先平仓再卖)       双边对称
                        BUY+SELL都积极      只平仓不开新空
    
    持有 NO              buy_biased        sell_biased_      symmetric
    (之前卖出的)          (先平仓再买)       holding            双边对称
                        只平仓不开新空      BUY+SELL都积极
    



    四、定价规则详解


    4.1 有流动性市场 (orderbook spread < 50%)


    
    TICK = 0.001
    
    buy_biased (无持仓):
      bid = min(best_bid + TICK, fair - TICK)
      ask = best_ask
    
    buy_biased_holding (持有 YES):
      bid = min(best_bid + TICK, fair - TICK)
      ask = market_ask - TICK            ← 对价减最小单位,成为新卖一
      cost_floor = avg_entry + 0.01
      ask = max(ask, cost_floor)         ← 绝不亏本卖(成本 + 1 分)
    
    sell_biased (无持仓):
      ask = max(best_ask - TICK, fair + TICK)
      bid = best_bid
    
    sell_biased_holding (持有 NO):
      ask = max(best_ask - TICK, fair + TICK)
      bid = market_bid + TICK            ← 对价加最小单位,成为新买一
      cost_ceiling = avg_entry - 0.01
      bid = min(bid, cost_ceiling)       ← 绝不亏本买回(成本 - 1 分)
    

    4.2 无流动性市场 (spread ≥ 50%)


    回退到 fair-price 中心定价:


    
    buy_biased:         bid = fair - spread×0.25, ask = fair + spread×0.75
    buy_biased_holding: bid = fair - spread×0.30, ask = fair + spread×0.30
    sell_biased:        bid = fair - spread×0.75, ask = fair + spread×0.25
    sell_biased_holding: bid = fair - spread×0.30, ask = fair + spread×0.30
    



    五、仓位大小规则


    5.1 基础参数


    参数
    BASE_ORDER_SIZE10 份
    MIN_ORDER_SIZE5 份
    MAX_ORDER_SIZE100 份
    MIN_NOTIONAL$1 (price × size ≥ $1)

    5.2 持仓模式下的双边大小


    
    # buy_biased_holding (持有 YES)
    bid_size = base × 1.8 × buy_bias  # 继续买入
    ask_size = max(base × 1.0, 计算值)  # 卖单至少 base 份
    
    # sell_biased_holding (持有 NO)
    ask_size = base × 1.8 × sell_bias  # 继续卖出
    bid_size = max(base × 1.0, 计算值)  # 买单至少 base 份
    

    5.3 离散档位


    所有 size 自动取整: 5 → 10 → 20 → 30 → 40 → 50...




    六、风控集成


    仓位管理受 WeatherRiskManager 约束:


    限制超限行为
    单合约最大敞口$10缩减 size
    总最大敞口$50缩减 50%
    单方向最大$10该侧设为 0
    日亏损上限$20全部停止
    连续亏损3 次暂停 1 小时



    七、Edge 消失 → 主动平仓 (closing 模式)


    当 |edge| < 20% 且持有仓位时,不做双边做市,而是积极平仓退出


    
    closing_long (持有 YES, edge 消失):
      SELL @ market_ask - 1 tick(成为新卖一, 主动出)
            ≥ avg_cost + 1¢(不亏本)
      BUY  @ market_bid(被动, 不吸筹)
      SELL size = base × 1.5(加大平仓力度)
    
    closing_short (持有 NO, edge 消失):
      BUY  @ market_bid + 1 tick(成为新买一, 主动平)
            ≤ avg_cost - 1¢(不亏本)
      SELL @ market_ask(被动, 不加空)
      BUY size = base × 1.5(加大平仓力度)
    

    触发条件: |edge| < 20% + has_position(之前 edge 够强时建的仓,现在信号消失)




    八、价格竞争(保持最优价)


    每次扫描后检查已有挂单是否还在盘口最优位置:


    
    BUY 挂单: our_price < best_bid → 被人超了
      → 建议撤单重挂 @ best_bid + 1 tick
    
    SELL 挂单: our_price > best_ask → 被人压了
      → 建议撤单重挂 @ best_ask - 1 tick
    

    检测结果写入 order_competition.json,Web UI 显示建议按钮。




    九、测试阶段:人工审批流程


    ⚠️ 当前测试阶段,所有订单不自动执行,需人工在 Web UI 点击 Approve。

    流程


    
    1. Runner 扫描 → 生成报价
    2. 强 edge (≥20%) 或 closing 模式的报价 → 保存到 pending_orders.json
    3. Web UI 显示待审批卡片(含 BUY/SELL 双向按钮)
    4. 人工点击 [Approve BUY] 或 [Approve SELL]
    5. 后端调用 CLOB API 下单
    6. 订单标记为 approved
    

    相关 API


    端点功能
    GET /api/mm/weather/pending-orders列出待审批
    POST /api/mm/weather/approve-order审批下单 {key, side}
    POST /api/mm/weather/reject-order拒绝 {key}
    GET /api/mm/weather/order-competition价格竞争建议
    POST /api/mm/weather/improve-order撤旧挂新 {order_id, new_price}



    十、完整流程示例


    
    时间线: 某日 10:00 - 16:00, 预测 28°C (fair=0.96), 当前 market=0.50
    
    10:00  扫描 #1  无持仓, edge=+46%
           → buy_biased: BUY 0.501 x30, SELL 0.550 x5
           → 保存到 pending_orders.json → Web UI 显示 [Approve BUY]
           → 人工点击 Approve → BUY 成交 @0.55
           → 持仓: YES=30, avg=0.55, cost=$16.50
    
    10:05  扫描 #2  有持仓(30YES, avg=0.55), edge 仍 +46%
           → buy_biased_holding: BUY 0.501 x30, SELL 0.56 x10
           → SELL = max(0.549, 0.56) = 0.56 (成本+1分)
           → Web UI: [Approve BUY] [Approve SELL]
    
    10:30  扫描 #N  价格竞争检查
           → 我们的 BUY @0.501 < best_bid @0.510
           → ⚠️ Web UI 显示: [撤单重挂 @0.511]
           → 人工点击 Improve → 撤旧挂新
    
    11:00  扫描 #M  市场涨到 0.70, market_ask=0.72
           → buy_biased_holding: BUY 0.701 x20, SELL 0.719 x10
           → BUY 成交 @0.72
           → 持仓: YES=50, avg=0.618
    
    13:00  扫描 #K  市场 0.62, edge 缩小到 +4% (< 20%!)
           → closing_long: SELL @0.639 x15 (积极平仓!)
           → 人工点击 [Approve SELL] → 成交 @0.64
           → 持仓: YES=35, 已实现 +$0.22
    
    16:00  温度已达 28.5°C, edge ≈ 0
           → closing_long: 继续平仓剩余
           → 持仓: YES=0, 总利润约 $5
    



    十一、关键设计决策


    1. 不做止损单: 不预设固定止损价。靠每 5 分钟重新评估 edge 决定方向。

    2. 不做止盈单: 不预设固定止盈。靠双边做市在市场回归 fair 时自然卖出。

    3. Edge 是唯一信号: 所有决策围绕 fair - market 展开。

    4. 双边做市只在持仓后触发: 无持仓时单向吸筹,有持仓后才是真正的 market maker。

    5. 成本底线: SELL 价 ≥ avg_cost + 1¢,BUY 价 ≤ avg_cost - 1¢。宁可不成交也不亏本。

    6. 对价优先: 卖单挂 market_ask - 1 tick,买单挂 market_bid + 1 tick。做市要成为盘口最优价。

    7. Edge 消失主动平仓: |edge| < 20% + 有仓位 → closing 模式,加大平仓力度。

    8. 价格竞争: 挂单不是最优价时,撤单往前挂,始终保持盘口第一。

    9. 测试期人工审批: 所有订单显示在 Web UI,人工点击 Approve 后才执行。




    本文档随代码同步更新。最后更新: 2026-04-26 19:51 CST