AlphaArena Replica Trading System


创建日期: 2025-10-22 17:26:45 最后修改: 2025-10-23 17:05:05
复制: 0 点击次数: 393
avatar of ianzeng123 ianzeng123
2
关注
327
关注者
策略源码
{"type":"n8n","content":"{\"workflowData\":{\"nodes\":[{\"parameters\":{\"notice\":\"\",\"rule\":{\"interval\":[{\"field\":\"minutes\",\"minutesInterval\":3}]}},\"type\":\"n8n-nodes-base.scheduleTrigger\",\"typeVersion\":1.2,\"position\":[-960,240],\"id\":\"364a6896-f44e-4523-8ac1-2cacc8ae035b\",\"name\":\"Scheduled Trigger\"},{\"parameters\":{\"mode\":\"append\",\"numberInputs\":2},\"type\":\"n8n-nodes-base.merge\",\"typeVersion\":3.2,\"position\":[-288,240],\"id\":\"ce8a4ce1-57de-4834-a1fe-3092c610b00b\",\"name\":\"Merge\"},{\"parameters\":{\"text\":\"=It has been {{ $node[\\\"Parameter Reset\\\"].json.duringtime }} minutes since you started trading. The current time is {{ $now.toISO() }} and you've been invoked {{ $node[\\\"Parameter Reset\\\"].json.invoketime }} times. Below, we are providing you with a variety of state data, price data, and predictive signals so you can discover alpha. Below that is your current account information, value, performance, positions, etc.\\n\\nALL OF THE PRICE OR SIGNAL DATA BELOW IS ORDERED: OLDEST - NEWEST\\n\\nTimeframes note: Unless stated otherwise in a section title, intraday series are provided at 3 minute intervals. If a coin uses a different interval, it is explicitly stated in that coin's section.\\n\\n**CURRENT MARKET STATE FOR ALL COINS**\\n\\n{{JSON.stringify($json.marketData)}}\\n\\n**HERE IS YOUR ACCOUNT INFORMATION & PERFORMANCE**  \\nCurrent Total Return (percent): {{ $node[\\\"Parameter Reset\\\"].json.totalReturnPercent }}  \\nAvailable Cash: {{ $node[\\\"Parameter Reset\\\"].json.availableCash }}\\nCurrent Account Value: {{ $node[\\\"Parameter Reset\\\"].json.currentAccountValue }}\\n\\nCurrent live positions & performance:  \\n\\n{{JSON.stringify($json.positions)}}\",\"options\":{\"systemMessage\":\"=You are an expert cryptocurrency swing trader managing a live perpetual futures portfolio. You make trading decisions every 3 minutes based on technical analysis and risk management principles.\\n\\n## HARD CONSTRAINTS\\n\\n### Position Limits\\n- Tradable coins: {{$vars.coinList}}\\n- Maximum 6 concurrent positions\\n- No pyramiding or adding to existing positions\\n- Must be flat before re-entering a coin\\n\\n### Risk Management\\n- Maximum risk per trade: 5% of account value\\n- Leverage range: 5x to 40x\\n- Minimum risk-reward ratio: 2:1\\n- Every position must have:\\n  - Stop loss (specific price level)\\n  - Profit target (specific price level)  \\n  - Invalidation condition (format: \\\"If price closes below/above [PRICE] on a [TIMEFRAME] candle\\\")\\n\\n### Position Sizing\\nPosition size will be calculated automatically by the trading system based on your stop loss and leverage.\\nYou only need to specify:\\n- risk_usd: Amount in USD you're willing to risk on this trade\\n- stop_loss: Price level where the trade is invalidated\\n- leverage: Multiplier for position size (5x to 40x)\\n\\n## DECISION FRAMEWORK\\n\\n### **Identifying Position Status**\\n\\nA coin has an **active position** if `quantity` is NOT null.\\nA coin has **no position** if `quantity` is null.\\n\\n### **For Coins WITH Active Positions**\\n\\nCheck each position in this order:\\n\\n1. **Invalidation condition triggered?** → Close immediately\\n2. **Stop loss or profit target hit?** → Close\\n3. **Technical setup still valid?** → Hold\\n4. **If uncertain** → Hold (trust your exit plan)\\n\\n**Available signals: \\\"hold\\\" or \\\"close\\\" ONLY**\\n- Use \\\"hold\\\" to maintain the position\\n- Use \\\"close\\\" to exit the position\\n\\n### **For Coins WITHOUT Positions**\\n\\nOnly consider if:\\n- Current active positions < 6\\n- Available cash > $1000  \\n- You see a high-probability setup\\n\\n**Available signal: \\\"entry\\\" ONLY**\\n- Use \\\"entry\\\" to open a new position\\n- If no good setup exists, simply don't include this coin in your output\\n\\nConsider:\\n- Trend direction and strength\\n- Entry/exit levels with logical risk-reward\\n- Current volatility (adjust leverage accordingly)\\n- Market sentiment (funding rate, open interest)\\n\\n## OUTPUT FORMAT\\n\\n**Output ONLY valid JSON. No other text.**\\n\\n**ALL signals must include the SAME fields. Use null for fields not applicable to the signal type.**\\n\\n### Standard Output Structure (All Signals)\\n```json\\n{\\n  \\\"COIN\\\": {\\n    \\\"trade_signal_args\\\": {\\n      \\\"coin\\\": \\\"COIN\\\",\\n      \\\"signal\\\": \\\"hold|close|entry\\\",\\n      \\\"profit_target\\\": 115000.0,\\n      \\\"stop_loss\\\": 112000.0,\\n      \\\"invalidation_condition\\\": \\\"If the price closes below 112500 on a 3-minute candle\\\",\\n      \\\"leverage\\\": 15,\\n      \\\"confidence\\\": 0.75,\\n      \\\"risk_usd\\\": 624.38,\\n      \\\"justification\\\": \\\"Reason for this decision\\\"\\n    }\\n  }\\n}\\n```\\n\\n### For Coins WITH Positions - Hold Signal\\n```json\\n{\\n  \\\"BTC\\\": {\\n    \\\"trade_signal_args\\\": {\\n      \\\"coin\\\": \\\"BTC\\\",\\n      \\\"signal\\\": \\\"hold\\\",\\n      \\\"profit_target\\\": 115000.0,\\n      \\\"stop_loss\\\": 112000.0,\\n      \\\"invalidation_condition\\\": \\\"If the price closes below 112500 on a 3-minute candle\\\",\\n      \\\"leverage\\\": 15,\\n      \\\"confidence\\\": 0.75,\\n      \\\"risk_usd\\\": 624.38,\\n      \\\"justification\\\": \\\"Position still valid, price above EMA20 with bullish momentum\\\"\\n    }\\n  }\\n}\\n```\\n\\n### For Coins WITH Positions - Close Signal\\n```json\\n{\\n  \\\"BTC\\\": {\\n    \\\"trade_signal_args\\\": {\\n      \\\"coin\\\": \\\"BTC\\\",\\n      \\\"signal\\\": \\\"close\\\",\\n      \\\"profit_target\\\": null,\\n      \\\"stop_loss\\\": null,\\n      \\\"invalidation_condition\\\": null,\\n      \\\"leverage\\\": null,\\n      \\\"confidence\\\": null,\\n      \\\"risk_usd\\\": 624.38,\\n      \\\"justification\\\": \\\"Invalidation triggered: price closed below 112500\\\"\\n    }\\n  }\\n}\\n```\\n\\n### For Coins WITHOUT Positions - Entry Signal\\n```json\\n{\\n  \\\"BTC\\\": {\\n    \\\"trade_signal_args\\\": {\\n      \\\"coin\\\": \\\"BTC\\\",\\n      \\\"signal\\\": \\\"entry\\\",\\n      \\\"profit_target\\\": 115000.0,\\n      \\\"stop_loss\\\": 112000.0,\\n      \\\"invalidation_condition\\\": \\\"If the price closes below 111800 on a 3-minute candle\\\",\\n      \\\"leverage\\\": 15,\\n      \\\"confidence\\\": 0.75,\\n      \\\"risk_usd\\\": 624.38,\\n      \\\"justification\\\": \\\"Bullish breakout above EMA20 with MACD turning positive, RSI 63\\\"\\n    }\\n  }\\n}\\n```\\n\\n## THINKING PROCESS\\n\\nBefore outputting JSON, think through your decisions step by step:\\n\\n1. **Identify position status for each coin:**\\n   - Check if `quantity` is null → no position\\n   - Check if `quantity` has a value → active position\\n\\n2. **Review coins WITH active positions:**\\n   - Check P&L, technicals, exit conditions\\n   - Decide: \\\"hold\\\" or \\\"close\\\" for each\\n   \\n3. **Review coins WITHOUT positions:**\\n   - If capacity available (< 6 active positions, > $1000 cash)\\n   - Scan for new entry opportunities\\n   - Decide: \\\"entry\\\" or skip\\n\\n4. Output final decisions in JSON with **consistent field structure**\\n\\nYour reasoning will be logged for audit but not shown to users.\\n\\n## CRITICAL RULES\\n\\n- **MUST check `quantity` field to determine if position exists**\\n- **Coins WITH positions** (quantity ≠ null): Only use \\\"hold\\\" or \\\"close\\\"\\n- **Coins WITHOUT positions** (quantity = null): Only use \\\"entry\\\" (or omit from output)\\n- **NEVER** use \\\"entry\\\" for a coin that has `quantity` ≠ null\\n- **NEVER** use \\\"hold\\\" or \\\"close\\\" for a coin that has `quantity` = null\\n- **ALL outputs must have identical field structure** - use null for non-applicable fields\\n\\n## FIELD REQUIREMENTS BY SIGNAL TYPE\\n\\n### \\\"entry\\\" signal:\\n- coin: required (string)\\n- signal: \\\"entry\\\"\\n- profit_target: required (number)\\n- stop_loss: required (number)\\n- invalidation_condition: required (string)\\n- leverage: required (number, 5-40)\\n- confidence: required (number, 0-1)\\n- justification: required (string)\\n\\n### \\\"hold\\\" signal:\\n- coin: required (string)\\n- signal: \\\"hold\\\"\\n- profit_target: required (number, from original entry)\\n- stop_loss: required (number, from original entry)\\n- invalidation_condition: required (string, from original entry)\\n- leverage: required (number, from original entry)\\n- confidence: required (number, from original entry)\\n- justification: required (string, explain why holding)\\n\\n### \\\"close\\\" signal:\\n- coin: required (string)\\n- signal: \\\"close\\\"\\n- profit_target: null\\n- stop_loss: null\\n- invalidation_condition: null\\n- leverage: null\\n- confidence: null\\n- justification: required (string, explain why closing)\\n\\n## ADDITIONAL NOTES\\n\\n- You receive data every 3 minutes. Be patient, don't overreact.\\n- Trust your exit plan. Don't close prematurely unless invalidation hits.\\n- Quality over quantity. No trade is better than a bad trade.\\n- The market data provided is comprehensive. Use what you find relevant.\\n- Current timestamp and account state will be provided in each user message.\\n- Position sizing is handled automatically - you just specify stop_loss and leverage\\n- **Always return the same field structure for all coins, using null for non-applicable fields**\\n\\n## FORBIDDEN\\n\\n- Never output anything except valid JSON\\n- Never violate position limits or risk rules\\n- Never use \\\"entry\\\" for coins that have active positions (quantity ≠ null)\\n- Never use \\\"hold\\\"/\\\"close\\\" for coins without positions (quantity = null)\\n- Never omit required fields from your output\\n- Never return inconsistent field structures between different coins\\n\\n---\\n\\n**Now begin trading. Your next message will contain current market data and account status.**\"}},\"type\":\"@n8n/n8n-nodes-langchain.agent\",\"typeVersion\":1,\"position\":[160,240],\"id\":\"c665ada6-6984-4d54-8c34-afd059432433\",\"name\":\"AI Agent\"},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"api_base = \\\"https://testnet.binancefuture.com\\\"\\nexchange.SetBase(api_base)\\n\\n// Initialize check\\nif (_G('invoketime') === null) {\\n  _G('invoketime', 0);\\n  _G('STARTTIME', Date.now());\\n  const initAccount = exchange.GetAccount();\\n  _G('initmoney', initAccount.Equity);\\n}\\n\\n// Loop execution\\nconst invoketime = _G('invoketime') + 1;\\n_G('invoketime', invoketime);\\n\\nconst duringtime = Math.floor((Date.now() - _G('STARTTIME')) / 60000); // Convert to minutes\\nconst currentAccount = exchange.GetAccount();\\nconst currentAccountValue = currentAccount.Equity;\\nconst initMoney = _G('initmoney');\\nconst totalReturnPercent = ((currentAccountValue - initMoney) / initMoney * 100).toFixed(2);\\n\\nLogProfit(currentAccountValue - initMoney, \\\"&\\\")\\n\\n// Return 5 data points\\nreturn [{\\n  json: {\\n    invoketime: invoketime,\\n    duringtime: duringtime, // Add unit\\n    totalReturnPercent: totalReturnPercent + '%',\\n    availableCash: currentAccount.Balance.toFixed(2),\\n    currentAccountValue: currentAccountValue.toFixed(2)\\n  }\\n}];\\n\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[-736,240],\"id\":\"cf3d3e78-9481-44a3-8058-8f4fbcb46e1a\",\"name\":\"Parameter Reset\"},{\"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\":[256,464],\"id\":\"293303bc-40a4-44a8-a76b-6529b2b02f03\",\"name\":\"OpenAI Model\",\"credentials\":{\"openAiApi\":{\"id\":\"54d0b567-b3fc-4c6a-b6be-546e0b9cd83f\",\"name\":\"openrouter\"}}},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"// Parse coin list\\nconst coins = $vars.coinList ? ($vars.coinList.includes(',') ? $vars.coinList.split(',') : [$vars.coinList]) : [];\\n\\nif (coins.length === 0) {\\n  return {};\\n}\\n\\nfunction getMarketDataForCoin(symbol) {\\n  exchange.SetCurrency(symbol + \\\"_USDT\\\");\\n  exchange.SetContractType(\\\"swap\\\");\\n  \\n  const kline3m = exchange.GetRecords(60 * 3);\\n  const kline4h = exchange.GetRecords(60 * 60 * 4);\\n  \\n  if (!kline3m || kline3m.length < 50 || !kline4h || kline4h.length < 50) {\\n    return { error: \\\"Insufficient K-line data\\\" };\\n  }\\n  \\n  const ema20_3m = TA.EMA(kline3m, 20);\\n  const macd_3m = TA.MACD(kline3m, 12, 26, 9);\\n  const rsi7_3m = TA.RSI(kline3m, 7);\\n  const rsi14_3m = TA.RSI(kline3m, 14);\\n  \\n  const ema20_4h = TA.EMA(kline4h, 20);\\n  const ema50_4h = TA.EMA(kline4h, 50);\\n  const macd_4h = TA.MACD(kline4h, 12, 26, 9);\\n  const rsi14_4h = TA.RSI(kline4h, 14);\\n  const atr3_4h = TA.ATR(kline4h, 3);\\n  const atr14_4h = TA.ATR(kline4h, 14);\\n  \\n  const latest3m = kline3m[kline3m.length - 1];\\n  const latest4h = kline4h[kline4h.length - 1];\\n  const recent10_3m = kline3m.slice(-10);\\n  const recent10_4h = kline4h.slice(-10);\\n  \\n  let fundingRate = null;\\n  //try {\\n    //const fundings = exchange.GetFundings();\\n    //if (fundings && fundings.length > 0) {\\n      //fundingRate = fundings[fundings.length - 1].Rate;\\n    //}\\n  //} catch (e) {}\\n  \\n  const volumes4h = recent10_4h.map(k => k.Volume);\\n  const avgVolume4h = volumes4h.reduce((a, b) => a + b, 0) / volumes4h.length;\\n  \\n  return {\\n    symbol: symbol,\\n    current_price: latest3m.Close,\\n    current_ema20: ema20_3m[ema20_3m.length - 1],\\n    current_macd: macd_3m[2][macd_3m[2].length - 1],\\n    current_rsi_7: rsi7_3m[rsi7_3m.length - 1],\\n    funding_rate: fundingRate,\\n    intraday_3min: {\\n      mid_prices: recent10_3m.map(k => k.Close),\\n      ema_20_series: recent10_3m.map((k, i) => ema20_3m[ema20_3m.length - 10 + i]),\\n      macd_series: recent10_3m.map((k, i) => macd_3m[2][macd_3m[2].length - 10 + i]),\\n      rsi_7_series: recent10_3m.map((k, i) => rsi7_3m[rsi7_3m.length - 10 + i]),\\n      rsi_14_series: recent10_3m.map((k, i) => rsi14_3m[rsi14_3m.length - 10 + i])\\n    },\\n    longer_term_4hour: {\\n      ema_20: ema20_4h[ema20_4h.length - 1],\\n      ema_50: ema50_4h[ema50_4h.length - 1],\\n      atr_3: atr3_4h[atr3_4h.length - 1],\\n      atr_14: atr14_4h[atr14_4h.length - 1],\\n      current_volume: latest4h.Volume,\\n      average_volume: avgVolume4h,\\n      macd_series: recent10_4h.map((k, i) => macd_4h[2][macd_4h[2].length - 10 + i]),\\n      rsi_14_series: recent10_4h.map((k, i) => rsi14_4h[rsi14_4h.length - 10 + i])\\n    }\\n  };\\n}\\n\\nconst allCoinsData = {};\\nfor (let i = 0; i < coins.length; i++) {\\n  const coin = coins[i].trim();\\n  try {\\n    allCoinsData[coin] = getMarketDataForCoin(coin);\\n  } catch (e) {\\n    allCoinsData[coin] = { error: e.toString() };\\n  }\\n}\\n\\nreturn { data: allCoinsData };\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[-512,144],\"id\":\"1bd794fb-7dfa-41a5-899b-a7921ab423ad\",\"name\":\"Market Data Fetch\"},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"function getTPSLOrderIds(symbol, currentPrice, posType) {\\n    try {\\n        // Get pending orders for this trading pair\\n        const cleanSymbol = symbol.replace('.swap', '').replace('_USDT', '');\\n        exchange.SetCurrency(cleanSymbol + \\\"_USDT\\\");\\n        exchange.SetContractType(\\\"swap\\\");\\n        \\n        const orders = exchange.GetOrders();\\n        \\n        if (!orders || orders.length === 0) {\\n            return { tpOrderId: -1, slOrderId: -1 };\\n        }\\n        \\n        let tpOrderId = -1;\\n        let slOrderId = -1;\\n        \\n        for (let order of orders) {\\n            // Long position (Type = 0 or PD_LONG)\\n            if (posType === 0 || posType === PD_LONG) {\\n                // take profit:卖单price > current price\\n                if (order.Type === ORDER_TYPE_SELL && order.Price > currentPrice) {\\n                    tpOrderId = order.Id;\\n                }\\n                // stop loss:卖单price < current price\\n                if (order.Type === ORDER_TYPE_SELL && order.Price < currentPrice) {\\n                    slOrderId = order.Id;\\n                }\\n            } \\n            // Short position\\n            else {\\n                // take profit:买单price < current price\\n                if (order.Type === ORDER_TYPE_BUY && order.Price < currentPrice) {\\n                    tpOrderId = order.Id;\\n                }\\n                // stop loss:买单price > current price\\n                if (order.Type === ORDER_TYPE_BUY && order.Price > currentPrice) {\\n                    slOrderId = order.Id;\\n                }\\n            }\\n        }\\n        \\n        return { tpOrderId, slOrderId };\\n        \\n    } catch (e) {\\n        Log(`⚠️ Get ${symbol} Order failed: ${e.message}`);\\n        return { tpOrderId: -1, slOrderId: -1 };\\n    }\\n}\\n\\nfunction getAllPositions() {\\n    // Get current account equity\\n    const curequity = exchange.GetAccount().Equity;\\n    \\n    // Get coin list\\n    const coins = $vars.coinList ? ($vars.coinList.includes(',') ? $vars.coinList.split(',') : [$vars.coinList]) : [];\\n    \\n    // 计算每个coin的risk_usd\\n    const risk_usd = coins.length > 0 ? curequity / coins.length : 0;\\n    \\n    // Set a default trading pair first to get all positions\\n    if (coins.length > 0) {\\n        exchange.SetCurrency(coins[0].trim() + \\\"_USDT\\\");\\n        exchange.SetContractType(\\\"swap\\\");\\n    }\\n    \\n    // Get all actual positions\\n    const rawPositions = exchange.GetPositions();\\n    \\n    // Create position mapping table (coinsymbol -> Position对象)\\n    const positionMap = {};\\n    \\n    if (rawPositions && rawPositions.length > 0) {\\n        for (let pos of rawPositions) {\\n            if (pos.Amount && Math.abs(pos.Amount) > 0) {\\n                // 提取coinsymbol (if BTC_USDT.swap -> BTC)\\n                const coinSymbol = pos.Symbol.replace('_USDT.swap', '').replace('.swap', '').replace('_USDT', '');\\n                positionMap[coinSymbol] = pos;\\n            }\\n        }\\n    }\\n    \\n    // 为每个coin创建positionInfo\\n    const allPositions = [];\\n    \\n    for (let i = 0; i < coins.length; i++) {\\n        const coin = coins[i].trim();\\n        const pos = positionMap[coin];\\n        \\n        if (pos) {\\n            // Has position case\\n            try {\\n                // 切换到对应Trading对Getticker\\n                exchange.SetCurrency(coin + \\\"_USDT\\\");\\n                exchange.SetContractType(\\\"swap\\\");\\n                \\n                const ticker = exchange.GetTicker();\\n                const currentPrice = ticker ? ticker.Last : pos.Price;\\n                \\n                // Gettake profitstop loss订单ID\\n                const { tpOrderId, slOrderId } = getTPSLOrderIds(pos.Symbol, currentPrice, pos.Type);\\n                \\n                // Getexit plan\\n                const exitPlan = _G(`exit_plan_${pos.Symbol}`) || {\\n                    profit_target: null,\\n                    stop_loss: null,\\n                    invalidation_condition: \\\"\\\"\\n                };\\n                \\n                allPositions.push({\\n                    symbol: coin,\\n                    quantity: Math.abs(pos.Amount),\\n                    entry_price: pos.Price,\\n                    current_price: currentPrice,\\n                    liquidation_price: pos.Info?.liqPx ? parseFloat(pos.Info.liqPx) : \\n                        (pos.MarginLevel > 1 ? (pos.Type === 0 ? \\n                            pos.Price * (1 - 0.9/pos.MarginLevel) : \\n                            pos.Price * (1 + 0.9/pos.MarginLevel)) : 0),\\n                    unrealized_pnl: _N(pos.Profit, 2),\\n                    leverage: pos.MarginLevel || 1,\\n                    exit_plan: exitPlan,\\n                    confidence: exitPlan?.confidence || null,\\n                    risk_usd: risk_usd,  // 使用计算出的risk_usd\\n                    sl_oid: slOrderId,      \\n                    tp_oid: tpOrderId,      \\n                    wait_for_fill: false,\\n                    entry_oid: pos.Info?.posId || -1,\\n                    notional_usd: _N(Math.abs(pos.Amount) * currentPrice, 2)\\n                });\\n            } catch (e) {\\n                Log(`⚠️ Processing ${coin} PositionInfo失败: ${e.message}`);\\n                // Add empty position record on error\\n                allPositions.push({\\n                    symbol: coin,\\n                    quantity: null,\\n                    entry_price: null,\\n                    current_price: null,\\n                    liquidation_price: null,\\n                    unrealized_pnl: null,\\n                    leverage: null,\\n                    exit_plan: null,\\n                    confidence: null,\\n                    risk_usd: risk_usd,\\n                    sl_oid: null,\\n                    tp_oid: null,\\n                    wait_for_fill: false,\\n                    entry_oid: null,\\n                    notional_usd: null\\n                });\\n            }\\n        } else {\\n            // No position case - 返回固定字段为null\\n            allPositions.push({\\n                symbol: coin,\\n                quantity: null,\\n                entry_price: null,\\n                current_price: null,\\n                liquidation_price: null,\\n                unrealized_pnl: null,\\n                leverage: null,\\n                exit_plan: null,\\n                confidence: null,\\n                risk_usd: risk_usd,  // 仍然返回risk_usd\\n                sl_oid: null,\\n                tp_oid: null,\\n                wait_for_fill: false,\\n                entry_oid: null,\\n                notional_usd: null\\n            });\\n        }\\n    }\\n    \\n    return allPositions;\\n}\\n\\nconst positions = getAllPositions();\\nreturn {positions};\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[-512,336],\"id\":\"7341b898-f760-42bf-bfd9-b0e116807512\",\"name\":\"Position Data Fetch\"},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"// Get input data\\nconst inputData = $input.all();\\n\\n// First input is market data, second is position data\\nconst marketData = inputData[0].json.data;\\nconst positions = inputData[1].json;\\n\\n// Return organized data\\nreturn [{\\n  json: {\\n    marketData: marketData,\\n    positions: positions\\n  }\\n}];\\n\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[-64,240],\"id\":\"a2495073-4c87-4a4a-a383-ea166fe7571d\",\"name\":\"Data Merge\"},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"// ========== Utility Functions ==========\\n\\nfunction parseAIOutput(output) {\\n    try {\\n        const cleaned = output.replace(/```[a-z]*\\\\n?/gi, '').trim();\\n        const start = cleaned.indexOf('{');\\n        const end = cleaned.lastIndexOf('}');\\n        return JSON.parse(cleaned.substring(start, end + 1));\\n    } catch (e) {\\n        return {};\\n    }\\n}\\n\\n// GetTrading precision info\\nfunction getPrecision(coin) {\\n    try {\\n        const symbol = coin + '_USDT.swap';\\n        const markets = exchange.GetMarkets();\\n        Log(markets[symbol]);\\n        \\n        if (markets && markets[symbol]) {\\n            return {\\n                price: markets[symbol].PricePrecision || 0,\\n                amount: markets[symbol].AmountPrecision || 0,\\n                minQty: markets[symbol].MinQty || 5\\n            };\\n        }\\n        \\n        // Default precision\\n        return { price: 0, amount: 0, minQty: 5 };\\n    } catch (e) {\\n        Log(`⚠️ Get${coin}Precision fetch failed, using default values`);\\n        return { price: 0, amount: 0, minQty: 5 };\\n    }\\n}\\n\\nfunction calculateQuantity(entryPrice, stopLoss, riskUsd, leverage, precision) {\\n    const riskPerContract = Math.abs(entryPrice - stopLoss);\\n    if (riskPerContract <= 0) return 0;\\n    \\n    const quantity = riskUsd / riskPerContract;\\n    const maxQuantity = (exchange.GetAccount().Balance * leverage / 6) / entryPrice;\\n    \\n    let finalQuantity = Math.min(quantity, maxQuantity);\\n    \\n    // Apply precision and minimum quantity constraint\\n    if (precision) {\\n        finalQuantity = _N(finalQuantity, precision.amount);\\n        \\n        if (finalQuantity < precision.minQty) {\\n            Log(`⚠️ Calculated quantity ${finalQuantity} is below minimum order size ${precision.minQty}`);\\n            return 0;\\n        }\\n    }\\n    \\n    return finalQuantity;\\n}\\n\\nfunction validateEntry(coin, currentPrice, profitTarget, stopLoss) {\\n    const isLong = profitTarget > stopLoss;\\n    \\n    if (isLong && (profitTarget <= currentPrice || stopLoss >= currentPrice)) return false;\\n    if (!isLong && (profitTarget >= currentPrice || stopLoss <= currentPrice)) return false;\\n    \\n    return true;\\n}\\n\\nfunction hasPosition(coin) {\\n    try {\\n        exchange.SetCurrency(coin + '_USDT');\\n        exchange.SetContractType(\\\"swap\\\");\\n        return exchange.GetPositions().some(p => p.Symbol.includes(coin) && Math.abs(p.Amount) > 0);\\n    } catch (e) {\\n        return false;\\n    }\\n}\\n\\nfunction saveExitPlan(symbol, args) {\\n    _G(`exit_plan_${symbol}.swap`, {\\n        profit_target: args.profit_target,\\n        stop_loss: args.stop_loss,\\n        invalidation_condition: args.invalidation_condition || \\\"\\\",\\n        confidence: args.confidence,\\n        risk_usd: args.risk_usd\\n    });\\n}\\n\\n// ========== Trading Execution ==========\\n\\nfunction executeClose(coin) {\\n    exchange.SetCurrency(coin + '_USDT');\\n    exchange.SetContractType(\\\"swap\\\");\\n    \\n    const orders = exchange.GetOrders();\\n    orders?.forEach(o => exchange.CancelOrder(o.Id));\\n    \\n    const pos = exchange.GetPositions().find(p => p.Symbol.includes(coin) && Math.abs(p.Amount) > 0);\\n    if (!pos) return;\\n    \\n    const isLong = pos.Type === PD_LONG || pos.Type === 0;\\n    const precision = getPrecision(coin);\\n\\n    const closeAmount = _N(Math.abs(pos.Amount), precision.amount);\\n    \\n    exchange.SetDirection(isLong ? \\\"closebuy\\\" : \\\"closesell\\\");\\n    \\n    const orderId = isLong ? exchange.Sell(-1, closeAmount) : exchange.Buy(-1, closeAmount);\\n    \\n    if (orderId) {\\n        Log(`✅ ${coin}: Close ${isLong ? 'Long' : 'Short'} success, quantity=${closeAmount}`);\\n        _G(`exit_plan_${coin}_USDT.swap`, null);\\n    }\\n}\\n\\nfunction executeEntry(coin, args) {\\n    exchange.SetCurrency(coin + '_USDT');\\n    exchange.SetContractType(\\\"swap\\\");\\n    \\n    const ticker = exchange.GetTicker();\\n    if (!ticker) return;\\n    \\n    const currentPrice = ticker.Last;\\n    if (!validateEntry(coin, currentPrice, args.profit_target, args.stop_loss)) return;\\n    \\n    const leverage = args.leverage || 10;\\n    exchange.SetMarginLevel(leverage);\\n    \\n    precision = getPrecision(coin);\\n    quantity = calculateQuantity(currentPrice, args.stop_loss, args.risk_usd, leverage, precision);\\n    \\n    if (quantity <= 0) {\\n        Log(`⚠️ ${coin}: Invalid calculated quantity, skipping entry`);\\n        return;\\n    }\\n    \\n    const isLong = args.profit_target > args.stop_loss;\\n    exchange.SetDirection(isLong ? \\\"buy\\\" : \\\"sell\\\");\\n    \\n    const orderId = isLong ? exchange.Buy(-1, quantity) : exchange.Sell(-1, quantity);\\n    \\n    if (orderId) {\\n        Sleep(1000);\\n        Log(`✅ ${coin}: Open ${isLong ? 'Long' : 'Short'} position, quantity=${quantity}, leverage=${leverage}x, precision=${precision.amount}`);\\n    } else {\\n        Log(`❌ ${coin}: Failed to open position`, precision.amount);\\n    }\\n}\\n\\n// ========== Take-Profit & Stop-Loss Monitor ==========\\n\\nfunction monitorPosition(coin) {\\n    exchange.SetCurrency(coin + '_USDT');\\n    exchange.SetContractType(\\\"swap\\\");\\n    \\n    const pos = exchange.GetPositions().find(p => p.Symbol.includes(coin) && Math.abs(p.Amount) > 0);\\n    if (!pos) return;\\n    \\n    const ticker = exchange.GetTicker();\\n    if (!ticker) return;\\n    \\n    const isLong = pos.Type === PD_LONG || pos.Type === 0;\\n    const currentPrice = ticker.Last;\\n    const pnl = (currentPrice - pos.Price) * (isLong ? 1 : -1) / pos.Price;\\n    \\n    const exitPlan = _G(`exit_plan_${coin}_USDT.swap`);\\n    if (!exitPlan?.profit_target || !exitPlan?.stop_loss) {\\n        if (pnl >= 0.03) return closePosition(coin, pos, isLong, \\\"take profit\\\", pnl);\\n        if (pnl <= -0.01) return closePosition(coin, pos, isLong, \\\"stop loss\\\", pnl);\\n        return;\\n    }\\n    \\n    const shouldTP = isLong ? currentPrice >= exitPlan.profit_target : currentPrice <= exitPlan.profit_target;\\n    const shouldSL = isLong ? currentPrice <= exitPlan.stop_loss : currentPrice >= exitPlan.stop_loss;\\n    \\n    if (shouldTP) return closePosition(coin, pos, isLong, \\\"take profit\\\", pnl);\\n    if (shouldSL) return closePosition(coin, pos, isLong, \\\"stop loss\\\", pnl);\\n}\\n\\nfunction closePosition(coin, pos, isLong, reason, pnl) {\\n    const precision = getPrecision(coin);\\n    const closeAmount = _N(Math.abs(pos.Amount), precision.amount);\\n    \\n    exchange.SetDirection(isLong ? \\\"closebuy\\\" : \\\"closesell\\\");\\n    isLong ? exchange.Sell(-1, closeAmount) : exchange.Buy(-1, closeAmount);\\n    \\n    Log(`${reason === 'take profit' ? '✅' : '❌'} ${coin} ${reason} ${(pnl*100).toFixed(2)}%`);\\n    _G(`exit_plan_${coin}_USDT.swap`, null);\\n}\\n\\n// ========== Signal Processing ==========\\n\\nconst signals = parseAIOutput($input.first().json.output);\\nLog(signals);\\n\\nconst signalTable = {\\n    type: \\\"table\\\",\\n    title: \\\"📊 AI Trading Signal Analysis\\\",\\n    cols: [\\\"Coin\\\", \\\"Signal\\\", \\\"Take Profit\\\", \\\"Stop Loss\\\", \\\"Risk Amount\\\", \\\"Confidence\\\", \\\"Signal Rationale\\\"],\\n    rows: []\\n};\\n\\nfor (const [coin, data] of Object.entries(signals)) {\\n    const args = data?.trade_signal_args;\\n    if (!args?.coin || !args?.signal) continue;\\n    \\n    const hasPos = hasPosition(coin);\\n    let displaySignal = args.signal;\\n    let signalEmoji = \\\"⏸️\\\";\\n    \\n    if ((args.signal === \\\"hold\\\" && !hasPos) || (args.signal === \\\"close\\\" && !hasPos)) {\\n        displaySignal = \\\"No Action\\\";\\n        signalEmoji = \\\"⚪\\\";\\n    } else if (args.signal === \\\"entry\\\") {\\n        const isLong = args.profit_target > args.stop_loss;\\n        displaySignal = isLong ? \\\"Long Entry\\\" : \\\"Short Entry\\\";\\n        signalEmoji = isLong ? \\\"🟢\\\" : \\\"🔴\\\";\\n    } else if (args.signal === \\\"close\\\") {\\n        displaySignal = \\\"Close Position\\\";\\n        signalEmoji = \\\"⏹️\\\";\\n    } else if (args.signal === \\\"hold\\\") {\\n        displaySignal = \\\"Hold Position\\\";\\n        signalEmoji = \\\"⏸️\\\";\\n    }\\n    \\n    const confidence = args.confidence ? (args.confidence * 100).toFixed(0) : 0;\\n    let confidenceDisplay = \\\"-\\\";\\n    if (confidence >= 70) {\\n        confidenceDisplay = `🔥 ${confidence}%`;\\n    } else if (confidence >= 50) {\\n        confidenceDisplay = `⚡ ${confidence}%`;\\n    } else if (confidence > 0) {\\n        confidenceDisplay = `⚠️ ${confidence}%`;\\n    }\\n    \\n    signalTable.rows.push([\\n        `💎 ${coin}`,\\n        `${signalEmoji} ${displaySignal}`,\\n        args.profit_target ? `$${_N(args.profit_target, 2)}` : \\\"-\\\",\\n        args.stop_loss ? `$${_N(args.stop_loss, 2)}` : \\\"-\\\",\\n        args.risk_usd ? `💰 $${args.risk_usd}` : \\\"-\\\",\\n        confidenceDisplay,\\n        args.justification\\n    ]);\\n    \\n    if (args.signal === \\\"hold\\\" && !hasPos) continue;\\n    if (args.signal === \\\"close\\\" && !hasPos) continue;\\n    if (args.signal === \\\"entry\\\" && hasPos) continue;\\n    \\n    if (args.signal !== \\\"close\\\") saveExitPlan(coin + \\\"_USDT\\\", args);\\n    \\n    try {\\n        if (args.signal === \\\"close\\\") {\\n            executeClose(coin);\\n        } else if (args.signal === \\\"hold\\\") {\\n            Log(`⏸️ ${coin}: Holding position`);\\n        } else if (args.signal === \\\"entry\\\") {\\n            if (!args.profit_target || !args.stop_loss || !args.risk_usd) continue;\\n            executeEntry(coin, args);\\n        }\\n    } catch (e) {\\n        Log(`❌ ${coin} execution failed: ${e.message}`);\\n    }\\n}\\n\\n// ========== Position Table ==========\\n\\nconst positionTable = {\\n    type: \\\"table\\\",\\n    title: \\\"💼 Position Monitor\\\",\\n    cols: [\\\"Coin\\\", \\\"Direction\\\", \\\"Position Size\\\", \\\"Entry Price\\\", \\\"Current Price\\\", \\\"PnL\\\", \\\"Take Profit\\\", \\\"Stop Loss\\\"],\\n    rows: []\\n};\\n\\nconst positions = exchange.GetPositions();\\nlet totalPnl = 0;\\nlet positionCount = 0;\\n\\npositions?.forEach(pos => {\\n    if (Math.abs(pos.Amount) > 0) {\\n        const coinMatch = pos.Symbol.match(/^([A-Z0-9]+)_USDT/);\\n        if (!coinMatch) return;\\n        \\n        const coin = coinMatch[1];\\n        \\n        exchange.SetCurrency(coin + '_USDT');\\n        exchange.SetContractType(\\\"swap\\\");\\n        const ticker = exchange.GetTicker();\\n        \\n        if (ticker) {\\n            const isLong = pos.Type === PD_LONG || pos.Type === 0;\\n            const currentPrice = ticker.Last;\\n            const pnlPercent = ((currentPrice - pos.Price) * (isLong ? 1 : -1) / pos.Price * 100);\\n            \\n            let pnlDisplay = \\\"\\\";\\n            if (pnlPercent > 0) pnlDisplay = `🟢 +${pnlPercent.toFixed(2)}%`;\\n            else if (pnlPercent < 0) pnlDisplay = `🔴 ${pnlPercent.toFixed(2)}%`;\\n            else pnlDisplay = `⚪ ${pnlPercent.toFixed(2)}%`;\\n            \\n            const exitPlan = _G(`exit_plan_${coin}_USDT.swap`);\\n            \\n            positionTable.rows.push([\\n                `💎 ${coin}`,\\n                isLong ? \\\"📈 Long\\\" : \\\"📉 Short\\\",\\n                _N(Math.abs(pos.Amount), 4),\\n                `$${_N(pos.Price, 2)}`,\\n                `$${_N(currentPrice, 2)}`,\\n                pnlDisplay,\\n                exitPlan?.profit_target ? `🎯 $${_N(exitPlan.profit_target, 2)}` : \\\"-\\\",\\n                exitPlan?.stop_loss ? `🛡️ $${_N(exitPlan.stop_loss, 2)}` : \\\"-\\\"\\n            ]);\\n            \\n            totalPnl += pnlPercent;\\n            positionCount++;\\n        }\\n        \\n        monitorPosition(coin);\\n        Sleep(500);\\n    }\\n});\\n\\nif (positionCount > 0) {\\n    const avgPnl = totalPnl / positionCount;\\n    let summaryEmoji = avgPnl > 0 ? \\\"📊 ✅\\\" : \\\"📊 ⚠️\\\";\\n    positionTable.rows.push([\\n        `${summaryEmoji} Summary`,\\n        `${positionCount} Positions`,\\n        \\\"-\\\",\\n        \\\"-\\\",\\n        \\\"-\\\",\\n        `Avg PnL: ${avgPnl > 0 ? '🟢' : '🔴'} ${_N(avgPnl, 2)}%`,\\n        \\\"-\\\",\\n        \\\"-\\\"\\n    ]);\\n}\\n\\nLogStatus('`' + JSON.stringify(signalTable) + '`\\\\n\\\\n' + '`' + JSON.stringify(positionTable) + '`');\\n\\nreturn { json: { processed: true } };\\n\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[560,240],\"id\":\"50db6dff-d213-42b1-970f-7edfc2ccf941\",\"name\":\"Trade Execution\"}],\"pinData\":{\"Merge\":[{\"json\":{\"data\":{\"BTC\":{\"symbol\":\"BTC\",\"current_price\":68069.8,\"current_ema20\":67393.20768448278,\"current_macd\":-141.8746193326781,\"current_rsi_7\":52.9288508745507,\"funding_rate\":0.0001,\"intraday_3min\":{\"mid_prices\":[67401.5,67165,69000,68407.8,68407.8,68684.9,68000,68357.1,68357.1,68069.8],\"ema_20_series\":[66099.34513443054,66200.83607400858,66467.42311457919,66652.22091319069,66819.41892145824,66997.08378608126,67092.59961597828,67213.02822398035,67321.98744074412,67393.20768448278],\"macd_series\":[-16.006824143769336,-69.58634083226798,6.014428448218268,3.707839368757277,-9.524287806496204,-11.205098203412263,-66.92471007867698,-86.94334103845972,-106.12700537746468,-141.8746193326781],\"rsi_7_series\":[57.14410668829288,54.207644432645544,68.7458859824149,61.40570539580122,61.40570539580122,63.86308795698043,53.95636962106131,57.926443593044496,57.926443593044496,52.9288508745507],\"rsi_14_series\":[58.98762063421963,57.676203920952986,64.30683032953367,60.98621445168773,60.98621445168773,62.04965866463078,57.85215138839635,59.39450596680049,59.39450596680049,57.4334549132294]},\"longer_term_4hour\":{\"ema_20\":66871.44523500973,\"ema_50\":64970.7337867347,\"atr_3\":345.79619599383733,\"atr_14\":690.0169061870516,\"current_volume\":35313.164,\"average_volume\":56951.986600000004,\"macd_series\":[426.0422367703495,341.32338737725445,260.18265336934655,169.8522577312142,172.51557125237014,153.6201343155467,139.53636356513493,90.28541005679085,42.28781555063165,-20.839281898691752],\"rsi_14_series\":[69.17666213847178,65.3120733492065,65.31207334920651,63.457829989520924,68.51624611516007,68.51624611516007,69.60426762048942,66.66910153972526,66.66910153972526,63.92885413247647]}},\"ETH\":{\"symbol\":\"ETH\",\"current_price\":2634.53,\"current_ema20\":2614.9296147421305,\"current_macd\":-4.165490433707042,\"current_rsi_7\":51.36232275243974,\"funding_rate\":0.0001,\"intraday_3min\":{\"mid_prices\":[2605.01,2595.61,2675.12,2641.11,2641.11,2630.05,2662.66,2647.45,2647.46,2634.53],\"ema_20_series\":[2574.4757662073725,2576.488550378099,2585.8820217706607,2591.1418292210737,2595.9007026285904,2599.1530166639627,2605.201300791204,2609.224986430137,2612.8664162939335,2614.9296147421305],\"macd_series\":[-4.185711424410172,-5.722140318309414,-1.6859674193456584,-1.6093170644715755,-1.8443301642352452,-2.9639878647206714,-1.7857564489043085,-2.2767080738443966,-2.8116408743069172,-4.165490433707042],\"rsi_7_series\":[52.36261931236752,50.224854553588735,64.51939637840309,56.43190091843034,56.43190091843034,53.46543778226064,60.59145876170869,55.93079609987136,55.933396040432946,51.36232275243974],\"rsi_14_series\":[54.7548184652012,53.76430055031283,60.305390332855936,56.615786115394435,56.615786115394435,55.33884289971598,58.32357179428579,56.42929836248256,56.4303002952759,54.67944074294108]},\"longer_term_4hour\":{\"ema_20\":2597.547540602427,\"ema_50\":2543.5599365084554,\"atr_3\":15.872936357830332,\"atr_14\":32.71648902120304,\"current_volume\":628929.781,\"average_volume\":581433.6469999999,\"macd_series\":[11.54345829086246,7.633758991501267,4.4086905406069405,1.1718645219821298,1.5982676834835843,1.3910126891717027,0.08846392695395622,-0.016262906078843287,-0.47448031326175055,-1.9549573836077556],\"rsi_14_series\":[64.25815717971402,58.20816072142766,58.20816072142766,56.847715545441034,61.53413250641639,61.534132506416384,59.70616117520849,61.63699424932504,61.63813198471269,59.19364931318056]}},\"XRP\":{\"symbol\":\"XRP\",\"current_price\":0.5361,\"current_ema20\":0.5437786920121773,\"current_macd\":-0.001251941771040462,\"current_rsi_7\":39.1447703425154,\"funding_rate\":0.0001,\"intraday_3min\":{\"mid_prices\":[0.5439,0.5392,0.553,0.5465,0.5465,0.5499,0.5402,0.5438,0.5438,0.5361],\"ema_20_series\":[0.5439023435262095,0.5434545012856181,0.5443635964012735,0.5445670634106761,0.5447511526096593,0.5452415190277871,0.544761374358474,0.5446698148957623,0.5445869753818802,0.5437786920121773],\"macd_series\":[0.000019065316097432918,-0.0005616847383798354,-0.00003884637847646408,-0.0001471182680196385,-0.00023013191681118487,-0.00007545790282062568,-0.0006157535461607695,-0.0007131411608352427,-0.0007559355807943934,-0.001251941771040462],\"rsi_7_series\":[48.43045329460375,44.31535490443866,56.869210203746086,50.600508511283245,50.60050851128325,54.195268415800086,43.628204043467385,48.01687407660396,48.01687407660395,39.1447703425154],\"rsi_14_series\":[50.46679354590206,48.31512549078356,54.45520784467868,51.36023605561266,51.36023605561266,52.981381811105926,48.05995053346808,49.91927094287775,49.91927094287775,45.84800121774665]},\"longer_term_4hour\":{\"ema_20\":0.5433519641118686,\"ema_50\":0.5462334730903491,\"atr_3\":0.005691361052890048,\"atr_14\":0.007628588682027389,\"current_volume\":125795806.2,\"average_volume\":191011802.01000002,\"macd_series\":[0.0028779238987069024,0.0019759560315650493,0.0012997365074725203,0.000497554833830462,0.0004231521517185325,0.00034197415839900213,0.00047700564452296925,0.00013311947143690743,-0.00010393158774197643,-0.0007527529893178355],\"rsi_14_series\":[63.84183720603018,50.45272336246969,50.45272336246968,48.023544707471004,51.89747995608326,51.89747995608326,53.75912618686042,50.0188904041059,50.0188904041059,45.39521716103208]}},\"BNB\":{\"symbol\":\"BNB\",\"current_price\":593.04,\"current_ema20\":594.2082156010609,\"current_macd\":-1.1391546473389038,\"current_rsi_7\":44.15895066362949,\"funding_rate\":0.0001,\"intraday_3min\":{\"mid_prices\":[592.84,591.81,602.54,599.03,599.03,601.3,595.21,597.94,597.93,593.04],\"ema_20_series\":[589.6663724189071,589.8705274266302,591.0771438621892,591.8345587324569,592.5198388531753,593.3560446766825,593.5326118503318,593.9523631026811,594.3311856643305,594.2082156010609],\"macd_series\":[-0.5753027271120423,-0.8982068889823918,-0.4259351957218467,-0.3878126844288756,-0.3989210110080048,-0.2945286376270513,-0.6560594630178214,-0.7263027926027998,-0.7834954994649408,-1.1391546473389038],\"rsi_7_series\":[50.0889915719095,48.94732174397368,60.02194944148143,55.432805809776454,55.432805809776454,58.24316267748149,48.64251698403509,52.7185563124752,52.70068176685397,44.15895066362949],\"rsi_14_series\":[53.16830901154786,52.59162826806784,57.73460663571017,55.60940574093283,55.60940574093284,56.802060961736814,52.71042845897757,54.29964167957075,54.29244423679928,50.74994035098356]},\"longer_term_4hour\":{\"ema_20\":592.0758767622689,\"ema_50\":583.0219418781236,\"atr_3\":3.714073159746165,\"atr_14\":6.112004636263452,\"current_volume\":103433.57,\"average_volume\":115766.356,\"macd_series\":[2.6533923127292134,1.7344312270889333,1.0130091619629296,0.3845396415146656,0.3728956689072689,0.2868629586527103,0.30292708378101896,0.022157540005722787,-0.21620452110668076,-0.7264284861302528],\"rsi_14_series\":[65.75977147892283,55.66735552906186,55.67264535729562,54.94541615914437,58.98940692880764,58.98940692880764,60.28909456870654,57.38990541336899,57.38106135148472,53.073903055837]}},\"DOGE\":{\"symbol\":\"DOGE\",\"current_price\":0.14574,\"current_ema20\":0.1328929005438362,\"current_macd\":0.0011859767326274457,\"current_rsi_7\":72.3144081888458,\"funding_rate\":0.0001,\"intraday_3min\":{\"mid_prices\":[0.12961,0.12946,0.14081,0.13717,0.13717,0.13692,0.14697,0.14402,0.14401,0.14574],\"ema_20_series\":[0.12059372837395041,0.12143813519547894,0.12328307470067142,0.12460563901489319,0.1258022448229986,0.12686107864937968,0.12877621401610542,0.13022800315742872,0.13154057428529264,0.1328929005438362],\"macd_series\":[0.001158178738554276,0.0010047258406519375,0.0015445474382381214,0.0015304546018109055,0.0013987257797024128,0.0011810280483436205,0.001575488880469932,0.0014997400645939902,0.00131744954957262,0.0011859767326274457],\"rsi_7_series\":[63.943765209817975,63.52331866270357,76.92004985716943,67.6270434407706,67.6270434407706,66.87179151304386,78.25911232901527,70.01714739600907,69.98799701851516,72.3144081888458],\"rsi_14_series\":[62.219165744518094,62.010569989701196,70.16209543415366,65.32125428228392,65.32125428228392,64.96422770004594,71.66818414426517,67.58046275332345,67.56639423705647,68.77734840205733]},\"longer_term_4hour\":{\"ema_20\":0.12911495390255942,\"ema_50\":0.11999682413689532,\"atr_3\":0.002857670649539113,\"atr_14\":0.0035715947072376317,\"current_volume\":2335922745,\"average_volume\":3272755506.8,\"macd_series\":[0.0012450643153989185,0.0015733421170683651,0.0016753594106202513,0.0016161837767769503,0.0019570008512366415,0.002034164823062749,0.0019214403860015614,0.002160287252011373,0.002148304130954042,0.002085880123765426],\"rsi_14_series\":[58.22431019898918,66.31208060480348,66.31973826321922,66.07710588442748,71.79000728835645,71.79000728835645,71.3382126698052,75.96450570018813,75.94591222339623,76.99497940885095]}},\"SOL\":{\"symbol\":\"SOL\",\"current_price\":157.54,\"current_ema20\":154.68935020014393,\"current_macd\":0.3181075477313864,\"current_rsi_7\":56.34137429262596,\"funding_rate\":0.0001,\"intraday_3min\":{\"mid_prices\":[150.44,149.55,156.64,154.86,154.86,153.51,159.78,159.7,159.7,157.54],\"ema_20_series\":[151.56606001015723,151.37405429490417,151.87557293348473,152.15980408267666,152.41696559861222,152.5210641130301,153.21239134036057,153.8302588317548,154.3892818001591,154.68935020014393],\"macd_series\":[-0.871018520309486,-0.9520563009755696,-0.5189800905999953,-0.35124957871237195,-0.24422931019543226,-0.26646842354202493,0.1183389315285448,0.33259100618104487,0.43305825841039014,0.3181075477313864],\"rsi_7_series\":[44.735325092763766,42.49763497955823,60.746353447618795,55.579982054469305,55.579982054469305,51.094141222939925,65.97443165027484,65.67696871850069,65.67696871850069,56.34137429262596],\"rsi_14_series\":[49.585379584745546,48.40461669473278,57.157058735741145,54.65053805115904,54.650538051159046,52.6207909700504,60.04336943674506,59.9143945083339,59.91439450833389,56.13838331901134]},\"longer_term_4hour\":{\"ema_20\":153.74602869060206,\"ema_50\":150.19863001024976,\"atr_3\":2.2865633159410663,\"atr_14\":2.8316652717383533,\"current_volume\":4830696.33,\"average_volume\":3305133.432,\"macd_series\":[0.4879068617318092,0.009189229988129988,-0.3161643149891864,-0.5837755928207167,-0.40416645253705097,-0.291614243973751,-0.3124813921650431,0.06601807546826155,0.2798094257699155,0.24067372707118295],\"rsi_14_series\":[59.007156124816454,50.31298617210408,50.29778427896974,48.88217692680351,56.710453938574034,56.710453938574034,54.26034713237825,62.30255620765094,62.30255620765094,58.163818761201156]}}}}},{\"json\":{\"positions\":[]}}],\"Data Merge\":[{\"json\":{\"marketData\":{\"BTC\":{\"symbol\":\"BTC\",\"current_price\":113119,\"current_ema20\":112783.56835492219,\"current_macd\":-12.513710209849307,\"current_rsi_7\":63.392207334488866,\"funding_rate\":null,\"intraday_3min\":{\"mid_prices\":[112423.1,112688.1,112442.1,112600.1,112790,113000,113087.5,113064.7,113119,113119],\"ema_20_series\":[112565.52950528485,112577.20288573392,112564.33594423546,112567.74204478446,112588.90946909071,112628.06094822493,112671.81704839398,112709.23447235646,112748.25976070347,112783.56835492219],\"macd_series\":[-45.713846863621995,-60.22980359460621,-85.08995230364837,-89.15415667389652,-77.73182987523649,-55.74172100260648,-35.971306062119766,-25.585652532246627,-16.647962003109285,-12.513710209849307],\"rsi_7_series\":[38.37793149199205,48.484513190003945,41.17143744814777,47.145228168115736,53.73312250547273,60.1424713421208,62.657172952954724,61.47802158370463,63.392207334488866,63.392207334488866],\"rsi_14_series\":[50.09625727458878,54.546392940094805,50.08168569221107,52.75639531814384,55.82041085633884,58.988061294153695,60.266402837608766,59.74383678850035,60.619617776834325,60.619617776834325]},\"longer_term_4hour\":{\"ema_20\":114656.04105969002,\"ema_50\":117362.48507017472,\"atr_3\":1283.066285506208,\"atr_14\":2075.672877044071,\"current_volume\":0,\"average_volume\":24916.619700000003,\"macd_series\":[-1255.5529976020273,-1173.796578051983,-1079.3066564327996,-988.1039108177149,-897.0167951501044,-769.6889617634342,-576.2885445212282,-382.2662708500384,-132.35347981272116,54.58187888645398],\"rsi_14_series\":[18.85001603391966,28.14426635021985,27.287279143428336,26.182841227563884,25.20874292834864,25.55841255563365,30.060010748314212,31.790911075588866,38.62089381721906,38.62089381721906]}},\"ETH\":{\"symbol\":\"ETH\",\"current_price\":4032.37,\"current_ema20\":4007.732980340257,\"current_macd\":-5.900362620072549,\"current_rsi_7\":59.442802237812636,\"funding_rate\":null,\"intraday_3min\":{\"mid_prices\":[3985.58,4012.31,3995.59,4007.19,4022,4032.86,4034.1,4030.04,4032.38,4032.37],\"ema_20_series\":[3982.897278848972,3985.698490387165,3986.6405389217207,3988.5976304529854,3991.778808505082,3995.6913029331695,3999.3492740823913,4002.272200360259,4005.139609849758,4007.732980340257],\"macd_series\":[-4.420467191570033,-6.149667644620472,-8.425518977452924,-9.098176902438965,-8.505131132075022,-7.382550103284039,-6.584013786724036,-6.353670330238728,-6.068619787005709,-5.900362620072549],\"rsi_7_series\":[40.159042420674766,51.89860836218618,45.399043109225815,50.42438077932665,56.40136060744022,60.47776018674783,60.96395273319537,58.227752274964764,59.451484416685716,59.442802237812636],\"rsi_14_series\":[55.62623830422558,60.529943042999825,56.3361479079016,58.48519695647083,61.11650292264657,62.96995783304418,63.18573692577144,61.91361037277647,62.38367987747949,62.38013658160162]},\"longer_term_4hour\":{\"ema_20\":4006.944015752896,\"ema_50\":4188.258371208763,\"atr_3\":105.03526391964714,\"atr_14\":122.0875307962505,\"current_volume\":0,\"average_volume\":994095.2991000001,\"macd_series\":[-69.60921375955037,-61.89337056627065,-53.80958105471939,-48.89017294530214,-42.80951377983496,-33.158305569609325,-21.04473495700634,-11.316982528971153,10.557274003743345,25.201042683536144],\"rsi_14_series\":[16.693661345309366,24.73548058752725,24.237180277371465,22.296868477276433,21.91622437173976,25.596206800365167,30.178722083793446,29.867516279331696,47.45166794286639,47.45106989997281]}},\"XRP\":{\"symbol\":\"XRP\",\"current_price\":2.4868,\"current_ema20\":2.471501352624425,\"current_macd\":-0.0023774448384688736,\"current_rsi_7\":60.291734417727874,\"funding_rate\":null,\"intraday_3min\":{\"mid_prices\":[2.46,2.4766,2.4702,2.4708,2.4795,2.487,2.485,2.4801,2.4869,2.4868],\"ema_20_series\":[2.4567886829255565,2.4586754750278845,2.459773048834753,2.4608232346600145,2.4626019742162035,2.4649255957194223,2.4668374437461438,2.468100544341749,2.4698909686901542,2.471501352624425],\"macd_series\":[-0.0017557585229409714,-0.0022851649149003214,-0.003115700123042447,-0.003637614053782587,-0.0034135166209983483,-0.0028023823776474124,-0.0025805782364359195,-0.0027936155655366723,-0.0025150014535006773,-0.0023774448384688736],\"rsi_7_series\":[43.61607799082379,54.87225985752346,50.35097012861683,50.79441734817487,57.25318579202811,62.23830569555997,60.05925508056242,54.59563660291347,60.42453017165801,60.291734417727874],\"rsi_14_series\":[54.87914127371831,59.88055546004133,57.245942959933814,57.43502022809825,60.18459663154035,62.43726500226252,61.43900486358851,58.952150906262844,61.2936085678904,61.23828697091055]},\"longer_term_4hour\":{\"ema_20\":2.5447556064719867,\"ema_50\":2.7062736867011843,\"atr_3\":0.0696150844192456,\"atr_14\":0.11503263988333844,\"current_volume\":0,\"average_volume\":172924048.32,\"macd_series\":[-0.0447168316040715,-0.03908943455058378,-0.03266886169888368,-0.030531550315859732,-0.02847292500777518,-0.02731074215595626,-0.02107400919338899,-0.014532933366980152,-0.0027501880775155085,0.005873596867243397],\"rsi_14_series\":[19.278019058603192,27.68536151764644,27.882353146391097,24.742970943774694,23.597613079114666,22.001883900910997,28.22733805052698,29.153467787419444,39.64334776185573,39.63642530420851]}},\"BNB\":{\"symbol\":\"BNB\",\"current_price\":1301.47,\"current_ema20\":1278.6979494913712,\"current_macd\":2.1492887908591882,\"current_rsi_7\":78.09233657569592,\"funding_rate\":null,\"intraday_3min\":{\"mid_prices\":[1263.29,1271.06,1272.02,1272.32,1286.71,1295.62,1292.28,1294.38,1301.48,1301.47],\"ema_20_series\":[1261.7642380363195,1262.6495486995273,1263.5419726329055,1264.3779752392954,1266.504834740315,1269.2777076221896,1271.4684021343621,1273.6504590739466,1276.3008915430946,1278.6979494913712],\"macd_series\":[-0.39716719054317373,-0.4717299672637427,-0.5049731353211442,-0.5515440335598045,0.2964207921746631,1.3102151616322697,1.5900508732317338,1.7387301104129982,2.1125344005157523,2.1492887908591882],\"rsi_7_series\":[46.29286593364927,56.34446683392122,57.49124302585116,57.894493676566896,72.49558708626637,78.00529246546436,71.72191132545612,73.29954996213277,78.11548165082797,78.09233657569592],\"rsi_14_series\":[53.887766548323874,58.79282157415975,59.36790628940853,59.55785129277632,67.42426989140586,71.16429866442584,68.01205258501312,68.94352003015895,71.92061467428663,71.91015888086011]},\"longer_term_4hour\":{\"ema_20\":1207.6361535383676,\"ema_50\":1195.4011973896602,\"atr_3\":45.434698619437604,\"atr_14\":56.63734912015824,\"current_volume\":0,\"average_volume\":413794.3779999999,\"macd_series\":[-24.802707211592455,-22.890831177942747,-19.641073353490494,-16.658588153854655,-14.189193651112854,-12.64521640548299,-8.322335469710112,-0.6305779784127701,9.050470016469028,14.81261274545231],\"rsi_14_series\":[32.46818224045394,38.564783483084106,40.67027926053836,40.39147942385535,39.66783640716389,37.96286789276451,45.17008617469597,54.91355015709917,62.541863925976074,62.5402956166394]}},\"DOGE\":{\"symbol\":\"DOGE\",\"current_price\":0.20497,\"current_ema20\":0.20215645258794518,\"current_macd\":-0.00018748959167820024,\"current_rsi_7\":66.80680373520559,\"funding_rate\":null,\"intraday_3min\":{\"mid_prices\":[0.20031,0.20266,0.20221,0.20276,0.20405,0.20537,0.20561,0.20516,0.20497,0.20497],\"ema_20_series\":[0.1988133828554084,0.1991797273453695,0.1994683247410486,0.19978181762285352,0.20018831118258176,0.2006818053556692,0.20115115722655785,0.20153295177640948,0.20186028970246572,0.20215645258794518],\"macd_series\":[-0.00009621087073354278,-0.00014893681997979686,-0.0002329199467192805,-0.0002677433969890475,-0.00022209369903690218,-0.00012597729702287048,-0.00007190387240433834,-0.0000908870943443804,-0.00013786593247735708,-0.00018748959167820024],\"rsi_7_series\":[48.24414685303213,61.95731574585454,58.494835396787536,61.55817853039424,68.01741122087644,73.36092694809683,74.2727102120898,69.09910825803621,66.80680373520559,66.80680373520559],\"rsi_14_series\":[61.08615870921124,66.93363540734924,64.92183667941944,66.25677607133701,69.21589822358787,71.92864126235844,72.40478486066448,70.00704417740036,68.96853175497387,68.96853175497387]},\"longer_term_4hour\":{\"ema_20\":0.2095981725261832,\"ema_50\":0.22787316445874825,\"atr_3\":0.007967268420951154,\"atr_14\":0.012395629422858948,\"current_volume\":0,\"average_volume\":2920955668.6,\"macd_series\":[-0.006577574264166148,-0.006462367385806243,-0.006096321912572632,-0.00594785389889806,-0.005391364715524007,-0.004649626677072402,-0.0035290553920361515,-0.002580392805240401,-0.0006722629562388657,0.0006959666615052491],\"rsi_14_series\":[18.633437771475457,21.44720135940156,20.91428494945616,18.809692045426374,19.758119890014157,19.755125650795733,25.301971512812543,24.866656883299513,41.43681183564021,41.43681183564021]}},\"SOL\":{\"symbol\":\"SOL\",\"current_price\":190.96,\"current_ema20\":188.94509768483596,\"current_macd\":-0.12102730724618871,\"current_rsi_7\":69.4098869775887,\"funding_rate\":null,\"intraday_3min\":{\"mid_prices\":[187.76,189,188.43,188.7,190.11,190.38,190.55,190.84,190.96,190.96],\"ema_20_series\":[187.09782485225344,187.27898439013407,187.38860492440702,187.5134996935111,187.76078543698625,188.01023444298755,188.25211687698874,188.49858193632315,188.73300270429237,188.94509768483596],\"macd_series\":[-0.08298732911305651,-0.15881865173342113,-0.2546408728718079,-0.30378262707780923,-0.24764535819498468,-0.20065174851828083,-0.1677771304215625,-0.13743484684407004,-0.12080613515994165,-0.12102730724618871],\"rsi_7_series\":[45.406833999662545,55.500496022405386,50.49382864282119,52.844644423346196,63.42585915245723,65.17179023378131,66.351698009932,68.4770901857602,69.4098869775887,69.4098869775887],\"rsi_14_series\":[57.43342014840041,61.74721604123928,58.797452524887085,59.7776439879998,64.5240117112639,65.3667949606506,65.91583484451877,66.88039672756632,67.2928624883273,67.2928624883273]},\"longer_term_4hour\":{\"ema_20\":194.63339582851356,\"ema_50\":207.57694875746978,\"atr_3\":5.525441827605696,\"atr_14\":7.917467092395901,\"current_volume\":0,\"average_volume\":6477353.016,\"macd_series\":[-4.294479495644041,-4.249354640938976,-3.92783817650045,-3.8615452968571216,-3.54720609642432,-3.1113167131913446,-2.2352856520805524,-1.576039701709524,-0.3325032045812737,0.561246544122751],\"rsi_14_series\":[18.849432157235725,20.061116657203357,20.476289170931892,17.932683767949413,17.921339260980332,17.748029761207818,27.447728129592775,26.49674111672259,40.923499836834644,40.923499836834644]}}},\"positions\":{\"positions\":[{\"symbol\":\"BTC\",\"quantity\":null,\"entry_price\":null,\"current_price\":null,\"liquidation_price\":null,\"unrealized_pnl\":null,\"leverage\":null,\"exit_plan\":null,\"confidence\":null,\"risk_usd\":833.3333333333334,\"sl_oid\":null,\"tp_oid\":null,\"wait_for_fill\":false,\"entry_oid\":null,\"notional_usd\":null},{\"symbol\":\"ETH\",\"quantity\":null,\"entry_price\":null,\"current_price\":null,\"liquidation_price\":null,\"unrealized_pnl\":null,\"leverage\":null,\"exit_plan\":null,\"confidence\":null,\"risk_usd\":833.3333333333334,\"sl_oid\":null,\"tp_oid\":null,\"wait_for_fill\":false,\"entry_oid\":null,\"notional_usd\":null},{\"symbol\":\"XRP\",\"quantity\":null,\"entry_price\":null,\"current_price\":null,\"liquidation_price\":null,\"unrealized_pnl\":null,\"leverage\":null,\"exit_plan\":null,\"confidence\":null,\"risk_usd\":833.3333333333334,\"sl_oid\":null,\"tp_oid\":null,\"wait_for_fill\":false,\"entry_oid\":null,\"notional_usd\":null},{\"symbol\":\"BNB\",\"quantity\":null,\"entry_price\":null,\"current_price\":null,\"liquidation_price\":null,\"unrealized_pnl\":null,\"leverage\":null,\"exit_plan\":null,\"confidence\":null,\"risk_usd\":833.3333333333334,\"sl_oid\":null,\"tp_oid\":null,\"wait_for_fill\":false,\"entry_oid\":null,\"notional_usd\":null},{\"symbol\":\"DOGE\",\"quantity\":null,\"entry_price\":null,\"current_price\":null,\"liquidation_price\":null,\"unrealized_pnl\":null,\"leverage\":null,\"exit_plan\":null,\"confidence\":null,\"risk_usd\":833.3333333333334,\"sl_oid\":null,\"tp_oid\":null,\"wait_for_fill\":false,\"entry_oid\":null,\"notional_usd\":null},{\"symbol\":\"SOL\",\"quantity\":null,\"entry_price\":null,\"current_price\":null,\"liquidation_price\":null,\"unrealized_pnl\":null,\"leverage\":null,\"exit_plan\":null,\"confidence\":null,\"risk_usd\":833.3333333333334,\"sl_oid\":null,\"tp_oid\":null,\"wait_for_fill\":false,\"entry_oid\":null,\"notional_usd\":null}]}}}]},\"connections\":{\"Scheduled Trigger\":{\"main\":[[{\"node\":\"Parameter Reset\",\"type\":\"main\",\"index\":0}]]},\"Merge\":{\"main\":[[{\"node\":\"Data Merge\",\"type\":\"main\",\"index\":0}]]},\"AI Agent\":{\"main\":[[{\"node\":\"Trade Execution\",\"type\":\"main\",\"index\":0}]]},\"Parameter Reset\":{\"main\":[[{\"node\":\"Market Data Fetch\",\"type\":\"main\",\"index\":0},{\"node\":\"Position Data Fetch\",\"type\":\"main\",\"index\":0}]]},\"OpenAI Model\":{\"ai_languageModel\":[[{\"node\":\"AI Agent\",\"type\":\"ai_languageModel\",\"index\":0}]]},\"Market Data Fetch\":{\"main\":[[{\"node\":\"Merge\",\"type\":\"main\",\"index\":0}]]},\"Position Data Fetch\":{\"main\":[[{\"node\":\"Merge\",\"type\":\"main\",\"index\":1}]]},\"Data Merge\":{\"main\":[[{\"node\":\"AI Agent\",\"type\":\"main\",\"index\":0}]]}},\"active\":false,\"settings\":{\"timezone\":\"Asia/Shanghai\",\"executionOrder\":\"v1\"},\"tags\":[],\"meta\":{\"templateCredsSetupCompleted\":true},\"credentials\":{},\"id\":\"b830c2aa-c71c-4e2d-bfc8-d4f78dc9a82e\",\"plugins\":{},\"mcpClients\":{}},\"startNodes\":[],\"triggerToStartFrom\":{\"name\":\"Scheduled Trigger\"}}"}