Start time lag when using TimeCurrent or market watch feed

 

Hi guys, basically i have built a simple ea that only trades at the start times i specify, sometimes it works well and other times i think theres lag because the time on the market watch is slow, its slow to kick it. 

I have tried to change the time from currentbartime to TimeLocal and then add in a seconds function as i would like to have the option to input seconds. Now i have posted a copy of the original ea and then a copy of the version

i tried to edit just adding pieces of mql4 reference. I think i have completely wrecked it now. So in short i want it to use TimeLocal to help prevent lag instead of waiting for a new tick to come in. 

Example start time 10:29:57 instead of currently i can only go 10:30 and then if no tick comes straight away it lags and i miss price movement. Im only fresh when it comes to programming, but any advice would be helpful guys!!

Thanks 

#define __STRATEGY_MAGIC 1001000000
#define __SLEEP_AFTER_EXECUTION_FAIL 400
//Input variables
input string  Time_Settings = "Input start time *GMT settings apply";
input double _Start_Hour = 0;                   // Start Hour
input double _Start_Minute = 0;                 // Start Minute
input double _End_Hour = 0;                     // End Hour
input double _End_Minute = 0;                   // End Minute

input string  Trade_Size = "Input lot sizes *Buy must = sell";
input double _Lot_Size_Buy = 0;                 // Lot Size Buy
input double _Lot_Size_Sell = 0;                        // Lot Size Sell

input string  Trade_Management = "Input values for trade management *Value in pips";
input double _Stop_Loss_Buy = 0;                        // Stop Loss Buy
input double _Stop_Loss_Sell = 0;                       // Stop Loss Sell
input double _Take_Profit_Buy = 0;                      // Take Profit Buy
input double _Take_Profit_Sell = 0;                     // Take Profit Sell

input string  Trailing_Stop_Management = "Input values for trail stop & adjustment points *Value in pips";
input double _Trailing_Stop_Buy = 0;                    // Trailing Stop Buy
input double _Trailing_Stop_Sell = 0;                   // Trailing Stop Sell
input double _Step_Value_Buy = 0;                       // Step Value Buy
input double _Step_Value_Sell = 0;                      // Step Value Sell

input string  Volatility_Settings = "Input settings for volatile events *Value in pips";
input int _Above_Buy_Entry_Value = 0;                   // Above Buy Entry Value
input int _Below_Sell_Entry_Value = 0;                  // Below Sell Entry Value

input string Current_Bar_Shift = "Input 0 for manual place of orders or 1 for automatic";
input int _Shift_Back_Buy = 0;                  // Shift Back Buy
input int _Shift_Back_Sell = 0;                 // Shift Back Sell


//Global declaration
bool _New_bar;
bool _AND_3;
bool _And_Alert;

int init() {

   return(0);
}

int start() {

   
   //Local declaration
   bool _Simple_Trailing_Buy = false;
   bool _Simple_Trailing_Sell = false;
   bool _Delete_Pending_2 = false;
   bool _Delete_Pending = false;
   bool _Sell_Stop_Pending = false;
   bool _Buy_Stop_Pending = false;
   _Simple_Trailing_Buy = Simple_Trailing_Stop(1, 0, _Trailing_Stop_Buy, _Step_Value_Buy);
   _New_bar = __isNewBar(true);
   _Simple_Trailing_Sell = Simple_Trailing_Stop(2, 0, _Trailing_Stop_Sell, _Step_Value_Sell);
   if( false ) Alert( "" );
   _AND_3 = (IsTime(_Start_Hour, _End_Hour, _Start_Minute, _End_Minute));
   if( _New_bar ) {
      _Delete_Pending_2 = __isPending( 1, Symbol() );
      if( _Delete_Pending_2 ) {
         int ticket = OrderTicket();
         _Delete_Pending_2 = OrderDelete(ticket);
      }
   }
   if( _New_bar ) {
      _Delete_Pending = __isPending( 2, Symbol() );
      if( _Delete_Pending ) {
         int ticket = OrderTicket();
         _Delete_Pending = OrderDelete(ticket);
      }
   }
   if( _AND_3 && !__isExist( 2, Symbol() ) ) {
      _Sell_Stop_Pending = _Lot_Size_Sell >= MarketInfo( Symbol() ,MODE_MINLOT);
      if( _Sell_Stop_Pending == true ) _Sell_Stop_Pending = OrderSend( Symbol(), 5, _Lot_Size_Sell, NormalizeDouble( (iLow(Symbol(), 0, _Shift_Back_Sell) -
    (Transform(_Below_Sell_Entry_Value, 2))), (int)MarketInfo( Symbol(), MODE_DIGITS ) ), 0, __stopLossValue( Symbol(), 5, (iLow(Symbol(), 0, _Shift_Back_Sell) -
    (Transform(_Below_Sell_Entry_Value, 2))), _Stop_Loss_Sell ), __takeProfitValue( Symbol(), 5, (iLow(Symbol(), 0, _Shift_Back_Sell) -
    (Transform(_Below_Sell_Entry_Value, 2))), _Take_Profit_Sell ), "CtCapitalFx" + "(" + WindowExpertName() + ") " + "", __STRATEGY_MAGIC + 2, D'1970.01.01 00:00:00' ) >= 0;
      if( _Sell_Stop_Pending == false ) Sleep(__SLEEP_AFTER_EXECUTION_FAIL); 
   }
   if( _AND_3 && !__isExist( 1, Symbol() ) ) {
      _Buy_Stop_Pending = _Lot_Size_Buy >= MarketInfo( Symbol() ,MODE_MINLOT);
      if( _Buy_Stop_Pending == true ) _Buy_Stop_Pending = OrderSend( Symbol(), 4, _Lot_Size_Buy, NormalizeDouble( (iHigh(Symbol(), 0, _Shift_Back_Buy) +
    (Transform(_Above_Buy_Entry_Value, 2))), (int)MarketInfo( Symbol(), MODE_DIGITS ) ), 0, __stopLossValue( Symbol(), 4, (iHigh(Symbol(), 0, _Shift_Back_Buy) +
    (Transform(_Above_Buy_Entry_Value, 2))), _Stop_Loss_Buy ), __takeProfitValue( Symbol(), 4, (iHigh(Symbol(), 0, _Shift_Back_Buy) +
    (Transform(_Above_Buy_Entry_Value, 2))), _Take_Profit_Buy ), "CtCapitalFx" + "(" + WindowExpertName() + ") " + "", __STRATEGY_MAGIC + 1, D'1970.01.01 00:00:00' ) >= 0;
      if( _Buy_Stop_Pending == false ) Sleep(__SLEEP_AFTER_EXECUTION_FAIL); 
   }
   if( _Buy_Stop_Pending ) Print("Last Error: ",ErrorDescription(GetLastError()));
   if( _Sell_Stop_Pending ) Print("Last Error: ",ErrorDescription(GetLastError()));
   _And_Alert = (_Sell_Stop_Pending && 
   _Buy_Stop_Pending);
   if( _And_Alert ) Alert( "" );

   return(0);
}



bool __selectOrderByMagic(int magic, string symbol)
{
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == __STRATEGY_MAGIC + magic && OrderSymbol() == symbol)
         return(true);
   }
   return(false);
}



bool __isExist(int magic, string symbol)
{
   return(__selectOrderByMagic(magic, symbol));
}



double __takeProfitValue(string symbol,int orderType, double price, double points)
{
   if (points == 0)
      return (0);
   else if (orderType == 0 || orderType == 2 || orderType == 4)
      return ( NormalizeDouble( price + MarketInfo( symbol, MODE_POINT ) * points, (int)MarketInfo( symbol, MODE_DIGITS ) ) );
   else 
      return ( NormalizeDouble( price - MarketInfo( symbol, MODE_POINT ) * points, (int)MarketInfo( symbol, MODE_DIGITS ) ) );
}



double __stopLossValue(string symbol, int orderType, double price, double points)
{
   if (points == 0)
      return (0);
   else if (orderType == 0 || orderType == 2 || orderType == 4)
      return ( NormalizeDouble( price - MarketInfo( symbol, MODE_POINT ) * points, (int)MarketInfo( symbol, MODE_DIGITS ) ) );
   else 
      return ( NormalizeDouble( price + MarketInfo( symbol, MODE_POINT ) * points, (int)MarketInfo( symbol, MODE_DIGITS ) ) );
}


#include "../include/stdlib.mqh";


datetime __currentBarTime;
bool __isNewBar(bool triggerAtStart)
{
   datetime newTime = Time[0];
   if (__currentBarTime != newTime) {
      if (!triggerAtStart && __currentBarTime == 0) {
         __currentBarTime = newTime;
         return false;   
      }
      __currentBarTime = newTime;
      return true;
   }
   return false;
}



bool __isPending(int magic, string symbol)
{
   if(!__selectOrderByMagic(magic, symbol))
      return(false);
   return(OrderType()==OP_BUYLIMIT || OrderType()==OP_BUYSTOP || OrderType()== OP_SELLLIMIT || OrderType()== OP_SELLSTOP);
}



int __Ticket(int magic, string symbol)
{   
   if(!__selectOrderByMagic(magic, symbol))
      return(0);
   return(OrderTicket());
}



bool Simple_Trailing_Stop(int MagicIndex, int WaitForProfit, int TrailingStopPoints, int MinAdjustmentPoints)
{   
   double pnlPoints=0;   
   double price, sl, tp;
   double point = MarketInfo(Symbol(),MODE_POINT);
   int stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL) + MarketInfo(Symbol(),MODE_SPREAD));  
   int cmd; 
      
   bool result = true;   
   double newSl;

   int total = OrdersTotal();
      for(int i=total-1;i>=0;i--){
      if (!OrderSelect(i, SELECT_BY_POS)) continue;
      if(OrderMagicNumber() != __STRATEGY_MAGIC + MagicIndex || OrderSymbol() != Symbol()) continue;
      
      cmd = OrderType();      
      sl = NormalizeDouble(OrderStopLoss(),Digits);
      tp = OrderTakeProfit();
       
      if (OrderType() == OP_BUY)
      {
         price = MarketInfo(Symbol(),MODE_BID);
         newSl = NormalizeDouble(price - TrailingStopPoints * point, Digits);    
         if(((tp - price)/point) < stopLevel && tp != 0) continue;         
         if(((price - newSl)/point) < stopLevel)continue; 
         if(WaitForProfit == 0)
         {        
            pnlPoints = (price - OrderOpenPrice())/point; 
            if (pnlPoints < TrailingStopPoints ) continue;  
         }        
         if (sl + MinAdjustmentPoints*point>= newSl) continue;       
         
         if(!OrderModify(OrderTicket(), OrderOpenPrice(), newSl, tp, 0))
         {
            printf("Error: Failed to modify trade. Ticket #%i, error code: %i", OrderTicket(), GetLastError());
            result = false;
            Sleep(__SLEEP_AFTER_EXECUTION_FAIL);
         }
      }  
      else if (OrderType() == OP_SELL)
      {
         price = MarketInfo(Symbol(),MODE_ASK);
         newSl = NormalizeDouble(price+ TrailingStopPoints * point, Digits);
         if(((price - tp)/point) < stopLevel) continue;
         if(((newSl - price)/point) < stopLevel) continue;
         if(WaitForProfit == 0)
         {              
            pnlPoints = (OrderOpenPrice() - price)/point;
            if (pnlPoints < TrailingStopPoints) continue; 
         }         
         if (sl - MinAdjustmentPoints*point <= newSl && sl != 0) continue;
         
         if(!OrderModify(OrderTicket(), OrderOpenPrice(), newSl, tp, 0))
         {
            printf("Error: Failed to modify trade. Ticket #%i, error code: %i", OrderTicket(), GetLastError());
            result = false;
            Sleep(__SLEEP_AFTER_EXECUTION_FAIL);
         }         
       }      
   }   
   return(result);
}


double Transform (double Value, int Transformation)
{
   static double pipSize = 0;   
   if(pipSize == 0) pipSize = Point * (1 + 9 * (Digits == 3 || Digits == 5));

   switch(Transformation)
   { 
      case 0: return(Value/Point);
      case 1: return(Value/pipSize);
      case 2: return(Value*Point);
      case 3: return(Value*pipSize);  
      default: return(0);    
   }
}


bool IsTime (int startHour, int endHour, int startMinute, int endMinute)
{
   if (startHour < 0 || startHour > 23 || endHour < 0 || endHour > 23 ||
       startMinute < 0 || startMinute > 59 || endMinute < 0 || endMinute > 59)
       return false;
   
   int startTime = startHour*60 + startMinute;
   int endTime = endHour*60 + endMinute;
   int time = Hour()*60 + Minute();
   
   if (startTime < endTime)
      return (time >= startTime && time <= endTime);
   else if (startTime > endTime)
      return (time >= startTime || time <= endTime);
   else
      return (time == startTime);
}
 

The first code is the original and the second one is the one i tried to tamper with i changed TimeCurrent to TimeLocal and tried to add some seconds functions in there, but now the expert trades at really random times as if the calculations are incorrect or something maybe. 


Thank you 

 
CtCapitalFx:

Hi guys, basically i have built a simple ea that only trades at the start times i specify, sometimes it works well and other times i think theres lag because the time on the market watch is slow, its slow to kick it. 

I have tried to change the time from currentbartime to TimeLocal and then add in a seconds function as i would like to have the option to input seconds. Now i have posted a copy of the original ea and then a copy of the version

i tried to edit just adding pieces of mql4 reference. I think i have completely wrecked it now. So in short i want it to use TimeLocal to help prevent lag instead of waiting for a new tick to come in. 

