#!/usr/bin/env python3 """ 格式化交易信号推送消息。 用法: python3 format_signal.py --symbol HYPE --side long --leverage 10 --trader "麻吉大哥" --trader-pos "3,900 HYPE" --trader-value "$275,703" --trader-entry 71.1826 --trader-pnl -1910 --signal-type A 输出: 完整的含📐性价比区块的推送消息(可直接push_to_qq.sh) """ import argparse import json import sys from pathlib import Path # Add parent to path sys.path.insert(0, str(Path(__file__).parent)) def main(): parser = argparse.ArgumentParser(description='格式化交易信号推送消息') parser.add_argument('--symbol', required=True, help='币种 (如 HYPE)') parser.add_argument('--side', required=True, help='方向 (long/short)') parser.add_argument('--leverage', type=int, default=10, help='杠杆') parser.add_argument('--trader', required=True, help='交易员名称') parser.add_argument('--trader-pos', required=True, help='交易员仓位 (如 "3,900 HYPE")') parser.add_argument('--trader-value', required=True, help='交易员仓位价值 (如 "$275,703")') parser.add_argument('--trader-entry', type=float, required=True, help='交易员入场价') parser.add_argument('--trader-pnl', type=float, default=0, help='交易员浮盈(负=浮亏)') parser.add_argument('--signal-type', default='A', help='信号类型 (A加仓/B减仓/C新开仓)') parser.add_argument('--json', action='store_true', help='输出JSON而非格式化文本') args = parser.parse_args() # Import and run advisor from okx_position_advisor import load_credentials, create_exchange, get_account_info, recommend_position, format_recommendation creds = load_credentials() exchange = create_exchange(creds) acct_info = get_account_info(exchange) symbol = args.symbol if '/' not in symbol: symbol = f"{symbol}/USDT" try: rec = recommend_position(symbol, args.side, args.leverage, exchange, acct_info) except ZeroDivisionError: print(f"⚠️ 余额不足(可用0 USDT),无法开仓 {args.symbol}") sys.exit(0) except Exception as e: print(f"❌ 错误: {e}", file=sys.stderr) sys.exit(1) if 'error' in rec: print(f"❌ 错误: {rec['error']}", file=sys.stderr) sys.exit(1) # Handle zero balance gracefully if rec.get('contracts', 0) == 0: print(f"⚠️ 余额不足,无法开仓 {args.symbol}") sys.exit(0) # Format output side_cn = '做多' if args.side == 'long' else '做空' emoji = '🟩' if args.side == 'long' else '🟥' signal_label = {'A': 'A类加仓', 'B': 'B类减仓', 'C': 'C类新开仓'}.get(args.signal_type, args.signal_type) pnl_emoji = '🔥' if args.trader_pnl > 0 else '🔴' pnl_sign = '+' if args.trader_pnl > 0 else '' # Cost check from advisor 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', '未知') msg = f"""⚡ 跟单建议 | {args.symbol} {side_cn} {emoji} {args.leverage}x({signal_label}) 📊 {args.trader} {args.trader_pos}(价值{args.trader_value})← 信号源,非你的仓位 入场: ${args.trader_entry} | 当前: ${rec['price']} 浮盈: {pnl_sign}{args.trader_pnl:.0f} {pnl_emoji} | 强平距: ${rec.get('liq_price', '?')} 📐 性价比检查(基于你的推荐仓位) • 你的仓位: {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 取消""" if args.json: print(json.dumps({'message': msg, 'recommendation': rec}, ensure_ascii=False, indent=2)) else: print(msg) if __name__ == '__main__': main()