How to change global variable value from inside function - page 2

 
Fernando Carreiro:
  1. You only need the "::" if you have local variables of the same name.
  2. The global variable "VL" does not exist.
  3. You are updating the global variable "VOL", but you are using the variable "buyorderVL" when placing the trade.
  4. Updating "VOL" will not automatically update " buyorderVL" just because you initially set it to "VOL".
  5. Your function is called "VOLdoubling", but you are calling "LOTdoubling" in the OnTick() event handler.
  6. There is no need to normalise a given price quote. Ask, Bid and other price quote data are already normalised.
  7. In fact, you should avoid using NormalizeDouble() when calculating prices and instead properly adjust price calculations based on tick size instead.
  8. You should also be adjusting your volume lots, based on the contract specifications of volume minimum, maximum and step size.
Obviously, that is not your proper code. The code you posted is incomplete and cannot be compiled and tested. If you are serious about getting help, then post your proper code.
    PS! And please learn to format/style your code properly or use the "Styler" in MetaEditor.

    Sorry for the mistake, here is all of my code. Still it is not changing the value of global variable "VL". Even though the function LOTdoubling is called before making any trades.

    #include <Trade/Trade.mqh>
    #include <Trade/PositionInfo.mqh>
    CTrade trade;
    int HandleXXX;
    double XXX[];
    
    
      
    ulong OrderTicket;
    int OopS;
    
    
    double TP = 1;   
          
    double SL = 1;   
    
    
    double VL = 0.1;
    
    
    
    
    
    void LOTdoubling()
    {
    double balance = AccountInfoDouble(ACCOUNT_BALANCE);
    double x=1;
    
    while (balance > 10000)
    {
    x++;
    ::VL = (::VL*x);
    balance = (balance - 10000);
    
    }
    
    
    }
    //SELL ORDER
    
    double sellorderTP = TP;
    double sellorderSL = SL;
    double sellorderVL = VL;
    
    
    //BUY ORDER
    
    double buyorderTP = TP;
    double buyorderSL = SL; 
    double buyorderVL = VL;
    
    
    
    
    
    
    
    
    //=========================================================
    int OnInit()
      {
       string Init = "Intialized";
       Print (Init);
       return(INIT_SUCCEEDED);
      }
    //=========================================================
    
    //=========================================================
    void OnDeinit(const int reason)
      {
    
       
      }
    //=========================================================
    
    
    
    
    
    
    
    void OnTick()
      {
      
      //==========TO GET PRICE FOR SL AND TP===========//
    double BID=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
    double ASK=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
      //==========TO GET PRICE FOR SL AND TP===========//
      
      
      //==========TO GET NUMBER OF OEPEN POSITIONS=====//
       int OpenPositions=0;
       for(int i=PositionsTotal()-1; i>=0; i--)
       {string symbol=PositionGetSymbol(i);
       if (Symbol ()==symbol)
       {OpenPositions+=1;}
       };  
      //==========TO GET NUMBER OF OEPEN POSITIONS=====//
      
      HandleXXX = iCustom(_Symbol,PERIOD_CURRENT,"customindicatorX");
      CopyBuffer(HandleXXX,42,41,6,XXX);
     
     
      if(OpenPositions==0)
      {
      if(XXX[0]!=XXX[1])
      {
      
    //======Entering Long===============================  
      if(XXX[1]==42)
      {
      Print ("entering long");
      LOTdoubling();
         trade.Buy(buyorderVL,_Symbol,ASK,ASK - buyorderSL,ASK + buyorderTP);
      }
    //==================================================  
      
      
      
    //======Entering Short===============================  
      if(XXX[1]==41)
      {
      Print ("entering short");
      LOTdoubling();
         trade.Sell(sellorderVL,_Symbol,BID,BID + sellorderSL,BID - sellorderTP);
      }
    //==================================================   
      
      
      
      
      
      }
      }
      
     
      
       
      }
     
    35117153: Sorry for the mistake, here is all of my code. Still it is not changing the value of global variable "VL". Even though the function LOTdoubling is called before making any trades.

    You did not correct the mistakes I pointed before. Pay attention next time please, or I will not help any further.

    Here are the primary points that you will need to fix first:

    1. You only need the "::" if you have local variables of the same name.
    2. You are updating the global variable "VL", but you are using the global variables "buyorderVL"/"sellorderVL" when placing the trade.
    3. Updating "VL" will NOT automatically update "buyorderVL"/"sellorderVL" just because you initially set it to "VL".
    4. Learn to format/style your code properly or use the "Styler" in MetaEditor.
    Fix the above points first and re-post your new code.


    Here is a second list of points that you will also need to fix going forward:

    1. There is no need to normalise a given price quote. Ask, Bid and other price quote data are already normalised.
    2. In fact, you should avoid using NormalizeDouble() when calculating prices and instead properly adjust price calculations based on tick size instead.
    3. You should also be adjusting your volume lots, based on the contract specifications of volume minimum, maximum and step size.
    Fix them as well.

    Below is a possible solution, but maybe not, because I do not know what you want to achieve. You have not explained it, so I just made some assumptions.

    I only fixed some of the points. The rest is up to you.

    #include <Trade/Trade.mqh>
    #include <Trade/PositionInfo.mqh>
    
    CTrade trade;
    int HandleXXX;
    double XXX[];
    
    ulong OrderTicket;
    int OopS;
    
    double TP = 1;
    double SL = 1;
    double VL = 0.1;
    
    void LOTdoubling()
    {
       double balance = AccountInfoDouble(ACCOUNT_BALANCE);
       double x=1;
    
       while (balance > 10000)
       {
          x++;
          VL = VL * x;
          balance = (balance - 10000);
       }
    }
    
    //SELL ORDER
    double sellorderTP = TP;
    double sellorderSL = SL;
    double sellorderVL = VL;
    
    //BUY ORDER
    double buyorderTP = TP;
    double buyorderSL = SL;
    double buyorderVL = VL;
    
    int OnInit()
    {
       string Init = "Intialized";
       Print (Init);
       return(INIT_SUCCEEDED);
    }
    
    void OnDeinit(const int reason)
    {
    }
    
    void OnTick()
    {
       //==========TO GET PRICE FOR SL AND TP===========//
       double BID=SymbolInfoDouble(_Symbol, SYMBOL_BID);
       double ASK=SymbolInfoDouble(_Symbol, SYMBOL_ASK);
    
       //==========TO GET PRICE FOR SL AND TP===========//
    
       //==========TO GET NUMBER OF OEPEN POSITIONS=====//
       int OpenPositions=0;
       for(int i=PositionsTotal()-1; i>=0; i--)
       {
          string symbol=PositionGetSymbol(i);
          if (Symbol()==symbol)
          {
             OpenPositions+=1;
          }
       };
       
       //==========TO GET NUMBER OF OEPEN POSITIONS=====//
       HandleXXX = iCustom(_Symbol, PERIOD_CURRENT, "customindicatorX");
       CopyBuffer(HandleXXX, 42, 41, 6, XXX);
    
       if(OpenPositions==0)
       {
          if(XXX[0]!=XXX[1])
          {
             //======Entering Long===============================
             if(XXX[1]==42)
             {
                Print ("entering long");
                LOTdoubling();
                buyorderVL = VL;
                trade.Buy(buyorderVL, _Symbol, ASK, ASK - buyorderSL, ASK + buyorderTP);
             }
    
             //======Entering Short===============================
             if(XXX[1]==41)
             {
                Print ("entering short");
                LOTdoubling();
                sellorderVL = VL;
                trade.Sell(sellorderVL, _Symbol, BID, BID + sellorderSL, BID - sellorderTP);
             }
          }
       }
    }
     
    Fernando Carreiro:

    You did not correct the mistakes I pointed before. Pay attention next time please, or I will not help any further.

    Here are the primary points that you will need to fix first:

    1. You only need the "::" if you have local variables of the same name.
    2. You are updating the global variable "VL", but you are using the global variables "buyorderVL"/"sellorderVL" when placing the trade.
    3. Updating "VL" will NOT automatically update "buyorderVL"/"sellorderVL" just because you initially set it to "VL".
    4. Learn to format/style your code properly or use the "Styler" in MetaEditor.
    Fix the above points first and re-post your new code.


    Here is a second list of points that you will also need to fix going forward:

    1. There is no need to normalise a given price quote. Ask, Bid and other price quote data are already normalised.
    2. In fact, you should avoid using NormalizeDouble() when calculating prices and instead properly adjust price calculations based on tick size instead.
    3. You should also be adjusting your volume lots, based on the contract specifications of volume minimum, maximum and step size.
    Fix them as well.

    Below is a possible solution, but maybe not, because I do not know what you want to achieve. You have not explained it, so I just made some assumptions.

    I only fixed some of the points. The rest is up to you.

    Thank you for your help and patience. The main issue was your 3rd point which is now fixed. The trade volumes are now being changed, but not as I desired.

    What I want to achieve is to multiply the volume (VL) by "x" and for the while loop to add +1 to "x" for each time the balance increases by 10000 and thus also automatically decreasing the multiplication of "VL" from 3 to 2 if the balance falls from say 30000 to 28000.

    The following function is to be called before making each trade but in this "x" seems to get very large values of above 36000, I do not understand how this is happening.

    void LOTdoubling()
    {
       double balance = AccountInfoDouble(ACCOUNT_BALANCE);
       double x=1;
       VL = 0.1;
       while (balance > 10000)
       {
          x++;
          VL = (VL*x);
          balance = (balance - 10000);
       }
    }
    
     
    35117153:

    Thank you for your help and patience. The main issue was your 3rd point which is now fixed. The trade volumes are now being changed, but not as I desired.

    What I want to achieve is to multiply the volume (VL) by "x" and for the while loop to add +1 to "x" for each time the balance increases by 10000 and thus also automatically decreasing the multiplication of "VL" from 3 to 2 if the balance falls from say 30000 to 28000.

    The following function is to be called before making each trade but in this "x" seems to get very large values of above 36000, I do not understand how this is happening.


    That is because you are multiplying on every single loop iteration. You probably want the following:

    void LOTdoubling()
    {
       double balance = AccountInfoDouble(ACCOUNT_BALANCE);
       double x=1;
       VL = 0.1;
       while (balance > 10000)
       {
          x++;
          balance = (balance - 10000);
       }
    
       VL = (VL*x);
    }


    Which can be rewritten as follows:

    void LOTdoubling()
    {
       int x = 1;        
       for( double balance = AccountInfoDouble( ACCOUNT_BALANCE );
            balance > 10000;
            balance -= 10000, x++ );
       VL *= x;
    };


    However, this can be simplified and made more efficient as follows:

    void LOTdoubling()
    {
       VL *= ceil( AccountInfoDouble( ACCOUNT_BALANCE ) / 100000.0 );
    };


    You should however, be checking for the contract conditions for volume:

    Forum on trading, automated trading systems and testing trading strategies

    How to calculate lots using multiplier according to number of opened orders?

    Fernando Carreiro, 2017.09.01 21:57

    Don't use NormalizeDouble(). Here is some guidance (code is untested, just serves as example):

    // Variables for Symbol Volume Conditions
    double
       dblLotsMinimum = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MIN  ),
       dblLotsMaximum = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_MAX  ),
       dblLotsStep    = SymbolInfoDouble( _Symbol, SYMBOL_VOLUME_STEP );
       
    // Variables for Geometric Progression
    double
       dblGeoRatio = 2.8,
       dblGeoInit  = dblLotsMinimum;
       
    // Calculate Next Geometric Element
    double
       dblGeoNext  = dblGeoInit * pow( dblGeoRatio, intOrderCount + 1 );
       
    // Adjust Volume for allowable conditions
    double
       dblLotsNext = fmin( dblLotsMaximum,                                     // Prevent too greater volume
                       fmax( dblLotsMinimum,                                   // Prevent too smaller volume
                         round( dblGeoNext / dblLotsStep ) * dblLotsStep ) );  // Align to Step value

    However, this is all wrong and dangerous for your account. Learn to properly calculate risk and volume:

    Forum on trading, automated trading systems and testing trading strategies

    Loss Recover from losses trades

    William Roeder, 2021.07.02 00:04

    Control your risk so you don't have to recover.

    Risk depends on your initial stop loss, lot size, and the value of the symbol. It does not depend on margin and leverage. No SL means you have infinite risk. Never risk more than a small percentage of your trading funds, certainly less than 2% per trade, 6% total.

    1. You place the stop where it needs to be — where the reason for the trade is no longer valid. E.g. trading a support bounce the stop goes below the support.

    2. AccountBalance * percent/100 = RISK = OrderLots * (|OrderOpenPrice - OrderStopLoss| * DeltaPerLot + CommissionPerLot) (Note OOP-OSL includes the spread, and DeltaPerLot is usually around $10/pip but it takes account of the exchange rates of the pair vs. your account currency.)

    3. Do NOT use TickValue by itself - DeltaPerLot and verify that MODE_TICKVALUE is returning a value in your deposit currency, as promised by the documentation, or whether it is returning a value in the instrument's base currency.
                MODE_TICKVALUE is not reliable on non-fx instruments with many brokers - MQL4 programming forum 2017.10.10
                Is there an universal solution for Tick value? - Currency Pairs - General - MQL5 programming forum 2018.02.11
                Lot value calculation off by a factor of 100 - MQL5 programming forum 2019.07.19

    4. You must normalize lots properly and check against min and max.

    5. You must also check FreeMargin to avoid stop out

    Most pairs are worth about $10 per PIP. A $5 risk with a (very small) 5 PIP SL is $5/$10/5 or 0.1 Lots maximum.

     
    Fernando Carreiro:

    That is because you are multiplying on every single loop iteration. You probably want the following:

    Which can be rewritten as follows:

    However, this can be simplified and made more efficient as follows:

    Everything is working as expected now. I thank you sincerely for the help

    Reason: