SightWhale
← 返回博客

流动性状态:在市场变得“可交易”之前识别它(先于大众)

SightWhale··8 分钟·Read in English

流动性状态:在市场变得“可交易”之前识别它(先于大众)

Polymarket上大多数“糟糕的交易”之所以糟糕,并不是因为你误判了事件结果。 而是因为你交易了一个尚未形成真正市场的市场。

同一个合约可能表现出截然不同的行为:

  • 一个薄而跳跃的品种,每笔交易都会推动价格
  • 或者一个深度订单簿,大单可以平稳成交,信号可复制

这种转变就是流动性状态变化

如果你能提前识别它,你将获得两个优势:

  1. 在散户注意到之前,执行成本已经下降
  2. 大户的资金流向变得可解读,而非充满噪音

内部链接:


1) “可交易”意味着什么(操作性定义)

“可交易”不是一种感觉,而是一组条件:

  • 价差足够窄,以至于成交不会吞噬你的期望收益
  • 顶部档位的深度足以容纳你的交易量
  • 订单簿会重新填充(流动性是真实的,而非快照)
  • 价格对知情交易有反应,而非随机噪音

换句话说:执行是稳定的


2) 可交易性评分(简单、实用、可审计)

我们将从三个维度构建一个0-100分的评分:

  1. 价差分(紧密度)
  2. 深度分(冲击)
  3. 稳定分(填充 vs 撤单压力)

A) 价差分

Polymarket的CLOB API提供了一个公开的价差端点(代币级别)。 外部来源(CLOB端点列表):https://docs.polymarket.com/quickstart/reference/endpoints

spread 为最佳卖价减最佳买价(以概率单位计)。

定义归一化的价差分:

spread_score = clamp(1 - spread / spread_target, 0, 1)

其中:

  • spread_target 对于流动性好的市场可取 0.005(0.5美分),一般使用可取 0.01(1美分)。

B) 深度分

拉取订单簿,计算如果交易固定名义金额(例如2000美元)时订单簿移动多少。

如果你能以低于0.5美分的冲击买入2000美元,深度良好。 如果头200美元就使价格移动2美分,那么深度尚未形成市场。

C) 稳定分(撤单压力代理)

单次快照无法获得完美的撤单率数据。 但你可以通过重复快照来估计稳定性:

  • 每10秒采样一次订单簿,持续10分钟
  • 计算顶部流动性消失与重新填充的频率

代理指标:

stability = 1 - (mean_abs_change(top_depth) / mean(top_depth))

然后截断到 [0, 1]。


3) 可复现的数据拉取(Gamma + CLOB)

你需要代币ID,然后获取订单簿。

Polymarket文档说明:

通过slug获取市场(Gamma):

curl "https://gamma-api.polymarket.com/markets?slug=YOUR_MARKET_SLUG"

然后拉取订单簿/价差(CLOB):

curl "https://clob.polymarket.com/book?token_id=YOUR_TOKEN_ID"
curl "https://clob.polymarket.com/spread?token_id=YOUR_TOKEN_ID"
curl "https://clob.polymarket.com/midpoint?token_id=YOUR_TOKEN_ID"

4) 一个计算评分的最小脚本

该脚本:

  • 重复采样订单簿
  • 计算价差、2000美元冲击和稳定性代理指标
  • 生成0-100的可交易性评分
import json
import time
import urllib.request
from statistics import mean

TOKEN_ID = "YOUR_TOKEN_ID"
NOTIONAL_USD = 2000
SAMPLES = 60          # 10分钟,每10秒一次
INTERVAL_SECONDS = 10

def get_json(url: str):
  with urllib.request.urlopen(url) as r:
    return json.loads(r.read().decode("utf-8"))

def snapshot():
  book = get_json(f"https://clob.polymarket.com/book?token_id={TOKEN_ID}")
  spread = get_json(f"https://clob.polymarket.com/spread?token_id={TOKEN_ID}")
  mid = get_json(f"https://clob.polymarket.com/midpoint?token_id={TOKEN_ID}")
  return book, float(spread["spread"]), float(mid["midpoint"])

def vwap_for_notional(asks, notional_usd):
  # 计算买入指定名义金额的成交量加权均价和冲击
  total_cost = 0.0
  total_size = 0.0
  for price, size in asks:
    price = float(price)
    size = float(size)
    cost = price * size
    if total_cost + cost <= notional_usd:
      total_cost += cost
      total_size += size
    else:
      remaining = notional_usd - total_cost
      total_cost += remaining
      total_size += remaining / price
      break
  avg_price = total_cost / total_size if total_size > 0 else 0
  return avg_price

# 主循环
spreads = []
impacts = []
depths = []
for _ in range(SAMPLES):
  book, spread, mid = snapshot()
  asks = book.get("asks", [])
  if not asks or spread is None:
    continue
  spreads.append(spread)
  # 计算冲击:买入2000美元后的均价与中点的差异
  avg_price = vwap_for_notional(asks, NOTIONAL_USD)
  impact = abs(avg_price - mid) / mid if mid else 0
  impacts.append(impact)
  # 记录顶部卖单的总深度
  top_depth = sum(float(size) for _, size in asks[:5])
  depths.append(top_depth)
  time.sleep(INTERVAL_SECONDS)

if not spreads:
  print("无法获取数据")
  exit()

# 计算各分项
spread_target = 0.01
spread_score = max(0, min(1, 1 - (mean(spreads) / spread_target)))

impact_threshold = 0.005  # 0.5美分
depth_score = max(0, min(1, 1 - (mean(impacts) / impact_threshold)))

# 稳定性:深度变化越小越稳定
if depths:
  mean_depth = mean(depths)
  abs_changes = [abs(depths[i] - depths[i-1]) for i in range(1, len(depths))]
  mean_abs_change = mean(abs_changes) if abs_changes else 0
  stability = max(0, min(1, 1 - (mean_abs_change / mean_depth))) if mean_depth > 0 else 0
else:
  stability = 0

# 综合评分(0-100)
tradability_score = (spread_score * 0.4 + depth_score * 0.4 + stability * 0.2) * 100
print(f"可交易性评分: {tradability_score:.1f}/100")

5) 下一步

  • 接入实时数据流,而非轮询
  • 按流动性桶(高、中、低)调整阈值
  • 当评分超过阈值时发送警报

内部链接:

发布于: 2026年6月23日 · 8 分钟 · SightWhale

相关文章