EA keeps ignoring Boolean logic variables

 

Hi all,

Thanks for looking at this thread. I've been developing a simple EA which essentially increases the position size based on volatility. However, it is only meant to be increasing the position size once per trade and then once again after another trade is open. I've attached the code that I use and the part of it in question is at the end. Thanks a lot for reading through it! Any help is very gratefully accepted.

//+------------------------------------------------------------------+
//|                                      Strategy: BWinter_test1.mq5 |

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

//--- The Trade Class
#include <Trade\Trade.mqh>
//--- The PositionInfo Class
#include <Trade\PositionInfo.mqh>
//--- The AccountInfo Class
#include <Trade\AccountInfo.mqh>
//--- The SymbolInfo Class
#include <Trade\SymbolInfo.mqh>
CTrade trade;
// The OrderInfo Class object
COrderInfo myorder;
CPositionInfo position_info;

int LotDigits; //initialized in OnInit
int MagicNumber=1486996;
double TradeSize=0.1;
double volume_step=0.01;
int MaxSlippage=3; //adjusted in OnInit
int MaxSlippage_;
double MinSL=0;
double MinSL_;
int MaxOpenTrades = 1;
int MaxLongTrades = 1;
int MaxShortTrades= 1;
int MaxPendingOrders=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 MA_handle;
int      no_candles_short=10;
int      no_candles_long=50;
int stop_loss=1000;
int take_profit=1000;
double current_volume=0;
int volume_add_bool=0;
int single_trade_bool=0;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void myAlert(string type,string message)
  {
   if(type=="print")
      Print(message);
   else if(type=="error")
     {
      Print(type+" | BWinter_test1 @ "+Symbol()+","+Period()+" | "+message);
     }
   else if(type=="order")
     {
     }
   else if(type=="modify")
     {
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int TradesCount(ENUM_ORDER_TYPE type) //returns # of open trades for order type, current symbol and magic number
  {
   if(type<=1)
     {
      if(PositionSelect(Symbol()) && PositionGetInteger(POSITION_MAGIC)==MagicNumber && PositionGetInteger(POSITION_TYPE)==type)
         return(1);
      else
         return(0);
     }
   else
     {
      int result= 0;
      int total = OrdersTotal();
      for(int i = 0; i < total; i++)
        {
         if(OrderGetTicket(i)<=0) continue;
         if(OrderGetInteger(ORDER_MAGIC)!=MagicNumber || OrderGetString(ORDER_SYMBOL)!=Symbol() || OrderGetInteger(ORDER_TYPE)!=type) continue;
         result++;
        }
      return(result);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
ulong myOrderSend(ENUM_ORDER_TYPE type,double price,double volume,string ordername) //send order, return ticket ("price" is irrelevant for market orders)
  {
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || !MQLInfoInteger(MQL_TRADE_ALLOWED)) return(0);
   int retries=0;
   int long_trades=TradesCount(ORDER_TYPE_BUY);
   int short_trades = TradesCount(ORDER_TYPE_SELL);
   int long_pending = TradesCount(ORDER_TYPE_BUY_LIMIT) + TradesCount(ORDER_TYPE_BUY_STOP) + TradesCount(ORDER_TYPE_BUY_STOP_LIMIT);
   int short_pending = TradesCount(ORDER_TYPE_SELL_LIMIT) + TradesCount(ORDER_TYPE_SELL_STOP) + TradesCount(ORDER_TYPE_SELL_STOP_LIMIT);
   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(0);
     }
//test maximum trades
   if((type%2==0 && long_trades>=MaxLongTrades)
      || (type%2==1 && short_trades>=MaxShortTrades)
      || (long_trades+short_trades>=MaxOpenTrades)
      || (type>1 && long_pending+short_pending>=MaxPendingOrders))
     {
      myAlert("print","Order"+ordername_+" not sent, maximum reached");
      return(0);
     }
//prepare to send order
   MqlTradeRequest request;
   ZeroMemory(request);
   request.action=(type<=1) ? TRADE_ACTION_DEAL : TRADE_ACTION_PENDING;

//set allowed filling type
   int filling=(int)SymbolInfoInteger(Symbol(),SYMBOL_FILLING_MODE);
   if(request.action==TRADE_ACTION_DEAL && (filling  &1)!=1)
      request.type_filling=ORDER_FILLING_IOC;

   request.magic=MagicNumber;
   request.symbol = Symbol();
   request.volume = NormalizeDouble(volume, LotDigits);
   request.sl = 0;
   request.tp = 0;
   request.deviation=MaxSlippage_;
   request.type=type;
   request.comment=ordername;

   int expiration=(int)SymbolInfoInteger(Symbol(),SYMBOL_EXPIRATION_MODE);
   if((expiration  &SYMBOL_EXPIRATION_GTC)!=SYMBOL_EXPIRATION_GTC)
     {
      request.type_time=ORDER_TIME_DAY;
      request.type_filling=ORDER_FILLING_RETURN;
     }

   MqlTradeResult result;
   ZeroMemory(result);
   while(!OrderSuccess(result.retcode) && retries<OrderRetry+1)
     {
      //refresh price before sending order
      MqlTick last_tick;
      SymbolInfoTick(Symbol(),last_tick);
      if(type==ORDER_TYPE_BUY)
         price=last_tick.ask;
      else if(type==ORDER_TYPE_SELL)
         price=last_tick.bid;
      else if(price<0) //invalid price for pending order
        {
         myAlert("order","Order"+ordername_+" not sent, invalid price for pending order");
         return(0);
        }
      request.price=NormalizeDouble(price,Digits());
      OrderSend(request,result);
      if(!OrderSuccess(result.retcode))
        {
         myAlert("print","OrderSend"+ordername_+" error: "+result.comment);
         Sleep(OrderWait*1000);
        }
      retries++;
     }
   if(!OrderSuccess(result.retcode))
     {
      myAlert("error","OrderSend"+ordername_+" failed "+(OrderRetry+1)+" times; error: "+result.comment);
      return(0);
     }
   string typestr[8]={"Buy","Sell","Buy Limit","Sell Limit","Buy Stop","Sell Stop","Buy Stop Limit","Sell Stop Limit"};
   myAlert("order","Order sent"+ordername_+": "+typestr[type]+" "+Symbol()+" Magic #"+MagicNumber);
   return(result.order);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int myOrderModifyRel(ENUM_ORDER_TYPE type,ulong ticket,double SL,double TP) //works for positions and orders, modify SL and TP (relative to open price), zero targets do not modify, ticket is irrelevant for open positions
  {
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || !MQLInfoInteger(MQL_TRADE_ALLOWED)) return(-1);
   int retries=0;
   int err;
   SL = NormalizeDouble(SL, Digits());
   TP = NormalizeDouble(TP, Digits());
   if(SL < 0) SL = 0;
   if(TP < 0) TP = 0;
//prepare to select order
   if((type<=1 && !PositionSelect(Symbol())) || (type>1 && !OrderSelect(ticket)))
     {
      err=GetLastError();
      myAlert("error","PositionSelect / OrderSelect failed; error #"+err);
      return(-1);
     }
//ignore open positions other than "type"
   if(type <= 1 && PositionGetInteger(POSITION_TYPE) != type) return(0);
//prepare to modify order, convert relative to absolute
   double openprice=(type<=1) ? PositionGetDouble(POSITION_PRICE_OPEN) : OrderGetDouble(ORDER_PRICE_OPEN);
   if(((type<=1) ? PositionGetInteger(POSITION_TYPE) : OrderGetInteger(ORDER_TYPE))%2==0) //buy
     {
      if(NormalizeDouble(SL,Digits())!=0)
         SL=openprice-SL;
      if(NormalizeDouble(TP,Digits())!=0)
         TP=openprice+TP;
     }
   else //sell
     {
      if(NormalizeDouble(SL,Digits())!=0)
         SL=openprice+SL;
      if(NormalizeDouble(TP,Digits())!=0)
         TP=openprice-TP;
     }
   double currentSL = (type <= 1) ? PositionGetDouble(POSITION_SL) : OrderGetDouble(ORDER_SL);
   double currentTP = (type <= 1) ? PositionGetDouble(POSITION_TP) : OrderGetDouble(ORDER_TP);
   if(NormalizeDouble(SL, Digits()) == 0) SL = currentSL; //not to modify
   if(NormalizeDouble(TP, Digits()) == 0) TP = currentTP; //not to modify
   if(NormalizeDouble(SL-currentSL,Digits())==0
      && NormalizeDouble(TP-currentTP,Digits())==0)
      return(0); //nothing to do
   MqlTradeRequest request;
   ZeroMemory(request);
   request.action=(type<=1) ? TRADE_ACTION_SLTP : TRADE_ACTION_MODIFY;
   if(type>1)
      request.order=ticket;
   else
      request.position=PositionGetInteger(POSITION_TICKET);
   request.symbol= Symbol();
   request.price =(type<= 1) ? PositionGetDouble(POSITION_PRICE_OPEN) : OrderGetDouble(ORDER_PRICE_OPEN);
   request.sl = NormalizeDouble(SL, Digits());
   request.tp = NormalizeDouble(TP, Digits());
   request.deviation=MaxSlippage_;
   MqlTradeResult result;
   ZeroMemory(result);
   while(!OrderSuccess(result.retcode) && retries<OrderRetry+1)
     {
      OrderSend(request,result);
      if(!OrderSuccess(result.retcode))
        {
         err=GetLastError();
         myAlert("print","OrderModify error #"+err);
         Sleep(OrderWait*1000);
        }
      retries++;
     }
   if(!OrderSuccess(result.retcode))
     {
      myAlert("error","OrderModify failed "+(OrderRetry+1)+" times; error #"+err);
      return(-1);
     }
   string alertstr="Order modify: ticket="+ticket;
   if(NormalizeDouble(SL, Digits()) != 0) alertstr = alertstr+" SL="+SL;
   if(NormalizeDouble(TP, Digits()) != 0) alertstr = alertstr+" TP="+TP;
   myAlert("modify",alertstr);
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void myOrderClose(ENUM_ORDER_TYPE type,int volumepercent,string ordername) //close open orders for current symbol, magic number and "type" (ORDER_TYPE_BUY or ORDER_TYPE_SELL)
  {
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || !MQLInfoInteger(MQL_TRADE_ALLOWED)) return;
   if(type>1)
     {
      myAlert("error","Invalid type in myOrderClose");
      return;
     }
   bool success=false;
   string ordername_=ordername;
   if(ordername != "")
      ordername_ = "("+ordername+")";
   if(!PositionSelect(Symbol())) return;
   if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber || PositionGetInteger(POSITION_TYPE)!=type)
      return;
   MqlTick last_tick;
   SymbolInfoTick(Symbol(),last_tick);
   double price=(type==ORDER_TYPE_SELL) ? last_tick.ask : last_tick.bid;
   MqlTradeRequest request;
   ZeroMemory(request);
   request.action=TRADE_ACTION_DEAL;
   request.position=PositionGetInteger(POSITION_TICKET);

//set allowed filling type
   int filling=(int)SymbolInfoInteger(Symbol(),SYMBOL_FILLING_MODE);
   if(request.action==TRADE_ACTION_DEAL && (filling  &1)!=1)
      request.type_filling=ORDER_FILLING_IOC;

   request.magic=MagicNumber;
   request.symbol = Symbol();
   request.volume = NormalizeDouble(PositionGetDouble(POSITION_VOLUME)*volumepercent * 1.0 / 100, LotDigits);
   if(NormalizeDouble(request.volume, LotDigits) == 0) return;
   request.price=NormalizeDouble(price,Digits());
   request.sl = 0;
   request.tp = 0;
   request.deviation=MaxSlippage_;
   request.type=1-type; //opposite type
   request.comment=ordername;
   MqlTradeResult result;
   ZeroMemory(result);
   OrderSend(request,result);
   success=OrderSuccess(result.retcode);
   if(!success)
     {
      myAlert("error","OrderClose"+ordername_+" failed; error: "+result.comment);
     }
   string typestr[8]={"Buy","Sell","Buy Limit","Sell Limit","Buy Stop","Sell Stop","Buy Stop Limit","Sell Stop Limit"};
   if(success) myAlert("order","Orders closed"+ordername_+": "+typestr[type]+" "+Symbol()+" Magic #"+MagicNumber);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool OrderSuccess(uint retcode)
  {
   return(retcode == TRADE_RETCODE_PLACED || retcode == TRADE_RETCODE_DONE
          || retcode==TRADE_RETCODE_DONE_PARTIAL || retcode==TRADE_RETCODE_NO_CHANGES);
  }
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   MaxSlippage_=MaxSlippage;
//initialize myPoint
   myPoint=Point();
   if(Digits()==5 || Digits()==3)
     {
      myPoint*=10;
      MaxSlippage_*=10;
     }
//initialize LotDigits
   double LotStep=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);
   if(LotStep>=1) LotDigits=0;
   else if(LotStep >= 0.1) LotDigits = 1;
   else if(LotStep >= 0.01) LotDigits = 2;
   else LotDigits=3;
   MinSL_=MinSL*myPoint;

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   trade.SetExpertMagicNumber(MagicNumber);
//Gathering the Ask price
   MqlTradeRequest newOrder;
   MqlTradeResult result;
   double Ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); //Obtaining the current price for buy trades
   double Bid=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);


