Files
Hermes-Skills/trading/okx-auto-position/scripts/fix_recommendation.py
T
Hermes Skills Manager 6770bc9b9d Initial commit: Hermes Agent skills collection
- Trading skills (OKX, dividend, lottery, quantitative)
- Creative skills (ASCII art, diagrams, video)
- Development skills (GitHub, debugging, TDD)
- Research skills (arXiv, blog monitoring)
- Productivity skills (email, documents, notes)
- MCP integration skills
- Custom user skills
2026-07-05 02:31:15 -04:00

171 lines
5.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
修正跟单方案金额。
用法: echo "原始信号文本" | python3 fix_recommendation.py
或: python3 fix_recommendation.py "原始信号文本"
从信号文本提取币种/方向/杠杆,调advisor脚本获取正确金额,替换原消息中的跟单方案部分。
"""
import sys
import re
import json
import subprocess
from pathlib import Path
ADVISOR = Path.home() / ".hermes/skills/trading/okx-auto-position/scripts/okx_position_advisor.py"
def extract_from_signal(text):
"""从信号文本提取关键字段"""
fields = {}
# 币种
m = re.search(r'跟单建议\s*\|\s*(\w+)', text)
if m:
fields['symbol'] = m.group(1)
# 方向
if '做多' in text:
fields['side'] = 'long'
elif '做空' in text:
fields['side'] = 'short'
# 杠杆
m = re.search(r'(\d+)x', text)
if m:
fields['leverage'] = m.group(1)
# 交易员
m = re.search(r'📊\s*(\S+)', text)
if m:
fields['trader'] = m.group(1)
# 交易员仓位
m = re.search(r'📊\s*\S+\s+([\d,.]+\s*\w+)', text)
if m:
fields['trader_pos'] = m.group(1)
# 交易员价值
m = re.search(r'(价值\$?([\d,.]+)', text)
if m:
fields['trader_value'] = m.group(1)
# 入场价
m = re.search(r'入场:\s*\$?([\d,.]+)', text)
if m:
fields['entry'] = m.group(1).replace(',', '')
# 浮盈
m = re.search(r'浮[盈亏]:\s*([+-]?\$?[\d,.]+)', text)
if m:
fields['pnl'] = m.group(1).replace('$', '').replace(',', '')
return fields
def run_advisor(symbol, side, leverage):
"""调advisor脚本获取正确数据"""
# Don't add /USDT - advisor handles symbol format internally
cmd = ['python3', str(ADVISOR), '--symbol', symbol, '--side', side, '--leverage', str(leverage), '--json']
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30, cwd=str(ADVISOR.parent))
if result.returncode == 0:
return json.loads(result.stdout)
except Exception as e:
return {'error': str(e)}
return {'error': 'advisor failed'}
def rebuild_message(original, fields, rec):
"""用正确数据重建消息"""
if 'error' in rec:
return f"⚠️ advisor错误: {rec['error']}\n\n{original}"
symbol = fields.get('symbol', '?')
side_cn = '做多' if fields.get('side') == 'long' else '做空'
emoji = '🟩' if fields.get('side') == 'long' else '🟥'
leverage = fields.get('leverage', '10')
trader = fields.get('trader', '?')
trader_pos = fields.get('trader_pos', '?')
trader_value = fields.get('trader_value', '?')
entry = fields.get('entry', '?')
pnl = fields.get('pnl', '0')
# 性价比
cc = rec.get('cost_check', {})
rr = cc.get('rr_ratio', rec.get('rr', 0))
profit = cc.get('profit_amount', rec.get('tp_pnl', 0))
fee = cc.get('fee_cost', 0)
fee_pct = cc.get('fee_pct', 0)
net = cc.get('net_profit', 0)
rating_emoji = cc.get('rating_emoji', '⚠️')
rating_text = cc.get('rating_text', '未知')
pnl_float = float(pnl) if pnl else 0
pnl_emoji = '🔥' if pnl_float > 0 else '🔴'
pnl_sign = '+' if pnl_float > 0 else ''
# 提取原始消息的趋势分析和ATR部分
trend_match = re.search(r'(📈 趋势分析.*?)(?=🛡️)', original, re.DOTALL)
trend_block = trend_match.group(1).strip() if trend_match else "📈 趋势分析\n• 数据加载中"
atr_match = re.search(r'(🛡️ ATR检查.*?)(?=📐|🎯|回复)', original, re.DOTALL)
atr_block = atr_match.group(1).strip() if atr_match else "🛡️ ATR检查\n• 数据加载中"
msg = f"""⚡ 跟单建议 | {symbol} {side_cn} {emoji} {leverage}x
📊 {trader} {trader_pos}(价值${trader_value})← 信号源,非你的仓位
入场: ${entry} | 当前: ${rec['price']}
浮盈: {pnl_sign}{pnl_float:.0f} {pnl_emoji} | 强平距: ${rec.get('liq_price', '?')}
{trend_block}
{atr_block}
📐 性价比检查(基于你的推荐仓位)
• 你的仓位: {rec['contracts']}张(保证金{rec['margin']:.2f} USDT
• 盈亏比: {rr}:1 {'✅' if rr >= 2 else '⚠️' if rr >= 1.5 else '❌'}
• 盈利额: +{profit:.2f} USDT {'✅' if profit >= 10 else '❌ <10U保底'}
• 手续费: {fee:.2f} USDT ({fee_pct:.1f}%) {'✅' if fee_pct < 5 else '❌'}
• 净盈利: {net:.2f} USDT {'✅' if net >= 10 else '❌'}
• 评级: {rating_emoji} {rating_text}
🎯 跟单方案(基于你的账户数据)
• 入场: ${rec['price']}(市价)
• 止损: ${rec['sl_price']}-{rec['sl_pct']:.1f}%-{rec['sl_pnl']:.2f} USDT
• 止盈: ${rec['tp_price']}+{rec['tp_pct']:.1f}%+{rec['tp_pnl']:.2f} USDT
• 仓位: {rec['contracts']}张(保证金{rec['margin']:.2f} USDT
• 强平: ${rec.get('liq_price', '?')}
回复 Y 确认跟单 / N 取消"""
return msg
def main():
# Get input
if len(sys.argv) > 1:
text = ' '.join(sys.argv[1:])
else:
text = sys.stdin.read()
if not text.strip():
print("用法: python3 fix_recommendation.py '信号文本'")
return
# Extract fields
fields = extract_from_signal(text)
if not fields.get('symbol') or not fields.get('side'):
print("⚠️ 无法解析信号文本")
print(text)
return
# Run advisor
leverage = fields.get('leverage', '10')
rec = run_advisor(fields['symbol'], fields['side'], leverage)
# Rebuild message
result = rebuild_message(text, fields, rec)
print(result)
if __name__ == '__main__':
main()