自己做的EA工具

Discussion in 'MetaTrader' started by ldawen, Aug 22, 2010.

  1. 搞MT4一年了,发个我在使用的EA,改写了一下,没有策略部的,当然,有些代码是在网上“山寨”过来的,改成这样的工具,如默认的止损,止盈,时间止损等,移动止损,帐户余额保护等等,作为辅助交易的工具,可以在手工交易时就非常非常有用了
    这个EA代码已经实战了很长时间,能够正常使用的,只是策略部分自己的思路还不够好。自己也一直在完善细节的部分,也一直有测试自己的策略,挂机测试,希望与各位共同学习提高。

    以下是基本的功能介绍:
    1)4位报价,5位报价都适用。所说的点,都是按第4位小数的值,在5位报价平台也是如此。
    2)帐户余保护,可以设置最大亏损百分比后就关仓。
    3)开仓单最大亏损百分比关仓。
    4)BEP,即设置到达一定的利润点后,就保护多少点值。
    5)移动止损。
    6)利润保护,可设置不同的利润保护等级,最多5个等级
    7)日期及时间的设置,指定日期及时间段开平仓。本来有EA中使用的,但现在将策略部分删除了,意义不大
    8)时间止损,可以设定一定时间内,单子不盈利就关掉


    Code:
    #include    <stdlib.mqh>
    #include    <stderror.mqh>
    #include    <WinUser32.mqh>
    
    extern bool         Debug               = false;
    extern string       UserComment         = "";
    extern int          MagicNum            = 0;
    extern bool         EADisabled          = false;
    extern bool         EmergencyCloseAll   = false;
    extern int          Portion = 1;
    extern bool         UseAccountProtect   = false;
    extern double       StopTradePercent    = 50;  // percent of account balance lost before trading stops
    extern double       MaxDDPercent        = 60;  // Percent of portion for max drawdown level.
    
    extern bool         MoveToBEP           = true; 
    extern int          MoveStopWhenPoint   = 48;
    extern int          LockProfit          = 3;
    
    extern string       mm8 = "OrderProfitProtect Settings";
    extern bool         UseOrderProfitProtect       = true;
    extern int          BeginProtectPositions       = 2;
    extern double       ProfitProtectLevel_0_Pips   = 50;
    extern double       ProfitProtectLevel_0_Percen = 10;
    extern double       ProfitProtectLevel_1_Pips   = 120;
    extern double       ProfitProtectLevel_1_Percen = 20;
    extern double       ProfitProtectLevel_2_Pips   = 220;
    extern double       ProfitProtectLevel_2_Percen = 40;
    extern double       ProfitProtectLevel_3_Pips   = 280;
    extern double       ProfitProtectLevel_3_Percen = 50;
    extern double       ProfitProtectLevel_4_Pips   = 380;
    extern double       ProfitProtectLevel_4_Percen = 60;
    extern double       ProfitProtectLevel_5_Pips   = 450;
    extern double       ProfitProtectLevel_5_Percen = 70;
    
    //-----------------------------------------------------
    extern string       s08                 = "--TRADING TIME MANAGEMENT--";
    extern string       TTM1                = "Set time frames when new trades can open.";
    extern string       TTM2                = "If Starthour = Stophour, then trade 24/5.";
    extern string       TTM3                = "If TTMGoFlat=true, close all open trades";
    extern string       TTM4                = "when outside trading hours or days.";
    extern bool         EnableTradeTimeManage = false;
    extern int          ManualGMToffset     = 3;       // Set your broker's GMT Offset
    extern int          GMTStartHour        = 0;       // Start trading at 0:00/GMT
    extern int          GMTStopHour         = 0;       // Stop trading at 23:59/GMT
    extern bool         TradeOnFriday       = true;
    extern int          FridayGMTStopHour   = -1;       // If set to 0 or higher, will prevent new trades from opening on Friday starting at that hour GMT.
    extern bool         TTMGoFlat           = false;
    
    extern string       s12                 = "-- Use this section to exclude trading days";
    extern bool         EnableBlackout      = false;
    extern int          StartBlackoutDay    = 20;
    extern int          StartBlackoutMonth  = 12;
    extern int          StopBlackoutDay     = 15;
    extern int          StopBlackoutMonth   = 01;
    int                 StartBlackout       = 0;
    int                 StopBlackout        = 0;
    
    
    //-----------------------------------------------------
    extern bool         UsingTakeProfit     = true;
    extern int          TakeProfit          = 300;
    extern bool         UsingStopLoss       = true;
    extern double       StopLoss            = 39;  // piont
    extern bool         UsingTrailingStop   = false;
    extern double       TrailingStop        = 55;//piont
    extern bool         UsingHiLoTrailingStop = true;
    extern bool         UsingTimeStopLoss   = true;
    extern int          TimeStopLossMin        = 125;  //Minute
    
    
    string     myType = "ALL";
    
    int        Magic;
    string     Type;
    
    double     myPoint;
    datetime   BarTime;
    
    double     Lot;
    double     StopTradeBalance;
    double     InitialAB;
    double     MaxDDPer;
    double     MaxDD;
    double     OrdersBuyLots;
    double     OrdersSellLots;
    double     MaxTradeLots;
    
    int        OrderCount;
    int        BuyOrderCount;
    int        SellOrderCount;
    double     OrderProfitPips = 0;
    double     OrderProfits = 0;
    double     MaxOrderProfitPips = 0;
    double     LastOrderOpenPrice;
    
    
    //---signal variable
    int        BaseEntrySignal;
    int        AddPositionSignal;
    int        CloseSignal;
    int        SignalFilter;
    
    
    double     uplevel;
    double     dnlevel;
    
    
    // Comment variable
    
    string     txt;
    
    //+------------------------------------------------------------------+
    //| expert initialization function                                   |
    //+------------------------------------------------------------------+
    int init()
      {
    //----
      myPoint = SetmyPoint();
      Magic = 0;
      Type = "ALL";
            
      while (!IsConnected())
      {
        Comment("Waiting for connection...");
        Sleep(10000);
      }
    
      StartBlackout = DayNumber(StartBlackoutMonth, StartBlackoutDay);
      StopBlackout =  DayNumber(StopBlackoutMonth, StopBlackoutDay);
      
      InitialAB=AccountBalance();
      StopTradeBalance=InitialAB - InitialAB*(StopTradePercent/100);
    
    //----
       return(0);
      }
    //+------------------------------------------------------------------+
    //| expert deinitialization function                                 |
    //+------------------------------------------------------------------+
    int deinit()
      {
    //----
       
    //----
       return(0);
      }
    //+------------------------------------------------------------------+
    //| expert start function                                            |
    //+------------------------------------------------------------------+
    
    int start()
      {
    
    
      if (EADisabled == true)
      {
        if (IsTesting()) Comment("EA Disabled! Check Journal Log for details.\n");
        else Comment("EA Disabled! Check Experts Log for details.\n");
        return(0);
      }
      
      Comment(txt);
    
      TraceOrderDetail(Type);  
    
      if(EmergencyCloseAll == true)
      {
        CloseOrders(OP_SELL,"ALL");
        CloseOrders(OP_BUY,"ALL");
        EADisabled = true;
        Comment("Close All Position and Halt");
        Print("Close All Position and Halt");
        return(0);
      }
      
      if(UseAccountProtect == true) 
      {
        if(AccountProtection()== true)
        {
    	   Comment("Account Balance dropped below stop trade percent");
    	   Comment( "Reset EA, account balance dropped below stop trade percent");
    	   Print("Account Balance dropped below stop trade percent");
    	   return(0);
    	 }
      }
      
      if(UseOrderProfitProtect == true)
      {  
        if(PositionsProtection(Type)== true)
        {
    	   BarTime = Time[0];   //don't open order in the current Bar
    	   return(0);
    	 }
      }
        
    
      if (!IsTradingTime() && TTMGoFlat && OrderProfitTotalPips("ALL") >0)
      {
        Comment("Closing orders because outside of trading window.");
        Print("Closing orders because outside of trading window.");
        CloseOrders(OP_SELL,"ALL");
        CloseOrders(OP_BUY,"ALL");
      }
         
      if(!IsTradingTime())
      {
        Comment("Closing orders because outside of trading window.");
        Print("Closing orders because outside of trading window.");
        return(0);
      }
       
      ModifyDefaultStopLoss();
     
     if(MoveToBEP == true) 
        BEP(Type);
        
     if(UsingTrailingStop == true)  
        TrailStop(Type,TrailingStop);
        
     if(UsingTimeStopLoss == true)
        TimeStopLoss (Type);    
    //-------------------------------------------------------------
        
    //----
       return(0);
      }
    //+------------------------------------------------------------------+
    //1 long -1 short 0 no signal
    
    
    
    //--------------------------------------------------------------------------------
    double SetmyPoint() 
    {
       double res;
       if (Digits < 4) res = 0.01;
       else res = 0.0001;
       return (res);
    }
    
    double StopLong(double Price, int Pips) 
    {
       if (Price == 0) return (0);
       else return (NormalizeDouble(Price - Pips * myPoint,Digits)); 
    }
    
    double StopShort(double Price, int Pips) 
    {
       if (Price == 0) return (0);
       else return (NormalizeDouble(Price + Pips * myPoint,Digits));
    }
    
    double TakeLong(double Price, int Pips) 
    {
       if (Price == 0) return (0);
       else return (NormalizeDouble(Price + Pips * myPoint,Digits));
    }
    
    double TakeShort(double Price, int Pips) 
    {
       if (Price == 0) return (0);
       else return (NormalizeDouble(Price - Pips * myPoint,Digits));
    }
    
    double ValidStopLoss(int myOrderType, double Price, double StopPrice) 
    {
       double Spread = MarketInfo(Symbol(), MODE_STOPLEVEL);
       if (Digits == 3 || Digits == 5) Spread /= 10.0;
       if (myOrderType == OP_BUY)
          if (Price - StopPrice < Spread * myPoint) StopPrice = NormalizeDouble(Price + Spread * myPoint,Digits);
       if (myOrderType == OP_SELL)
          if (StopPrice - Price < Spread * myPoint) StopPrice = NormalizeDouble(Price - Spread * myPoint,Digits);
       return (StopPrice);
    }
    
    double ValidTakeProfit(int myOrderType, double Price, double myTakeProfit) 
    {
       double Spread = MarketInfo(Symbol(), MODE_STOPLEVEL);
       if (Digits == 3 || Digits == 5) Spread /= 10.0;
       if (myOrderType == OP_SELL)
          if (Price - myTakeProfit < Spread * myPoint) 
            myTakeProfit = Price - Spread * myPoint;
            
       if (myOrderType == OP_BUY)
          if (myTakeProfit - Price < Spread * myPoint) 
            myTakeProfit = Price + Spread * myPoint;
       return (myTakeProfit);
    }
    
    
    int CalculateBuyOrders(string  myType)
    {
      int cnt = 0;
      int total = OrdersTotal();
      for(int i = 0;i<total;i++)
      {
        if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ==false) continue;
        if( isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType) &&  
            (OrderType()==OP_BUY)
          )
          cnt++;
      }
      return(cnt);
    }
    
    
    int CalculateSellOrders(string  myType)
    {
      int cnt = 0;
      int total = OrdersTotal();
      for(int i = 0;i<total;i++)
      {
        if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ==false) continue;
        if( isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType) &&  
            (OrderType()==OP_SELL)
          )
          cnt++;
      }
      return(cnt);
    }
    
    
    //------------------------------------------------------------------------------------
    double CalculateBuyLots(string myType)
    {
      double sum = 0;
      int total = OrdersTotal();
      for(int i = 0;i<total;i++)
      {
        if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ==false) continue;
    
        if( isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType)  &&  
            (OrderType()==OP_BUY)
          )
          sum+=OrderLots();
      }
      return(sum);
    }
    
    double CalculateSellLots(string myType)
    {
      double sum = 0;
      int total = OrdersTotal();
      for(int i = 0;i<total;i++)
      {
        if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ==false) continue;
        
        if( isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType) &&  
            (OrderType()==OP_SELL)
          )
          sum+=OrderLots();
      }
      return(sum);
    }
    
    bool isOrder(string mySymbol,int myMagicNumber,string myOrderComment,string  myType)
    {
    
      if(Debug)
      {
        Print(mySymbol," ",myMagicNumber," ",myOrderComment," ",myType); 
      }
    
        if(myType =="ALL" || myType ==""  )
        {  if(StringFind(myOrderComment,UserComment)>=0 && 
               mySymbol == Symbol() &&  myMagicNumber == Magic )
            return(true);
          else
            return(false);
        }
        
             
    }  //END FUN
    
    void TraceOrderDetail(string myType)
    {  
      static int LastOrderCount = -1;
      
      BuyOrderCount = CalculateBuyOrders ("ALL");
      SellOrderCount = CalculateSellOrders("ALL");
      OrderCount = BuyOrderCount  + SellOrderCount;
    
      
      
      if(OrderCount < 1 || LastOrderCount != OrderCount) 
      {
        MaxOrderProfitPips = 0;
        LastOrderOpenPrice = 99999999999;
        LastOrderCount = OrderCount;
      } else
      {
        OrderProfitPips = OrderProfitTotalPips(myType); //order profit pips
        OrderProfits =  OrderProfitPips * MarketInfo(Symbol(),MODE_TICKVALUE) * (myPoint /Point);
        OrdersBuyLots = CalculateBuyLots(myType);
        OrdersSellLots = CalculateSellLots(myType);
    
        if(MaxOrderProfitPips < OrderProfitPips)
           MaxOrderProfitPips  = OrderProfitPips;
      }
    
      
    }
    //+------------------------------------------------------------------+
    
    
    
    //---------------------------------------------------------
    
    double OrderProfitTotalPips(string myType)
    {
       int     cnt,  total = 0;
       double tickvalue = MarketInfo(Symbol(),MODE_TICKVALUE);
       double TotalProfitPips = 0;
       for(cnt=0;cnt<OrdersTotal();cnt++)
       {
          if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES) ==false) continue;
        
          if((OrderType()==OP_SELL||OrderType()==OP_BUY) &&
             isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType))
             {
             double PipProfitPips = (OrderProfit()/OrderLots()/ (tickvalue * (myPoint / Point)));
             TotalProfitPips = TotalProfitPips+PipProfitPips;
             }
       }
       return(TotalProfitPips);
    } 
    
    //---------------------------------------------------------
    
    void  StopMoveToCost (string myType,int OffsetPips)
    {
      bool res = false;
      int total = OrdersTotal();
      for(int i = 0;i<total;i++)
      {
        if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ==false) continue;
        if( isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType))  
          {
            if( OrderType()==OP_BUY  && OrderOpenPrice() - OffsetPips * myPoint > OrderStopLoss()) 
              ModiFyOrder(OrderTicket(),OrderOpenPrice(), OrderOpenPrice() - OffsetPips * myPoint, OrderTakeProfit());
            if( OrderType()==OP_SELL && OrderOpenPrice() + OffsetPips * myPoint < OrderStopLoss()) 
              ModiFyOrder(OrderTicket(),OrderOpenPrice(), OrderOpenPrice() + OffsetPips * myPoint, OrderTakeProfit());
          }
      } //for
      }
    //---------------------------------------------------------
    
    
    
    
    bool  AccountProtection ()
    {
    
    		double PortionBalance = NormalizeDouble(AccountBalance() / Portion, 2);
    
    		if ( -OrderProfits >= (PortionBalance * MaxDDPercent / 100) )
          {
            CloseOrders(OP_SELL,"ALL");
            CloseOrders(OP_BUY,"ALL");
            Print("AccountProtection Close");
          }
          
    		if ( -OrderProfits > MaxDD) MaxDD = -OrderProfits;
    		MaxDDPer = MathMax(MaxDDPer, MaxDD / PortionBalance * 100);
    
    
    		double StepAB = InitialAB + InitialAB * (StopTradePercent / 100);
    		double StepSTB = AccountBalance() - AccountBalance()*(StopTradePercent / 100);
    		double NextISTB = StepAB - StepAB*(StopTradePercent / 100);
    
    		if (StepSTB > NextISTB){
    				InitialAB = StepAB;
    				StopTradeBalance = StepSTB;
    		}
    
    		double InitialAccountMultiPortion = StopTradeBalance/Portion;
    
    		if (PortionBalance < InitialAccountMultiPortion){
    				return (true);
    		}
    
          return(false);
    }
    
    bool  PositionsProtection(string  myType)
    {
       if(OrderCount < BeginProtectPositions) 
         return(false);
         
    //  profit protect level 5
       if(MaxOrderProfitPips >= ProfitProtectLevel_5_Pips) 
       { if(OrderProfitPips < NormalizeDouble(MaxOrderProfitPips * (ProfitProtectLevel_5_Percen /100),0))
         {
            CloseOrders(OP_SELL,myType);
            CloseOrders(OP_BUY,myType);
            Print("Order protected ",ProfitProtectLevel_5_Percen," MaxOrderProfitPips ",MaxOrderProfitPips," now " ,OrderProfitPips);
            return(true);
         } else return(false);
       } else
    
    //  profit protect level 4
       if(MaxOrderProfitPips >= ProfitProtectLevel_4_Pips) 
       { if(OrderProfitPips < NormalizeDouble(MaxOrderProfitPips * (ProfitProtectLevel_4_Percen /100),0))
         {
            CloseOrders(OP_SELL,myType);
            CloseOrders(OP_BUY,myType);
            Print("Order protected ",ProfitProtectLevel_4_Percen," MaxOrderProfitPips ",MaxOrderProfitPips," now " ,OrderProfitPips);
            return(true);
         } else return(false);
       } else
    
    //  profit protect level 3
       if(MaxOrderProfitPips >= ProfitProtectLevel_3_Pips) 
       { if(OrderProfitPips < NormalizeDouble(MaxOrderProfitPips * (ProfitProtectLevel_3_Percen /100),0))
         {
            CloseOrders(OP_SELL,myType);
            CloseOrders(OP_BUY,myType);
            Print("Order protected ",ProfitProtectLevel_3_Percen," MaxOrderProfitPips ",MaxOrderProfitPips," now " ,OrderProfitPips);
            return(true);
         } else return(false);
       }  else
    
    //  profit protect level 2
       if(MaxOrderProfitPips >= ProfitProtectLevel_2_Pips) 
       { if(OrderProfitPips < NormalizeDouble(MaxOrderProfitPips * (ProfitProtectLevel_2_Percen /100),0))
         {
            CloseOrders(OP_SELL,myType);
            CloseOrders(OP_BUY,myType);
            Print("Order protected ",ProfitProtectLevel_2_Percen," MaxOrderProfitPips ",MaxOrderProfitPips," now " ,OrderProfitPips);
            return(true);
         } else return(false);
       }  else
    
    //  profit protect level 1
       if(MaxOrderProfitPips >= ProfitProtectLevel_1_Pips) 
       { if(OrderProfitPips < NormalizeDouble(MaxOrderProfitPips * (ProfitProtectLevel_1_Percen /100),0))
         {
            CloseOrders(OP_SELL,myType);
            CloseOrders(OP_BUY,myType);
            Print("Order protected ",ProfitProtectLevel_1_Percen," MaxOrderProfitPips ",MaxOrderProfitPips," now " ,OrderProfitPips);
            return(true);
         } 
       }  else
    
    //  profit protect level 0   
       if(MaxOrderProfitPips >= ProfitProtectLevel_0_Pips) 
       { if(OrderProfitPips < NormalizeDouble(MaxOrderProfitPips * (ProfitProtectLevel_0_Percen /100),0))
         {
            CloseOrders(OP_SELL,myType);
            CloseOrders(OP_BUY,myType);
            Print("Order protected ",ProfitProtectLevel_0_Percen," MaxOrderProfitPips ",MaxOrderProfitPips," now " ,OrderProfitPips);
            return(true);
         } else return(false);
       }  
    
      return(false);
    
    }  // end PositionsProtection
    
    //---------------------------------------------------------
    bool GetTradeContext()
    {
      bool hadToWait=false;
      
      while(!IsTradeAllowed())
      {
        Sleep(5000);
        hadToWait=true;
      }
      
      while(IsTradeContextBusy())
      {
        Sleep(200);
        hadToWait=true;
      }
      
      return(hadToWait);
    }
    
    //------------------ModifyStop function-------------------------------------
    bool ModiFyOrder(int Ticket,double myOrderPrice,double myStopPrice,double myTakeProfit)
    { 
     bool res = true;
     int retryTimes = 5,cnt = 0;
     
     if(myStopPrice ==0.0 && myTakeProfit == 0.0) 
        return(true);
     
     while(cnt < retryTimes)
     {
        res = OrderModify(Ticket,myOrderPrice,myStopPrice,myTakeProfit,0,Blue);
        if(res==false)
        {        
          cnt += 1;
        } 
        else  
        {
          cnt = retryTimes;
        }
      }  
      
      if(res==false)
      {
          Print("ModiFyOrder error:" ,ErrorDescription(GetLastError()));
          Print("Ticket",Ticket,"OrderPrice ",myOrderPrice," StopPrice ",myStopPrice," TakeProfit ",myTakeProfit);     
      }
        return(res);
    }
    
    //------------------------------------------------------------------------------------- 
    bool CloseOrder(int Ticket, double Lots, int myOrderType) 
    {
       bool res;
       int ErrorCode;
       double Price;
       bool Status = false;
       
       if(myOrderType == OP_BUYLIMIT || myOrderType == OP_BUYSTOP || 
          myOrderType == OP_SELLLIMIT || myOrderType == OP_SELLSTOP)
       {
          OrderDelete(OrderTicket());
          return(true);
       }
       
       if (myOrderType == OP_BUY)   Price = Bid;
       if (myOrderType == OP_SELL)  Price = Ask;
       if (Digits > 0) Price = NormalizeDouble(Price, Digits);
       int cnt = 0;
       while (!Status) {
          if (IsTradeAllowed() == true) {
             res = OrderClose(Ticket, Lots, Price, MarketInfo(Symbol(),MODE_SPREAD), Violet);
             ErrorCode = GetLastError();
          } else cnt++;
          
          if (res == true) Status = true;
          ErrorCode = GetLastError();
          switch (ErrorCode) {
          case 0/* NO_ERROR */:
             Status = true;
             break;
          case 4/* SERVER_BUSY */:
          case 6/* NO_CONNECTION */:
          case 129/* INVALID_PRICE */:
          case 136/* OFF_QUOTES */:
          case 137/* BROKER_BUSY */:
          case 146/* TRADE_CONTEXT_BUSY */:
          case 128/* TRADE_TIMEOUT */:
             RefreshRates();
             cnt++;
             break;
          case 135/* PRICE_CHANGED */:
          case 138/* REQUOTE */:
             RefreshRates();
             continue;
          default:
             Status = TRUE;
          }
          if (cnt > 20) Status = TRUE;  //10 time try
          if (!Status) 
          {
             Sleep(500);
             RefreshRates();
          }
       }
       if (res == true || ErrorCode == 0/* NO_ERROR */) return (true);
       Print(" Error closing order : (", ErrorCode, ") " + ErrorDescription(ErrorCode));
       return (false);
    }
    
    bool CloseOrders(int orderMode,string myType)
    {
      int OrderCount=0, gle=0;
      int cnt,mode;
      int TicketArray[100];
      double ClosePrice=0;
      string stringOrderMode;
      
      if (orderMode==OP_BUY)  stringOrderMode="BUY";
      if (orderMode==OP_SELL) stringOrderMode="SELL";
    
    // first, we retrieve all ticket IDs for existing orders to close out  
      for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
      {
        if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
        {
          mode=OrderType();
          if (isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType))
    	   {
            if (mode==orderMode)
            { 
              TicketArray[OrderCount]=OrderTicket();
              Print("OrderCount: ",OrderCount,", Ticket: ",TicketArray[OrderCount]," Selected for closure.");
              OrderCount++;
    	 	  }
          }
    	 }
    	 else
    	 {
    	   gle=GetLastError();
          Print("Error selecting an order in CloseAllOrders!!! Error #",gle,": ",ErrorDescription(gle));
          return(false); //Since returning false, the caller will retry this function again
    	 }
      }
    
    // second, we close out all applicable orders in the array.  this two step method prevents problems closing out all orders successfully at once.
      int retries=0;
      while(retries<20)
      {
        for(cnt=0;cnt<OrderCount;cnt++)
        {
          if (TicketArray[cnt]>0)
          {
            if (OrderSelect(TicketArray[cnt], SELECT_BY_TICKET, MODE_TRADES))
            {
              mode=OrderType();
              GetTradeContext(); RefreshRates();
              if (mode==OP_BUY)  ClosePrice=NormalizeDouble(Bid,Digits);
              if (mode==OP_SELL) ClosePrice=NormalizeDouble(Ask,Digits);
              if (mode == (orderMode+2) || mode == (orderMode+4))
              {
                if (OrderDelete(OrderTicket()))
                {
                  TicketArray[cnt]=0;
                }
                else        
                {
                  gle=GetLastError();
                  Print("Error closing pending order #",TicketArray[cnt],": Error #",gle,": ",ErrorDescription(gle));
                }
              }
              else
              {
                if (CloseOrder(OrderTicket(), OrderLots(), OrderType()))
                {
                  
                  TicketArray[cnt]=0;
                }
                else
                {
                  gle=GetLastError();
                  Print("Error closing order #",TicketArray[cnt],": Error #",gle,": ",ErrorDescription(gle));
                }
              }
            }
            else
            {
              gle=GetLastError();
              Print("Error selecting order #",TicketArray[cnt],": Error #",gle,": ",ErrorDescription(gle));
            }
          }
        }
      retries++;
      }
      
      bool CloseAllSuccess=true;
      for(cnt=0;cnt<OrderCount;cnt++)
      {
        if (TicketArray[cnt]>0)
        {
          CloseAllSuccess=false;
          Alert("Could not close ticket #",TicketArray[cnt],"! Will keep retrying.");
        }
      }
      
      if(CloseAllSuccess)
      {
        return(true);
      }
      else
      {
        Print("There was a critical error closing one or more ",stringOrderMode," orders when trying to CLOSE ALL!");
        return(false); //Since returning false, the caller will retry this function again
      }
    }
    
    
    	
    //------------------------------------------------------------------------------------- 
    bool ModifyDefaultStopLoss()
    {
       double StopPrice;
       double TakeProfitPrice;
       double myPrice; 
       int retryTimes = 5,cnt = 0;
    
      bool res = false;
      int total = OrdersTotal();
      
      for(int i = 0;i<total;i++)
      {
        if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ==false) continue;
        if(!isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType))  continue;
        
       while(cnt < retryTimes)
       {           
         RefreshRates(); 
         if(OrderType() == OP_BUY)
         {
           myPrice = Ask;
           StopPrice =StopLong (Ask,StopLoss);
           StopPrice = ValidStopLoss(OP_BUY,Ask,StopPrice);
          
           TakeProfitPrice=TakeLong(Ask,TakeProfit);
           TakeProfitPrice=ValidTakeProfit(OP_BUY,Ask,TakeProfitPrice);
         }
       
         if(OrderType() == OP_SELL)
         {
           myPrice = Bid;
           StopPrice =StopShort(Bid,StopLoss);
           StopPrice = ValidStopLoss(OP_SELL,Bid,StopPrice);
           
           TakeProfitPrice=TakeShort(Bid,TakeProfit);
           TakeProfitPrice=ValidTakeProfit(OP_SELL,Bid,TakeProfitPrice);
         }
       
         if(UsingStopLoss   == false)  StopPrice = 0;
         if(UsingTakeProfit == false)  TakeProfitPrice = 0;
         
          if(ModiFyOrder(OrderTicket(),OrderOpenPrice(),StopPrice,TakeProfitPrice)== true) 
          {            
            cnt =  retryTimes;
            res =  true;
          }
          else  cnt++; 
           
         } //while 
       
      } //for
    
       
       return(res);
    
    }
    
    //---------------------------------------------------------------------------
    void TrailStop(string myType,int triling_i)
    {       
      if (triling_i > 0)
      for (int k=0;k<OrdersTotal();k++)
      {
        if(OrderSelect(k,SELECT_BY_POS)!= true) continue;
        if(isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType))
        {       
          if (OrderType()==OP_BUY && NormalizeDouble(Ask-OrderOpenPrice(),Digits)>=triling_i*myPoint &&
             (OrderStopLoss()< NormalizeDouble(Ask-triling_i*myPoint,Digits) || OrderStopLoss()==0)) 
          {
             if (!ModiFyOrder(OrderTicket(),OrderOpenPrice(),NormalizeDouble(Ask-triling_i*myPoint,Digits),OrderTakeProfit())   )
             {
                Print("Trailing stop error Buy :" +ErrorDescription(GetLastError()));
             }   
          }
          if (OrderType()==OP_SELL && NormalizeDouble(Bid+triling_i*myPoint,Digits)<=OrderOpenPrice() &&
          (OrderStopLoss()>NormalizeDouble(Bid+triling_i*myPoint,Digits) || OrderStopLoss()==0)) 
          {
             if (!ModiFyOrder(OrderTicket(),OrderOpenPrice(),NormalizeDouble(Bid+triling_i*myPoint,Digits),OrderTakeProfit())   )
             {
                Print("Trailing stop error Sell :"+ErrorDescription(GetLastError())); 
             }
          }
        }
      }
    }
    
    //----------------------------------------------------------
    
    void BEP(string myType)
    {
          for (int i = 0; i < OrdersTotal(); i++)
          {
             OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
             if(isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType))
             {
                if(OrderType()==OP_BUY)
                {
                   if(Bid-OrderOpenPrice() >= myPoint * MoveStopWhenPoint)
                   {
                      if(OrderStopLoss()<OrderOpenPrice())
                      {
                         ModiFyOrder(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()+myPoint*LockProfit,Digits),OrderTakeProfit());  
                         return(0);
                      }
                   }
                }
             
                if(OrderType()==OP_SELL)
                {
                   if(OrderOpenPrice()-Ask >= myPoint * MoveStopWhenPoint)
                   {
                      if(OrderStopLoss()>OrderOpenPrice())
                      {
                         ModiFyOrder(OrderTicket(),OrderOpenPrice(),NormalizeDouble(OrderOpenPrice()-myPoint*LockProfit,Digits),OrderTakeProfit());  
                         return(0);
                      }
                   }      
                }
             } 
          }   
    }
    
    
    
    //---------------------------------------------------
    void TimeStopLoss(string myType)
    {     
          
          for (int i = 0; i < OrdersTotal(); i++)
          {
             OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
             if(isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType))
             {
                if(TimeCurrent()-OrderOpenTime() > TimeStopLossMin * 60)
                { 
                  if(OrderType()==OP_BUY)
                  {
                    if(Bid-OrderOpenPrice() < 3 * myPoint )
                    {
                      CloseOrder(OrderTicket(), OrderLots(), OrderType());
                      Print("Time stopLoss,Close");
                    }
                  }
                  
                  if(OrderType()==OP_SELL)
                  {
                    if(OrderOpenPrice()-Ask  < 3 * myPoint )
                    {
                      CloseOrder(OrderTicket(), OrderLots(), OrderType());
                      Print("Time stopLoss,Close");
                    }
                  }
    
                }
             } 
          }   
    }
    
    //---------------------------------------------------
    
    bool IsTradingTime()
    {
       if (EnableTradeTimeManage == false) return(true);
       if (BlackoutTime()) return(false);  // Added for blackout dates
       int currentDay = TimeDayOfWeek(TimeCurrent() - 3600 * ManualGMToffset);
       int currentHour = TimeHour(TimeCurrent() - 3600 * ManualGMToffset);
       if (!TradeOnFriday && currentDay >= 5) return(false); // GMT Adjusted Day of Week
       if (currentDay >= 5 && currentHour >= FridayGMTStopHour && FridayGMTStopHour >= 0) return(false);
       if (GMTStartHour == GMTStopHour) return(true);
       return(IsTradingTimeSub(GMTStartHour, GMTStopHour));
    }
    
    
    bool IsTradingTimeSub(int myStartHour, int myEndHour)
    {
       int currentHour = TimeHour(TimeCurrent() - 3600 * ManualGMToffset);
       int adjustedEndHour = NormalizedHourParam(myEndHour - 1);
    
       if (myStartHour == adjustedEndHour) if (currentHour != myStartHour) return(false);
       if (myStartHour > adjustedEndHour)  if (currentHour < myStartHour && currentHour > adjustedEndHour) return(false);
       if (myStartHour < adjustedEndHour)  if (currentHour < myStartHour || currentHour > adjustedEndHour) return(false);
    
       return(true);
    }
    
    bool BlackoutTime() //DM: Kept variables global in scope
    {
       if (EnableBlackout)
       {
          StartBlackout = DayNumber(StartBlackoutMonth, StartBlackoutDay);
          StopBlackout = DayNumber(StopBlackoutMonth, StopBlackoutDay);
          
          if (StartBlackout <= StopBlackout && DayOfYear() >= StartBlackout && DayOfYear() < StopBlackout)
          {
             return (true);
          }
          
          if ((StartBlackout > StopBlackout && DayOfYear() >= StartBlackout) || (StartBlackout > StopBlackout && DayOfYear() < StopBlackout))
          {
             return (true);
          }
          
          
          else return (false);
          
       }      
       
       return (false);
    }
    
    int DayNumber(int month, int day) {
       
       int days = 0;
       switch(month)
       {
          case 1 : days = 0; break;    
          case 2 : days = 31; break;
          case 3 : days = 59; break;
          case 4 : days = 90; break;
          case 5 : days = 120; break;
          case 6 : days = 151; break;
          case 7 : days = 181; break;
          case 8 : days = 212; break;
          case 9 : days = 243; break;
          case 10: days = 273; break;
          case 11: days = 304; break;
          case 12: days = 334; break;
       }
       
       days = days + day;
       
       bool leapYear = false;
       
       if (MathMod(Year(), 4) == 0)
       {
          leapYear = true;
       }
       else if (MathMod(Year(), 400) == 0)
       {
          leapYear = true;
       }
       else if (MathMod(Year(), 100) == 0)
       {
          leapYear = false;
       }
       
       if (leapYear == true && month > 2) days++;
       
       return (days);
    }
    
    int NormalizedHourParam(int myParam)
    {
      while (true)
      {
        if (myParam >= 24)
        {
           myParam -= 24;
           continue;
        }
        if (myParam >= 0) break;
        myParam += 24;
      }
      return(myParam);
    }
    
    //+------------------------------------------------------------------+
    //| return error description                                         |
    //+------------------------------------------------------------------+
    string ErrorDescription(int error_code)
      {
       string error_string;
    //----
       switch(error_code)
         {
          //---- codes returned from trade server
          case 0:
          case 1:   error_string="no error";                                                  break;
          case 2:   error_string="common error";                                              break;
          case 3:   error_string="invalid trade parameters";                                  break;
          case 4:   error_string="trade server is busy";                                      break;
          case 5:   error_string="old version of the client terminal";                        break;
          case 6:   error_string="no connection with trade server";                           break;
          case 7:   error_string="not enough rights";                                         break;
          case 8:   error_string="too frequent requests";                                     break;
          case 9:   error_string="malfunctional trade operation";                             break;
          case 64:  error_string="account disabled";                                          break;
          case 65:  error_string="invalid account";                                           break;
          case 128: error_string="trade timeout";                                             break;
          case 129: error_string="invalid price";                                             break;
          case 130: error_string="invalid stops";                                             break;
          case 131: error_string="invalid trade volume";                                      break;
          case 132: error_string="market is closed";                                          break;
          case 133: error_string="trade is disabled";                                         break;
          case 134: error_string="not enough money";                                          break;
          case 135: error_string="price changed";                                             break;
          case 136: error_string="off quotes";                                                break;
          case 137: error_string="broker is busy";                                            break;
          case 138: error_string="requote";                                                   break;
          case 139: error_string="order is locked";                                           break;
          case 140: error_string="long positions only allowed";                               break;
          case 141: error_string="too many requests";                                         break;
          case 145: error_string="modification denied because order too close to market";     break;
          case 146: error_string="trade context is busy";                                     break;
          //---- mql4 errors
          case 4000: error_string="no error";                                                 break;
          case 4001: error_string="wrong function myPointer";                                 break;
          case 4002: error_string="array index is out of range";                              break;
          case 4003: error_string="no memory for function call stack";                        break;
          case 4004: error_string="recursive stack overflow";                                 break;
          case 4005: error_string="not enough stack for parameter";                           break;
          case 4006: error_string="no memory for parameter string";                           break;
          case 4007: error_string="no memory for temp string";                                break;
          case 4008: error_string="not initialized string";                                   break;
          case 4009: error_string="not initialized string in array";                          break;
          case 4010: error_string="no memory for array\' string";                             break;
          case 4011: error_string="too long string";                                          break;
          case 4012: error_string="remainder from zero divide";                               break;
          case 4013: error_string="zero divide";                                              break;
          case 4014: error_string="unknown command";                                          break;
          case 4015: error_string="wrong jump (never generated error)";                       break;
          case 4016: error_string="not initialized array";                                    break;
          case 4017: error_string="dll calls are not allowed";                                break;
          case 4018: error_string="cannot load library";                                      break;
          case 4019: error_string="cannot call function";                                     break;
          case 4020: error_string="expert function calls are not allowed";                    break;
          case 4021: error_string="not enough memory for temp string returned from function"; break;
          case 4022: error_string="system is busy (never generated error)";                   break;
          case 4050: error_string="invalid function parameters count";                        break;
          case 4051: error_string="invalid function parameter value";                         break;
          case 4052: error_string="string function internal error";                           break;
          case 4053: error_string="some array error";                                         break;
          case 4054: error_string="incorrect series array using";                             break;
          case 4055: error_string="custom indicator error";                                   break;
          case 4056: error_string="arrays are incompatible";                                  break;
          case 4057: error_string="global variables processing error";                        break;
          case 4058: error_string="global variable not found";                                break;
          case 4059: error_string="function is not allowed in testing mode";                  break;
          case 4060: error_string="function is not confirmed";                                break;
          case 4061: error_string="send mail error";                                          break;
          case 4062: error_string="string parameter expected";                                break;
          case 4063: error_string="integer parameter expected";                               break;
          case 4064: error_string="double parameter expected";                                break;
          case 4065: error_string="array as parameter expected";                              break;
          case 4066: error_string="requested history data in update state";                   break;
          case 4099: error_string="end of file";                                              break;
          case 4100: error_string="some file error";                                          break;
          case 4101: error_string="wrong file name";                                          break;
          case 4102: error_string="too many opened files";                                    break;
          case 4103: error_string="cannot open file";                                         break;
          case 4104: error_string="incompatible access to a file";                            break;
          case 4105: error_string="no order selected";                                        break;
          case 4106: error_string="unknown symbol";                                           break;
          case 4107: error_string="invalid price parameter for trade function";               break;
          case 4108: error_string="invalid ticket";                                           break;
          case 4109: error_string="trade is not allowed";                                     break;
          case 4110: error_string="longs are not allowed";                                    break;
          case 4111: error_string="shorts are not allowed";                                   break;
          case 4200: error_string="object is already exist";                                  break;
          case 4201: error_string="unknown object property";                                  break;
          case 4202: error_string="object is not exist";                                      break;
          case 4203: error_string="unknown object type";                                      break;
          case 4204: error_string="no object name";                                           break;
          case 4205: error_string="object coordinates error";                                 break;
          case 4206: error_string="no specified subwindow";                                   break;
          default:   error_string="unknown error";
         }
    //----
       return(error_string);
      }  
      
    
    
     
  2. 多謝分享~
     
  3. 日系货币也能适用,2位3位报价均可,还有是紧急情况下关闭多个仓位的,都是较方便的。

    另外,

    如果是作为手工辅助交易工具的,还需要在 ModifyDefaultStopLoss函数中

    for(int i = 0;i<total;i++)
    {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) ==false) continue;
    if(!isOrder(OrderSymbol(), OrderMagicNumber(), OrderComment(), myType)) continue;
    的下方,加入
    if(!(OrderStopLoss() == 0 || OrderTakeProfit() == 0)) continue;

    本来,这个EA不是作为辅助工具而开发的,所以考虑不太周全,如果朋友能用上,或者可以提点意见去完善一下
     
  4. 强,好帖留名
     
  5. 学习学习。
     
  6. 很强!
    7)日期及时间的设置,指定日期及时间段开平仓。本来有EA中使用的,但现在将策略部分删除了,意义不大——指定日期及时间段开、平仓,这个意义还是很大的,另外指定时间全撤单也有意义。

    另外大部分MT4的经纪公司都限制单笔委托的最大手数的,所以常常需要将计算得到的总委托手数分解成多笔委托(每笔委托手数限制在经纪公司允许的最大手数内或自定义的手数内)。
     
  7. 单笔分解的功能,估计难度也不是很大。放出来的代码只是交易辅助工具,暂没考虑开仓,如果要考虑进去,那是一个全功能的EA才行
     
  8. 对MT4还是半桶水,那些老大写的代码太周密,思想逻辑跟不上,只好看明白自己写的笨代码。看不明白只能弃用,好在自己也可以实现。
     
  9. 谢谢楼主分享,这个太有用了。我是MT4新手,请问这个是不是自己添加策略部分就可以形成一个完整的EA了?如果我要自己添加策略部分,应该把策略部分的代码插入到哪里?