文章 "DoEasy 函数库中的时间序列(第三十九部分):基于函数库的指标 - 准备数据和时间序列事件"

 

新文章 DoEasy 函数库中的时间序列(第三十九部分):基于函数库的指标 - 准备数据和时间序列事件已发布:

本文讨论如何应用 DoEasy 库来创建多品种、多周期指标。 我们准备在指标中操控函数库类,并创建时间序列作为指标的数据源进行测试。 我们还将实现时间序列事件的创建和发送。

编译指标并启动,我们已经很长时间没有触及品种图表了(同时在预设置中操控当前品种设定),然后选择操控指定的时间帧列表。 若在长时间未使用的品种图表上启动指标,将会令指标下载缺失的数据,并在日志和图表中发出通知:


在此,我们可以看到在每次即时报价处,每个空时间序列都会被同步并创建。 日志中会显示以下条目:

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

作者:Artyom Trishkin

[删除]  

文章是否有误?

如果指标在符号图表上运行,库就会在定时器中工作;如果指标在测试器中运行,库就会在定时器的OnCalculate() 中工作。

还是我理解错了?
 
Сергей Таболин:

文章是否有误?

如果指标在符号图表上运行,库就会在定时器中工作;如果指标在测试器中运行,库就会在定时器的 OnCalculate() 中工作。

还是我理解错了?
没错。就是这样。
 

你好、

我正试图将最后一个 "完整 "条形图的一些参数 打印到日志中,但我猜我要么没有更新存储的系列数据,要么没有对其进行排序(但我也不知道如何按时间排序并获得我想要的条形图),我的结果总是历史中的第二个条形图,从未更新过上一个完整条形图的实时数据...接下来,我想将最近的完整条形图与之前的 10-20 条形图进行比较, 如果有任何正确的方法,我将不胜感激!

是在 "新条形图 "事件中执行此操作 的:

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

        
//--- 在每个新条形上打印最后一个完整的条形尺寸 
         // 从传递的字符串中获取符号对象参数 
         CSymbol *symbol=engine.GetSymbolObjByName(sparam);
         if(symbol==NULL)
            return;
         // 获取该时间框架的最后一个完整条形图(图表右侧的当前 -1)。
         CBar *bar=engine.SeriesGetBar(symbol.Name(),(ENUM_TIMEFRAMES)dparam,1);
         if(bar==NULL)
            return;            
         //--- 显示从条形图对象接收到的数据
         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()));        
        
        }
     }

附上日志结果截图

附加的文件:
Example.jpg  102 kb
 
iabbott :

你好、

我正试图将最后一个 "完整 "条形图的一些参数打印到日志中,但我猜我要么没有更新存储的系列数据,要么没有对其进行排序(但我也不知道如何按时间排序并得到我想要的条形图),我的结果总是历史中的第 2 个条形图,从未更新过上一个完整条形图的实时数据......接下来,我想将最近的完整条形图与之前的 10-20 条形图进行比较, 如果有任何正确的方法,我将不胜感激!

我是在 "新条形图 "事件中执行此操作 的:

附上日志结果截图

请在此附上您获得此类结果的程序源代码。

您希望在新条形图打开时收到哪个时间段的条形图?

 

您好、

我刚刚在 Pt39 TestDoEasy EA 的新条形事件中添加了该代码块,没有做其他改动(附件中第 544 行)。

在打开新的条形图时,我想检查 触发事件的时间框架的条形图历史记录 - 因为事件是在每个时间框架上分别触发的,所以我想把这个检查作为事件的一部分会更容易些。

谢谢

附加的文件:
 

嘿,有什么新情况吗?

是不是我做得不对?在我看来,如果是程序库的问题,有人会比现在更早发现的:)

谢谢!

 
iabbott:

嘿,有什么新消息吗?

是不是我做得不对?在我看来,如果是程序库的问题,有人会比现在更早发现的:)

谢谢!

我向您道歉。我很忙。我很快就会知道你的问题出在哪里。
 

您好,Artyom,对于使用:: Comment () 像在CEngine::SeriesSync() 中那样在图表注释中写入注释库,您有具体的想法吗?

void CEngine::SeriesSync(SDataCalculate &data_calculate,const uint required=0)
  {
//...
      //--- 以图表注释的形式显示空时间序列数据,并尝试将时间序列与服务器数据同步
      ::Comment(series.Header(),": ",CMessage::Text(MSG_LIB_TEXT_TS_TEXT_WAIT_FOR_SYNC));
      ::ChartRedraw(::ChartID());

//...
            //--- 用重新创建的时间序列数据显示图表注释和日志条目
            ::Comment(series.Header(),": OK");
            ::ChartRedraw(::ChartID());
            Print(series.Header()," ",CMessage::Text(MSG_LIB_TEXT_TS_TEXT_CREATED_OK),":");
            series.PrintShort();

//...
     //-- 删除所有评论
      ::Comment("");
      ::ChartRedraw(::ChartID());
  }

依我之见,最好还是让库的用户来做...我有自己的库,可以操纵图表注释来输出我的 EA 的关键操作方面,因此我强烈希望避免来自 DoEasy 库的干扰。您在这方面的未来计划是什么?

 
Dima Diall :

您好,Artyom,对于使用:: Comment () 编写图表注释的库,您是否有具体的想法,就像您在CEngine::SeriesSync() 中做的那样?

依我之见,最好还是让库的用户来做...我有自己的库,可以操纵图表注释来输出我的 EA 的关键操作方面,因此我强烈希望避免来自 DoEasy 库的干扰。您在这方面的未来计划是什么?

如果将来有图形工作,将不会有标准注释。

 

您好 - 在仔细查看事件处理程序代码时,我注意到您使用了不同的方法来解析事件源......在某些情况下,它基于OnChartEvent() 中的图表事件 id 参数,而在另一些情况下,您通过engine.EventSource(lparam)lparam 参数中提取了事件源 - 是否有什么特殊原因导致在每种情况下都不同?

void OnDoEasyEvent(const int id,
                   const long &lparam,
                   const double &dparam,
                   const string &sparam)
  {
   int idx=id-CHARTEVENT_CUSTOM;
//--- 从 lparam 中读取 (1) 事件时间毫秒、(2) 原因和 (3) 来源,以及 (4) 设置准确的事件时间
   ushort msc=engine.EventMSC(lparam);
   ushort reason=engine.EventReason(lparam);
   ushort source=engine.EventSource(lparam);
   long time=TimeCurrent()*1000+msc;
   
//--- 处理符号事件
   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)
     {
      //...
     }