Files
Hermes-Skills/okx-auto-position/scripts/fix_recommendation.py
T
mike 657dc41c46 Initial commit: Trading skills collection
- OKX交易自动化 (okx-auto-position, okx-crypto, okx-exchange)
- 交易信号处理 (signal-confirmation-templates, trading-signal-aggregator)
- 量化因子挖掘 (quant-factor-mining)
- 长桥集成 (longbridge-cli, longbridge-python-sdk)
- 六合彩分析 (lottery-hk)
- 股息投资 (dividend-investing, dividend-scanner)
- 日内交易 (intraday-trading)
- 同花顺 (tonghuashun)
2026-07-05 02:39:41 -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()