Files
my-polymarket-copytrader/项目概要.md
T

9.9 KiB
Raw Blame History

项目全流程

Polymarket Copy Trader — 一个自动跟单系统:监控 Polymarket 上最赚钱的钱包,找出多个钱包同时下注的"共识信号",然后发送 Telegram 通知(可选自动执行)。


启动命令

python -m src.main run        # 主程序:跑整个循环(6 个 asyncio 任务)
python -m src.main dashboard  # Web 看板(FastAPI,端口 8518
python -m src.main stats      # CLI 查看命中率 / PnL 统计
python -m src.main backfill   # 手动回填已 resolve 市场的信号结果
python -m src.main pool       # 立即重建钱包池并退出
python -m src.main test-stream # 测试交易流轮询

1. 钱包池构建(Pool Build

启动时,从 Polymarket 公开 API 拉取 24h 交易量最高的 200 个活跃市场,对每个市场拉取前 30 名持仓者,聚合后筛选出约 100 个最赚钱的钱包(PnL 最高、交易笔数多、覆盖品类多)。这 100 个钱包就是"被跟单目标"。

PnL 计算的数据源:对每个候选钱包并行调用 /positions(当前持仓 cashPnl+ /trades(近 30 天成交)+ /closed-positions(近 30 天已平仓 realizedPnl)。/closed-positionssortBy=TIMESTAMP + offset 翻页拉满整个 30 天窗口,避免服务端 50 条上限导致漏数据。详见 data_api.py:get_closed_positions_since


2. 交易流监控(Trade Stream

每隔 30 秒,对这 100 个钱包轮询 Polymarket Data API,抓取他们最新的交易记录。每笔交易触发 on_trade 回调,交给信号聚合器处理。


3. 共识信号聚合(Signal Aggregator

对每笔交易做 五层过滤

  1. 交易金额 ≥ 500 USDMIN_TRADE_SIZE_USD,可在 .env 调整)
  2. 价格在 0.1 ~ 0.9 之间(MIN_PRICE / MAX_PRICE,过滤已决议或极端价格市场)
  3. 钱包信誉分 ≥ 0.3MIN_CREDIBILITY
  4. 同一钱包对同一市场 10 分钟内只算一次(WALLET_DEBOUNCE_SECONDS
  5. 通过则进入"市场累加器"

共识规则:在 10 分钟窗口内(CONSENSUS_WINDOW_SECONDS),有 ≥ 2 个钱包 朝同一方向(都买或都卖)下注同一市场,且正反面力量差 ≥ 0.4(CONSENSUS_STRENGTH_THRESHOLD),就发出信号。

信号包含:市场名称、方向、入场价、聚合强度、参与钱包数、Kelly 公式建议仓位。


4. 信号输出

  • 存库:写入 SQLitedata/copytrader.db),供 Dashboard 展示
  • Telegram 通知:发送格式化消息(市场名、方向、建议仓位、来源钱包数)
  • Dashboard:Web 页面实时展示 Top 钱包排名 + 最近信号(每 30 秒自动刷新)

5. 贝叶斯信誉更新(Bayesian Updater

每 60 分钟(CREDIBILITY_UPDATE_MINUTES)运行一次:根据钱包历史交易的实际表现(赢/亏),用贝叶斯方法更新每个钱包的信誉分,形成 先验→后验 的正反馈。表现好的钱包权重上升,表现差的下降。

数据源:调用 /closed-positionssortBy=TIMESTAMP + 翻页)拉取近 BAYESIAN_DECAY_DAYS(默认 14 天)的全部平仓记录,累加 realizedPnl 作为更新依据。API 返回的已经全部在窗口内,无需在 Python 端二次过滤。


6. 钱包池定期刷新

每 24 小时(WALLET_REFRESH_HOURS)重建一次钱包池,淘汰表现差的,引入新晋赚钱钱包。


7. 信号结果回填(Outcome Resolver

第 6 个 asyncio 循环,每 15 分钟(OUTCOME_RESOLVE_MINUTES)扫描 copy_signals 表中 resolved_at IS NULL 的信号,调用 Gamma /markets API 拉取市场结算结果,回填以下字段:

字段 含义
exit_price 1.0(赢) / 0.0(输)
pnl_usd 理论 PnLwin = S*(1-p)/ploss = -SS=suggested_sizep=entry_price
outcome_correct 1(赢) / 0(输) / -1(市场取消)
resolved_at 市场 closedTime

PnL 模型说明:理论"全仓按 entry_price 成交" PnL,不建模滑点。用于策略评估,非真实账户 PnL。

手动 backfillpython -m src.main backfill --batch 500 一次性回填历史信号。

解析逻辑严格遵循 Gamma /markets 文档:closed=true + outcomePrices 中价格 ≥ 0.99 的 outcome 即为赢家。


8. 策略分析看板(Analytics Dashboard

访问 http://localhost:8518/analytics,展示 6 个维度的聚合统计,每个维度都用于调参:

维度 调参目标
强度分桶命中率 CONSENSUS_STRENGTH_THRESHOLD — 理想下强度越高命中率越高
共识钱包数分桶 CONSENSUS_MIN_WALLETS — 理想下钱包数越多命中率越高
各时段命中率 优化 pool_refresh 调度时间
品类表现 发现跟单有效的品类
钱包排行榜 反向验证信誉分公式 — 高信誉钱包应排前列
总体表现 总命中率 / 总 PnL / 平均 PnL

API 端点/api/outcomes, /api/stats/by-strength, /by-wallet-count, /by-wallet, /by-category, /by-hour, /api/credibility-history?address=...

调参闭环:看 Analytics → 发现某分桶表现差 → 调 .env → 重启 → 等待新数据 → 再看 Analytics 验证。


.env 关键配置

分组 配置项 说明
资金 INITIAL_CAPITAL_USD 模拟本金(默认 $10000
KELLY_FRACTION Kelly 仓位比例(0.5 = 半 Kelly
价格防护 MIN_PRICE / MAX_PRICE 只跟单价格在 0.1~0.9 的市场
交易规则 MIN_TRADE_SIZE_USD 忽略低于此金额的交易(默认 500
ENABLE_EXECUTION 设为 true 才真执行(默认 false 只通知)
钱包池 WALLET_POOL_SIZE 监控钱包数(默认 100
WALLET_PNL_MIN_USD 钱包最低 PnL 门槛(默认 $5000)
WALLET_REFRESH_HOURS 池刷新间隔(默认 24h
共识 CONSENSUS_MIN_WALLETS 触发信号最少钱包数(默认 2
CONSENSUS_WINDOW_SECONDS 共识窗口(默认 600s
CONSENSUS_STRENGTH_THRESHOLD 正反面差值门槛(默认 0.4
MIN_CREDIBILITY 钱包最低信誉分(默认 0.3
WALLET_DEBOUNCE_SECONDS 去重窗口(默认 600s
信誉分 BAYESIAN_PRIOR_SKILL 初始信誉分(默认 0.5
BAYESIAN_DECAY_DAYS PnL 累计窗口(默认 14 天)
BAYESIAN_STEP 贝叶斯步长(默认 0.05
CREDIBILITY_UPDATE_MINUTES 更新间隔(默认 60min
信号回填 OUTCOME_RESOLVE_MINUTES 回填循环间隔(默认 15min
OUTCOME_RESOLVE_BATCH_SIZE 每批最多扫描信号数(默认 50
OUTCOME_RESOLVE_TIMEOUT 单次 /markets 请求超时(默认 5s
Telegram TELEGRAM_ENABLED 是否启用(默认 false
TELEGRAM_BOT_TOKEN BotFather 给的 token(必填)
TELEGRAM_CHAT_ID 发送目标的 chat ID(必填)
代理 HTTP_PROXY 需要翻墙时填写(如 http://127.0.0.1:7890
轮询 USER_POLL_INTERVAL_SECONDS 钱包轮询间隔(默认 30s
STREAM_MAX_TRADES_PER_WALLET 每次拉取最多交易数(默认 20
数据库 DB_PATH SQLite 路径(默认 data/copytrader.db
CLOB POLY_API_KEY 仅启用实盘执行时填

数据库并发模型

SQLite 由四个异步协程并发写入:pool_refresh(写钱包池)、trade_stream(写信号)、credibility(写信誉分 + 信誉历史)、outcome_resolve(写信号回填),均通过 asyncio.to_thread 在线程池里执行。CopyTraderDatabase 的并发治理策略(见 db/database.py):

  • 单一长连接 + check_same_thread=False(不再每次操作开关连接)
  • threading.RLock 串行化所有方法,进程内永远只有一个 writer
  • WAL 模式 + synchronous=NORMAL:多读不阻塞写
  • busy_timeout=10000ms:跨进程写冲突(如 Dashboard 进程)等待 10s 而非立即抛 database is locked

数据库表结构

用途 关键字段
wallet_targets 跟单目标钱包池 address, credibility, health_score, pnl_30d_usd
copy_signals 发出的共识信号 condition_id, side, entry_price, aggregated_strength, n_contributors, outcome_correct, pnl_usd, resolved_at
credibility_history 信誉分演化历史(append-only address, credibility, realized_pnl_window, n_closed, updated_at
trade_executions 实盘执行记录 signal_id, order_id, status, executed_at
pool_state KV 持久化(重启恢复) key, valueJSON

pool_state 存储的 keylast_pool_refreshlast_credibility_updateopen_accumulators(共识累加器)、stream_last_seen(交易去重)、wallet_debounce(钱包级去重)。