Order modify problem

 

I've got a nagging problem with this piece of code. It is supposed to modify the stop loss of OP_BUY or OP_SELL orders, but somehow is it tries to modify pending orders, and ignores the op_buy/sell orders. I thought the:

if( OrderType() <= OP_SELL ) 

would take care of that but it doesn't.. :(


When it tries to modify orders it throws an 130 error (obviously):

2009.12.22 11:14:18	2009.06.10 10:00  GrailOne v2.1 EURUSD,H1: OrderModify error 130
2009.12.22 11:14:18	2009.06.10 10:00  GrailOne v2.1 EURUSD,H1: OrderModify=>OrderTicket:8,OrderOpenPrice:1.3852,OrderStopLoss:1.3852,OrderTakeProfit:1.3902,OrderExpiration:0||Bid:1.4086,Ask:1.4088

Does anyone see the problem?

for( int j=0;j<OrdersTotal();j++ )
      {
         //Print("Order ",i," of ", OrdersTotal());
         if( OrderSelect(j,SELECT_BY_POS,MODE_TRADES)==false ) {
            break;
         }   
         if( OrderMagicNumber()!=MagicNumber || OrderSymbol()!=Symbol() ) {
            break;
         }
           
         if( OrderType() <= OP_SELL )                             //--- Only modify OP_BUY of OP_SELL orders
         {  
            if( LastSlChange < Time[0] )                          //--- Stop los hasn't been changed so far during this bar
            {
               Print("OrderType:",OrderType());
               if( CalculateCurrentOrders(Symbol(),12) < 2 )         //--- Only one of the hedge-pair is still active
               {
                  int    CurrentTicket    = OrderTicket();
                  double OpenPrice        = OrderOpenPrice();
                  double NewSL            = 0;
                  double CurrentSL        = OrderStopLoss();
                  double CurrentTP        = OrderTakeProfit();
                  int    CurrentExp       = OrderExpiration();
                  
                  NewSL = OpenPrice;
                  
                  if( NewSL != CurrentSL )
                  {                     
                     Print("OrderModify=>OrderTicket:",CurrentTicket,",OrderOpenPrice:",OpenPrice,",OrderStopLoss:",NewSL,",OrderTakeProfit:",CurrentTP,",OrderExpiration:",CurrentExp,"||Bid:",Bid,",Ask:",Ask);
                     OrderModify( CurrentTicket, OpenPrice, NewSL, CurrentTP, CurrentExp, White ); 
                     LastSlChange = Time[0];
                  }
               }
            }
         }
         
      }
 

Your error 130 is caused by trying to set your stoploss equal to your open price.

Check the output of MarketInfo(Symbol(),MODE_STOPLEVEL) to see how close your stops are allowed to be.


CB

 
cloudbreaker:

Your error 130 is caused by trying to set your stoploss equal to your open price.

Check the output of MarketInfo(Symbol(),MODE_STOPLEVEL) to see how close your stops are allowed to be.


CB

I know the reason for the 130 error, it's because the EA is tries to modify a pending order. The question however is, why does it modify a pending order?

if( OrderType() <= OP_SELL )

Should prevent that.


I solved the problem already with a bit of very ugly code, but I still would like to know why the code above doesn't work

 

Have you tried substituting either of:

if( OrderType() <= 1 )

or

if( OrderType() == OP_SELL || OrderType() == OP_BUY )

 
cloudbreaker:

Have you tried substituting either of: [...]

The various alternatives you're discussing are (or should be) identical. I don't see a problem with the way the code ignores pending orders.


Is it possible that the CalculateCurrentOrders() function is doing an OrderSelect(), changing the order "context" after you've established that order n is not pending? It looks from the comments as though CalculateCurrentOrders() does something involving examining pairs of buys and sells, and there's a potential problem if it's doing this by (re-)scanning the order list and doing an OrderSelect()...

 

Agreed - that all 3 options for that conditional statement should be the same.

jjc, I think you're absolutely right about the existence of a further OrderSelect() in the CalculateCurrentOrders() getting in the way.


CB

 
cloudbreaker wrote >>

Agreed - that all 3 options for that conditional statement should be the same.

jjc, I think you're absolutely right about the existence of a further OrderSelect() in the CalculateCurrentOrders() getting in the way.

CB

hi cloudbreaker

Could you please help me to make this ea work with ECN broker,and many thanks

/+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
double llots;
double lSL;

if (TakeProfit==0) TakeProfit=StopLoss/2;

if (StopDistance!=TakeProfit)
if (StopDistance!=(TakeProfit/2))
return (-1);
if (TimeFrame!=0)
if ((TimeFrame!=PERIOD_M1) && (TimeFrame!=PERIOD_M5) && (TimeFrame!=PERIOD_M15) && (TimeFrame!=PERIOD_M30) && (TimeFrame!=PERIOD_H1) && (TimeFrame!=PERIOD_H4) && (TimeFrame!=PERIOD_D1) && (TimeFrame!=PERIOD_W1) && (TimeFrame!=PERIOD_MN1))
return (-1);

if(MaxLots==0) llots=LotSize(); else
if(MaxLots==LotSize()) llots=3*LotSize(); else
llots=MaxLots*2;

lSL=StopLoss;

CheckSignal();


if(cur_signal & _BUY !=0)
OpenOrder(OP_BUY, llots, Ask, Slippage, lSL, TakeProfit, WindowExpertName(), MagicNumber, 0, Blue);

if(cur_signal & _SELL !=0)
OpenOrder(OP_SELL, llots, Bid, Slippage, lSL, TakeProfit, WindowExpertName(), MagicNumber, 0, Red);

if(cur_signal & _CLOSEBUY !=0)
{
CloseLongs(MagicNumber);
}

if(cur_signal & _CLOSESELL !=0)
{
CloseShorts(MagicNumber);
}

if(cur_signal & _DELETEBUYSTOP !=0)
DeleteOpenOrder(OP_BUYSTOP);

if(cur_signal & _DELETESELLSTOP !=0)
DeleteOpenOrder(OP_SELLSTOP);

if(cur_signal & _OPENBUYSTOP !=0)
{
DeleteOpenOrder(OP_BUYSTOP);
if(FirstOrderIsLong) BuyStopPrice=EntryPrice; else BuyStopPrice=EntryPrice+StopDistance*point;
Print ("First Order Is Long = " + FirstOrderIsLong);
OpenOrder(OP_BUYSTOP, llots, BuyStopPrice, Slippage, lSL, TakeProfit, WindowExpertName(), MagicNumber, 0, Blue);
}

if(cur_signal & _OPENSELLSTOP !=0)
{
DeleteOpenOrder(OP_SELLSTOP);
Print ("Entry Price = " + NormalizeDouble(EntryPrice,Digits));
if(FirstOrderIsLong) SellStopPrice=EntryPrice-StopDistance*point; else SellStopPrice=EntryPrice;
Print ("First Order Is Long = " + FirstOrderIsLong);
OpenOrder(OP_SELLSTOP, llots, SellStopPrice, Slippage, lSL, TakeProfit, WindowExpertName(), MagicNumber, 0, Red);
}

CheckOpenPositions();
HandleOpenPositions();
return(0);
}
//+------------------------------------------------------------------+


void CheckSignal()
{
cur_signal=_NONE;

if(OpenBuy==0 && OpenSell==0)
{
if(OpenBuyStop>0) cur_signal |= _DELETEBUYSTOP;
if(OpenSellStop>0) cur_signal |= _DELETESELLSTOP;

if(cur_signal==_NONE)
{
// to see if it's possible to made a trade
if(BlockTradingFilter1())
return(0);

MA=iMA(NULL,TimeFrame,Period_MA,0,MODE_SMA,PRICE_CLOSE,0);

if (Bid > MA && Fact_Up == true) // Checking if price above
{
Fact_Dn = true; // Report about price above MA
Fact_Up = false; // Don't report about price below MA
//Alert("Price is above MA(",Period_MA,")."); // Alert
FirstOrderIsLong = true;
}
//--------------------------------------------------------------------
if (Bid < MA && Fact_Dn == true) // Checking if price below
{
Fact_Up = true; // Report about price below MA
Fact_Dn = false; // Don't report about price above MA
//Alert("Price is below MA(",Period_MA,").");// Alert
FirstOrderIsLong = false;
}


if(FirstOrderIsLong) cur_signal |= _BUY; else cur_signal |= _SELL;
EntryPrice=0;
}
}

if(OpenBuy!=0 || OpenSell!=0)
{
if(OpenBuy>OpenSell && OpenSellStop==0)
{
cur_signal |= _OPENSELLSTOP;
}
if(OpenBuy<OpenSell && OpenBuyStop==0)
{
cur_signal |= _OPENBUYSTOP;
}
}
}

//+------------------------------------------------------------------+
//| FILTER BLOCK MODULES
//+------------------------------------------------------------------+
bool BlockTradingFilter1()
{ //Original code Contributed by Wackena
bool BlockTrade=false; //trade by default
if (UseHourTrade)
{
if( !(Hour() >= StartHourTrade && Hour() <= EndHourTrade && Minute()<= 3) )
{
// Comment("Non-Trading Hours!");
BlockTrade=true;
}
}
return (BlockTrade);
}

//+------------------------------------------------------------------+
//| Handle Open Positions |
//| Check if any open positions need to be closed or modified |
//+------------------------------------------------------------------+
int HandleOpenPositions()
{
int cnt;
bool YesClose;
double pt;

for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
{
OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES);
if ( OrderSymbol() != Symbol()) continue;
if ( OrderMagicNumber() != MagicNumber) continue;

if(OrderType() == OP_BUY)
{
}

if(OrderType() == OP_SELL)
{
}
}
return(0);
}


int OpenOrder(int aCmd, double aLots, double aPrice, int aSlipPage, int aStopLoss, int aTakeProfit, string aComment, int aMagic, datetime aExpiration, color aColor)
{
int order_ticket = 0;
int err = 0;
int l_Try = 0;
int l_MaxTry = 10;
double aPrice2=aPrice;// +Ask-Bid;
double maxLots = MarketInfo(Symbol(),MODE_MAXLOT);
double StopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL);

switch (aCmd) {
case OP_BUY:
case OP_BUYLIMIT:
case OP_BUYSTOP:
for (l_Try = 0; l_Try < l_MaxTry; l_Try++)
{
aPrice2=aPrice;
if(aCmd==OP_BUY) { RefreshRates(); aPrice=Ask; /*aPrice2=Bid;*/ }
if (aLots<=maxLots)
order_ticket = OrderSend(Symbol(), aCmd, aLots, aPrice, aSlipPage, StopLong(aPrice, aStopLoss), TakeLong(aPrice, aTakeProfit), aComment, aMagic, aExpiration, aColor);
else{
while (aLots>0){
double bLots = 0;
string bLotComment = DoubleToStr( aLots,2);
if (aLots>maxLots)
{
aLots = aLots - maxLots;
bLots = maxLots;
}
else{
bLots = aLots;
aLots = 0;
}
order_ticket = OrderSend(Symbol(), aCmd, bLots, aPrice, aSlipPage, StopLong(aPrice, aStopLoss), TakeLong(aPrice, aTakeProfit), bLotComment, aMagic, aExpiration, aColor);
}
}
if (order_ticket > 0) break;
err = GetLastError();
if (err == 0) break;
if (err == 4 || err == 137 || err == 146 || err == 136) Sleep(5000);
else {
if (aCmd == OP_BUY)
Print ("Buy");
else if (aCmd == OP_BUYSTOP)
Print ("Buy Stop");
else
Print ("Buy Limit");
Print("Buy Error Code= ", err, "Lots = " + DoubleToStr(MathMax(bLots,aLots),2), "SL = " + DoubleToStr(StopLong(aPrice,aStopLoss),Digits), "TP = " + DoubleToStr(TakeLong(aPrice,TakeProfit),Digits), " When Price = " + DoubleToStr(aPrice,Digits), " StopLevel = " + DoubleToStr(StopLevel,2), " Bid = " + DoubleToStr(Bid,Digits), " Ask = " + DoubleToStr(Ask,Digits), " AB = " + DoubleToStr(AccountBalance(),2), " AE = " + DoubleToStr(AccountEquity(),2), " EP = " + DoubleToStr(EntryPrice,Digits));
break;
}
}
break;
case OP_SELL:
case OP_SELLLIMIT:
case OP_SELLSTOP:
for (l_Try = 0; l_Try < l_MaxTry; l_Try++) {
aPrice2=aPrice;
if(aCmd==OP_SELL) { RefreshRates(); aPrice=Bid; aPrice2=Ask; }
if (aLots<=maxLots)
order_ticket = OrderSend(Symbol(), aCmd, aLots, aPrice, aSlipPage, StopShort(aPrice, aStopLoss), TakeShort(aPrice, aTakeProfit), aComment, aMagic, aExpiration, aColor);
else{
double sLots = 0;
string slotComment = DoubleToStr( aLots,2);
if (aLots>maxLots)
{
aLots = aLots - maxLots;
sLots = maxLots;
}
else{
sLots = aLots;
aLots = 0;
}
order_ticket = OrderSend(Symbol(), aCmd, sLots, aPrice, aSlipPage, StopShort(aPrice, aStopLoss), TakeShort(aPrice, aTakeProfit), slotComment, aMagic, aExpiration, aColor);
}
if (order_ticket > 0) break;
err = GetLastError();
if (err == 0) break;
if (err == 4 || err == 137 || err == 146 || err == 136) Sleep(5000);
else {
if (aCmd == OP_SELL)
Print ("Sell");
else if (aCmd == OP_SELLSTOP)
Print ("Sell Stop");
else
Print ("Sell Limit");
Print("Sell Error Code= ", err, "Lots = " + DoubleToStr(MathMax(sLots,aLots),2), "SL = " + DoubleToStr(StopShort(aPrice,aStopLoss),Digits), "TP = " + DoubleToStr(TakeShort(aPrice,TakeProfit),Digits), " When Price = " + DoubleToStr(aPrice,Digits), " StopLevel = " + DoubleToStr(StopLevel,2), " Bid = " + DoubleToStr(Bid,Digits), " Ask = " + DoubleToStr(Ask,Digits), " AB = " + DoubleToStr(AccountBalance(),2), " AE = " + DoubleToStr(AccountEquity(),2), " EP = " + DoubleToStr(EntryPrice,Digits));
break;
}
}
}
CheckStops(order_ticket);
return (order_ticket);
}

double StopLong(double aPrice, int aPips) {
if (aPips == 0) return (0);
else return (NormalizeDouble(aPrice - aPips * point,Digits));
}

double StopShort(double aPrice, int aPips) {
if (aPips == 0) return (0);
else return (NormalizeDouble(aPrice + aPips * point,Digits));
}

double TakeLong(double aPrice, int aPips) {
if (aPips == 0) return (0);
else return (NormalizeDouble(aPrice + aPips * point,Digits));
}

double TakeShort(double aPrice, int aPips) {
if (aPips == 0) return (0);
else return (NormalizeDouble(aPrice - aPips * point,Digits));
}

double CheckOpenPositions(bool InclOpenOrder=true)
{
int cnt, total;
double NumPositions;

NumPositions = 0;
total=OrdersTotal();
OpenBuy=0;
OpenSell=0;
OpenBuyLimit=0;
OpenSellLimit=0;
OpenBuyStop=0;
OpenSellStop=0;
MaxLots=0;

for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
{
OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES);
if ( OrderSymbol() != Symbol()) continue;

if ( OrderMagicNumber() != MagicNumber) continue;


if (OrderComment()==WindowExpertName())
{
if(MaxLots<OrderLots()) MaxLots=OrderLots();
}
else
{
if(MaxLots<StrToDouble(OrderComment())) MaxLots=StrToDouble(OrderComment());
}

//Print ("MaxLots = " + MaxLots + " Comment = " + OrderComment() + " Expert Name = " + WindowExpertName());

if(OrderType() == OP_BUY )
{
OpenBuy=OpenBuy+OrderLots();
if(EntryPrice==0) EntryPrice=OrderOpenPrice();
}
if(OrderType() == OP_SELL )
{
OpenSell=OpenSell+OrderLots();
if(EntryPrice==0) EntryPrice=OrderOpenPrice();
}

if(OrderType() == OP_BUYLIMIT ) OpenBuyLimit=OpenBuyLimit+OrderLots();
if(OrderType() == OP_SELLLIMIT ) OpenSellLimit=OpenSellLimit+OrderLots();
if(OrderType() == OP_BUYSTOP ) {OpenBuyStop=OpenBuyStop+OrderLots(); LastBuyStopPrice=OrderOpenPrice();}
if(OrderType() == OP_SELLSTOP ) {OpenSellStop=OpenSellStop+OrderLots(); LastSellStopPrice=OrderOpenPrice();}
}
NumPositions = OpenBuy-OpenSell;
if(InclOpenOrder) NumPositions += OpenBuyLimit+OpenBuyStop-OpenSellLimit-OpenSellStop;
return (NumPositions);
}


void CloseLongs(int MagicNumber, double clots=0)
{
int trade, err;
double llots;

//Print("Close Longs:",MagicNumber,", Lots:",clots);
for(trade=OrdersTotal()-1;trade>=0;trade--)
{
if(!OrderSelect(trade,SELECT_BY_POS,MODE_TRADES)) continue;
if(OrderSymbol()!=Symbol()) continue;
if(OrderMagicNumber()!=MagicNumber) continue;
if(OrderType()!=OP_BUY) continue;

if (clots==0) llots=OrderLots(); else llots=clots;
//Print("Ticket:",OrderTicket(),", MagicNumber:",OrderMagicNumber(),", Lots:",llots);
OrderClose(OrderTicket(),llots,Bid,Slippage,Blue);

err=GetLastError();
if(err!=0) Print("Error = ", err," - ",ErrorDescription(err));
}//for
}

void CloseShorts(int MagicNumber, double clots=0)
{
int trade, err;
double olots;
for(trade=OrdersTotal()-1;trade>=0;trade--)
{
if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES)==false) continue;
if(OrderSymbol()!=Symbol()) continue;
if(OrderMagicNumber()!=MagicNumber) continue;
if(OrderType()!=OP_SELL) continue;

olots=OrderLots();
if (clots==0) clots=olots;
OrderClose(OrderTicket(),clots,Ask,Slippage,Red);

err=GetLastError();
if(err!=0) Print("Error = ", err," - ",ErrorDescription(err));
}//for
}


int DeleteOpenOrder(int aOrderType=-1)
{
int cnt;

for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
{
OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol() != Symbol()) continue;
if(OrderMagicNumber() != MagicNumber) continue;

if(aOrderType==OrderType()) OrderDelete(OrderTicket());
else if(aOrderType==-1)
switch(OrderType())
{
case OP_BUYLIMIT:
case OP_SELLLIMIT:
case OP_BUYSTOP:
case OP_SELLSTOP: OrderDelete(OrderTicket()); break;
}
}
return(0);
}
void CheckStops(int tkt){
if (OrderSelect(tkt,SELECT_BY_TICKET,MODE_TRADES)){
double tp = NormalizeDouble(TakeProfit * point,5);
double sl = NormalizeDouble(StopLoss * point,5);
double otp = NormalizeDouble(MathAbs(OrderTakeProfit() - OrderOpenPrice()),5);
double osl = NormalizeDouble(MathAbs(OrderStopLoss() - OrderOpenPrice()),5);
if (otp!=tp)
Print ("TakeProfit not Equal tp=" + tp + " otp=" + otp + " tkt = " + tkt);
if (osl!=sl)
Print ("StopLoss not Equal sl=" + sl + " osl=" + osl + " tkt = " + tkt);
}
}
double LotSize(){
if (InitialRisk ==0) return (Lots);
double lot;
if (FiveDigitBroker)
lot=NormalizeDouble(AccountBalance( )*(InitialRisk/100)/StopLoss/((MarketInfo(Symbol(), MODE_TICKVALUE)*10)),LotDigits);
else
lot=NormalizeDouble(AccountBalance( )*(InitialRisk/100)/StopLoss/(MarketInfo(Symbol(), MODE_TICKVALUE)),LotDigits);
if (lot<Lots) lot = Lots;
return (lot);
}

Reason: