We have four positions:
Code:
//+------------------------------------------------------------------+ //| ProjectName | //| Copyright 2018, CompanyName | //| http://www.companyname.net | //+------------------------------------------------------------------+ /* barabashkakvn Trading engine 3.138 */ #include <Trade\PositionInfo.mqh> #include <Trade\Trade.mqh> //--- CPositionInfo m_position; // object of CPositionInfo class CTrade m_trade; // object of CTrade class #property version "1.00" //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { ulong old_ticket_buy = 0; ulong old_ticket_sell = 0; ulong young_ticket_buy = 0; ulong young_ticket_sell = 0; datetime old_time_buy = D'3000.12.31 00:00'; datetime old_time_sell = D'3000.12.31 00:00'; datetime young_time_buy = D'1970.01.01 00:00'; datetime young_time_sell = D'1970.01.01 00:00'; //--- for(int i=PositionsTotal()-1; i>=0; i--) if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties if(m_position.Symbol()==Symbol()) { datetime pos_time=m_position.Time(); if(m_position.PositionType()==POSITION_TYPE_BUY) { if(pos_time<old_time_buy) { old_time_buy=pos_time; old_ticket_buy=m_position.Ticket(); } if(pos_time>young_time_buy) { young_time_buy=pos_time; young_ticket_buy=m_position.Ticket(); } continue; } else if(m_position.PositionType()==POSITION_TYPE_SELL) { if(pos_time<old_time_sell) { old_time_sell=pos_time; old_ticket_sell=m_position.Ticket(); } if(pos_time>young_time_sell) { young_time_sell=pos_time; young_ticket_sell=m_position.Ticket(); } } } //--- old_ticket_buy -> young_ticket_sell if(old_ticket_buy>0 && young_ticket_sell>0) m_trade.PositionCloseBy(old_ticket_buy,young_ticket_sell); //--- old_ticket_sell -> young_ticket_buy if(old_ticket_sell>0 && young_ticket_buy>0) m_trade.PositionCloseBy(old_ticket_sell,young_ticket_buy); } //+------------------------------------------------------------------+
Result:
2020.08.18 21:48:43.516 Scripts script 1 (GBPUSD,H1) loaded successfully 2020.08.18 21:48:43.528 Trades '32113828': close position #686455741 buy 0.02 GBPUSD by position #686720600 sell 0.02 GBPUSD 2020.08.18 21:48:43.595 Trades '32113828': accepted close position #686455741 buy 0.02 GBPUSD by position #686720600 2020.08.18 21:48:43.614 Trades '32113828': deal #665327266 sell 0.02 GBPUSD at 1.32391 done (based on order #686721037) 2020.08.18 21:48:43.616 Trades '32113828': close position #686455741 buy 0.02 GBPUSD by position #686720600 done in 88.341 ms 2020.08.18 21:48:43.616 Trades '32113828': close position #686720589 sell 0.02 GBPUSD by position #686720571 buy 0.02 GBPUSD 2020.08.18 21:48:43.660 Trades '32113828': accepted close position #686720589 sell 0.02 GBPUSD by position #686720571 2020.08.18 21:48:43.662 Trades '32113828': deal #665327270 buy 0.02 GBPUSD at 1.32401 done (based on order #686721040) 2020.08.18 21:48:43.664 Trades '32113828': close position #686720589 sell 0.02 GBPUSD by position #686720571 done in 48.044 ms 2020.08.18 21:48:43.664 Scripts script 1 (GBPUSD,H1) removed
Finally used this code:
ulong iTicket=0; int OrdersCount=0; int BuyOrders=0,SellOrders=0; for(int i=0;i<PositionsTotal();i++){ iTicket=PositionGetTicket(i); if(PositionSelectByTicket(iTicket)&& PositionGetString(POSITION_SYMBOL)==SName){ if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY){BuyOrders++;} if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL){SellOrders++;} } }
//----------------------------------------- PositionCloseBy ---! for(int h=PositionsTotal()-1;h>=0;h--){ ulong hTicket=PositionGetTicket(h); if(PositionSelectByTicket(hTicket)&& PositionGetString(POSITION_SYMBOL)==SName){ OrdersCount++;if(OrdersCount>1){ if(!trade.PositionCloseBy(hTicket,iTicket)){ Print("PositionCloseBy error ",trade.ResultRetcode()); return; } } } }
Results comparison between Reversal Close&Open (1) and PositionCloseBy (2) before commissions:
The same curve with less profit, it seems to be some kind of problem with LotSizing.
Finally used this code:
Results comparison between Reversal Close&Open (1) and PositionCloseBy (2) before commissions:
The same curve with less profit, it seems to be some kind of problem with LotSizing.
To all,
When using closeby, ticket order doesn't matter. What does matter is you use some kind of recursion to cleanup all your flattened positions and this is vitally important because if/when you use different position sizes in the closeby it will spawn new positions of smaller sizes. The key is to constantly widdle them down until there is none left. If you're not re-scanning the position pool after each call to closeby then you will have bugs and you will miss positions, I guarantee it.
//+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool closeByAll(const string symbol) { CPositionInfo pos; for(int i=PositionsTotal()-1; i>=0; --i) { if(pos.SelectByIndex(i) && pos.Symbol() == symbol) { ENUM_POSITION_TYPE type1 = pos.PositionType(); ulong ticket1 = pos.Ticket(); for(int j=i-1; j>=0; --j) { if(pos.SelectByIndex(j) && pos.Symbol() == symbol && pos.PositionType() != type1) { CTrade trade; if(trade.PositionCloseBy(ticket1, pos.Ticket()) { return closeByAll(symbol); } return false; } } } } return true; }
To all,
When using closeby, order doesn't matter. What does matter is you use some kind of recursion to cleanup all your flattened positions and this is vitally important because if/when you use different position sizes in the closeby it will spawn new positions of smaller sizes. The key is to constantly widdle them down until there is none left. If you're not re-scanning the position pool after each call to closeby then you will have bugs and you will miss positions, I guarantee it.
Thank you for your reply. So you're closing a ticket by the same one?
ulong ticket1 = pos.Ticket(); for (int j=i-1; j>=0; --j) { if (pos.SelectByIndex(j) && pos.Symbol() == symbol && pos.PositionType() != type1) { CTrade trade; if (trade.PositionCloseBy(ticket1, pos.Ticket())
Thank you for your reply. So you're closing a ticket by the same one?
No. See code. Not the same.
No. See code. Not the same.
Oh, ok. Does this really save on commissions?
If you have opposing orders with a net flat position then of course, yes.
If you have opposing orders with a net flat position then of course, yes.
I tried to make your method (one loop inside another) in my way of coding, but doesn't properly work. These are the lines:
for(int i=0;i<PositionsTotal();i++){ ulong iTicket=PositionGetTicket(i); if(PositionSelectByTicket(iTicket)&& PositionGetString(POSITION_SYMBOL)==SName){ for(int j=PositionsTotal()-1;j>=0;j--){ ulong jTicket=PositionGetTicket(j); if(PositionSelectByTicket(jTicket)&& PositionGetString(POSITION_SYMBOL)==SName){ OrdersCount++;if(OrdersCount>1){ // <-- If there are two positions they are opposite. if(!trade.PositionCloseBy(jTicket,iTicket)){ Print("PositionCloseBy error ",trade.ResultRetcode()); return; } } } } } }
Return: PositionCloseBy error 0.
I tried to make your method ( one loop inside another ) in my way of coding, but doesn't properly work. These are the lines:
A nested loop is dangerous and wrong.
You need to do one cycle: during the cycle, find opposite positions and memorize their tickets. After the loop, just apply CloseBy.
I gave an example in a post #1 - this is a simple way. But you can make it even more complicated: search for positions by lot size, by opposite profit ...
- 2020.08.18
- www.mql5.com
- 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 due to my expert it's not getting profitable due to spend on commissions my question is the following: How to save on commissions by using PositionCloseBy?
Made a test by using this code but it's not working the same as the original version(less profit):
Hope someone can help on this topic, thank you in advance.