乐于分享
好东西不私藏

完美一键设置止盈止损的EA源码发布

完美一键设置止盈止损的EA源码发布

如果你是一个做手单的朋友,如果你一次要下很多单子,但是你的单子想要一次设置止盈或者止损的话,那么,这个源码就太适合你了。先来看看图:
我这个EA的设计就很人性了
有一些什么功能,大家一看就知道,首先2个模式,可以价格模式和点位模式来设置,点击可以切换,然后可以选择设置订单的多单还是空单,还可以选择时间,这样对于那些喜欢手单的朋友来说,太合适了!
不知道怎么编译的,联系我吧:
我们自己已经用了很久了,下面开放代码吧:
//+------------------------------------------------------------------+//|                                              OneClickPanelSLTP.mq4|//|                                     Generated by AutoGen Assistant|//|                                                                  |//+------------------------------------------------------------------+#property copyright "Your Name"#property link      ""#property version   "1.80"#property strict// 输入参数(面板外观和位置)input int      InpPanelCorner = 0;          // 面板角落 (0=左上,1=右上,2=左下,3=右下)input int      InpPanelX      = 10;          // 面板X偏移input int      InpPanelY      = 50;          // 面板Y偏移input int      InpPanelWidth  = 340;         // 面板宽度input int      InpPanelHeight = 430;         // 面板高度input color    InpPanelColor  = clrLightGray; // 面板背景色// 对象名称前缀#define PREFIX "OneClickPanel_"#define BTN_APPLY   PREFIX + "ApplyBtn"#define BTN_CLEAR   PREFIX + "ClearBtn"#define BTN_MODE    PREFIX + "ModeBtn"       // 模式切换按钮#define ED_SL       PREFIX + "EditSL"#define ED_TP       PREFIX + "EditTP"#define LBL_SL      PREFIX + "LabelSL"#define LBL_TP      PREFIX + "LabelTP"#define LBL_TYPE    PREFIX + "LabelType"#define LBL_TIME    PREFIX + "LabelTime"#define RADIO_TYPE_BUY  PREFIX + "RadioTypeBuy"#define RADIO_TYPE_SELL PREFIX + "RadioTypeSell"#define RADIO_TYPE_ALL  PREFIX + "RadioTypeAll"#define RADIO_TIME_TODAY PREFIX + "RadioTimeToday"#define RADIO_TIME_ALL   PREFIX + "RadioTimeAll"#define RADIO_TIME_CUSTOM PREFIX + "RadioTimeCustom"#define LBL_DATE_START PREFIX + "LabelDateStart"#define ED_DATE_START  PREFIX + "EditDateStart"#define LBL_DATE_END   PREFIX + "LabelDateEnd"#define ED_DATE_END    PREFIX + "EditDateEnd"#define RECT_BG     PREFIX + "RectBG"// 全局变量int  g_orderType    = 0;       // 0=所有, 1=仅多单, 2=仅空单int  g_timeFilter   = 1;       // 0=所有订单, 1=仅今天订单, 2=自定义范围bool g_priceMode    = false;   // true=价格模式, false=点数模式//+------------------------------------------------------------------+//| 专家初始化函数                                                   |//+------------------------------------------------------------------+intOnInit(){   // 创建面板背景矩形   if(!ObjectCreate(0, RECT_BG, OBJ_RECTANGLE_LABEL, 000))      return(INIT_FAILED);   ObjectSetInteger(0, RECT_BG, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, RECT_BG, OBJPROP_XDISTANCE, InpPanelX);   ObjectSetInteger(0, RECT_BG, OBJPROP_YDISTANCE, InpPanelY);   ObjectSetInteger(0, RECT_BG, OBJPROP_XSIZE, InpPanelWidth);   ObjectSetInteger(0, RECT_BG, OBJPROP_YSIZE, InpPanelHeight);   ObjectSetInteger(0, RECT_BG, OBJPROP_BGCOLOR, InpPanelColor);   ObjectSetInteger(0, RECT_BG, OBJPROP_BORDER_COLOR, clrBlack);   ObjectSetInteger(0, RECT_BG, OBJPROP_STATE, false);   ObjectSetInteger(0, RECT_BG, OBJPROP_SELECTABLE, false);   ObjectSetInteger(0, RECT_BG, OBJPROP_HIDDEN, true);   // 计算内部布局的参考点   int startX = InpPanelX + 15;   int startY = InpPanelY + 15;   int labelW = 85;              // 标签宽度   int editW = InpPanelWidth - 115;   int rowHeight = 38;   int radioRowHeight = 32;   int btnHeight = 32;   // --- 模式切换按钮(放在止损/止盈上方)---   int modeBtnY = startY;   ObjectCreate(0, BTN_MODE, OBJ_BUTTON, 000);   ObjectSetInteger(0, BTN_MODE, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, BTN_MODE, OBJPROP_XDISTANCE, startX);   ObjectSetInteger(0, BTN_MODE, OBJPROP_YDISTANCE, modeBtnY);   ObjectSetInteger(0, BTN_MODE, OBJPROP_XSIZE, InpPanelWidth - 30);   ObjectSetInteger(0, BTN_MODE, OBJPROP_YSIZE, 26);   ObjectSetString(0, BTN_MODE, OBJPROP_TEXT, "当前模式: 点数模式 (点击切换)");   ObjectSetInteger(0, BTN_MODE, OBJPROP_BGCOLOR, clrLightBlue);   ObjectSetInteger(0, BTN_MODE, OBJPROP_COLOR, clrBlack);   ObjectSetInteger(0, BTN_MODE, OBJPROP_FONTSIZE, 10);   ObjectSetInteger(0, BTN_MODE, OBJPROP_HIDDEN, true);   ObjectSetInteger(0, BTN_MODE, OBJPROP_SELECTABLE, false);   ObjectSetInteger(0, BTN_MODE, OBJPROP_ZORDER, 1);   // --- 第1行:止损 ---   int slY = modeBtnY + 30;   ObjectCreate(0, LBL_SL, OBJ_LABEL, 000);   ObjectSetInteger(0, LBL_SL, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, LBL_SL, OBJPROP_XDISTANCE, startX);   ObjectSetInteger(0, LBL_SL, OBJPROP_YDISTANCE, slY);   ObjectSetString(0, LBL_SL, OBJPROP_TEXT, "止损点数:");   ObjectSetInteger(0, LBL_SL, OBJPROP_FONTSIZE, 12);   ObjectSetInteger(0, LBL_SL, OBJPROP_COLOR, clrBlack);   ObjectSetInteger(0, LBL_SL, OBJPROP_HIDDEN, true);   ObjectCreate(0, ED_SL, OBJ_EDIT, 000);   ObjectSetInteger(0, ED_SL, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, ED_SL, OBJPROP_XDISTANCE, startX + labelW);   ObjectSetInteger(0, ED_SL, OBJPROP_YDISTANCE, slY - 3);   ObjectSetInteger(0, ED_SL, OBJPROP_XSIZE, editW);   ObjectSetInteger(0, ED_SL, OBJPROP_YSIZE, 26);   ObjectSetString(0, ED_SL, OBJPROP_TEXT, "50");   ObjectSetInteger(0, ED_SL, OBJPROP_FONTSIZE, 11);   ObjectSetInteger(0, ED_SL, OBJPROP_BGCOLOR, clrWhite);   ObjectSetInteger(0, ED_SL, OBJPROP_HIDDEN, true);   ObjectSetInteger(0, ED_SL, OBJPROP_READONLY, false);   // --- 第2行:止盈 ---   int tpY = slY + rowHeight;   ObjectCreate(0, LBL_TP, OBJ_LABEL, 000);   ObjectSetInteger(0, LBL_TP, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, LBL_TP, OBJPROP_XDISTANCE, startX);   ObjectSetInteger(0, LBL_TP, OBJPROP_YDISTANCE, tpY);   ObjectSetString(0, LBL_TP, OBJPROP_TEXT, "止盈点数:");   ObjectSetInteger(0, LBL_TP, OBJPROP_FONTSIZE, 12);   ObjectSetInteger(0, LBL_TP, OBJPROP_COLOR, clrBlack);   ObjectSetInteger(0, LBL_TP, OBJPROP_HIDDEN, true);   ObjectCreate(0, ED_TP, OBJ_EDIT, 000);   ObjectSetInteger(0, ED_TP, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, ED_TP, OBJPROP_XDISTANCE, startX + labelW);   ObjectSetInteger(0, ED_TP, OBJPROP_YDISTANCE, tpY - 3);   ObjectSetInteger(0, ED_TP, OBJPROP_XSIZE, editW);   ObjectSetInteger(0, ED_TP, OBJPROP_YSIZE, 26);   ObjectSetString(0, ED_TP, OBJPROP_TEXT, "100");   ObjectSetInteger(0, ED_TP, OBJPROP_FONTSIZE, 11);   ObjectSetInteger(0, ED_TP, OBJPROP_BGCOLOR, clrWhite);   ObjectSetInteger(0, ED_TP, OBJPROP_HIDDEN, true);   ObjectSetInteger(0, ED_TP, OBJPROP_READONLY, false);   // --- 第3行:订单类型标签 ---   int typeLabelY = tpY + rowHeight + 5;   ObjectCreate(0, LBL_TYPE, OBJ_LABEL, 000);   ObjectSetInteger(0, LBL_TYPE, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, LBL_TYPE, OBJPROP_XDISTANCE, startX);   ObjectSetInteger(0, LBL_TYPE, OBJPROP_YDISTANCE, typeLabelY);   ObjectSetString(0, LBL_TYPE, OBJPROP_TEXT, "订单类型:");   ObjectSetInteger(0, LBL_TYPE, OBJPROP_FONTSIZE, 12);   ObjectSetInteger(0, LBL_TYPE, OBJPROP_COLOR, clrBlack);   ObjectSetInteger(0, LBL_TYPE, OBJPROP_HIDDEN, true);   int radioTypeY = typeLabelY + 23;   CreateRadioButton(RADIO_TYPE_BUY, "多单", startX, radioTypeY, false);   CreateRadioButton(RADIO_TYPE_SELL, "空单", startX + 85, radioTypeY, false);   CreateRadioButton(RADIO_TYPE_ALL, "所有", startX + 170, radioTypeY, true);   // --- 第4行:订单时间标签 ---   int timeLabelY = radioTypeY + radioRowHeight + 10;   ObjectCreate(0, LBL_TIME, OBJ_LABEL, 000);   ObjectSetInteger(0, LBL_TIME, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, LBL_TIME, OBJPROP_XDISTANCE, startX);   ObjectSetInteger(0, LBL_TIME, OBJPROP_YDISTANCE, timeLabelY);   ObjectSetString(0, LBL_TIME, OBJPROP_TEXT, "订单时间:");   ObjectSetInteger(0, LBL_TIME, OBJPROP_FONTSIZE, 12);   ObjectSetInteger(0, LBL_TIME, OBJPROP_COLOR, clrBlack);   ObjectSetInteger(0, LBL_TIME, OBJPROP_HIDDEN, true);   int radioTimeY = timeLabelY + 23;   CreateRadioButton(RADIO_TIME_TODAY, "今天", startX, radioTimeY, true);   CreateRadioButton(RADIO_TIME_ALL, "所有", startX + 85, radioTimeY, false);   CreateRadioButton(RADIO_TIME_CUSTOM, "自定义", startX + 170, radioTimeY, false);   // --- 自定义日期输入框区域 ---   int dateY = radioTimeY + radioRowHeight + 10;   ObjectCreate(0, LBL_DATE_START, OBJ_LABEL, 000);   ObjectSetInteger(0, LBL_DATE_START, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, LBL_DATE_START, OBJPROP_XDISTANCE, startX);   ObjectSetInteger(0, LBL_DATE_START, OBJPROP_YDISTANCE, dateY);   ObjectSetString(0, LBL_DATE_START, OBJPROP_TEXT, "起始日期:");   ObjectSetInteger(0, LBL_DATE_START, OBJPROP_FONTSIZE, 10);   ObjectSetInteger(0, LBL_DATE_START, OBJPROP_COLOR, clrBlack);   ObjectSetInteger(0, LBL_DATE_START, OBJPROP_HIDDEN, true);   ObjectCreate(0, ED_DATE_START, OBJ_EDIT, 000);   ObjectSetInteger(0, ED_DATE_START, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, ED_DATE_START, OBJPROP_XDISTANCE, startX + 70);   ObjectSetInteger(0, ED_DATE_START, OBJPROP_YDISTANCE, dateY - 2);   ObjectSetInteger(0, ED_DATE_START, OBJPROP_XSIZE, 110);   ObjectSetInteger(0, ED_DATE_START, OBJPROP_YSIZE, 24);   ObjectSetString(0, ED_DATE_START, OBJPROP_TEXT, TimeToString(TimeCurrent(), TIME_DATE));   ObjectSetInteger(0, ED_DATE_START, OBJPROP_FONTSIZE, 10);   ObjectSetInteger(0, ED_DATE_START, OBJPROP_BGCOLOR, clrWhite);   ObjectSetInteger(0, ED_DATE_START, OBJPROP_HIDDEN, true);   ObjectSetInteger(0, ED_DATE_START, OBJPROP_READONLY, false);   ObjectCreate(0, LBL_DATE_END, OBJ_LABEL, 000);   ObjectSetInteger(0, LBL_DATE_END, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, LBL_DATE_END, OBJPROP_XDISTANCE, startX + 190);   ObjectSetInteger(0, LBL_DATE_END, OBJPROP_YDISTANCE, dateY);   ObjectSetString(0, LBL_DATE_END, OBJPROP_TEXT, "结束日期:");   ObjectSetInteger(0, LBL_DATE_END, OBJPROP_FONTSIZE, 10);   ObjectSetInteger(0, LBL_DATE_END, OBJPROP_COLOR, clrBlack);   ObjectSetInteger(0, LBL_DATE_END, OBJPROP_HIDDEN, true);   ObjectCreate(0, ED_DATE_END, OBJ_EDIT, 000);   ObjectSetInteger(0, ED_DATE_END, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, ED_DATE_END, OBJPROP_XDISTANCE, startX + 260);   ObjectSetInteger(0, ED_DATE_END, OBJPROP_YDISTANCE, dateY - 2);   ObjectSetInteger(0, ED_DATE_END, OBJPROP_XSIZE, 110);   ObjectSetInteger(0, ED_DATE_END, OBJPROP_YSIZE, 24);   ObjectSetString(0, ED_DATE_END, OBJPROP_TEXT, TimeToString(TimeCurrent(), TIME_DATE));   ObjectSetInteger(0, ED_DATE_END, OBJPROP_FONTSIZE, 10);   ObjectSetInteger(0, ED_DATE_END, OBJPROP_BGCOLOR, clrWhite);   ObjectSetInteger(0, ED_DATE_END, OBJPROP_HIDDEN, true);   ObjectSetInteger(0, ED_DATE_END, OBJPROP_READONLY, false);   // --- 应用按钮 ---   int btnY1 = InpPanelY + InpPanelHeight - 90;   ObjectCreate(0, BTN_APPLY, OBJ_BUTTON, 000);   ObjectSetInteger(0, BTN_APPLY, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, BTN_APPLY, OBJPROP_XDISTANCE, startX);   ObjectSetInteger(0, BTN_APPLY, OBJPROP_YDISTANCE, btnY1);   ObjectSetInteger(0, BTN_APPLY, OBJPROP_XSIZE, InpPanelWidth - 30);   ObjectSetInteger(0, BTN_APPLY, OBJPROP_YSIZE, btnHeight);   ObjectSetString(0, BTN_APPLY, OBJPROP_TEXT, "设置止盈止损");   ObjectSetInteger(0, BTN_APPLY, OBJPROP_BGCOLOR, clrDodgerBlue);   ObjectSetInteger(0, BTN_APPLY, OBJPROP_COLOR, clrWhite);   ObjectSetInteger(0, BTN_APPLY, OBJPROP_FONTSIZE, 12);   ObjectSetInteger(0, BTN_APPLY, OBJPROP_HIDDEN, true);   ObjectSetInteger(0, BTN_APPLY, OBJPROP_SELECTABLE, false);   ObjectSetInteger(0, BTN_APPLY, OBJPROP_ZORDER, 1);   // --- 清除按钮 ---   int btnY2 = InpPanelY + InpPanelHeight - 50;   ObjectCreate(0, BTN_CLEAR, OBJ_BUTTON, 000);   ObjectSetInteger(0, BTN_CLEAR, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, BTN_CLEAR, OBJPROP_XDISTANCE, startX);   ObjectSetInteger(0, BTN_CLEAR, OBJPROP_YDISTANCE, btnY2);   ObjectSetInteger(0, BTN_CLEAR, OBJPROP_XSIZE, InpPanelWidth - 30);   ObjectSetInteger(0, BTN_CLEAR, OBJPROP_YSIZE, btnHeight);   ObjectSetString(0, BTN_CLEAR, OBJPROP_TEXT, "清除止盈止损");   ObjectSetInteger(0, BTN_CLEAR, OBJPROP_BGCOLOR, clrOrangeRed);   ObjectSetInteger(0, BTN_CLEAR, OBJPROP_COLOR, clrWhite);   ObjectSetInteger(0, BTN_CLEAR, OBJPROP_FONTSIZE, 12);   ObjectSetInteger(0, BTN_CLEAR, OBJPROP_HIDDEN, true);   ObjectSetInteger(0, BTN_CLEAR, OBJPROP_SELECTABLE, false);   ObjectSetInteger(0, BTN_CLEAR, OBJPROP_ZORDER, 1);   // 初始根据时间筛选模式控制日期输入框的可见性   UpdateDateInputsState();   // 根据模式更新标签文字   UpdateModeUI();   Print("一键设置面板EA已启动,支持点数/价格模式切换。价格模式下完全按输入值设置,不做自动修正。");   return(INIT_SUCCEEDED);}//+------------------------------------------------------------------+//| 创建单选按钮                                                     |//+------------------------------------------------------------------+voidCreateRadioButton(string name, string text, int x, int y, bool selected){   ObjectCreate(0, name, OBJ_BUTTON, 000);   ObjectSetInteger(0, name, OBJPROP_CORNER, InpPanelCorner);   ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);   ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);   ObjectSetInteger(0, name, OBJPROP_XSIZE, 70);   ObjectSetInteger(0, name, OBJPROP_YSIZE, 28);   ObjectSetString(0, name, OBJPROP_TEXT, text);   ObjectSetInteger(0, name, OBJPROP_BGCOLOR, selected ? clrLightBlue : clrLightGray);   ObjectSetInteger(0, name, OBJPROP_COLOR, clrBlack);   ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 11);   ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);   ObjectSetInteger(0, name, OBJPROP_STATE, selected);   ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);}//+------------------------------------------------------------------+//| 根据当前模式更新界面文本                                          |//+------------------------------------------------------------------+voidUpdateModeUI(){   string modeText = g_priceMode ? "当前模式: 价格模式 (点击切换)" : "当前模式: 点数模式 (点击切换)";   ObjectSetString(0, BTN_MODE, OBJPROP_TEXT, modeText);   string slLabel = g_priceMode ? "止损价格:" : "止损点数:";   string tpLabel = g_priceMode ? "止盈价格:" : "止盈点数:";   ObjectSetString(0, LBL_SL, OBJPROP_TEXT, slLabel);   ObjectSetString(0, LBL_TP, OBJPROP_TEXT, tpLabel);   ChartRedraw(0);}//+------------------------------------------------------------------+//| 根据当前时间筛选模式,控制日期输入框的显示                         |//+------------------------------------------------------------------+voidUpdateDateInputsState(){   bool visible = (g_timeFilter == 2);   ObjectSetInteger(0, LBL_DATE_START, OBJPROP_HIDDEN, !visible);   ObjectSetInteger(0, ED_DATE_START, OBJPROP_HIDDEN, !visible);   ObjectSetInteger(0, LBL_DATE_END, OBJPROP_HIDDEN, !visible);   ObjectSetInteger(0, ED_DATE_END, OBJPROP_HIDDEN, !visible);   ChartRedraw(0);}//+------------------------------------------------------------------+//| 专家反初始化函数                                                 |//+------------------------------------------------------------------+voidOnDeinit(constint reason){   // 删除所有创建的对象   string objects[] = {RECT_BG, BTN_MODE, LBL_SL, ED_SL, LBL_TP, ED_TP, LBL_TYPE, LBL_TIME,                       RADIO_TYPE_BUY, RADIO_TYPE_SELL, RADIO_TYPE_ALL,                       RADIO_TIME_TODAY, RADIO_TIME_ALL, RADIO_TIME_CUSTOM,                       LBL_DATE_START, ED_DATE_START, LBL_DATE_END, ED_DATE_END,                       BTN_APPLY, BTN_CLEAR};   for(int i=0; i<ArraySize(objects); i++)      ObjectDelete(0, objects[i]);   Print("EA已卸载,面板已清除");}//+------------------------------------------------------------------+//| 图表事件处理                                                     |//+------------------------------------------------------------------+voidOnChartEvent(constint id,                  const long &lparam,                  const double &dparam,                  const string &sparam){   if(id == CHARTEVENT_OBJECT_CLICK)   {      // 模式切换按钮      if(sparam == BTN_MODE)      {         g_priceMode = !g_priceMode;         UpdateModeUI();         Print("模式切换为: ", g_priceMode ? "价格模式 (完全按输入值设置)" : "点数模式 (自动调整最小距离)");      }      // 应用按钮      else if(sparam == BTN_APPLY)      {         Print("设置按钮被点击");         ApplySettings();      }      // 清除按钮      else if(sparam == BTN_CLEAR)      {         Print("清除按钮被点击");         ClearSLTP();      }      // 订单类型单选      else if(sparam == RADIO_TYPE_BUY)      {         SetRadioState(RADIO_TYPE_BUY, true);         SetRadioState(RADIO_TYPE_SELL, false);         SetRadioState(RADIO_TYPE_ALL, false);         g_orderType = 1;      }      else if(sparam == RADIO_TYPE_SELL)      {         SetRadioState(RADIO_TYPE_BUY, false);         SetRadioState(RADIO_TYPE_SELL, true);         SetRadioState(RADIO_TYPE_ALL, false);         g_orderType = 2;      }      else if(sparam == RADIO_TYPE_ALL)      {         SetRadioState(RADIO_TYPE_BUY, false);         SetRadioState(RADIO_TYPE_SELL, false);         SetRadioState(RADIO_TYPE_ALL, true);         g_orderType = 0;      }      // 时间筛选单选      else if(sparam == RADIO_TIME_TODAY)      {         SetRadioState(RADIO_TIME_TODAY, true);         SetRadioState(RADIO_TIME_ALL, false);         SetRadioState(RADIO_TIME_CUSTOM, false);         g_timeFilter = 1;         UpdateDateInputsState();      }      else if(sparam == RADIO_TIME_ALL)      {         SetRadioState(RADIO_TIME_TODAY, false);         SetRadioState(RADIO_TIME_ALL, true);         SetRadioState(RADIO_TIME_CUSTOM, false);         g_timeFilter = 0;         UpdateDateInputsState();      }      else if(sparam == RADIO_TIME_CUSTOM)      {         SetRadioState(RADIO_TIME_TODAY, false);         SetRadioState(RADIO_TIME_ALL, false);         SetRadioState(RADIO_TIME_CUSTOM, true);         g_timeFilter = 2;         UpdateDateInputsState();      }   }}//+------------------------------------------------------------------+//| 设置单选按钮的选中状态                                           |//+------------------------------------------------------------------+voidSetRadioState(string name, bool state){   ObjectSetInteger(0, name, OBJPROP_STATE, state);   if(state)      ObjectSetInteger(0, name, OBJPROP_BGCOLOR, clrLightBlue);   else      ObjectSetInteger(0, name, OBJPROP_BGCOLOR, clrLightGray);   ChartRedraw(0);}//+------------------------------------------------------------------+//| 获取当前时间筛选的起始和结束时间                                   |//+------------------------------------------------------------------+boolGetTimeRange(datetime &startTime, datetime &endTime){   if(g_timeFilter == 0// 所有   {      startTime = 0;      endTime = D'01.01.3000';      return true;   }   else if(g_timeFilter == 1// 今天   {      datetime now = TimeCurrent();      startTime = StringToTime(TimeToString(now, TIME_DATE));      endTime = startTime + 24*3600 - 1;      return true;   }   else // 自定义   {      string startStr = ObjectGetString(0, ED_DATE_START, OBJPROP_TEXT);      string endStr   = ObjectGetString(0, ED_DATE_END, OBJPROP_TEXT);      startTime = ParseDate(startStr);      endTime   = ParseDate(endStr);      if(startTime == 0 || endTime == 0)      {         Print("日期解析失败,请使用格式 YYYY.MM.DD 或 YYYY-MM-DD");         return false;      }      endTime = endTime + 24*3600 - 1;      return true;   }}//+------------------------------------------------------------------+//| 简单日期解析,返回0表示失败                                        |//+------------------------------------------------------------------+datetime ParseDate(string dateStr){   StringTrimLeft(dateStr);   StringTrimRight(dateStr);   if(StringLen(dateStr) == 0return 0;   StringReplace(dateStr, "-"".");   if(StringLen(dateStr) == 10 && StringGetChar(dateStr,4) == '.' && StringGetChar(dateStr,7) == '.')   {      string timeStr = dateStr + " 00:00";      return StringToTime(timeStr);   }   return 0;}//+------------------------------------------------------------------+//| 检查订单时间是否在范围内                                           |//+------------------------------------------------------------------+boolIsOrderInRange(datetime openTime){   datetime start, end;   if(!GetTimeRange(start, end)) return false;   return (openTime >= start && openTime <= end);}//+------------------------------------------------------------------+//| 根据模式获取止损和止盈的目标值                                     |//| 价格模式:直接返回输入的价格                                      |//| 点数模式:返回计算后的价格,并进行最小距离检查                       |//+------------------------------------------------------------------+boolGetSLTPValues(int orderType, double &slValue, double &tpValue, string &errorMsg){   string slText = ObjectGetString(0, ED_SL, OBJPROP_TEXT);   string tpText = ObjectGetString(0, ED_TP, OBJPROP_TEXT);   if(g_priceMode)   {      // 价格模式:直接读取价格,不做任何自动调整      slValue = StringToDouble(slText);      tpValue = StringToDouble(tpText);      if(slValue == 0 && slText != "0"      {         errorMsg = "止损价格无效";         return false;      }      if(tpValue == 0 && tpText != "0")      {         errorMsg = "止盈价格无效";         return false;      }      return true;   }   else   {      // 点数模式:读取点数,转换为价格,并进行最小距离检查(后续在调用处处理)      int slPoints = (int)StringToInteger(slText);      int tpPoints = (int)StringToInteger(tpText);      if(slPoints <= 0 && slPoints != 0)      {         errorMsg = "止损点数无效";         return false;      }      if(tpPoints <= 0 && tpPoints != 0)      {         errorMsg = "止盈点数无效";         return false;      }      if(slPoints > 0)      {         if(orderType == OP_BUY)            slValue = Bid - slPoints * Point;         else            slValue = Ask + slPoints * Point;      }      else         slValue = 0;      if(tpPoints > 0)      {         if(orderType == OP_BUY)            tpValue = Bid + tpPoints * Point;         else            tpValue = Ask - tpPoints * Point;      }      else         tpValue = 0;      return true;   }}//+------------------------------------------------------------------+//| 遍历符合条件的订单并执行操作                                       |//+------------------------------------------------------------------+voidProcessOrders(bool setSLTP, int dummySL, int dummyTP// 参数为占位,实际值通过GetSLTPValues获取{   int total = OrdersTotal();   int modified = 0;   int errors = 0;   for(int i = total-1; i >= 0; i--)   {      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))      {         // 只处理当前品种的订单         if(OrderSymbol() != Symbol())            continue;         // 时间筛选         if(g_timeFilter != 0 && !IsOrderInRange(OrderOpenTime()))            continue;         int orderType = OrderType();         if(orderType == OP_BUY && g_orderType == 2continue;         if(orderType == OP_SELL && g_orderType == 1continue;         if(orderType != OP_BUY && orderType != OP_SELL) continue;         double openPrice = OrderOpenPrice();         double newSL = OrderStopLoss();         double newTP = OrderTakeProfit();         bool modify = false;         if(setSLTP)         {            double slValue = 0, tpValue = 0;            string errorMsg;            if(!GetSLTPValues(orderType, slValue, tpValue, errorMsg))            {               Print("获取止损/止盈数值失败: ", errorMsg);               continue;            }            // 处理止损            if(slValue != 0)            {               newSL = slValue;               // 仅在点数模式下进行最小距离自动修正,价格模式下不修正,完全按用户输入               if(!g_priceMode)               {                  double minDist = MarketInfo(OrderSymbol(), MODE_STOPLEVEL) * Point;                  if(orderType == OP_BUY && newSL > 0 && newSL > openPrice - minDist)                     newSL = openPrice - minDist;                  if(orderType == OP_SELL && newSL > 0 && newSL < openPrice + minDist)                     newSL = openPrice + minDist;               }               if(newSL != OrderStopLoss())                  modify = true;            }            // 处理止盈            if(tpValue != 0)            {               newTP = tpValue;               if(!g_priceMode)               {                  double minDist = MarketInfo(OrderSymbol(), MODE_STOPLEVEL) * Point;                  if(orderType == OP_BUY && newTP > 0 && newTP < openPrice + minDist)                     newTP = openPrice + minDist;                  if(orderType == OP_SELL && newTP > 0 && newTP > openPrice - minDist)                     newTP = openPrice - minDist;               }               if(newTP != OrderTakeProfit())                  modify = true;            }         }         else         {            // 清除模式            if(OrderStopLoss() != 0 || OrderTakeProfit() != 0)            {               newSL = 0;               newTP = 0;               modify = true;            }         }         if(modify)         {            if(OrderModify(OrderTicket(), openPrice, newSL, newTP, 0, clrNONE))            {               modified++;               if(setSLTP)                  Print("订单 ", OrderTicket(), " 修改成功。 SL=", newSL, " TP=", newTP);               else                  Print("订单 ", OrderTicket(), " 止盈止损已清除");            }            else            {               errors++;               Print("订单 ", OrderTicket(), " 修改失败,错误: ", GetLastError());            }         }      }   }   if(setSLTP)      Print("设置操作完成,成功: ", modified, " 失败: ", errors);   else      Print("清除操作完成,成功: ", modified, " 失败: ", errors);}//+------------------------------------------------------------------+//| 应用设置                                                         |//+------------------------------------------------------------------+voidApplySettings(){   // 验证输入框内容非空   string slText = ObjectGetString(0, ED_SL, OBJPROP_TEXT);   string tpText = ObjectGetString(0, ED_TP, OBJPROP_TEXT);   if(StringLen(slText) == 0 || StringLen(tpText) == 0)   {      Print("止损或止盈输入为空");      return;   }   // 在点数模式下,检查是否都是数字   if(!g_priceMode)   {      int slPoints = (int)StringToInteger(slText);      int tpPoints = (int)StringToInteger(tpText);      if(slPoints == 0 && slPoints != 0)      {         Print("止损点数无效: ", slText);         return;      }      if(tpPoints == 0 && tpPoints != 0)      {         Print("止盈点数无效: ", tpText);         return;      }      if(slPoints == 0 && tpPoints == 0)      {         Print("止损和止盈点数均为0,无需操作");         return;      }   }   else   {      // 价格模式下,检查是否为有效数字      double slPrice = StringToDouble(slText);      double tpPrice = StringToDouble(tpText);      if(slPrice == 0 && slText != "0")      {         Print("止损价格无效: ", slText);         return;      }      if(tpPrice == 0 && tpText != "0")      {         Print("止盈价格无效: ", tpText);         return;      }      if(slPrice == 0 && tpPrice == 0)      {         Print("止损和止盈价格均为0,无需操作");         return;      }   }   ProcessOrders(true00);}//+------------------------------------------------------------------+//| 清除止盈止损                                                     |//+------------------------------------------------------------------+voidClearSLTP(){   ProcessOrders(false00);}//+------------------------------------------------------------------+