监控平仓面版--源码
监控平仓面版--源码
免费
  • 人气:163

监控平仓面版--源码

优化目标

  1. 详细记录平仓日志
    • 记录每次平仓的具体时间、订单票号、平仓价格、盈亏等信息。
    • 记录批量平仓的触发原因(盈利或亏损)、订单总数和平仓次数。
  2. 增强平仓监控
    • 检查订单是否真的被平仓成功。
    • 如果平仓失败,记录详细错误信息。
  3. 优化平仓逻辑
    • 确保平仓操作更稳定,避免重复平仓或遗漏订单。
    • 减少不必要的计算,提升性能。

//+------------------------------------------------------------------+

//|                                              交易面板系统.mq4 |

//|                                 版权 © 2023-2025, AI编程zblog  |

//|                                          http://www.eawalk.com|

//+------------------------------------------------------------------+

#propertycopyright "Copyright 2024, eawalk.com"

#propertylink      "http://www.eawalk.com"

stringver = "篮子1.1"; // 交易面板系统.mq4

#propertyversion   "1.00"

#propertystrict

//---输入参数

inputdouble Profit = 50;              // 盈利目标(单位:货币)

inputdouble TotalCloseValue = 10000;  // 总亏损值(达到此值时平仓,单位:货币)

inputint MonitorTickInterval = 8;     // 监测TICK间隔(单位:tick

inputcolor TextColor = White;         // 文字颜色

inputint TextSize = 12;              // 文字体大小

inputint PanelWidth = 200;           // 面板宽度(像素,用于定位)

inputint PanelHeight = 100;          // 面板高度(像素,用于定位)

inputint PanelXOffset = 10;          // 面板距离右侧的偏移量(像素)

inputint PanelYOffset = 10;          // 面板距离顶部的偏移量(像素)

//---全局变量

datetimelastTickTime = 0;

intgMonitorTickInterval;              // 存储 MonitorTickInterval 的可修改副本

intgPanelWidth;                      // 存储 PanelWidth 的可修改副本

intgPanelHeight;                     // 存储 PanelHeight 的可修改副本

intcloseCount = 0;                   // 记录批量平仓次数

intgPanelXOffset;                    // 存储PanelXOffset 的可修改副本

intgPanelYOffset;                    // 存储PanelYOffset 的可修改副本

//+------------------------------------------------------------------+

//|专家初始化函数                                                 |

//+------------------------------------------------------------------+

intOnInit()

{

  // 初始化时检查参数并赋值给全局变量

  gMonitorTickInterval = MonitorTickInterval;

  if (gMonitorTickInterval < 1) gMonitorTickInterval = 1; // 确保间隔有效

  gPanelWidth = PanelWidth;

  if (gPanelWidth < 100) gPanelWidth = 100;             // 确保面板宽度有效

  gPanelHeight = PanelHeight;

  if (gPanelHeight < 50) gPanelHeight = 50;             // 确保面板高度有效

  gPanelXOffset = PanelXOffset;

  if (gPanelXOffset < 0) gPanelXOffset = 0;             // 确保偏移量有效

  gPanelYOffset = PanelYOffset;

  if (gPanelYOffset < 0) gPanelYOffset = 0;             // 确保偏移量有效

  

  return(INIT_SUCCEEDED);

}

//+------------------------------------------------------------------+

//|专家反初始化函数                                               |

//+------------------------------------------------------------------+

voidOnDeinit(const int reason)

{

  // 清理所有与面板相关的对象

  ObjectsDeleteAll(0, "Panel_");

}

//+------------------------------------------------------------------+

//|tick执行函数                                                 |

//+------------------------------------------------------------------+

voidOnTick()

{

  // 每隔gMonitorTickInterval tick 执行一次

  if (TimeCurrent() - lastTickTime < gMonitorTickInterval * Point)return;

  lastTickTime = TimeCurrent();

  // 绘制信息面板

  DrawInfoPanel();

  

  // 检查交易逻辑(盈利/亏损)

  CheckTradingLogic();

}

//+------------------------------------------------------------------+

//|绘制信息面板(仅文字,无背景)                                   |

//+------------------------------------------------------------------+

voidDrawInfoPanel()

