Weather MM 挂单策略


天气做市系统的挂单机制、智能定价算法、以及 UI 操作指南。



1. 智能挂单定价算法


核心原则:始终排在己方最优位置,不跨越价差,避免不必要的撤单重挂。


1.1 算法流程



输入: side (BUY/SELL), bids[], asks[], existingOrderPrice (己方已有挂单价格, nullable)

Step 1: 计算目标价格 p

  BUY 方:
    p = 本方 1 档(best_bid) + 1 tick
    如果 p >= 对方 1 档(best_ask) → p = 本方 1 档 (不跨越价差)

  SELL 方:
    p = 本方 1 档(best_ask) - 1 tick
    如果 p <= 对方 1 档(best_bid) → p = 本方 1 档 (不跨越价差)

Step 2: 检查己方是否已存在挂单 x

  ┌─ x = null (无挂单)         → 直接挂 p
  ├─ x < p (挂价比目标差)       → 撤 x,挂 p
  ├─ x = p (挂价=目标)          → 不重复挂 p。触发 2 档检查
  └─ x > p (挂价已优于目标)     → 不做任何操作

Step 3: 2 档检查 (仅当 x = p 时触发)

  y = 本方 2 档(second_best) + 1 tick
  如果 y < x (2 档远落后于当前挂单位置)
    → 撤 x,p = y,重新挂 p
  否则
    → 不做任何操作,保持当前位置

1.2 图解示例


BUY 挂单



盘口:
  Ask:  0.026  ← 对方 1 档
        ─────────
  Bid:  0.022  ← 本方 1 档
        0.021  ← 本方 2 档

1) p = ceilTick(0.022 + 0.0001) = 0.023
2) p (0.023) < ask (0.026) → 不跨越,p = 0.023 ✓
3) 无己方挂单 → 直接挂 p = 0.023

己方已有挂单,价格差于目标



己方挂单 x = 0.021 (BUY)
目标 p = 0.023

x (0.021) < p (0.023) → 撤 x,挂 p = 0.023

己方已挂 p,2 档远落后



己方挂单 x = 0.023 (BUY) = p
本方 2 档 = 0.005

y = ceilTick(0.005 + 0.0001) = 0.006
y (0.006) < x (0.023) → 2 档远落后 → 撤 x,挂 p = 0.006
此时己方已经是唯一的最优买价,不需要支付过高溢价,撤回靠近 2 档。

SELL 挂单



盘口:
  Ask:  0.026  ← 本方 1 档 (SELL 方)
        0.030  ← 本方 2 档
        ─────────
  Bid:  0.022  ← 对方 1 档

1) p = floorTick(0.026 - 0.0001) = 0.025
2) p (0.025) > bid (0.022) → 不跨越,p = 0.025 ✓
3) 无己方挂单 → 直接挂 p = 0.025



2. 价格步长(Tick Size)


Tick size 由 CLOB 官方 API 返回,每个 token 固定,不是按价格分段:



GET https://clob.polymarket.com/tick-size?token_id=<token_id>
→ {"minimum_tick_size": 0.01}  或  {"minimum_tick_size": 0.001}

实测 4/28 香港天气合约:


温度Tick
26°C0.001
27°C0.01
28°C0.01
29°C0.01
30°C0.001

⚠️ 同一天不同温度合约的 tick 可能不同,必须按 token 逐次查询。前端和后端在下单前都会调用此 API 获取正确 tick。



3. 挂单方式


3.1 快捷按钮(Quote Card)


每个温度卡片上有 4 个快捷按钮,点击后自动应用智能定价算法:


