市場結算是 Polymarket 確定預測市場最終結果並分配獎金的過程。
法律合規提醒:在使用 Polymarket 服務或 API 前,請確認您所在地區的法律規定。Polymarket 目前不支援比利時、法國、新加坡、泰國、中國大陸等地區,政策可能隨時變化。
什麼是市場結算?
市場結算是在預測事件發生後,確定哪個結果獲勝,並允許獲勝方兌換代幣為 USDC 的過程。
事件發生 → Oracle 報告 → 爭議期 → 最終結算 → 用戶贖回
結算流程
1. 事件發生
現實世界的事件結果確定(如選舉結果公布、比賽結束)
2. Oracle 提交結果
UMA Oracle 根據預定義的規則提交結果
3. 爭議期
2-48 小時的爭議期,任何人可以質疑結果
5. 用戶贖回
獲勝代幣持有者可以將代幣兌換為 USDC
UMA Oracle 系統
Polymarket 使用 UMA (Universal Market Access) 作為去中心化 Oracle:
UMA 的優勢
工作機制
- 提議:任何人可以提交結果提議
- 質押:提議者需要質押 UMA 代幣
- 爭議:其他人可以質押代幣質疑
- 投票:如有爭議,UMA 代幣持有者投票
- 獎懲:正確方獲得獎勵,錯誤方失去質押
結算標準
每個市場有明確的結算規則,通常包括:
數據源
**數據源**:美聯社(AP)、路透社、彭博社等權威媒體
**結算時間**:官方結果公布後 48 小時
**爭議處理**:如有重大爭議,延長結算時間
示例:總統選舉市場
問題:誰將贏得 2024 年美國總統大選?
結算規則:
1. 數據源:美聯社、CNN、福克斯新聞中至少兩家宣布獲勝者
2. 時間:選舉日後,當獲勝者獲得 270 張選舉人票
3. 特殊情況:如選舉結果被推翻,市場可能重新結算
檢查結算狀態
通過 API 查詢
from py_clob_client.client import ClobClient
import requests
# 使用 Subgraph 查詢
SUBGRAPH_URL = "https://api.thegraph.com/subgraphs/name/polymarket/polymarket"
def check_settlement_status(condition_id):
"""
檢查市場是否已結算
"""
query = """
query CheckSettlement($conditionId: String!) {
condition(id: $conditionId) {
id
resolved
resolveTimestamp
payouts
}
}
"""
response = requests.post(
SUBGRAPH_URL,
json={'query': query, 'variables': {'conditionId': condition_id}}
)
data = response.json()['data']['condition']
if data['resolved']:
print(f"✓ 市場已結算")
print(f"結算時間: {data['resolveTimestamp']}")
print(f"支付向量: {data['payouts']}")
# 判斷獲勝方
if data['payouts'][0] > data['payouts'][1]:
print("獲勝方: Yes")
elif data['payouts'][1] > data['payouts'][0]:
print("獲勝方: No")
else:
print("結果: 無效/平局")
else:
print("✗ 市場尚未結算")
return data['resolved']
# 使用示例
condition_id = "0x1234..."
check_settlement_status(condition_id)
TypeScript 示例
interface SettlementStatus {
resolved: boolean;
resolveTimestamp?: string;
payouts?: number[];
winner?: 'Yes' | 'No' | 'Invalid';
}
async function checkSettlement(conditionId: string): Promise<SettlementStatus> {
const query = `
query {
condition(id: "${conditionId}") {
id
resolved
resolveTimestamp
payouts
}
}
`;
const response = await fetch(SUBGRAPH_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query })
});
const data = await response.json();
const condition = data.data.condition;
if (condition.resolved) {
const winner = condition.payouts[0] > condition.payouts[1]
? 'Yes'
: condition.payouts[1] > condition.payouts[0]
? 'No'
: 'Invalid';
return {
resolved: true,
resolveTimestamp: condition.resolveTimestamp,
payouts: condition.payouts,
winner
};
}
return { resolved: false };
}
結算類型
1. 標準結算
最常見的情況,有明確的獲勝方:
Yes 代幣: 1 USDC
No 代幣: 0 USDC
2. 無效結算
當市場規則不明確或無法確定結果:
Yes 代幣: 0.5 USDC
No 代幣: 0.5 USDC
3. 部分結算
罕見情況,結果介於兩者之間(通常會避免):
Yes 代幣: 0.7 USDC
No 代幣: 0.3 USDC
爭議處理
發起爭議
如果你認為結算結果不正確:
- 準備證據:收集支援你觀點的證據
- 質押代幣:需要質押一定數量的 UMA 代幣
- 提交爭議:在 UMA 系統中提交
- 等待投票:UMA 代幣持有者投票決定
爭議成本
爭議質押: 通常 1000-10000 UMA
時間: 48-96 小時
風險: 如果爭議失敗,質押會被沒收
注意:發起爭議有成本和風險。只在有充分理由時才爭議。
自動監控結算
創建腳本監控市場結算:
import time
from datetime import datetime
def monitor_settlements(condition_ids):
"""
持續監控多個市場的結算狀態
"""
settled = set()
while len(settled) < len(condition_ids):
print(f"\n[{datetime.now()}] 检查结算状态...")
for condition_id in condition_ids:
if condition_id in settled:
continue
try:
status = check_settlement_status(condition_id)
if status:
print(f"✓ 市场 {condition_id[:8]}... 已结算")
settled.add(condition_id)
# 可以在这里自动赎回
# redeem_tokens(condition_id)
else:
print(f"○ 市场 {condition_id[:8]}... 等待结算")
except Exception as e:
print(f"✗ 查询失败: {e}")
if len(settled) < len(condition_ids):
print(f"\n等待中... ({len(settled)}/{len(condition_ids)} 已结算)")
time.sleep(300) # 5分钟后再检查
print("\n所有市场已结算完成!")
# 使用示例
markets_to_monitor = [
"0xabc123...",
"0xdef456...",
"0x789ghi..."
]
monitor_settlements(markets_to_monitor)
结算后赎回
市场结算后,立即赎回获胜代币:
from web3 import Web3
def auto_redeem_on_settlement(condition_id, winning_side):
"""
市场结算后自动赎回
"""
# CTF 合约
ctf_contract = w3.eth.contract(
address='0x4D97DCd97eC945f40cF65F87097ACe5EA0476045',
abi=ctf_abi
)
# 确定赎回的索引集
if winning_side == 'Yes':
index_sets = [1]
elif winning_side == 'No':
index_sets = [2]
else: # Invalid
index_sets = [1, 2]
# 赎回代币
tx = ctf_contract.functions.redeemPositions(
usdc_address,
'0x' + '0' * 64,
condition_id,
index_sets
).build_transaction({
'from': your_address,
'nonce': w3.eth.get_transaction_count(your_address)
})
signed_tx = w3.eth.account.sign_transaction(tx, private_key)
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
print(f"赎回交易: {tx_hash.hex()}")
receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
print(f"✓ 赎回成功")
return receipt
结算时间线
典型的市场结算时间线:
事件发生: 2024-11-05 20:00 (选举日)
↓
初步结果: 2024-11-06 02:00 (+6小时)
↓
Oracle 提交: 2024-11-06 10:00 (+14小时)
↓
争议期开始: 2024-11-06 10:00
争议期结束: 2024-11-08 10:00 (+48小时)
↓
最终结算: 2024-11-08 10:00
↓
用户赎回: 随时可进行
查看历史结算
def get_settlement_history(days=30):
"""
获取过去N天的结算历史
"""
import time
timestamp = int(time.time()) - (days * 24 * 3600)
query = """
query RecentSettlements($timestamp: Int!) {
conditions(
where: {
resolved: true
resolveTimestamp_gt: $timestamp
}
orderBy: resolveTimestamp
orderDirection: desc
first: 100
) {
id
questionId
resolveTimestamp
payouts
}
}
"""
response = requests.post(
SUBGRAPH_URL,
json={'query': query, 'variables': {'timestamp': timestamp}}
)
settlements = response.json()['data']['conditions']
print(f"过去 {days} 天共结算 {len(settlements)} 个市场:\n")
for s in settlements[:10]: # 显示前10个
print(f"条件 ID: {s['id'][:10]}...")
print(f"结算时间: {s['resolveTimestamp']}")
print(f"支付向量: {s['payouts']}")
print("---")
return settlements
常见问题
Q: 结算需要多长时间?
A: 通常在事件发生后 6-72 小时,取决于结果的明确性和是否有争议。
Q: 如果结算结果错误怎么办?
A: 可以在争议期内发起争议,需要质押 UMA 代币。
Q: 无效结算时我会损失吗?
A: 不会。无效结算时,Yes 和 No 代币各获得 50% 的价值。
Q: 赎回有时间限制吗?
A: 没有。你可以在结算后任何时间赎回,即使是几个月后。
Q: 可以在结算前卖出代币吗?
A: 可以。在市场结算前,你可以随时在 CLOB 上交易代币。
下一步
參考資源