Files
winning-wallet-finder/每周五Review命令.md
T
gavindiaz 24af8d88f0 docs: add 每周五Review命令.md - 7-step weekly review with exact commands
7 steps with comments explaining what each does and which files it reads:
1. Run portfolio.py --days 30 (regenerate forward P&L)
2. Read portfolio.json per-wallet forward realized (core decision data)
3. Read watch_sharps.json copy_pnl + conv_win rankings (reference only)
4. Check daily.log for floor drift warnings
5. Check live bot journalctl for trading activity
6. Query chain pUSD balance via SecureClient
7. Find new candidates in watch_sharps not in backtest.json

Includes one-shot script that runs all 7 steps at once.
2026-07-24 08:10:03 +08:00

9.3 KiB
Raw Blame History

每周五 Bench Review 完整流程

每周五在服务器上跑一遍,把输出贴给 AI 代理分析。 AI 代理按 AGENT.md 的 5 个维度给建议,人类拍板执行。


第 1 步:重新跑 30 天回测

做什么:用最新的 cache 数据,对 backtest.json 里的所有钱包(live + bench)跑一次 30 天模拟跟单,产出 portfolio.json

相关文件backtest.json(输入:钱包列表)-> portfolio.json(输出:前瞻盈亏)

cd /opt/winning-wallet-finder/live && python3 portfolio.py --days 30

第 2 步:看每个钱包的前瞻盈亏排名

做什么:读 portfolio.json 的 wallets 数组,按 30 天前瞻 realized 盈亏排序,标注哪个是 LIVE 哪个是 bench

相关文件portfolio.json(读)-> copybot.paper.json(对比哪些是 LIVE

这是决策的核心数据:前瞻 realized > 0 才考虑保留,连续 2 周负考虑降级

python3 -c "
import json
d = json.load(open('portfolio.json'))
live_names = {'Kruto2027','0xbadaf319','1kto1m','Vahan88','LSB1','EdwardIN','lma0o0o0o','Coteykens'}
ws = d.get('wallets', [])
print('=== 30天前瞻盈亏排名 ===')
print(f'{\"钱包\":20s} {\"笔数\":>4s} {\"胜\":>3s} {\"负\":>3s} {\"卖\":>3s} {\"已实现\":>10s} {\"状态\":>6s}')
print('-' * 60)
for w in sorted(ws, key=lambda x: x.get('realized',0), reverse=True):
    name = w.get('name','?')
    tag = 'LIVE' if name in live_names else 'bench'
    print(f'{name:20s} {w.get(\"bets\",0):4d} {w.get(\"won\",0):3d} {w.get(\"lost\",0):3d} {w.get(\"sold\",0):3d}  \${w.get(\"realized\",0):+9.2f}  {tag:>6s}')
print(f'\n总计: equity \${d[\"equity\"]:,.0f} | realized \${d[\"realized\"]:+,.0f} | {d[\"resolved_count\"]} resolved')
"

第 3 步:看候选池排名

做什么:读 watch_sharps.json,按 copy_pnl 排序,看信念胜率和前瞻胜率

相关文件watch_sharps.jsondaily.sh 自动产出)

注意copy_pnl 是 in-sample 的,会骗人(oliman2 copy_pnl #1 但前瞻亏)。只作参考,不作决策依据

cat watch_sharps.json | python3 -c "
import sys,json
data=json.load(sys.stdin)
data.sort(key=lambda w: w.get('copy_pnl',0), reverse=True)
print('=== watch_sharps 候选排名 ===')
for i,w in enumerate(data):
    name = w.get('name') or w.get('wallet','')[:10]
    win = w.get('conv_win')
    winstr = f'{win:.0f}%' if win is not None else '?'
    fwd = w.get('fwd_win',0)
    fwdstr = f'{fwd:.0f}%' if fwd else '?'
    print(f'#{i+1:2d} {name:20s} copy_pnl+{w.get(\"copy_pnl\",0):5d} conv_win={winstr} fwd_win={fwdstr}')
print(f'\n总共 {len(data)} 个候选')
"

第 4 步:看 floor 有没有漂移

做什么:读 daily.log 里 sync_floors 的输出,看有没有门槛大幅漂移的警告

相关文件daily.log(读)-> copybot.paper.jsonfloor 被 sync_floors.py 写入)

