Files
Hermes-Skills/okx-auto-position/references/v4.5.90-2026-09-16-position-sizing-200cap-1000skip-hard-check.md

4.8 KiB
Raw Permalink Blame History

v4.5.90 (2026-09-16) 仓位上限规则细化: $200 单币 ceiling + $1000 总资产 disable + process_signal hard pre-trade check

会话: 9 月 16 日继续 9/14 CL 98.5% bug 修复讨论, 用户最终拍板单币种仓位规则。

用户最终拍板的规则

# 单币种上限 = min(总资产, $200)
# 首仓 (已用=0): 上限 × 70%
# 加仓 (已用>0): 上限 × 100% (可追满)
# 总资产 ≥ $1000: 整个信号跳过 + 推 QQ 提示

多次纠正理解:

  • 第一轮: user 说 "单币最多 $200 的 70%", 我理解成"单币占总资产 70%" (MEMORY 9/10 已存)
  • 第二轮: 我又理解错为"单次加仓 $200"
  • 第三轮: user 明确"单币种的总占用上限就是 $200, 多少用多少, 百分比按这个算"

改动 (3 处)

1. config.json

"position_sizing": {
  "balance_utilization": 0.60,
  "single_coin_max_pct": 0.70,                    // 已有
  "single_coin_add_pct": 1.00,                    // 新
  "single_coin_ceiling_usdt": 200,                // 新
  "single_coin_total_cap_disable_usdt": 1000,     // 新 (≥1000 跳过)
  "safety_factor": 1.07,                           // 新 (从代码迁出)
  "max_leverage": 20,
  "default_leverage": 10,
  "min_profit_usdt": 10
}

2. okx_position_advisor.py recommend_position

替换原 75% × total_cap 公式:

# 2026-09-16: 单币种上限 = min(总资产, $200), 百分比按上限算
total_cap = acct_info.get('total_capital', acct_info['usdt_free'])
disable_threshold = cfg('position_sizing', 'single_coin_total_cap_disable_usdt', 1000)
if total_cap >= disable_threshold:
    return {'error': f'⚠️ 总资产 ${total_cap:.2f} ≥ ${disable_threshold}, 配置上限失效, 跳过'}

# 当前同币种已用保证金
base = symbol.split('/')[0]
same_coin_margin = 0.0
for p in acct_info.get('positions', []):
    if p['symbol'].startswith(base):
        same_coin_margin += abs(p['margin'])

# 单币种上限 = min(总资产, $200)
coin_cap = min(total_cap, cfg('position_sizing', 'single_coin_ceiling_usdt', 200))
# 首仓 vs 加仓
if same_coin_margin == 0:
    cap = coin_cap * cfg('position_sizing', 'single_coin_max_pct', 0.70)
else:
    cap = coin_cap * cfg('position_sizing', 'single_coin_add_pct', 1.00)
# 还可加仓 = 上限 - 已用
single_coin_avail = max(0, cap - same_coin_margin)

# 同时考虑 free 余额 + 1.07 缓冲
SAFETY_FACTOR = cfg('position_sizing', 'safety_factor', 1.07)
avail_margin = min(acct_info['usdt_free'] / SAFETY_FACTOR, single_coin_avail / SAFETY_FACTOR)

advisor return dict 加 single_coin_avail 字段 (供 process_signal hard check 用):

return {
    ...
    'single_coin_avail': round(single_coin_avail, 2),
    ...
}

3. process_signal.py hard pre-trade check (CL bug 9/14 必修)

execute 前加:

# 2026-09-16: hard pre-trade check (CL bug 9/14 教训)
# 不可信 advisor rec['contracts'] — 复核单币种上限
try:
    margin_to_use = float(rec.get('margin') or 0)
    single_coin_avail = float(rec.get('single_coin_avail') or 0)
except (TypeError, ValueError):
    margin_to_use = 0
    single_coin_avail = 0
if margin_to_use > single_coin_avail + 1.0:  # 1 刀容差
    push_to_qq(f"❌ 拒绝: {symbol} 单币超限 "
               f"(本次 ${margin_to_use:.2f} > 上限 ${single_coin_avail:.2f})")
    record_signal(dedup_conn, text, symbol, trader)
    dedup_conn.close()
    return f"⏭️ 单币超限跳过 | {symbol} | ${margin_to_use:.2f} > ${single_coin_avail:.2f}"

record_signal + dedup_conn.close() 在跳过分支 — 信号标 done 不再来 (用户原话: "A. 拒绝执行 + 推 QQ + 信号标记 done (不会再来)")。

触发场景

总资产 单币上限 首仓 (70%) 加仓 (100%)
$50 $50 $35 $50
$150 $150 $105 $150
$200 $200 $140 $200
$300 $200 (封顶) $140 $200
$500 $200 $140 $200
$999 $200 $140 $200
$1000+ ⚠️ 跳过 ⚠️ 跳过 ⚠️ 跳过

验证

$ cd ~/.hermes/skills/trading/okx-auto-position/scripts && python3 -c "
from config_loader import get as cfg
print('ceiling =', cfg('position_sizing', 'single_coin_ceiling_usdt'))  # 200
print('max_pct =', cfg('position_sizing', 'single_coin_max_pct'))       # 0.7
print('add_pct =', cfg('position_sizing', 'single_coin_add_pct'))       # 1.0
print('disable =', cfg('position_sizing', 'single_coin_total_cap_disable_usdt'))  # 1000
print('safety  =', cfg('position_sizing', 'safety_factor'))             # 1.07
"

关联

  • v4.5.86: 单币种上限 70% 首次配置化 (比例, 无 $200 封顶)
  • v4.5.87-88: CL 98.5% bug 教训, advisor free 字段不可信
  • v4.5.89: advisor hard pre-trade check 入口 (现在 v4.5.90 落地)
  • v4.5.90 (本次): 完整公式 + $200 ceiling + $1000 disable + advisor return single_coin_avail 字段 + process_signal hard check