The correct direction of bypassing positions is necessary:
for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of current positions
after that, create a list that will be sorted by time and then close positions by ticket (you will take the ticket from your sorted list)
Tested this method into one advisor and compared with LIFO close, these are the results:
- FIFO: profit 71,12%, drawdown 8,65%, PF 2,94, RF 7,38, SR 18,66, trades 141.
- LIFO: profit 48,34%, drawdown 13,23%, PF 2,13, RF 3,28, SR 14,89, trades 131.
Quite strange, mostly about drawdown if there was a mistake on risk control.
Tested this method into one advisor and compared with LIFO close, these are the results:
- FIFO: profit 71,12%, drawdown 8,65%, PF 2,94, RF 7,38, SR 18,66, trades 141.
- LIFO: profit 48,34%, drawdown 13,23%, PF 2,13, RF 3,28, SR 14,89, trades 131.
Quite strange, mostly about drawdown if there was a mistake on risk control.
It depends on the strategy. Some strategies are not affected at all whether it is FIFO, LIFO or anything else. But other strategies can be heavily affected and some cannot work at all with FIFO.
That is why it is best to redesign a strategy to carry out trades in a mathematically equivalent "netting" method.
Strategies like Grids, same symbol Hedging, Stacking, Scaling-in, Scaling-out, should all be studied mathematically to create a "netting" equivalent which will be compatible to FIFO.
Obviously when you reduce Grids and same symbol Hedging to a "netting" equivalent, one discovers that it is the same as not trading at all except for the trade costs, but zero profit.
It depends on the strategy. Some strategies are not affected at all whether it is FIFO, LIFO or anything else. But other strategies can be heavily affected and some cannot work at all with FIFO.
That is why it is best to redesign a strategy to carry out trades in a mathematically equivalent "netting" method.
Strategies like Grids, same symbol Hedging, Stacking, Scaling-in, Scaling-out, should all be studied mathematically to create a "netting" equivalent which will be compatible to FIFO.
Obviously when you reduce Grids and same symbol Hedging to a "netting" equivalent, one discovers that it is the same as not trading at all except for the trade costs, but zero profit.
Thank you for your reply, the advisor works only one trade per pair.
Now trying to apply a new way to set global risk by PositionsTotal and compare results back again but I got stucked, will post new results further.
This is my code to close all positions (FIFO-compliant)
#include <Arrays\ArrayLong.mqh> #include <Trade\PositionInfo.mqh> #include <Trade\Trade.mqh> //--- CArrayLong arr_tickets; // array tickets CPositionInfo position; // position info object CTrade trade; // trading object //+------------------------------------------------------------------+ //| Close market positions | //+------------------------------------------------------------------+ void ClosePositions() { //--- initialize common information trade.SetDeviationInPoints(INT_MAX); trade.SetAsyncMode(true); trade.SetMarginMode(); trade.LogLevel(LOG_LEVEL_ERRORS); //--- for(uint retry=0; retry<5 && !IsStopped(); retry++) { bool result = true; //--- Collect and Close Method (FIFO-Compliant, for US brokers) //--- Tickets are processed starting with the oldest one. arr_tickets.Shutdown(); for(int i=0; i<PositionsTotal() && !IsStopped(); i++) { ResetLastError(); if(!position.SelectByIndex(i)) { PrintFormat("> Error: selecting position with index #%d failed. Error Code: %d",i,GetLastError()); result = false; continue; } //--- build array of position tickets to be processed if(!arr_tickets.Add(position.Ticket())) { PrintFormat("> Error: adding position ticket #%I64u failed.",position.Ticket()); result = false; } } //--- now process the list of tickets stored in the array for(int i=0; i<arr_tickets.Total() && !IsStopped(); i++) { ResetLastError(); ulong m_curr_ticket = arr_tickets.At(i); if(!position.SelectByTicket(m_curr_ticket)) { PrintFormat("> Error: selecting position ticket #%I64u failed. Error Code: %d",m_curr_ticket,GetLastError()); result = false; continue; } //--- check freeze level int freeze_level = (int)SymbolInfoInteger(position.Symbol(),SYMBOL_TRADE_FREEZE_LEVEL); double point = SymbolInfoDouble(position.Symbol(),SYMBOL_POINT); bool TP_check = (MathAbs(position.PriceCurrent() - position.TakeProfit()) > freeze_level * point); bool SL_check = (MathAbs(position.PriceCurrent() - position.StopLoss()) > freeze_level * point); if(!TP_check || !SL_check) { PrintFormat("> Error: closing position ticket #%I64u on %s is prohibited. Position TP or SL is too close to activation price.",position.Ticket(),position.Symbol()); result = false; continue; } //--- trading object trade.SetExpertMagicNumber(position.Magic()); trade.SetTypeFillingBySymbol(position.Symbol()); //--- close positions if(trade.PositionClose(position.Ticket()) && (trade.ResultRetcode()==TRADE_RETCODE_DONE || trade.ResultRetcode()==TRADE_RETCODE_PLACED)) { PrintFormat("Position ticket #%I64u on %s to be closed.",position.Ticket(),position.Symbol()); PlaySound("expert.wav"); } else { PrintFormat("> Error: closing position ticket #%I64u on %s failed. Retcode=%u (%s)",position.Ticket(),position.Symbol(),trade.ResultRetcode(),trade.ResultComment()); result = false; } } if(result) break; Sleep(1000); PlaySound("timeout.wav"); } } //+------------------------------------------------------------------+
You might take a look at the full implementation of my 'close_all' script on codebase.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hi there community,
There's a problem on closing several positions from the pool by FIFO rule with this code.
It seems to be working ok on EAs through the strategy tester, even throwing better results than LIFO close, but for some reason it's not working fine on live trading.
Made the code as simple as possible, these are the lines:
What it does
- Loop forward from the first position index.
- If done, count back again to the new first position index.
What's the flaw/problem: at some point the algorithm can't count back to the new first position index and it just stops leaving open positions once a target is reached.
----
Would be glad if someone can shred some light on this matter.