Example start time 10:29:57 instead of currently i can only go 10:30 and then if no tick comes straight away it lags and i miss price movement. Im only fresh when it comes to programming, but any advice would be helpful guys!!

Thanks 


It does not lag.

start() function is executed when new tick arrives - meaning market price changed. 

That can happen several times per second, but it also can have longer gaps (seconds, even minutes when the market is slow).

If you want to execute your orders at the exact time, you have to use timer and OnTimer() function. 


You might want to replace old function calls (init(), start()) with new ones (OnInit(), OnTick()). Old ones are obsoleted three years ago. 

 
CtCapitalFx: So in short i want it to use TimeLocal to help prevent lag instead of waiting for a new tick to come in.
  1. If there is no new tick, nothing has changed. Why didn't you do it last tick? If nothing has changed, why are you going to do something now?

  2. There can be minutes between ticks during the Asian session. "Free-of-Holes" Charts - MQL4 Articles
    No candle if open = close ? - MQL4 and MetaTrader 4 - MQL4 programming forum

  3. Start using the new Event Handling Functions Event Handling Functions - Functions - Language Basics - MQL4 Reference

  4. newSl = NormalizeDouble(price - TrailingStopPoints * point, Digits);
    Do NOT use NormalizeDouble, EVER. For ANY Reason. It's a kludge, don't use it. It's use is always wrong

  5. Code breaks on 4 digit brokers, exotics (e.g. USDZAR where spread is over 500 points,) and metals. Compute what a pip is and use it, not points. How to manage JPY pairs with parameters? - MQL4 and MetaTrader 4 - MQL4 programming forum

 

Thanks guys for your information


In regards to the old functions i take that into consideration and I'm now making those changes to the event handling functions as this ea was constructed using an ea builder more so then from scratch and I'm a clean skin when it comes to programming.


In regards to the normalizedouble area, it never seemed to have any issues with different pairs, it worked live on aususd, usdcad, usdjpy, and I've had several successful trades with gold.


Forgive me for my lack on knowledge but I'm confused at several parts of your response whroeder1, i understand where your coming from with the asian session and new incoming ticks hence why i thought maybe more of a strict timer function that i can include seconds would be much more appropriate instead of server time because by the time the new tick comes in (if delayed), the ea does the calculations and then places orders on the chart the price movement I'm trying to catch is already underway and then i get the error invalid stop or tp because my order could not be placed in time for the move or spike. This doesn't happen all the time only when there is a large volatile spike, but normal intraday price both orders are places, its more in times of NFP and such. 

 
CtCapitalFx:

this ea was constructed using an ea builder more so then from scratch and I'm a clean skin when it comes to programming.

In regards to the normalizedouble area, it never seemed to have any issues with different pairs,

the new tick comes in (if delayed), .. its more in times of NFP and such. 

    • We hate EA builder
    • You couldn't be bothered to learn mql4, therefor there is no common language for us to communicate.
    • There are only two choices: learn to code it, or pay someone. We're not going to code it FOR you. We are willing to HELP you when you post your attempt (using SRC) and the nature of your problem, but we are not going to debug your hundreds lines of code.
    • EA builder makes bad code counting up while closing multiple orders.
    • EA builder makes bad code Bars is unreliable (max bars on chart) volume is unreliable (miss ticks) Always use time. New candle - MQL4 forum
    • EA builder makes bad code Not adjusting for 4/5 digit brokers, TP/SL and slippage.
    • EA builder makes bad code not adjusting for ECN brokers.
    • EA builder makes bad code not checking return codes.
    • EATree uses objects on chart to save values - not persistent storage (files or GV+Flush.) No recovery (crash/reboot.)
  1. Just because you have seen the issues doesn't mean they don't exist. I told you why with links.
  2. Stop repeating that. You've been answered multiple times. There is no delay, even during NFP. If you want to trade that, spend the $million and get a co-located server. You can't do it over the internet and during news, it can take minutes to open a new order with most brokers.
 

This is basic Indicator skeleton with OnTimer() event handler:


#property version   "1.00"
#property strict
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Create 2 seconds timer
   EventSetTimer(2);   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   Print( "  ", __FUNCTION__, " TimeCurrent()=  ",  TimeCurrent(), "  TimeLocal()= ", TimeLocal());
  }
//+------------------------------------------------------------------+


Run this and check Experts tab log messages.

 

Im experimenting with the example you gave, by trying to create a code so for example if: time = 10:29 then: EventSetTimer (57) so theres a countdown before the ea can actually place orders. 


Thanks for your help 

 
Problem is solved, thanks for all your help 


@Drazen Penic 

@whroeder1