//Creates a struct where the information about the candles (e.g. price) will be stored.
   MqlRates PriceInfo[];
//Sorts it from the current candle to the oldest candle
   ArraySetAsSeries(PriceInfo,true);
//Copies the price information into the array
   double Data=CopyRates(Symbol(),PERIOD_CURRENT,0,Bars(Symbol(),PERIOD_CURRENT),PriceInfo);

//Creating 'buy' arrays
   double high_price[]; //Store the high price
   double low_price[]; //Store the low price
   double close_price[]; //Store the close price
   double tp[]; //Store the typical price
   double tr[]; //Store true range values
   ArrayResize(high_price,no_candles_long+1);
   ArrayResize(low_price,no_candles_long+1);
   ArrayResize(close_price,no_candles_long+1);
   ArrayResize(tp,no_candles_long+1);
   ArrayResize(tr,no_candles_long);

   for(int i=0; i<=no_candles_long; i=i+1)
     {
      high_price[i]=PriceInfo[i+1].high;
      low_price[i]=PriceInfo[i+1].low;
      close_price[i]=PriceInfo[i+1].close;
      //Calculating the typical price
      tp[i]=(high_price[i]+low_price[i]+close_price[i])/3;
     }
   double sum_tp_short=0,MA_short_val,sum_tp_long=0,MA_long_val;
   for(int i=0;i<no_candles_short;i++)
     {
      sum_tp_short=sum_tp_short+tp[i];
     }

   MA_short_val=sum_tp_short/no_candles_short;

   for(int i=0;i<no_candles_long;i++)
     {
      sum_tp_long=sum_tp_long+tp[i];
     }
   MA_long_val=sum_tp_long/no_candles_long;

   double avg_tr=0,high_minus_low=0,high_minus_close=0,low_minus_close=0;
   for(int i=no_candles_long-1;i>=0;i=i-1)
     {
      high_minus_low=high_price[i]-low_price[i];
      high_minus_close= MathAbs(high_price[i]-close_price[i+1]);
      low_minus_close = MathAbs(low_price[i]-close_price[i+1]);

      tr[i]=MathMax(MathMax(high_minus_low,high_minus_close),low_minus_close);
     }

   double tr_sum=0,norm_avg_tr=0;
   for(int i=0;i<no_candles_long;i=i+1)
     {
      tr_sum=tr_sum+tr[i];
     }
   avg_tr=tr_sum/no_candles_long;

   ulong ticket=0;
   double price;
   double SL;
   double TP;