按钮含义算法计算的 Token
🟢 BUY YES做多该温度YES token, BUY 方向
🔴 BUY NO做空该温度(买 NO)NO token, BUY 方向
🔴 SELL YES平多 / 做空YES token, SELL 方向
🔴 SELL NO平空 / 做多NO token, SELL 方向

  • 点击后自动拉取 CLOB 全量盘口,执行定价算法
  • 按钮灰色不可点时表示冷却中
  • 按钮标注 🔄 更新 表示存在同方向旧单将被撤销重挂

  • 3.2 Quick 挂单(手动)


    卡片展开后底部的手动按钮,同样使用智能定价算法:


    
    手动 Buy YES    手动 Buy NO
    

  • 自动从 CLOB 拉取盘口并计算
  • 确认弹窗显示算法计算的挂单价和策略说明

  • 3.3 API 直连


    
    POST /api/mm/weather/place-order
    {
        "token_id": "0x...",
        "price": 0.49,
        "size": 5,
        "side": "BUY",
        "temp": 28,
        "comp_type": "exact"
    }
    

    
    POST /api/mm/weather/quick-order
    {
        "token_id": "0x...",
        "side": "BUY",
        "size": 5,
        "price": 0.067    // 可选:前端已计算的价格
    }
    

    后端 quick-order 同样实现了完整的智能定价算法。




    4. 安全机制


    4.1 冷却时间(Cooldown)


    同一 token + 同一方向的下单有 30 秒冷却


  • 防止短时间内重复挂单
  • 冷却期间按钮显示 ⏳ BUY 冷却 Xs
  • 后端返回 HTTP 429 拒绝

  • 4.2 自成交防护(Self-Trade Prevention)


    单向挂单检查


    下单前检查同一 token 是否存在反向挂单


  • 新 BUY 价格 ≥ 现有 SELL 价格 → 拒绝
  • 新 SELL 价格 ≤ 现有 BUY 价格 → 拒绝
  • 冲突时弹出提示,需先撤反向单或调整价格

  • 双边挂单检查(Quote Engine)


    系统生成双边报价时,额外检查 BUY/SELL 是否交叉:


    
    如果 ask ≤ bid(卖价 ≤ 买价):
      → 自成交危险!
      → 以中价为准,bid/ask 各退 1 tick
      → 如果退 1 tick 后仍然交叉:
          buy_biased 方向 → 放弃 SELL,只保留 BUY
          sell_biased 方向 → 放弃 BUY,只保留 SELL
          symmetric      → 放弃 SELL
    

    原则:双向报价时 bid < ask 且至少相差 1 tick,绝不自己吃自己。

    4.3 重复单处理


    同一 token + 同一方向已存在挂单时:


    1. 自动撤销旧挂单

    2. 等待撤单确认

    3. 再挂新单


    智能定价算法会自动判断是否需要撤旧重挂(仅当 x < p 或 2 档落后时)。


    4.4 最大订单额


  • 测试阶段:单笔订单金额上限 $10
  • 超过上限会直接拒绝

  • 4.5 最低数量


  • CLOB 要求最低数量 5
  • Size 自动截断到 2 位小数



  • 5. 盘口深度面板


    点击卡片标题行展开深度面板:


    YES 卖盘(Asks)

  • 顶层红色,从低到高显示卖单
  • 含你的卖单会标 ⭐

  • YES 买盘(Bids)

  • 底层绿色,从高到低显示买单
  • 含你的买单会标 ⭐
  • 你的单子行高亮蓝色背景

  • NO 侧买卖盘

  • 同样显示 NO token 的 5 档深度
  • NO 价格 = 1 - YES 价格



  • 6. 状态栏标签


    卡片底部状态栏显示:


    标签说明
    🟢 BUY 2.2¢持有 YES 买单(可点击撤单 ×)
    🔴 SELL 2.6¢持有 YES 卖单(可点击撤单 ×)
    📦 YES 5.0当前持仓(YES 方向)
    📦 NO 3.0当前持仓(NO 方向)



    7. 不可交易温度(Hard Bound)


    系统根据当前实际温度设定 硬下限


  • 当前温度 ≥ X°C → X°C 及以下合约被标记为 ⛔ impossible
  • 不可交易温度用灰色显示,仍然可以看到盘口但不显示下单按钮

  • 示例:当前香港气温 26°C → 26°C 及以下的所有合约被判定为"已不可能",无需再交易。



    8. NO Token 操作逻辑


    天气市场为每个温度创建 YES 和 NO 两个 token,互为对手:


    操作Token方向经济含义
    BUY YESYESBUY做多该温度
    SELL YESYESSELL平多 / 做空该温度
    BUY NONOBUY做空该温度(买 NO = 买不会)
    SELL NONOSELL平空 / 做多该温度(卖 NO = 卖不会 = 买会)

    NO 价格 = 1 - YES 价格(在有效市场中)。




    9. 实现位置


    组件文件说明
    前端算法mm_weather.htmlcomputeOrderPlacementPrice()所有下单按钮(快捷/手动)的定价入口
    前端按钮mm_weather.htmlconfirmOrder(), quickOrder()拉取 CLOB 盘口后调用算法
    后端算法app.pyapi_mm_weather_quick_order()quick-order 接口的 CLOB fallback 路径
    后端自成交app.pyplace-order单向挂单时检查反向挂单冲突
    双向自成交weather_quotes.py_calculate_quote()Quote Engine 生成双边报价时防交叉
    后端取整app.pyplace-order, quick-order所有入口均做 token 级 tick 取整