夜雨聆风学习资料网

ARTICLE · 1148055

源码公开:给 MT5 网格 EA 装上"驾驶舱",参数跑着改,风险看得见

源码公开:给 MT5 网格 EA 装上"驾驶舱",参数跑着改,风险看得见

“

本文基于 GridPro Panel v1.00(MetaTrader 5 版,源码文件 GridPro_Panel_v1.mq5)。EA 仅支持对冲(Hedging)账户,文末附完整 MQL5 源码,可自行编译运行。

免责声明

本文所述内容仅供技术交流与学习参考,不构成任何投资建议。金融市场存在不确定性,过往表现不代表未来结果。投资者应根据自身情况独立判断,审慎决策,自行承担投资风险。


一、跑网格的人,多少都遇过这几件事 😤

网格 EA 挂上去,就"失联"了:现在攒了多少单、均价在哪、这一篮子浮亏多少,得切到终端列表里一单一单数,数完再切回图表看行情。

行情判断变了,想把加仓间距从 300 点放宽到 500 点:先移除 EA、重新加载、把十几个参数再填一遍——等填完,行情早走远了。

最不踏实的是用"黑盒"网格:手里只有一个 ex5 文件,里面怎么加仓、什么条件止损、风险藏在哪,全都看不到。马丁网格最怕的不是不赚钱,而是单边行情来了没人踩刹车。

GridPro Panel 想解决的就是这三件事:逻辑开源看得见、运行状态上面板、关键参数跑着改。

二、它是什么

GridPro Panel 是一款 MT5 网格策略 EA,自带一块暗色主题的可视化控制面板。一句话概括:网格逻辑全在源码里,读得到;持仓风险全在面板上,看得见;核心参数在面板里,回车就改。

几个基本设定先说清楚:

  • 需要对冲(Hedging)账户:EA 启动时会自动检查账户类型,非对冲账户直接拒绝运行,避免在净持账户上多空对冲失效;
  • 多空双向网格:可以只做多、只做空,也可以多空同时各跑各的篮子,互不干扰;
  • 魔术号 + 品种隔离:只管理自己魔术号下的持仓,同一账户多个图表各挂一套也不会打架;
  • 信号只管首单:技术信号只在首单入场时起作用,加仓节奏完全交给网格间距,不反复猜方向。
GridPro 面板总览:账户卡片、持仓卡片、参数卡片、操作按钮

三、网格引擎:入场、加仓、出场

首单入场:五种方式任选。 默认"无信号",挂上即开首单;也可以从四种技术信号里选——均线金叉/死叉、RSI 超买超卖、布林带下轨回归/上轨回归、随机指标低位金叉/高位死叉,还支持一键反向。选信号的目的只有一个:让首单别在随便的位置进场。

加仓手数:三种模式。 固定手数(每层一样多)、马丁倍数(每层 ×1.5,倍数可调)、等差递增(每层 +0.01,增量可调)。另有"按余额自动放大首单"开关——每满 N 余额首单手数翻一档,不同资金规模的账户可以共用一套参数。

网格间距:固定或动态。 固定点数间距最直观;ATR 动态间距按 H1 周期 ATR(14) 乘以系数自适应波动率,行情剧烈时间距自动放宽。间距还支持逐层放大(比如每层 ×1.2),越逆势层距越宽,避免底部密集成仓。

篮子出场:按单边篮子整体计算。金额止盈(如整篮浮盈 +8 启动、回撤 $3 落袋,启用后接管金额止盈);另设篮子止损金额兜底。

四、九项风控:给网格系上"安全带"

马丁类加仓的风险必须直说:单边行情里网格会持续加仓,手数递增会同步放大敞口。所以这套 EA 把风控做成了默认可用的"硬约束",一共九项:

  1. 账户回撤止损%:净值回撤达到设定值(默认 30%),全部平仓并停止运行,面板直接显示触发原因;
  2. 日亏损上限%:当日亏损触及红线,全平并锁定,次日自动解除;
  3. 日盈利达标%:当日盈利达到目标,落袋锁定到次日,赚到"目标位"就收手;
  4. 篮子止损金额:单边浮亏触及设定金额,整篮出局;
  5. 最大总手数:全账户总仓位封顶,防止手数失控;
  6. 最低保证金比例%:保证金比例低于阈值停止开新仓,给极端行情留缓冲;
  7. 最大点差:点差异常(跳点、流动性稀薄)时暂停开仓,面板同步提示;
  8. 交易时段:首单只允许在设定时段入场(支持跨午夜时段);
  9. 周五定时全平:周五到点全部平仓并停止,不带单过周末。

另设"两单最小间隔秒数",防止瞬间行情里连环开单。

五、控制面板:把管理权搬回图上

面板自上而下五块区域:

  • 状态栏:品种名 + 运行状态(运行中 / 已暂停 / 风控触发原因)+ 一键最小化;
  • 账户卡片:余额、净值、浮盈、回撤%、当前点差、今日盈亏,六项数据实时刷新,浮盈红绿变色;
  • 持仓卡片:多空两侧各自的单数、总手数、篮子浮盈,一行看全;
  • 参数卡片:首单手数、间距、间距倍数、手数倍数、最大层数、止盈金额、止盈点数、回撤止损%——共 8 个参数运行时直接改、回车即生效,不用移除 EA 重新加载;
  • 操作区:启动/暂停、立即买入、立即卖出、平多单、平空单、全部平仓六个按钮;图上还会自动画出多空两条均价虚线,价格离均价多远一眼可见。

顺带说一个实现上的小心思:MT5 原生控件并不支持圆角,面板里那些圆角卡片,是源码里 RoundRes() 函数逐像素用抗锯齿算法画出来的位图资源——对界面细节感兴趣的朋友,可以在文末源码里找到这段实现。

六、参数一览:七组输入,一张图看全

GridPro 的全部可调参数分七组,挂图前在 EA 输入窗口配置,运行后核心 8 项还能在面板上继续改。关键默认值先划重点:

参数组
关键参数与默认值
基础设置
魔术号 20260101 · 双向交易 · 最大滑点 30 点 · 两单最小间隔 1 秒 · 订单备注可自定义(图 2 中即改为联系标识的示例,成交报表里一眼认出订单归属)
手数设置
首单 0.01 手 · 加仓模式三选一:固定 / 马丁 ×1.5 / 等差 +0.01 · 单笔上限 1.0 手 · 可按余额自动放大首单
网格设置
固定间距 300 点 或 ATR 动态间距(H1 · ATR14 · 系数 1.0)· 间距倍数逐层放大 · 单边最多 10 层
入场信号
默认无信号立即入场;可选 MA(10/30, EMA) 金叉死叉、RSI(14) 30/70、布林带(20, 2.0) 回归、随机指标(5,3,3) 20/80 · 信号周期 M15 · 支持一键反向
止盈设置
篮子止盈 8 启动、回撤 $3 落袋)
风控设置
篮子止损金额 · 账户回撤止损 30% · 日亏损上限 / 日盈利目标 · 最大点差 · 最大总手数 · 最低保证金比例 300% · 交易时段 · 周五定时全平
面板设置
显示开关 · 面板坐标 · 主题强调色 · 均价线绘制
GridPro 输入参数全貌:七组参数与默认值

七、上手五步

  1. 打开 MT5 的 MetaEditor,新建 EA,粘贴文末完整源码,按 F7 编译(0 错误 0 警告);
  2. 确认交易账户为对冲(Hedging)模式(netting 账户会拒绝启动);
  3. 把 EA 拖到目标图表,勾选"允许算法交易";
  4. 先在模拟盘跑默认参数:首单 0.01 手、间距 300 点、马丁 ×1.5、单边最多 10 层、篮子止盈 $10、回撤止损 30%,对照上文观察面板各卡片的变化;
  5. 熟悉逻辑后,再结合品种波动调整间距与层数;持仓期间随时可在面板里改参数,回车生效。

八、几句实话

它是一套策略框架 + 管理面板,不是赚钱的保证:网格不是无风险策略,马丁加仓在单边趋势里会放大回撤,任何参数都无法保证盈利。面板和风控的作用,是把风险约束在你设定的规则内,把账户状态摆在你眼前——决策与责任,始终在使用者自己。请务必先在模拟账户充分测试,理解每一项参数的含义后再考虑其他用途。

九、完整源码(GridPro_Panel_v1.mq5)

以下为完整源码(含版权声明),复制到 MetaEditor 编译即可使用。参数的含义文中都已讲到,源码里另有中文注释对照阅读:

//+------------------------------------------------------------------+//|                                              GridPro_Panel.mq5   |//|   MT5 网格策略 EA + 可视化控制面板(暗色主题,运行时可改参数)      |//|   需要【对冲账户】(Hedging)                                       |//|                                                                  |//|   版权所有 (C) 2026 超哥量化                                      |//|   微信技术交流:fxquant                                           |//|   微信公众号:超哥量化(回复 GRID 获取最新版本与更多量化工具)      |//|                                                                  |//|   本源码随公众号文章公开,供量化爱好者学习交流使用;               |//|   转载请保留本版权声明,请勿用于商业转售。                         |//+------------------------------------------------------------------+#property copyright "版权所有 (C) 2026 超哥量化 · 微信 fxquant · 公众号:超哥量化"#property link      "微信公众号:超哥量化"#property version   "1.00"#property description "可定制网格 EA:多信号入场 / 灵活加仓 / 多重风控 / 实时面板"#include<Trade/Trade.mqh>//--- 枚举 ---------------------------------------------------------enum ENUM_DIR      { DIR_BOTH=0,  // 双向(多空同时)                     DIR_BUY=1,   // 只做多                     DIR_SELL=2 };// 只做空enum ENUM_SIG      { SIG_NONE=0,  // 无信号(立即入场)                     SIG_MA=1,    // 均线金叉/死叉                     SIG_RSI=2,   // RSI 超买超卖                     SIG_BOLL=3,  // 布林带突破回归                     SIG_STOCH=4 };// 随机指标enum ENUM_LOTMODE  { LOT_FIXED=0, // 固定手数                     LOT_MARTI=1, // 倍数递增(马丁)                     LOT_ARITH=2 };// 等差递增enum ENUM_STEPMODE { STEP_FIXED=0,// 固定点数间距                     STEP_ATR=1 };// ATR 动态间距//--- 输入参数 -----------------------------------------------------input group "═══ 基础设置 ═══"input long          InpMagic       = 20260101;     // 魔术号input string        InpComment     = "GridPro";    // 订单备注input ENUM_DIR      InpDir         = DIR_BOTH;     // 交易方向input int           InpSlippage    = 30;           // 最大滑点(点)input int           InpMinInterval = 1;            // 两单最小间隔(秒)input group "═══ 手数设置 ═══"input double        InpFirstLot    = 0.01;         // 首单手数input double        InpAutoLotBal  = 0;            // 自动手数: 每N余额放大一倍首单(0=关)input ENUM_LOTMODE  InpLotMode     = LOT_MARTI;    // 加仓手数模式input double        InpLotMult     = 1.5;          // 加仓手数倍数(马丁)input double        InpLotAdd      = 0.01;         // 加仓手数增量(等差)input double        InpMaxLot      = 1.0;          // 单笔最大手数input group "═══ 网格设置 ═══"input ENUM_STEPMODE InpStepMode    = STEP_FIXED;   // 间距模式input double        InpStepPts     = 300;          // 加仓间距(点)input double        InpStepMult    = 1.0;          // 间距倍数(每层放大)input int           InpAtrPeriod   = 14;           // ATR 周期input ENUM_TIMEFRAMES InpAtrTf     = PERIOD_H1;    // ATR 周期框架input double        InpAtrMult     = 1.0;          // ATR 间距系数input int           InpMaxLevels   = 10;           // 单边最大层数(含首单)input group "═══ 入场信号(仅作用于首单)═══"input ENUM_SIG      InpSignal      = SIG_NONE;     // 入场信号input ENUM_TIMEFRAMES InpSigTf     = PERIOD_M15;   // 信号周期input bool          InpReverse     = false;        // 反向信号input int           InpMAFast      = 10;           // MA 快线input int           InpMASlow      = 30;           // MA 慢线input ENUM_MA_METHOD InpMAMethod   = MODE_EMA;     // MA 类型input int           InpRSIPeriod   = 14;           // RSI 周期input double        InpRSIBuy      = 30;           // RSI 买入线(≤)input double        InpRSISell     = 70;           // RSI 卖出线(≥)input int           InpBBPeriod    = 20;           // 布林周期input double        InpBBDev       = 2.0;          // 布林偏差input int           InpStochK      = 5;            // 随机 %Kinput int           InpStochD      = 3;            // 随机 %Dinput int           InpStochSlow   = 3;            // 随机 Slowinginput double        InpStochLow    = 20;           // 随机超卖线input double        InpStochHigh   = 80;           // 随机超买线input group "═══ 止盈设置(按单边篮子计算)═══"input double        InpTPMoney     = 10.0;         // 篮子止盈金额($, 0=关)input double        InpTPPoints    = 0;            // 均价止盈点数(0=关)input bool          InpTrailOn     = false;        // 启用篮子移动止盈(启用后忽略金额止盈)input double        InpTrailStart  = 8.0;          // 移动止盈启动盈利($)input double        InpTrailGap    = 3.0;          // 移动止盈回撤($)input group "═══ 风控设置 ═══"input double        InpBasketSL    = 0;            // 篮子止损金额($, 0=关)input double        InpMaxDDPct    = 30.0;         // 账户回撤止损%(0=关)input double        InpDailyLoss   = 0;            // 日亏损上限%(0=关)input double        InpDailyProfit = 0;            // 日盈利目标%(0=关)input double        InpMaxSpread   = 0;            // 最大点差(点, 0=不限)input double        InpMaxTotalLots= 0;            // 最大总手数(0=不限)input double        InpMinMarginLvl= 300;          // 最低保证金比例%(低于则停止加仓, 0=关)input bool          InpUseTime     = false;        // 启用交易时段(仅限制首单)input int           InpStartHour   = 8;            // 开始小时(服务器时间)input int           InpEndHour     = 22;           // 结束小时(服务器时间)input int           InpFriCloseHr  = 0;            // 周五几点后全平并停止(0=关)input group "═══ 面板设置 ═══"input bool          InpShowPanel   = true;         // 显示面板input int           InpPanelX      = 15;           // 面板 Xinput int           InpPanelY      = 25;           // 面板 Yinput color         InpAccent      = C'64,156,255';// 主题强调色input bool          InpDrawLines   = true;         // 在图上绘制均价线//--- 常量 ---------------------------------------------------------#define P        "GP_"#define PW       330conststring FONT = "Microsoft YaHei";//--- 配色 ---------------------------------------------------------color C_BG     = C'16,20,30';color C_HEAD   = C'26,32,48';color C_CARD   = C'24,29,42';color C_TEXT   = C'214,222,238';color C_MUTED  = C'124,134,156';color C_GREEN  = C'38,200,130';color C_RED    = C'240,84,100';color C_AMBER  = C'255,184,64';color C_EDIT   = C'34,41,60';//--- 统计结构 -----------------------------------------------------structSideStat  {int      n;double   lots;double   profit;double   avg;double   ext;       // 多单: 最低开仓价, 空单: 最高开仓价double   lastLot;   datetime lastTime;  };//--- 全局状态 -----------------------------------------------------CTrade   trade;SideStat g_b, g_s;int      hFast=INVALID_HANDLE, hSlow=INVALID_HANDLE, hRSI=INVALID_HANDLE,         hBB=INVALID_HANDLE, hStoch=INVALID_HANDLE, hATR=INVALID_HANDLE;// 运行时可修改参数(面板可调)double   g_firstLot, g_stepPts, g_stepMult, g_lotMult, g_tpMoney, g_tpPts, g_ddPct;int      g_maxLevels;bool     g_running   = true;bool     g_minimized = false;string   g_halt      = "";     // 风控停止原因bool     g_haltDaily = false;  // 是否为日内风控(次日自动解除)string   g_note      = "";datetime g_dayKey    = 0;double   g_dayStartEq= 0;double   g_peakB=0, g_peakS=0;datetime g_lastOpen  = 0;int      g_lotDigits = 2;int      g_runStyle  = -1;string   g_res[];#define  BTNW  ((PW-16-12)/3)//+------------------------------------------------------------------+//| 初始化                                                            |//+------------------------------------------------------------------+intOnInit(){if((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)!=ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)     {      Alert("网格 EA 需要【对冲(Hedging)】账户,当前账户类型不支持!");return INIT_FAILED;     }   trade.SetExpertMagicNumber(InpMagic);   trade.SetDeviationInPoints(InpSlippage);   trade.SetTypeFillingBySymbol(_Symbol);double vs=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);   g_lotDigits=0;while(g_lotDigits<8 && MathAbs(vs*MathPow(10,g_lotDigits)-MathRound(vs*MathPow(10,g_lotDigits)))>1e-9) g_lotDigits++;   g_firstLot=InpFirstLot;  g_stepPts=InpStepPts;  g_stepMult=InpStepMult;   g_lotMult=InpLotMult;    g_tpMoney=InpTPMoney;  g_tpPts=InpTPPoints;   g_ddPct=InpMaxDDPct;     g_maxLevels=InpMaxLevels;// 指标句柄switch(InpSignal)     {case SIG_MA:         hFast=iMA(_Symbol,InpSigTf,InpMAFast,0,InpMAMethod,PRICE_CLOSE);         hSlow=iMA(_Symbol,InpSigTf,InpMASlow,0,InpMAMethod,PRICE_CLOSE);if(hFast==INVALID_HANDLE||hSlow==INVALID_HANDLE) return INIT_FAILED;break;case SIG_RSI:         hRSI=iRSI(_Symbol,InpSigTf,InpRSIPeriod,PRICE_CLOSE);if(hRSI==INVALID_HANDLE) return INIT_FAILED;break;case SIG_BOLL:         hBB=iBands(_Symbol,InpSigTf,InpBBPeriod,0,InpBBDev,PRICE_CLOSE);if(hBB==INVALID_HANDLE) return INIT_FAILED;break;case SIG_STOCH:         hStoch=iStochastic(_Symbol,InpSigTf,InpStochK,InpStochD,InpStochSlow,MODE_SMA,STO_LOWHIGH);if(hStoch==INVALID_HANDLE) return INIT_FAILED;break;default: break;     }if(InpStepMode==STEP_ATR)     {      hATR=iATR(_Symbol,InpAtrTf,InpAtrPeriod);if(hATR==INVALID_HANDLE) return INIT_FAILED;     }   RollDay();if(InpShowPanel) BuildPanel();   EventSetMillisecondTimer(500);return INIT_SUCCEEDED;  }voidOnDeinit(constint reason){   EventKillTimer();if(hFast!=INVALID_HANDLE)  IndicatorRelease(hFast);if(hSlow!=INVALID_HANDLE)  IndicatorRelease(hSlow);if(hRSI!=INVALID_HANDLE)   IndicatorRelease(hRSI);if(hBB!=INVALID_HANDLE)    IndicatorRelease(hBB);if(hStoch!=INVALID_HANDLE) IndicatorRelease(hStoch);if(hATR!=INVALID_HANDLE)   IndicatorRelease(hATR);   ObjectsDeleteAll(0,P);for(int i=0;i<ArraySize(g_res);i++) ResourceFree("::"+g_res[i]);   ChartRedraw();  }//+------------------------------------------------------------------+//| 主循环                                                            |//+------------------------------------------------------------------+voidOnTick(){   RollDay();   GetStats(POSITION_TYPE_BUY,g_b);   GetStats(POSITION_TYPE_SELL,g_s);// 1) 账户级风控if(CheckGlobalRisk()) { UpdatePanel(); return; }// 2) 篮子出场bool closed=false;if(ManageExit(true,g_b,g_peakB))  closed=true;if(ManageExit(false,g_s,g_peakS)) closed=true;if(closed)     {      GetStats(POSITION_TYPE_BUY,g_b);      GetStats(POSITION_TYPE_SELL,g_s);     }// 3) 入场 / 加仓   ManageEntries(true,g_b);   ManageEntries(false,g_s);  }voidOnTimer(){   UpdatePanel();   DrawLines();  }//+------------------------------------------------------------------+//| 统计                                                              |//+------------------------------------------------------------------+voidGetStats(const ENUM_POSITION_TYPE type,SideStat &s){   s.n=0; s.lots=0; s.profit=0; s.avg=0; s.ext=0; s.lastLot=0; s.lastTime=0;double pv=0;for(int i=PositionsTotal()-1;i>=0;i--)     {      ulong t=PositionGetTicket(i);if(t==0) continue;if(PositionGetString(POSITION_SYMBOL)!=_Symbol) continue;if(PositionGetInteger(POSITION_MAGIC)!=InpMagic) continue;if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)!=type) continue;double   v=PositionGetDouble(POSITION_VOLUME);double   p=PositionGetDouble(POSITION_PRICE_OPEN);      datetime tm=(datetime)PositionGetInteger(POSITION_TIME);      s.n++;      s.lots+=v;      pv+=p*v;      s.profit+=PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_SWAP);if(type==POSITION_TYPE_BUY) { if(s.ext==0 || p<s.ext) s.ext=p; }else                        { if(p>s.ext) s.ext=p; }if(tm>=s.lastTime) { s.lastTime=tm; s.lastLot=v; }     }if(s.lots>0) s.avg=pv/s.lots;  }//+------------------------------------------------------------------+//| 手数计算                                                          |//+------------------------------------------------------------------+doubleNormLot(double lot){double step=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);double mn=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);double mx=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);if(InpMaxLot>0) mx=MathMin(mx,InpMaxLot);   lot=MathFloor(lot/step+1e-8)*step;   lot=MathMax(mn,MathMin(mx,lot));return NormalizeDouble(lot,g_lotDigits);  }doubleFirstLot(){double lot=g_firstLot;if(InpAutoLotBal>0)     {double k=MathMax(1.0,MathFloor(AccountInfoDouble(ACCOUNT_BALANCE)/InpAutoLotBal));      lot*=k;     }return lot;  }doubleCalcLot(int n,double lastLot){double lot;if(n==0) lot=FirstLot();else     {switch(InpLotMode)        {case LOT_MARTI: lot=lastLot*g_lotMult;            break;case LOT_ARITH: lot=FirstLot()+n*InpLotAdd;        break;default:        lot=FirstLot();                    break;        }     }return NormLot(lot);  }//+------------------------------------------------------------------+//| 间距(点)                                                        |//+------------------------------------------------------------------+doubleStepDistance(int n){double base=g_stepPts;if(InpStepMode==STEP_ATR && hATR!=INVALID_HANDLE)     {double a[];      ArraySetAsSeries(a,true);if(CopyBuffer(hATR,0,1,1,a)==1 && a[0]>0) base=a[0]*InpAtrMult/_Point;     }return base*MathPow(g_stepMult,MathMax(0,n-1));  }//+------------------------------------------------------------------+//| 入场信号: 1=买 -1=卖 0=无                                         |//+------------------------------------------------------------------+boolBuf(int h,int idx,double &arr[],int cnt=3){   ArraySetAsSeries(arr,true);return CopyBuffer(h,idx,0,cnt,arr)==cnt;  }intGetSignal(){int sig=0;double a[],b[],c[];switch(InpSignal)     {case SIG_NONE: return0;case SIG_MA:if(Buf(hFast,0,a) && Buf(hSlow,0,b))           {if(a[2]<=b[2] && a[1]>b[1]) sig=1;if(a[2]>=b[2] && a[1]<b[1]) sig=-1;           }break;case SIG_RSI:if(Buf(hRSI,0,a))           {if(a[1]<=InpRSIBuy)  sig=1;if(a[1]>=InpRSISell) sig=-1;           }break;case SIG_BOLL:if(Buf(hBB,1,a) && Buf(hBB,2,b))           {double cl=iClose(_Symbol,InpSigTf,1);if(cl<b[1]) sig=1;if(cl>a[1]) sig=-1;           }break;case SIG_STOCH:if(Buf(hStoch,0,a) && Buf(hStoch,1,b))           {if(a[1]<=InpStochLow  && a[1]>b[1]) sig=1;if(a[1]>=InpStochHigh && a[1]<b[1]) sig=-1;           }break;     }if(InpReverse) sig=-sig;return sig;  }//+------------------------------------------------------------------+//| 过滤条件                                                          |//+------------------------------------------------------------------+boolTimeOK(){   MqlDateTime t; TimeToStruct(TimeCurrent(),t);if(InpFriCloseHr>0 && t.day_of_week==5 && t.hour>=InpFriCloseHr) returnfalse;if(!InpUseTime) returntrue;if(InpStartHour<=InpEndHour) return (t.hour>=InpStartHour && t.hour<InpEndHour);return (t.hour>=InpStartHour || t.hour<InpEndHour);   // 跨午夜  }boolEntryAllowed(){if(!g_running)      { returnfalse; }if(g_halt!="")      { returnfalse; }if(TimeCurrent()-g_lastOpen<InpMinInterval) returnfalse;if(InpMaxSpread>0 && SymbolInfoInteger(_Symbol,SYMBOL_SPREAD)>InpMaxSpread)     { g_note="点差过大,暂停开仓"; returnfalse; }double ml=AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);if(InpMinMarginLvl>0 && ml>0 && ml<InpMinMarginLvl)     { g_note="保证金比例过低,停止加仓"; returnfalse; }returntrue;  }//+------------------------------------------------------------------+//| 开仓                                                              |//+------------------------------------------------------------------+boolOpenOrder(bool isBuy,double lot){if(lot<=0) returnfalse;if(InpMaxTotalLots>0 && g_b.lots+g_s.lots+lot>InpMaxTotalLots+1e-8)     { g_note="已达最大总手数"; returnfalse; }double price=isBuy?SymbolInfoDouble(_Symbol,SYMBOL_ASK):SymbolInfoDouble(_Symbol,SYMBOL_BID);double m;if(OrderCalcMargin(isBuy?ORDER_TYPE_BUY:ORDER_TYPE_SELL,_Symbol,lot,price,m) &&      m>AccountInfoDouble(ACCOUNT_MARGIN_FREE))     { g_note="可用保证金不足"; returnfalse; }bool ok=isBuy?trade.Buy(lot,_Symbol,0,0,0,InpComment):trade.Sell(lot,_Symbol,0,0,0,InpComment);if(ok) { g_lastOpen=TimeCurrent(); g_note=""; }else   { g_note="开仓失败: "+IntegerToString(trade.ResultRetcode()); Print(g_note," ",trade.ResultRetcodeDescription()); }return ok;  }voidManageEntries(bool isBuy,SideStat &s){if(isBuy  && InpDir==DIR_SELL) return;if(!isBuy && InpDir==DIR_BUY)  return;if(!EntryAllowed()) return;if(s.n==0)   // 首单     {if(!TimeOK()) return;if(InpSignal!=SIG_NONE)        {int sig=GetSignal();if(isBuy && sig!=1)   return;if(!isBuy && sig!=-1) return;        }      OpenOrder(isBuy,CalcLot(0,0));return;     }if(s.n>=g_maxLevels) return;   // 加仓double dist =StepDistance(s.n)*_Point;double price=isBuy?SymbolInfoDouble(_Symbol,SYMBOL_ASK):SymbolInfoDouble(_Symbol,SYMBOL_BID);bool hit=isBuy?(price<=s.ext-dist):(price>=s.ext+dist);if(hit) OpenOrder(isBuy,CalcLot(s.n,s.lastLot));  }//+------------------------------------------------------------------+//| 平仓                                                              |//+------------------------------------------------------------------+voidCloseSide(bool isBuy){   ENUM_POSITION_TYPE type=isBuy?POSITION_TYPE_BUY:POSITION_TYPE_SELL;for(int i=PositionsTotal()-1;i>=0;i--)     {      ulong t=PositionGetTicket(i);if(t==0) continue;if(PositionGetString(POSITION_SYMBOL)!=_Symbol) continue;if(PositionGetInteger(POSITION_MAGIC)!=InpMagic) continue;if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)!=type) continue;      trade.PositionClose(t);     }  }voidCloseAll(){ CloseSide(true); CloseSide(false); }boolManageExit(bool isBuy,SideStat &s,double &peak){if(s.n==0) { peak=0; returnfalse; }bool close=false;if(InpBasketSL>0 && s.profit<=-InpBasketSL) close=true;elseif(InpTrailOn)     {if(s.profit>=InpTrailStart)        {         peak=MathMax(peak,s.profit);if(s.profit<=peak-InpTrailGap) close=true;        }     }elseif(g_tpMoney>0 && s.profit>=g_tpMoney) close=true;if(!close && g_tpPts>0)     {double bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);if(isBuy  && bid>=s.avg+g_tpPts*_Point) close=true;if(!isBuy && ask<=s.avg-g_tpPts*_Point) close=true;     }if(close) { CloseSide(isBuy); peak=0; returntrue; }returnfalse;  }//+------------------------------------------------------------------+//| 风控                                                              |//+------------------------------------------------------------------+voidRollDay(){   datetime d=iTime(_Symbol,PERIOD_D1,0);if(d!=g_dayKey)     {      g_dayKey=d;      g_dayStartEq=AccountInfoDouble(ACCOUNT_EQUITY);if(g_haltDaily) { g_halt=""; g_haltDaily=false; }     }  }boolCheckGlobalRisk(){double bal=AccountInfoDouble(ACCOUNT_BALANCE);double eq =AccountInfoDouble(ACCOUNT_EQUITY);bool   has=(g_b.n+g_s.n)>0;// 周五定时全平if(InpFriCloseHr>0 && has)     {      MqlDateTime t; TimeToStruct(TimeCurrent(),t);if(t.day_of_week==5 && t.hour>=InpFriCloseHr)        { CloseAll(); g_note="周五定时全平"; returntrue; }     }if(has && g_ddPct>0 && bal>0 && (bal-eq)/bal*100.0>=g_ddPct)     {      CloseAll();      g_halt="回撤止损触发"; g_haltDaily=false; g_running=false;      Alert("GridPro: 账户回撤达到 ",DoubleToString(g_ddPct,1),"%,已全平并停止");returntrue;     }if(g_dayStartEq>0)     {if(InpDailyLoss>0 && (g_dayStartEq-eq)/g_dayStartEq*100.0>=InpDailyLoss && g_halt=="")        {if(has) CloseAll();         g_halt="日亏损上限"; g_haltDaily=true;return has;        }if(InpDailyProfit>0 && (eq-g_dayStartEq)/g_dayStartEq*100.0>=InpDailyProfit && g_halt=="")        {if(has) CloseAll();         g_halt="日盈利达标"; g_haltDaily=true;return has;        }     }returnfalse;  }//+------------------------------------------------------------------+//| 图上均价线                                                        |//+------------------------------------------------------------------+voidDrawLine(string name,double price,color clr){   name=P+name;if(!InpDrawLines || price<=0) { ObjectDelete(0,name); return; }if(ObjectFind(0,name)<0)     {      ObjectCreate(0,name,OBJ_HLINE,0,0,price);      ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_DASH);      ObjectSetInteger(0,name,OBJPROP_COLOR,clr);      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);     }   ObjectSetDouble(0,name,OBJPROP_PRICE,price);  }voidDrawLines(){   SideStat b,s;   GetStats(POSITION_TYPE_BUY,b);   GetStats(POSITION_TYPE_SELL,s);   DrawLine("L_buy",b.avg,C_GREEN);   DrawLine("L_sell",s.avg,C_RED);  }//+------------------------------------------------------------------+//| ============================ 面板 ============================== |//+------------------------------------------------------------------+voidRegRes(string name){for(int i=0;i<ArraySize(g_res);i++) if(g_res[i]==name) return;int n=ArraySize(g_res);   ArrayResize(g_res,n+1);   g_res[n]=name;  }// 生成抗锯齿圆角矩形位图资源(带 1px 描边)voidRoundRes(string name,int w,int h,int r,color fill,color border){   uint px[];   ArrayResize(px,w*h);double fr=(double)((uint)fill&0xFF),   fg=(double)(((uint)fill>>8)&0xFF),   fb=(double)(((uint)fill>>16)&0xFF);double br=(double)((uint)border&0xFF), bg=(double)(((uint)border>>8)&0xFF), bb=(double)(((uint)border>>16)&0xFF);double hw=w/2.0, hh=h/2.0;for(int y=0;y<h;y++)for(int x=0;x<w;x++)        {double qx=MathAbs(x+0.5-hw)-(hw-r);double qy=MathAbs(y+0.5-hh)-(hh-r);double ox=MathMax(qx,0.0), oy=MathMax(qy,0.0);double d=MathSqrt(ox*ox+oy*oy)+MathMin(MathMax(qx,qy),0.0)-r;double ao=MathMax(0.0,MathMin(1.0,0.5-d));double ai=MathMax(0.0,MathMin(1.0,0.5-(d+1.0)));         uint rr=(uint)MathRound(br+(fr-br)*ai);         uint gg=(uint)MathRound(bg+(fg-bg)*ai);         uint b2=(uint)MathRound(bb+(fb-bb)*ai);         px[y*w+x]=((uint)MathRound(ao*255.0)<<24)|(rr<<16)|(gg<<8)|b2;        }   ResourceCreate("::"+name,px,w,h,0,0,w,COLOR_FORMAT_ARGB_NORMALIZE);   RegRes(name);  }voidSetBmp(string objName,string resName){   ObjectSetString(0,objName,OBJPROP_BMPFILE,0,"::"+resName);   ObjectSetString(0,objName,OBJPROP_BMPFILE,1,"::"+resName);  }// 圆角矩形(位图实现,MT5 原生矩形不支持圆角)voidRect(string id,int x,int y,int w,int h,color bg,color border,int r=10){string n=P+id;string res="GP_"+id;   RoundRes(res,w,h,r,bg,border);   ObjectCreate(0,n,OBJ_BITMAP_LABEL,0,0,0);   ObjectSetInteger(0,n,OBJPROP_XDISTANCE,InpPanelX+x);   ObjectSetInteger(0,n,OBJPROP_YDISTANCE,InpPanelY+y);   SetBmp(n,res);   ObjectSetInteger(0,n,OBJPROP_BACK,false);   ObjectSetInteger(0,n,OBJPROP_SELECTABLE,false);   ObjectSetInteger(0,n,OBJPROP_HIDDEN,true);   ObjectSetInteger(0,n,OBJPROP_ZORDER,0);  }voidLabel(string id,int x,int y,string txt,color clr,int size=9){string n=P+id;   ObjectCreate(0,n,OBJ_LABEL,0,0,0);   ObjectSetInteger(0,n,OBJPROP_XDISTANCE,InpPanelX+x);   ObjectSetInteger(0,n,OBJPROP_YDISTANCE,InpPanelY+y);   ObjectSetInteger(0,n,OBJPROP_COLOR,clr);   ObjectSetInteger(0,n,OBJPROP_FONTSIZE,size);   ObjectSetString(0,n,OBJPROP_FONT,FONT);   ObjectSetString(0,n,OBJPROP_TEXT,txt);   ObjectSetInteger(0,n,OBJPROP_SELECTABLE,false);   ObjectSetInteger(0,n,OBJPROP_HIDDEN,true);   ObjectSetInteger(0,n,OBJPROP_ZORDER,1);  }voidButton(string id,int x,int y,int w,int h,string txt,color bg,color fg=clrWhite){   Rect("r_bb_"+id,x,y,w,h,bg,bg,8);       // 圆角底板string n=P+id;   ObjectCreate(0,n,OBJ_BUTTON,0,0,0);     // 原生按钮内缩 3px 叠在底板上,负责点击   ObjectSetInteger(0,n,OBJPROP_XDISTANCE,InpPanelX+x+3);   ObjectSetInteger(0,n,OBJPROP_YDISTANCE,InpPanelY+y+3);   ObjectSetInteger(0,n,OBJPROP_XSIZE,w-6);   ObjectSetInteger(0,n,OBJPROP_YSIZE,h-6);   ObjectSetInteger(0,n,OBJPROP_BGCOLOR,bg);   ObjectSetInteger(0,n,OBJPROP_BORDER_COLOR,bg);   ObjectSetInteger(0,n,OBJPROP_COLOR,fg);   ObjectSetInteger(0,n,OBJPROP_FONTSIZE,9);   ObjectSetString(0,n,OBJPROP_FONT,FONT);   ObjectSetString(0,n,OBJPROP_TEXT,txt);   ObjectSetInteger(0,n,OBJPROP_SELECTABLE,false);   ObjectSetInteger(0,n,OBJPROP_HIDDEN,true);   ObjectSetInteger(0,n,OBJPROP_ZORDER,2);  }voidEditBox(string id,int x,int y,int w,int h,string txt){   Rect("r_eb_"+id,x,y,w,h,C_EDIT,InpAccent,7);   // 圆角描边底板string n=P+id;   ObjectCreate(0,n,OBJ_EDIT,0,0,0);   ObjectSetInteger(0,n,OBJPROP_XDISTANCE,InpPanelX+x+3);   ObjectSetInteger(0,n,OBJPROP_YDISTANCE,InpPanelY+y+3);   ObjectSetInteger(0,n,OBJPROP_XSIZE,w-6);   ObjectSetInteger(0,n,OBJPROP_YSIZE,h-6);   ObjectSetInteger(0,n,OBJPROP_BGCOLOR,C_EDIT);   ObjectSetInteger(0,n,OBJPROP_BORDER_COLOR,C_EDIT);   ObjectSetInteger(0,n,OBJPROP_COLOR,C_TEXT);   ObjectSetInteger(0,n,OBJPROP_ALIGN,ALIGN_CENTER);   ObjectSetInteger(0,n,OBJPROP_FONTSIZE,9);   ObjectSetString(0,n,OBJPROP_FONT,FONT);   ObjectSetString(0,n,OBJPROP_TEXT,txt);   ObjectSetInteger(0,n,OBJPROP_SELECTABLE,false);   ObjectSetInteger(0,n,OBJPROP_HIDDEN,true);   ObjectSetInteger(0,n,OBJPROP_ZORDER,2);  }voidParamRow(string key,string title,int lx,int ex,int y,int ew){   Label("t_"+key,lx,y+5,title,C_MUTED,8);   EditBox("E_"+key,ex,y,ew,24,"");  }voidBuildPanel(){   ObjectsDeleteAll(0,P+"E_");   ObjectsDeleteAll(0,P+"b_");   ObjectsDeleteAll(0,P+"t_");   ObjectsDeleteAll(0,P+"v_");   ObjectsDeleteAll(0,P+"r_");   g_runStyle=-1;int H=g_minimized?36:408;   Rect("r_bg",0,0,PW,H,C_BG,InpAccent,16);   Rect("r_head",3,3,PW-6,30,C_HEAD,C_HEAD,13);   Rect("r_bar",12,11,4,14,InpAccent,InpAccent,2);   Label("t_title",24,9,"◆ GRID PRO  "+_Symbol,C_TEXT,10);   Label("v_status",196,11,"● 运行中",C_GREEN,8);   Button("b_min",PW-38,4,28,28,g_minimized?"+":"–",C_EDIT,C_TEXT);if(g_minimized) { UpdatePanel(); ChartRedraw(); return; }// 账户卡片   Rect("r_c1",8,42,PW-16,68,C_CARD,C_CARD);   Label("t_bal",16,50,"余额",C_MUTED,8);  Label("v_bal",54,49,"-",C_TEXT,9);   Label("t_eq",172,50,"净值",C_MUTED,8);  Label("v_eq",210,49,"-",C_TEXT,9);   Label("t_pl",16,72,"浮盈",C_MUTED,8);   Label("v_pl",54,71,"-",C_TEXT,9);   Label("t_dd",172,72,"回撤",C_MUTED,8);  Label("v_dd",210,71,"-",C_TEXT,9);   Label("t_sp",16,94,"点差",C_MUTED,8);   Label("v_sp",54,93,"-",C_TEXT,9);   Label("t_day",172,94,"今日",C_MUTED,8); Label("v_day",210,93,"-",C_TEXT,9);// 持仓卡片   Rect("r_c2",8,116,PW-16,46,C_CARD,C_CARD);   Label("v_b",16,122,"-",C_GREEN,9);   Label("v_s",16,142,"-",C_RED,9);// 参数卡片   Rect("r_c3",8,168,PW-16,142,C_CARD,C_CARD);   Label("t_ptitle",16,174,"参数(回车生效,实时可改)",InpAccent,8);   ParamRow("lot",  "首单手数",16, 84,194,64);   ParamRow("step", "间距(点)",172,238,194,72);   ParamRow("smult","间距倍数",16, 84,222,64);   ParamRow("lmult","手数倍数",172,238,222,72);   ParamRow("maxlv","最大层数",16, 84,250,64);   ParamRow("tp",   "止盈($)", 172,238,250,72);   ParamRow("tppts","止盈(点)",16, 84,278,64);   ParamRow("dd",   "回撤止损%",172,238,278,72);   SyncEdits();// 按钮int bw=BTNW;   Button("b_run", 8,        318,bw,30,"",C_GREEN);   Button("b_buy", 8+bw+6,   318,bw,30,"立即买入",C'30,110,200');   Button("b_sell",8+2*(bw+6),318,bw,30,"立即卖出",C'200,70,90');   Button("b_cb",  8,        354,bw,30,"平多单",C_EDIT,C_TEXT);   Button("b_cs",  8+bw+6,   354,bw,30,"平空单",C_EDIT,C_TEXT);   Button("b_ca",  8+2*(bw+6),354,bw,30,"全部平仓",C'150,50,60');   Label("v_note",14,390,"",C_AMBER,8);   UpdatePanel();   ChartRedraw();  }voidSetT(string id,string txt,color clr=clrNONE){string n=P+id;   ObjectSetString(0,n,OBJPROP_TEXT,txt);if(clr!=clrNONE) ObjectSetInteger(0,n,OBJPROP_COLOR,clr);  }color PnlColor(double v){ return v>0?C_GREEN:(v<0?C_RED:C_TEXT); }voidSyncEdits(){   ObjectSetString(0,P+"E_lot",  OBJPROP_TEXT,DoubleToString(g_firstLot,g_lotDigits));   ObjectSetString(0,P+"E_step", OBJPROP_TEXT,DoubleToString(g_stepPts,0));   ObjectSetString(0,P+"E_smult",OBJPROP_TEXT,DoubleToString(g_stepMult,2));   ObjectSetString(0,P+"E_lmult",OBJPROP_TEXT,DoubleToString(g_lotMult,2));   ObjectSetString(0,P+"E_maxlv",OBJPROP_TEXT,IntegerToString(g_maxLevels));   ObjectSetString(0,P+"E_tp",   OBJPROP_TEXT,DoubleToString(g_tpMoney,2));   ObjectSetString(0,P+"E_tppts",OBJPROP_TEXT,DoubleToString(g_tpPts,0));   ObjectSetString(0,P+"E_dd",   OBJPROP_TEXT,DoubleToString(g_ddPct,1));  }voidUpdatePanel(){if(!InpShowPanel) return;   SideStat b,s;   GetStats(POSITION_TYPE_BUY,b);   GetStats(POSITION_TYPE_SELL,s);double bal=AccountInfoDouble(ACCOUNT_BALANCE);double eq =AccountInfoDouble(ACCOUNT_EQUITY);double pl =b.profit+s.profit;double dd =(bal>0)?MathMax(0.0,(bal-eq)/bal*100.0):0.0;double day=eq-g_dayStartEq;// 状态if(g_halt!="")      SetT("v_status","● "+g_halt,C_RED);elseif(!g_running) SetT("v_status","● 已暂停",C_AMBER);else                SetT("v_status","● 运行中",C_GREEN);if(g_minimized) return;   SetT("v_bal",DoubleToString(bal,2));   SetT("v_eq", DoubleToString(eq,2));   SetT("v_pl", (pl>=0?"+":"")+DoubleToString(pl,2),PnlColor(pl));   SetT("v_dd", DoubleToString(dd,2)+"%",dd>=10?C_RED:C_TEXT);   SetT("v_sp", IntegerToString((int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD)));   SetT("v_day",(day>=0?"+":"")+DoubleToString(day,2),PnlColor(day));   SetT("v_b","▲ 多单  "+IntegerToString(b.n)+" 单 | "+DoubleToString(b.lots,g_lotDigits)+" 手 | "+        (b.profit>=0?"+":"")+DoubleToString(b.profit,2));   SetT("v_s","▼ 空单  "+IntegerToString(s.n)+" 单 | "+DoubleToString(s.lots,g_lotDigits)+" 手 | "+        (s.profit>=0?"+":"")+DoubleToString(s.profit,2));// 运行按钮(圆角底板随状态换色)int rs=g_running?1:0;   color rc=g_running?C_AMBER:C_GREEN;if(rs!=g_runStyle)     {      g_runStyle=rs;      RoundRes("GP_r_bb_b_run",BTNW,30,8,rc,rc);      SetBmp(P+"r_bb_b_run","GP_r_bb_b_run");      ObjectSetInteger(0,P+"b_run",OBJPROP_BGCOLOR,rc);      ObjectSetInteger(0,P+"b_run",OBJPROP_BORDER_COLOR,rc);     }   ObjectSetString(0,P+"b_run",OBJPROP_TEXT,g_running?"⏸ 暂停":"▶ 启动");   ObjectSetInteger(0,P+"b_run",OBJPROP_COLOR,C'20,20,20');   SetT("v_note",g_note);   ChartRedraw();  }//+------------------------------------------------------------------+//| 面板事件                                                          |//+------------------------------------------------------------------+voidManualOpen(bool isBuy){   GetStats(POSITION_TYPE_BUY,g_b);   GetStats(POSITION_TYPE_SELL,g_s);   SideStat s=isBuy?g_b:g_s;   OpenOrder(isBuy,CalcLot(s.n,s.lastLot));  }voidApplyEdit(string name){string key=StringSubstr(name,StringLen(P)+2);   // 去掉 "GP_E_"double v=StringToDouble(ObjectGetString(0,name,OBJPROP_TEXT));if(key=="lot"   && v>0)  g_firstLot=v;if(key=="step"  && v>0)  g_stepPts=v;if(key=="smult" && v>0)  g_stepMult=v;if(key=="lmult" && v>0)  g_lotMult=v;if(key=="maxlv" && v>=1) g_maxLevels=(int)v;if(key=="tp"    && v>=0) g_tpMoney=v;if(key=="tppts" && v>=0) g_tpPts=v;if(key=="dd"    && v>=0) g_ddPct=v;   SyncEdits();   ChartRedraw();  }voidOnChartEvent(constint id,constlong &lparam,constdouble &dparam,conststring &sparam){if(!InpShowPanel) return;if(id==CHARTEVENT_OBJECT_ENDEDIT && StringFind(sparam,P+"E_")==0)     { ApplyEdit(sparam); return; }if(id!=CHARTEVENT_OBJECT_CLICK) return;if(StringFind(sparam,P+"b_")!=0) return;if(sparam==P+"b_min")  { g_minimized=!g_minimized; BuildPanel(); return; }if(sparam==P+"b_run")     {      g_running=!g_running;if(g_running) { g_halt=""; g_haltDaily=false; g_note=""; }     }elseif(sparam==P+"b_buy")  ManualOpen(true);elseif(sparam==P+"b_sell") ManualOpen(false);elseif(sparam==P+"b_cb")   CloseSide(true);elseif(sparam==P+"b_cs")   CloseSide(false);elseif(sparam==P+"b_ca")   CloseAll();   ObjectSetInteger(0,sparam,OBJPROP_STATE,false);   // 按钮弹起   UpdatePanel();  }//+------------------------------------------------------------------+

🎁 获取方式

完整源码就在上文第九节,复制到 MetaEditor 按 F7 编译即可使用——不设门槛,无需任何形式的"提取"或"解密"。

觉得有用的话,欢迎关注公众号「超哥量化」:GridPro 后续版本的升级动态、参数进阶玩法,以及更多量化策略源码与交易工具,都会第一时间在那里发布。

回复关键词 FTA,还可以获取另一款 MT5 图上快速交易工具 Fast Trade Assistant(市价下单、鼠标挂单、批量平仓、仓位保护一应俱全)。

⚠️ 风险提示

  1. 杠杆交易(如外汇、贵金属、差价合约)具有高风险,可能导致损失全部本金,请充分了解相关风险后再参与交易。
  2. 网格策略在单边行情中会持续加仓,马丁类手数递增会同步放大仓位与回撤,极端行情下可能造成较大亏损,请务必理解策略原理并配置风控后再使用。
  3. 本文源码仅供技术交流与学习参考,不构成任何投资建议,不生成交易信号;所有交易决策由使用者自行做出。
  4. 新策略请先在模拟账户(Demo)上充分测试,确认逻辑与风险可控后再考虑用于实盘;任何参数设置都无法保证盈利。
  5. 过往表现不代表未来结果,历史回测结论存在失效风险。

欢迎关注公众号"超哥量化",获取更多量化交易技术分析内容与智能交易工具资讯。如需量化学习资料、技术交流或个性化指标定制服务,可通过公众号留言与我们取得联系。软件定制开发,请联系技术支持。


    相关学习资料