MQL5 自己的编写的常用函数

Title MQL5 自己的编写的常用函数
Framework MQL5
User wy8817399@vip.qq.com
Id 65
Created 3/6/26, 8:00 PM
Modified 3/6/26, 8:00 PM
Published Yes
Content

自己以前写的代码,用来判断一些常用的事件包括

1、检查是否有新的K线出现

2、限制小数位数(部分品种历史数据中有超过图表正常值)

3、检测保证金是否充足

4、是否达到订单上限

5、下单

6、追踪止损

7、是否在允许的交易时间范围

8、单边总共有多少亏损订单(这个一般马丁用,实际情况几乎不用)

//+------------------------------------------------------------------+
//| 检查是否有新K线                                                  |
//+------------------------------------------------------------------+
bool IsNewBar(string symbol, ENUM_TIMEFRAMES timeframe) {
// 获取当前时间周期的最新K线时间
   datetime currentBarTime = iTime(symbol, timeframe, 0);

// 如果当前K线时间与上次记录的不同,说明有新K线生成
   if (currentBarTime > lastBarTimes) {
      lastBarTimes = currentBarTime; // 更新最后K线时间
      return true; // 返回新K线标志
   }
   return false; // 没有新K线
}



//+------------------------------------------------------------------+
//| 限制小数位数                                                     |
//+------------------------------------------------------------------+
double RoundToNDecimalPlaces(double value, int decimalPlaces) {
   double factor = MathPow(10, decimalPlaces);
   value = MathRound(value * factor) / factor;
   return value;
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| 检测保证金是否充足                                               |
//+------------------------------------------------------------------+
bool CheckMoneyForTrade(string symb, double lots, ENUM_ORDER_TYPE type) {
//--- Getting the opening price
   MqlTick mqltick;
   SymbolInfoTick(symb, mqltick);
   double price = mqltick.ask;
   if(type == ORDER_TYPE_SELL)
      price = mqltick.bid;
//--- values of the required and free margin
   double margin, free_margin = AccountInfoDouble(ACCOUNT_MARGIN_FREE);
//--- call of the checking function
   if(!OrderCalcMargin(type, symb, lots, price, margin)) {
      //--- something went wrong, report and return false
      Print("Error in ", __FUNCTION__, " code=", GetLastError());
      return(false);
   }
//--- if there are insufficient funds to perform the operation\
   if(margin > free_margin) {
      //--- report the error and return false
      Print("Not enough money for ", EnumToString(type), " ", lots, " ", symb, " Error code=", GetLastError());
      return(false);
   }
//--- checking successful
   return(true);
}





//+------------------------------------------------------------------+
//| 是否达到订单上限                                                 |
//+------------------------------------------------------------------+
bool IsLimitOrder(string symbol,string type,string comment) {
   CTrade trade;
   int totalPositions = PositionsTotal();
   int count = 0;
   for(int i = 0; i < totalPositions; i++) {
      ulong ticket = PositionGetTicket(i);
      // 如果成功选择持仓订单
      if(PositionSelectByTicket(ticket)) {
         string order_symbol = PositionGetString(POSITION_SYMBOL);
         string order_comment = PositionGetString(POSITION_COMMENT);
         // 获取订单类型
         ENUM_POSITION_TYPE positionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
         string order_type = (positionType == POSITION_TYPE_BUY) ? "Buy" : "Sell";

         if(symbol == order_symbol && type == order_type && comment == order_comment) {
            count++;
         }

      }
   }

   if(count >= iOrderLimit) {
      return false;
   }

   return true;
}
//+------------------------------------------------------------------+


////+------------------------------------------------------------------+
////| 单边共有多少损单                                                 |
////+------------------------------------------------------------------+
//int FindNearestLossCount(string symbol,ENUM_TIMEFRAMES timeframe, string order_type) {
//   HistorySelect(TimeLocal() - 2 * 24 * 3600, TimeCurrent());
//   int total = HistoryDealsTotal();
//   int count = 0;
//   bool is_break = false;
//   //Print(total+"订单总数");
//   for(int i=total-1; i>=0; i--) {
//
//      ulong in_order_ticket = HistoryDealGetTicket(i);
//      ENUM_DEAL_ENTRY in_order_entry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(in_order_ticket, DEAL_ENTRY);
//      //入方向订单(开仓)
//      if(in_order_entry == DEAL_ENTRY_IN) {
//         ulong in_order_positionId = HistoryDealGetInteger(in_order_ticket, DEAL_POSITION_ID);
//         string in_order_symbol = HistoryDealGetString(in_order_ticket, DEAL_SYMBOL);
//         int digits = SymbolInfoInteger(in_order_symbol, SYMBOL_DIGITS);
//         string in_order_type = (HistoryDealGetInteger(in_order_ticket, DEAL_TYPE) == DEAL_TYPE_BUY) ? "Buy" : "Sell";
//         double in_order_commission = RoundToNDecimalPlaces(HistoryDealGetDouble(in_order_ticket, DEAL_COMMISSION),digits);
//         string in_order_comment = HistoryDealGetString(in_order_ticket, DEAL_COMMENT);
//         double in_order_swap = RoundToNDecimalPlaces(HistoryDealGetDouble(in_order_ticket, DEAL_SWAP),digits);
//
//
//         string result[];
//         string sep = "_";
//         ushort u_sep;
//         u_sep = StringGetCharacter(sep, 0);
//         int k = StringSplit(in_order_comment, u_sep, result);
//         if(ArraySize(result)>0) {
//            for(int j=total-1; j>=0; j--) {
//               ulong out_order_ticket = HistoryDealGetTicket(j);
//               ENUM_DEAL_ENTRY out_order_entry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(out_order_ticket, DEAL_ENTRY);
//               if(out_order_entry == DEAL_ENTRY_OUT || out_order_entry == DEAL_ENTRY_OUT_BY) {
//                  ulong out_order_positionId = HistoryDealGetInteger(out_order_ticket, DEAL_POSITION_ID);
//                  double out_order_commission = RoundToNDecimalPlaces(HistoryDealGetDouble(out_order_ticket, DEAL_COMMISSION),digits);
//                  //出方向订单(平仓)
//                  if(out_order_positionId == in_order_positionId && result[0] == "LeonSpikeGoldEA" && result[1] == timeframe  && order_type == in_order_type && symbol == in_order_symbol) {
//                     double order_profit = RoundToNDecimalPlaces(HistoryDealGetDouble(out_order_ticket, DEAL_PROFIT),digits);
//                     if((order_profit+in_order_commission+out_order_commission+in_order_swap) < 0) {
//                        count++;
//                     } else {
//                        is_break =true;
//                        break;
//
//                     }
//                  }
//               }
//            }
//         }
//
//
//      }
//      if(is_break == true) {
//         break;
//      }
//   }
//   //Print(count+"count");
//   return count;
//
//}
////+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| 下单                                                             |
//+------------------------------------------------------------------+
void SendOrders(int magic, string symbol, double lots, ENUM_SYMBOL_INFO_DOUBLE type, double sl, double tp, string comment,ulong slippage) {
   CTrade trade;
   trade.SetExpertMagicNumber(magic);
   trade.SetDeviationInPoints(slippage);
   int digits = SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   double price = RoundToNDecimalPlaces(SymbolInfoDouble(symbol, type),digits);

   if(type == SYMBOL_BID) {
      int ticket =  trade.Sell(lots, symbol, price, sl, tp, comment);
      if(ticket < 0) {
         PrintFormat("Sell order failed. Error code: %d", GetLastError());
      }
   } else if (type == SYMBOL_ASK) {
      int ticket = trade.Buy(lots, symbol, price, sl, tp, comment);
      if(ticket < 0) {
         PrintFormat("Buy order failed. Error code: %d", GetLastError());
      }
   }
}



//+------------------------------------------------------------------+
//| 追踪止损                                                         |
//+------------------------------------------------------------------+
void TrailingStop() {
   CTrade trade;
   int totalPositions = PositionsTotal();
   for(int i = 0; i < totalPositions; i++) {
      ulong ticket = PositionGetTicket(i);

      // 如果成功选择持仓订单
      if(PositionSelectByTicket(ticket)) {
         // 获取持仓订单的详细信息
         string symbol = PositionGetString(POSITION_SYMBOL);
         string comment = PositionGetString(POSITION_COMMENT);
         double magic = PositionGetInteger(POSITION_MAGIC);
         double sl = PositionGetDouble(POSITION_SL);
         double tp = PositionGetDouble(POSITION_TP);
         double open = PositionGetDouble(POSITION_PRICE_OPEN);
         double current = PositionGetDouble(POSITION_PRICE_CURRENT);

         // 获取订单类型
         ENUM_POSITION_TYPE positionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
         string orderType = (positionType == POSITION_TYPE_BUY) ? "Buy" : "Sell";

         string result[];
         string sep = "_";
         ushort u_sep;
         u_sep = StringGetCharacter(sep, 0);
         int k = StringSplit(comment, u_sep, result);
         int digits = SymbolInfoInteger(symbol, SYMBOL_DIGITS);
         if(StringLen(comment) != 0 && result[0] == "LeonSpikeGoldEA") {
            if(orderType == "Sell" ) {
               if((open - current) > iTrailingStopPrice) {
                  double new_sl = open - ((open - current) * iPriceDifferentPercent / 100);
                  new_sl = RoundToNDecimalPlaces(new_sl, digits);
                  if(new_sl < sl) {
                     if (!trade.PositionModify(ticket, new_sl, tp)) {
                        //PrintFormat("追踪损设置失败 订单 %d. 错误代码: %d", ticket, GetLastError());
                     } else {
                        //PrintFormat("%d 单的追踪止损设置为 %f", ticket, new_sl);
                     }
                  }
               }

            } else if(orderType == "Buy") {
               if((current - open) > iTrailingStopPrice) {
                  double new_sl = open + ((current - open) * iPriceDifferentPercent / 100);
                  new_sl = RoundToNDecimalPlaces(new_sl, digits);
                  if(new_sl > sl) {
                     if (!trade.PositionModify(ticket, new_sl, tp)) {
                        //PrintFormat("追踪损设置失败 订单 %d. Error code: %d", ticket, GetLastError());
                     } else {
                        //PrintFormat("%d 订单的追踪止损设置为 %f", ticket, new_sl);
                     }
                  }
               }

            }
         }
      }
   }
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| 是不否在允许交易的时间                                           |
//+------------------------------------------------------------------+
bool IsAllowPeriod() {
   MqlDateTime dt;
   TimeCurrent(dt);
   if(dt.day_of_week == 5 &&dt.hour > iFriday_day_stop_trading) {
      return false;
   } else if(dt.day_of_week == 1 && dt.hour < iMonday_day_stop_trading) {
      return false;
   } else {
      if(dt.hour== 0 && dt.min<=30) {
         return iBlock_0000_0030;
      } else if(dt.hour== 0 && dt.min>30) {
         return iBlock_0030_0100;
      } else if(dt.hour == 1 && dt.min<=30) {
         return iBlock_0100_0130;
      } else if(dt.hour == 1 && dt.min>30) {
         return iBlock_0130_0200;
      } else if(dt.hour == 2 && dt.min<=30) {
         return iBlock_0200_0230;
      } else if(dt.hour == 2 && dt.min>30) {
         return iBlock_0230_0300;
      } else if(dt.hour == 3 && dt.min<=30) {
         return iBlock_0300_0330;
      } else if(dt.hour == 3 && dt.min>30) {
         return iBlock_0330_0400;
      } else if(dt.hour == 4 && dt.min<=30) {
         return iBlock_0400_0430;
      } else if(dt.hour == 4 && dt.min>30) {
         return iBlock_0430_0500;
      } else if(dt.hour == 5 && dt.min<=30) {
         return iBlock_0500_0530;
      } else if(dt.hour == 5 && dt.min>30) {
         return iBlock_0530_0600;
      } else if(dt.hour == 6 && dt.min<=30) {
         return iBlock_0600_0630;
      } else if(dt.hour == 6 && dt.min>30) {
         return iBlock_0630_0700;
      } else if(dt.hour == 7 && dt.min<=30) {
         return iBlock_0700_0730;
      } else if(dt.hour == 7 && dt.min>30) {
         return iBlock_0730_0800;
      } else if(dt.hour == 8 && dt.min<=30) {
         return iBlock_0800_0830;
      } else if(dt.hour == 8 && dt.min>30) {
         return iBlock_0830_0900;
      } else if(dt.hour == 9 && dt.min<=30) {
         return iBlock_0900_0930;
      } else if(dt.hour == 9 && dt.min>30) {
         return iBlock_0930_1000;
      } else if(dt.hour == 10 && dt.min<=30) {
         return iBlock_1000_1030;
      } else if(dt.hour == 10 && dt.min>30) {
         return iBlock_1030_1100;
      } else if(dt.hour == 11 && dt.min<=30) {
         return iBlock_1100_1130;
      } else if(dt.hour == 11 && dt.min>30) {
         return iBlock_1130_1200;
      } else if(dt.hour == 12 && dt.min<=30) {
         return iBlock_1200_1230;
      } else if(dt.hour == 12 && dt.min>30) {
         return iBlock_1230_1300;
      } else if(dt.hour == 13 && dt.min<=30) {
         return iBlock_1300_1330;
      } else if(dt.hour == 13 && dt.min>30) {
         return iBlock_1330_1400;
      } else if(dt.hour == 14 && dt.min<=30) {
         return iBlock_1400_1430;
      } else if(dt.hour == 14 && dt.min>30) {
         return iBlock_1430_1500;
      } else if(dt.hour == 15 && dt.min<=30) {
         return iBlock_1500_1530;
      } else if(dt.hour == 15 && dt.min>30) {
         return iBlock_1530_1600;
      } else if(dt.hour == 16 && dt.min<=30) {
         return iBlock_1600_1630;
      } else if(dt.hour == 16 && dt.min>30) {
         return iBlock_1630_1700;
      } else if(dt.hour == 17 && dt.min<=30) {
         return iBlock_1700_1730;
      } else if(dt.hour == 17 && dt.min>30) {
         return iBlock_1730_1800;
      } else if(dt.hour == 18 && dt.min<=30) {
         return iBlock_1800_1830;
      } else if(dt.hour == 18 && dt.min>30) {
         return iBlock_1830_1900;
      } else if(dt.hour == 19 && dt.min<=30) {
         return iBlock_1900_1930;
      } else if(dt.hour == 19 && dt.min>30) {
         return iBlock_1930_2000;
      } else if(dt.hour == 20 && dt.min<=30) {
         return iBlock_2000_2030;
      } else if(dt.hour == 20 && dt.min>30) {
         return iBlock_2030_2100;
      } else if(dt.hour == 21 && dt.min<=30) {
         return iBlock_2100_2130;
      } else if(dt.hour == 21 && dt.min>30) {
         return iBlock_2130_2200;
      } else if(dt.hour == 22 && dt.min<=30) {
         return iBlock_2200_2230;
      } else if(dt.hour == 22 && dt.min>30) {
         return iBlock_2230_2300;
      } else if(dt.hour == 23 && dt.min<=30) {
         return iBlock_2300_2330;
      } else if(dt.hour == 23 && dt.min>30) {
         return iBlock_2330_2400;
      }
   }

   return true;
}
//+------------------------------------------------------------------+