//Close Long Positions
   if(MA_long_val>MA_short_val && single_trade_bool==1 //Moving Average > Moving Average
      )
     {
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && MQLInfoInteger(MQL_TRADE_ALLOWED))
        {
         myOrderClose(ORDER_TYPE_BUY,100,"");
         single_trade_bool=0;
         volume_add_bool=0;
        }
     }

//Close Short Positions

   if(MA_long_val<MA_short_val && single_trade_bool==1 //Moving Average < Moving Average
      )
     {
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && MQLInfoInteger(MQL_TRADE_ALLOWED))
        {
         myOrderClose(ORDER_TYPE_SELL,100,"");
         single_trade_bool=0;
         volume_add_bool=0;
        }
     }

   int total=PositionsTotal();

//Open Buy Order
   if(MA_long_val<MA_short_val && single_trade_bool==0 //Moving Average > Moving Average
      )
     {
      SL=stop_loss*myPoint; //Stop Loss = value in points (relative to price)
      if(SL<MinSL_) SL=MinSL_;
      TP=take_profit*myPoint; //Take Profit = value in points (relative to price)   

      if(single_trade_bool==0)
        {
         int count=0;
         for(int i=total-1;i>=0;i--)
           {
            if(PositionGetTicket(i))
              {
               if(PositionGetInteger(POSITION_MAGIC)==MagicNumber)
                 {
                  count=count+1;
                 }
              }
           }
         if(count==0) trade.Buy(TradeSize,NULL,Ask,Ask-SL,Ask+TP,NULL);
         single_trade_bool=1;
         Print("Buy trade made");
        }

     }

//Open Sell Order

   if(MA_long_val>MA_short_val && single_trade_bool==0 //Moving Average < Moving Average
      )
     {
      SL=stop_loss*myPoint; //Stop Loss = value in points (relative to price)
      if(SL<MinSL_) SL=MinSL_;
      TP=take_profit*myPoint; //Take Profit = value in points (relative to price)   
      if(single_trade_bool==0)
        {
         int count=0;
         for(int i=total-1;i>=0;i--)
           {
            if(PositionGetTicket(i))
              {
               if(PositionGetInteger(POSITION_MAGIC)==MagicNumber)
                 {
                  count=count+1;
                 }
              }
           }
         if(count==0) trade.Sell(TradeSize,NULL,Bid,Bid+SL,Bid-TP,NULL);
         single_trade_bool=1;
         Print("Sell trade made");
        }

     }

   double position_profit=0;
   for(int i=total-1;i>=0;i--)
     {
      if(PositionGetTicket(i))
        {
         if(PositionGetInteger(POSITION_MAGIC)==MagicNumber)
           {

            current_volume=PositionGetDouble(POSITION_VOLUME);
            position_profit=position_info.Profit();

           }
        }
     }

   if(volume_add_bool==0)
     {
      if(avg_tr<=1)
        {
         for(int i=total-1;i>=0;i--)
           {
            if(PositionGetTicket(i))
              {
               if(PositionGetInteger(POSITION_MAGIC)==MagicNumber)
                 {

                  if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
                    {
                     trade.Buy(volume_step,NULL,Ask,Ask-stop_loss*myPoint,Ask+take_profit*myPoint,NULL);
                     volume_add_bool=1;
                     Print("Added volume to a buy position");
                    }

                  if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
                    {
                     trade.Sell(volume_step,NULL,Bid,Bid+stop_loss*myPoint,Bid-take_profit*myPoint,NULL);
                     volume_add_bool=1;
                     Print("Added volume to a sell position");
                    }
                 }
              }

           }
        }
     }
   Comment(StringFormat("MA short  = %G\nMA long = %G\nATR = %G\nPosition volume = %G\nPostion Profit = %G\nSingle trade bool = %G\nVolume add bool = %G\n",MA_short_val,MA_long_val,avg_tr,current_volume,position_profit,single_trade_bool,volume_add_bool));

  }
//+------------------------------------------------------------------+
Reason: