Help With EA code Please :(

 

Hello Everyone.

First all a big Thank You to everyone who is going to have a look at my code!


This is what I tried to make the code "do":

1. Open 1 Trade when "Buycrossover","BuyTrend","SellCrossover" or "Selltrend" has been confirmd. I tried doing this by using bools.

2. Once one of these has been confirmed I want the EA to Open 1 Trade each time the candle closes in the oposite direction so: If it is a buy confirmation everytime the candle goes down it should open a buy order.

3. This cycle continues until all the order get closed by the close condition which I also tried to solve by a confirmation by the CCI indicator which has to enter an overbought or oversold value twice once when the first order was placed and the second time when all orders get closed.


This is what the EA is currently doing (See Screenshot=):

I tried debugging what it was doing and this is what I figured out so far.

I haven't made much progress with my debugging which is why im reaching out to some experts on here ;)

1. So it seems to recognize at least the BuyTrend and Selltrend condition correctly. Something is wrong with the crossoverconditions since it just seems like the EA opens orders indefinitely even though the signal is not even true according to the indicators.

2. Even though it recognizes buyTrend as a signal it just opens oders indefinetly and dosen't stop after the signal was made like I tried to make it go. I am still a beginner with my code so bar with me I learn as I go. 


All advice and help is greatly appreciated <3

Screenshot of backtesting the EA for the 30.nov
#include <stdlib.mqh>
#include <stderror.mqh>

int LotDigits; //initialized in OnInit
int MagicNumber = 1447868;
extern int TOD_From_Hour = 09; //time of the day (from hour)
extern int TOD_From_Min = 00; //time of the day (from min)
extern int TOD_To_Hour = 14; //time of the day (to hour)
extern int TOD_To_Min = 00; //time of the day (to min)
extern double TradeSize = 0.1;
int MaxSlippage = 3; //adjusted in OnInit
bool crossed[2]; //initialized to true, used in function Cross
int MaxOpenTrades = 1000;
int MaxLongTrades = 1000;
int MaxShortTrades = 1000;
int MaxPendingOrders = 1000;
int MaxLongPendingOrders = 1000;
int MaxShortPendingOrders = 1000;
bool Hedging = true;
int OrderRetry = 5; //# of retries if sending order returns error
int OrderWait = 5; //# of seconds to wait if sending order returns error
double myPoint; //initialized in OnInit

int Sellcount = 0;
int Buycount = 0;
bool BuyCrossover = false;
bool SellCrossover = false;
bool BuyTrend = false;
bool SellTrend = false;
bool Buy = false;
bool Sell = false;


bool inTimeInterval(datetime t, int From_Hour, int From_Min, int To_Hour, int To_Min)
  {
   string TOD = TimeToString(t, TIME_MINUTES);
   string TOD_From = StringFormat("%02d", From_Hour)+":"+StringFormat("%02d", From_Min);
   string TOD_To = StringFormat("%02d", To_Hour)+":"+StringFormat("%02d", To_Min);
   return((StringCompare(TOD, TOD_From) >= 0 && StringCompare(TOD, TOD_To) <= 0)
     || (StringCompare(TOD_From, TOD_To) > 0
       && ((StringCompare(TOD, TOD_From) >= 0 && StringCompare(TOD, "23:59") <= 0)
         || (StringCompare(TOD, "00:00") >= 0 && StringCompare(TOD, TOD_To) <= 0))));
  }

bool Cross(int i, bool condition) //returns true if "condition" is true and was false in the previous call
  {
   bool ret = condition && !crossed[i];
   crossed[i] = condition;
   return(ret);
  }

void myAlert(string type, string message)
  {
   if(type == "print")
      Print(message);
   else if(type == "error")
     {
      Print(type+" | Morning EA @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }
   else if(type == "order")
     {
     }
   else if(type == "modify")
     {
     }
  }

int TradesCount(int type) //returns # of open trades for order type, current symbol and magic number
  {
   int result = 0;
   int total = OrdersTotal();
   for(int i = 0; i < total; i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) continue;
      if(OrderMagicNumber() != MagicNumber || OrderSymbol() != Symbol() || OrderType() != type) continue;
      result++;
     }
   return(result);
  }

int myOrderSend(int type, double price, double volume, string ordername) //send order, return ticket ("price" is irrelevant for market orders)
  {
   if(!IsTradeAllowed()) return(-1);
   int ticket = -1;
   int retries = 0;
   int err = 0;
   int long_trades = TradesCount(OP_BUY);
   int short_trades = TradesCount(OP_SELL);
   int long_pending = TradesCount(OP_BUYLIMIT) + TradesCount(OP_BUYSTOP);
   int short_pending = TradesCount(OP_SELLLIMIT) + TradesCount(OP_SELLSTOP);
   string ordername_ = ordername;
   if(ordername != "")
      ordername_ = "("+ordername+")";
   //test Hedging
   if(!Hedging && ((type % 2 == 0 && short_trades + short_pending > 0) || (type % 2 == 1 && long_trades + long_pending > 0)))
     {
      myAlert("print", "Order"+ordername_+" not sent, hedging not allowed");
      return(-1);
     }
   //test maximum trades
   if((type % 2 == 0 && long_trades >= MaxLongTrades)
   || (type % 2 == 1 && short_trades >= MaxShortTrades)
   || (long_trades + short_trades >= MaxOpenTrades)
   || (type > 1 && type % 2 == 0 && long_pending >= MaxLongPendingOrders)
   || (type > 1 && type % 2 == 1 && short_pending >= MaxShortPendingOrders)
   || (type > 1 && long_pending + short_pending >= MaxPendingOrders)
   )
     {
      myAlert("print", "Order"+ordername_+" not sent, maximum reached");
      return(-1);
     }
   //prepare to send order
   while(IsTradeContextBusy()) Sleep(100);
   RefreshRates();
   if(type == OP_BUY)
      price = Ask;
   else if(type == OP_SELL)
      price = Bid;
   else if(price < 0) //invalid price for pending order
     {
      myAlert("order", "Order"+ordername_+" not sent, invalid price for pending order");
          return(-1);
     }
   int clr = (type % 2 == 1) ? clrRed : clrBlue;
   while(ticket < 0 && retries < OrderRetry+1)
     {
      ticket = OrderSend(Symbol(), type, NormalizeDouble(volume, LotDigits), NormalizeDouble(price, Digits()), MaxSlippage, 0, 0, ordername, MagicNumber, 0, clr);
      if(ticket < 0)
        {
         err = GetLastError();
         myAlert("print", "OrderSend"+ordername_+" error #"+IntegerToString(err)+" "+ErrorDescription(err));
         Sleep(OrderWait*1000);
        }
      retries++;
     }
   if(ticket < 0)
     {
      myAlert("error", "OrderSend"+ordername_+" failed "+IntegerToString(OrderRetry+1)+" times; error #"+IntegerToString(err)+" "+ErrorDescription(err));
      return(-1);
     }
   string typestr[6] = {"Buy", "Sell", "Buy Limit", "Sell Limit", "Buy Stop", "Sell Stop"};
   myAlert("order", "Order sent"+ordername_+": "+typestr[type]+" "+Symbol()+" Magic #"+IntegerToString(MagicNumber));
   return(ticket);
  }

void myOrderClose(int type, double volumepercent, string ordername) //close open orders for current symbol, magic number and "type" (OP_BUY or OP_SELL)
  {
   if(!IsTradeAllowed()) return;
   if (type > 1)
     {
      myAlert("error", "Invalid type in myOrderClose");
      return;
     }
   bool success = false;
   int err = 0;
   string ordername_ = ordername;
   if(ordername != "")
      ordername_ = "("+ordername+")";
   int total = OrdersTotal();
   int orderList[][2];
   int orderCount = 0;
   int i;
   for(i = 0; i < total; i++)
     {
      while(IsTradeContextBusy()) Sleep(100);
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderMagicNumber() != MagicNumber || OrderSymbol() != Symbol() || OrderType() != type) continue;
      orderCount++;
      ArrayResize(orderList, orderCount);
      orderList[orderCount - 1][0] = (int)OrderOpenTime();
      orderList[orderCount - 1][1] = OrderTicket();
     }
   if(orderCount > 0)
      ArraySort(orderList, WHOLE_ARRAY, 0, MODE_ASCEND);
   for(i = 0; i < orderCount; i++)
     {
      if(!OrderSelect(orderList[i][1], SELECT_BY_TICKET, MODE_TRADES)) continue;
      while(IsTradeContextBusy()) Sleep(100);
      RefreshRates();
      double price = (type == OP_SELL) ? Ask : Bid;
      double volume = NormalizeDouble(OrderLots()*volumepercent * 1.0 / 100, LotDigits);
      if (NormalizeDouble(volume, LotDigits) == 0) continue;
      success = OrderClose(OrderTicket(), volume, NormalizeDouble(price, Digits()), MaxSlippage, clrWhite);
      if(!success)
        {
         err = GetLastError();
         myAlert("error", "OrderClose"+ordername_+" failed; error #"+IntegerToString(err)+" "+ErrorDescription(err));
        }
     }
   string typestr[6] = {"Buy", "Sell", "Buy Limit", "Sell Limit", "Buy Stop", "Sell Stop"};
   if(success) myAlert("order", "Orders closed"+ordername_+": "+typestr[type]+" "+Symbol()+" Magic #"+IntegerToString(MagicNumber));
  }

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {   
   //initialize myPoint
   myPoint = Point();
   if(Digits() == 5 || Digits() == 3)
     {
      myPoint *= 10;
      MaxSlippage *= 10;
     }
   //initialize LotDigits
   double LotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
   if(NormalizeDouble(LotStep, 3) == round(LotStep))
      LotDigits = 0;
   else if(NormalizeDouble(10*LotStep, 3) == round(10*LotStep))
      LotDigits = 1;
   else if(NormalizeDouble(100*LotStep, 3) == round(100*LotStep))
      LotDigits = 2;
   else LotDigits = 3;
   int i;
   //initialize crossed
   for (i = 0; i < ArraySize(crossed); i++)
      crossed[i] = true;
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   int ticket = -1;
   double price;   
   
   
   //Close Long Positions^
   
   if(inTimeInterval(TimeCurrent(), TOD_From_Hour, TOD_From_Min, TOD_To_Hour, TOD_To_Min) && iCCI(NULL, PERIOD_CURRENT, 25, PRICE_TYPICAL, 1) > 90)

   {
   Buycount = Buycount + 1;
   }
   
   if(Buycount == 2 && (iCCI(NULL, PERIOD_CURRENT, 25, PRICE_TYPICAL, 2)>iCCI(NULL, PERIOD_CURRENT, 25, PRICE_TYPICAL, 1)) 
   && (iCCI(NULL, PERIOD_CURRENT, 25, PRICE_TYPICAL, 3)<iCCI(NULL, PERIOD_CURRENT, 25, PRICE_TYPICAL, 2)) && inTimeInterval(TimeCurrent(), TOD_From_Hour, TOD_From_Min, TOD_To_Hour, TOD_To_Min)
   )
     {   
      if(IsTradeAllowed())
         myOrderClose(OP_BUY, 100, "");
         Buycount = 0;
         BuyCrossover = false;
         BuyTrend = false;
         Buy = false;
     }

//Short postition conditions
if(inTimeInterval(TimeCurrent(), TOD_From_Hour, TOD_From_Min, TOD_To_Hour, TOD_To_Min) && iCCI(NULL, PERIOD_CURRENT, 25, PRICE_TYPICAL, 1) < -90)

   {
   Sellcount = Sellcount + 1;
   }
  
   
   if(Sellcount == 2 && (iCCI(NULL, PERIOD_CURRENT, 25, PRICE_TYPICAL, 2)<iCCI(NULL, PERIOD_CURRENT, 25, PRICE_TYPICAL, 1)) 
   && (iCCI(NULL, PERIOD_CURRENT, 25, PRICE_TYPICAL, 3)>iCCI(NULL, PERIOD_CURRENT, 25, PRICE_TYPICAL, 2)) && inTimeInterval(TimeCurrent(), TOD_From_Hour, TOD_From_Min, 22, TOD_To_Min)
   )
     {   
      if(IsTradeAllowed())
         myOrderClose(OP_SELL, 100, "");
         Sellcount = 0;
         SellCrossover = false;
         SellTrend = false;
         Sell = false;
     }
   
   //Singal Identification;
   
    if(Cross(1, iMA(NULL, PERIOD_CURRENT, 10, 0, MODE_EMA, PRICE_CLOSE, 1) > iMA(NULL, PERIOD_CURRENT, 25, 0, MODE_SMMA, PRICE_CLOSE, 2))
    && inTimeInterval(TimeCurrent(), TOD_From_Hour, TOD_From_Min, 11, 20) && Sell == false
    )
    
    {
    BuyCrossover = false;
    }
    
    if(Cross(1, iMA(NULL, PERIOD_CURRENT, 10, 0, MODE_EMA, PRICE_CLOSE, 1) < iMA(NULL, PERIOD_CURRENT, 25, 0, MODE_SMMA, PRICE_CLOSE, 2))
    && inTimeInterval(TimeCurrent(), TOD_From_Hour, TOD_From_Min, 11, 20) && Buy == false
    )
    
    {
    SellCrossover = false;
    }
    
    if((iMA(NULL, PERIOD_CURRENT, 10, 0, MODE_EMA, PRICE_CLOSE, 1)-iMA(NULL, PERIOD_CURRENT, 25, 0, MODE_SMMA, PRICE_CLOSE, 2)) >= 0.00070
    && iCCI(NULL, PERIOD_CURRENT, 25, PRICE_TYPICAL, 1)>90 && inTimeInterval(TimeCurrent(), TOD_From_Hour, TOD_From_Min, TOD_To_Hour, TOD_To_Min) && Buy == False
    )
   {
   BuyTrend = true;
   }
   
   if((iMA(NULL, PERIOD_CURRENT, 25, 0, MODE_SMMA, PRICE_CLOSE, 2)-iMA(NULL, PERIOD_CURRENT, 10, 0, MODE_EMA, PRICE_CLOSE, 1)) >= 0.00070
    && iCCI(NULL, PERIOD_CURRENT, 25, PRICE_TYPICAL, 1)<-90 && inTimeInterval(TimeCurrent(), TOD_From_Hour, TOD_From_Min, TOD_To_Hour, TOD_To_Min) && Sell == False
    )
   {
   SellTrend = True;
   }
   
   
   //Open Buy Order, instant signal is tested first
   if(BuyCrossover == True || BuyTrend == True
   )
     {
      RefreshRates();
      price = Ask;
      if(!inTimeInterval(TimeCurrent(), TOD_From_Hour, TOD_From_Min, TOD_To_Hour, TOD_To_Min)) return; //open trades only at specific times of the day   
      if(IsTradeAllowed())
        {
         ticket = myOrderSend(OP_BUY, price, TradeSize, "");
         BuyCrossover = false;
         BuyTrend = false;
         Buy = True;
         if(ticket <= 0) return;
        }
      else //not autotrading => only send alert
         myAlert("order", "");
     }
     
   if(Buy == True && Open[1]>Close[1]
   )
     {
      RefreshRates();
      price = Ask;
      if(!inTimeInterval(TimeCurrent(), TOD_From_Hour, TOD_From_Min, TOD_To_Hour, TOD_To_Min)) return; //open trades only at specific times of the day   
      if(IsTradeAllowed())
        {
         ticket = myOrderSend(OP_BUY, price, TradeSize, "");
         if(ticket <= 0) return;
        }
      else //not autotrading => only send alert
         myAlert("order", "");
     }
   
   //Open Sell Order, instant signal is tested first
   if(SellCrossover == True || SellTrend == true
   )
     {
      RefreshRates();
      price = Bid;
      if(!inTimeInterval(TimeCurrent(), TOD_From_Hour, TOD_From_Min, TOD_To_Hour, TOD_To_Min)) return; //open trades only at specific times of the day   
      if(IsTradeAllowed())
        {
         ticket = myOrderSend(OP_SELL, price, TradeSize, "");
         SellCrossover = False;
         SellTrend = False;
         Sell = True;
         if(ticket <= 0) return;
        }
      else //not autotrading => only send alert
         myAlert("order", "");
     }
     
    if(Sell == True && Open[1]<Close[1]
   )
     {
      RefreshRates();
      price = Ask;
      if(!inTimeInterval(TimeCurrent(), TOD_From_Hour, TOD_From_Min, TOD_To_Hour, TOD_To_Min)) return; //open trades only at specific times of the day   
      if(IsTradeAllowed())
        {
         ticket = myOrderSend(OP_BUY, price, TradeSize, "");
         if(ticket <= 0) return;
        }
      else //not autotrading => only send alert
         myAlert("order", "");
     }
     
  }
//+------------------------------------------------------------------+
 
  1. Wir können her Deutsch sprechen :)
  2. Durch den ganzen Code eines anderen zu gehen und zu verstehen ist sehr aufwendig.
  3. Wenn Du schon versucht hast, mit dem Debugger zu arbeiten, dann versuch doch als nächstes von Deinen vier Handelssituationen erst einmal nur eine laufen zu lassen und das erst mit dem Debugger dabei lässt Du die jede wichtige Änderung mit Comment(..) anzeigen.
  4. Hier noch eine Hilfe um einfach Name und Wert einer Variablen als Zeichenkette auszugeben:
// not tested:
#define _2StrD(a,d) #a+":"+DoubleToString(a,d)+"  " 
#define _2Str(a) #a+":"+DoubleToString(a,_Digits)+"  " 
// use: Comment(_2StrD(profit,2), _2StrD(close[i]), ..)

Grund der Beschwerde: