CPositionInfo Problem

 

Hello,

i have a problem with CPositionInfo:

It seems that after on OnTradeTransaction event type=...ORDER_ADD

CPositionInfo.Select(transaction.Symbol) sometimes provides

volume BEFORE this fill and sometime INCLUDING the fill of this transaction. 


 

You can't rely on it.

Has anyone the same problem ? 

How to evade ?

Thank you 

 

Hello,

Can you provide a snippet of code to reproduce your issue ?

 
yes. but give me some time please.
 
chinaski:
yes. but give me some time please.
Sure :-)
 
#include <Trade\PositionInfo.mqh>

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Trade function                                                   |
//+------------------------------------------------------------------+
void OnTrade()
  {
//---
   
  }
  
bool order_is_pending(int otype)
{
   if(otype == ORDER_TYPE_BUY_LIMIT ||
        otype == ORDER_TYPE_SELL_LIMIT ||
        otype == ORDER_TYPE_BUY_STOP ||
        otype == ORDER_TYPE_SELL_STOP ||
        otype == ORDER_TYPE_BUY_STOP_LIMIT ||
        otype == ORDER_TYPE_SELL_STOP_LIMIT)
        return true;
    return false;
}  
bool transaction_type_matching(int ttype,int otype)
{
    bool pending=order_is_pending(otype);
    if( (ttype == (int) TRADE_TRANSACTION_ORDER_ADD && pending == false) ||
        //(ttype == (int) TRADE_TRANSACTION_HISTORY_ADD && pending == false) ||
        (ttype == (int) TRADE_TRANSACTION_ORDER_DELETE && pending == true) ||
        (ttype == (int) TRADE_TRANSACTION_ORDER_UPDATE && pending == true) ||
        ttype == (int) TRADE_TRANSACTION_POSITION) /// change stop and/or loss for exisiting position
        return true;
    return false;
}
bool deal_type_matching(int dtype)
{
   if(dtype == DEAL_TYPE_BUY ||
        dtype == DEAL_TYPE_SELL ||
        dtype == DEAL_TYPE_BUY_CANCELED ||
        dtype == DEAL_TYPE_SELL_CANCELED)
        return true;
    return false;
}  
string dump_MqlTradeTransaction(const MqlTradeTransaction& t)
{
    //CDealInfo deal;
    //deal.Ticket(t.deal);
   if(t.deal > 0)
      HistoryDealSelect(t.deal);
   string msg=StringFormat("symbol=%s price=%.7f volume=%.2f sl=%.7f tp=%.7f order=%d deal=%d entry-type=%s trans-type=%s order_type=%s deal_type=%s type_time=%d expiration=%s price_trigger=%.7f profit=%.2f order-open=%.6f order-current=%.6f deal-price=%.6f"
                           
                           ,t.symbol
                           ,t.price
                           ,t.volume                           
                           ,t.price_sl
                           ,t.price_tp
                           ,t.order
                           ,t.deal           
                                                   ,EnumToString((ENUM_DEAL_ENTRY)HistoryDealGetInteger(t.deal,DEAL_ENTRY))                                          
                           ,EnumToString((ENUM_TRADE_TRANSACTION_TYPE) t.type)
                           ,EnumToString(t.order_type)
                           ,EnumToString(t.deal_type)
                           ,t.time_type
                           ,TimeToString(t.time_expiration)                           
                           ,t.price_trigger
                           ,HistoryDealGetDouble(t.deal,DEAL_PROFIT)
                                                        ,HistoryOrderGetDouble(t.order,ORDER_PRICE_OPEN)
                                                        ,HistoryOrderGetDouble(t.order,ORDER_PRICE_CURRENT)
                                                        ,HistoryDealGetDouble(t.order,DEAL_PRICE)
                           );
                        
    return msg;
}
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
{

    if(transaction_type_matching(trans.type,trans.order_type) == true && deal_type_matching(trans.deal_type) == true)   
    {
        double volume=0.0;
                CPositionInfo pi;
                if(pi.Select(trans.symbol) == true)
                        volume=pi.Volume();
                PrintFormat("position with latest transaction=%.2f",volume);
                Print(dump_MqlTradeTransaction(trans));
                
    }
}
//+------------------------------------------------------------------+
 

Just do some runs with enter and closing market.

Sooner or later it will either show current volume including ORDER_ADD or excluding (in particular in debug mode) 

 

I think i possibly have the solution.

In terms of what can change a position, i should wait for server confirmation.

So listen to TRADE_TRANSACTION_DEAL_ADD instead of TRADE_TRANSACTION_ORDER_ADD.

At least, in my latest runs it worked. 

 

Definetly TRADE_TRANSACTION_DEAL_ADD means that actual positions are returned by CPositionInfo.

where TRADE_TRANSACTION_ORDER_ADD can mean that actual positions are returned by CPositionInfo buy you can't be sure.

So a missunderstanding of  TRADE_TRANSACTION_ORDER_ADD event on my side.

Reason: