OrderSend error 4051 - invalid lots amount

Back to topics list To post a new topic, please log in or register
avatar
3
tonkament 2011.03.07 01:14
 

Hey everyone,

I am trying to run my first backtest through MT4 on the Alpari (US) system. The problem seems to be that Alpari is a 5-digit broker and the EA source material that I am testing from TradingSystemForex seems to have been developed for 4 digit brokers. Could anyone guide me in the right direction for adjusting this EA? Thanks.

//+------------------------------------------------------------------+
//|                                      FastSlow MA RSI MACD EA.mq4 |
//|                              Copyright © 2008, TradingSytemForex |
//|                                http://www.tradingsystemforex.com |
//+------------------------------------------------------------------+

#property copyright "Copyright © 2008, TradingSytemForex"
#property link "http://www.tradingsystemforex.com"

#define eaN "FastSlow MA RSI MACD EA"

extern string separator1="---------------- Entry Settings";
extern int FastEMA=5;
extern int SlowEMA=15;
extern int MACDSMA=1;
extern int FastMAPeriod=10;
extern int FastMAMethod=1;
extern int SlowMAPeriod=20;
extern int SlowMAMethod=1;
extern int RSIPeriod=21;
extern int RSIUpLevel=50;
extern int RSIDnLevel=50;
extern string separator2="---------------- Lot Management";
extern double Lots=0.1;
extern bool RiskManagement=false; //money management
extern double Risk=10; //risk in percentage
extern bool Martingale=false; //martingale
extern double Multiplier=1.5; //multiplier
extern double MinProfit=0; //minimum profit to apply the martingale
extern string separator3="---------------- TP SL TS BE";
bool EnableRealSL=false;
int RealSL=5; //stop loss under 15 pîps
bool EnableRealTP=false;
int RealTP=10; //take profit under 10 pîps
extern int StopLoss=0; //stop loss
extern int TakeProfit=0; //take profit
extern int TrailingStop=0; //trailing stop
int TSStep=1; //trailing step
extern int BreakEven=0; //breakeven
extern string separator4="---------------- Extras";
extern bool Reverse=false;
extern bool AddPositions=false; //positions cumulated
extern int MaxOrders=100; //maximum number of orders
extern bool MAFilter=false; //moving average filter
extern int MAPeriod=20;
extern int MAMethod=1;
extern int MAPrice=0;
extern bool TimeFilter=false; //time filter
extern int StartHour=8;
extern int EndHour=21;
extern int Magic=0;

int Slip=3;static int TL=0;double Balance=0.0;int err=0;int TK;

//start function
int start(){int j=0,limit=1;double BV=0,SV=0;BV=0;SV=0;if(CntO(OP_BUY,Magic)>0)TL=1;if(CntO(OP_SELL,Magic)>0)TL=-1;
for(int i=1;i<=limit;i++){

//time filter
string TIFI="false";if(TimeFilter){if(!(Hour()>=StartHour && Hour()<=EndHour)){TIFI="true";}}

//ma filter
double MAF=iMA(Symbol(),0,MAPeriod,0,MAMethod,MAPrice,i);string MAFIB="false";string MAFIS="false";
if((MAFilter==false)||(MAFilter&&Bid>MAF))MAFIB="true";if((MAFilter==false)||(MAFilter&&Ask<MAF))MAFIS="true";

//main signal
double FMA2=iMA(NULL,0,FastMAPeriod,0,FastMAMethod,PRICE_CLOSE,i);
double FMA1=iMA(NULL,0,FastMAPeriod,0,FastMAMethod,PRICE_CLOSE,i);
double SMA2=iMA(NULL,0,SlowMAPeriod,0,SlowMAMethod,PRICE_CLOSE,i);
double SMA1=iMA(NULL,0,SlowMAPeriod,0,SlowMAMethod,PRICE_CLOSE,i);
double RSI2=iRSI(0,0,RSIPeriod,0,i+1);
double RSI1=iRSI(0,0,RSIPeriod,0,i);
double MAC2=iMACD(NULL,0,FastEMA,SlowEMA,MACDSMA,PRICE_CLOSE,MODE_SIGNAL,i+1);
double MAC1=iMACD(NULL,0,FastEMA,SlowEMA,MACDSMA,PRICE_CLOSE,MODE_SIGNAL,i);
string SBUY="false";string SSEL="false";
if((FMA1-SMA1)>0&&RSI1>RSIUpLevel&&MAC2<0&&MAC1>0)SBUY="true";if((FMA1-SMA1)<0&&RSI1<RSIDnLevel&&MAC2>0&&MAC1<0)SSEL="true";

//entry conditions
if(MAFIB=="true"&&SBUY=="true"&&TIFI=="false"){if(Reverse)SV=1;else BV=1;break;}
if(MAFIS=="true"&&SSEL=="true"&&TIFI=="false"){if(Reverse)BV=1;else SV=1;break;}}

//risk management
bool MM=RiskManagement;
if(MM){if(Risk<0.1||Risk>100){Comment("Invalid Risk Value.");return(0);}
else{Lots=MathFloor((AccountFreeMargin()*AccountLeverage()*Risk*Point*100)/(Ask*MarketInfo(Symbol(),MODE_LOTSIZE)*
MarketInfo(Symbol(),MODE_MINLOT)))*MarketInfo(Symbol(),MODE_MINLOT);}}
if(MM==false){Lots=Lots;}

//martingale
if(Balance!=0.0&&Martingale==True){if(Balance>AccountBalance())Lots=Multiplier*Lots;else if((Balance+MinProfit)<AccountBalance())Lots=Lots/Multiplier;
else if((Balance+MinProfit)>=AccountBalance()&&Balance<=AccountBalance())Lots=Lots;}Balance=AccountBalance();

//positions initialization
int cnt=0,OP=0,OS=0,OB=0,CS=0,CB=0;OP=0;for(cnt=0;cnt<OrdersTotal();cnt++){OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
if((OrderType()==OP_SELL||OrderType()==OP_BUY)&&OrderSymbol()==Symbol()&&((OrderMagicNumber()==Magic)||Magic==0))OP=OP+1;}
if(OP>=1){OS=0; OB=0;}OB=0;OS=0;CB=0;CS=0;int SL=StopLoss;int TP=TakeProfit;

//entry conditions verification
if(SV>0){OS=1;OB=0;}if(BV>0){OB=1;OS=0;}

//conditions to close position
if((SV>0)||(TIFI=="true")||(EnableRealSL&&(OrderOpenPrice()-Bid)/Point>=RealSL)||(EnableRealTP&&(Ask-OrderOpenPrice())/Point>=RealTP)){CB=1;}
if((BV>0)||(TIFI=="true")||(EnableRealSL&&(Ask-OrderOpenPrice())/Point>=RealSL)||(EnableRealTP&&(OrderOpenPrice()-Bid)/Point>=RealTP)){CS=1;}
for(cnt=0;cnt<OrdersTotal();cnt++){OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
if(OrderType()==OP_BUY&&OrderSymbol()==Symbol()&&((OrderMagicNumber()==Magic)||Magic==0)){if(CB==1){OrderClose(OrderTicket(),OrderLots(),Bid,Slip,Red);return(0);}}
if(OrderType()==OP_SELL&&OrderSymbol()==Symbol()&&((OrderMagicNumber()==Magic)||Magic==0)){if(CS==1){OrderClose(OrderTicket(),OrderLots(),Ask,Slip,Red);return(0);}}}
double SLI=0,TPI=0;int TK=0;

//open position
if((AddP()&&AddPositions&&OP<=MaxOrders)||(OP==0&&!AddPositions)){
if(OS==0&&OB==0){Comment("no order opened");}
if(OS==1){if(TP==0)TPI=0;else TPI=Bid-TP*Point;if(SL==0)SLI=0;else SLI=Bid+SL*Point;
TK=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slip,SLI,TPI,eaN,Magic,0,Red);OS=0;Comment("sell order opened","\n","magic number : ",Magic);return(0);} 
if(OB==1){if(TP==0)TPI=0;else TPI=Ask+TP*Point;if(SL==0)SLI=0;else SLI=Ask-SL*Point;
TK=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slip,SLI,TPI,eaN,Magic,0,Lime);OB=0;Comment("buy order opened","\n","magic number : ",Magic);return(0);}}
for(j=0;j<OrdersTotal();j++){if(OrderSelect(j,SELECT_BY_POS,MODE_TRADES)){if(OrderSymbol()==Symbol()&&((OrderMagicNumber()==Magic)||Magic==0)){TrP();}}}return(0);}

//number of orders
int CntO(int Type,int Magic){int _CntO;_CntO=0;
for(int j=0;j<OrdersTotal();j++){OrderSelect(j,SELECT_BY_POS,MODE_TRADES);if(OrderSymbol()==Symbol()){
if((OrderType()==Type&&(OrderMagicNumber()==Magic)||Magic==0))_CntO++;}}return(_CntO);}

//breakeven
void TrP(){int BE;double pb,pa,pp;pp=MarketInfo(OrderSymbol(),MODE_POINT);if(OrderType()==OP_BUY){pb=MarketInfo(OrderSymbol(),MODE_BID);
BE=BreakEven;if(BE>0){if((pb-OrderOpenPrice())>BE*pp){if((OrderStopLoss()-OrderOpenPrice())<0){ModSL(OrderOpenPrice()+0*pp);}}}

//trailing stop 
int TS=TrailingStop;
if(TS>0){if((pb-OrderOpenPrice())>TS*pp){if(OrderStopLoss()<pb-(TS+TSStep-1)*pp){ModSL(pb-TS*pp);return;}}}}
if(OrderType()==OP_SELL){pa=MarketInfo(OrderSymbol(),MODE_ASK);
BE=BreakEven;if(BE>0){if((OrderOpenPrice()-pa)>BE*pp){if((OrderOpenPrice()-OrderStopLoss())<0){ModSL(OrderOpenPrice()-0*pp);}}}
if(TS>0){if(OrderOpenPrice()-pa>TS*pp){if(OrderStopLoss()>pa+(TS+TSStep-1)*pp||OrderStopLoss()==0){ModSL(pa+TS*pp);return;}}}}}

//stop loss modification function
void ModSL(double ldSL){bool fm;fm=OrderModify(OrderTicket(),OrderOpenPrice(),ldSL,OrderTakeProfit(),0,CLR_NONE);}

//add positions function
bool AddP(){int _num=0; int _ot=0;
for (int j=0;j<OrdersTotal();j++){if(OrderSelect(j,SELECT_BY_POS)==true && OrderSymbol()==Symbol()&&OrderType()<3&&((OrderMagicNumber()==Magic)||Magic==0)){    
_num++;if(OrderOpenTime()>_ot) _ot=OrderOpenTime();}}if(_num==0) return(true);if(_num>0 && ((Time[0]-_ot))>0) return(true);else return(false);

//not enough money message to continue the martingale
if(TK<0){if (GetLastError()==134){err=1;Print("NOT ENOGUGHT MONEY!!");}return (-1);}}

 
avatar
2985
Ais 2011.03.07 03:20 #
 

Hi,

"extern" variables should be "read only".

Try to exclude this block:

//risk management
/*
bool MM=RiskManagement;
if(MM){if(Risk<0.1||Risk>100){Comment("Invalid Risk Value.");return(0);}
else{Lots=MathFloor((AccountFreeMargin()*AccountLeverage()*Risk*Point*100)/(Ask*MarketInfo(Symbol(),MODE_LOTSIZE)*
MarketInfo(Symbol(),MODE_MINLOT)))*MarketInfo(Symbol(),MODE_MINLOT);}}
if(MM==false){Lots=Lots;}
*/

and this:

//martingale
/*
if(Balance!=0.0&&Martingale==True){if(Balance>AccountBalance())Lots=Multiplier*Lots;else if((Balance+MinProfit)<AccountBalance())Lots=Lots/Multiplier;
else if((Balance+MinProfit)>=AccountBalance()&&Balance<=AccountBalance())Lots=Lots;}Balance=AccountBalance();
*/

 
avatar
3
tonkament 2011.03.07 03:34 #
 
Ais:

Hi,

"extern" variables should be "read only".

Try to exclude this block:

//risk management
/*
bool MM=RiskManagement;
if(MM){if(Risk<0.1||Risk>100){Comment("Invalid Risk Value.");return(0);}
else{Lots=MathFloor((AccountFreeMargin()*AccountLeverage()*Risk*Point*100)/(Ask*MarketInfo(Symbol(),MODE_LOTSIZE)*
MarketInfo(Symbol(),MODE_MINLOT)))*MarketInfo(Symbol(),MODE_MINLOT);}}
if(MM==false){Lots=Lots;}
*/

and this:

//martingale
/*
if(Balance!=0.0&&Martingale==True){if(Balance>AccountBalance())Lots=Multiplier*Lots;else if((Balance+MinProfit)<AccountBalance())Lots=Lots/Multiplier;
else if((Balance+MinProfit)>=AccountBalance()&&Balance<=AccountBalance())Lots=Lots;}Balance=AccountBalance();
*/


If I exclude the risk management partition, how is the EA supposed to manage the risk? And I don't think that will solve the original error.

The error:

OrderSend error 4051 - invalid lots amount

 
avatar
2985
Ais 2011.03.07 03:43 #
 

This EA already failed to manage risks, because computes wrong order size.

And, please try to place

Alert (Lots) ;

just before first "OrderSend (...);"

Also, for test, you may try to change this:

" extern double Lots=0.1;"

For example:

// extern double Lots=0.1;

and place just in the beginning of "start ()" function:

double Lots = MarketInfo(Symbol(),MODE_MINLOT);

In this case EA will trade with minimal lot size.

All these measures are to eliminate the original error.

Good luck.

 
avatar
12992
WHRoeder 2011.03.07 16:32 #
 
  1. int cnt=0,OP=0,OS=0,OB=0,CS=0,CB=0;OP=0;for(cnt=0;cnt<OrdersTotal();cnt++){OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
    if((OrderType()==OP_SELL||OrderType()==OP_BUY)&&OrderSymbol()==Symbol()&&((OrderMagicNumber()==Magic)||Magic==0))OP=OP+1;
    Always count down in the presence of multiple order (multiple charts) especially when closing/deleting. Always test return codes.
        for(pos = OrdersTotal()-1; pos >= 0 ; pos--) if (
            OrderSelect(pos, SELECT_BY_POS)                 // Only my orders w/
        &&  OrderMagicNumber()  == magic.number             // my magic number
        &&  OrderSymbol()       == Symbol()                 // and my pair.
        &&  OrderType()         <= OP_SELL ){               // Open ordrs only
            OP++;
        }
    

  2. Adjust TP, SL, and slippage for 5 digit brokers. On ECN brokers you must open the order first and then set TP/SL
    //++++ These are adjusted for 5 digit brokers.
    double  pips2points,    // slippage  3 pips    3=points    30=points
            pips2dbl;       // Stoploss 15 pips    0.0015      0.00150
    int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)
    int     init(){
        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; }
        // OrderSend(... Slippage.Pips * pips2points, Bid - StopLossPips * pips2dbl
    

  3. OrderSend error 4051 - invalid lots amount
        double  minLot  = MarketInfo(Symbol(), MODE_MINLOT),
                lotStep = MarketInfo(Symbol(), MODE_LOTSTEP),
            size = MathFloor(MathMax(0.,size)/lotStep)*lotStep;
            if (size < minLot){ at.risk.new = 0;    EA.status = status; return(0); }
    
avatar
3
tonkament 2011.04.21 09:33 #
 
WHRoeder:
  1. Always count down in the presence of multiple order (multiple charts) especially when closing/deleting. Always test return codes.
  2. Adjust TP, SL, and slippage for 5 digit brokers. On ECN brokers you must open the order first and then set TP/SL
  3. OrderSend error 4051 - invalid lots amount
Thanks. Just noticed the responses.
avatar
2
tanukitrader 2011.05.05 11:39 #
 
WHRoeder:
  1. Always count down in the presence of multiple order (multiple charts) especially when closing/deleting. Always test return codes.
  2. Adjust TP, SL, and slippage for 5 digit brokers. On ECN brokers you must open the order first and then set TP/SL
  3. OrderSend error 4051 - invalid lots amount


Hello WHRoeder, I realize this is an old thread but I am having difficulty with error 4051 on an OrderSend.

The command works fine when I put a constant value in the lotsize but when I assign the same number to

a variable for lotsize, I get that error. My demo account is set for $50,000,000 and my lotsize was 272 in

this case. It was well above the min lotsize and well below the maxlotsize. Is there anything you can think

of that I might want to check that could help me through this issue.

Best Regards

JT

 
avatar
70
Keelan 2015.12.08 05:38 #
 
Always find my way to old threads :D
avatar
Moderator
3412
GumRai 2015.12.08 06:16 #
 
So what was the point in posting in it and bringing it to the top?
avatar
12992
WHRoeder 2015.12.08 16:01 #
 
tanukitrader: It was well above the min lotsize and well below the maxlotsize. Is there anything you can think of that I might want to check that could help me through this issue.
Where do you check for free margin?
  • 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.
  • Account Balance * percent = RISK = |OrderOpenPrice - OrderStopLoss| * OrderLots * DeltaPerlot (Note OOP-OSL includes the SPREAD)
  • Do NOT use TickValue by itself - DeltaPerlot
  • You must normalize lots properly and check against min and max.
  • You must also check FreeMargin to avoid stop out
avatar
Moderator
3412
GumRai 2015.12.08 21:07 #
 

This thread is over 4 years old.Why resurrect it?

Back to topics list  

To add comments, please log in or register