fxDreema

    • Register
    • Login
    • Search
    • Back to the main page
    • Categories
    • Recent
    • Tags
    • Popular
    • Search
    1. Home
    2. Archer
    3. Posts
    • Profile
    • Following 0
    • Followers 0
    • Topics 9
    • Posts 70
    • Best 8
    • Controversial 0
    • Groups 0

    Posts made by Archer

    • RE: News during Backtest

      Hi @roar,

      Have you considered whether there might be any upcoming updates to this indicator in the near future ?
      I'm particularly interested in even minor additions, such as event names on each vertical line.
      I'll highly value any progress made on this project.

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      @cmuphyfx

      sure, there you go:

      https://we.tl/t-v79ol3wENN

      @tec-nacks

      well... It's not functioning because you didn't follow my instructions.
      You've already made a mistake in the second block.
      It should be >=.

      I strongly suggest understanding the idea of this solution step by step first.
      Manually add a red vertical line to the chart to simulate upcoming news.
      Start moving it and observe how its value changes relative to the time values.
      Then, add another red line and see how the EA reacts to two news events that are close together. Check if the times overlap or if they're okay.
      Based on this, adjust the values in the EA.

      Also, decide whether the solution I mentioned earlier, skip ticks or on/off, works better for you.
      Perhaps combining them might be a better solution.
      Maybe separating them into tabs for on timer / on tick could be the right approach.
      It all depends on your needs and the structure of your EA.

      Regardless of your choice, always stick to the KISS principle that I follow myself and in the end, everything should work properly.

      Certainly, a bad idea is adding many additional conditions before understanding how the basic one works, which seems to be what you've done in the given project...

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      @tec-nacks
      I've already shared with you the indicators I personally use in one of my previous posts.
      Try them out first.
      An important element is setting the color of the vertical lines in the indicator to red, not something like 'C'217,83,79'.
      Otherwise, EA won't recognize the lines...

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      @roar

      I would help you out man, but despite some serious brainstorming over the past days, I haven't hit upon any great ideas worth sharing with you all.
      I'm hoping someone else in the forum might jump into this conversation and help us crack the DLS time problem.

      In the meantime, could you pls consider adding those options I mentioned earlier to the indicator?
      You know, the ones about filtering news using keywords and labeling news names for vertical lines.

      @tec-nacks

      Are you referring to backtesting or the live market?
      If it's backtesting, will those vertical lines show up on the chart during the test?
      If they do, could you show me a snippet of your project that handles news avoidance?
      Something might be off because everything seems to be working fine on my end...

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      @jstap said in News during Backtest:

      Isn't DLS time set by your broker (server time)? Meaning as this is used on backtest, DSL happens anyway...

      Yes, it is.
      And for some reason, the GMT offset function only works for one 'season.'
      Subsequently in my case during the gap there's a two-hour discrepancy from the correct news time, which reduces to one hour after two weeks.
      So for now I have to manually adjust the offset each time to get correct time of news apperance.

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      Hi @roar !

      I'm still testing various configurations in backtesting with this indicator, and as I mentioned earlier, it works fine in a basic scope.
      However, to reach a higher level of sophistication and acquire solid data, at least two important functions are missing:

      1. The first is the option I've mentioned before - filtering news that contain specific keywords along with the impact level, such as "Speaks,H," or/ and filtering based solely on the provided word.

      2. The second is the ability to adjust the broker's time and the time in the database concerning daylight saving time. Unfortunately, currently, the tester needs to be stopped four times a year to manually adjust the offset: for daylight saving time, for the two-week gap resulting from the fact that the USA and other regions change time with a two weeks delay compared to Europe, then back to standard time, and again for the two-week gap. Forgetting this adjustment will cause news markers to appear incorrectly on the chart and in buffers depending on the season. Perhaps introducing four separate options for the offset to account for these four time changes at once could work? Or maybe there's an easier solution... I'm not quite sure.

      Regardless, I would be extremely grateful if these two functions could be added in the next update.

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      nope, and I don't think there is one.

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      thank you @roar
      I'll fallow yor way.

      @tec-nacks

      I normally use two news idicators:

      IceFX.NewsInfo.ex4
      FFC_March_2021.mq4
      FFC_March_2021.ex4

      IceFX has a cool built-in additional function for disabling auto trading on the entire platform, but for obvious reasons, you need to be careful when using it if you're using more than one EA.

      Regarding the backtest, simply place the file named "All news events 2007-01-01 thru 2023-12-31 timestamped UTC time -- sorted by date, time.csv" into the folder that roar mentioned in the previous message, just rename it to "news.csv".
      Then the indicator will start working.

      The logic in the block you're asking about is simple ->>> -3600 seconds means that one hour before the news, the EA will trigger the SKIP TICKS function, which will block EA actions for a specified number of minutes in that block. So, if you set it to, for example, 90 minutes and the news was at 14:00, the EA won't do anything from 13:00 to 14:30.

      I don't know the structure of your EA, so I'm not sure which method, SKIP TICKS or ON/OFF, will be more effective for you.

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      @roar said in News during Backtest:

      @Archer glad it works. Currently the indicator filters for USD and the margin and profit currency of current pair. These filters are on line 75, you can add more currencies similar to the "USD" part

      thx @roar

      So I added the currencies I'm interested in to the code

      sample.png

      and ran a test on the USDJPY pair.
      It seems like everything is working as it should.
      I just hope I didn't mess up your code, and this is how it should be added.
      Please let me know if this isn't the right approach.

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      @tec-nacks said in News during Backtest:

      @Archer oh okay, How can I get it into FxDreema block to be able to use it in real-time inside an EA?

      To prevent the EA from opening positions in the live market before and after news events, I came up with this solution:

      https://fxdreema.com/shared/x0YpZjKB

      You simply need an indicator that draws vertical lines on the chart indicating upcoming news. There are plenty of such indicators available online. Choose one that suits you.

      Instead of the "SKIP TICKS" block, you can also use ON/OFF blocks to deactivate the desired block in the EA before and after the news. This way, you won't stop all actions in the "ON TICK" section, but only specific ones.

      Just keep in mind that I'm a very basic user of fxDreema. This isn't a genius method, and certainly, more advanced users on this forum might find better solutions. However, it has been working for me for many months, so I'm using it for now.

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      so I've ran a few tests and already can do some basic news filtration.
      Awesome stuff ! Can't wait for next upgrades.

      @roar quick question - is there any chance to 'force' the indicator to include news buffers from currencies other than the one being tested?
      If so, where can I add those currencies in the indicator's code?
      For instance, while backtesting on EUR/USD, I'd also like to consider news from GBP and other currencies I select.

      And a less urgent matter, maybe for later if it's not much of a hassle - the names of specific news events.
      It would be great if they were included in the names of the vertical lines that are shown on the chart.
      And that's all for now πŸ™‚

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      @roar said in News during Backtest:

      Hi!

      I got this project a little bit forward, adding the 6 datetimes to the indicator buffers and also visualizing the event dates. Keywords aren't supported in this version.

      newsfilter.ex5
      newsfilter.mq5

      very cool @roar , very cool !

      I am convinced that with each subsequent version of your work we will reach a one blocker on fxDreema πŸ˜‰

      In the meantime, thank you once more for your commitment !

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      well... according to the author - YES
      I've never tried it myself, cause live option is not what I'm aiming for.

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      I found another solution on how to filter news in backtesting on MT5.
      Full description of how to use it is explained below.
      Perhaps this method will prove to be easier to integrate with FX Dreema ?

      One block like this:

      screenshot-fxdreema.com-2023.11.29-16_06_02.png

      plus txt filtering news content option which I mentioned earlier would be a dream come true ! πŸ™‚

      //+------------------------------------------------------------------+
      //|                                                         News.mqh |
      //|                                                 username Chris70 |
      //|                                             https://www.mql5.com |
      //+------------------------------------------------------------------+
      
      // ___________________________________________________________________
      //
      // this is a workaround in order to be able to use Metaquotes' built-in Economic Event Calendar functions not only during live trading,
      // but also in the Strategy Tester and even for genetic optimization
      //
      // HOW TO USE THIS FILE:
      // 1. copy this file to your ../MQL5/include/ folder
      // 2. global scope:
      //    #include <News.mqh>
      //    CNews news;
      // 3. if(!) your broker isn't located in central Europe (or the same time zone, with daylight saving time):
      //    adjust the GMT_OFFSET default value definitions (below) to the requirements of your country/region;
      //    alternatively adjust the values in OnInit():
      //    e.g.
      //    news.server_offset_winter=2;
      //    news.server_offset_summer=3;
      //    why is this information necessary? because the event calendar seems to use GMT time for event dates/time,
      //    however in the strategy tester TimeGMT() returns wrong values and then is the same as TimeCurrent() or TimeTradeServer(),
      //    therefore in the tester GMT time needs to be simulated in order to match with the event data supplied by Metaquotes
      // 4. keep the event array updated in your main event handler (OnTick(),OnStart(), OnCalculate()..) by calling
      //    news.update();
      //    by default the updates will be limited to once every 60 seconds, which is usually much more than enough
      //    because most scheduled events are announced already with several days in advance, so that staying even more "current"
      //    usually in reality doesn't change anything;
      //    if a different update frequency is desired, just add this as a parameter, e.g.
      //    news.update(900); for array updates every 15 minutes;
      //    if detailed print log information is desired e.g. during debugging, set the second parameter to 'true' (false by default), e.g.:
      //    news.update(60,true);
      //    there is one exception with some strategies where instant updates are necessary: exactly around the time of the news event in those cases when we need instant access
      //    to the 'actual value' (e.g. in order to compare it to the forecast), then
      //    news.update(0);
      //    is recommended
      // 5. the total number of accessible historical, current and scheduled near future events is given by the return value of the update function, e.g.
      //    int total_events=news.update();
      //    this number (minus 1) also represents the highest possible index of the event array, so it's the same as ArraySize(news.event);
      //    to access detailed information about any event, then just address it via its index:
      //    news.event[index].value_id
      //    news.event[index].event_id
      //    news.event[index].time
      //    news.event[index].period
      //    news.event[index].revision
      //    news.event[index].actual_value
      //    news.event[index].prev_value
      //    news.event[index].revised_prev_value
      //    news.event[index].forecast_value
      //    news.event[index].impact_type
      //    news.event[index].event_type
      //    news.event[index].sector
      //    news.event[index].frequency
      //    news.event[index].timemode
      //    news.event[index].importance
      //    news.event[index].multiplier
      //    news.event[index].unit
      //    news.event[index].digits
      //    news.event[index].country_id
      //    news.eventname[index]
      //
      //    in order to make sense of a country id (which is just a number) and get the currency (=as a 3 character string) of this country
      //    just use the function news.CountryIdToCurrency()
      //    accordingly, in order to get the country id for a given currency, use news.CurrencyToCountryId();
      //
      //    there is one thing to mention about the 'index': at the time I'm writing this about 90.000 historical events can be accessed from the Metaquotes servers,
      //    however, this also means the index number can be pretty high and we probably don't want to go through the entire history of all past events until we have found the next upcoming event,
      //    so in order to make this more convenient (/efficient), I added the function
      //    news.next()
      //    which returns the index number of the next upcoming event relative to a given index to start the search with, e.g..
      //    news.next(last_event_index,"USD",true,0);
      //    in order to find the next following event that affects the dollar pairs, starting the search with index 'last_event_index';
      //    'true' and '0' in this case means that the event will be shown on the current chart as a vertical line with the name of the event attached
      //
      //    IMPORTANT: please note that this method works for both the strategy tester and live trading,
      //    actually the main motivation for this 'workaround' was to be able to test news strategies before deploying them in live trading,
      //    however, by default Metaquotes makes it impossible to directly access historical event data in the strategy tester, so that for testing this workaround
      //    consists in ONCE storing historical data to the harddrive and access them then later offline from this file;
      //    this means that in order to make this work, the EA has to be run at least ONCE in live mode; live mode doesn't mean trading; for example also just having called the news.update() function only once
      //    in the "debugging with live data" mode already is enough to ensure that the event data file exists (as a .bin file in the common files folder);
      //    for actual live trading on the other hand of course the news history file is irrelevant (because then we can also access the data directly, like intended by the built-in functions), but it also 'doesn't hurt';
      //    as a consequence, there are no differences of how to use this code whether it's for testing or live; I think this makes dealing with events in an EA a lot easier
      //
      //    Happy news trading,
      //
      //    Chris
      // ___________________________________________________________________
      #property copyright  "username Chris70"
      #property link       "https://www.mql5.com"
      #define   GMT_OFFSET_WINTER_DEFAULT 2
      #define   GMT_OFFSET_SUMMER_DEFAULT 3
      
      enum ENUM_COUNTRY_ID
        {
         World=0,
         EU=999,
         USA=840,
         Canada=124,
         Australia=36,
         NewZealand=554,
         Japan=392,
         China=156,
         UK=826,
         Switzerland=756,
         Germany=276,
         France=250,
         Italy=380,
         Spain=724,
         Brazil=76,
         SouthKorea=410
        };
      
      class CNews
        {
      private:
         struct            EventStruct
                             {
                              ulong    value_id;
                              ulong    event_id;
                              datetime time;
                              datetime period;
                              int      revision;
                              long     actual_value;
                              long     prev_value;
                              long     revised_prev_value;
                              long     forecast_value;
                              ENUM_CALENDAR_EVENT_IMPACT impact_type;
                              ENUM_CALENDAR_EVENT_TYPE event_type;
                              ENUM_CALENDAR_EVENT_SECTOR sector;
                              ENUM_CALENDAR_EVENT_FREQUENCY frequency;
                              ENUM_CALENDAR_EVENT_TIMEMODE timemode;
                              ENUM_CALENDAR_EVENT_IMPORTANCE importance;
                              ENUM_CALENDAR_EVENT_MULTIPLIER multiplier;
                              ENUM_CALENDAR_EVENT_UNIT unit;
                              uint     digits;
                              ulong    country_id; // ISO 3166-1
                             };
         string            future_eventname[];
         MqlDateTime       tm;
         datetime          servertime; 
      public:
         EventStruct       event[];
         string            eventname[];
         int               SaveHistory(bool printlog_info=false);
         int               LoadHistory(bool printlog_info=false);
         int               update(int interval_seconds,bool printlog_info=false);
         int               next(int start_index,string currency,bool show_on_chart,long chart_id);
         int               next(datetime start_gmt,string currency="ALL",bool show_on_chart=true,long chart_id=0);   
         string            CountryIdToCurrency(ENUM_COUNTRY_ID c);
         string            CountryIdToCountry(ENUM_COUNTRY_ID c);
         int               CurrencyToCountryId(string currency);  
         datetime          GMT(void);  
         datetime          last_update;
         ushort            GMT_offset_winter;
         ushort            GMT_offset_summer;    
                           CNews(void)
                             {
                              ArrayResize(event,100000,0);ZeroMemory(event);
                              ArrayResize(eventname,100000,0);ZeroMemory(eventname);
                              ArrayResize(future_eventname,100000,0);ZeroMemory(future_eventname);
                              GMT_offset_winter=GMT_OFFSET_WINTER_DEFAULT;
                              GMT_offset_summer=GMT_OFFSET_SUMMER_DEFAULT;
                              last_update=0;
                              SaveHistory(true);
                              LoadHistory(true);
                             }
                          ~CNews(void){};
        };
      
      //+------------------------------------------------------------------+
      //| update news events (file and buffer arrays)                      |
      //+------------------------------------------------------------------+
      int CNews::update(int interval_seconds=60,bool printlog_info=false)
        {
         static datetime last_time=0;
         static int total_events=0;
         if (TimeCurrent()<last_time+interval_seconds){return total_events;}
         SaveHistory(printlog_info);
         total_events=LoadHistory(printlog_info);
         last_time=TimeCurrent();
         return total_events;
        }
      
      //+------------------------------------------------------------------+
      //| grab news history and save it to disk                            |
      //+------------------------------------------------------------------+
      int CNews::SaveHistory(bool printlog_info=false)
        {
         datetime tm_gmt=GMT();
         int filehandle;
         
         // create or open history file
         if (!FileIsExist("news\\newshistory.bin",FILE_COMMON))
           {
            filehandle=FileOpen("news\\newshistory.bin",FILE_READ|FILE_WRITE|FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_COMMON|FILE_BIN);
            if (filehandle!=INVALID_HANDLE){if(printlog_info){Print(__FUNCTION__,": creating new file common/files/news/newshistory.bin");}}
            else {if (printlog_info){Print(__FUNCTION__,"invalid filehandle, can't create news history file");}return 0;}
            FileSeek(filehandle,0,SEEK_SET);
            FileWriteLong(filehandle,(long)last_update);
           }
         else
           {
            filehandle=FileOpen("news\\newshistory.bin",FILE_READ|FILE_WRITE|FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_COMMON|FILE_BIN);
            FileSeek(filehandle,0,SEEK_SET);
            last_update=(datetime)FileReadLong(filehandle);
            if (filehandle!=INVALID_HANDLE){if(printlog_info){Print(__FUNCTION__,": previous newshistory file found in common/files; history update starts from ",last_update," GMT");}}
            else {if(printlog_info){Print(__FUNCTION__,": invalid filehandle; can't open previous news history file");};return 0;}
            bool from_beginning=FileSeek(filehandle,0,SEEK_END);
            if(!from_beginning){Print(__FUNCTION__": unable to go to the file's beginning");}
           }
         if (last_update>tm_gmt)
           {
            if (printlog_info)
              {Print(__FUNCTION__,": time of last news update is in the future relative to timestamp of request; the existing data won't be overwritten/replaced,",
               "\nexecution of function therefore prohibited; only future events relative to this timestamp will be loaded");}
            return 0; //= number of new events since last update
           }
           
         // get entire event history from last update until now
         MqlCalendarValue eventvaluebuffer[];ZeroMemory(eventvaluebuffer);
         MqlCalendarEvent eventbuffer;ZeroMemory(eventbuffer);
         CalendarValueHistory(eventvaluebuffer,last_update,tm_gmt);
         
         int number_of_events=ArraySize(eventvaluebuffer);
         int saved_elements=0;
         if (number_of_events>=ArraySize(event)){ArrayResize(event,number_of_events,0);}
         for (int i=0;i<number_of_events;i++)
           {
            event[i].value_id          =  eventvaluebuffer[i].id;
            event[i].event_id          =  eventvaluebuffer[i].event_id;
            event[i].time              =  eventvaluebuffer[i].time;
            event[i].period            =  eventvaluebuffer[i].period;
            event[i].revision          =  eventvaluebuffer[i].revision;
            event[i].actual_value      =  eventvaluebuffer[i].actual_value;
            event[i].prev_value        =  eventvaluebuffer[i].prev_value;
            event[i].revised_prev_value=  eventvaluebuffer[i].revised_prev_value;
            event[i].forecast_value    =  eventvaluebuffer[i].forecast_value;
            event[i].impact_type       =  eventvaluebuffer[i].impact_type;
            
            CalendarEventById(eventvaluebuffer[i].event_id,eventbuffer);
            
            event[i].event_type        =  eventbuffer.type;
            event[i].sector            =  eventbuffer.sector;
            event[i].frequency         =  eventbuffer.frequency;
            event[i].timemode          =  eventbuffer.time_mode;
            event[i].importance        =  eventbuffer.importance;
            event[i].multiplier        =  eventbuffer.multiplier;
            event[i].unit              =  eventbuffer.unit;
            event[i].digits            =  eventbuffer.digits;
            event[i].country_id        =  eventbuffer.country_id;
            if (event[i].event_type!=CALENDAR_TYPE_HOLIDAY &&           // ignore holiday events
               event[i].timemode==CALENDAR_TIMEMODE_DATETIME)           // only events with exactly published time
              {
               FileWriteStruct(filehandle,event[i]);
               int length=StringLen(eventbuffer.name);
               FileWriteInteger(filehandle,length,INT_VALUE);
               FileWriteString(filehandle,eventbuffer.name,length);
               saved_elements++; 
              }
           }
         // renew update time
         FileSeek(filehandle,0,SEEK_SET);
         FileWriteLong(filehandle,(long)tm_gmt);
         FileClose(filehandle);
         if (printlog_info)
            {Print(__FUNCTION__,": ",number_of_events," total events found, ",saved_elements,
            " events saved (holiday events and events without exact published time are ignored)");}
         return saved_elements; //= number of new events since last update
        }
      
      //+------------------------------------------------------------------+
      //| load history                                                     |
      //+------------------------------------------------------------------+
      int CNews::LoadHistory(bool printlog_info=false)
        {
         datetime dt_gmt=GMT();
         int filehandle;
         int number_of_events=0;
         
         // open history file
         if (FileIsExist("news\\newshistory.bin",FILE_COMMON))
           {
            filehandle=FileOpen("news\\newshistory.bin",FILE_READ|FILE_WRITE|FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_COMMON|FILE_BIN);
            FileSeek(filehandle,0,SEEK_SET);
            last_update=(datetime)FileReadLong(filehandle);
            if (filehandle!=INVALID_HANDLE){if (printlog_info){Print (__FUNCTION__,": previous news history file found; last update was on ",last_update," (GMT)");}}
            else {if (printlog_info){Print(__FUNCTION__,": can't open previous news history file; invalid file handle");}return 0;}
            
            ZeroMemory(event);
            // read all stored events
            int i=0;
            while (!FileIsEnding(filehandle) && !IsStopped())
              {
               if (ArraySize(event)<i+1){ArrayResize(event,i+1000);}
               FileReadStruct(filehandle,event[i]);
               int length=FileReadInteger(filehandle,INT_VALUE);
               eventname[i]=FileReadString(filehandle,length);
               i++;
              }
            number_of_events=i;
            // FileClose(filehandle);
            if (printlog_info)
              {Print(__FUNCTION__,": loading of event history completed (",number_of_events," events), continuing with events after ",last_update," (GMT) ...");}
           }
         else
           {
            if (printlog_info)
              {Print(__FUNCTION__,": no newshistory file found, only upcoming events will be loaded");}
            last_update=dt_gmt;
           }
           
         // get future events
         MqlCalendarValue eventvaluebuffer[];ZeroMemory(eventvaluebuffer);
         MqlCalendarEvent eventbuffer;ZeroMemory(eventbuffer);
         CalendarValueHistory(eventvaluebuffer,last_update,0);
         int future_events=ArraySize(eventvaluebuffer);
         if (printlog_info)
           {Print(__FUNCTION__,": ",future_events," new events found (holiday events and events without published exact time will be ignored)");}
         EventStruct future[];ArrayResize(future,future_events,0);ZeroMemory(future);
         ArrayResize(event,number_of_events+future_events);
         ArrayResize(eventname,number_of_events+future_events);
         for (int i=0;i<future_events;i++)
           {
      
            future[i].value_id          =  eventvaluebuffer[i].id;
            future[i].event_id          =  eventvaluebuffer[i].event_id;
            future[i].time              =  eventvaluebuffer[i].time;
            future[i].period            =  eventvaluebuffer[i].period;
            future[i].revision          =  eventvaluebuffer[i].revision;
            future[i].actual_value      =  eventvaluebuffer[i].actual_value;
            future[i].prev_value        =  eventvaluebuffer[i].prev_value;
            future[i].revised_prev_value=  eventvaluebuffer[i].revised_prev_value;
            future[i].forecast_value    =  eventvaluebuffer[i].forecast_value;
            future[i].impact_type       =  eventvaluebuffer[i].impact_type;
            
            CalendarEventById(eventvaluebuffer[i].event_id,eventbuffer);
            
            future[i].event_type        =  eventbuffer.type;
            future[i].sector            =  eventbuffer.sector;
            future[i].frequency         =  eventbuffer.frequency;
            future[i].timemode          =  eventbuffer.time_mode;
            future[i].importance        =  eventbuffer.importance;
            future[i].multiplier        =  eventbuffer.multiplier;
            future[i].unit              =  eventbuffer.unit;
            future[i].digits            =  eventbuffer.digits;
            future[i].country_id        =  eventbuffer.country_id;
            future_eventname[i]         =  eventbuffer.name;
            if (future[i].event_type!=CALENDAR_TYPE_HOLIDAY &&           // ignore holiday events
               future[i].timemode==CALENDAR_TIMEMODE_DATETIME)           // only events with exactly published time
              {
               number_of_events++;
               event[number_of_events]=future[i];
               eventname[number_of_events]=future_eventname[i];
              }
           }
         if (printlog_info)
           {Print(__FUNCTION__,": loading of news history completed, ",number_of_events," events in memory");}
         last_update=dt_gmt;
         return number_of_events;
        }
      
      // +------------------------------------------------------------------+
      // | get index to next event for given currency                     |
      // +------------------------------------------------------------------+
      int CNews::next(int start_index,string currency="ALL",bool show_on_chart=true,long chart_id=0)
        {
         datetime dt_gmt=GMT();
         for (int p=start_index;p<ArraySize(event);p++)
           {
            if 
              (
               (event[p].country_id==CurrencyToCountryId(currency) || currency=="ALL")
              )
              {
               if (start_index!=p && show_on_chart && !MQLInfoInteger(MQL_OPTIMIZATION))
                 {
                  ObjectCreate(chart_id,"event "+IntegerToString(p),OBJ_VLINE,0,event[p].time+TimeTradeServer()-dt_gmt,0);
                  ObjectSetInteger(chart_id,"event "+IntegerToString(p),OBJPROP_WIDTH,3);
                  ObjectCreate(chart_id,"label "+IntegerToString(p),OBJ_TEXT,0,event[p].time+TimeTradeServer()-dt_gmt,SymbolInfoDouble(Symbol(),SYMBOL_BID));
                  ObjectSetInteger(chart_id,"label "+IntegerToString(p),OBJPROP_YOFFSET,800);
                  ObjectSetInteger(chart_id,"label "+IntegerToString(p),OBJPROP_BACK,true);
                  ObjectSetString(chart_id,"label "+IntegerToString(p),OBJPROP_FONT,"Arial");
                  ObjectSetInteger(chart_id,"label "+IntegerToString(p),OBJPROP_FONTSIZE,10);
                  ObjectSetDouble(chart_id,"label "+IntegerToString(p),OBJPROP_ANGLE,-90);
                  ObjectSetString(chart_id,"label "+IntegerToString(p),OBJPROP_TEXT,eventname[p]);
                 }
               return p;         
              }
           }
         return start_index;
        }
        
      int CNews::next(datetime start_gmt,string currency="ALL",bool show_on_chart=true,long chart_id=0)
        {
         datetime dt_gmt=GMT();
         int index=MathMax(ArraySize(event),1);
         while(event[index-1].time>start_gmt && index>=0){index--;}
         while(event[index].country_id!=CurrencyToCountryId(currency) && currency!="ALL"){index++;}
         if (show_on_chart && !MQLInfoInteger(MQL_OPTIMIZATION))
           {
            ObjectCreate(chart_id,"event "+IntegerToString(index),OBJ_VLINE,0,event[index].time+TimeTradeServer()-dt_gmt,0);
            ObjectSetInteger(chart_id,"event "+IntegerToString(index),OBJPROP_WIDTH,3);
            ObjectCreate(chart_id,"label "+IntegerToString(index),OBJ_TEXT,0,event[index].time+TimeTradeServer()-dt_gmt,SymbolInfoDouble(Symbol(),SYMBOL_BID));
            ObjectSetInteger(chart_id,"label "+IntegerToString(index),OBJPROP_YOFFSET,800);
            ObjectSetInteger(chart_id,"label "+IntegerToString(index),OBJPROP_BACK,true);
            ObjectSetString(chart_id,"label "+IntegerToString(index),OBJPROP_FONT,"Arial");
            ObjectSetInteger(chart_id,"label "+IntegerToString(index),OBJPROP_FONTSIZE,10);
            ObjectSetDouble(chart_id,"label "+IntegerToString(index),OBJPROP_ANGLE,-90);
            ObjectSetString(chart_id,"label "+IntegerToString(index),OBJPROP_TEXT,eventname[index]);
           }
         return index;
        }  
      
      //+------------------------------------------------------------------+
      //| country id to currency                                           |
      //+------------------------------------------------------------------+
      string CNews::CountryIdToCurrency(ENUM_COUNTRY_ID c)
        {
         switch(c)
           {
            case 999:      return "EUR";     // EU
            case 840:      return "USD";     // USA
            case 36:       return "AUD";     // Australia
            case 554:      return "NZD";     // NewZealand
            case 156:      return "CYN";     // China
            case 826:      return "GBP";     // UK
            case 756:      return "CHF";     // Switzerland
            case 276:      return "EUR";     // Germany
            case 250:      return "EUR";     // France
            case 380:      return "EUR";     // Italy
            case 724:      return "EUR";     // Spain
            case 76:       return "BRL";     // Brazil
            case 410:      return "KRW";     // South Korea
            default:       return "";
           }
        }  
      
      //+------------------------------------------------------------------+  
      //| country id to country                                            |
      //+------------------------------------------------------------------+
      string CNews::CountryIdToCountry(ENUM_COUNTRY_ID c)
        {
         switch(c)
           {
            case 999:      return "EU";     		// EU
            case 840:      return "USA";        // USA
            case 36:       return "Australia";  // Australia
            case 554:      return "NewZealand"; // NewZealand
            case 156:      return "China";     	// China
            case 826:      return "UK";     		// UK
            case 756:      return "Switzerland";// Switzerland
            case 276:      return "Germany";    // Germany
            case 250:      return "France";     // France
            case 380:      return "Italy";     	// Italy
            case 724:      return "Spain";     	// Spain
            case 76:       return "Brazil";     // Brazil
            case 410:      return "South Korea";// South Korea
            default:       return "";
           }
        }    
        
      //+------------------------------------------------------------------+
      //| currency to country id                                           |
      //+------------------------------------------------------------------+
      int CNews::CurrencyToCountryId(string currency)
        {
         if (currency=="EUR"){return 999;}
         if (currency=="USD"){return 840;}
         if (currency=="AUD"){return 36;}
         if (currency=="NZD"){return 554;}
         if (currency=="CYN"){return 156;}
         if (currency=="GBP"){return 826;}
         if (currency=="CHF"){return 756;}
         if (currency=="BRL"){return 76;}
         if (currency=="KRW"){return 410;}
         return 0;
        }
      
      //+------------------------------------------------------------------+
      //| convert server time to GMT                                       |
      //| (=for correct GMT time during both testing and live trading)     |
      //+------------------------------------------------------------------+
      datetime CNews::GMT(void)
        {
         // CASE 1: LIVE ACCOUNT
         if (!MQLInfoInteger(MQL_OPTIMIZATION) && !MQLInfoInteger(MQL_TESTER)){return TimeGMT();}
         
         // CASE 2: TESTER or OPTIMIZER
         servertime=TimeCurrent(); //=should be the same as TimeTradeServer() in tester mode, however, the latter sometimes leads to performance issues
         TimeToStruct(servertime,tm);
         static bool initialized=false;
         static bool summertime=true;
         // make a rough guess
         if (!initialized)
           {
            if (tm.mon<=2 || (tm.mon==3 && tm.day<=7)) {summertime=false;}
            if ((tm.mon==11 && tm.day>=8) || tm.mon==12) {summertime=false;}
            initialized=true;
           }
         // switch to summertime
         if (tm.mon==3 && tm.day>7 && tm.day_of_week==0 && tm.hour==7+GMT_offset_winter) // second sunday in march, 7h UTC New York=2h local winter time
           {
            summertime=true;
           }
         // switch to wintertime
         if (tm.mon==11 && tm.day<=7 && tm.day_of_week==0 && tm.hour==7+GMT_offset_summer) // first sunday in november, 7h UTC New York=2h local summer time
           {
            summertime=false;
           }
         if (summertime){return servertime-GMT_offset_summer*3600;}
         else {return servertime-GMT_offset_winter*3600;}
        }
      
      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      @roar

      I tried to work with this indicator, thinking that the buffers you added would give me some reference point. Unfortunately, they return a zero value.

      I had such an idea to stop the EA from opening new positions 60 minutes before and 60 minutes after the news:

      del.png

      I use a similar solution in live market, referencing different news indicator that I possess, and it works very well.

      So, it would be great if, for example, buffer 0 created a unix timestamp value with the time of the next upcoming event with HIGH IMPACT. Buffer 1 would do the same but for MEDIUM IMPACT. Then we would have a specific reference to the time, and the above solution should work.

      It would be also great if you could add Buffer 3, which filters events based on specific words entered somewhere in the indicator and provides a unix timestamp value only for events that contain those specific words.

      For instance, I personally avoid trading when someone from the Fed speaks, or when Lagarde does. So, after entering the word 'FED' or words separated by commas like 'H, Speaks' Buffer 3 would provide the timestamp only for the nearest upcoming event containing those words.

      I know that everyone has different preferences when it comes to trading the news, some avoiding or trading only specific events like for example the ADP Non-Farm Employment Change, etc.
      That's why I believe such a filter would be helpful for many individuals.

      Moreover, having these buffers would offer unlimited possibilities for controlling the behavior of the EA concerning news events during backtesting and not just preventing it from opening new positions.

      Does what I've written make sense to you?
      If so, would you be able to create such Buffers?

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      @roar said in News during Backtest:

      Hi!

      I processed the csv file in a custom indicator project, but trying to move the same code to fxdreema causes some weird problems. I think fxdreema cannot handle such big arrays, it needs to be constructed in some other way...

      Maybe someone finds the indicator format useful. I will try to better integrate this to fxdreema at some point...

      I used the file "All news events 2007-01-01 thru 2023-12-31 timestamped UTC time -- sorted by date, time.csv", renamed to "news.csv" and moved to the Common folder.

      The indicator looks promising.
      I'll play around with it soon.
      @roar, thank you for your work !

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      @roar said in News during Backtest:

      @Archer thank you! That is good data, valuable stuff. I'll try to find some time this week to code it and update here. Please remind me if I dont

      Hey @roar , how's that coding goin' ?
      Do you think you'll be able to share your work with us by the end of this week ?

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      I sure will @roar
      Can't wait to see the results.
      GL!

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      @roar said in News during Backtest:

      @Archer sure, lets do it!

      Alright, have fun with it !

      https://we.tl/t-LICj3Q0aAx

      Files include news from 2007-01-01 thru 2023-12-31.

      Data runs through to the end of this year (news events that haven't occurred yet have their 'Actual' value set to "").

      Format is:
      "date","time","currency","impact","description","actual","forecast","previous","revised from","event id"

      Events in the zip file are timestamped UTC; (UTC–5 during winter and UTC–4 during summer).

      The credit goes to my old buddy Hanover; hats off to him for sharing the database. I'm just the middleman and the initiator here.

      posted in Questions & Answers
      Archer
      Archer
    • RE: News during Backtest

      @roar said in News during Backtest:

      @tec-nacks most news filters dont support that.

      Technically its possible, if you get some kind of database of old news records. In fact, I'm willing to code it for you, if you really find such database.

      While searching for a solution on how to filter news in backtesting on MT5, I came across this thread.
      As it happens, I have access to a database of historical news dating back to 2007.

      So, my question to you, @roar - are you still capable of writing or designing a block that would prevent an EA from opening new positions, for instance, 1 hour before high-impact news and 1 hour after?

      @l-andorrΓ  mentioned in another thread that this is the Holy Grail everyone is searching for on this forum.

      Of course, I still refer to backtesting, but If your solution were to also work in the live market, it would be a great bonus for everyone here, I think.

      Since the @fxDreema isn't eager to write such a block, perhaps we could create it ourselves?
      What do you think?

      posted in Questions & Answers
      Archer
      Archer
    • 1
    • 2
    • 3
    • 4
    • 1 / 4