Trading daily close on daily timeframe

 

I'm trying to implement a strategy that trades on the daily timeframe based on the daily close. The problem, of course, is that the instant the daily candle closes, the market is closed. So I need to catch the next open (not necessarily NYC - in fact, don't want to wait on that).

It seems to me in theory that since OnTick() is triggered on the next available price change, that should work. But I end up getting some trades, and missing others. This is an example of what shows in the tester log, although other trades were made (these weren't retried).

IF      2       10:21:48.798    Core 01 2018.11.15 00:01:00   failed market buy 0.01 NDX100 sl: 1411.33 [Market closed]
GE      0       10:21:48.798    Core 01 2018.11.15 00:01:00   CTrade::OrderSend: market buy 0.01 NDX100 sl: 1411.33 [market closed]
GJ      2       10:21:48.798    Core 01 2018.11.20 00:01:00   failed market buy 0.01 NDX100 sl: 1691.64 [Market closed]
QQ      0       10:21:48.798    Core 01 2018.11.20 00:01:00   CTrade::OrderSend: market buy 0.01 NDX100 sl: 1691.64 [market closed]
KN      2       10:21:48.798    Core 01 2018.11.21 00:00:30   failed market buy 0.01 NDX100 sl: 1375.24 [Market closed]
MN      0       10:21:48.798    Core 01 2018.11.21 00:00:30   CTrade::OrderSend: market buy 0.01 NDX100 sl: 1375.24 [market closed]
FS      2       10:21:48.798    Core 01 2018.11.23 00:00:30   failed market buy 0.01 NDX100 sl: 1656.61 [Market closed]
LJ      0       10:21:48.798    Core 01 2018.11.23 00:00:30   CTrade::OrderSend: market buy 0.01 NDX100 sl: 1656.61 [market closed]

I don't want to have to try to code around knowing when the market opens are, because that doesn't port well between brokers, or even different asset classes. So I thought I'd use a timer and put in a timer loop:

void ExecuteBuyOrder()
{
   trade.SetExpertMagicNumber(MagicNumber);

   double stopLoss = ATRStopLossMultiplier > 0.0 ? atrValue * ATRStopLossMultiplier : 0.0;
   double buyPrice = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);

   int retryIntervalInSeconds = 60; // Retry every minute
   bool orderExecuted = false;

   while (!orderExecuted)
   {
      if (stopLoss > 0.0)
      {
         double stopLossPrice = NormalizeDouble(buyPrice - stopLoss, _Digits);
         if(trade.Buy(LotSize, NULL, 0, stopLossPrice, 0, "Buy signal (test order)"))
         {
            orderExecuted = true;
         }
      }
      else
      {
         if(trade.Buy(LotSize, NULL, 0, 0, 0, "Buy signal (test order)"))
         {
            orderExecuted = true;
         }
      }

      if (!orderExecuted)
      {
         Print("Order execution failed, will retry in ", retryIntervalInSeconds, " seconds.");
         Sleep(retryIntervalInSeconds * 1000); // Sleep for retry interval (milliseconds)
      }
   }

   Print("Buy order executed successfully.");
} 

Which seems to work in a single test (haven't checked rigorously), but it makes it not work in an optimization. The sleep function breaks it:

CI      2       10:35:52.945    Core 03 pass 2 tested with error "critical runtime error 512 in OnTester function (sleep function reaches end of test)" in 0:00:02.799
OE      2       10:35:53.221    Core 01 pass 0 tested with error "critical runtime error 512 in OnTester function (sleep function reaches end of test)" in 0:00:03.097
LP      2       10:35:53.227    Core 02 pass 1 tested with error "critical runtime error 512 in OnTester function (sleep function reaches end of test)" in 0:00:03.083
IS      2       10:35:53.232    Core 04 pass 3 tested with error "critical runtime error 512 in OnTester function (sleep function reaches end of test)" in 0:00:03.091

So, how am I supposed to trade the daily close?  Am I just missing something, or is my approach completely wrong?

P.S. My broker doesn't support market-on-open orders, so that approach won't work either.

 
OK - made some progress in at least figuring out what's going on. It looks like if you catch the last tick of the day, sometimes in just the execution time delay, the market closes. So in theory, it should be available on the next tick, I'm thinking.  So how do you queue it up to make sure it's executed on the next tick
 

You may check if market is closed before trying to open trade.

https://www.mql5.com/en/forum/373227
How to check 'Market is closed' befor opening a position? - My expert advisor is trying to open a position immediately at time 00.00, because the market is closed during Friday night and
How to check 'Market is closed' befor opening a position? - My expert advisor is trying to open a position immediately at time 00.00, because the market is closed during Friday night and
  • 2021.07.13
  • www.mql5.com
My expert advisor is trying to open a position immediately at time 00:00. I get 'market is closed' ( trade_retcode_market_closed , error code: 10018) message, because the trading is start only at time 00:01: how can i check in advance if it is possible to open a position
 

IMHO this is typical issue for auto trading. This issue usually is not spotted by developers, and EA loosing effeciency.

The problem occurs not only when ordering, but also when closing. If the positions requires closing at a specific time/condition, it obviously loses performance when not secured.


This is how I deal with it.


1. In the function responsible for creating the order, I check the result

void Buy(double paLotSize){

   Trade.Buy(paLotSize, _Symbol, NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK), _Digits), 0, 0);

   if(Trade.ResultRetcode() == TRADE_RETCODE_MARKET_CLOSED){
      BuyOrder.MarketClosed = true;
      BuyOrder.Lots = paLotSize; 
   }
   else{
      BuyOrder.MarketClosed = false;
   }
}

2. In On Tick I check the flags and repeat the order until it is completed. Most often, after a dozen or so ticks, the order is already created.

void OnTick(){
 
   if(SellPosition.MarketClosed || BuyPosition.MarketClosed) CloseAllPositions();
   if(BuyOrder.MarketClosed) Buy(BuyOrder.Lots);
   if(SellOrder.MarketClosed) Sell(SellOrder.Lots);

   ClosePositionsByProfit();

   if(!NewBar(inpTimeFrame)) return;

   CheckToOpen();
}

and simple structure for storing info

struct MarketClosed{
   bool MarketClosed;
   double Lots; 
};

MarketClosed SellOrder, BuyOrder, SellPosition, BuyPosition;