Discussion of article "Timeseries in DoEasy library (part 39): Library-based indicators - preparing data and timeseries events"

MetaQuotes
Moderator
238056

New article Timeseries in DoEasy library (part 39): Library-based indicators - preparing data and timeseries events has been published:

The article deals with applying DoEasy library for creating multi-symbol multi-period indicators. We are going to prepare the library classes to work within indicators and test creating timeseries to be used as data sources in indicators. We will also implement creating and sending timeseries events.

Compile the indicator and launch it on the symbol chart we have not worked with for a long time (while setting working with the current symbol in the settings beforehand) and select working with the specified timeframe list. Launching the indicator on long unused symbols makes the indicator to download missing data and inform of that in the journal and on the chart:


Here we can see that each next empty timeseries has been synchronized and created at each new tick. The following entries have been displayed in the journal:

Account 8550475: Artyom Trishkin (MetaQuotes Software Corp.) 10425.23 USD, 1:100, Hedge, MetaTrader 5 demo
--- Initializing "DoEasy" library ---
Working with the current symbol only: "USDCAD"
Working with the specified timeframe list:
"M1"  "M5"  "M15" "M30" "H1"  "H4"  "D1"  "W1"  "MN1"
USDCAD symbol timeseries: 
- Timeseries "USDCAD" M1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" M5: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" M15: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" M30: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" H1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" H4: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" D1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" W1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
- Timeseries "USDCAD" MN1: Requested: 1000, Actual: 0, Created: 0, On the server: 0
Library initialization time: 00:00:01.406
"USDCAD" M1 timeseries created successfully:
- Timeseries "USDCAD" M1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5001
"USDCAD" M5 timeseries created successfully:
- Timeseries "USDCAD" M5: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5741
"USDCAD" M15 timeseries created successfully:
- Timeseries "USDCAD" M15: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5247
"USDCAD" M30 timeseries created successfully:
- Timeseries "USDCAD" M30: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5123
"USDCAD" H1 timeseries created successfully:
- Timeseries "USDCAD" H1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 6257
"USDCAD" H4 timeseries created successfully:
- Timeseries "USDCAD" H4: Requested: 1000, Actual: 1000, Created: 1000, On the server: 6232
"USDCAD" D1 timeseries created successfully:
- Timeseries "USDCAD" D1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 5003
"USDCAD" W1 timeseries created successfully:
- Timeseries "USDCAD" W1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 1403
"USDCAD" MN1 timeseries created successfully:
- Timeseries "USDCAD" MN1: Requested: 1000, Actual: 323, Created: 323, On the server: 323
New bar on USDCAD M1: 2020.03.19 12:18
New bar on USDCAD M1: 2020.03.19 12:19
New bar on USDCAD M1: 2020.03.19 12:20
New bar on USDCAD M5: 2020.03.19 12:20

Author: Artyom Trishkin

iabbott
8
iabbott  

Hi,