判断⚠ floor X->Y 漂移 > 15% -> 建议钉 floor_pin 防止 paper/live 门槛不一致

grep "floor" daily.log | tail -10

第 5 步:看本周 bot 跟单记录

做什么:读 live bot 最近 7 天的日志,看 FOLLOW(跟了什么)、skip(跳过了什么)、OPEN(实际下单了什么)

相关文件journalctlsystemd 日志)

用途:看 bot 实际跟了哪些信号、有没有异常(大量 skip / ORDER FAILED / RTDS down

journalctl -u copybot-live --since "7 days ago" --no-pager | grep -E "FOLLOW|OPEN|skip" | tail -30

第 6 步:看链上真实余额

做什么:通过 SecureClient 查存款钱包的实际 pUSD 余额

相关文件/etc/copybot/live.env(读私钥)-> Polymarket 链上

用途:确认真实资金状况,对比 bot 账本是否一致(CASH≠CHAIN

export LIVE_PRIVATE_KEY=$(grep LIVE_PRIVATE_KEY /etc/copybot/live.env | cut -d= -f2-) && export HTTPS_PROXY=http://127.0.0.1:7890 && python3 -c "from polymarket import SecureClient; c=SecureClient.create(private_key='$LIVE_PRIVATE_KEY'); b=c.get_balance_allowance(asset_type='COLLATERAL'); print('链上 pUSD: %.2f' % (b.balance/1e6)); c.close()"

第 7 步:找出新候选(watch_sharps 里有但 backtest.json 里没有的)

做什么:对比 watch_sharps.json 和 backtest.json,找出 daily.sh 新筛出来但还没在观察区的钱包

相关文件watch_sharps.json(读:全部候选)+ backtest.json(读:已在观察的)

用途:发现新钱包,如果 copy_pnl 高 + 信念胜率好,加到 backtest.json 开始观察前瞻表现

python3 -c "
import json
sharps = json.load(open('watch_sharps.json'))
bt = json.load(open('backtest.json'))
bt_addrs = {w['wallet'].lower() for w in bt['wallets']}

new_candidates = [w for w in sharps if w.get('wallet','').lower() not in bt_addrs]
new_candidates.sort(key=lambda w: w.get('copy_pnl',0), reverse=True)

print('=== watch_sharps 里的新候选(不在 backtest.json 里)===')
print(f'watch_sharps 总共 {len(sharps)} 个,backtest.json 已有 {len(bt[\"wallets\"])} 个')
print(f'新候选: {len(new_candidates)} 个')
print()
print(f'{\"名字\":20s} {\"copy_pnl\":>10s} {\"信念胜率\":>8s} {\"前瞻胜率\":>8s}')
print('-' * 50)
for w in new_candidates[:15]:
    name = w.get('name') or w.get('wallet','')[:10]
    win = w.get('conv_win')
    winstr = f'{win:.0f}%' if win is not None else '?'
    fwd = w.get('fwd_win',0)
    fwdstr = f'{fwd:.0f}%' if fwd else '?'
    print(f'{name:20s} +{w.get(\"copy_pnl\",0):9d} {winstr:>8s} {fwdstr:>8s}')
"

一键跑全部 7 步

如果想一次性跑完所有步骤,复制下面整段:

cd /opt/winning-wallet-finder/live

echo "========== 第 1 步:跑回射 =========="
python3 portfolio.py --days 30

echo ""
echo "========== 第 2 步:前瞻盈亏排名 =========="
python3 -c "
import json
d = json.load(open('portfolio.json'))
live_names = {'Kruto2027','0xbadaf319','1kto1m','Vahan88','LSB1','EdwardIN','lma0o0o0o','Coteykens'}
ws = d.get('wallets', [])
print('=== 30天前瞻盈亏排名 ===')
print(f'{\"钱包\":20s} {\"笔数\":>4s} {\"胜\":>3s} {\"负\":>3s} {\"卖\":>3s} {\"已实现\":>10s} {\"状态\":>6s}')
print('-' * 60)
for w in sorted(ws, key=lambda x: x.get('realized',0), reverse=True):
    name = w.get('name','?')
    tag = 'LIVE' if name in live_names else 'bench'
    print(f'{name:20s} {w.get(\"bets\",0):4d} {w.get(\"won\",0):3d} {w.get(\"lost\",0):3d} {w.get(\"sold\",0):3d}  \${w.get(\"realized\",0):+9.2f}  {tag:>6s}')
print(f'\n总计: equity \${d[\"equity\"]:,.0f} | realized \${d[\"realized\"]:+,.0f} | {d[\"resolved_count\"]} resolved')
"

echo ""
echo "========== 第 3 步:候选池排名 =========="
cat watch_sharps.json | python3 -c "
import sys,json
data=json.load(sys.stdin)
data.sort(key=lambda w: w.get('copy_pnl',0), reverse=True)
print('=== watch_sharps 候选排名 ===')
for i,w in enumerate(data):
    name = w.get('name') or w.get('wallet','')[:10]
    win = w.get('conv_win')
    winstr = f'{win:.0f}%' if win is not None else '?'
    fwd = w.get('fwd_win',0)
    fwdstr = f'{fwd:.0f}%' if fwd else '?'
    print(f'#{i+1:2d} {name:20s} copy_pnl+{w.get(\"copy_pnl\",0):5d} conv_win={winstr} fwd_win={fwdstr}')
print(f'\n总共 {len(data)} 个候选')
"

echo ""
echo "========== 第 4 步:floor 漂移 =========="
grep "floor" daily.log | tail -10

echo ""
echo "========== 第 5 步:本周跟单记录 =========="
journalctl -u copybot-live --since "7 days ago" --no-pager | grep -E "FOLLOW|OPEN|skip" | tail -30

echo ""
echo "========== 第 6 步:链上余额 =========="
export LIVE_PRIVATE_KEY=$(grep LIVE_PRIVATE_KEY /etc/copybot/live.env | cut -d= -f2-) && export HTTPS_PROXY=http://127.0.0.1:7890 && python3 -c "from polymarket import SecureClient; c=SecureClient.create(private_key='$LIVE_PRIVATE_KEY'); b=c.get_balance_allowance(asset_type='COLLATERAL'); print('链上 pUSD: %.2f' % (b.balance/1e6)); c.close()"

echo ""
echo "========== 第 7 步:新候选 =========="
python3 -c "
import json
sharps = json.load(open('watch_sharps.json'))
bt = json.load(open('backtest.json'))
bt_addrs = {w['wallet'].lower() for w in bt['wallets']}
new_candidates = [w for w in sharps if w.get('wallet','').lower() not in bt_addrs]
new_candidates.sort(key=lambda w: w.get('copy_pnl',0), reverse=True)
print('=== watch_sharps 里的新候选(不在 backtest.json 里)===')
print(f'watch_sharps 总共 {len(sharps)} 个,backtest.json 已有 {len(bt[\"wallets\"])} 个')
print(f'新候选: {len(new_candidates)} 个')
print()
print(f'{\"名字\":20s} {\"copy_pnl\":>10s} {\"信念胜率\":>8s} {\"前瞻胜率\":>8s}')
print('-' * 50)
for w in new_candidates[:15]:
    name = w.get('name') or w.get('wallet','')[:10]
    win = w.get('conv_win')
    winstr = f'{win:.0f}%' if win is not None else '?'
    fwd = w.get('fwd_win',0)
    fwdstr = f'{fwd:.0f}%' if fwd else '?'
    print(f'{name:20s} +{w.get(\"copy_pnl\",0):9d} {winstr:>8s} {fwdstr:>8s}')
"

echo ""
echo "========== 全部完成,把以上输出贴给 AI 代理分析 =========="

跑完后

  1. 把全部输出复制给 AI 代理
  2. AI 代理按 AGENT.md 的 5 个维度分析,输出建议报告
  3. 人类根据建议做决策
  4. 人类在服务器执行变更(晋升/降级/钉 floor/加新候选)
  5. 变更后更新 setup_wallets.py 记录