策略源码
{"type":"n8n","content":"{\"workflowData\":{\"nodes\":[{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"// 设置测试网基地址\\nexchange.SetBase(\\\"https://testnet.binancefuture.com\\\");\\n\\n// 权益百分比下单数量计算节点\\nconst symbol = $vars.coin + '_USDT.swap' || 'ETH_USDT.swap';\\nconst riskRatio = $vars.riskRatio || 0.05; // 5%风险比例\\nconst savestatus = _G('status')\\n\\nif(!savestatus){\\n _G('status','unfinished')\\n}\\n\\nif(savestatus == 'monitor'){\\n Log('监控止盈止损')\\n return [{ \\n json: { \\n success: true,\\n status: 'monitor' // 添加状态信息传递\\n } \\n }];\\n}\\n\\ntry {\\n // 1. 获取账户信息\\n const accountInfo = exchange.GetAccount();\\n if (!accountInfo) {\\n return [{ \\n json: { \\n success: false, \\n error: \\\"获取账户信息失败\\\" \\n } \\n }];\\n }\\n \\n const availBalance = accountInfo.Balance;\\n Log(\\\"账户可用余额:\\\", availBalance);\\n \\n // 2. 获取市场信息\\n const allMarkets = exchange.GetMarkets();\\n const marketsInfo = allMarkets[symbol];\\n if (!marketsInfo) {\\n return [{ \\n json: { \\n success: false, \\n error: `未找到交易对信息: ${symbol}` \\n } \\n }];\\n }\\n \\n // 3. 获取当前价格\\n const ticker = exchange.GetTicker(symbol);\\n if (!ticker) {\\n return [{ \\n json: { \\n success: false, \\n error: \\\"获取价格信息失败\\\" \\n } \\n }];\\n }\\n \\n const currentPrice = ticker.Last;\\n Log(\\\"当前价格:\\\", currentPrice);\\n \\n // 4. 计算合约张数\\n let coinQuantity = availBalance * riskRatio / currentPrice;\\n let contractQuantity = coinQuantity / marketsInfo.CtVal;\\n contractQuantity = _N(contractQuantity, marketsInfo.AmountPrecision);\\n \\n Log(\\\"计算步骤:\\\");\\n Log(\\\"- 风险金额:\\\", availBalance * riskRatio);\\n Log(\\\"- 币种数量:\\\", coinQuantity);\\n Log(\\\"- 合约面值:\\\", marketsInfo.CtVal);\\n Log(\\\"- 原始合约张数:\\\", coinQuantity / marketsInfo.CtVal);\\n Log(\\\"- 精度处理后:\\\", contractQuantity);\\n \\n // 5. 检查限制\\n if (contractQuantity < marketsInfo.MinQty) {\\n return [{ \\n json: { \\n success: false, \\n error: `计算数量${contractQuantity}小于最小要求${marketsInfo.MinQty}`,\\n calculatedQuantity: contractQuantity,\\n minQty: marketsInfo.MinQty\\n } \\n }];\\n }\\n \\n if (contractQuantity > marketsInfo.MaxQty) {\\n Log(\\\"数量超过最大限制,使用最大值:\\\", marketsInfo.MaxQty);\\n contractQuantity = marketsInfo.MaxQty;\\n }\\n \\n Log(\\\"最终下单数量:\\\", contractQuantity);\\n \\n // 6. 返回计算结果\\n return [{ \\n json: { \\n success: true,\\n symbol: symbol,\\n positionSize: contractQuantity,\\n availBalance: availBalance,\\n openSide: $vars.openSide == 0 ? 'openLong' : 'openShort',\\n riskRatio: riskRatio,\\n riskAmount: availBalance * riskRatio,\\n status: _G('status'),\\n marketInfo: {\\n ctVal: marketsInfo.CtVal,\\n amountPrecision: marketsInfo.AmountPrecision,\\n pricePrecision: marketsInfo.PricePrecision,\\n minQty: marketsInfo.MinQty,\\n maxQty: marketsInfo.MaxQty\\n },\\n message: \\\"下单数量计算完成\\\"\\n } \\n }];\\n \\n} catch (error) {\\n console.error(\\\"计算数量节点执行错误:\\\", error);\\n return [{ \\n json: { \\n success: false, \\n error: error.message || \\\"未知错误\\\" \\n } \\n }];\\n}\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[208,0],\"id\":\"3cb8c762-ef19-4e70-9111-83d18fd17085\",\"name\":\"权益百分比下单数量计算\"},{\"parameters\":{\"mode\":\"runOnceForAllItems\",\"language\":\"javaScript\",\"jsCode\":\"// 智能空仓交易管理节点 - 状态管理修正版\\nconst positionData = $input.first().json;\\n\\n// 检查第一个节点是否成功\\nif (!positionData.success) {\\n return [{ \\n json: { \\n success: false, \\n error: \\\"上游节点计算失败: \\\" + positionData.error \\n } \\n }];\\n}\\n\\ntry {\\n Log(\\\"=== 智能交易管理开始 ===\\\");\\n\\n // 状态1: 未完成开仓\\n if (positionData.status == 'unfinished') {\\n const symbol = positionData.symbol;\\n const positionSize = positionData.positionSize;\\n const currentPrice = positionData.currentPrice;\\n const openSide = positionData.openSide; // 'openLong' or 'openShort'\\n \\n // 交易参数配置\\n const stopLossPercent = $vars.slRatio || 0.02; // 2%止损\\n const takeProfitPercent = $vars.tpRatio || 0.04; // 4%止盈\\n Log(\\\"📈 开始开仓流程\\\");\\n Log(\\\"当前状态:\\\", positionData.status);\\n Log(\\\"交易对:\\\", symbol, \\\"开仓数量:\\\", positionSize, \\\"当前价格:\\\", currentPrice);\\n \\n const dir = openSide == 'openLong' ? 'buy' : 'sell';\\n \\n Log(\\\"开仓方向:\\\", dir, \\\"订单量:\\\", positionSize);\\n \\n // 开仓下单\\n const openOrder = exchange.CreateOrder(symbol, dir, -1, positionSize); \\n if (!openOrder) {\\n Log(\\\"❌ 开仓失败\\\");\\n return [{ \\n json: { \\n success: false, \\n error: \\\"开仓失败\\\" \\n } \\n }];\\n }\\n \\n Log(\\\"✅ 开仓订单提交成功 ID:\\\", openOrder);\\n Sleep(3000); // 等待订单成交\\n \\n // 检查开仓订单状态\\n const openOrderInfo = exchange.GetOrder(openOrder);\\n if (!openOrderInfo) {\\n Log(\\\"❌ 无法获取开仓订单信息\\\");\\n return [{ \\n json: { \\n success: false, \\n error: \\\"无法获取开仓订单信息\\\" \\n } \\n }];\\n }\\n \\n Log(\\\"开仓订单状态:\\\", openOrderInfo.Status);\\n \\n if (openOrderInfo.Status == ORDER_STATE_CLOSED) { // 订单已成交\\n Log(\\\"🎯 开仓成功,开始设置止盈止损\\\");\\n \\n // 计算止盈止损价格\\n const entryPrice = openOrderInfo.AvgPrice;\\n let stopLossPrice, takeProfitPrice;\\n \\n if (openSide == 'openShort') {\\n // 空仓:止损价格上涨,止盈价格下跌\\n stopLossPrice = _N(entryPrice * (1 + stopLossPercent), positionData.marketInfo.pricePrecision);\\n takeProfitPrice = _N(entryPrice * (1 - takeProfitPercent), positionData.marketInfo.pricePrecision);\\n } else {\\n // 多仓:止损价格下跌,止盈价格上涨\\n stopLossPrice = _N(entryPrice * (1 - stopLossPercent), positionData.marketInfo.pricePrecision);\\n takeProfitPrice = _N(entryPrice * (1 + takeProfitPercent), positionData.marketInfo.pricePrecision);\\n }\\n \\n Log(\\\"入场价格:\\\", entryPrice);\\n Log(\\\"止损价格:\\\", stopLossPrice);\\n Log(\\\"止盈价格:\\\", takeProfitPrice);\\n \\n // 设置止损单\\n const closeDirection = openSide == 'openShort' ? \\\"closesell\\\" : \\\"closebuy\\\";\\n const stopLossOrderId = exchange.CreateConditionOrder(\\n symbol,\\n closeDirection,\\n openOrderInfo.Amount,\\n {\\n \\\"ConditionType\\\": ORDER_CONDITION_TYPE_SL,\\n \\\"SlTriggerPrice\\\": stopLossPrice,\\n \\\"SlOrderPrice\\\": openSide == 'openShort' ? stopLossPrice + 2 : stopLossPrice - 2\\n },\\n \\\"止损单\\\"\\n );\\n \\n // 设置止盈单\\n const takeProfitOrderId = exchange.CreateConditionOrder(\\n symbol,\\n closeDirection,\\n openOrderInfo.Amount,\\n {\\n \\\"ConditionType\\\": ORDER_CONDITION_TYPE_TP,\\n \\\"TpTriggerPrice\\\": takeProfitPrice,\\n \\\"TpOrderPrice\\\": openSide == 'openShort' ? takeProfitPrice + 2 : takeProfitPrice - 2\\n },\\n \\\"止盈单\\\"\\n );\\n \\n Log(\\\"止损单ID:\\\", stopLossOrderId);\\n Log(\\\"止盈单ID:\\\", takeProfitOrderId);\\n \\n if (stopLossOrderId && takeProfitOrderId) {\\n // 验证止盈止损单状态\\n Sleep(2000);\\n const slOrder = exchange.GetConditionOrder(stopLossOrderId);\\n const tpOrder = exchange.GetConditionOrder(takeProfitOrderId);\\n \\n if (slOrder && tpOrder && slOrder.Status == 0 && tpOrder.Status == 0) {\\n Log(\\\"✅ 止盈止损单设置成功,进入监控状态\\\");\\n \\n // 保存订单ID和状态\\n _G('stopLossOrderId', stopLossOrderId);\\n _G('takeProfitOrderId', takeProfitOrderId);\\n _G('status', 'monitor');\\n _G('entryPrice', entryPrice);\\n _G('openSide', openSide);\\n \\n return [{ \\n json: { \\n success: true,\\n action: \\\"position_opened\\\",\\n status: \\\"monitor\\\",\\n symbol: symbol,\\n openSide: openSide,\\n positionSize: openOrderInfo.Amount,\\n entryPrice: entryPrice,\\n stopLossPrice: stopLossPrice,\\n takeProfitPrice: takeProfitPrice,\\n stopLossOrderId: stopLossOrderId,\\n takeProfitOrderId: takeProfitOrderId,\\n message: \\\"开仓成功,止盈止损单已设置,进入监控状态\\\"\\n } \\n }];\\n } else {\\n Log(\\\"❌ 止盈止损单设置失败\\\");\\n // 取消可能成功的订单\\n if (stopLossOrderId) exchange.CancelConditionOrder(stopLossOrderId);\\n if (takeProfitOrderId) exchange.CancelConditionOrder(takeProfitOrderId);\\n \\n return [{ \\n json: { \\n success: false,\\n error: \\\"止盈止损单设置失败\\\"\\n } \\n }];\\n }\\n } else {\\n Log(\\\"❌ 止盈止损单ID获取失败\\\");\\n return [{ \\n json: { \\n success: false,\\n error: \\\"止盈止损单ID获取失败\\\"\\n } \\n }];\\n }\\n \\n } else {\\n // 开仓订单未成交,取消订单\\n Log(\\\"⚠️ 开仓订单未成交,取消订单\\\");\\n exchange.CancelOrder(openOrder);\\n \\n return [{ \\n json: { \\n success: false,\\n error: \\\"开仓订单未成交,已取消订单\\\"\\n } \\n }];\\n }\\n }\\n \\n // 状态2: 监控持仓和止盈止损单\\n if (positionData.status == 'monitor') {\\n Log(\\\"📊 监控止盈止损单状态\\\");\\n \\n const stopLossOrderId = _G('stopLossOrderId');\\n const takeProfitOrderId = _G('takeProfitOrderId');\\n const entryPrice = _G('entryPrice');\\n const openSide = _G('openSide');\\n\\n const symbol = $vars.coin + '_USDT.swap' || 'ETH_USDT.swap';\\n const ticker = exchange.GetTicker(symbol);\\n if (!ticker) {\\n return [{ \\n json: { \\n success: false, \\n error: \\\"获取价格信息失败\\\" \\n } \\n }];\\n }\\n \\n const currentPrice = ticker.Last;\\n\\n if (!stopLossOrderId || !takeProfitOrderId) {\\n Log(\\\"❌ 缺少止盈止损单ID信息\\\");\\n return [{ \\n json: { \\n success: false,\\n error: \\\"缺少止盈止损单ID信息\\\"\\n } \\n }];\\n }\\n \\n Log(\\\"监控订单 - 止损ID:\\\", stopLossOrderId, \\\"止盈ID:\\\", takeProfitOrderId);\\n \\n // 检查止盈止损单状态\\n const slOrder = exchange.GetConditionOrder(stopLossOrderId);\\n const tpOrder = exchange.GetConditionOrder(takeProfitOrderId);\\n \\n let slStatus = slOrder ? slOrder.Status : -1;\\n let tpStatus = tpOrder ? tpOrder.Status : -1;\\n \\n Log(\\\"止损单状态:\\\", slStatus, \\\"止盈单状态:\\\", tpStatus);\\n Log(\\\"状态说明: 0=活跃, 1=已触发, -1=不存在\\\");\\n \\n // 检查是否有订单被触发\\n if (slStatus == 1 && tpStatus == 0) {\\n // 止损被触发,取消止盈单\\n Log(\\\"🛑 止损单已触发,取消止盈单\\\");\\n const cancelResult = exchange.CancelConditionOrder(takeProfitOrderId);\\n Log(\\\"取消止盈单结果:\\\", cancelResult);\\n \\n _G('status', 'finished');\\n \\n return [{ \\n json: { \\n success: true,\\n action: \\\"stop_loss_triggered\\\",\\n status: \\\"finished\\\",\\n triggerType: \\\"stop_loss\\\",\\n entryPrice: entryPrice,\\n exitType: \\\"止损\\\",\\n message: \\\"止损单触发,交易结束\\\"\\n } \\n }];\\n \\n } else if (tpStatus == 1 && slStatus == 0) {\\n // 止盈被触发,取消止损单\\n Log(\\\"🎯 止盈单已触发,取消止损单\\\");\\n const cancelResult = exchange.CancelConditionOrder(stopLossOrderId);\\n Log(\\\"取消止损单结果:\\\", cancelResult);\\n \\n _G('status', 'finished');\\n \\n return [{ \\n json: { \\n success: true,\\n action: \\\"take_profit_triggered\\\",\\n status: \\\"finished\\\",\\n triggerType: \\\"take_profit\\\",\\n entryPrice: entryPrice,\\n exitType: \\\"止盈\\\",\\n message: \\\"止盈单触发,交易结束\\\"\\n } \\n }];\\n \\n } else if (slStatus == 1 && tpStatus == 1) {\\n // 两个单都触发了(异常情况)\\n Log(\\\"⚠️ 止盈止损单都已触发\\\");\\n _G('status', 'finished');\\n \\n return [{ \\n json: { \\n success: true,\\n action: \\\"both_triggered\\\",\\n status: \\\"finished\\\",\\n message: \\\"止盈止损单都已触发,交易结束\\\"\\n } \\n }];\\n \\n } else if (slStatus == 0 && tpStatus == 0) {\\n // 两个单都还活跃,继续监控\\n Log(\\\"⏳ 止盈止损单都活跃,继续监控\\\");\\n \\n // 显示当前价格和距离止盈止损的百分比\\n const currentPricePercent = openSide == 'openShort' ? \\n ((entryPrice - currentPrice) / entryPrice * 100).toFixed(2) :\\n ((currentPrice - entryPrice) / entryPrice * 100).toFixed(2);\\n \\n Log(\\\"当前\\\", openSide == 'openShort' ? \\\"空仓\\\" : \\\"多仓\\\", \\\"盈亏:\\\", currentPricePercent + \\\"%\\\");\\n \\n return [{ \\n json: { \\n success: true,\\n action: \\\"monitoring\\\",\\n status: \\\"monitor\\\",\\n entryPrice: entryPrice,\\n profitPercent: currentPricePercent,\\n slActive: true,\\n tpActive: true,\\n message: \\\"持仓监控中\\\"\\n } \\n }];\\n \\n } else {\\n // 异常情况:单子状态异常\\n Log(\\\"❌ 止盈止损单状态异常,重置状态\\\");\\n _G('status', 'finished');\\n \\n return [{ \\n json: { \\n success: false,\\n error: \\\"止盈止损单状态异常,已重置状态\\\"\\n } \\n }];\\n }\\n }\\n \\n // 状态3: 交易完成\\n if (positionData.status == 'finished') {\\n Log(\\\"✅ 交易周期完成,准备下次交易\\\");\\n _G('status', 'unfinished'); // 重置状态为未完成,准备下次交易\\n \\n return [{ \\n json: { \\n success: true,\\n action: \\\"cycle_completed\\\",\\n status: \\\"unfinished\\\",\\n message: \\\"交易周期完成,状态已重置\\\"\\n } \\n }];\\n }\\n \\n // 默认返回\\n return [{ \\n json: { \\n success: true,\\n action: \\\"default\\\",\\n status: positionData.status,\\n message: \\\"默认处理完成\\\"\\n } \\n }];\\n \\n} catch (error) {\\n Log(\\\"❌ 智能交易管理节点执行错误:\\\", error);\\n Log(\\\"错误堆栈:\\\", error.stack);\\n \\n return [{ \\n json: { \\n success: false, \\n error: error.message || \\\"未知错误\\\",\\n details: error.stack || \\\"无堆栈信息\\\"\\n } \\n }];\\n}\",\"notice\":\"\"},\"type\":\"n8n-nodes-base.code\",\"typeVersion\":2,\"position\":[416,0],\"id\":\"b176d8f6-f9ae-4c72-b17b-93a745f8f599\",\"name\":\"止盈止损模块\"},{\"parameters\":{\"notice\":\"\",\"exchange\":0,\"symbol\":{\"__rl\":true,\"value\":\"={{$vars.coin}}_USDT.swap\",\"mode\":\"id\"},\"period\":60,\"limit\":500,\"rule\":{\"interval\":[{\"field\":\"seconds\",\"secondsInterval\":1}]}},\"type\":\"n8n-nodes-base.klineCloseTrigger\",\"typeVersion\":1,\"position\":[0,0],\"id\":\"fdd0b24a-79a7-45a0-beeb-70f39acb43b5\",\"name\":\"K线收盘触发器\"}],\"pinData\":{},\"connections\":{\"权益百分比下单数量计算\":{\"main\":[[{\"node\":\"止盈止损模块\",\"type\":\"main\",\"index\":0}]]},\"K线收盘触发器\":{\"main\":[[{\"node\":\"权益百分比下单数量计算\",\"type\":\"main\",\"index\":0}]]},\"止盈止损模块\":{\"main\":[[]]}},\"active\":false,\"settings\":{\"timezone\":\"Asia/Shanghai\",\"executionOrder\":\"v1\"},\"tags\":[],\"credentials\":{},\"id\":\"42d34c52-c2ab-4512-b74b-9eac4f4e97a4\",\"plugins\":{},\"mcpClients\":{}},\"startNodes\":[],\"triggerToStartFrom\":{\"name\":\"K线收盘触发器\"}}"}