多AI模型窝里斗交易系统


创建日期: 2025-11-06 15:31:47 最后修改: 2025-11-12 15:39:38
复制: 0 点击次数: 337
avatar of ianzeng123 ianzeng123
2
关注
327
关注者
策略源码
{"type":"n8n","content":"{\"workflowData\":{\"nodes\":[{\"parameters\":{\"notice\":\"\",\"rule\":{\"interval\":[{\"field\":\"minutes\",\"minutesInterval\":10}]}},\"type\":\"n8n-nodes-base.scheduleTrigger\",\"typeVersion\":1.2,\"position\":[-1824,1056],\"id\":\"e69bb228-4a53-4b4e-9c25-fd6dd5a6f78b\",\"name\":\"定时触发器\"},{\"parameters\":{\"model\":{\"__rl\":true,\"value\":\"anthropic/claude-sonnet-4.5\",\"mode\":\"list\",\"cachedResultName\":\"anthropic/claude-sonnet-4.5\"}},\"type\":\"n8n-nodes-base.lmOpenAi\",\"typeVersion\":1,\"position\":[-1152,1008],\"id\":\"350178d0-645f-427f-86c4-f1e6adc22635\",\"name\":\"Claude4.5\",\"credentials\":{\"openAiApi\":{\"id\":\"54d0b567-b3fc-4c6a-b6be-546e0b9cd83f\",\"name\":\"openrouter\"}}},{\"parameters\":{\"model\":{\"__rl\":true,\"value\":\"deepseek/deepseek-chat-v3.1\",\"mode\":\"list\",\"cachedResultName\":\"deepseek/deepseek-chat-v3.1\"}},\"type\":\"n8n-nodes-base.lmOpenAi\",\"typeVersion\":1,\"position\":[-1152,752],\"id\":\"7b70e6b3-3473-4316-8cdc-0ec26bd89fd6\",\"name\":\"DS3.1\",\"credentials\":{\"openAiApi\":{\"id\":\"54d0b567-b3fc-4c6a-b6be-546e0b9cd83f\",\"name\":\"openrouter\"}}},{\"parameters\":{\"text\":\"=你是一位专业的加密货币量化交易分析师。请基于以下多时间框架技术指标、当前持仓信息和竞争排名,提供交易决策建议。\\n\\n## 竞争状态\\n你是{{ $json.ranking.currentModel }}大模型,在{{ $json.ranking.totalModels }}个AI模型的交易竞赛中,你目前排名第{{ $json.ranking.currentRank }}位。\\n{{$json.ranking.currentPnl === 0 && $json.ranking.totalTrades === 0 ? '比赛刚开始!这是建立收益基础的好机会!起始阶段积极寻找优质交易机会!' : ''}}\\n\\n### 当前表现\\n- 你的已实现盈亏: {{ $json.ranking.currentPnl }} USDT {{ $json.ranking.currentPnl === 0 ? '(起始状态)' : '' }}\\n- 你的总资产价值: {{ $json.ranking.currentTotalValue }} USDT\\n- 总交易次数: {{ $json.ranking.totalTrades }} {{ $json.ranking.totalTrades === 0 ? '(尚未开始交易)' : '' }}\\n- 胜率: {{ $json.ranking.winRate }}%{{ $json.ranking.totalTrades === 0 ? ' (暂无数据)' : '' }}\\n\\n### 竞争对手排名\\n{{ $json.ranking.rankingText }}\\n{{ $json.ranking.currentPnl === 0 && $json.ranking.totalTrades === 0 ? '比赛开始!!!' : $json.ranking.gapInfo}}\\n\\n## 当前数据概览\\n- 交易对: {{ $json.symbol }}\\n- 分析时间: {{ new Date($json.timestamp).toLocaleString() }}\\n- 当前持仓: {{ $json.position && $json.position.length > 0 ? '有持仓' : '无持仓' }}\\n\\n## 技术指标数据(OLDEST-NEWEST)\\n### 日线级别 (趋势判断)\\n- 价格: {{ $json.timeframes.day?.lastPrice || 'N/A' }}\\n- RSI(14): {{ $json.timeframes.day?.RSI || 'N/A' }} \\n- MACD柱: {{ $json.timeframes.day?.MACD.histogram || 'N/A' }} \\n- ATR: {{ $json.timeframes.day?.ATR || 'N/A' }} \\n- OBV: {{ $json.timeframes.day?.OBV || 'N/A' }} \\n\\n### 小时线级别 (中期趋势)\\n- 价格: {{ $json.timeframes.hour?.lastPrice || 'N/A' }}\\n- RSI(14): {{ $json.timeframes.hour?.RSI || 'N/A' }}\\n- MACD柱: {{ $json.timeframes.hour?.MACD.histogram || 'N/A' }}\\n- ATR: {{ $json.timeframes.hour?.ATR || 'N/A' }}\\n- OBV: {{ $json.timeframes.hour?.OBV || 'N/A' }}\\n\\n### 5分钟线级别 (入场时机)\\n- 价格: {{ $json.timeframes.min5?.lastPrice || 'N/A' }}\\n- RSI(14): {{ $json.timeframes.min5?.RSI || 'N/A' }}\\n- MACD柱: {{ $json.timeframes.min5?.MACD.histogram || 'N/A' }}\\n- ATR: {{ $json.timeframes.min5?.ATR || 'N/A' }}\\n- OBV: {{ $json.timeframes.min5?.OBV || 'N/A' }}\\n\\n### 当前持仓信息\\n{{JSON.stringify($json.position, null, 2)}}\\n\\n## 分析要求\\n基于技术指标和你的竞争排名情况,制定最优交易策略。你的目标是持续创造更多收益,而非单纯保持排名。{{ $json.ranking.totalTrades === 0 ? '作为比赛开始阶段,积极寻找高质量交易机会来建立收益基础.' : '继续寻找优质交易机会来扩大收益,避免因过度保守而错失盈利机会.' }}\\n\\n### 策略建议:\\n{{ $json.ranking.totalTrades === 0 ? '- 比赛刚开始,积极寻找最佳入场时机建立收益基础' : $json.ranking.currentRank > 1 ? '- 你目前落后,积极寻找更多优质交易机会来追赶并创造收益' : '- 你目前表现良好,继续保持积极交易来扩大收益优势' }}\\n- 仔细分析多时间框架指标的一致性\\n- 在技术信号明确时果断执行交易\\n- {{ $json.ranking.totalTrades === 0 ? '首次交易要建立良好开局' : '持续寻找盈利机会,避免过度保守' }}\\n- 重点关注风险回报比,而非排名保护\\n\\n### 可执行的动作:\\n- **OPEN_LONG**: 开多单(无持仓的状态下)\\n- **OPEN_SHORT**: 开空单(无持仓的状态下)  \\n- **CLOSE_LONG**: 平多单(持有多仓的状态下)\\n- **CLOSE_SHORT**: 平空单(持有空仓的状态下)\\n- **NO_ACTION**: 观望(当技术信号不明确时)\\n\\n### 执行标准:\\n- 优先考虑收益创造机会\\n- {{ $json.ranking.totalTrades === 0 ? '首次交易要求建立收益基础' : '持续寻找高质量交易机会来扩大总收益' }}\\n- 风险控制与收益追求并重\\n- 只有在技术信号明显冲突时才选择NO_ACTION\\n\\n## 返回格式\\n```json\\n{\\n  \\\"action\\\": \\\"OPEN_LONG | OPEN_SHORT | CLOSE_LONG | CLOSE_SHORT | NO_ACTION\\\",\\n  \\\"reasoning\\\": \\\"结合技术指标和收益创造目标的极其简洁决策依据\\\",\\n  \\\"modelname\\\": \\\"{{ $json.ranking.currentModel }}\\\"\\n}\\n```\\n请直接给出判断结果。\",\"options\":{}},\"type\":\"@n8n/n8n-nodes-langchain.agent\",\"typeVersion\":1,\"position\":[-1152,592],\"id\":\"63b30c5e-df14-4a0a-ac58-17ce39cceef8\",\"name\":\"DeepSeek\",\"retryOnFail\":true,\"onError\":\"continueRegularOutput\"},{\"parameters\":{\"text\":\"=你是一位专业的加密货币量化交易分析师。请基于以下多时间框架技术指标、当前持仓信息和竞争排名,提供交易决策建议。\\n\\n## 竞争状态\\n你是{{ $json.ranking.currentModel }}大模型,在{{ $json.ranking.totalModels }}个AI模型的交易竞赛中,你目前排名第{{ $json.ranking.currentRank }}位。\\n{{$json.ranking.currentPnl === 0 && $json.ranking.totalTrades === 0 ? '比赛刚开始!这是建立收益基础的好机会!起始阶段积极寻找优质交易机会!' : ''}}\\n\\n### 当前表现\\n- 你的已实现盈亏: {{ $json.ranking.currentPnl }} USDT {{ $json.ranking.currentPnl === 0 ? '(起始状态)' : '' }}\\n- 你的总资产价值: {{ $json.ranking.currentTotalValue }} USDT\\n- 总交易次数: {{ $json.ranking.totalTrades }} {{ $json.ranking.totalTrades === 0 ? '(尚未开始交易)' : '' }}\\n- 胜率: {{ $json.ranking.winRate }}%{{ $json.ranking.totalTrades === 0 ? ' (暂无数据)' : '' }}\\n\\n### 竞争对手排名\\n{{ $json.ranking.rankingText }}\\n{{ $json.ranking.currentPnl === 0 && $json.ranking.totalTrades === 0 ? '比赛开始!!!' : $json.ranking.gapInfo}}\\n\\n## 当前数据概览\\n- 交易对: {{ $json.symbol }}\\n- 分析时间: {{ new Date($json.timestamp).toLocaleString() }}\\n- 当前持仓: {{ $json.position && $json.position.length > 0 ? '有持仓' : '无持仓' }}\\n\\n## 技术指标数据(OLDEST-NEWEST)\\n### 日线级别 (趋势判断)\\n- 价格: {{ $json.timeframes.day?.lastPrice || 'N/A' }}\\n- RSI(14): {{ $json.timeframes.day?.RSI || 'N/A' }} \\n- MACD柱: {{ $json.timeframes.day?.MACD.histogram || 'N/A' }} \\n- ATR: {{ $json.timeframes.day?.ATR || 'N/A' }} \\n- OBV: {{ $json.timeframes.day?.OBV || 'N/A' }} \\n\\n### 小时线级别 (中期趋势)\\n- 价格: {{ $json.timeframes.hour?.lastPrice || 'N/A' }}\\n- RSI(14): {{ $json.timeframes.hour?.RSI || 'N/A' }}\\n- MACD柱: {{ $json.timeframes.hour?.MACD.histogram || 'N/A' }}\\n- ATR: {{ $json.timeframes.hour?.ATR || 'N/A' }}\\n- OBV: {{ $json.timeframes.hour?.OBV || 'N/A' }}\\n\\n### 5分钟线级别 (入场时机)\\n- 价格: {{ $json.timeframes.min5?.lastPrice || 'N/A' }}\\n- RSI(14): {{ $json.timeframes.min5?.RSI || 'N/A' }}\\n- MACD柱: {{ $json.timeframes.min5?.MACD.histogram || 'N/A' }}\\n- ATR: {{ $json.timeframes.min5?.ATR || 'N/A' }}\\n- OBV: {{ $json.timeframes.min5?.OBV || 'N/A' }}\\n\\n### 当前持仓信息\\n{{JSON.stringify($json.position, null, 2)}}\\n\\n## 分析要求\\n基于技术指标和你的竞争排名情况,制定最优交易策略。你的目标是持续创造更多收益,而非单纯保持排名。{{ $json.ranking.totalTrades === 0 ? '作为比赛开始阶段,积极寻找高质量交易机会来建立收益基础.' : '继续寻找优质交易机会来扩大收益,避免因过度保守而错失盈利机会.' }}\\n\\n### 策略建议:\\n{{ $json.ranking.totalTrades === 0 ? '- 比赛刚开始,积极寻找最佳入场时机建立收益基础' : $json.ranking.currentRank > 1 ? '- 你目前落后,积极寻找更多优质交易机会来追赶并创造收益' : '- 你目前表现良好,继续保持积极交易来扩大收益优势' }}\\n- 仔细分析多时间框架指标的一致性\\n- 在技术信号明确时果断执行交易\\n- {{ $json.ranking.totalTrades === 0 ? '首次交易要建立良好开局' : '持续寻找盈利机会,避免过度保守' }}\\n- 重点关注风险回报比,而非排名保护\\n\\n### 可执行的动作:\\n- **OPEN_LONG**: 开多单(无持仓的状态下)\\n- **OPEN_SHORT**: 开空单(无持仓的状态下)  \\n- **CLOSE_LONG**: 平多单(持有多仓的状态下)\\n- **CLOSE_SHORT**: 平空单(持有空仓的状态下)\\n- **NO_ACTION**: 观望(当技术信号不明确时)\\n\\n### 执行标准:\\n- 优先考虑收益创造机会\\n- {{ $json.ranking.totalTrades === 0 ? '首次交易要求建立收益基础' : '持续寻找高质量交易机会来扩大总收益' }}\\n- 风险控制与收益追求并重\\n- 只有在技术信号明显冲突时才选择NO_ACTION\\n\\n## 返回格式\\n```json\\n{\\n  \\\"action\\\": \\\"OPEN_LONG | OPEN_SHORT | CLOSE_LONG | CLOSE_SHORT | NO_ACTION\\\",\\n  \\\"reasoning\\\": \\\"结合技术指标和收益创造目标的极其简洁决策依据\\\",\\n  \\\"modelname\\\": \\\"{{ $json.ranking.currentModel }}\\\"\\n}\\n```\\n请直接给出判断结果。\",\"options\":{}},\"type\":\"@n8n/n8n-nodes-langchain.agent\",\"typeVersion\":1,\"position\":[-1152,864],\"id\":\"477e56cb-fc70-44a1-8488-ff917bd82bec\",\"name\":\"Claude\",\"retryOnFail\":true,\"onError\":\"continueRegularOutput\"},{\"parameters\":{\"text\":\"=你是一位专业的加密货币量化交易分析师。请基于以下多时间框架技术指标、当前持仓信息和竞争排名,提供交易决策建议。\\n\\n## 竞争状态\\n你是{{ $json.ranking.currentModel }}大模型,在{{ $json.ranking.totalModels }}个AI模型的交易竞赛中,你目前排名第{{ $json.ranking.currentRank }}位。\\n{{$json.ranking.currentPnl === 0 && $json.ranking.totalTrades === 0 ? '比赛刚开始!这是建立收益基础的好机会!起始阶段积极寻找优质交易机会!' : ''}}\\n\\n### 当前表现\\n- 你的已实现盈亏: {{ $json.ranking.currentPnl }} USDT {{ $json.ranking.currentPnl === 0 ? '(起始状态)' : '' }}\\n- 你的总资产价值: {{ $json.ranking.currentTotalValue }} USDT\\n- 总交易次数: {{ $json.ranking.totalTrades }} {{ $json.ranking.totalTrades === 0 ? '(尚未开始交易)' : '' }}\\n- 胜率: {{ $json.ranking.winRate }}%{{ $json.ranking.totalTrades === 0 ? ' (暂无数据)' : '' }}\\n\\n### 竞争对手排名\\n{{ $json.ranking.rankingText }}\\n{{ $json.ranking.currentPnl === 0 && $json.ranking.totalTrades === 0 ? '比赛开始!!!' : $json.ranking.gapInfo}}\\n\\n## 当前数据概览\\n- 交易对: {{ $json.symbol }}\\n- 分析时间: {{ new Date($json.timestamp).toLocaleString() }}\\n- 当前持仓: {{ $json.position && $json.position.length > 0 ? '有持仓' : '无持仓' }}\\n\\n## 技术指标数据(OLDEST-NEWEST)\\n### 日线级别 (趋势判断)\\n- 价格: {{ $json.timeframes.day?.lastPrice || 'N/A' }}\\n- RSI(14): {{ $json.timeframes.day?.RSI || 'N/A' }} \\n- MACD柱: {{ $json.timeframes.day?.MACD.histogram || 'N/A' }} \\n- ATR: {{ $json.timeframes.day?.ATR || 'N/A' }} \\n- OBV: {{ $json.timeframes.day?.OBV || 'N/A' }} \\n\\n### 小时线级别 (中期趋势)\\n- 价格: {{ $json.timeframes.hour?.lastPrice || 'N/A' }}\\n- RSI(14): {{ $json.timeframes.hour?.RSI || 'N/A' }}\\n- MACD柱: {{ $json.timeframes.hour?.MACD.histogram || 'N/A' }}\\n- ATR: {{ $json.timeframes.hour?.ATR || 'N/A' }}\\n- OBV: {{ $json.timeframes.hour?.OBV || 'N/A' }}\\n\\n### 5分钟线级别 (入场时机)\\n- 价格: {{ $json.timeframes.min5?.lastPrice || 'N/A' }}\\n- RSI(14): {{ $json.timeframes.min5?.RSI || 'N/A' }}\\n- MACD柱: {{ $json.timeframes.min5?.MACD.histogram || 'N/A' }}\\n- ATR: {{ $json.timeframes.min5?.ATR || 'N/A' }}\\n- OBV: {{ $json.timeframes.min5?.OBV || 'N/A' }}\\n\\n### 当前持仓信息\\n{{JSON.stringify($json.position, null, 2)}}\\n\\n## 分析要求\\n基于技术指标和你的竞争排名情况,制定最优交易策略。你的目标是持续创造更多收益,而非单纯保持排名。{{ $json.ranking.totalTrades === 0 ? '作为比赛开始阶段,积极寻找高质量交易机会来建立收益基础.' : '继续寻找优质交易机会来扩大收益,避免因过度保守而错失盈利机会.' }}\\n\\n### 策略建议:\\n{{ $json.ranking.totalTrades === 0 ? '- 比赛刚开始,积极寻找最佳入场时机建立收益基础' : $json.ranking.currentRank > 1 ? '- 你目前落后,积极寻找更多优质交易机会来追赶并创造收益' : '- 你目前表现良好,继续保持积极交易来扩大收益优势' }}\\n- 仔细分析多时间框架指标的一致性\\n- 在技术信号明确时果断执行交易\\n- {{ $json.ranking.totalTrades === 0 ? '首次交易要建立良好开局' : '持续寻找盈利机会,避免过度保守' }}\\n- 重点关注风险回报比,而非排名保护\\n\\n### 可执行的动作:\\n- **OPEN_LONG**: 开多单(无持仓的状态下)\\n- **OPEN_SHORT**: 开空单(无持仓的状态下)  \\n- **CLOSE_LONG**: 平多单(持有多仓的状态下)\\n- **CLOSE_SHORT**: 平空单(持有空仓的状态下)\\n- **NO_ACTION**: 观望(当技术信号不明确时)\\n\\n### 执行标准:\\n- 优先考虑收益创造机会\\n- {{ $json.ranking.totalTrades === 0 ? '首次交易要求建立收益基础' : '持续寻找高质量交易机会来扩大总收益' }}\\n- 风险控制与收益追求并重\\n- 只有在技术信号明显冲突时才选择NO_ACTION\\n\\n## 返回格式\\n```json\\n{\\n  \\\"action\\\": \\\"OPEN_LONG | OPEN_SHORT | CLOSE_LONG | CLOSE_SHORT | NO_ACTION\\\",\\n  \\\"reasoning\\\": \\\"结合技术指标和收益创造目标的极其简洁决策依据\\\",\\n  \\\"modelname\\\": \\\"{{ $json.ranking.currentModel }}\\\"\\n}\\n```\\n请直接给出判断结果。\",\"options\":{}},\"type\":\"@n8n/n8n-nodes-langchain.agent\",\"typeVersion\":1,\"position\":[-1152,1152],\"id\":\"58e65b3e-2230-4b3c-820b-4aad2aea7f85\",\"name\":\"QWEN\",\"retryOnFail\":true,\"onError\":\"continueRegularOutput\"},{\"parameters\":{\"model\":{\"__rl\":true,\"value\":\"qwen/qwen3-max\",\"mode\":\"list\",\"cachedResultName\":\"qwen/qwen3-max\"}},\"type\":\"n8n-nodes-base.lmOpenAi\",\"typeVersion\":1,\"position\":[-1152,1296],\"id\":\"50e76e0f-8f71-4cb8-9aeb-f0d0b38f9587\",\"name\":\"OpenAI 模型\",\"credentials\":{\"openAiApi\":{\"id\":\"54d0b567-b3fc-4c6a-b6be-546e0b9cd83f\",\"name\":\"openrouter\"}}},{\"parameters\":{\"text\":\"=你是一位专业的加密货币量化交易分析师。请基于以下多时间框架技术指标、当前持仓信息和竞争排名,提供交易决策建议。\\n\\n## 竞争状态\\n你是{{ $json.ranking.currentModel }}大模型,在{{ $json.ranking.totalModels }}个AI模型的交易竞赛中,你目前排名第{{ $json.ranking.currentRank }}位。\\n{{$json.ranking.currentPnl === 0 && $json.ranking.totalTrades === 0 ? '比赛刚开始!这是建立收益基础的好机会!起始阶段积极寻找优质交易机会!' : ''}}\\n\\n### 当前表现\\n- 你的已实现盈亏: {{ $json.ranking.currentPnl }} USDT {{ $json.ranking.currentPnl === 0 ? '(起始状态)' : '' }}\\n- 你的总资产价值: {{ $json.ranking.currentTotalValue }} USDT\\n- 总交易次数: {{ $json.ranking.totalTrades }} {{ $json.ranking.totalTrades === 0 ? '(尚未开始交易)' : '' }}\\n- 胜率: {{ $json.ranking.winRate }}%{{ $json.ranking.totalTrades === 0 ? ' (暂无数据)' : '' }}\\n\\n### 竞争对手排名\\n{{ $json.ranking.rankingText }}\\n{{ $json.ranking.currentPnl === 0 && $json.ranking.totalTrades === 0 ? '比赛开始!!!' : $json.ranking.gapInfo}}\\n\\n## 当前数据概览\\n- 交易对: {{ $json.symbol }}\\n- 分析时间: {{ new Date($json.timestamp).toLocaleString() }}\\n- 当前持仓: {{ $json.position && $json.position.length > 0 ? '有持仓' : '无持仓' }}\\n\\n## 技术指标数据(OLDEST-NEWEST)\\n### 日线级别 (趋势判断)\\n- 价格: {{ $json.timeframes.day?.lastPrice || 'N/A' }}\\n- RSI(14): {{ $json.timeframes.day?.RSI || 'N/A' }} \\n- MACD柱: {{ $json.timeframes.day?.MACD.histogram || 'N/A' }} \\n- ATR: {{ $json.timeframes.day?.ATR || 'N/A' }} \\n- OBV: {{ $json.timeframes.day?.OBV || 'N/A' }} \\n\\n### 小时线级别 (中期趋势)\\n- 价格: {{ $json.timeframes.hour?.lastPrice || 'N/A' }}\\n- RSI(14): {{ $json.timeframes.hour?.RSI || 'N/A' }}\\n- MACD柱: {{ $json.timeframes.hour?.MACD.histogram || 'N/A' }}\\n- ATR: {{ $json.timeframes.hour?.ATR || 'N/A' }}\\n- OBV: {{ $json.timeframes.hour?.OBV || 'N/A' }}\\n\\n### 5分钟线级别 (入场时机)\\n- 价格: {{ $json.timeframes.min5?.lastPrice || 'N/A' }}\\n- RSI(14): {{ $json.timeframes.min5?.RSI || 'N/A' }}\\n- MACD柱: {{ $json.timeframes.min5?.MACD.histogram || 'N/A' }}\\n- ATR: {{ $json.timeframes.min5?.ATR || 'N/A' }}\\n- OBV: {{ $json.timeframes.min5?.OBV || 'N/A' }}\\n\\n### 当前持仓信息\\n{{JSON.stringify($json.position, null, 2)}}\\n\\n## 分析要求\\n基于技术指标和你的竞争排名情况,制定最优交易策略。你的目标是持续创造更多收益,而非单纯保持排名。{{ $json.ranking.totalTrades === 0 ? '作为比赛开始阶段,积极寻找高质量交易机会来建立收益基础.' : '继续寻找优质交易机会来扩大收益,避免因过度保守而错失盈利机会.' }}\\n\\n### 策略建议:\\n{{ $json.ranking.totalTrades === 0 ? '- 比赛刚开始,积极寻找最佳入场时机建立收益基础' : $json.ranking.currentRank > 1 ? '- 你目前落后,积极寻找更多优质交易机会来追赶并创造收益' : '- 你目前表现良好,继续保持积极交易来扩大收益优势' }}\\n- 仔细分析多时间框架指标的一致性\\n- 在技术信号明确时果断执行交易\\n- {{ $json.ranking.totalTrades === 0 ? '首次交易要建立良好开局' : '持续寻找盈利机会,避免过度保守' }}\\n- 重点关注风险回报比,而非排名保护\\n\\n### 可执行的动作:\\n- **OPEN_LONG**: 开多单(无持仓的状态下)\\n- **OPEN_SHORT**: 开空单(无持仓的状态下)  \\n- **CLOSE_LONG**: 平多单(持有多仓的状态下)\\n- **CLOSE_SHORT**: 平空单(持有空仓的状态下)\\n- **NO_ACTION**: 观望(当技术信号不明确时)\\n\\n### 执行标准:\\n- 优先考虑收益创造机会\\n- {{ $json.ranking.totalTrades === 0 ? '首次交易要求建立收益基础' : '持续寻找高质量交易机会来扩大总收益' }}\\n- 风险控制与收益追求并重\\n- 只有在技术信号明显冲突时才选择NO_ACTION\\n\\n## 返回格式\\n```json\\n{\\n  \\\"action\\\": \\\"OPEN_LONG | OPEN_SHORT | CLOSE_LONG | CLOSE_SHORT | NO_ACTION\\\",\\n  \\\"reasoning\\\": \\\"结合技术指标和收益创造目标的极其简洁决策依据\\\",\\n  \\\"modelname\\\": \\\"{{ $json.ranking.currentModel }}\\\"\\n}\\n```\\n请直接给出判断结果。\",\"options\":{}},\"type\":\"@n8n/n8n-nodes-langchain.agent\",\"typeVersion\":1,\"position\":[-1152,1424],\"id\":\"1cc9371f-8390-47cd-a79e-beb030c10781\",\"name\":\"Grok\",\"retryOnFail\":true,\"onError\":\"continueRegularOutput\"},{\"parameters\":{\"model\":{\"__rl\":true,\"value\":\"x-ai/grok-4\",\"mode\":\"list\",\"cachedResultName\":\"x-ai/grok-4\"}},\"type\":\"n8n-nodes-base.lmOpenAi\",\"typeVersion\":1,\"position\":[-1152,1584],\"id\":\"31929d64-519e-4635-b321-c95f917429c2\",\"name\":\"Grok4\",\"credentials\":{\"openAiApi\":{\"id\":\"54d0b567-b3fc-4c6a-b6be-546e0b9cd83f\",\"name\":\"openrouter\"}}},{\"parameters\":{\"mode\":\"append\",\"numberInputs\":4},\"type\":\"n8n-nodes-base.merge\",\"typeVersion\":3.2,\"position\":[-752,1024],\"id\":\"b24faeb3-319a-49bc-a130-fb150f2ec64b\",\"name\":\"合并\"},{\"parameters\":{\"operation\":\"csv\",\"binaryPropertyName\":\"data\",\"options\":{}},\"type\":\"n8n-nodes-base.convertToFile\",\"typeVersion\":1.1,\"position\":[-80,1152],\"id\":\"f0c9ec35-299b-4244-897d-5dbe10a9768c\",\"name\":\"转换为文件\"},{\"parameters\":{\"info\":\"\",\"fileName\":\"tradelog.csv\",\"dataPropertyName\":\"data\",\"options\":{}},\"type\":\"n8n-nodes-base.writeFile\",\"typeVersion\":1,\"position\":[144,1152],\"id\":\"b871fce4-554f-46df-bfbd-7e67bee688fd\",\"name\":\"写入文件到磁盘\"},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"// 获取AI决策结果并清洗数据\\nconst aiResults = $input.all().map(item => {\\n    if (item.json && item.json.output) {\\n        return { output: item.json.output };\\n    } else if (item.output) {\\n        return { output: item.output };\\n    }\\n    return null;\\n}).filter(item => item !== null);\\n\\nexchange.SetContractType('swap') \\nconst ticker = _C(exchange.GetTicker);\\nconst fixedSize = $vars.size || 0.01; // 固定交易数量\\n\\nif (!ticker || !ticker.Last) {\\n    Log(\\\"获取价格失败\\\");\\n    return $input.all();\\n}\\n\\nconst currentPrice = ticker.Last;\\nconst timestamp = Date.now();\\n\\n// 获取合约价值\\nconst markets = _G('markets');\\nconst ctVal = markets ? markets.CtVal : 1;\\n\\n// 获取模型数据 - 使用深拷贝避免修改原始数据\\nconst models = JSON.parse(JSON.stringify($node['策略初始化'].json));\\n\\n// 处理每个AI的决策\\naiResults.forEach(item => {\\n    Log('当前item:', item)\\n    if (!item.output){\\n      return;\\n    }\\n    \\n    try {\\n        let decision;\\n        \\n        // 尝试提取markdown包裹的JSON\\n        const jsonMatch = item.output.match(/```json\\\\s*([\\\\s\\\\S]*?)\\\\s*```/);\\n        \\n        if (jsonMatch) {\\n            // Claude格式:```json ... ```\\n            decision = JSON.parse(jsonMatch[1]);\\n        } else {\\n            // DS格式:直接就是JSON\\n            decision = JSON.parse(item.output);\\n        }\\n        \\n        const modelKey = decision.modelname;\\n\\n        if (!models || !models[modelKey]) {\\n            Log(`未找到模型: ${modelKey}`);\\n            return;\\n        }\\n        \\n        const model = models[modelKey];\\n        \\n        // 记录决策\\n        model.decisions.push({\\n            timestamp,\\n            action: decision.action,\\n            reasoning: decision.reasoning,\\n            price: currentPrice\\n        });\\n        \\n        // ============ 虚拟持仓交易逻辑 ============\\n        \\n        if (decision.action === 'OPEN_LONG') {\\n            // 检查是否已有持仓(虚拟持仓)\\n            if (model.positions.length === 0) {\\n                model.positions.push({\\n                    side: 'long',\\n                    size: fixedSize,\\n                    entryPrice: currentPrice,\\n                    ctVal: ctVal,\\n                    timestamp: timestamp\\n                });\\n                \\n                model.account.totalTrades++;\\n                \\n                model.tradeHistory.push({\\n                    action: 'OPEN_LONG',\\n                    price: currentPrice,\\n                    size: fixedSize,\\n                    ctVal: ctVal,\\n                    timestamp: timestamp\\n                });\\n                \\n                Log(`${modelKey} 虚拟开多: ${currentPrice}, 数量: ${fixedSize}`);\\n            }\\n        }\\n        \\n        else if (decision.action === 'OPEN_SHORT') {\\n            // 检查是否已有持仓(虚拟持仓)\\n            if (model.positions.length === 0) {\\n                model.positions.push({\\n                    side: 'short',\\n                    size: fixedSize,\\n                    entryPrice: currentPrice,\\n                    ctVal: ctVal,\\n                    timestamp: timestamp\\n                });\\n                \\n                model.account.totalTrades++;\\n                \\n                model.tradeHistory.push({\\n                    action: 'OPEN_SHORT',\\n                    price: currentPrice,\\n                    size: fixedSize,\\n                    ctVal: ctVal,\\n                    timestamp: timestamp\\n                });\\n                \\n                Log(`${modelKey} 虚拟开空: ${currentPrice}, 数量: ${fixedSize}`);\\n            }\\n        }\\n        \\n        else if (decision.action === 'CLOSE_LONG' || decision.action === 'CLOSE_SHORT') {\\n            // 平仓(虚拟持仓)\\n            const targetSide = decision.action === 'CLOSE_LONG' ? 'long' : 'short';\\n            const posIndex = model.positions.findIndex(pos => pos.side === targetSide);\\n            \\n            if (posIndex !== -1) {\\n                const position = model.positions[posIndex];\\n                \\n                // ✅ 修复:计算绝对盈亏(不除以entryPrice)\\n                const pnl = position.side === 'long' \\n                    ? (currentPrice - position.entryPrice) * position.size * position.ctVal\\n                    : (position.entryPrice - currentPrice) * position.size * position.ctVal;\\n                \\n                // 开仓和平仓手续费\\n                const openFee = position.size * position.ctVal * 0.001;\\n                const closeFee = position.size * position.ctVal * 0.001;\\n                const totalFee = openFee + closeFee;\\n                \\n                const netPnl = pnl - totalFee;\\n                \\n                // 累计到总盈亏\\n                model.account.realizedPnl += netPnl;\\n                \\n                if (netPnl > 0) model.account.winTrades++;\\n                \\n                model.tradeHistory.push({\\n                    action: decision.action,\\n                    price: currentPrice,\\n                    size: position.size,\\n                    ctVal: position.ctVal,\\n                    entryPrice: position.entryPrice,\\n                    pnl: netPnl,\\n                    fee: totalFee,\\n                    timestamp: timestamp\\n                });\\n                \\n                Log(`${modelKey} 虚拟平仓: ${currentPrice}, 盈亏: ${netPnl.toFixed(2)}`);\\n                \\n                // 移除虚拟持仓\\n                model.positions.splice(posIndex, 1);\\n            }\\n        }\\n        \\n        // ✅ 修复:计算未实现盈亏(不除以entryPrice)\\n        let unrealizedPnl = 0;\\n        model.positions.forEach(pos => {\\n            if (pos.side === 'long') {\\n                unrealizedPnl += (currentPrice - pos.entryPrice) * pos.size * pos.ctVal;\\n            } else {\\n                unrealizedPnl += (pos.entryPrice - currentPrice) * pos.size * pos.ctVal;\\n            }\\n        });\\n        \\n        model.account.totalValue = model.account.initialBalance + model.account.realizedPnl + unrealizedPnl;\\n        model.account.balance = model.account.totalValue;\\n        \\n    } catch (error) {\\n        Log(`处理决策时出错: ${error.message}`);\\n        Log(`原始输出: ${item.output}`);\\n    }\\n});\\n\\n// 保存更新后的models到_G\\n_G('models', models);\\n\\nreturn models;\\n\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[-528,1056],\"id\":\"a94826bd-46be-4cdc-aff9-e8c71e40d680\",\"name\":\"结果核算\"},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"// 提取并格式化所有模型的交易数据\\nconst inputData = $input.all()[0].json;\\n\\n// ✅ 自动从数据中获取模型列表\\nconst models = Object.keys(inputData);\\n\\n// 构建结果数组\\nconst results = models.map(model => {\\n  const data = inputData[model];\\n  \\n  // ✅ 安全检查\\n  if (!data || !data.account) {\\n    Log(`警告: 模型 ${model} 数据不完整,跳过`);\\n    return null;\\n  }\\n  \\n  // 获取最新决策\\n  const latestDecision = data.decisions && data.decisions.length > 0 \\n    ? data.decisions[data.decisions.length - 1] \\n    : null;\\n  \\n  // 获取当前持仓\\n  const currentPosition = data.positions && data.positions.length > 0\\n    ? data.positions[0]\\n    : null;\\n  \\n  return {\\n    // 模型名称\\n    model: model,\\n    \\n    // 账户信息\\n    initialBalance: data.account.initialBalance,\\n    balance: data.account.balance,\\n    totalValue: data.account.totalValue,\\n    realizedPnl: data.account.realizedPnl,\\n    totalTrades: data.account.totalTrades,\\n    winTrades: data.account.winTrades,\\n    winRate: data.account.totalTrades > 0 \\n      ? ((data.account.winTrades / data.account.totalTrades) * 100).toFixed(2) + '%'\\n      : '0%',\\n    \\n    // 持仓信息\\n    hasPosition: currentPosition ? 'YES' : 'NO',\\n    positionType: currentPosition?.type || '-',\\n    positionSize: currentPosition?.size || 0,\\n    entryPrice: currentPosition?.entryPrice || 0,\\n    currentPrice: currentPosition?.currentPrice || 0,\\n    unrealizedPnl: currentPosition?.unrealizedPnl || 0,\\n    \\n    // 最新决策\\n    latestAction: latestDecision?.action || 'NO_DECISION',\\n    latestPrice: latestDecision?.price || 0,\\n    latestTimestamp: latestDecision?.timestamp || 0,\\n    latestReasoning: latestDecision?.reasoning || '-',\\n    \\n    // 交易历史统计\\n    tradeHistoryCount: data.tradeHistory.length,\\n    decisionsCount: data.decisions.length,\\n    \\n    // 添加时间戳\\n    recordTime: new Date().toISOString()\\n  };\\n}).filter(item => item !== null); // ✅ 过滤无效数据\\n\\nlet tradelog = _G('tradelog') || [];\\n\\n// 添加当前所有模型的记录\\ntradelog.push({\\n  timestamp: new Date().toISOString(),\\n  models: results\\n});\\n\\n_G('tradelog', tradelog);\\n\\n// 返回数据用于下一个节点\\nreturn tradelog;\\n\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[-304,1056],\"id\":\"a6280d67-b499-4a9b-9a9b-cd15397f7f4a\",\"name\":\"交易记录保存\"},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"// 获取所有模型数据\\nconst inputData = $node['结果核算'].json;\\n\\n// 获取当前真实交易使用的模型(如果有)\\nlet activeModel = _G('activeModel') || null;\\nlet highestPnl = _G('highestPnl') || 15; // 初始阈值\\n\\nLog('highestPnl:', highestPnl)\\n\\n// 遍历所有模型,找出最优模型\\nlet bestModel = null;\\nlet bestPnl = highestPnl;\\n\\nObject.keys(inputData).forEach(modelName => {\\n    const model = inputData[modelName];\\n    const realizedPnl = model.account.realizedPnl;\\n    \\n    // 找出盈亏最高的模型\\n    if (realizedPnl > bestPnl) {\\n        bestPnl = realizedPnl;\\n        bestModel = modelName;\\n    }\\n});\\n\\n// 决策逻辑\\nlet shouldTrade = false;\\nlet tradeAction = null;\\nlet modelChanged = false;\\n\\nif (bestModel) {\\n    // 如果没有激活模型,且找到盈利的模型\\n    if (!activeModel) {\\n        activeModel = bestModel;\\n        highestPnl = bestPnl;\\n        modelChanged = true;\\n        Log(`🎯 启动真实交易!选择模型: ${activeModel}, 盈亏: ${bestPnl.toFixed(2)} USDT`);\\n    } \\n    // 如果当前模型不是最优模型,切换到最优模型\\n    else if (bestModel !== activeModel) {\\n        Log(`🔄 模型切换: ${activeModel} (${highestPnl.toFixed(2)}) -> ${bestModel} (${bestPnl.toFixed(2)})`);\\n        activeModel = bestModel;\\n        highestPnl = bestPnl;\\n        modelChanged = true;\\n    }\\n    \\n    // 获取激活模型的纸面持仓状态\\n    const activeModelData = inputData[activeModel];\\n    const paperPositions = activeModelData.positions || [];\\n    \\n    // 获取真实持仓状态\\n    const realPositions = exchange.GetPosition();\\n    const hasRealLong = realPositions && realPositions.some(p => p.Type === PD_LONG && p.Amount > 0);\\n    const hasRealShort = realPositions && realPositions.some(p => p.Type === PD_SHORT && p.Amount > 0);\\n    \\n    // 纸面持仓状态\\n    const hasPaperLong = paperPositions.some(p => p.side === 'long');\\n    const hasPaperShort = paperPositions.some(p => p.side === 'short');\\n    \\n    // 同步逻辑:让真实持仓与纸面持仓一致\\n    if (hasPaperLong && !hasRealLong) {\\n        // 纸面有多单,真实没有多单\\n        if (hasRealShort) {\\n            // 如果真实有空单,先平空单\\n            shouldTrade = true;\\n            tradeAction = {\\n                model: activeModel,\\n                action: 'CLOSE_SHORT',\\n                reason: '同步持仓:先平空单',\\n                paperPosition: paperPositions[0],\\n                modelPnl: activeModelData.account.realizedPnl\\n            };\\n        } else {\\n            // 真实无持仓,开多单\\n            shouldTrade = true;\\n            tradeAction = {\\n                model: activeModel,\\n                action: 'OPEN_LONG',\\n                reason: '同步持仓:开多单',\\n                paperPosition: paperPositions[0],\\n                modelPnl: activeModelData.account.realizedPnl\\n            };\\n        }\\n    } \\n    else if (hasPaperShort && !hasRealShort) {\\n        // 纸面有空单,真实没有空单\\n        if (hasRealLong) {\\n            // 如果真实有多单,先平多单\\n            shouldTrade = true;\\n            tradeAction = {\\n                model: activeModel,\\n                action: 'CLOSE_LONG',\\n                reason: '同步持仓:先平多单',\\n                paperPosition: paperPositions[0],\\n                modelPnl: activeModelData.account.realizedPnl\\n            };\\n        } else {\\n            // 真实无持仓,开空单\\n            shouldTrade = true;\\n            tradeAction = {\\n                model: activeModel,\\n                action: 'OPEN_SHORT',\\n                reason: '同步持仓:开空单',\\n                paperPosition: paperPositions[0],\\n                modelPnl: activeModelData.account.realizedPnl\\n            };\\n        }\\n    }\\n    else if (!hasPaperLong && !hasPaperShort && (hasRealLong || hasRealShort)) {\\n        // 纸面无持仓,但真实有持仓,需要平仓\\n        if (hasRealLong) {\\n            shouldTrade = true;\\n            tradeAction = {\\n                model: activeModel,\\n                action: 'CLOSE_LONG',\\n                reason: '同步持仓:纸面已平仓',\\n                modelPnl: activeModelData.account.realizedPnl\\n            };\\n        } else if (hasRealShort) {\\n            shouldTrade = true;\\n            tradeAction = {\\n                model: activeModel,\\n                action: 'CLOSE_SHORT',\\n                reason: '同步持仓:纸面已平仓',\\n                modelPnl: activeModelData.account.realizedPnl\\n            };\\n        }\\n    }\\n}\\n\\n// 保存状态\\n_G('activeModel', activeModel);\\n_G('highestPnl', highestPnl);\\n\\n// 执行真实交易\\nif (shouldTrade && tradeAction) {\\n    const symbol = $vars.coin + \\\"_USDT.swap\\\";\\n    const size = $vars.size || 0.01;\\n    \\n    Log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);\\n    Log(`🤖 真实交易执行(同步纸面持仓)`);\\n    Log(`模型: ${tradeAction.model}`);\\n    Log(`动作: ${tradeAction.action}`);\\n    Log(`原因: ${tradeAction.reason}`);\\n    Log(`数量: ${size}`);\\n    Log(`模型盈亏: ${tradeAction.modelPnl.toFixed(2)} USDT`);\\n    if (tradeAction.paperPosition) {\\n        Log(`纸面持仓: ${tradeAction.paperPosition.side}, 入场价: ${tradeAction.paperPosition.entryPrice}`);\\n    }\\n    Log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);\\n    \\n    try {\\n        // 获取当前持仓\\n        const positions = exchange.GetPosition();\\n        const hasLongPosition = positions && positions.some(p => p.Type === PD_LONG && p.Amount > 0);\\n        const hasShortPosition = positions && positions.some(p => p.Type === PD_SHORT && p.Amount > 0);\\n        \\n        // 执行交易\\n        if (tradeAction.action === 'OPEN_LONG' && !hasLongPosition && !hasShortPosition) {\\n            exchange.SetDirection(\\\"buy\\\");\\n            const orderId = exchange.Buy(-1, size);\\n            Log(`✅ 开多单成功, 订单ID: ${orderId}`);\\n        } \\n        else if (tradeAction.action === 'OPEN_SHORT' && !hasLongPosition && !hasShortPosition) {\\n            exchange.SetDirection(\\\"sell\\\");\\n            const orderId = exchange.Sell(-1, size);\\n            Log(`✅ 开空单成功, 订单ID: ${orderId}`);\\n        }\\n        else if (tradeAction.action === 'CLOSE_LONG' && hasLongPosition) {\\n            const longPos = positions.find(p => p.Type === PD_LONG && p.Amount > 0);\\n            exchange.SetDirection(\\\"closebuy\\\");\\n            const orderId = exchange.Sell(-1, longPos.Amount);\\n            Log(`✅ 平多单成功, 订单ID: ${orderId}`);\\n        }\\n        else if (tradeAction.action === 'CLOSE_SHORT' && hasShortPosition) {\\n            const shortPos = positions.find(p => p.Type === PD_SHORT && p.Amount > 0);\\n            exchange.SetDirection(\\\"closesell\\\");\\n            const orderId = exchange.Buy(-1, shortPos.Amount);\\n            Log(`✅ 平空单成功, 订单ID: ${orderId}`);\\n        }\\n        else {\\n            Log(`⚠️ 无法执行交易: 持仓状态不匹配`);\\n        }\\n    } catch (error) {\\n        Log(`❌ 交易执行失败: ${error.message}`);\\n    }\\n}\\n\\n// 返回状态信息\\nreturn [{\\n    json: {\\n        activeModel: activeModel,\\n        highestPnl: highestPnl,\\n        shouldTrade: shouldTrade,\\n        modelChanged: modelChanged,\\n        tradeAction: tradeAction,\\n        allModelsStatus: Object.keys(inputData).map(modelName => {\\n            const model = inputData[modelName];\\n            return {\\n                model: modelName,\\n                realizedPnl: model.account.realizedPnl,\\n                totalValue: model.account.totalValue,\\n                isActive: modelName === activeModel,\\n                paperPosition: model.positions.length > 0 ? model.positions[0].side : 'none'\\n            };\\n        }).sort((a, b) => b.realizedPnl - a.realizedPnl)\\n    }\\n}];\\n\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[-80,960],\"id\":\"51e667f8-000e-40e2-bc38-8b885260cb94\",\"name\":\"最优交易\"},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"api_base = \\\"https://testnet.binancefuture.com\\\"\\nexchange.SetBase(api_base)\\n\\n\\n// 获取并分割模型列表\\nconst modelListStr = $vars.modelList || '';\\nconst modelList = modelListStr.split(',').filter(name => name.trim());\\n\\nif (modelList.length === 0) {\\n    return {};\\n}\\n\\n// 初始化全局容器\\nif (!_G('models')) {\\n    _G('models', {});\\n    _G('tradelog')\\n\\n    let allMarkets = null;\\n    for (let i = 0; i < 5; i++) {\\n        allMarkets = exchange.GetMarkets();\\n        if (allMarkets && Object.keys(allMarkets).length > 0) {\\n            break;\\n        }\\n        Sleep(1000);\\n    }\\n    \\n    const symbol = $vars.coin + '_USDT.swap';\\n    _G('markets', allMarkets[symbol]);\\n    Log(_G('markets'))\\n    \\n\\n    const initAccount = exchange.GetAccount();\\n    _G('initmoney', initAccount.Balance);\\n}\\n\\n// 为每个模型创建交易系统\\nmodelList.forEach(modelName => {\\n    const key = modelName.trim();\\n    const models = _G('models');\\n    \\n    if (!models[key]) {\\n        models[key] = {\\n            account: {\\n                initialBalance: 10000,  // 添加初始资金\\n                balance: 10000,\\n                totalValue: 10000,\\n                realizedPnl: 0,\\n                totalTrades: 0,\\n                winTrades: 0\\n            },\\n            positions: [],\\n            tradeHistory: [],\\n            decisions: []\\n        };\\n        _G('models', models);\\n    }\\n});\\n\\nreturn _G('models');\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[-1600,1056],\"id\":\"722030a0-2be6-438f-b8bc-2f6396045b79\",\"name\":\"策略初始化\"},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"// ========== AI模型竞赛可视化仪表板 ==========\\n\\n/**\\n * 安全格式化辅助函数\\n */\\nfunction safeFormat(value, decimals = 2, prefix = '') {\\n    if (value === null || value === undefined || isNaN(value)) {\\n        return prefix + '0';\\n    }\\n    return prefix + _N(value, decimals);\\n}\\n\\nfunction safePercentage(numerator, denominator, decimals = 1) {\\n    if (!denominator || denominator === 0) return '0%';\\n    const result = (numerator / denominator) * 100;\\n    return safeFormat(result, decimals) + '%';\\n}\\n\\n/**\\n * 表格1: 模型运行状态\\n */\\nfunction createModelStatusTable(allModelsStatus, models) {\\n    const statusTable = {\\n        type: \\\"table\\\",\\n        title: \\\"🤖 AI模型实时运行状态\\\",\\n        cols: [\\\"模型\\\", \\\"激活\\\", \\\"初始\\\", \\\"当前\\\", \\\"已实现\\\", \\\"盈利率\\\", \\\"纸面仓\\\", \\\"交易数\\\", \\\"胜率\\\", \\\"最新决策\\\", \\\"决策价格\\\", \\\"决策原因\\\"],\\n        rows: []\\n    };\\n    \\n    try {\\n        allModelsStatus.forEach(model => {\\n            const modelData = models[model.model];\\n            if (!modelData) {\\n                Log(`警告: 未找到模型数据 ${model.model}`);\\n                return;\\n            }\\n            \\n            const latestDecision = modelData.decisions && modelData.decisions.length > 0\\n                ? modelData.decisions[modelData.decisions.length - 1]\\n                : null;\\n            \\n            const profitRate = ((modelData.account.realizedPnl || 0) / (modelData.account.initialBalance || 1)) * 100;\\n            \\n            // 盈利率显示\\n            let profitRateDisplay = \\\"\\\";\\n            if (profitRate > 5) {\\n                profitRateDisplay = `🔥 +${safeFormat(profitRate)}%`;\\n            } else if (profitRate > 0) {\\n                profitRateDisplay = `🟢 +${safeFormat(profitRate)}%`;\\n            } else if (profitRate < 0) {\\n                profitRateDisplay = `🔴 ${safeFormat(profitRate)}%`;\\n            } else {\\n                profitRateDisplay = `⚪ 0%`;\\n            }\\n            \\n            // 持仓显示\\n            let positionDisplay = \\\"\\\";\\n            if (model.paperPosition === 'none') {\\n                positionDisplay = \\\"📭 空\\\";\\n            } else if (model.paperPosition === 'long') {\\n                positionDisplay = \\\"📈 多\\\";\\n            } else {\\n                positionDisplay = \\\"📉 空\\\";\\n            }\\n            \\n            // 决策显示\\n            let actionDisplay = latestDecision?.action || \\\"无\\\";\\n            switch(actionDisplay) {\\n                case 'OPEN_LONG':\\n                    actionDisplay = \\\"🟢 开多\\\";\\n                    break;\\n                case 'OPEN_SHORT':\\n                    actionDisplay = \\\"🔴 开空\\\";\\n                    break;\\n                case 'CLOSE_LONG':\\n                    actionDisplay = \\\"⏹️ 平多\\\";\\n                    break;\\n                case 'CLOSE_SHORT':\\n                    actionDisplay = \\\"⏹️ 平空\\\";\\n                    break;\\n                case 'NO_ACTION':\\n                    actionDisplay = \\\"⏸️ 观望\\\";\\n                    break;\\n            }\\n            \\n            const realizedPnl = modelData.account.realizedPnl || 0;\\n            let pnlDisplay = \\\"\\\";\\n            if (realizedPnl > 0) {\\n                pnlDisplay = `🟢 ${safeFormat(realizedPnl, 2, \\\"$\\\")}`;\\n            } else if (realizedPnl < 0) {\\n                pnlDisplay = `🔴 ${safeFormat(realizedPnl, 2, \\\"$\\\")}`;\\n            } else {\\n                pnlDisplay = `⚪ $0`;\\n            }\\n            \\n            statusTable.rows.push([\\n                `${model.isActive ? '⭐' : '💎'} ${model.model}`,\\n                model.isActive ? \\\"✅\\\" : \\\"❌\\\",\\n                safeFormat(modelData.account.initialBalance, 2, \\\"$\\\"),\\n                safeFormat(modelData.account.totalValue, 2, \\\"$\\\"),\\n                pnlDisplay,\\n                profitRateDisplay,\\n                positionDisplay,\\n                modelData.account.totalTrades || 0,\\n                safePercentage(modelData.account.winTrades || 0, modelData.account.totalTrades || 1),\\n                actionDisplay,\\n                latestDecision?.price ? safeFormat(latestDecision.price, 2, \\\"$\\\") : '-',\\n                latestDecision?.reasoning ? latestDecision.reasoning : '-'\\n            ]);\\n        });\\n        \\n    } catch (e) {\\n        Log(`❌ 创建模型状态表失败: ${e.message}`);\\n        Log(`错误堆栈: ${e.stack}`);\\n        statusTable.rows.push([\\n            \\\"❌ 错误\\\", \\\"获取数据失败\\\", \\\"-\\\", \\\"-\\\", \\\"-\\\", \\\"-\\\", \\\"-\\\", \\\"-\\\", \\\"-\\\", \\\"-\\\", \\\"-\\\", e.message\\n        ]);\\n    }\\n    \\n    return statusTable;\\n}\\n\\n/**\\n * 表格2: 模型性能对比分析\\n */\\nfunction createPerformanceComparisonTable(allModelsStatus, models) {\\n    const perfTable = {\\n        type: \\\"table\\\",\\n        title: \\\"📊 AI模型性能对比分析 (按盈亏排序)\\\",\\n        cols: [\\\"排名\\\", \\\"模型\\\", \\\"已实现\\\", \\\"总资产\\\", \\\"最大盈利\\\", \\\"最大亏损\\\", \\\"最大回撤\\\", \\\"夏普比率\\\", \\\"盈亏比\\\", \\\"交易数\\\", \\\"胜率\\\", \\\"平均盈\\\", \\\"平均亏\\\"],\\n        rows: []\\n    };\\n    \\n    try {\\n        const performanceData = allModelsStatus.map((model, index) => {\\n            const modelData = models[model.model];\\n            if (!modelData) {\\n                return null;\\n            }\\n            \\n            const tradeHistory = modelData.tradeHistory || [];\\n            \\n            // 筛选平仓交易(有pnl的记录)\\n            const closedTrades = tradeHistory.filter(trade => \\n                trade.pnl !== undefined && trade.pnl !== null\\n            );\\n            \\n            // 计算最大盈利\\n            const maxProfit = closedTrades.length > 0\\n                ? Math.max(...closedTrades.map(t => t.pnl || 0))\\n                : 0;\\n            \\n            // 计算最大亏损\\n            const maxLoss = closedTrades.length > 0\\n                ? Math.min(...closedTrades.map(t => t.pnl || 0))\\n                : 0;\\n            \\n            // 计算最大回撤\\n            let maxDrawdown = 0;\\n            let peak = modelData.account.initialBalance || 10000;\\n            let cumulativePnl = 0;\\n            \\n            closedTrades.forEach(trade => {\\n                cumulativePnl += (trade.pnl || 0);\\n                const currentValue = (modelData.account.initialBalance || 10000) + cumulativePnl;\\n                \\n                if (currentValue > peak) {\\n                    peak = currentValue;\\n                }\\n                \\n                const drawdown = peak > 0 ? ((peak - currentValue) / peak) * 100 : 0;\\n                if (drawdown > maxDrawdown) {\\n                    maxDrawdown = drawdown;\\n                }\\n            });\\n            \\n            // 计算夏普比率\\n            let sharpeRatio = 0;\\n            if (closedTrades.length > 1) {\\n                const initialBalance = modelData.account.initialBalance || 10000;\\n                const returns = closedTrades.map(t => (t.pnl || 0) / initialBalance);\\n                const avgReturn = returns.reduce((a, b) => a + b, 0) / returns.length;\\n                \\n                const variance = returns.reduce((sum, r) => sum + Math.pow(r - avgReturn, 2), 0) / returns.length;\\n                const stdDev = Math.sqrt(variance);\\n                \\n                sharpeRatio = stdDev !== 0 ? (avgReturn / stdDev) : 0;\\n            }\\n            \\n            // 盈亏比\\n            const winTrades = closedTrades.filter(t => (t.pnl || 0) > 0);\\n            const lossTrades = closedTrades.filter(t => (t.pnl || 0) < 0);\\n            \\n            const avgWin = winTrades.length > 0\\n                ? winTrades.reduce((sum, t) => sum + (t.pnl || 0), 0) / winTrades.length\\n                : 0;\\n            \\n            const avgLoss = lossTrades.length > 0\\n                ? Math.abs(lossTrades.reduce((sum, t) => sum + (t.pnl || 0), 0) / lossTrades.length)\\n                : 0;\\n            \\n            const profitLossRatio = avgLoss !== 0 ? (avgWin / avgLoss) : 0;\\n            \\n            return {\\n                model: model.model,\\n                rank: index + 1,\\n                realizedPnl: modelData.account.realizedPnl || 0,\\n                totalValue: modelData.account.totalValue || 0,\\n                maxProfit: maxProfit,\\n                maxLoss: maxLoss,\\n                maxDrawdown: maxDrawdown,\\n                sharpeRatio: sharpeRatio,\\n                profitLossRatio: profitLossRatio,\\n                totalTrades: closedTrades.length,\\n                winRate: (modelData.account.totalTrades || 0) > 0 \\n                    ? (((modelData.account.winTrades || 0) / modelData.account.totalTrades) * 100)\\n                    : 0,\\n                avgWin: avgWin,\\n                avgLoss: avgLoss\\n            };\\n        }).filter(perf => perf !== null).sort((a, b) => b.realizedPnl - a.realizedPnl);\\n        \\n        performanceData.forEach((perf, index) => {\\n            // 排名显示\\n            let rankDisplay = \\\"\\\";\\n            if (index === 0) {\\n                rankDisplay = \\\"🥇\\\";\\n            } else if (index === 1) {\\n                rankDisplay = \\\"🥈\\\";\\n            } else if (index === 2) {\\n                rankDisplay = \\\"🥉\\\";\\n            } else {\\n                rankDisplay = `${index + 1}`;\\n            }\\n            \\n            // 夏普比率显示\\n            let sharpeDisplay = \\\"\\\";\\n            if (perf.sharpeRatio > 2) {\\n                sharpeDisplay = `🔥 ${safeFormat(perf.sharpeRatio)}`;\\n            } else if (perf.sharpeRatio > 1) {\\n                sharpeDisplay = `✅ ${safeFormat(perf.sharpeRatio)}`;\\n            } else if (perf.sharpeRatio > 0) {\\n                sharpeDisplay = `⚡ ${safeFormat(perf.sharpeRatio)}`;\\n            } else {\\n                sharpeDisplay = `⚠️ ${safeFormat(perf.sharpeRatio)}`;\\n            }\\n            \\n            perfTable.rows.push([\\n                rankDisplay,\\n                `💎 ${perf.model}`,\\n                perf.realizedPnl > 0 \\n                    ? `🟢 ${safeFormat(perf.realizedPnl, 2, \\\"$\\\")}`\\n                    : perf.realizedPnl < 0\\n                    ? `🔴 ${safeFormat(perf.realizedPnl, 2, \\\"$\\\")}`\\n                    : `⚪ $0`,\\n                safeFormat(perf.totalValue, 2, \\\"$\\\"),\\n                perf.maxProfit > 0 ? `🟢 ${safeFormat(perf.maxProfit, 2, \\\"$\\\")}` : '$0',\\n                perf.maxLoss < 0 ? `🔴 ${safeFormat(perf.maxLoss, 2, \\\"$\\\")}` : '$0',\\n                perf.maxDrawdown > 0 ? `⚠️ ${safeFormat(perf.maxDrawdown)}%` : '0%',\\n                sharpeDisplay,\\n                perf.profitLossRatio > 0 ? safeFormat(perf.profitLossRatio) : '0',\\n                perf.totalTrades,\\n                `${safeFormat(perf.winRate, 1)}%`,\\n                perf.avgWin > 0 ? safeFormat(perf.avgWin, 2, \\\"$\\\") : '$0',\\n                perf.avgLoss > 0 ? safeFormat(perf.avgLoss, 2, \\\"$\\\") : '$0'\\n            ]);\\n        });\\n        \\n        // 添加汇总行\\n        if (performanceData.length > 0) {\\n            const avgPnl = performanceData.reduce((sum, p) => sum + p.realizedPnl, 0) / performanceData.length;\\n            const avgSharpe = performanceData.reduce((sum, p) => sum + p.sharpeRatio, 0) / performanceData.length;\\n            const totalTrades = performanceData.reduce((sum, p) => sum + p.totalTrades, 0);\\n            \\n            perfTable.rows.push([\\n                \\\"📊\\\",\\n                \\\"平均\\\",\\n                avgPnl > 0 ? `🟢 ${safeFormat(avgPnl, 2, \\\"$\\\")}` : avgPnl < 0 ? `🔴 ${safeFormat(avgPnl, 2, \\\"$\\\")}` : `⚪ $0`,\\n                \\\"-\\\",\\n                \\\"-\\\",\\n                \\\"-\\\",\\n                \\\"-\\\",\\n                safeFormat(avgSharpe),\\n                \\\"-\\\",\\n                totalTrades,\\n                \\\"-\\\",\\n                \\\"-\\\",\\n                \\\"-\\\"\\n            ]);\\n        }\\n        \\n    } catch (e) {\\n        Log(`❌ 创建性能对比表失败: ${e.message}`);\\n        Log(`错误堆栈: ${e.stack}`);\\n        perfTable.rows.push([\\n            \\\"❌\\\", \\\"错误\\\", \\\"获取数据失败\\\", \\\"-\\\", \\\"-\\\", \\\"-\\\", \\\"-\\\", \\\"-\\\", \\\"-\\\", \\\"-\\\", \\\"-\\\", \\\"-\\\", e.message\\n        ]);\\n    }\\n    \\n    return perfTable;\\n}\\n\\n/**\\n * 表格3: 实际交易状态\\n */\\nfunction createRealTradingTable(inputData, models) {\\n    const realTable = {\\n        type: \\\"table\\\",\\n        title: \\\"💼 实盘交易状态\\\",\\n        cols: [\\\"项目\\\", \\\"数值\\\", \\\"状态\\\", \\\"说明\\\"],\\n        rows: []\\n    };\\n    \\n    try {\\n        const activeModel = inputData.activeModel;\\n        const realAccount = exchange.GetAccount();\\n        const realPositions = exchange.GetPosition();\\n        \\n        // 获取真实持仓信息\\n        let realPositionInfo = {\\n            type: '无',\\n            size: 0,\\n            entryPrice: 0,\\n            currentPrice: 0,\\n            unrealizedPnl: 0\\n        };\\n        \\n        if (realPositions && realPositions.length > 0) {\\n            const pos = realPositions[0];\\n            const ticker = exchange.GetTicker();\\n            const currentPrice = ticker ? ticker.Last : 0;\\n            \\n            realPositionInfo = {\\n                type: pos.Type === PD_LONG ? '多' : '空',\\n                size: pos.Amount || 0,\\n                entryPrice: pos.Price || 0,\\n                currentPrice: currentPrice,\\n                unrealizedPnl: pos.Profit || 0\\n            };\\n        }\\n        \\n        // 计算实际账户的累计收益\\n        const initMoney = _G('initmoney') || 10000;\\n        const currentBalance = realAccount ? (realAccount.Balance || 0) : 0;\\n        const currentEquity = realAccount ? (realAccount.Equity || 0) : 0;\\n        const realizedProfit = currentBalance - initMoney;\\n        const totalProfit = currentEquity - initMoney;\\n        const returnRate = initMoney > 0 ? ((totalProfit / initMoney) * 100) : 0;\\n\\n        LogProfit(totalProfit, \\\"&\\\");\\n        \\n        // 激活模型信息\\n        realTable.rows.push([\\n            \\\"🤖 激活模型\\\",\\n            activeModel || \\\"未启动\\\",\\n            activeModel ? \\\"✅ 运行中\\\" : \\\"⏸️ 待启动\\\",\\n            activeModel && models[activeModel] \\n                ? `盈亏: ${safeFormat(models[activeModel].account.realizedPnl, 2, \\\"$\\\")}` \\n                : \\\"等待盈利大于阈值触发\\\"\\n        ]);\\n        \\n        // 账户信息\\n        realTable.rows.push([\\n            \\\"💰 初始资金\\\",\\n            safeFormat(initMoney, 2, \\\"$\\\"),\\n            \\\"📊\\\",\\n            \\\"实盘起始金额\\\"\\n        ]);\\n        \\n        realTable.rows.push([\\n            \\\"💵 当前余额\\\",\\n            safeFormat(currentBalance, 2, \\\"$\\\"),\\n            \\\"📊\\\",\\n            \\\"可用资金\\\"\\n        ]);\\n        \\n        realTable.rows.push([\\n            \\\"💎 账户权益\\\",\\n            safeFormat(currentEquity, 2, \\\"$\\\"),\\n            \\\"📊\\\",\\n            \\\"余额 + 持仓盈亏\\\"\\n        ]);\\n        \\n        // 盈亏信息\\n        let profitDisplay = \\\"\\\";\\n        let profitStatus = \\\"\\\";\\n        if (totalProfit > 0) {\\n            profitDisplay = `🟢 +${safeFormat(totalProfit, 2, \\\"$\\\")}`;\\n            profitStatus = \\\"✅ 盈利中\\\";\\n        } else if (totalProfit < 0) {\\n            profitDisplay = `🔴 ${safeFormat(totalProfit, 2, \\\"$\\\")}`;\\n            profitStatus = \\\"⚠️ 亏损中\\\";\\n        } else {\\n            profitDisplay = `⚪ $0`;\\n            profitStatus = \\\"⚪ 持平\\\";\\n        }\\n        \\n        realTable.rows.push([\\n            \\\"📈 累计盈亏\\\",\\n            profitDisplay,\\n            profitStatus,\\n            `收益率: ${returnRate > 0 ? '+' : ''}${safeFormat(returnRate)}%`\\n        ]);\\n        \\n        // 持仓信息\\n        realTable.rows.push([\\n            \\\"💼 当前持仓\\\",\\n            realPositionInfo.type === '无' ? \\\"📭 空仓\\\" : `${realPositionInfo.type === '多' ? '📈' : '📉'} ${realPositionInfo.type}单`,\\n            realPositionInfo.type === '无' ? \\\"⚪ 无持仓\\\" : \\\"✅ 持仓中\\\",\\n            realPositionInfo.type === '无' ? \\\"-\\\" : `数量: ${safeFormat(realPositionInfo.size, 4)}`\\n        ]);\\n        \\n        if (realPositionInfo.type !== '无') {\\n            realTable.rows.push([\\n                \\\"💰 持仓均价\\\",\\n                safeFormat(realPositionInfo.entryPrice, 4, \\\"$\\\"),\\n                \\\"📊\\\",\\n                `当前: ${safeFormat(realPositionInfo.currentPrice, 4, \\\"$\\\")}`\\n            ]);\\n            \\n            let positionPnlDisplay = \\\"\\\";\\n            let positionPnlStatus = \\\"\\\";\\n            if (realPositionInfo.unrealizedPnl > 0) {\\n                positionPnlDisplay = `🟢 +${safeFormat(realPositionInfo.unrealizedPnl, 2, \\\"$\\\")}`;\\n                positionPnlStatus = \\\"✅ 浮盈\\\";\\n            } else if (realPositionInfo.unrealizedPnl < 0) {\\n                positionPnlDisplay = `🔴 ${safeFormat(realPositionInfo.unrealizedPnl, 2, \\\"$\\\")}`;\\n                positionPnlStatus = \\\"⚠️ 浮亏\\\";\\n            } else {\\n                positionPnlDisplay = `⚪ $0`;\\n                positionPnlStatus = \\\"⚪ 持平\\\";\\n            }\\n            \\n            realTable.rows.push([\\n                \\\"📊 持仓盈亏\\\",\\n                positionPnlDisplay,\\n                positionPnlStatus,\\n                \\\"未实现盈亏\\\"\\n            ]);\\n        }\\n        \\n        // 同步状态\\n        realTable.rows.push([\\n            \\\"🔄 同步状态\\\",\\n            inputData.shouldTrade ? \\\"待同步\\\" : \\\"已同步\\\",\\n            inputData.shouldTrade ? \\\"🔄 执行中\\\" : \\\"✅ 同步\\\",\\n            inputData.tradeAction?.reason || \\\"纸面与实盘一致\\\"\\n        ]);\\n        \\n        // 上次交易\\n        if (inputData.tradeAction) {\\n            let actionDisplay = inputData.tradeAction.action;\\n            switch(actionDisplay) {\\n                case 'OPEN_LONG':\\n                    actionDisplay = \\\"🟢 开多\\\";\\n                    break;\\n                case 'OPEN_SHORT':\\n                    actionDisplay = \\\"🔴 开空\\\";\\n                    break;\\n                case 'CLOSE_LONG':\\n                    actionDisplay = \\\"⏹️ 平多\\\";\\n                    break;\\n                case 'CLOSE_SHORT':\\n                    actionDisplay = \\\"⏹️ 平空\\\";\\n                    break;\\n            }\\n            \\n            realTable.rows.push([\\n                \\\"📝 上次交易\\\",\\n                actionDisplay,\\n                \\\"📊\\\",\\n                inputData.tradeAction.reason || \\\"-\\\"\\n            ]);\\n        }\\n        \\n        // 模型对比\\n        if (activeModel && models[activeModel]) {\\n            const modelPnl = models[activeModel].account.realizedPnl || 0;\\n            const gap = realizedProfit - modelPnl;\\n            \\n            realTable.rows.push([\\n                \\\"📊 与模型差距\\\",\\n                gap > 0 ? `🟢 领先 ${safeFormat(gap, 2, \\\"$\\\")}` : gap < 0 ? `🔴 落后 ${safeFormat(Math.abs(gap), 2, \\\"$\\\")}` : `⚪ 一致`,\\n                gap > 0 ? \\\"✅ 超越\\\" : gap < 0 ? \\\"⚠️ 追赶\\\" : \\\"⚪ 同步\\\",\\n                `模型纸面: ${safeFormat(modelPnl, 2, \\\"$\\\")}`\\n            ]);\\n        }\\n        \\n    } catch (e) {\\n        Log(`❌ 创建实盘交易表失败: ${e.message}`);\\n        Log(`错误堆栈: ${e.stack}`);\\n        realTable.rows.push([\\n            \\\"❌ 错误\\\",\\n            \\\"获取数据失败\\\",\\n            \\\"🚨\\\",\\n            e.message\\n        ]);\\n    }\\n    \\n    return realTable;\\n}\\n\\n/**\\n * 表格4: 系统统计信息\\n */\\nfunction createSystemStatsTable(allModelsStatus, models, inputData) {\\n    const statsTable = {\\n        type: \\\"table\\\",\\n        title: \\\"📊 系统整体统计\\\",\\n        cols: [\\\"统计项\\\", \\\"数值\\\", \\\"评级\\\", \\\"备注\\\"],\\n        rows: []\\n    };\\n    \\n    try {\\n        // 模型总数\\n        statsTable.rows.push([\\n            \\\"🤖 参赛模型\\\",\\n            `${allModelsStatus.length} 个`,\\n            \\\"📊\\\",\\n            \\\"AI模型竞赛\\\"\\n        ]);\\n        \\n        // 最优模型\\n        if (allModelsStatus.length > 0) {\\n            const bestModel = allModelsStatus[0];\\n            statsTable.rows.push([\\n                \\\"🥇 最优模型\\\",\\n                bestModel.model,\\n                bestModel.realizedPnl > 0 ? \\\"✅ 盈利\\\" : \\\"⚠️ 亏损\\\",\\n                `盈亏: ${safeFormat(bestModel.realizedPnl, 2, \\\"$\\\")}`\\n            ]);\\n        }\\n        \\n        // 平均表现\\n        if (allModelsStatus.length > 0) {\\n            const avgPnl = allModelsStatus.reduce((sum, m) => sum + (m.realizedPnl || 0), 0) / allModelsStatus.length;\\n            statsTable.rows.push([\\n                \\\"📊 平均盈亏\\\",\\n                avgPnl > 0 ? `🟢 ${safeFormat(avgPnl, 2, \\\"$\\\")}` : avgPnl < 0 ? `🔴 ${safeFormat(avgPnl, 2, \\\"$\\\")}` : `⚪ $0`,\\n                avgPnl > 0 ? \\\"✅ 正收益\\\" : \\\"⚠️ 负收益\\\",\\n                \\\"所有模型平均\\\"\\n            ]);\\n        }\\n        \\n        // 盈利模型数\\n        const profitableModels = allModelsStatus.filter(m => (m.realizedPnl || 0) > 0).length;\\n        statsTable.rows.push([\\n            \\\"✅ 盈利模型\\\",\\n            `${profitableModels} / ${allModelsStatus.length}`,\\n            profitableModels > allModelsStatus.length / 2 ? \\\"✅ 良好\\\" : \\\"⚠️ 偏少\\\",\\n            `占比: ${safePercentage(profitableModels, allModelsStatus.length)}`\\n        ]);\\n        \\n        // 总交易次数\\n        const totalTrades = allModelsStatus.reduce((sum, m) => {\\n            const modelData = models[m.model];\\n            return sum + (modelData ? (modelData.account.totalTrades || 0) : 0);\\n        }, 0);\\n        \\n        statsTable.rows.push([\\n            \\\"🎲 总交易数\\\",\\n            totalTrades,\\n            totalTrades > 50 ? \\\"✅ 充足\\\" : totalTrades > 10 ? \\\"✅ 适中\\\" : \\\"⚠️ 偏少\\\",\\n            `所有模型合计`\\n        ]);\\n        \\n        // 平均胜率\\n        let totalWinRate = 0;\\n        let validModels = 0;\\n        allModelsStatus.forEach(m => {\\n            const modelData = models[m.model];\\n            if (modelData && (modelData.account.totalTrades || 0) > 0) {\\n                totalWinRate += ((modelData.account.winTrades || 0) / modelData.account.totalTrades) * 100;\\n                validModels++;\\n            }\\n        });\\n        const avgWinRate = validModels > 0 ? totalWinRate / validModels : 0;\\n        \\n        statsTable.rows.push([\\n            \\\"🎯 平均胜率\\\",\\n            `${safeFormat(avgWinRate, 1)}%`,\\n            avgWinRate > 60 ? \\\"🔥 优秀\\\" : avgWinRate > 45 ? \\\"✅ 良好\\\" : \\\"⚠️ 需改进\\\",\\n            \\\"有效交易模型平均\\\"\\n        ]);\\n        \\n        // 持仓模型数\\n        const modelsWithPosition = allModelsStatus.filter(m => m.paperPosition !== 'none').length;\\n        statsTable.rows.push([\\n            \\\"💼 持仓模型\\\",\\n            `${modelsWithPosition} / ${allModelsStatus.length}`,\\n            modelsWithPosition > 0 ? \\\"✅ 活跃\\\" : \\\"📭 空仓\\\",\\n            `占比: ${safePercentage(modelsWithPosition, allModelsStatus.length)}`\\n        ]);\\n        \\n        // 实盘状态\\n        const isRealTrading = inputData.activeModel ? true : false;\\n        statsTable.rows.push([\\n            \\\"🚀 实盘状态\\\",\\n            isRealTrading ? \\\"运行中\\\" : \\\"未启动\\\",\\n            isRealTrading ? \\\"✅ 激活\\\" : \\\"⏸️ 待命\\\",\\n            isRealTrading ? `跟随: ${inputData.activeModel}` : \\\"等待盈利>500\\\"\\n        ]);\\n        \\n        // 最后更新时间\\n        const updateTime = new Date().toLocaleString();\\n        statsTable.rows.push([\\n            \\\"🕐 更新时间\\\",\\n            updateTime,\\n            \\\"📊\\\",\\n            \\\"实时监控中\\\"\\n        ]);\\n        \\n    } catch (e) {\\n        Log(`❌ 创建统计表失败: ${e.message}`);\\n        Log(`错误堆栈: ${e.stack}`);\\n        statsTable.rows.push([\\n            \\\"❌ 错误\\\",\\n            \\\"计算失败\\\",\\n            \\\"🚨\\\",\\n            e.message\\n        ]);\\n    }\\n    \\n    return statsTable;\\n}\\n\\n/**\\n * 主函数 - 显示完整仪表板\\n */\\nfunction main() {\\n    try {\\n        Log('可视化节点开始执行');\\n        \\n        // 获取输入数据\\n        const inputData = $input.all()[0].json;\\n        Log('inputData keys:', Object.keys(inputData));\\n        \\n        const allModelsStatus = inputData.allModelsStatus;\\n        if (!allModelsStatus || !Array.isArray(allModelsStatus)) {\\n            throw new Error('allModelsStatus 数据无效或不是数组');\\n        }\\n        \\n        Log(`模型数量: ${allModelsStatus.length}`);\\n        \\n        // 获取详细的模型数据\\n        const models = $node['结果核算'].json;\\n        if (!models) {\\n            throw new Error('无法获取结果核算节点的数据');\\n        }\\n        \\n        Log('models keys:', Object.keys(models));\\n        \\n        // 创建4个表格\\n        const table1 = createModelStatusTable(allModelsStatus, models);\\n        const table2 = createPerformanceComparisonTable(allModelsStatus, models);\\n        const table3 = createRealTradingTable(inputData, models);\\n        const table4 = createSystemStatsTable(allModelsStatus, models, inputData);\\n        \\n        // 组合显示\\n        const dashboardDisplay = \\n            '`' + JSON.stringify(table1) + '`\\\\n\\\\n' +\\n            '`' + JSON.stringify(table2) + '`\\\\n\\\\n' +\\n            '`' + JSON.stringify(table3) + '`\\\\n\\\\n' +\\n            '`' + JSON.stringify(table4) + '`';\\n        \\n        LogStatus(dashboardDisplay);\\n        \\n        Log('✅ 可视化显示成功');\\n        \\n        // 返回完整数据\\n        return [{\\n            json: {\\n                ...inputData,\\n                tables: {\\n                    modelStatus: table1,\\n                    performance: table2,\\n                    realTrading: table3,\\n                    systemStats: table4\\n                },\\n                timestamp: Date.now(),\\n                updateTime: new Date().toLocaleString()\\n            }\\n        }];\\n        \\n    } catch (e) {\\n        Log(`❌ 显示仪表板失败: ${e.message}`);\\n        Log(`❌ 错误堆栈: ${e.stack}`);\\n        \\n        // 错误时显示简单状态\\n        const errorTable = {\\n            type: \\\"table\\\",\\n            title: \\\"❌ 系统错误\\\",\\n            cols: [\\\"错误类型\\\", \\\"错误信息\\\", \\\"时间\\\"],\\n            rows: [[\\n                \\\"可视化错误\\\",\\n                e.message,\\n                new Date().toLocaleString()\\n            ]]\\n        };\\n        \\n        LogStatus('`' + JSON.stringify(errorTable) + '`');\\n        \\n        return [{\\n            json: {\\n                error: e.message,\\n                stack: e.stack,\\n                timestamp: Date.now()\\n            }\\n        }];\\n    }\\n}\\n\\n// 执行主函数\\nreturn main();\\n\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[144,960],\"id\":\"30d90c04-224e-442c-a72d-31a8a1792835\",\"name\":\"可视化\"},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"const symbol = $vars.coin + \\\"_USDT.swap\\\"\\nconst timeframes = {\\n    day: PERIOD_D1,\\n    hour: PERIOD_H1,\\n    min5: PERIOD_M5\\n}\\n\\nfunction getIndicatorsForPeriod(symbol, period, periodName) {\\n    const records = exchange.GetRecords(symbol, period)\\n    \\n    if (!records || records.length <= 10) {\\n        Log(`警告: ${periodName}周期数据不足,仅有 ${records ? records.length : 0} 条记录`)\\n        return null\\n    }\\n    \\n    const macd = talib.MACD(records)\\n    const rsi = talib.RSI(records, 14)\\n    const atr = talib.ATR(records, 14)\\n    const obv = talib.OBV(records)\\n    \\n    function getLast10Values(arr) {\\n        if (!arr || arr.length === 0) return []\\n        return arr.slice(-10)\\n    }\\n    \\n    return {\\n        period: periodName,\\n        recordsCount: records.length,\\n        lastPrice: records[records.length - 1].Close,\\n        MACD: {\\n            macd: getLast10Values(macd[0]),\\n            signal: getLast10Values(macd[1]), \\n            histogram: getLast10Values(macd[2])\\n        },\\n        RSI: getLast10Values(rsi),\\n        ATR: getLast10Values(atr),\\n        OBV: getLast10Values(obv)\\n    }\\n}\\n\\nconst models = _G('models')\\nconst modelPnlData = Object.keys(models).map(modelName => ({\\n    name: modelName,\\n    realizedPnl: models[modelName].account.realizedPnl,\\n    totalValue: models[modelName].account.totalValue\\n}))\\n\\nconst sortedModels = modelPnlData.sort((a, b) => b.realizedPnl - a.realizedPnl)\\n\\nconst rankedModels = []\\nlet currentRank = 1\\nlet previousPnl = null\\n\\nsortedModels.forEach((model, index) => {\\n    if (previousPnl !== null && model.realizedPnl < previousPnl) {\\n        currentRank = index + 1\\n    }\\n    \\n    rankedModels.push({\\n        ...model,\\n        rank: currentRank\\n    })\\n    \\n    previousPnl = model.realizedPnl\\n})\\n\\nconst currentModelName = Object.keys(models)[0] // DS是第一个模型\\nconst currentModelRank = rankedModels.find(model => model.name === currentModelName)\\n\\nconst rankingText = rankedModels.map(model => \\n    `${model.rank}. ${model.name}: ${model.realizedPnl} USDT${model.name === currentModelName ? ' ← 你的位置' : ''}`\\n).join('\\\\n')\\n\\nlet gapInfo = ''\\nif (currentModelRank.rank > 1) {\\n    const firstPlace = rankedModels[0]\\n    const gap = (firstPlace.realizedPnl - currentModelRank.realizedPnl).toFixed(2)\\n    gapInfo = `### 与第一名差距\\\\n第一名盈亏: ${firstPlace.realizedPnl} USDT\\\\n你需要追赶: ${gap} USDT`\\n} else {\\n    gapInfo = '🏆 恭喜!你目前领先!保持优势!'\\n}\\n\\nconst result = {\\n    symbol: symbol,\\n    timestamp: Date.now(),\\n    timeframes: {\\n        day: getIndicatorsForPeriod(symbol, timeframes.day, '日线'),\\n        hour: getIndicatorsForPeriod(symbol, timeframes.hour, '小时线'),\\n        min5: getIndicatorsForPeriod(symbol, timeframes.min5, '5分钟线')\\n    },\\n    // ⚠️ 修改点:使用模型自己的虚拟持仓,而不是真实持仓\\n    position: models[currentModelName].positions || [],\\n    ranking: {\\n        currentModel: currentModelName,\\n        currentRank: currentModelRank.rank,\\n        currentPnl: currentModelRank.realizedPnl,\\n        currentTotalValue: currentModelRank.totalValue,\\n        totalTrades: models[currentModelName].account.totalTrades,\\n        winTrades: models[currentModelName].account.winTrades,\\n        winRate: models[currentModelName].account.totalTrades > 0 ? \\n            (models[currentModelName].account.winTrades / models[currentModelName].account.totalTrades * 100).toFixed(2) : '0',\\n        rankingText: rankingText,\\n        gapInfo: gapInfo,\\n        totalModels: Object.keys(models).length,\\n        allRankings: rankedModels\\n    }\\n}\\n\\nreturn result\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[-1360,592],\"id\":\"2326b0ac-9d46-4170-a4ec-49700cd11310\",\"name\":\"DS处理\"},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"const symbol = $vars.coin + \\\"_USDT.swap\\\"\\nconst timeframes = {\\n    day: PERIOD_D1,\\n    hour: PERIOD_H1,\\n    min5: PERIOD_M5\\n}\\n\\nfunction getIndicatorsForPeriod(symbol, period, periodName) {\\n    const records = exchange.GetRecords(symbol, period)\\n    \\n    if (!records || records.length <= 10) {\\n        Log(`警告: ${periodName}周期数据不足,仅有 ${records ? records.length : 0} 条记录`)\\n        return null\\n    }\\n    \\n    const macd = talib.MACD(records)\\n    const rsi = talib.RSI(records, 14)\\n    const atr = talib.ATR(records, 14)\\n    const obv = talib.OBV(records)\\n    \\n    function getLast10Values(arr) {\\n        if (!arr || arr.length === 0) return []\\n        return arr.slice(-10)\\n    }\\n    \\n    return {\\n        period: periodName,\\n        recordsCount: records.length,\\n        lastPrice: records[records.length - 1].Close,\\n        MACD: {\\n            macd: getLast10Values(macd[0]),\\n            signal: getLast10Values(macd[1]), \\n            histogram: getLast10Values(macd[2])\\n        },\\n        RSI: getLast10Values(rsi),\\n        ATR: getLast10Values(atr),\\n        OBV: getLast10Values(obv)\\n    }\\n}\\n\\nconst models = _G('models')\\nconst modelPnlData = Object.keys(models).map(modelName => ({\\n    name: modelName,\\n    realizedPnl: models[modelName].account.realizedPnl,\\n    totalValue: models[modelName].account.totalValue\\n}))\\n\\nconst sortedModels = modelPnlData.sort((a, b) => b.realizedPnl - a.realizedPnl)\\n\\nconst rankedModels = []\\nlet currentRank = 1\\nlet previousPnl = null\\n\\nsortedModels.forEach((model, index) => {\\n    if (previousPnl !== null && model.realizedPnl < previousPnl) {\\n        currentRank = index + 1\\n    }\\n    \\n    rankedModels.push({\\n        ...model,\\n        rank: currentRank\\n    })\\n    \\n    previousPnl = model.realizedPnl\\n})\\n\\nconst currentModelName = Object.keys(models)[1] // DS是第一个模型\\nconst currentModelRank = rankedModels.find(model => model.name === currentModelName)\\n\\nconst rankingText = rankedModels.map(model => \\n    `${model.rank}. ${model.name}: ${model.realizedPnl} USDT${model.name === currentModelName ? ' ← 你的位置' : ''}`\\n).join('\\\\n')\\n\\nlet gapInfo = ''\\nif (currentModelRank.rank > 1) {\\n    const firstPlace = rankedModels[0]\\n    const gap = (firstPlace.realizedPnl - currentModelRank.realizedPnl).toFixed(2)\\n    gapInfo = `### 与第一名差距\\\\n第一名盈亏: ${firstPlace.realizedPnl} USDT\\\\n你需要追赶: ${gap} USDT`\\n} else {\\n    gapInfo = '🏆 恭喜!你目前领先!保持优势!'\\n}\\n\\nconst result = {\\n    symbol: symbol,\\n    timestamp: Date.now(),\\n    timeframes: {\\n        day: getIndicatorsForPeriod(symbol, timeframes.day, '日线'),\\n        hour: getIndicatorsForPeriod(symbol, timeframes.hour, '小时线'),\\n        min5: getIndicatorsForPeriod(symbol, timeframes.min5, '5分钟线')\\n    },\\n    // ⚠️ 修改点:使用模型自己的虚拟持仓,而不是真实持仓\\n    position: models[currentModelName].positions || [],\\n    ranking: {\\n        currentModel: currentModelName,\\n        currentRank: currentModelRank.rank,\\n        currentPnl: currentModelRank.realizedPnl,\\n        currentTotalValue: currentModelRank.totalValue,\\n        totalTrades: models[currentModelName].account.totalTrades,\\n        winTrades: models[currentModelName].account.winTrades,\\n        winRate: models[currentModelName].account.totalTrades > 0 ? \\n            (models[currentModelName].account.winTrades / models[currentModelName].account.totalTrades * 100).toFixed(2) : '0',\\n        rankingText: rankingText,\\n        gapInfo: gapInfo,\\n        totalModels: Object.keys(models).length,\\n        allRankings: rankedModels\\n    }\\n}\\n\\nreturn result\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[-1376,864],\"id\":\"39896a53-f6a8-459f-ab90-c22834514b2f\",\"name\":\"Claude处理\"},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"const symbol = $vars.coin + \\\"_USDT.swap\\\"\\nconst timeframes = {\\n    day: PERIOD_D1,\\n    hour: PERIOD_H1,\\n    min5: PERIOD_M5\\n}\\n\\nfunction getIndicatorsForPeriod(symbol, period, periodName) {\\n    const records = exchange.GetRecords(symbol, period)\\n    \\n    if (!records || records.length <= 10) {\\n        Log(`警告: ${periodName}周期数据不足,仅有 ${records ? records.length : 0} 条记录`)\\n        return null\\n    }\\n    \\n    const macd = talib.MACD(records)\\n    const rsi = talib.RSI(records, 14)\\n    const atr = talib.ATR(records, 14)\\n    const obv = talib.OBV(records)\\n    \\n    function getLast10Values(arr) {\\n        if (!arr || arr.length === 0) return []\\n        return arr.slice(-10)\\n    }\\n    \\n    return {\\n        period: periodName,\\n        recordsCount: records.length,\\n        lastPrice: records[records.length - 1].Close,\\n        MACD: {\\n            macd: getLast10Values(macd[0]),\\n            signal: getLast10Values(macd[1]), \\n            histogram: getLast10Values(macd[2])\\n        },\\n        RSI: getLast10Values(rsi),\\n        ATR: getLast10Values(atr),\\n        OBV: getLast10Values(obv)\\n    }\\n}\\n\\nconst models = _G('models')\\nconst modelPnlData = Object.keys(models).map(modelName => ({\\n    name: modelName,\\n    realizedPnl: models[modelName].account.realizedPnl,\\n    totalValue: models[modelName].account.totalValue\\n}))\\n\\nconst sortedModels = modelPnlData.sort((a, b) => b.realizedPnl - a.realizedPnl)\\n\\nconst rankedModels = []\\nlet currentRank = 1\\nlet previousPnl = null\\n\\nsortedModels.forEach((model, index) => {\\n    if (previousPnl !== null && model.realizedPnl < previousPnl) {\\n        currentRank = index + 1\\n    }\\n    \\n    rankedModels.push({\\n        ...model,\\n        rank: currentRank\\n    })\\n    \\n    previousPnl = model.realizedPnl\\n})\\n\\nconst currentModelName = Object.keys(models)[2] // DS是第一个模型\\nconst currentModelRank = rankedModels.find(model => model.name === currentModelName)\\n\\nconst rankingText = rankedModels.map(model => \\n    `${model.rank}. ${model.name}: ${model.realizedPnl} USDT${model.name === currentModelName ? ' ← 你的位置' : ''}`\\n).join('\\\\n')\\n\\nlet gapInfo = ''\\nif (currentModelRank.rank > 1) {\\n    const firstPlace = rankedModels[0]\\n    const gap = (firstPlace.realizedPnl - currentModelRank.realizedPnl).toFixed(2)\\n    gapInfo = `### 与第一名差距\\\\n第一名盈亏: ${firstPlace.realizedPnl} USDT\\\\n你需要追赶: ${gap} USDT`\\n} else {\\n    gapInfo = '🏆 恭喜!你目前领先!保持优势!'\\n}\\n\\nconst result = {\\n    symbol: symbol,\\n    timestamp: Date.now(),\\n    timeframes: {\\n        day: getIndicatorsForPeriod(symbol, timeframes.day, '日线'),\\n        hour: getIndicatorsForPeriod(symbol, timeframes.hour, '小时线'),\\n        min5: getIndicatorsForPeriod(symbol, timeframes.min5, '5分钟线')\\n    },\\n    // ⚠️ 修改点:使用模型自己的虚拟持仓,而不是真实持仓\\n    position: models[currentModelName].positions || [],\\n    ranking: {\\n        currentModel: currentModelName,\\n        currentRank: currentModelRank.rank,\\n        currentPnl: currentModelRank.realizedPnl,\\n        currentTotalValue: currentModelRank.totalValue,\\n        totalTrades: models[currentModelName].account.totalTrades,\\n        winTrades: models[currentModelName].account.winTrades,\\n        winRate: models[currentModelName].account.totalTrades > 0 ? \\n            (models[currentModelName].account.winTrades / models[currentModelName].account.totalTrades * 100).toFixed(2) : '0',\\n        rankingText: rankingText,\\n        gapInfo: gapInfo,\\n        totalModels: Object.keys(models).length,\\n        allRankings: rankedModels\\n    }\\n}\\n\\nreturn result\\n\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[-1376,1152],\"id\":\"00a89176-edaf-4f84-ab7e-72e0f3da8cf4\",\"name\":\"QWEN处理\"},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"const symbol = $vars.coin + \\\"_USDT.swap\\\"\\nconst timeframes = {\\n    day: PERIOD_D1,\\n    hour: PERIOD_H1,\\n    min5: PERIOD_M5\\n}\\n\\nfunction getIndicatorsForPeriod(symbol, period, periodName) {\\n    const records = exchange.GetRecords(symbol, period)\\n    \\n    if (!records || records.length <= 10) {\\n        Log(`警告: ${periodName}周期数据不足,仅有 ${records ? records.length : 0} 条记录`)\\n        return null\\n    }\\n    \\n    const macd = talib.MACD(records)\\n    const rsi = talib.RSI(records, 14)\\n    const atr = talib.ATR(records, 14)\\n    const obv = talib.OBV(records)\\n    \\n    function getLast10Values(arr) {\\n        if (!arr || arr.length === 0) return []\\n        return arr.slice(-10)\\n    }\\n    \\n    return {\\n        period: periodName,\\n        recordsCount: records.length,\\n        lastPrice: records[records.length - 1].Close,\\n        MACD: {\\n            macd: getLast10Values(macd[0]),\\n            signal: getLast10Values(macd[1]), \\n            histogram: getLast10Values(macd[2])\\n        },\\n        RSI: getLast10Values(rsi),\\n        ATR: getLast10Values(atr),\\n        OBV: getLast10Values(obv)\\n    }\\n}\\n\\nconst models = _G('models')\\nconst modelPnlData = Object.keys(models).map(modelName => ({\\n    name: modelName,\\n    realizedPnl: models[modelName].account.realizedPnl,\\n    totalValue: models[modelName].account.totalValue\\n}))\\n\\nconst sortedModels = modelPnlData.sort((a, b) => b.realizedPnl - a.realizedPnl)\\n\\nconst rankedModels = []\\nlet currentRank = 1\\nlet previousPnl = null\\n\\nsortedModels.forEach((model, index) => {\\n    if (previousPnl !== null && model.realizedPnl < previousPnl) {\\n        currentRank = index + 1\\n    }\\n    \\n    rankedModels.push({\\n        ...model,\\n        rank: currentRank\\n    })\\n    \\n    previousPnl = model.realizedPnl\\n})\\n\\nconst currentModelName = Object.keys(models)[3] // DS是第一个模型\\nconst currentModelRank = rankedModels.find(model => model.name === currentModelName)\\n\\nconst rankingText = rankedModels.map(model => \\n    `${model.rank}. ${model.name}: ${model.realizedPnl} USDT${model.name === currentModelName ? ' ← 你的位置' : ''}`\\n).join('\\\\n')\\n\\nlet gapInfo = ''\\nif (currentModelRank.rank > 1) {\\n    const firstPlace = rankedModels[0]\\n    const gap = (firstPlace.realizedPnl - currentModelRank.realizedPnl).toFixed(2)\\n    gapInfo = `### 与第一名差距\\\\n第一名盈亏: ${firstPlace.realizedPnl} USDT\\\\n你需要追赶: ${gap} USDT`\\n} else {\\n    gapInfo = '🏆 恭喜!你目前领先!保持优势!'\\n}\\n\\nconst result = {\\n    symbol: symbol,\\n    timestamp: Date.now(),\\n    timeframes: {\\n        day: getIndicatorsForPeriod(symbol, timeframes.day, '日线'),\\n        hour: getIndicatorsForPeriod(symbol, timeframes.hour, '小时线'),\\n        min5: getIndicatorsForPeriod(symbol, timeframes.min5, '5分钟线')\\n    },\\n    // ⚠️ 修改点:使用模型自己的虚拟持仓,而不是真实持仓\\n    position: models[currentModelName].positions || [],\\n    ranking: {\\n        currentModel: currentModelName,\\n        currentRank: currentModelRank.rank,\\n        currentPnl: currentModelRank.realizedPnl,\\n        currentTotalValue: currentModelRank.totalValue,\\n        totalTrades: models[currentModelName].account.totalTrades,\\n        winTrades: models[currentModelName].account.winTrades,\\n        winRate: models[currentModelName].account.totalTrades > 0 ? \\n            (models[currentModelName].account.winTrades / models[currentModelName].account.totalTrades * 100).toFixed(2) : '0',\\n        rankingText: rankingText,\\n        gapInfo: gapInfo,\\n        totalModels: Object.keys(models).length,\\n        allRankings: rankedModels\\n    }\\n}\\n\\nreturn result\\n\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[-1360,1424],\"id\":\"9ffa443e-8335-4be5-acc9-c7d34c5de9f2\",\"name\":\"Grok处理\"}],\"pinData\":{\"合并\":[{\"json\":{\"output\":\"```json\\n{\\n  \\\"action\\\": \\\"NO_ACTION\\\",\\n  \\\"reasoning\\\": \\\"日线RSI从超买区域回落(72→57)但仍处中性区间,MACD柱状线显著收缩(391→-393)显示动能减弱;小时线RSI46-49无明确方向信号,MACD持续负值;5分钟级别同样缺乏清晰入场信号。比赛初期需等待更明确的高质量交易机会\\\",\\n  \\\"modelname\\\": \\\"DS\\\"\\n}\\n```\"}},{\"json\":{\"output\":\"```json\\n{\\n  \\\"action\\\": \\\"NO_ACTION\\\",\\n  \\\"reasoning\\\": \\\"多时间框架信号冲突:日线RSI从72回落至49显示上涨动能衰竭,MACD柱由正转负呈现死叉形态;小时线和5分钟线RSI在42-47区间徘徊,MACD持续负值但未见明显反转信号;OBV各周期分化严重。当前处于方向不明的震荡整理阶段,不符合高质量首次交易的标准,等待更清晰的趋势确认信号。\\\",\\n  \\\"modelname\\\": \\\"Claude\\\"\\n}\\n```\"}},{\"json\":{\"output\":\"{\\n  \\\"action\\\": \\\"OPEN_SHORT\\\",\\n  \\\"reasoning\\\": \\\"日线RSI跌破50且MACD柱深度为负、OBV走低;小时/5分RSI均<50且MACD柱为负,多周期一致偏空且无反转信号。\\\"\\n}\"}},{\"json\":{\"output\":\"```json\\n{\\n  \\\"action\\\": \\\"NO_ACTION\\\",\\n  \\\"reasoning\\\": \\\"日线RSI从超买回落且MACD柱转负,显示上涨动能减弱;但小时和5分钟级别指标未出现明确方向性信号,OBV持续流出且价格缺乏有力突破,整体处于趋势转换不明朗阶段,不宜贸然开仓。\\\"\\n}\\n```\"}},{\"json\":{\"output\":\"```json\\n{\\n  \\\"action\\\": \\\"NO_ACTION\\\",\\n  \\\"reasoning\\\": \\\"日线RSI下降、MACD负值、OBV卖压增加显示整体熊市趋势;小时/5min MACD负柱缩小暗示短期动量减弱但未明确反转信号,疑虑存在,优先风险控制。\\\"\\n}\\n```\"}},{\"json\":{\"output\":\"```json\\n{\\n  \\\"action\\\": \\\"NO_ACTION\\\",\\n  \\\"reasoning\\\": \\\"日线级别虽呈明显空头趋势(RSI<50, MACD为负, OBV下降),但小时线MACD负柱缩短,显示下跌动能减弱,可能存在短期反弹或盘整。多时间框架信号未完全统一,未出现高确定性入场点,故选择观望。\\\"\\n}\\n```\"}}]},\"connections\":{\"定时触发器\":{\"main\":[[{\"node\":\"策略初始化\",\"type\":\"main\",\"index\":0}]]},\"Claude4.5\":{\"ai_languageModel\":[[{\"node\":\"Claude\",\"type\":\"ai_languageModel\",\"index\":0}]]},\"DS3.1\":{\"ai_languageModel\":[[{\"node\":\"DeepSeek\",\"type\":\"ai_languageModel\",\"index\":0}]]},\"DeepSeek\":{\"main\":[[{\"node\":\"合并\",\"type\":\"main\",\"index\":0}]]},\"Claude\":{\"main\":[[{\"node\":\"合并\",\"type\":\"main\",\"index\":1}]]},\"QWEN\":{\"main\":[[{\"node\":\"合并\",\"type\":\"main\",\"index\":2}]]},\"OpenAI 模型\":{\"ai_languageModel\":[[{\"node\":\"QWEN\",\"type\":\"ai_languageModel\",\"index\":0}]]},\"Grok\":{\"main\":[[{\"node\":\"合并\",\"type\":\"main\",\"index\":3}]]},\"Grok4\":{\"ai_languageModel\":[[{\"node\":\"Grok\",\"type\":\"ai_languageModel\",\"index\":0}]]},\"合并\":{\"main\":[[{\"node\":\"结果核算\",\"type\":\"main\",\"index\":0}]]},\"转换为文件\":{\"main\":[[{\"node\":\"写入文件到磁盘\",\"type\":\"main\",\"index\":0}]]},\"结果核算\":{\"main\":[[{\"node\":\"交易记录保存\",\"type\":\"main\",\"index\":0}]]},\"交易记录保存\":{\"main\":[[{\"node\":\"转换为文件\",\"type\":\"main\",\"index\":0},{\"node\":\"最优交易\",\"type\":\"main\",\"index\":0}]]},\"最优交易\":{\"main\":[[{\"node\":\"可视化\",\"type\":\"main\",\"index\":0}]]},\"策略初始化\":{\"main\":[[{\"node\":\"DS处理\",\"type\":\"main\",\"index\":0},{\"node\":\"Claude处理\",\"type\":\"main\",\"index\":0},{\"node\":\"QWEN处理\",\"type\":\"main\",\"index\":0},{\"node\":\"Grok处理\",\"type\":\"main\",\"index\":0}]]},\"DS处理\":{\"main\":[[{\"node\":\"DeepSeek\",\"type\":\"main\",\"index\":0}]]},\"Claude处理\":{\"main\":[[{\"node\":\"Claude\",\"type\":\"main\",\"index\":0}]]},\"QWEN处理\":{\"main\":[[{\"node\":\"QWEN\",\"type\":\"main\",\"index\":0}]]},\"Grok处理\":{\"main\":[[{\"node\":\"Grok\",\"type\":\"main\",\"index\":0}]]}},\"active\":false,\"settings\":{\"timezone\":\"Asia/Shanghai\",\"executionOrder\":\"v1\"},\"tags\":[],\"meta\":{\"templateCredsSetupCompleted\":true},\"credentials\":{},\"id\":\"6c8dfda8-4657-42fa-b4dc-8f723e88aaa7\",\"plugins\":{},\"mcpClients\":{}},\"startNodes\":[],\"triggerToStartFrom\":{\"name\":\"定时触发器\"}}"}