Globally declared variable keeps reverts to the value of zero on a multiple symbol EA

 

Hi 

I'm quite a newbie when it comes to programming EA's and programming in general.

I have a situation where I have been coding an EA for multiple symbols, and my global variable keep on changing to zero after I have assigned the value of 1 to it. 

The globally declared variable that keeps resetting to the value of zero is 'LosingOrWinningTrend. The problem only appears when I have multiple symbols in my code.

I've added a simplified version of my code down under. The structure is pretty much the same for the full version of my code though.

Hope someone can help find out what the problem is.


SymbolCOPPERUS = COPPERUS.pro

int LosingOrWinningTrend;

int handleDc5COPPERUS;
int handleDc10COPPERUS;

//Define Breakouts
int FiveDayLongBreakoutCOPPERUS;
int TenDayLongBreakoutCOPPERUS;

double currentSlCOPPERUS;


int OnInit(){

        //Create handle for Donchian Channel for 5 days
        handleDc5COPPERUS = iCustom(SymbolCOPPERUS,PERIOD_D1,"DonchianChannel.ex5",5);

        //Create handle for Donchian Channel for 10 days
        handleDc10COPPERUS = iCustom(SymbolCOPPERUS,PERIOD_D1,"DonchianChannel.ex5",10);
        

void OnTick(){

   // Create integer variable for total long and short positions
   int totalPositionsLongCOPPERUS = 0;

   //Create double variable for highest opening price for long positions.
   double highestAskCOPPERUS = 0.0;
   
        // Use for loop to find total amount of long and short positions. 
        // The highest long positions are found.
        for(int i=PositionsTotal() - 1; i >= 0; i--){
                if(PositionGetSymbol(i) == SymbolCOPPERUS){
                        if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){
                                totalPositionsLongCOPPERUS++;
                                double posAskPriceCOPPERUS = PositionGetDouble(POSITION_PRICE_OPEN);
                                if(posAskPriceCOPPERUS >= highestAskCOPPERUS){
                                        highestAskCOPPERUS = posAskPriceCOPPERUS;
                                }
                        }
                }
        }

       // Define lows
       double TwoDayLowCOPPERUS = 0.0;
       double FiveDayLowCOPPERUS = 0.0;
        
        if(totalPositionsLongCOPPERUS > 0 && FiveDayLongBreakoutCOPPERUS == 1){
                // Calculate the Two-day low only for open long positions
                int TwoDayLowestIndexCOPPERUS = iLowest(SymbolCOPPERUS,PERIOD_D1,MODE_LOW,2,1);
                TwoDayLowCOPPERUS = NormalizeDouble((iLow(SymbolCOPPERUS,PERIOD_D1,TwoDayLowestIndexCOPPERUS)),_Digits);

        if(totalPositionsLongCOPPERUS > 0 && TenDayLongBreakoutCOPPERUS == 1){
                // Calculate the Two-day low only for open long positions
                int FiveDayLowestIndexCOPPERUS = iLowest(SymbolCOPPERUS,PERIOD_D1,MODE_LOW,5,1);
                FiveDayLowCOPPERUS = NormalizeDouble((iLow(SymbolCOPPERUS,PERIOD_D1,FiveDayLowestIndexCOPPERUS)),_Digits);


        // Use for loop to modify SL for open position when a new position is opened.
        // If 2-day/5-day low is higher than the Current Position Unit SL for long positions a new SL is set. 
        for(int i=PositionsTotal() - 1; i >= 0; i--){
                if(PositionGetSymbol(i) == SymbolCOPPERUS){
                        ulong PositionTicketCOPPERUS = PositionGetInteger(POSITION_TICKET);
                        if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){
                                if(FiveDayLongBreakoutCOPPERUS == 1){
                                        if(PositionGetDouble(POSITION_SL) < currentSlCOPPERUS && currentSlCOPPERUS > TwoDayLowCOPPERUS){
                                                trade.PositionModify(PositionTicketCOPPERUS,currentSlCOPPERUS,0);
                                                losingOrWinningTrendCOPPERUS = 0;
                                        }else if(PositionGetDouble(POSITION_SL) < TwoDayLowCOPPERUS && currentSlCOPPERUS < TwoDayLowCOPPERUS){
                                                trade.PositionModify(PositionTicketCOPPERUS,TwoDayLowCOPPERUS,0);
                                                losingOrWinningTrendCOPPERUS = 1;
                  
                                        }      
                                }else if(TenDayLongBreakoutCOPPERUS == 1){
                                        if(PositionGetDouble(POSITION_SL) < currentSlCOPPERUS && currentSlCOPPERUS > FiveDayLowCOPPERUS){
                                                trade.PositionModify(PositionTicketCOPPERUS,currentSlCOPPERUS,0);
                                                losingOrWinningTrendCOPPERUS = 0;
                                        }else if(PositionGetDouble(POSITION_SL) < TenDayLowCOPPERUS && currentSlCOPPERUS < TenDayLowCOPPERUS){
                                                trade.PositionModify(PositionTicketCOPPERUS,TenDayLowCOPPERUS,0);
                                                losingOrWinningTrendCOPPERUS = 1;
                                        }   
                                }  
                        }
                }
        }



        double AskCOPPERUS = NormalizeDouble(SymbolInfoDouble(SymbolCOPPERUS,SYMBOL_ASK),_Digits);

        if(totalPositionsLongCOPPERUS == 0){

                currentSLCOPPERUS = 0;

                if(losingOrWinningTrendCOPPERUS == 0){
                        double dcUpper5COPPERUS[]; 
                        CopyBuffer(handleDc5COPPERUS,0,0,1,dcUpper5COPPERUS);
                        
                        if(AskCOPPERUS >= dcUPPER5COPPERUS[0]){
                                
                                FiveDayLongBreakoutCOPPERUS = 1;
                                TenDayLongBreakoutCOPPERUS = 0;

                                currentSlCOPPERUS = NormalizeDouble((AskCOPPERUS * 0.98),5);
                                
                                trade.Buy(1.00,SymbolCOPPERUS,AskCOPPERUS,currentSlCOPPERUS,0,"1st Position long");     

                                LosingOrWinningTrend = 0;
                        }
                }else if(losingOrWinningTrendCOPPERUS == 1){
                        double dcUpper10COPPERUS[]; 
                        CopyBuffer(handleDc10COPPERUS,0,0,1,dcUpper10COPPERUS);
                        
                        if(AskCOPPERUS >= dcUPPER5COPPERUS[0]){

                                FiveDayLongBreakoutCOPPERUS = 0;
                                TenDayLongBreakoutCOPPERUS = 1;

                                currentSlCOPPERUS = NormalizeDouble((AskCOPPERUS * 0.98),5);
                                
                                trade.Buy(1.00,SymbolCOPPERUS,AskCOPPERUS,currentSlCOPPERUS,0,"1st Position long");     

                                LosingOrWinningTrend = 0;
                        }
                }
        }
                



 
Dinomayn:
LosingOrWinningTrend
In the code you posted this variable is not initialized and is never set to 1.
 
Alain Verleyen #:
In the code you posted this variable is not initialized and is never set to 1.

My Appologies, Alain.

LosingOrWinningTrend is supposed to be LosingOrWinningTrendCOPPERUS instead. I have corrected it in this code, added trade library and Ctrade instance which is a part of the bigger code.

When it's LosingOrWinningTrendCOPPERUS, it gets the value of 1 in the loop for modifying the SL when I have open long positions and the conditions are right. Then when I get stopped out, the value of 1 remains, which is want. 

However the LosingOrWinningTrendCOPPERUS reverts to 0 even though no breakout and new position opening happens and it only happens with multiple symbols.

The code is identical for other symbols. The 'COPPERUS' is just replaced with other symbols in the entire subpart of the code for the other symbols.


// Import Trade Library
#include <Trade/Trade.mqh>

// Create an instance of Ctrade called trade
CTrade trade;

SymbolCOPPERUS = COPPERUS.pro

int LosingOrWinningTrendCOPPERUS;

int handleDc5COPPERUS;
int handleDc10COPPERUS;

//Define Breakouts
int FiveDayLongBreakoutCOPPERUS;
int TenDayLongBreakoutCOPPERUS;

double currentSlCOPPERUS;


int OnInit(){

        //Create handle for Donchian Channel for 5 days
        handleDc5COPPERUS = iCustom(SymbolCOPPERUS,PERIOD_D1,"DonchianChannel.ex5",5);

        //Create handle for Donchian Channel for 10 days
        handleDc10COPPERUS = iCustom(SymbolCOPPERUS,PERIOD_D1,"DonchianChannel.ex5",10);
        

void OnTick(){

   // Create integer variable for total long and short positions
   int totalPositionsLongCOPPERUS = 0;

   //Create double variable for highest opening price for long positions.
   double highestAskCOPPERUS = 0.0;
   
        // Use for loop to find total amount of long and short positions. 
        // The highest long positions are found.
        for(int i=PositionsTotal() - 1; i >= 0; i--){
                if(PositionGetSymbol(i) == SymbolCOPPERUS){
                        if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){
                                totalPositionsLongCOPPERUS++;
                                double posAskPriceCOPPERUS = PositionGetDouble(POSITION_PRICE_OPEN);
                                if(posAskPriceCOPPERUS >= highestAskCOPPERUS){
                                        highestAskCOPPERUS = posAskPriceCOPPERUS;
                                }
                        }
                }
        }

       // Define lows
       double TwoDayLowCOPPERUS = 0.0;
       double FiveDayLowCOPPERUS = 0.0;
        
        if(totalPositionsLongCOPPERUS > 0 && FiveDayLongBreakoutCOPPERUS == 1){
                // Calculate the Two-day low only for open long positions
                int TwoDayLowestIndexCOPPERUS = iLowest(SymbolCOPPERUS,PERIOD_D1,MODE_LOW,2,1);
                TwoDayLowCOPPERUS = NormalizeDouble((iLow(SymbolCOPPERUS,PERIOD_D1,TwoDayLowestIndexCOPPERUS)),_Digits);

        if(totalPositionsLongCOPPERUS > 0 && TenDayLongBreakoutCOPPERUS == 1){
                // Calculate the Two-day low only for open long positions
                int FiveDayLowestIndexCOPPERUS = iLowest(SymbolCOPPERUS,PERIOD_D1,MODE_LOW,5,1);
                FiveDayLowCOPPERUS = NormalizeDouble((iLow(SymbolCOPPERUS,PERIOD_D1,FiveDayLowestIndexCOPPERUS)),_Digits);


        // Use for loop to modify SL for open position when a new position is opened.
        // If 2-day/5-day low is higher than the Current Position Unit SL for long positions a new SL is set. 
        for(int i=PositionsTotal() - 1; i >= 0; i--){
                if(PositionGetSymbol(i) == SymbolCOPPERUS){
                        ulong PositionTicketCOPPERUS = PositionGetInteger(POSITION_TICKET);
                        if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){
                                if(FiveDayLongBreakoutCOPPERUS == 1){
                                        if(PositionGetDouble(POSITION_SL) < currentSlCOPPERUS && currentSlCOPPERUS > TwoDayLowCOPPERUS){
                                                trade.PositionModify(PositionTicketCOPPERUS,currentSlCOPPERUS,0);
                                                losingOrWinningTrendCOPPERUS = 0;
                                        }else if(PositionGetDouble(POSITION_SL) < TwoDayLowCOPPERUS && currentSlCOPPERUS < TwoDayLowCOPPERUS){
                                                trade.PositionModify(PositionTicketCOPPERUS,TwoDayLowCOPPERUS,0);
                                                losingOrWinningTrendCOPPERUS = 1;
                  
                                        }      
                                }else if(TenDayLongBreakoutCOPPERUS == 1){
                                        if(PositionGetDouble(POSITION_SL) < currentSlCOPPERUS && currentSlCOPPERUS > FiveDayLowCOPPERUS){
                                                trade.PositionModify(PositionTicketCOPPERUS,currentSlCOPPERUS,0);
                                                losingOrWinningTrendCOPPERUS = 0;
                                        }else if(PositionGetDouble(POSITION_SL) < TenDayLowCOPPERUS && currentSlCOPPERUS < TenDayLowCOPPERUS){
                                                trade.PositionModify(PositionTicketCOPPERUS,TenDayLowCOPPERUS,0);
                                                losingOrWinningTrendCOPPERUS = 1;
                                        }   
                                }  
                        }
                }
        }



        double AskCOPPERUS = NormalizeDouble(SymbolInfoDouble(SymbolCOPPERUS,SYMBOL_ASK),_Digits);

        if(totalPositionsLongCOPPERUS == 0){

                currentSLCOPPERUS = 0;

                if(losingOrWinningTrendCOPPERUS == 0){
                        double dcUpper5COPPERUS[]; 
                        CopyBuffer(handleDc5COPPERUS,0,0,1,dcUpper5COPPERUS);
                        
                        if(AskCOPPERUS >= dcUPPER5COPPERUS[0]){
                                
                                FiveDayLongBreakoutCOPPERUS = 1;
                                TenDayLongBreakoutCOPPERUS = 0;

                                currentSlCOPPERUS = NormalizeDouble((AskCOPPERUS * 0.98),5);
                                
                                trade.Buy(1.00,SymbolCOPPERUS,AskCOPPERUS,currentSlCOPPERUS,0,"1st Position long");     

                                LosingOrWinningTrendCOPPERUS = 0;
                        }
                }else if(losingOrWinningTrendCOPPERUS == 1){
                        double dcUpper10COPPERUS[]; 
                        CopyBuffer(handleDc10COPPERUS,0,0,1,dcUpper10COPPERUS);
                        
                        if(AskCOPPERUS >= dcUPPER5COPPERUS[0]){

                                FiveDayLongBreakoutCOPPERUS = 0;
                                TenDayLongBreakoutCOPPERUS = 1;

                                currentSlCOPPERUS = NormalizeDouble((AskCOPPERUS * 0.98),5);
                                
                                trade.Buy(1.00,SymbolCOPPERUS,AskCOPPERUS,currentSlCOPPERUS,0,"1st Position long");     

                                LosingOrWinningTrendCOPPERUS = 0;
                        }
                }
        }
 
Dinomayn #:

My Appologies, Alain.

LosingOrWinningTrend is supposed to be LosingOrWinningTrendCOPPERUS instead. I have corrected it in this code, added trade library and Ctrade instance which is a part of the bigger code.

When it's LosingOrWinningTrendCOPPERUS, it gets the value of 1 in the loop for modifying the SL when I have open long positions and the conditions are right. Then when I get stopped out, the value of 1 remains, which is want. 

However the LosingOrWinningTrendCOPPERUS reverts to 0 even though no breakout and new position opening happens and it only happens with multiple symbols.

The code is identical for other symbols. The 'COPPERUS' is just replaced with other symbols in the entire subpart of the code for the other symbols.


You have to debug your code and logic. Your variable LosingOrWinningTrendCOPPERUS is set to 0 in 4 different places (Well one of these is useless as it's already 0). Run your code with the debugger, put breakpoint on these lines where it's reset to 0.

And I strongly suggest you to INITIALIZE your variables as already stated.

 
Alain Verleyen #:

You have to debug your code and logic. Your variable LosingOrWinningTrendCOPPERUS is set to 0 in 4 different places (Well one of these is useless as it's already 0). Run your code with the debugger, put breakpoint on these lines where it's reset to 0.

And I strongly suggest you to INITIALIZE your variables as already stated.

Thank you very much for your advices, Alain. It's very well received.


If a current trend or the last trend before a new breakout is considered a winning trend, then losingOrWinningTrendCOPPERUS is assigned the value of 1. If it's a losing trend, it's then assigned the value of 0. 

losingOrWinningTrendCOPPERUS is used to define the next breakout criteria.  I'm really not sure in which place 'losingOrWinningTrend = 0' is useless. Can you point it out? 





I ran the debugger. Didn't even know it existed before your comment. So thank you very much.

When I ran the debugger, I checked the related variables out and noticed that the value of BidCOPPERUS had the same value as BidEURUSD, which is super weird.

BidEURUSD value is correct for EURUSD. BidCOPPERUS shouldn't have the same value. (Picture 1):

In the strategy tester visualization, the values are different which is correct. (Picture 2):

I usually get the correct bid price for copper when testing and suddenly for a split second I receive the wrong bid price, which is the same bid price for the EURUSD. 

My code relating for the bid prices is this:

string SymbolEURUSD = "EURUSD.pro";
string SymbolCOPPERUS = "COPPER-US.pro.Custom";


void OnTick(){

   // Get the Bid price
   double BidCOPPERUS = NormalizeDouble(SymbolInfoDouble(SymbolCOPPERUS,SYMBOL_BID),_Digits);

   // Get the Bid price
   double BidEURUSD = NormalizeDouble(SymbolInfoDouble(SymbolEURUSD,SYMBOL_BID),_Digits);

}

Do you know what the issue might be?




I have intialized the remaining globally declared variables with the value of 0 as shown right underneath.

SymbolCOPPERUS = COPPERUS.pro

int LosingOrWinningTrendCOPPERUS = 0;

int handleDc5COPPERUS = 0;
int handleDc10COPPERUS = 0;

//Define Breakouts
int FiveDayLongBreakoutCOPPERUS = 0;
int TenDayLongBreakoutCOPPERUS = 0;

double currentSlCOPPERUS = 0;
Files:
Picture_1.png  5 kb
Picture_2.png  16 kb
 
Dinomayn #:

Thank you very much for your advices, Alain. It's very well received.


If a current trend or the last trend before a new breakout is considered a winning trend, then losingOrWinningTrendCOPPERUS is assigned the value of 1. If it's a losing trend, it's then assigned the value of 0. 

losingOrWinningTrendCOPPERUS is used to define the next breakout criteria.  I'm really not sure in which place 'losingOrWinningTrend = 0' is useless. Can you point it out? 

if(losingOrWinningTrendCOPPERUS == 0){
                        double dcUpper5COPPERUS[]; 
                        CopyBuffer(handleDc5COPPERUS,0,0,1,dcUpper5COPPERUS);
                        
                        if(AskCOPPERUS >= dcUPPER5COPPERUS[0]){
                                
                                FiveDayLongBreakoutCOPPERUS = 1;
                                TenDayLongBreakoutCOPPERUS = 0;

                                currentSlCOPPERUS = NormalizeDouble((AskCOPPERUS * 0.98),5);
                                
                                trade.Buy(1.00,SymbolCOPPERUS,AskCOPPERUS,currentSlCOPPERUS,0,"1st Position long");     

                                LosingOrWinningTrendCOPPERUS = 0;
                        }


I ran the debugger. Didn't even know it existed before your comment. So thank you very much.

When I ran the debugger, I checked the related variables out and noticed that the value of BidCOPPERUS had the same value as BidEURUSD, which is super weird.

BidEURUSD value is correct for EURUSD. BidCOPPERUS shouldn't have the same value. (Picture 1):

In the strategy tester visualization, the values are different which is correct. (Picture 2):

I usually get the correct bid price for copper when testing and suddenly for a split second I receive the wrong bid price, which is the same bid price for the EURUSD. 

My code relating for the bid prices is this:

Do you know what the issue might be?

No idea what is the problem with that but you should use SymbolInfoTick() to get the current price not SymbolInfoDouble(). Also there is no need to use NormalizeDouble there.

I have intialized the remaining globally declared variables with the value of 0 as shown right underneath.

 
Alain Verleyen #:


No idea what is the problem with that but you should use SymbolInfoTick() to get the current price not SymbolInfoDouble(). Also there is no need to use NormalizeDouble there.

Thanks, Alain!

It seems that somehow the problem disappeared when I replaced SymbolInfoDouble() with SymbolInfoTick() and removed NormalizeDouble. Don't know why.

Why isn't SymbolInfoDouble() an appropriate function in my case? Just curious.

 
Dinomayn #:

Thanks, Alain!

It seems that somehow the problem disappeared when I replaced SymbolInfoDouble() with SymbolInfoTick() and removed NormalizeDouble. Don't know why.

Why isn't SymbolInfoDouble() an appropriate function in my case? Just curious.

I don't really know why as I have no information about the internal working of these functions.

It's recommended in the documentation, and I know by experience that SymbolInfoTick() is reliable while SymbolInfoDouble() is not to get tick prices.


 
Alain Verleyen #:

I don't really know why as I have no information about the internal working of these functions.

It's recommended in the documentation, and I know by experience that SymbolInfoTick() is reliable while SymbolInfoDouble() is not to get tick prices.


Makes perfect sense.

In my case the breakpoints with the price errors are now corrected, which is terrific.

Now that you mention some sort of documentation. Where can I access this documentation?

Reason: