Why won't it trade?

 
Here is a simple EA (ignore the crummy algorithm).
It gets the signals OK but won't trade - error 130.
Where is the bug? Please!

#property copyright "HS"

extern int EA_magic = 20100430;

extern double slippage = 2;
extern double minLots = 0.1;
extern double maxLots = 10;
extern int Risk_percent = 3;
extern int tp = 60;
extern int sl = 30;
extern int TimeLimit = 4;

int numPos;
bool TradeBuy = false;
bool TradeSell = false;
double Lots, MyPoint;
datetime LastSignal=0;
double tickvalue;
int ticket;

int init()
{
MyPoint = Point;
tickvalue = (MarketInfo(Symbol(),MODE_TICKVALUE));
if(Digits == 5 || Digits == 3) {
MyPoint = MyPoint*10;
slippage = slippage*10;
}

return(0);
}

int deinit()
{
return(0);
}

bool get_signal()
{
TradeBuy = false;
TradeSell = false;

bool enable_trade = false;
double hi = 0;
double lo = 0;
double trend1 = iMA(NULL, 0, 4, 0, MODE_SMA, PRICE_OPEN, 0);
double trend2 = iMA(NULL, 0, 6, 0, MODE_SMA, PRICE_OPEN, 0);
double trend1prev = iMA(NULL, 0, 4, 0, MODE_SMA, PRICE_OPEN, 1);
double trend2prev = iMA(NULL, 0, 6, 0, MODE_SMA, PRICE_OPEN, 1);
double trend1prev2 = iMA(NULL, 0, 4, 0, MODE_SMA, PRICE_OPEN, 2);
double trend2prev2 = iMA(NULL, 0, 6, 0, MODE_SMA, PRICE_OPEN, 2);

if( Bars >= 100 ){
if( trend1>trend2 && trend1prev>trend2prev && trend1prev2<=trend2prev2 ) TradeBuy=true;
if( trend1<trend2 && trend1prev<trend2prev && trend1prev2>=trend2prev2 ) TradeSell=true;

if( TradeBuy==true || TradeSell==true ) enable_trade = true;
return(enable_trade);
}
}

void CheckForClose()
{
if( Time[TimeLimit]==LastSignal )// other closes are controlled by stops
{
OrderClose(OrderTicket(),OrderLots(),Bid,slippage+MarketInfo(Symbol(),MODE_SPREAD),CLR_NONE);
}
return(0);
}

void count_position()
{
int ordticket;
numPos = 0;

for( int i = 0 ; i < OrdersTotal() ; i++ ){
if( OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) == false ){
break;
}
if( OrderMagicNumber() != EA_magic ){
continue;
}
if( OrderSymbol() != Symbol() ){
continue;
}
ordticket = OrderTicket();
numPos++;
}
if(numPos > 0) OrderSelect(ordticket, SELECT_BY_TICKET, MODE_TRADES);
}

int OpenLong(double volume=0.1)
{
ticket = OrderSend( Symbol(), OP_BUY, volume, Ask, slippage, Ask-sl*MyPoint, Ask+tp*MyPoint, "HS-5patterns", EA_magic, 0, Blue );

if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
return(0);
}
else
{
Print("OpenLong(),OrderSelect() - returned an error : ",GetLastError());
return(-1);
}
}
else
{
Print("Error opening Buy order : ",GetLastError());
return(-1);
}
}

int OpenShort(double volume=0.1)
{
ticket = OrderSend( Symbol(), OP_SELL, volume, Bid, slippage, Bid+sl*MyPoint, Bid-tp*MyPoint, "HS-5patterns-test", EA_magic, 0, Red );

if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
return(0);
}
else
{
Print("OpenShort(),OrderSelect() - returned an error : ",GetLastError());
return(-1);
}
}
else
{
Print("Error opening Sell order : ",GetLastError());
return(-1);
}
}

void Call_MM(double slpips)
{
double riskcapital = AccountBalance()*Risk_percent/100;

Lots=(riskcapital/slpips)/tickvalue;

Lots=MathMin(maxLots,MathMax(minLots,Lots));

if( Lots < 0.1 ) // is money enough for opening 0.1 lot?
if( ( AccountFreeMarginCheck( Symbol(), OP_BUY, 0.1 ) < 10. ) ||
( AccountFreeMarginCheck( Symbol(), OP_SELL, 0.1 ) < 10. ) ||
( GetLastError() == 134 ) )
Lots = 0.0; // not enough
else Lots = 0.1; // enough; open 0.1
else Lots = NormalizeDouble( Lots, 2 );

return(0);
}

int start()
{
if( IsTradeAllowed() != true ){
return(0);
}

count_position();
if( numPos > 0){
CheckForClose();
}
else
{
if( LastSignal != Time[0] )
{
if( get_signal() == true )
{
Call_MM(sl);// sets Lots after some tests
if (Lots > 0)
{
if( TradeBuy == true ) OpenLong(Lots);
if( TradeSell == true ) OpenShort(Lots);
}
LastSignal = Time[0];
}
}
}

return(0);
}
 
ERR_INVALID_STOPS 130 Invalid stops.
 
jcadong5:
ERR_INVALID_STOPS 130 Invalid stops.


Thank you, jc, yes I know, but why?
 
Perhaps your broker only allows Market Execution rather than Instant Execution. You can check by attempting to place a manual order and looking to see if the stops fields are disabled. If this is the case your EA will need to place the order with zero stops and then modify the order to add them. Or change broker. CB
 
engcomp:


Thank you, jc, yes I know, but why?

There are many things that can go wrong in:

Bid+sl*MyPoint


Try display the actual value and see why the stop value is getting rejected.

You may look into NormalizeDouble if you need to make sure the stop value you pass is of correct format.

 
cloudbreaker:
Perhaps your broker only allows Market Execution rather than Instant Execution. You can check by attempting to place a manual order and looking to see if the stops fields are disabled. If this is the case your EA will need to place the order with zero stops and then modify the order to add them. Or change broker. CB


You have a good point, cloud. When I place a manual order, the stop fields ARE disabled. In this case, how can I make the EA work while I sleep? I will NOT enter a trade without at least a stop loss. So no automated EA trading?
 
engcomp:


You have a good point, cloud. When I place a manual order, the stop fields ARE disabled. In this case, how can I make the EA work while I sleep? I will NOT enter a trade without at least a stop loss. So no automated EA trading?


And I have another problem - when I set sl to 0, I get a division by 0 in Call_MM, which MT4 doesn't like. Change brokers? Mine is FXopen ECN - you know of them?
 
engcomp:
... how can I make the EA work while I sleep? I will NOT enter a trade without at least a stop loss. So no automated EA trading?

First place the order with TP/SL set to zero, then use OrderModify() to change the TP/SL -> https://docs.mql4.com/trading/OrderModify.



 
Open the order without Stop Loss and Take Profit first. Then select the last order and modify with SL and TP. Following is the simple code to fix that Error 130 bug.

OrderSend(Symbol(),OP_SELL,Lots,Bid,5,0,0,"Reverse",255,0,CLR_NONE);
OrderSelect(SELECT_BY_POS, MODE_TRADES);
if(OrderType()==OP_SELL && OrderSymbol()== Symbol()&& OrderComment()== "Reverse")
{
OrderModify(OrderTicket(),5,OrderOpenPrice()+(200*Point),OrderOpenPrice()-(500*Point),0,CLR_NONE);
}
 
EuroTrader:
Open the order without Stop Loss and Take Profit first. Then select the last order and modify with SL and TP. Following is the simple code to fix that Error 130 bug.

OrderSend(Symbol(),OP_SELL,Lots,Bid,5,0,0,"Reverse",255,0,CLR_NONE);
OrderSelect(SELECT_BY_POS, MODE_TRADES);
if(OrderType()==OP_SELL && OrderSymbol()== Symbol()&& OrderComment()== "Reverse")
{
OrderModify(OrderTicket(),5,OrderOpenPrice()+(200*Point),OrderOpenPrice()-(500*Point),0,CLR_NONE);
}

Thank you, everybody, for such a keen interest.

I have added the line if(slpips<=0) slpips=100; to CallMM(sl) because I want a conservative but proportionate lot size.

The code you suggest seems like a good template for my problem, I shall try it. Thank you all very much.

 
I have adopted your code as follows...
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
{
OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+(sl*MyPoint),OrderOpenPrice()-(tp*MyPoint),0,CLR_NONE);
return(0);
}
Do you agree?
Reason: