Help Setting Trading Volume from Risk


I have seen many topics around this subject, but i am finding it difficult to understand.

My trading algorithm sets my stop loss to 1.5 x the ATR of a symbol.

My risk is 2% of my Free margin.

(Is free margin the best place to take 2% of my balance?)

//--- ATR calculations for Stop loss and Take profit
double   risk   = 2;             // Percentage of equity to risk
double   FreeMarg = AccountInfoDouble(ACCOUNT_MARGIN_FREE);
double   riskVal = (risk/100) * FreeMarg;

pipVal = riskVal/(atr * 1.5);  // Pip value in account currency if stop loss is hit within risk budget

I want to set my trade volume to equal my pip value, and this is where i get stuck

I have used so far:

double         lotsMin = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);        // MODE_MINLOT   
double         lotsMax = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);        // MODE_MAXLOT
double         lotsStep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);      // MODE_LOTSTEP

// Normalise lots function
double lots_calc( double lots_vol ){
   return ( fmin( lotsMax,                         // Prevent too greater volume
            fmax( lotsMin,                         // Prevent too smaller volume
            round( lots_vol ) * lotsStep ) ));     // Align to Step value

// Function to normalize prices to tick size 
double Round2Ticksize(double price, string pair=""){
   if (pair == "") pair =_Symbol;
   double tick_size = SymbolInfoDouble(pair, SYMBOL_TRADE_TICK_SIZE );
   return( round( price / tick_size ) * tick_size );

// Function to calculate value in account currency of a Pip of Symbol
double   PipValuePerLot(string pair=""){ return(DeltaValuePerLot(pair) * pips2dbl); }

/* Function to calculate value in account currency of a Point of Symbol.
This covers all instruments where tick is not the same as a point */
double   DeltaValuePerLot(string pair=""){
   if (pair == "") pair = _Symbol;
      return(  SymbolInfoDouble(pair, SYMBOL_TRADE_TICK_VALUE)
           / SymbolInfoDouble(pair, SYMBOL_TRADE_TICK_SIZE) );

   if (_Digits == 5 || _Digits == 3){                                      // Adjust for five (5) digit brokers_
        pips2dbl = _Point * 10; pips2points = 10;   Digits_pips = 1;
   } else {
        pips2dbl = _Point;    pips2points = 1;   Digits_pips = 0;
   double MyATRArray[];                                                    // Array to hold ATR data
   ArraySetAsSeries(MyATRArray,true);                                      // Sort the price array from the current candle downwards   
   int AverageTrueRangeHandle = iATR(_Symbol,_Period,14);                  // Define the properties of the AverageTrueRangeValue EA   
   CopyBuffer(AverageTrueRangeHandle,0,0,3,MyATRArray);                    // Fill our array, one line, from current candle, back 3 candles
   double atrVal=MyATRArray[0];                                            // Get the value of the current candle, last 5 digits
   double atr=MathRound(atrVal/pips2dbl);  

   if (atr==0) {
      Alert("ATR is 0, cannot trade");

//--- Define some MQL5 Structures we will use for our trade
   MqlTick latest_price;      // To be used for getting recent/latest price quotes
   MqlTradeRequest mrequest;  // To be used for sending our trade requests
   MqlTradeResult mresult;    // To be used to get our trade results
   MqlRates mrate[];          // To be used to store the prices, volumes and spread of each bar
   ZeroMemory(mrequest);      // Initialization of mrequest structure

   double Ask=Round2Ticksize(latest_price.ask);                   // Buy price              
   double Bid=Round2Ticksize(;                   // Sell price
   double slAmt = Round2Ticksize(atrVal * 1.5);              
   double long_sl = Bid - slAmt;                  // Long Stop loss level
   double short_sl = Ask + slAmt;                 // Short Stop loss level
   double long_tp = Bid + atrVal;                 // Long Take profit level
   double short_tp = Ask - atrVal;                // Short Take profit level  

   pipVal = riskVal/(atr * 1.5);                                  // Pip value in account currency if stop loss is hit within risk budget
   double long_tradeLots = pipVal / (Ask * PipValuePerLot());
   double short_tradeLots = pipVal / (Bid * PipValuePerLot());
// Adjust Volume for allowable conditions
   double long_tradeVol = lots_calc( long_tradeLots );
   double short_tradeVol = lots_calc( short_tradeLots );    

I am not sure if my long_tradeVol, and short_tradeVol are correct, and would like someone to correct it if possible.

As a test riskVal in account currency should equal  tradeVolume * (Price - OrderStopLoss * DeltaPerLot + CommissionPerLot), but i am stuck on how to test this as well.

Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Account Properties
Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Account Properties
, then each symbol positions will be closed in the same order, in which they are opened, starting with the oldest one. In case of an attempt to close positions in a different order, the trader will receive an appropriate error. There are several types of accounts that can be opened on a trade server. The type of account on which an MQL5 program...