Pyramiding in MT5 and open price of positions (solved)

 

Good Morning!

Here I go again today =P I am porting an MT4 Ea which uses pyramiding and I am re-arranging the code because MT5 only supports one opened position. So, my EA opens several positions in the same direction increasing the total lotsize with more or less the desired effect. My problem comes finding out which was the open price of the last trade, as PositionGetDouble(PRICE_OPEN) returns the averaged price for all trades, instead of the open price of the last trade, which I need to calculate the next pyramid level. 

So I need the open price of the last order since it does not match the position open price (just the first trade does).

I've tried to iterate orders with no result. Could you be kind enough to point me in the right direction?

Thanks in advance!

double LastOrderOpen(ENUM_ORDER_TYPE Type, string COMM)
{
   uint total = OrdersTotal();
   ulong ticket = 0;
   for(uint i = 0; i < total; i++)
   {
      if((ticket=OrderGetTicket(i))>0)
      {
         // Properties
         string comment     = OrderGetString(ORDER_COMMENT);
         double open_price  = OrderGetDouble(ORDER_PRICE_OPEN);
         int order_magic    = (int) OrderGetInteger(ORDER_MAGIC);
         ENUM_ORDER_TYPE type = (ENUM_ORDER_TYPE) OrderGetInteger(ORDER_TYPE);
         
         // Check
         if(comment == COMM && order_magic >= MagicNumber && type == Type)
            return(open_price);
     }
  }
  return(0);
}
 
PzTrading:

Good Morning!

Here I go again today =P I am porting an MT4 Ea which uses pyramiding and I am re-arranging the code because MT5 only supports one opened position. So, my EA opens several positions in the same direction increasing the total lotsize with more or less the desired effect. My problem comes finding out which was the open price of the last trade, as PositionGetDouble(PRICE_OPEN) returns the averaged price for all trades, instead of the open price of the last trade, which I need to calculate the next pyramid level. 

So I need the open price of the last order since it does not match the position open price (just the first trade does).

I've tried to iterate orders with no result. Could you be kind enough to point me in the right direction?

Thanks in advance!

Shouldn't you be looking at the deals ?

https://www.mql5.com/en/articles/211 

Orders, Positions and Deals in MetaTrader 5
Orders, Positions and Deals in MetaTrader 5
  • 2011.02.01
  • MetaQuotes Software Corp.
  • www.mql5.com
Creating a robust trading robot cannot be done without an understanding of the mechanisms of the MetaTrader 5 trading system. The client terminal receives the information about the positions, orders, and deals from the trading server. To handle this data properly using the MQL5, it's necessary to have a good understanding of the interaction between the MQL5-program and the client terminal.
 
PzTrading:

Good Morning!

Here I go again today =P I am porting an MT4 Ea which uses pyramiding and I am re-arranging the code because MT5 only supports one opened position. So, my EA opens several positions in the same direction increasing the total lotsize with more or less the desired effect. My problem comes finding out which was the open price of the last trade, as PositionGetDouble(PRICE_OPEN) returns the averaged price for all trades, instead of the open price of the last trade, which I need to calculate the next pyramid level. 

So I need the open price of the last order since it does not match the position open price (just the first trade does).

I've tried to iterate orders with no result. Could you be kind enough to point me in the right direction?

Thanks in advance!

The same principle applies that for profit : Obtain profit from last closed deal (closed).

In my opinion, it's not a good practice to rely on comment to manage orders/deals.

 
angevoyageur:

In my opinion, it's not a good practice to rely on comment to manage orders/deals.

I agree with you, but in this case the EA trades two different strategies pyramided differently, so I store the strategy name into the comment and the amount of piramided trades as a modulus of the magic number. Thanks to RaptorUK, I obtained the open price of the last pyramided trade for any give position like follows.

double LastOpenPriceOfPosition(long position_id, ENUM_POSITION_TYPE Type)
{
   double price = 0;
   if(HistorySelectByPosition(position_id))
   {
      int total = HistoryDealsTotal();
      for(int i = 0; i < total; i++)
      {
         ulong DealTicket = HistoryDealGetTicket(i);
         double dp = HistoryDealGetDouble(DealTicket, DEAL_PRICE);
         if(price == 0) price = dp;
         if(Type == POSITION_TYPE_BUY) price = MathMax(dp, price);
         if(Type == POSITION_TYPE_SELL) price = MathMin(dp, price);
      }
   }
   return(price);
}

Thanks for the tips! Now I understand better the difference between position, orders and deals coming from MT4.

Documentation on MQL5: Standard Constants, Enumerations and Structures / Indicator Constants / Price Constants
Documentation on MQL5: Standard Constants, Enumerations and Structures / Indicator Constants / Price Constants
  • www.mql5.com
Standard Constants, Enumerations and Structures / Indicator Constants / Price Constants - Documentation on MQL5
 
PzTrading:

I agree with you, but in this case the EA trades two different strategies pyramided differently. Thanks to RaptorUK, I solved it like this.

Thanks for the tips! Now I understand better the difference between position, orders and deals coming from MT4.

Good for you

I draw your attention to the fact that 1 order may result in several deals. It's probably uncommon for Forex, but I already saw it.

EDIT: If you trade 2 strategies in 1 EA, why not use 2 different magic number ? It's more reliable than comments.

 
angevoyageur:

Good for you

I draw your attention to the fact that 1 order may result in several deals. It's probably uncommon for Forex, but I already saw it.

EDIT: If you trade 2 strategies in 1 EA, why not use 2 different magic number ? It's more reliable than comments.

Thanks for the tip. Because I have to store in the magic number the amount of pyramided trades LOL. The comment holds the strategy.
 
PzTrading:
Thanks for the tip. Because I have to store in the magic number the amount of pyramided trades LOL. The comment holds the strategy.
I'm sure you can encode all that information in the Magic Number . . .  it's a long so goes up to 9 223 372 036 854 775 807
 
RaptorUK:
I'm sure you can encode all that information in the Magic Number . . .  it's a long so goes up to 9 223 372 036 854 775 807

Sure. See this article (a bit overcomplicated but it gives the idea).

EDIT : Anyway magic is an ulong (not long), so it can be up to 18 446 744 073 709 551 615.

 
angevoyageur:

Sure. See this article (a bit overcomplicated but it gives the idea).

EDIT : Anyway magic is an ulong (not long), so it can be up to 18 446 744 073 709 551 615.

I was going by this . . . https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties  it says long,  but yes I see that the MqlTradeRequest structure says ulong for magic . . . in any case,  there is plenty to play with.
Documentation on MQL5: Standard Constants, Enumerations and Structures / Trade Constants / Order Properties
Documentation on MQL5: Standard Constants, Enumerations and Structures / Trade Constants / Order Properties
  • www.mql5.com
Standard Constants, Enumerations and Structures / Trade Constants / Order Properties - Documentation on MQL5
 
RaptorUK:
I was going by this . . . https://www.mql5.com/en/docs/constants/tradingconstants/orderproperties  it says long,  but yes I see that the MqlTradeRequest structure says ulong for magic . . . in any case,  there is plenty to play with.

Oh, you are right, I will check and report this to ServiceDesk eventually.7

EDIT: The problem is that OrderGetInteger(), HistoryOrderGetInteger(), HistoryDealGetInteger, PositionGetInteger return a long, so we have to typecast the result to ulong. Otherwise if magic is > to 9 223 372 036 854 775 807, we get a negative number. For example :

(ulong)HistoryDealGetInteger(deal, DEAL_MAGIC);


Reason: