Polymarket

exchange.SetCurrency()

Polymarket 版本。设置当前交易标的,即某个预测市场的某个结果(Outcome)。格式、校验时机和解析方式都与其他交易所不同,通用说明见 exchange.SetCurrency()。

语法

python
exchange.SetCurrency(currency)

参数

参数类型必填说明
currencystr是标的,格式 {market_slug}_USDC.{outcome}

标的格式

plaintext
{market_slug}_USDC.{outcome}
示例含义
btc-updown-5m-1778612700_USDC.UpBTC 5 分钟涨跌市场的 Up 结果
btc-updown-5m-1778612700_USDC.Down同一市场的 Down 结果
will-bitcoin-hit-150k_USDC.Yes二元市场的 Yes 结果
  • market_slug:Polymarket 市场 slug(市场页面 URL 中的那一段)
  • outcome:结果名称,大小写不敏感,必须是该市场 outcomes 中的一个
  • 分隔符固定为 _USDC.
  • exchange.GetMarkets() 返回的 key、exchange.GetPosition() 返回的 Symbol 都是这种格式,可直接传入

返回值

  • 成功:None
  • gRPC 调用失败:False(错误写入策略日志)

格式错误不会让 SetCurrency() 失败,见下文"只保存,不校验"。

与其他交易所的区别

项其他交易所Polymarket
格式BASE_QUOTE,如 BTC_USDT{market_slug}_USDC.{outcome}
校验设置时即确定交易对只保存字符串,不访问网络、不校验
解析交易对直接用于下单每次使用时请求 Gamma API,把 slug + outcome 解析为 CLOB Token ID
优先级唯一的交易对来源低于全局 Token ID(IO("SetTokenID"))
实盘配置 symbol启动时生效当前不会传入,必须在策略中调用
GetCurrency() 默认值配置的交易对未设置时显示 "BTC_USDT"(无效值)

行为说明

1. 只保存,不校验

托管者只把字符串存入交易所实例。格式错误、slug 不存在、outcome 拼错,要到之后第一次调用 GetTicker / GetDepth / GetTrades / Buy / Sell / GetOrders / GetPendingOrders / CancelAllOrders 时才报错。建议设置后立刻调用一次 GetTicker() 验证。

2. 每次使用都会解析

需要 Token ID 时,托管者按以下步骤解析:

  1. 按 _USDC. 拆出 slug 和 outcome;
  2. 请求 Gamma API GET /markets?slug={slug};
  3. 在 outcomes 中查找 outcome(大小写不敏感),取同一下标的 clobTokenIds。

每次约 100~300ms。高频策略请在设置标的后再调用 exchange.IO("SetTokenID") 省去解析。

3. Token ID 优先级

plaintext
1. exchange.IO("SetTokenID", id) 设置的全局 Token ID   ← 最高优先级
2. exchange.SetCurrency(currency) 设置的标的             ← 每次请求 Gamma 解析
3. 都没有                                                 ← 报错
  • Buy / Sell / GetOrders / GetPendingOrders / CancelAllOrders 不接受 symbol,只按上述优先级。
  • GetTicker / GetDepth / GetTrades 传入 symbol 参数时直接按 symbol 解析,不受优先级影响,也不会改变当前标的。
  • 设置过全局 Token ID 后,只调用 SetCurrency() 不会改变下单标的。切换标的时先 exchange.IO("ClearTokenID"),或重新 SetTokenID。

4. 启动后必须设置

实盘配置中的 symbol 当前不会传入 Polymarket 实例。实例创建时标的为空,Python 端 GetCurrency() 会回退显示 "BTC_USDT",这不是有效的 Polymarket 标的。请在 main() 开头调用 SetCurrency() 或 IO("SetTokenID")。

解析错误

错误信息原因
invalid currency: missing '_USDC.' separator缺少 _USDC. 分隔符
invalid currency: missing slug before '_USDC.'slug 为空
invalid currency: missing outcome after '_USDC.'outcome 为空
market not found: {slug} / market not found with exact slugslug 不存在或已下线
outcome 'X' not found in market '{slug}' (available: [...])outcome 不在该市场的结果列表中
未设置 token ID 或 currency,请先调用 IO('SetTokenID', id) 或 SetCurrency(currency)两者都没有设置

这些错误出现在后续调用中,对应方法返回 None,详情写入策略日志。

示例

设置并立即验证

python
def main():
    exchange.SetCurrency("will-bitcoin-hit-150k_USDC.Yes")
    ticker = exchange.GetTicker()          # 首次真正解析标的
    if ticker is None:
        Log("标的无效,请检查 slug 和 outcome")
        return
    Log(f"Yes 价格 {ticker['Last']},当前标的 {exchange.GetCurrency()}")

从 GetMarkets 选择标的

python
markets = exchange.GetMarkets()
symbol = next((k for k in markets if k.startswith("btc-updown-5m-") and k.endswith("_USDC.Up")), None)
if symbol:
    exchange.SetCurrency(symbol)
    Log("已选择:", symbol)

在同一市场的两个结果之间切换下单

python
slug = "btc-updown-5m-1778612700"

exchange.IO("ClearTokenID")                  # 确保 SetCurrency 生效
exchange.SetCurrency(f"{slug}_USDC.Up")
exchange.Buy(0.45, 10, "买入 Up")

exchange.SetCurrency(f"{slug}_USDC.Down")
exchange.Buy(0.52, 10, "买入 Down")

只查行情时不必切换标的

python
slug = "btc-updown-5m-1778612700"
up = exchange.GetTicker(f"{slug}_USDC.Up")      # 不改变当前标的
down = exchange.GetTicker(f"{slug}_USDC.Down")
Log(f"Up {up['Last']} + Down {down['Last']} = {up['Last'] + down['Last']:.3f}")

高频策略:设置标的后固定 Token ID

python
markets = exchange.GetMarkets()
symbol = "btc-updown-5m-1778612700_USDC.Up"
info = markets[symbol]["info"]
outcomes = info["outcomes"] if isinstance(info["outcomes"], list) else json.loads(info["outcomes"])
token_ids = info["clobTokenIds"] if isinstance(info["clobTokenIds"], list) else json.loads(info["clobTokenIds"])

exchange.SetCurrency(symbol)
exchange.IO("SetTokenID", token_ids[[o.lower() for o in outcomes].index("up")])

相关方法