CTrade::Buy() - different behavior on Demo and Live account

 

I developed an EA, did the back-testing and optimization and ran it for a while on a demo account. All nice and dandy. But when I started it today on a live account, strange things happened. My buy positions where closed immediately. After some digging I realized, that after opening a position with CTrade::Buy() or CTrade::Sell(), and asking for the price, at which the position was now actually opened, the return value was always 0.0.

I use CTrade::Buy() and Sell() without specifying the price, only volume and symbol are specified. According to the documentation the current ask/bid prices will be used at execution time. I then use CTrade::RequestPrice() to ask for the price, at which the position was opened. I store the returned value to calculate the break-even and take-profit points, as I do some cost averaging over multiple positions. On the demo accounts this worked fine, but on the live account CTrade::RequestPrice() returns 0.0.

To dig into the problem I wrote a simple test program.

#include <Trade\Trade.mqh>

CTrade Trade;

input int BuyOrSell;


bool PositionHasBeenOpened = false;
ulong LastBar, CurrentBar;

//+------------------------------------------------------------------+
int OnInit()
{
  Print("Test opening and closing position");
  Print("Symbol = ", Symbol(), " Timeframe = ", EnumToString(PERIOD_CURRENT));

  LastBar = Bars(Symbol(), PERIOD_CURRENT);

  Trade.LogLevel(LOG_LEVEL_ALL);

  return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}


//+------------------------------------------------------------------+
void OnTick()
{
// check if new bar
  CurrentBar = Bars(_Symbol, PERIOD_CURRENT);
  if (CurrentBar == LastBar) {
    return;
  }

  LastBar = CurrentBar;

  if (!PositionHasBeenOpened) {
    OpenPosition();                                                     // 1 for buy, -1 for sell
    PositionHasBeenOpened = true;
  }
}



//+------------------------------------------------------------------+
void OpenPosition()
{
  Print( "Open position with CTrade" );
  
  if (BuyOrSell == 1)
          bool Result = Trade.Buy(0.01, Symbol(), 0.0, 0.0, 0.0, "CTrade.Buy()");
        if (BuyOrSell == -1 )
          bool Result = Trade.Sell(0.01, Symbol(), 0.0, 0.0, 0.0, "CTrade.Sell()");

  Print( "The request:" );
  Trade.PrintRequest();

  Print( "The result:" );
  Trade.PrintResult();

  Print( "Request Action: ", EnumToString(Trade.RequestAction()), " - ", Trade.RequestActionDescription());
  Print( "Result Code:    ", Trade.ResultRetcode(), " - ", Trade.ResultRetcodeDescription());

  Print( "Request Volume: ", Trade.RequestVolume());
  Print( "Result Volume:  ", Trade.ResultVolume());

  Print( "Request Price: ", Trade.RequestPrice());
  Print( "Result Price:  ", Trade.ResultPrice());

  Print( "Deal ticket  = ", Trade.ResultDeal() );
  Print( "Order ticket = ", Trade.ResultOrder() );

  int NumberOfPositions = PositionsTotal();
  Print( "Number of open positions = ", NumberOfPositions );

//--- get the ticket of the latest position
  ulong Ticket = PositionGetTicket( NumberOfPositions - 1 );
  Print( "Position ticket = ", Ticket);

}

When I run this on a demo account and on a live account I get the output in the Experts and Journal tabs shown in the attached file CTrade_Buy.png below (sorry, couldn't figure out how to embed an image into the text).

What can be seen in the highlighted lines is that on the live account CTrade::ResultPrice() returns 0.0, but not in the demo account. Also, in the live account the deal ticket number is 0.

Any information on what I am doing wrong is appreciated.

 
Stephan.Vogel:

CTrade::ResultPrice() returns 0.0

the deal ticket number is 0.

Any information on what I am doing wrong is appreciated.

There is a lot of information on this topic on the forum. Use the search.

 
fxsaber #:

There is a lot of information on this topic on the forum. Use the search.

Hi fxsaber! Of course did I search, both the forum and also in the web. I tried different queries and found a few postings where people reported on problems with CTrade functions, but nothing which related to the problem I described.

I should have mentioned that the position is opened in the live account just as it is opened in the demo account at the current price. As you can see in my code, I do check for the error, and the error code is 10009, i.e. no error. The difference is in the information reported back. While the position, e.g. EURUSD is opened at price 1.16398, the entry in the log is: CTrade::OrderSend: market buy 0.01 EURUSD.s [done at 0.00000]. 

In further experiments I could verify that when I use 

ulong OrderTicket = Trade.ResultOrder();

Position.SelectByTicket(OrderTicket);

double PriceOpen = Position.PriceOpen();

I do get the correct price, whereas CTrade::ResultPrice() returned 0.0.


All very strange!

 
Stephan.Vogel #:

I do get the correct price, whereas CTrade::ResultPrice() returned 0.0.

Find a demo account with the same behavior. Then you can figure out the problem for free.
 
CTrade::RequestPrice() is the price you asked for in the order request. For a market order where you do not set price , that field is 0. On some demo servers it may get filled, but you cannot rely on it.
 
Stephan.Vogel #:

Hi fxsaber! Of course did I search, both the forum and also in the web. I tried different queries and found a few postings where people reported on problems with CTrade functions, but nothing which related to the problem I described.

I should have mentioned that the position is opened in the live account just as it is opened in the demo account at the current price. As you can see in my code, I do check for the error, and the error code is 10009, i.e. no error. The difference is in the information reported back. While the position, e.g. EURUSD is opened at price 1.16398, the entry in the log is: CTrade::OrderSend: market buy 0.01 EURUSD.s [done at 0.00000]. 

In further experiments I could verify that when I use 

ulong OrderTicket = Trade.ResultOrder();

Positio PriceOpen = Position.PriceOpen();

I do get the correct price, whereas CTrade::ResultPrice() returned 0.0.


All very strange!

On demo account the execution is instant, on live account it is not. That is why the deal / position is not ready instantly and you can not get the resultprice.

You need to wait until the position can be selected by the order ticket. 

 
Laszlo Tormasi #:

On demo account the execution is instant, on live account it is not. That is why the deal / position is not ready instantly and you can not get the resultprice.

You need to wait until the position can be selected by the order ticket. 

Thank you Laszlo! I added now a loop to wait for an increment in the count of positions with a Sleep(10) command, and then also check if the magic number is correct. I was also able to get this behavior on the demo account by setting CTrade::SetAsyncMode(true), which should be useful for more realistic testing during further development of the program.

 
fxsaber #:
Find a demo account with the same behavior. Then you can figure out the problem for free.

Hi fxsaber, please don't waste your time with such useless comments. I see that you posted quite a number of informative articles. This is where you can put your time to much better use.

 
Stephan.Vogel #:

Hi fxsaber, please don't waste your time with such useless comments. I see that you posted quite a number of informative articles. This is where you can put your time to much better use.

There are demo accounts that reproduce this situation. And there were discussions about this, including the names of trading servers.

In particular, I myself once experimented a lot on such accounts to figure it out.

I won't interfere.