Solving Non Closure of Trades due to a FIFO Violation MT4 EA

 

I often open a number of trades in one direction and the EA closes out all trades in one hit. But I always get FIFO violations.

I've not been so concerned as they eventually get processed within a few seconds, that is until today when it seems it didn't, Oh time for action!

Could someone kindly look at the code below and edit it so as to select the earliest order for closure first!

void closeAllPoisitions(int type)

{

//close all

int oc = orderCount(type);

while(oc > 0)

{

int total = OrdersTotal();

RefreshRates();

for(int cnt = 0 ;cnt<=total;cnt++)

{

OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);

if(OrderMagicNumber() == getMagic())

{

if(OrderType() == OP_BUY && type == OP_BUY)

{

OrderClose(OrderTicket(),OrderLots(), Bid, 0, Yellow);

}

else if(OrderType() == OP_SELL && type == OP_SELL)

{

OrderClose(OrderTicket(),OrderLots(), Ask, 0, Yellow);

}

}

}

oc = orderCount(type);

}

}

 

...

Try this. It should close oldest first. Think it will work OK but it needs testing (I assumed that orderCount(...) will return the number of still opened order of some type. Also, you will probably need some "dead lop" switch if, for some reason, it repeatedly fails to close some order)

void closeAllPoisitions(int type)

{

while(orderCount(type) > 0)

{

datetime oldest = Time[0]+Period()*60+1;

int ticketToClose = -1;

double closePrice;

//

//

//

//

//

for(int cnt = OrdersTotal()-1; cnt>=0; cnt--)

{

if (!OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) continue;

if (OrderMagicNumber() != getMagic()) continue;

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

if (OrderOpenTime()<oldest)

{

oldest = OrderOpenTime();

ticketToClose = OrderTicket();

RefreshRates();

if (OrderType() == OP_BUY)

closePrice = Bid;

else closePrice = Ask;

}

}

//

//

//

//

//

if (ticketToClose!=-1)

if (OrderSelect(ticketToClose,SELECT_BY_TICKET,MODE_TRADES)) OrderClose(ticketToClose,OrderLots(),closePrice,0,CLR_NONE);

}

}

shawndowney:
I often open a number of trades in one direction and the EA closes out all trades in one hit. But I always get FIFO violations.

I've not been so concerned as they eventually get processed within a few seconds, that is until today when it seems it didn't, Oh time for action!

Could someone kindly look at the code below and edit it so as to select the earliest order for closure first!

void closeAllPoisitions(int type)

{

//close all

int oc = orderCount(type);

while(oc > 0)

{

int total = OrdersTotal();

RefreshRates();

for(int cnt = 0 ;cnt<=total;cnt++)

{

OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);

if(OrderMagicNumber() == getMagic())

{

if(OrderType() == OP_BUY && type == OP_BUY)

{

OrderClose(OrderTicket(),OrderLots(), Bid, 0, Yellow);

}

else if(OrderType() == OP_SELL && type == OP_SELL)

{

OrderClose(OrderTicket(),OrderLots(), Ask, 0, Yellow);

}

}

}

oc = orderCount(type);

}

}
 

Great! Thanks, I've popped it in and compiled! It needs 48hrs to cook !

Thanks so much!

 

Hi Mladen,

That worked.

It closed out all orders but it did not trace on the chart. Can you please advise where that error maybe!

Cheers

S

 

...

Replace the CLR_NONE in OrderClose() command with some color (you had Yellow in your code, but I don't like when it places those things on my charts so I automatically replaced it with no color (habit, habit ) - when it does not draw anything upon closure) Change the CLR_NONE with Yellow and it will show

shawndowney:
Hi Mladen,

That worked.

It closed out all orders but it did not trace on the chart. Can you please advise where that error maybe!

Cheers

S
 

Hi Mladen,

I have been using the code above with success when trading one currency pair only on one account. But found an issue when closing trades on an account with multiple currency pairs.

Could you amend the code to become specific to a particular currency pair?

Thanks in advance.

Cheers S

 

...

You have to add one line of code to it to do that. This is the changed code :
void closeAllPoisitions(int type)

{

while(orderCount(type) > 0)

{

datetime oldest = Time[0]+Period()*60+1;

int ticketToClose = -1;

double closePrice;

//

//

//

//

//

for(int cnt = OrdersTotal()-1; cnt>=0; cnt--)

{

if (!OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) continue;

if (OrderSymbol() != Symbol()) continue;

if (OrderMagicNumber() != getMagic()) continue;

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

if (OrderOpenTime()<oldest)

{

oldest = OrderOpenTime();

ticketToClose = OrderTicket();

RefreshRates();

if (OrderType() == OP_BUY)

closePrice = Bid;

else closePrice = Ask;

}

}

//

//

//

//

//

if (ticketToClose!=-1)

if (OrderSelect(ticketToClose,SELECT_BY_TICKET,MODE_TRADES)) OrderClose(ticketToClose,OrderLots(),closePrice,0,CLR_NONE);

}

}

Hapy trading

shawndowney:
Hi Mladen,

I have been using the code above with success when trading one currency pair only on one account. But found an issue when closing trades on an account with multiple currency pairs.

Could you amend the code to become specific to a particular currency pair?

Thanks in advance.

Cheers S
 

Hello, sir

I use multi trade manager for my grid strategy.But its not FIFO compatible.For manage my all trades i set "ManageBasketTrades =true"

I need first is first out.

I follow all your instructions but i failed.

Please look into the code and help please.

Thanks.

 
onlineindia:
Hello, sir

I use multi trade manager for my grid strategy.But its not FIFO compatible.For manage my all trades i set "ManageBasketTrades =true"

I need first is first out.

I follow all your instructions but i failed.

Please look into the code and help please.

Thanks.

In the EA OrderClose() is called on 17 occasions. All those closing should be centralized and the closing procedure than honors FIFO rules should be used instead of those

 
mladen:
In the EA OrderClose() is called on 17 occasions. All those closing should be centralized and the closing procedure than honors FIFO rules should be used instead of those

Hello sir

Thanks for your reply,But i am not expert in coding.Please I really need your help..

Thanks.

 
mladen:
Try this. It should close oldest first. Think it will work OK but it needs testing (I assumed that orderCount(...) will return the number of still opened order of some type. Also, you will probably need some "dead lop" switch if, for some reason, it repeatedly fails to close some order)

//----

hey mladen..... yes, there needs to be a '150' error code alert... ERR_TRADE_PROHIBITED_BY_FIFO.

//-----

until this week, ibfx had not been implementing fifo in the states..... this may be just specific to ibfx, but if 2 or more orders have the same orderopentime, the fifo tie breaker is the ticket number....

orderopentime's smallest increment is in minutes.... so it's quite possible for many orders to be opened in that same minute.....

OrderSelect(i, SELECT_BY_POS) should return the smallest ticket, but for some reason it did not when orders had the same orderopentime.... it never once returned the proper ticket if 2 or more orders had same opentime....

the 150 error code would lockup the platform....

my solution was to add an additional function to select the pairs smallest ticket. and include that number as a condition...... thereby assuring both time and ticket conditions were met......

and again, this might be relative to ibfx only..... h

//-----

while(Count() > 0)

{

datetime oldest = Time[0]+Period()*60+1;

int ticketToClose = -1;

double closePrice;

int lowticket;

for(int cnt = OrdersTotal()-1; cnt>=0; cnt--)

{

lowticket = ticket(); //--- ticket() is an external fuction that returns lowest ticket number

if (!OrderSelect(cnt, SELECT_BY_POS)) continue;

if (OrderSymbol() != Symbol()) continue;

if (OrderOpenTime() < oldest && OrderTicket() == lowticket)

{

oldest = OrderOpenTime();

ticketToClose = OrderTicket();

RefreshRates();

if (OrderType() == OP_BUY)

closePrice = Bid;

else closePrice = Ask;

}

}
Reason: