OrderSend: Error code 131 - page 3

 
Florian Riedrich #:
OrderSend

use Print("Lot size: "+Lots); before OrderSend function and observe the lot size in the terminal expert log.

 
Ahmed Ali #:

use Print("Lot size: "+Lots); before OrderSend function and observe the lot size in the terminal expert log.


Hello,

thanks for your reply.

In the backtest the EA behaves like it's supposed to be:

2024.03.14 23:43:01.172 2021.02.05 17:00:00  TestEA v1.00 EURNZD,H1: open #11 sell 0.01 EURNZD at 1.67230 ok

2024.03.14 23:43:01.172 2021.02.05 17:00:00  TestEA  v1.00 EURNZD,H1: Enter sell 1 trade for EURNZD | lots: 0.01


I tried my code with 1.000.000 € and 1.000 € as deposit. The EA-calculations are correct.

Does someone has some other thoughts?

 
Florian Riedrich #:


Hello,

Does someone has some other thoughts?

Hello,

Try to apply this check:

bool CheckMoneyForTrade(string symb, double lots, int type)
{
   double free_margin=AccountFreeMarginCheck(symb,type,lots);

   if(free_margin<0)
   {
      string oper =(type==OP_BUY)? "Buy":"Sell";
      Print("Not enough money for ",oper," ",lots," ",symb," Error code=",GetLastError());
      return(false);
   }
   return(true);
}
   if(Bull && CheckMoneyForTrade(_Symbol,Lots,OP_BUY))
 
Alexander Voronkov #:

Hello,

Try to apply this check:

Hello,

thanks for the idea. I already implemented this.


The error refers to https://www.mql5.com/en/articles/2555#invalid_lot


//+------------------------------------------------------------------+
//| Check the correctness of the order volume                        |
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume,string &description)


Do I have to use this specific function? How do I use 

&description

This is an input. What do I have to insert here?


Maybe this helps? Bu honestly I don't think so.

The checks a trading robot must pass before publication in the Market
The checks a trading robot must pass before publication in the Market
  • www.mql5.com
Before any product is published in the Market, it must undergo compulsory preliminary checks in order to ensure a uniform quality standard. This article considers the most frequent errors made by developers in their technical indicators and trading robots. An also shows how to self-test a product before sending it to the Market.
 
double NormalizeLots(double lot)
{
   double lotstep = MarketInfo(Symbol(), MODE_LOTSTEP);
   double lots = NormalizeDouble(lot / lotstep,0)* lotstep;
   lots = MathMax(lots, MarketInfo(Symbol(), MODE_MINLOT));
   lots = MathMin(lots, MarketInfo(Symbol(), MODE_MAXLOT));
   return(lots);
}
void OnTick()
{ 
   Lots = NormalizeLots(FixedLots);
 

Normally I use such a code to cut digits

NextLots = NormalizeDouble(LotLastTicket * LotsExponent,2);

Is this something different to your code?

 

Hello,

I would like to upload my EA-structure with simplified code - I got rid of all code which is not relevant for the topic (mostly). This upload to mql does not work either.

Is there somewhere a mistake which I don't see? The mq4-file is attachted

This is really anoying as it works in Backtests & live trading...

I appreciate any help! :-)

#define PropVersion "1.00"
#property version     PropVersion
#import "stdlib.ex4"
#property strict
#import

#include<Strings\String.mqh>
#include <stdlib.mqh>
#include <stderror.mqh>
             
extern int MagicNumber = 1111;                           
extern int TakeProfit = 200;                             
extern int PipGap = 500;                           
            
enum intOptionsA
  {
   A1  = 1, // by Equity
   A2  = 2, // by Balance
   A3  = 3, // Fixed Lots
  };
extern intOptionsA RiskLotSize = A2;                     
extern double  FixedLots =0.01;                         
extern int     RiskInitialLotSize = 10000;              
extern double  LotsExponent = 1.40;                     

double pip, Multi;

ENUM_TIMEFRAMES TFs[9]= {1,5,15,30,60,240,1440,10080,43200};

string OComment;
int init() {

   OComment = "Test EA";

   //---
   _lastBarTime_M1   = iTime(Symbol(),PERIOD_M1,0); 
   _lastBarTime_M5   = iTime(Symbol(),PERIOD_M5,0); 
   _lastBarTime_M15  = iTime(Symbol(),PERIOD_M15,0); 
   _lastBarTime_M30  = iTime(Symbol(),PERIOD_M30,0); 
   _lastBarTime_H1   = iTime(Symbol(),PERIOD_H1,0); 
   _lastBarTime_H4   = iTime(Symbol(),PERIOD_H4,0); 
   _lastBarTime_D1   = iTime(Symbol(),PERIOD_D1,0); 
   _lastBarTime_W1   = iTime(Symbol(),PERIOD_W1,0); 
   _lastBarTime_MN1  = iTime(Symbol(),PERIOD_MN1,0); 
   

   GetSymbolSpecificParameters(Symbol());

   return (INIT_SUCCEEDED);
}



  
int _SymDigits;
void OnTick() {
      GetSymbolSpecificParameters(Symbol());
      CountOrders_Symbol(Symbol());  

if(NewBar(PERIOD_H4)) {
      RiskManagement(Symbol());
      
      TradingAlgo(Symbol(), OP_BUY);
      TradingAlgo(Symbol(), OP_SELL);
      
      CountOrders_Symbol(Symbol());
      AveragePrice(Symbol());
      
      Set_TP(Symbol(),OP_BUY);
      Set_TP(Symbol(),OP_SELL);
}
   
if(NewBar(PERIOD_H4))   {
   for(int i=0; i< ArraySize(TFs); i++)
      NewBar_Reset(TFs[i]);
}

}



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int Check_Grid()
  {
   if(OpenTicketsBuy > 0 && _SymAsk < (YoungestOOP_Buy - PipGap * _SymPoint)) 
      return(1);

   if(OpenTicketsSell > 0 && _SymBid > (YoungestOOP_Sell + PipGap * _SymPoint))
      return(-1);

   return(0);
  }
  
  
int Slippage;
double TP, SL;
void TradingAlgo(string Pair, int _OrderType) {

if ((OpenTicketsBuy == 0 || Check_Grid() == 1) && CheckMoneyForTrade(Pair, NextLots_Buy, OP_BUY) && _OrderType == OP_BUY) {
   string temp_CommentAdd = "";
   PlaceOrder(Pair, OP_BUY, NextLots_Buy, _SymAsk, Slippage, SL, TP, OComment, MagicNumber, 0, clrBlue, temp_CommentAdd);
}


if ((OpenTicketsSell == 0 || Check_Grid() == -1) && CheckMoneyForTrade(Pair, NextLots_Sell, OP_SELL) && _OrderType == OP_SELL) {
   string temp_CommentAdd = "";
   PlaceOrder(Pair, OP_SELL, NextLots_Sell, _SymBid, Slippage, SL, TP, OComment, MagicNumber, 0, clrRed, temp_CommentAdd);
}

}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void deinit() {

ObjectsDeleteAll();
}

 
double _SymTickValue, _SymTickSize, _SymAsk, _SymBid, _SymPoint, _SymStoplevel;
void GetSymbolSpecificParameters(string Pair)
{
_SymTickValue = MarketInfo(Pair,MODE_TICKVALUE);
_SymTickSize  = MarketInfo(Pair,MODE_TICKSIZE);
_SymDigits    = (int)MarketInfo(Pair,MODE_DIGITS);
_SymAsk       = MarketInfo(Pair,MODE_ASK);
_SymBid       = MarketInfo(Pair,MODE_BID);
_SymPoint     = MarketInfo(Pair,MODE_POINT);
_SymStoplevel = MarketInfo(Pair, MODE_STOPLEVEL);
      
if(_SymDigits==4 || _SymDigits<=2) {pip=_SymPoint;    Multi = 1000000;}
if(_SymDigits==5 || _SymDigits==3) {pip=_SymPoint*10; Multi = 100000;}

}


