MQL5交易策略自动化(第十七部分):借助动态仪表盘精通网格马丁格尔(Grid-Mart)短线交易策略·进阶篇
(2/3)·2.0点间隔、4点微利、层级指数膨胀——这套EA怎么在波动市活下来
「网格马丁头皮EA的输入参数骨架」
这套网格马丁头皮策略在 MT5 里靠一组 input 参数驱动,先把外层开关和仓位逻辑定清楚,后面才好接网格层。EA 名称定为 GridMart Scalper,CONTINUE_TRADING 默认 true,意味着一个交易周期平仓后若条件仍在,会继续开下一轮,MAX_CYCLES 给到 1000 圈上限防止死循环。 交易时段由 START_HOUR=0 与 END_HOUR=23 框定,等于全天运行;LOT_MODE=1 代表按乘数加仓,BASE_LOT=0.01 是首层底仓。STOP_LOSS_PIPS=100 而 TAKE_PROFIT_PIPS=3,典型的薄利宽损头皮结构,配合 GRID_DISTANCE=3.0 pips 的网格间距,在 EURUSD 这类点差 1~2 pip 品种上可能频繁触发平仓。 加仓梯度由 LOT_MULTIPLIER=1.3 控制,每下一层仓位乘 1.3 倍,MAX_GRID_LEVELS=30 封顶。若从 0.01 手起按 1.3 倍铺满 30 层,末层手数约 0.01×1.3^29 ≈ 12.2 手,外汇和贵金属属高风险,这种指数加仓在单边行情中回撤可能极快。 风控组默认关闭:ENABLE_DAILY_DRAWDOWN=false、DRAWDOWN_LIMIT=-1.0、CLOSE_ON_DRAWDOWN=false,实盘前建议手动开启并填阈值。面板参数 PANEL_X=30、PANEL_Y=50 决定 HUD 左上偏移,DASHBOARD_WIDTH=300、HEIGHT=260 是像素尺寸,pipValue 为运行时按品种算出的点值变量。 下面逐行拆这组声明,复制进 MQ5 文件头部即可编译: input string EA_NAME = "GridMart Scalper"; // 定义EA名称字符串输入 input bool CONTINUE_TRADING = true; // 周期结束后是否继续交易 input int MAX_CYCLES = 1000; // 最大交易周期数 input int START_HOUR = 0; // 交易开始小时 input int END_HOUR = 23; // 交易结束小时 input int LOT_MODE = 1; // 手数模式:1乘数 2固定 input double BASE_LOT = 0.01; // 基础手数 input int STOP_LOSS_PIPS = 100; // 止损点数 input int TAKE_PROFIT_PIPS = 3; // 止盈点数 input double GRID_DISTANCE = 3.0; // 网格间距点数 input double LOT_MULTIPLIER = 1.3; // 手数乘数 input int MAX_GRID_LEVELS = 30; // 最大网格层数 input int LOT_PRECISION = 2; // 手数小数精度 input int MAGIC = 1234567890; // 魔术码 input color TEXT_COLOR = clrWhite; // 面板文字色 input group "EA Risk Management Settings" // 风控参数分组 input bool ENABLE_DAILY_DRAWDOWN = false; // 日回撤限制开关 input double DRAWDOWN_LIMIT = -1.0; // 日回撤阈值(%) input bool CLOSE_ON_DRAWDOWN = false; // 触阈是否平仓 input group "Dashboard Settings" // 面板参数分组 input int PANEL_X = 30; // 面板X像素偏移 input int PANEL_Y = 50; // 面板Y像素偏移 double pipValue; // 点值变量 const int DASHBOARD_WIDTH = 300; // 面板宽像素 const int DASHBOARD_HEIGHT = 260; // 面板高像素
input class="type">class="kw">string EA_NAME = "GridMart Scalper"; class=class="str">"cmt">// EA Name input class="type">bool CONTINUE_TRADING = true; class=class="str">"cmt">// Continue Trading After Cycle input class="type">int MAX_CYCLES = class="num">1000; class=class="str">"cmt">// Max Trading Cycles input class="type">int START_HOUR = class="num">0; class=class="str">"cmt">// Start Trading Hour input class="type">int END_HOUR = class="num">23; class=class="str">"cmt">// End Trading Hour input class="type">int LOT_MODE = class="num">1; class=class="str">"cmt">// Lot Mode(class="num">1=Multiplier, class="num">2=Fixed) input class="type">class="kw">double BASE_LOT = class="num">0.01; class=class="str">"cmt">// Base Lot Size input class="type">int STOP_LOSS_PIPS = class="num">100; class=class="str">"cmt">// Stop Loss(Pips) input class="type">int TAKE_PROFIT_PIPS = class="num">3; class=class="str">"cmt">// Take Profit(Pips) input class="type">class="kw">double GRID_DISTANCE = class="num">3.0; class=class="str">"cmt">// Grid Distance(Pips) input class="type">class="kw">double LOT_MULTIPLIER = class="num">1.3; class=class="str">"cmt">// Lot Multiplier input class="type">int MAX_GRID_LEVELS = class="num">30; class=class="str">"cmt">// Max Grid Levels input class="type">int LOT_PRECISION = class="num">2; class=class="str">"cmt">// Lot Decimal Precision input class="type">int MAGIC = class="num">1234567890; class=class="str">"cmt">// Magic Number input class="type">color TEXT_COLOR = clrWhite; class=class="str">"cmt">// Dashboard Text Color input group "EA Risk Management Settings" input class="type">bool ENABLE_DAILY_DRAWDOWN = false; class=class="str">"cmt">// Enable Daily Drawdown Limiter input class="type">class="kw">double DRAWDOWN_LIMIT = -class="num">1.0; class=class="str">"cmt">// Daily Drawdown Threshold(-%) input class="type">bool CLOSE_ON_DRAWDOWN = false; class=class="str">"cmt">// Close Positions When Threshold Hit input group "Dashboard Settings" input class="type">int PANEL_X = class="num">30; class=class="str">"cmt">// Initial X Distance(pixels) input class="type">int PANEL_Y = class="num">50; class=class="str">"cmt">// Initial Y Distance(pixels) class=class="str">"cmt">//--- Pip value for price calculations class="type">class="kw">double pipValue; class=class="str">"cmt">//--- Dashboard constants const class="type">int DASHBOARD_WIDTH = class="num">300; class=class="str">"cmt">//--- Width of the dashboard in pixels const class="type">int DASHBOARD_HEIGHT = class="num">260; class=class="str">"cmt">//--- Height of the dashboard in pixels
◍ 面板常量与余额取数怎么定
做 MT5 自定义盯盘面板,第一件事是把界面尺寸和配色固化成常量,避免后期调样式时满屏改字面量。下面这段把头部高度锁在 30 像素、关闭按钮 40×28,悬停时头部从 clrGold 切到 C'200,150,0',关闭键背景由 clrCrimson 变 clrDodgerBlue——这些都是直接抄进代码就能跑的硬参数。 数值语义也靠颜色区分:正向盈利用 clrLimeGreen,亏损用 clrHotPink,回撤激活态用 clrRed。字体上头部 12pt、区块标题 11pt、指标值 9pt,按钮 12pt,在 1920×1080 下基本不挤。 取账户余额不需要自己算,直接包一层 AccountInfoDouble(ACCOUNT_BALANCE) 就行。下面代码逐行拆完,你开 MT5 新建 EA 把这段贴进全局,编译零报错就能用。 别把常量当装饰 面板常量若散落在绘图函数里,改一次主题色要搜几十处;集中成 const 后,调金色主题只动 HEADER_NORMAL_COLOR 一行。外汇与贵金属波动剧烈,面板误读颜色可能让你错判回撤,实盘前务必在策略测试器里跑一遍视觉校验。
const class="type">int HEADER_HEIGHT = class="num">30; class=class="str">"cmt">//--- Height of the header section const class="type">int CLOSE_BUTTON_WIDTH = class="num">40; class=class="str">"cmt">//--- Width of the close button const class="type">int CLOSE_BUTTON_HEIGHT = class="num">28; class=class="str">"cmt">//--- Height of the close button const class="type">color HEADER_NORMAL_COLOR = clrGold; class=class="str">"cmt">//--- Normal class="type">color of the header const class="type">color HEADER_HOVER_COLOR = C&class="macro">#x27;class="num">200,class="num">150,class="num">0&class="macro">#x27;; class=class="str">"cmt">//--- Header class="type">color when hovered const class="type">color BACKGROUND_COLOR = clrDarkSlateGray; class=class="str">"cmt">//--- Background class="type">color of the dashboard const class="type">color BORDER_COLOR = clrBlack; class=class="str">"cmt">//--- Border class="type">color of dashboard elements const class="type">color SECTION_TITLE_COLOR = clrLightGray; class=class="str">"cmt">//--- Color for section titles const class="type">color CLOSE_BUTTON_NORMAL_BG = clrCrimson; class=class="str">"cmt">//--- Normal background class="type">color of the close button const class="type">color CLOSE_BUTTON_HOVER_BG = clrDodgerBlue; class=class="str">"cmt">//--- Hover background class="type">color of the close button const class="type">color CLOSE_BUTTON_NORMAL_BORDER = clrBlack; class=class="str">"cmt">//--- Normal border class="type">color of the close button const class="type">color CLOSE_BUTTON_HOVER_BORDER = clrBlue; class=class="str">"cmt">//--- Hover border class="type">color of the close button const class="type">color VALUE_POSITIVE_COLOR = clrLimeGreen; class=class="str">"cmt">//--- Color for positive values(e.g., profit, low spread) const class="type">color VALUE_NEGATIVE_COLOR = clrOrange; class=class="str">"cmt">//--- Color for negative or warning values(e.g., loss, high spread) const class="type">color VALUE_LOSS_COLOR = clrHotPink; class=class="str">"cmt">//--- Color for negative profit const class="type">color VALUE_ACTIVE_COLOR = clrGold; class=class="str">"cmt">//--- Color for active states(e.g., open orders, medium spread) const class="type">color VALUE_DRAWDOWN_INACTIVE = clrAqua; class=class="str">"cmt">//--- Color for inactive drawdown state const class="type">color VALUE_DRAWDOWN_ACTIVE = clrRed; class=class="str">"cmt">//--- Color for active drawdown state const class="type">int FONT_SIZE_HEADER = class="num">12; class=class="str">"cmt">//--- Header text font size(pt) const class="type">int FONT_SIZE_SECTION_TITLE = class="num">11; class=class="str">"cmt">//--- Section title font size(pt) const class="type">int FONT_SIZE_METRIC = class="num">9; class=class="str">"cmt">//--- Metric label/value font size(pt) const class="type">int FONT_SIZE_BUTTON = class="num">12; class=class="str">"cmt">//--- Button font size(pt) class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Retrieve the current account balance | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">class="kw">double GetAccountBalance() { class=class="str">"cmt">//--- Return the current account balance class="kw">return AccountInfoDouble(ACCOUNT_BALANCE); }
持仓属性抓取与面板底框函数
做 EA 面板或盯盘脚本时,第一件事是把当前选中持仓的关键字段读出来。下面这组函数分别封装了魔术码、开仓价、止损、止盈、品种、订单号、开仓时间、持仓方向,全部走 MT5 的 PositionGetInteger / PositionGetDouble / PositionGetString 接口,调用前需先用 PositionSelect() 或 PositionGetSymbol() 锁定持仓。 long GetPositionMagic() { return PositionGetInteger(POSITION_MAGIC); } 上面这句拿的是订单魔术码,用来区分同一品种上不同策略开的仓。POSITION_MAGIC 是 long 型,直接返回即可,多策略同跑时它是分流处理的唯一可靠标识。 double GetPositionOpenPrice() { return PositionGetDouble(POSITION_PRICE_OPEN); } double GetPositionSL() { return PositionGetDouble(POSITION_SL); } double GetPositionTP() { return PositionGetDouble(POSITION_TP); } 开仓价、SL、TP 都是 double,注意 SL/TP 若未设置,PositionGetDouble 返回 0.0 而非 NULL,面板显示时要自己判断是否为 0 再画线。 string GetPositionSymbol() { return PositionGetString(POSITION_SYMBOL); } ulong GetPositionTicket() { return PositionGetInteger(POSITION_TICKET); } datetime GetPositionOpenTime() { return (datetime)PositionGetInteger(POSITION_TIME); } int GetPositionType() { return (int)PositionGetInteger(POSITION_TYPE); } 品种名是 string, ticket 是 ulong 订单唯一号,开仓时间从整型强转 datetime,持仓方向 POSITION_TYPE 转 int 后 0 为买、1 为卖。把这些拼起来,一个持仓卡片的数据层就齐了。 void CreateRectangle(string name, int x, int y, int width, int height, color bgColor, color borderColor) { 开头先查对象是否存在——这是画矩形底框的标准起手,避免重复创建导致图表对象堆积。后续用 OBJ_RECTANGLE 绑定坐标与配色,x/y 是像素锚点,和前面读出的持仓数据分层渲染就是盯盘面板的骨架。外汇与贵金属杠杆高,面板只做展示与辅助,实操下单仍须自担风险。
class="type">long GetPositionMagic() { class=class="str">"cmt">//--- Return the magic number of the selected position class="kw">return PositionGetInteger(POSITION_MAGIC); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Retrieve the open price of the selected position | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">class="kw">double GetPositionOpenPrice() { class=class="str">"cmt">//--- Return the open price of the selected position class="kw">return PositionGetDouble(POSITION_PRICE_OPEN); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Retrieve the stop-loss price of the selected position | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">class="kw">double GetPositionSL() { class=class="str">"cmt">//--- Return the stop-loss price of the selected position class="kw">return PositionGetDouble(POSITION_SL); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Retrieve the take-profit price of the selected position | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">class="kw">double GetPositionTP() { class=class="str">"cmt">//--- Return the take-profit price of the selected position class="kw">return PositionGetDouble(POSITION_TP); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Retrieve the symbol of the selected position | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">class="kw">string GetPositionSymbol() { class=class="str">"cmt">//--- Return the symbol of the selected position class="kw">return PositionGetString(POSITION_SYMBOL); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Retrieve the ticket number of the selected position | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">ulong GetPositionTicket() { class=class="str">"cmt">//--- Return the ticket number of the selected position class="kw">return PositionGetInteger(POSITION_TICKET); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Retrieve the open time of the selected position | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">class="kw">datetime GetPositionOpenTime() { class=class="str">"cmt">//--- Return the open time of the selected position as a class="type">class="kw">datetime class="kw">return (class="type">class="kw">datetime)PositionGetInteger(POSITION_TIME); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Retrieve the type of the selected position | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int GetPositionType() { class=class="str">"cmt">//--- Return the type of the selected position(buy/sell) class="kw">return (class="type">int)PositionGetInteger(POSITION_TYPE); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Create a rectangular object for the dashboard | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void CreateRectangle(class="type">class="kw">string name, class="type">int x, class="type">int y, class="type">int width, class="type">int height, class="type">color bgColor, class="type">color borderColor) { class=class="str">"cmt">//--- Check if object does not exist
「用矩形与文本标签搭MT5面板」
在 MT5 里做轻量盯盘面板,不必依赖第三方指标。用 OBJ_RECTANGLE_LABEL 画底板、OBJ_LABEL 写文字,两个函数就能拼出可叠加在报价窗口的 HUD。 下面这段先建矩形底板:若对象不存在才创建,避免每帧重画闪屏;随后用 ObjectSetInteger 把坐标、尺寸、边框、背景一口气写好,并把 OBJPROP_HIDDEN 置 true,让它在对象列表里隐身、不干扰手动操作。 文本标签同理,区别在调用 ObjectSetString 写 OBJPROP_TEXT 与 OBJPROP_FONT。字体默认 Arial、字号由 fontSize 传参,颜色走 clr 参数,同样置前台且不可选中。 实盘里这类面板常用于把多周期 RSI 极值或黄金突破位直接印在 K 线右上角。外汇与贵金属波动剧烈、杠杆高风险,面板只作提示,进出场仍须自担判断。
if(ObjectFind(class="num">0, name) < class="num">0) { class=class="str">"cmt">//--- Create a rectangle label object ObjectCreate(class="num">0, name, OBJ_RECTANGLE_LABEL, class="num">0, class="num">0, class="num">0); } class=class="str">"cmt">//--- Set X-coordinate ObjectSetInteger(class="num">0, name, OBJPROP_XDISTANCE, x); class=class="str">"cmt">//--- Set Y-coordinate ObjectSetInteger(class="num">0, name, OBJPROP_YDISTANCE, y); class=class="str">"cmt">//--- Set width ObjectSetInteger(class="num">0, name, OBJPROP_XSIZE, width); class=class="str">"cmt">//--- Set height ObjectSetInteger(class="num">0, name, OBJPROP_YSIZE, height); class=class="str">"cmt">//--- Set background class="type">color ObjectSetInteger(class="num">0, name, OBJPROP_BGCOLOR, bgColor); class=class="str">"cmt">//--- Set border type to flat ObjectSetInteger(class="num">0, name, OBJPROP_BORDER_TYPE, BORDER_FLAT); class=class="str">"cmt">//--- Set border class="type">color ObjectSetInteger(class="num">0, name, OBJPROP_COLOR, borderColor); class=class="str">"cmt">//--- Set border width ObjectSetInteger(class="num">0, name, OBJPROP_WIDTH, class="num">1); class=class="str">"cmt">//--- Set object to foreground ObjectSetInteger(class="num">0, name, OBJPROP_BACK, false); class=class="str">"cmt">//--- Disable object selection ObjectSetInteger(class="num">0, name, OBJPROP_SELECTABLE, false); class=class="str">"cmt">//--- Hide object from object list ObjectSetInteger(class="num">0, name, OBJPROP_HIDDEN, true); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Create a text label for the dashboard | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void CreateTextLabel(class="type">class="kw">string name, class="type">int x, class="type">int y, class="type">class="kw">string text, class="type">color clr, class="type">int fontSize, class="type">class="kw">string font = "Arial") { class=class="str">"cmt">//--- Check if object does not exist if(ObjectFind(class="num">0, name) < class="num">0) { class=class="str">"cmt">//--- Create a text label object ObjectCreate(class="num">0, name, OBJ_LABEL, class="num">0, class="num">0, class="num">0); } class=class="str">"cmt">//--- Set X-coordinate ObjectSetInteger(class="num">0, name, OBJPROP_XDISTANCE, x); class=class="str">"cmt">//--- Set Y-coordinate ObjectSetInteger(class="num">0, name, OBJPROP_YDISTANCE, y); class=class="str">"cmt">//--- Set label text ObjectSetString(class="num">0, name, OBJPROP_TEXT, text); class=class="str">"cmt">//--- Set font ObjectSetString(class="num">0, name, OBJPROP_FONT, font); class=class="str">"cmt">//--- Set font size ObjectSetInteger(class="num">0, name, OBJPROP_FONTSIZE, fontSize); class=class="str">"cmt">//--- Set text class="type">color ObjectSetInteger(class="num">0, name, OBJPROP_COLOR, clr); class=class="str">"cmt">//--- Set object to foreground ObjectSetInteger(class="num">0, name, OBJPROP_BACK, false);
◍ 给盯盘面板造按钮并锁属性
想在 MT5 图表上叠一个不被鼠标误选、也不在对象列表里刷屏的按钮,核心就是先 ObjectCreate 建 OBJ_BUTTON,再用 ObjectSetInteger 把 SELECTABLE 和 HIDDEN 都置为 false / true。这样按钮只负责触发逻辑,不会干扰你拖趋势线或看对象树。 下面这段 CreateButton 封装了坐标、尺寸、字体、配色和背景层级。注意 OBJPROP_BACK 由入参 isBack 控制:设 true 按钮沉到背景,设 false 浮在 K 线上方;OBJPROP_STATE 每次重建都复位成 false,避免残留按下态。
class="type">void CreateButton(class="type">class="kw">string name, class="type">class="kw">string text, class="type">int x, class="type">int y, class="type">int width, class="type">int height, class="type">color textColor, class="type">color bgColor, class="type">int fontSize, class="type">color borderColor, class="type">bool isBack, class="type">class="kw">string font = "Arial") { if(ObjectFind(class="num">0, name) < class="num">0) { ObjectCreate(class="num">0, name, OBJ_BUTTON, class="num">0, class="num">0, class="num">0); } ObjectSetInteger(class="num">0, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(class="num">0, name, OBJPROP_YDISTANCE, y); ObjectSetInteger(class="num">0, name, OBJPROP_XSIZE, width); ObjectSetInteger(class="num">0, name, OBJPROP_YSIZE, height); ObjectSetString(class="num">0, name, OBJPROP_TEXT, text); ObjectSetString(class="num">0, name, OBJPROP_FONT, font); ObjectSetInteger(class="num">0, name, OBJPROP_FONTSIZE, fontSize); ObjectSetInteger(class="num">0, name, OBJPROP_COLOR, textColor); ObjectSetInteger(class="num">0, name, OBJPROP_BGCOLOR, bgColor); ObjectSetInteger(class="num">0, name, OBJPROP_BORDER_COLOR, borderColor); ObjectSetInteger(class="num">0, name, OBJPROP_BACK, isBack); ObjectSetInteger(class="num">0, name, OBJPROP_STATE, false); ObjectSetInteger(class="num">0, name, OBJPROP_SELECTABLE, false); ObjectSetInteger(class="num">0, name, OBJPROP_HIDDEN, true); }
class="type">void CreateButton(class="type">class="kw">string name, class="type">class="kw">string text, class="type">int x, class="type">int y, class="type">int width, class="type">int height, class="type">color textColor, class="type">color bgColor, class="type">int fontSize, class="type">color borderColor, class="type">bool isBack, class="type">class="kw">string font = "Arial") { if(ObjectFind(class="num">0, name) < class="num">0) { ObjectCreate(class="num">0, name, OBJ_BUTTON, class="num">0, class="num">0, class="num">0); } ObjectSetInteger(class="num">0, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(class="num">0, name, OBJPROP_YDISTANCE, y); ObjectSetInteger(class="num">0, name, OBJPROP_XSIZE, width); ObjectSetInteger(class="num">0, name, OBJPROP_YSIZE, height); ObjectSetString(class="num">0, name, OBJPROP_TEXT, text); ObjectSetString(class="num">0, name, OBJPROP_FONT, font); ObjectSetInteger(class="num">0, name, OBJPROP_FONTSIZE, fontSize); ObjectSetInteger(class="num">0, name, OBJPROP_COLOR, textColor); ObjectSetInteger(class="num">0, name, OBJPROP_BGCOLOR, bgColor); ObjectSetInteger(class="num">0, name, OBJPROP_BORDER_COLOR, borderColor); ObjectSetInteger(class="num">0, name, OBJPROP_BACK, isBack); ObjectSetInteger(class="num">0, name, OBJPROP_STATE, false); ObjectSetInteger(class="num">0, name, OBJPROP_SELECTABLE, false); ObjectSetInteger(class="num">0, name, OBJPROP_HIDDEN, true); }
用面板把浮盈和权益实时画出来
EA 想在图表上自绘监控面板,核心是先遍历持仓把未实现利润累加,再按数值正负染色。下面这段从持仓回环到仪表盘刷新的代码,直接决定了你盯盘时看到的数字是否跟账户同步。 for(int i=PositionsTotal()-1;i>=0;i--){ // 从最后一笔持仓倒序遍历,避免删除时索引错位 ulong ticket=PositionGetTicket(i); // 按序号取持仓 ticket if(PositionSelectByTicket(ticket)&&GetPositionSymbol()==_Symbol&&GetPositionMagic()==MAGIC){ // 只统计当前品种且魔术码匹配的仓 profit+=PositionGetDouble(POSITION_PROFIT); // 累加该仓的浮盈浮亏 } } return profit; // 返回当前 EA 管辖范围内的总浮盈 刷新函数 UpdateDashboard 里,header 高固定 HEADER_HEIGHT,内容区首行 Y 偏移 HEADER_HEIGHT+15,左列标签 X 距边 15、右列数值 X 距边 160,行高 15——这些像素值你在 MT5 里改小一点面板就更紧凑。 profitColor 用三目判断:profit>0 取 VALUE_POSITIVE_COLOR,<0 取 VALUE_LOSS_COLOR,否则 TEXT_COLOR;equity 与 balance 比较、balance 与 dailyBalance 比较同理染色。外汇与贵金属杠杆高,浮盈面板只是概率层面的辅助,实际回撤可能瞬间吃掉显示的利润。
for (class="type">int i = PositionsTotal() - class="num">1; i >= class="num">0; i--) { class=class="str">"cmt">//--- Get position ticket class="type">ulong ticket = PositionGetTicket(i); class=class="str">"cmt">//--- Select position by ticket if (PositionSelectByTicket(ticket) && GetPositionSymbol() == _Symbol && GetPositionMagic() == MAGIC) { class=class="str">"cmt">//--- Accumulate unrealized profit profit += PositionGetDouble(POSITION_PROFIT); } } class=class="str">"cmt">//--- Return total profit class="kw">return profit; } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Update the dashboard with real-time trading metrics | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void UpdateDashboard() { class=class="str">"cmt">//--- Exit if dashboard is not visible if (!dashboardVisible) class="kw">return; class=class="str">"cmt">//--- Create dashboard background rectangle CreateRectangle("Dashboard", panelStartX, panelStartY, DASHBOARD_WIDTH, DASHBOARD_HEIGHT, BACKGROUND_COLOR, BORDER_COLOR); class=class="str">"cmt">//--- Create header rectangle CreateRectangle("Header", panelStartX, panelStartY, DASHBOARD_WIDTH, HEADER_HEIGHT, headerHovered ? HEADER_HOVER_COLOR : HEADER_NORMAL_COLOR, BORDER_COLOR); class=class="str">"cmt">//--- Create header text label CreateTextLabel("HeaderText", panelStartX + class="num">10, panelStartY + class="num">8, EA_NAME, clrBlack, FONT_SIZE_HEADER, "Arial Bold"); class=class="str">"cmt">//--- Create close button CreateButton("CloseButton", CharToString(class="num">122), panelStartX + DASHBOARD_WIDTH - CLOSE_BUTTON_WIDTH, panelStartY + class="num">1, CLOSE_BUTTON_WIDTH, CLOSE_BUTTON_HEIGHT, clrWhite, closeButtonHovered ? CLOSE_BUTTON_HOVER_BG : CLOSE_BUTTON_NORMAL_BG, FONT_SIZE_BUTTON, closeButtonHovered ? CLOSE_BUTTON_HOVER_BORDER : CLOSE_BUTTON_NORMAL_BORDER, false, "Wingdings"); class=class="str">"cmt">//--- Initialize dashboard content layout class=class="str">"cmt">//--- Set initial Y-position below header class="type">int sectionY = panelStartY + HEADER_HEIGHT + class="num">15; class=class="str">"cmt">//--- Set left column X-position for labels class="type">int labelXLeft = panelStartX + class="num">15; class=class="str">"cmt">//--- Set right column X-position for values class="type">int valueXRight = panelStartX + class="num">160; class=class="str">"cmt">//--- Set row height for metrics class="type">int rowHeight = class="num">15; class=class="str">"cmt">//--- Pre-calculate values for conditional coloring class=class="str">"cmt">//--- Calculate total unrealized profit class="type">class="kw">double profit = CalculateTotalProfit(); class=class="str">"cmt">//--- Set profit class="type">color based on value class="type">color profitColor = (profit > class="num">0) ? VALUE_POSITIVE_COLOR : (profit < class="num">0) ? VALUE_LOSS_COLOR : TEXT_COLOR; class=class="str">"cmt">//--- Get current equity class="type">class="kw">double equity = AccountInfoDouble(ACCOUNT_EQUITY); class=class="str">"cmt">//--- Get current balance class="type">class="kw">double balance = AccountInfoDouble(ACCOUNT_BALANCE); class=class="str">"cmt">//--- Set equity class="type">color based on comparison with balance class="type">color equityColor = (equity > balance) ? VALUE_POSITIVE_COLOR : (equity < balance) ? VALUE_NEGATIVE_COLOR : TEXT_COLOR; class=class="str">"cmt">//--- Set balance class="type">color based on comparison with daily balance class="type">color balanceColor = (balance > dailyBalance) ? VALUE_POSITIVE_COLOR : (balance < dailyBalance) ? VALUE_NEGATIVE_COLOR : TEXT_COLOR; class=class="str">"cmt">//--- Set open orders class="type">color based on active orders class="type">color ordersColor = (activeOrders > class="num">0) ? VALUE_ACTIVE_COLOR : TEXT_COLOR; class=class="str">"cmt">//--- Set drawdown active class="type">color based on trading state