I am trying to print some parameters of the last "complete" bar into the journal, but I would guess I have either not updated the stored series data, or have not sorted it (but I also can't work out how to sort it by time and get the bar I want), my result is always the 2nd bar in the history, never updated realtime data of the previous complete bar... Next I want to compare the most recent complete bar size against the previous 10-20 bars, any push in the right direction will be appreciated!

I am performing this action on the "New Bar" event:

   else if(idx>SERIES_EVENTS_NO_EVENT && idx<SERIES_EVENTS_NEXT_CODE)
     {
      //--- "New bar" event
      if(idx==SERIES_EVENTS_NEW_BAR)
        {
         Print(TextByLanguage("Новый бар на ","New Bar on "),sparam," ",TimeframeDescription((ENUM_TIMEFRAMES)dparam),": ",TimeToString(lparam));

        
//--- printing last complete bar size on every new bar         
         // Get the Symbol object from the passed string param  
         CSymbol *symbol=engine.GetSymbolObjByName(sparam);
         if(symbol==NULL)
            return;
         // Get the last complete bar (current -1 from right of chart) for this timeframe
         CBar *bar=engine.SeriesGetBar(symbol.Name(),(ENUM_TIMEFRAMES)dparam,1);
         if(bar==NULL)
            return;            
         //--- Display the data received from the bar object
         Print(TextByLanguage("Бар \"","Data from Bar \"")+symbol.Name()+"\" "+TimeframeDescription((ENUM_TIMEFRAMES)dparam)+": "+TimeToString(bar.Time(),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+
            " H: "+DoubleToString(bar.High(),symbol.Digits())+
            " L: "+DoubleToString(bar.Low(),symbol.Digits())+
            " Size: "+DoubleToString(bar.Size(),symbol.Digits()));        
        
        }
     }

Attached screenshot of the journal results

Files:
Example.jpg  102 kb
Artyom Trishkin
Moderator
82618
iabbott :

Hi,

I am trying to print some parameters of the last "complete" bar into the journal, but I would guess I have either not updated the stored series data, or have not sorted it (but I also can't work out how to sort it by time and get the bar I want), my result is always the 2nd bar in the history, never updated realtime data of the previous complete bar... Next I want to compare the most recent complete bar size against the previous 10-20 bars,  any push in the right direction will be appreciated!

I am performing this action on the "New Bar" event:

Attached screenshot of the journal results

Attach here the source code of the program in which you get such results, please.

What timeframe bars do you want to receive at the opening of a new bar?

iabbott
8
iabbott  

Hi,

I have just added that code block to the new bar event of the Pt39 TestDoEasy EA, no other changes (line 544 in the attached)

On the open of a new bar, I want to check the bar history of the timeframe which triggered the event - since the event is triggered on each timeframe separately, I figured it would be easier to put this check as part of the event

Thanks

Files:
iabbott
8
iabbott  

Hey-any update?

Is it something I'm not doing right? Seems to me that if it was an issue with the library that someone would have found it much earlier than this :)

Thanks!

Artyom Trishkin
Moderator
82618
iabbott:

Hey-any update?

Is it something I'm not doing right? Seems to me that if it was an issue with the library that someone would have found it much earlier than this :)

Thanks!

I apologize. I was busy. I'll see what your problem is soon.
Dima Diall
61
Dima Diall  

Hi Artyom, do you have specific ideas for the library to write in the chart comments, using ::Comment() like you do in CEngine::SeriesSync()?

void CEngine::SeriesSync(SDataCalculate &data_calculate,const uint required=0)
  {
//...
      //--- Display the empty timeseries data as a chart comment and try synchronizing the timeseries with the server data
      ::Comment(series.Header(),": ",CMessage::Text(MSG_LIB_TEXT_TS_TEXT_WAIT_FOR_SYNC));
      ::ChartRedraw(::ChartID());

//...
            //--- display the chart comment and the journal entry with the re-created timeseries data
            ::Comment(series.Header(),": OK");
            ::ChartRedraw(::ChartID());
            Print(series.Header()," ",CMessage::Text(MSG_LIB_TEXT_TS_TEXT_CREATED_OK),":");
            series.PrintShort();

//...
      //--- Delete all comments
      ::Comment("");
      ::ChartRedraw(::ChartID());
  }

In my humble opinion, it is probably best to leave this to the user of the library... I have my own library that manipulates the chart comments to output key operational aspects of my EAs, so would strongly prefer to avoid interference from DoEasy library. What are your future plans in that respect?

Artyom Trishkin
Moderator
82618
Dima Diall :

Hi Artyom, do you have specific ideas for the library to write in the chart comments, using ::Comment() like you do in  CEngine::SeriesSync() ?

In my humble opinion, it is probably best to leave this to the user of the library... I have my own library that manipulates the chart comments to output key operational aspects of my EAs, so would strongly prefer to avoid interference from DoEasy library. What are your future plans in that respect?

If there is future work with graphics, there will be no standard comments.

Dima Diall
61
Dima Diall  

Hello - in reviewing the event-handler code more closely, I noticed that you use different methods to parse out the source of the event... in some cases it's based on the chart event id parameter from OnChartEvent()while in others you extract it from the lparam parameter via engine.EventSource(lparam) -- is there a particular reason why it is different in each case? 

void OnDoEasyEvent(const int id,
                   const long &lparam,
                   const double &dparam,
                   const string &sparam)
  {
   int idx=id-CHARTEVENT_CUSTOM;
//--- Retrieve (1) event time milliseconds, (2) reason and (3) source from lparam, as well as (4) set the exact event time
   ushort msc=engine.EventMSC(lparam);
   ushort reason=engine.EventReason(lparam);
   ushort source=engine.EventSource(lparam);
   long time=TimeCurrent()*1000+msc;
   
//--- Handling symbol events
   if(source==COLLECTION_SYMBOLS_ID)
     {
      //...
     }
//--- Handling account events
   else if(source==COLLECTION_ACCOUNT_ID)
     {
      //...
     }
//--- Handling market watch window events
   else if(idx>MARKET_WATCH_EVENT_NO_EVENT && idx<SYMBOL_EVENTS_NEXT_CODE)
     {
      //...
     }
//--- Handling timeseries events
   else if(idx>SERIES_EVENTS_NO_EVENT && idx<SERIES_EVENTS_NEXT_CODE)
     {
      //...
     }
//--- Handling trading events
   else if(idx>TRADE_EVENT_NO_EVENT && idx<TRADE_EVENTS_NEXT_CODE)
     {
      //...
     }
Dima Diall
61
Dima Diall  
Dima Diall:

Hello - in reviewing the event-handler code more closely, I noticed that you use different methods to parse out the source of the event... in some cases it's based on the chart event id parameter from OnChartEvent()while in others you extract it from the lparam parameter via engine.EventSource(lparam) -- is there a particular reason why it is different in each case? 

Hi Artyom - can you clarify this for me, please?
Artyom Trishkin
Moderator
82618
Dima Diall :
Hi Artyom - can you clarify this for me, please?

Please, a little later - very busy for now