{

  // 获取图表宽度以动态定位到右上角

  int chartWidth = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);

  int panelX = chartWidth - gPanelWidth - gPanelXOffset; // 距离右侧偏移

  // 显示盈利信息

  if (!ObjectCreate(0, "Panel_Profit", OBJ_LABEL, 0, 0, 0))

     return;

  ObjectSetInteger(0, "Panel_Profit", OBJPROP_XDISTANCE, panelX +10);

  ObjectSetInteger(0, "Panel_Profit", OBJPROP_YDISTANCE,gPanelYOffset + 20);

  ObjectSetString(0, "Panel_Profit", OBJPROP_TEXT, "盈利: " + DoubleToString(Profit,2));

  ObjectSetInteger(0, "Panel_Profit", OBJPROP_COLOR, TextColor);

  ObjectSetInteger(0, "Panel_Profit", OBJPROP_FONTSIZE,TextSize);

  // 显示总亏损值

  if (!ObjectCreate(0, "Panel_TotalClose", OBJ_LABEL, 0, 0, 0))

     return;

  ObjectSetInteger(0, "Panel_TotalClose", OBJPROP_XDISTANCE,panelX + 10);

  ObjectSetInteger(0, "Panel_TotalClose", OBJPROP_YDISTANCE,gPanelYOffset + 40);

  ObjectSetString(0, "Panel_TotalClose", OBJPROP_TEXT, "总亏损值: " +DoubleToString(TotalCloseValue, 2));

  ObjectSetInteger(0, "Panel_TotalClose", OBJPROP_COLOR,TextColor);

  ObjectSetInteger(0, "Panel_TotalClose", OBJPROP_FONTSIZE,TextSize);

  // 显示平仓次数

  if (!ObjectCreate(0, "Panel_CloseCount", OBJ_LABEL, 0, 0, 0))

     return;

  ObjectSetInteger(0, "Panel_CloseCount", OBJPROP_XDISTANCE,panelX + 10);

  ObjectSetInteger(0, "Panel_CloseCount", OBJPROP_YDISTANCE,gPanelYOffset + 60);

  ObjectSetString(0, "Panel_CloseCount", OBJPROP_TEXT, "平仓次数: " +IntegerToString(closeCount));

  ObjectSetInteger(0, "Panel_CloseCount", OBJPROP_COLOR,TextColor);

  ObjectSetInteger(0, "Panel_CloseCount", OBJPROP_FONTSIZE,TextSize);

}

//+------------------------------------------------------------------+

//|检查交易逻辑                                                   |

//+------------------------------------------------------------------+

voidCheckTradingLogic()

{

  // 计算当前所有订单的总亏损

  double totalLoss = 0;

  for (int i = OrdersTotal() - 1; i >= 0; i--)

  {

     if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))

     {

        if (OrderSymbol() == Symbol())

        {

           double orderProfit = OrderProfit() +OrderSwap() + OrderCommission();

           if (orderProfit < 0) // 只计算亏损订单

           {

              totalLoss += MathAbs(orderProfit);// 累计亏损值(取绝对值)

           }

        }

     }

  }

  // 当总亏损达到 TotalCloseValue 时平仓所有订单

  if (totalLoss >= TotalCloseValue)

  {

     bool batchClosed = false; // 标记是否发生批量平仓

     for (int i = OrdersTotal() - 1; i >= 0; i--)

     {

        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))

        {

           if (OrderSymbol() == Symbol())

           {

              bool closed =OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 3, clrRed);

              if (closed)

              {

                 batchClosed = true; // 只要有一笔订单成功平仓,标记为批量平仓

                 Print("因总亏损平仓: ",totalLoss);

              }

              else

              {

                 Print("平仓失败,错误代码 #",GetLastError());

              }

           }

        }

     }

     if (batchClosed)

     {

        closeCount++; // 批量平仓成功后,计数加1

        Print("批量平仓完成,总平仓次数: ", closeCount);

     }

  }

  // 基于盈利的平仓条件

  double currentProfit = AccountProfit();

  if (currentProfit >= Profit)

  {

     bool batchClosed = false; // 标记是否发生批量平仓

     for (int i = OrdersTotal() - 1; i >= 0; i--)

     {

        if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))

        {

           if (OrderSymbol() == Symbol())

           {

              bool closed = OrderClose(OrderTicket(),OrderLots(), OrderClosePrice(), 3, clrRed);

              if (closed)

              {

                 batchClosed = true; // 只要有一笔订单成功平仓,标记为批量平仓

                 Print("因盈利平仓: ",currentProfit);

              }

              else

              {

                 Print("平仓失败,错误代码 #",GetLastError());

              }

           }

        }

     }

     if (batchClosed)

     {

        closeCount++; // 批量平仓成功后,计数加1

        Print("批量平仓完成,总平仓次数: ", closeCount);

     }

  }

}

//+------------------------------------------------------------------+

2018080503263266.jpg