//+------------------------------------------------------------------+
//|Riskmanagement                                                    |
//+------------------------------------------------------------------+
double InitialLots, NextLots_Buy, NextLots_Sell;
void RiskManagement(string Pair)
{

if(RiskLotSize == 1)
   InitialLots = NormalizeDouble(AccountEquity()* MarketInfo(Pair,MODE_MINLOT)/RiskInitialLotSize,2);
if(RiskLotSize == 2)
   InitialLots = NormalizeDouble(AccountBalance() * MarketInfo(Pair,MODE_MINLOT)/RiskInitialLotSize,2);
if(RiskLotSize == 3)
   InitialLots = FixedLots;

   
if(InitialLots < SymbolInfoDouble(Pair,SYMBOL_VOLUME_MIN))
   InitialLots = SymbolInfoDouble(Pair,SYMBOL_VOLUME_MIN);

if(InitialLots > SymbolInfoDouble(Pair,SYMBOL_VOLUME_MAX))
   InitialLots = SymbolInfoDouble(Pair,SYMBOL_VOLUME_MAX);

if(OpenTicketsBuy == 0)
   NextLots_Buy = InitialLots;
if(OpenTicketsSell == 0)
   NextLots_Sell = InitialLots;


if(OpenTicketsBuy > 0)  {
   NextLots_Buy = NormalizeDouble(YoungestOL_Buy * LotsExponent,2);
   
   if(NextLots_Buy == YoungestOL_Buy)
      NextLots_Buy += MarketInfo(Pair,MODE_MINLOT);
            
   if(NextLots_Buy < SymbolInfoDouble(Pair,SYMBOL_VOLUME_MIN))
      NextLots_Buy = SymbolInfoDouble(Pair,SYMBOL_VOLUME_MIN);

   if(NextLots_Buy > SymbolInfoDouble(Pair,SYMBOL_VOLUME_MAX))
      NextLots_Buy = SymbolInfoDouble(Pair,SYMBOL_VOLUME_MAX);
  
  }

if(OpenTicketsSell > 0)  {
   NextLots_Sell = NormalizeDouble(YoungestOL_Sell * LotsExponent,2);
   
   if(NextLots_Sell == YoungestOL_Sell)
      NextLots_Sell += MarketInfo(Pair,MODE_MINLOT);
      
   if(NextLots_Sell < SymbolInfoDouble(Pair,SYMBOL_VOLUME_MIN))
      NextLots_Sell = SymbolInfoDouble(Pair,SYMBOL_VOLUME_MIN);

   if(NextLots_Sell > SymbolInfoDouble(Pair,SYMBOL_VOLUME_MAX))
      NextLots_Sell = SymbolInfoDouble(Pair,SYMBOL_VOLUME_MAX);
   }
}


int      OpenTicketsBuy, OpenTicketsSell;

double   OpenLots_Buy, OpenLots_Sell, YoungestOL_Buy, YoungestOL_Sell, OpenProfit_Buy, OpenProfit_Sell, YoungestOOP_Buy, YoungestOOP_Sell;

void CountOrders_Symbol(string _Pair)
  {
   OpenTicketsBuy=0;              OpenTicketsSell=0;            
   OpenLots_Buy=0;         OpenLots_Sell=0;
   OpenProfit_Buy=0;          OpenProfit_Sell=0;
   YoungestOOP_Buy = 1000000; YoungestOOP_Sell = 0;
  
   for(int i=0; i<=OrdersTotal(); i++)
     {
      if(OrderSelect(i,SELECT_BY_POS, MODE_TRADES))

         if(OrderMagicNumber() == MagicNumber && OrderSymbol() == _Pair)
           {
            if(OrderType() == OP_BUY)
              {
               OpenTicketsBuy++;
               OpenLots_Buy     += OrderLots();
               OpenProfit_Buy   += OrderProfit()+OrderCommission()+OrderSwap();
               
               if(OrderOpenPrice() < YoungestOOP_Buy) {
                  YoungestOL_Buy       = OrderLots();
                  YoungestOOP_Buy      = OrderOpenPrice();
               }
              }

            if(OrderType() == OP_SELL)
              {
               OpenTicketsSell++;
               OpenLots_Sell    += OrderLots();
               OpenProfit_Sell  += OrderProfit()+OrderCommission()+OrderSwap();

               if(OrderOpenPrice() > YoungestOOP_Sell) {
                  YoungestOL_Sell     = OrderLots();
                  YoungestOOP_Sell      = OrderOpenPrice();
               }
              }
           }
     }
  }

//+------------------------------------------------------------------+
//Check for new Bar
//+------------------------------------------------------------------+
static datetime _lastBarTime_M1,_lastBarTime_M5,_lastBarTime_M15,_lastBarTime_M30,_lastBarTime_H1,_lastBarTime_H4,_lastBarTime_D1,_lastBarTime_W1, _lastBarTime_MN1;           // DateTime of the last new bar which opened
bool NewBar(const ENUM_TIMEFRAMES TF)
  {
   if(TF == 1 && iTime(Symbol(),TF,0)!=_lastBarTime_M1)     return (true);
   if(TF == 5 && iTime(Symbol(),TF,0)!=_lastBarTime_M5)     return (true);
   if(TF == 15 && iTime(Symbol(),TF,0)!=_lastBarTime_M15)   return (true);
   if(TF == 30 && iTime(Symbol(),TF,0)!=_lastBarTime_M30)   return (true);
   if(TF == 60 && iTime(Symbol(),TF,0)!=_lastBarTime_H1)    return (true);
   if(TF == 240 && iTime(Symbol(),TF,0)!=_lastBarTime_H4)   return (true);
   if(TF == 1440 && iTime(Symbol(),TF,0)!=_lastBarTime_D1)  return (true);
   if(TF == 10080 && iTime(Symbol(),TF,0)!=_lastBarTime_W1) return (true);
   if(TF == 43200 && iTime(Symbol(),TF,0)!=_lastBarTime_MN1)return (true);

   else
      return (false);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void NewBar_Reset(const ENUM_TIMEFRAMES TF)
  {
  //Print("Old last Bar Time: " + _lastBarTime_D1);
   if(TF == 1 && iTime(Symbol(),TF,0)!=_lastBarTime_M1)     {_lastBarTime_M1  = iTime(Symbol(),TF,0);}
   if(TF == 5 && iTime(Symbol(),TF,0)!=_lastBarTime_M5)     {_lastBarTime_M5  = iTime(Symbol(),TF,0);}
   if(TF == 15 && iTime(Symbol(),TF,0)!=_lastBarTime_M15)   {_lastBarTime_M15 = iTime(Symbol(),TF,0);}
   if(TF == 30 && iTime(Symbol(),TF,0)!=_lastBarTime_M30)   {_lastBarTime_M30 = iTime(Symbol(),TF,0);}
   if(TF == 60 && iTime(Symbol(),TF,0)!=_lastBarTime_H1)    {_lastBarTime_H1  = iTime(Symbol(),TF,0);}
   if(TF == 240 && iTime(Symbol(),TF,0)!=_lastBarTime_H4)   {_lastBarTime_H4  = iTime(Symbol(),TF,0);}
   if(TF == 1440 && iTime(Symbol(),TF,0)!=_lastBarTime_D1)  {_lastBarTime_D1  = iTime(Symbol(),TF,0);}
   if(TF == 10080 && iTime(Symbol(),TF,0)!=_lastBarTime_W1) {_lastBarTime_W1  = iTime(Symbol(),TF,0);}
   if(TF == 43200 && iTime(Symbol(),TF,0)!=_lastBarTime_MN1){_lastBarTime_MN1 = iTime(Symbol(),TF,0);}
  //Print("New last Bar Time: " + _lastBarTime_D1);
  }


bool CheckMoneyForTrade(string symb, double lots,int type)
  {
   //to pass mql-test!!!
   //https://www.mql5.com/en/forum/229850/page2
   double free_margin=AccountFreeMarginCheck(symb,type, lots);
   //-- if there is not enough money
   if(free_margin < 0)
     {
      string oper=(type==OP_BUY)? "Buy":"Sell";
      Print("Not enough money for ", oper," ",lots, " ", symb, " Error code=",GetLastError());
      return(false);
     }
   //--- checking successful
   return(true);
  }


double   Av_Distance_Buy, Av_Distance_Sell, AveragePrice, AveragePrice_Buy, AveragePrice_Sell, TakeProfitPrice_Buy, TakeProfitPrice_Sell;
void AveragePrice(string Pair)
{

AveragePrice_Buy=0;     AveragePrice_Sell=0;
Av_Distance_Buy=0;      Av_Distance_Sell=0;
TakeProfitPrice_Buy=0;  TakeProfitPrice_Sell=0;


if (OpenTicketsBuy > 0) {
   Av_Distance_Buy   =  (OpenProfit_Buy / (OpenLots_Buy * _SymTickValue) * _SymTickSize);
   AveragePrice_Buy  =  NormalizeDouble(_SymBid - Av_Distance_Buy, _SymDigits);
   TakeProfitPrice_Buy= NormalizeDouble(AveragePrice_Buy + TakeProfit * _SymAsk * _SymPoint, _SymDigits);
}


if (OpenTicketsSell > 0) {
   Av_Distance_Sell     = (OpenProfit_Sell / ((OpenLots_Sell * _SymTickValue)) *_SymTickSize);
   AveragePrice_Sell    = NormalizeDouble(_SymAsk + Av_Distance_Sell, _SymDigits);
   TakeProfitPrice_Sell = NormalizeDouble(AveragePrice_Sell - TakeProfit * _SymBid * _SymPoint, _SymDigits);
}
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Set_TP(string Pair, int _OrderType)
{
   double TP_temp = 0;
   if(_OrderType == OP_BUY)   TP_temp = TakeProfitPrice_Buy;
   if(_OrderType == OP_SELL)  TP_temp = TakeProfitPrice_Sell;

   for(int z=0; z < OrdersTotal(); z++)   {
      if(OrderSelect(z,SELECT_BY_POS,MODE_TRADES)) {
         if(OrderSymbol() == Pair && OrderType() == _OrderType && OrderMagicNumber() == MagicNumber && OrderTakeProfit() != TP_temp) {
            ModifyOrder("TP", OrderTicket(), OrderSymbol(), OrderType(), OrderOpenPrice(), OrderStopLoss(), TP_temp, 10, clrRed);
         }
      }
   }
}
  

//+------------------------------------------------------------------+
//| open order
//+------------------------------------------------------------------+
void PlaceOrder(string _Sym, int _direction, double _lots, double _price, int _slippage, double _SL, double _TP, string _comment, int _Magic, datetime _expiration, color _OrderColor, string _CommentAdd)
  {
   int Cycle=10, check=ERR_NO_ERROR;
   int result=-1;
   string _OrderComment = StringConcatenate(_comment,_CommentAdd);
   string message = "", direction = "";
   
   if(!IsTradeContextBusy() && IsConnected() && IsTradeAllowed())
     {
      if(_direction == 0)  {direction = "BUY"; _price=Ask;}
      if(_direction == 1)  {direction = "SELL"; _price=Bid;}
      
      while(result < 0 && Cycle > 0)  {         
         result = OrderSend(_Sym, _direction, _lots, _price, _slippage, _SL, _TP, _OrderComment, _Magic, _expiration, _OrderColor);
         Sleep(200);
         Cycle--;
         
        }
      check=GetLastError();

      if(result < 0 && check!=ERR_NO_ERROR)  {
         Alert("======= Order " + _Sym + " - direction: " + direction + " could not be opened. Error: ",ErrorDescription(check));
         Alert("======= Order: " + _OrderComment + " | Sym: " + _Sym + " | Lots: " + DoubleToStr(_lots,2));
      }
      else  {
         message =   "======= Order opened: " + " | Symbol: " + _Sym + " | Ticket: " + IntegerToString(result) + " | direction: " + direction + " | Lots: " + 
                     DoubleToStr(_lots,2) + " | Magic: " + IntegerToString(_Magic) + " | Comment: " + _OrderComment;
      }
     }
  }

//+------------------------------------------------------------------+
//| Order Modify
//+------------------------------------------------------------------+
void ModifyOrder(string _type, int _Ticket, string _Pair, int _OrderType, double _OOP, double _StoppLoss, double _TakeProfit, int _Slippage, color _color)
  {
   int Cycle=10, check;
   bool result=false;
   string direction;
   double WhatIsChanged = 0;
   
   if(_type == "TP") WhatIsChanged = _TakeProfit;
   if(_type == "SL") WhatIsChanged = _StoppLoss;
   
   if(!IsTradeContextBusy() && IsConnected() && IsTradeAllowed())
     {
      if(_OrderType == OP_BUY)  direction = "BUY";
      if(_OrderType == OP_SELL) direction = "SELL";

      while(!result && Cycle > 0)  {
         result = OrderModify(_Ticket, _OOP, _StoppLoss, _TakeProfit, _Slippage, _color);
         Sleep(200);
         Cycle--;
        }
      check=GetLastError();

      if(!result && check!=ERR_NO_ERROR)
         Alert("======= Symbol: " + _Pair + " | direction: " + direction + " | Order " + IntegerToString(_Ticket) + " | "+ _type +": " + DoubleToStr(WhatIsChanged,_SymDigits) + " | ask: " + DoubleToStr(_SymAsk,_SymDigits) + 
         " | bid: " + DoubleToStr(_SymBid,_SymDigits) + " - no change. Error: " + ErrorDescription(check));
     }
  }
  • Errors count: 21

test on EURUSD,H1 2021.04.05 16:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 16:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 16:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 16:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 16:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 16:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 16:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 16:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 16:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 16:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 20:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 20:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 20:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 20:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 20:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 20:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 20:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 20:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 20:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.05 20:00:00 Test_EA EURUSD,H1: OrderSend error 131 2021.04.06 00:00:00 Test_EA EURUSD,H1: OrderSend error 131 strategy tester report 7 total trades

OrderSend: Error code 131 - What is Wrong on my code?
OrderSend: Error code 131 - What is Wrong on my code?
  • 2019.01.24
  • Freddi Setiono
  • www.mql5.com
If we tell you what you need, you can't code it. We are willing to help you when you post your attempt (using code button ) and state the nature of your problem, but we are not going to debug your hundreds of lines of code
Files:
Test_EA.mq4  15 kb
 
...
extern double  LotsExponent = 1.40;
...
if(OpenTicketsBuy > 0)  {
   NextLots_Buy  = NormalizeDouble(YoungestOL_Buy  * LotsExponent,2);
...
if(OpenTicketsSell > 0)  {
   NextLots_Sell = NormalizeDouble(YoungestOL_Sell * LotsExponent,2);
...   
if(...) { YoungestOL_Buy  = OrderLots();
...
if(...) { YoungestOL_Sell = OrderLots();
...
// IN CASES WHEN                               OrderLots() == SymbolInfoDouble(Pair,SYMBOL_VOLUME_MIN) FOR EXAMPLE = 0.01
//          AND  SymbolInfoDouble(Pair,SYMBOL_VOLUME_STEP) == SymbolInfoDouble(Pair,SYMBOL_VOLUME_MIN) FOR EXAMPLE = 0.01
//          THEN                                                                                                         
//               PINK CODE WILL LEAD TO INCORRECT ORDER VOLUME                                                           
//          BECAUSE                                                                                                      
//               0.01 * 1.4 = 0.014 BUT ALLOWED VOLUMES ARE 0.01 0.02 AND SO ON <FOR THIS EXAMPLE>                       
//                                                                                                                       
 

About using NormalizeDouble(..) in cases other than prices for sending orders

=======================================================================
Most cases of using NormalizeDouble(..) at least are useless
Many => harmful like this => mql5.com/ru/forum/160683/page1049
=======================================================================

 
...
lots = MathMax(lots, MarketInfo(Symbol(), MODE_MINLOT));
...

This statement is similar to

if ( lots < minLot ) lots = minLot ;

Both are very popular but very incorrect

Because lead to the possibility of taking more risk than allowed by risk-management calculations of =lots=

For example when lots = 0.01 and minLot = 0.10 then accepted risk will be 10 times greater than required


Must be

if ( lots < minLot ) lots = NULL ;


Links

https://www.mql5.com/en/forum/111230

https://www.mql5.com/en/forum/112782

https://www.mql5.com/en/forum/132147

https://www.mql5.com/en/forum/336236

How do I calculate lot size?
How do I calculate lot size?
  • 2008.09.22
  • [Deleted]
  • www.mql5.com
Let's say my mini account has margin of $10,000, and i want to risk 2% on the next trade (that is, simply use $200 to buy of contracts). You don't need to calculate the lot size here as you see