量化软件——赫兹MT5创建多交易品种、多周期指标

概述
继续为 EA 交易和指标中的技术指标创建模板的主题,该主题从与创建仪表盘相关的文章中开始,然后在另外三篇文章中发展,其中我们探讨了振荡器、交易量指标和比尔威廉姆斯以及趋势指标,今天我们将开始创建多交易品种、多周期指标的主题。其中包括在当前图表上运行但使用其他交易品种和(或)其他图表时间框架的数据计算的指标。我们将创建一个基础多指标类和一组基于所有标准指标类型的类。我们还将为自定义指示器创建一个类,使用该类可以将任何指标“转换”为多交易品种和多周期指标。对于所有指标类,我们将创建一个统一集合类。程序中创建的所有指标都将被放入此集合中。此外,还可以使用方法访问集合中任何创建的指标,以获得相关的指标数据。最终目标是开发一种方便的工具,用于创建多指标和处理其数据。


基本原则
为了正确理解指标操作的逻辑,让我们试着了解它是如何工作的。指标分为两部分:计算和绘图。这些部分中的每一个都对另一个一无所知。当创建指标时,终端子系统在图表上查找这样的指标是否存在。在这种情况下,它会查找具有相同名称和参数的指标。如果这样的指标已经在图表上运行,或者已经为此图表以编程方式创建,则终端将使用现有指标的句柄,而不是创建新指标。指标的绘图部分使用其句柄从计算部分接收所需的数据。可能存在多个绘图部件同时访问一个计算部件的情况。


函数将指定数量的指定指标缓冲区的数据接收到“buffer”数组中。

复制数据的元素(具有索引buffer_num的指标缓冲区)从开始位置开始计数,从现在到过去,也就是说,等于0的开始位置表示当前柱(当前柱的指标值)。

如果事先不知道要复制的数据量,建议使用动态数组作为目标数组缓冲区,因为CopyBuffer()会尝试将接收数组的大小分配到复制的数据的量。如果接收数组缓冲区是一个指标缓冲区(之前由SetIndexBufer()函数分配的用于存储指标值的数组),则允许部分复制。

如果需要将指标值部分复制到另一个数组(而不是指标缓冲区),则应使用一个中间数组,将所需数量复制到该数组中。从这个中间数组中,逐个成员将所需数量的值复制到接收数组的所需位置。

如果需要复制预定量的数据,建议使用静态分配的缓冲区,以避免不必要的内存重新分配。

接收数组的属性,即as_series=true或as_series=false,将被忽略:在复制过程中,最旧的元素将被复制到为数组分配的物理内存的开头。有三种函数选项。

按根据初始位置和所需元素的数量的访问

int  CopyBuffer(
   int       indicator_handle,     // indicator handle
   int       buffer_num,           // indicator buffer index
   int       start_pos,            // starting point 
   int       count,                // amount to copy
   double    buffer[]              // array the data to be copied to
   );
按初始日期和所需元素数量访问

int  CopyBuffer(
   int       indicator_handle,     // indicator handle
   int       buffer_num,           // indicator buffer index
   datetime  start_time,           // starting date
   int       count,                // amount to copy
   double    buffer[]              // array the data to be copied to
   );
按所需时间间隔的初始日期和最终日期访问

int  CopyBuffer(
   int       indicator_handle,     // indicator handle
   int       buffer_num,           // indicator buffer index
   datetime  start_time,           // starting date
   datetime  stop_time,            // end date
   double    buffer[]              // array the data to be copied to
   );
参数

indicator_handle

[in] 通过相关指标函数获得的指标句柄。

buffer_num

[in] 指标缓冲区的编号。

start_pos

[in] 复制的第一个元素的索引。

count

[in] 复制的元素数。

start_time

[in] 第一个元素对应的柱的时间。

stop_time

[in] 最后一个元素对应的柱的时间。

buffer[]

[out] double类型的数组。

返回值

复制的数组元素数,如果出现错误,则为-1。

注意

当从指标请求数据时,如果请求的时间序列尚未构建或应该从服务器下载,则函数会立即返回-1。在这种情况下,会启动所需数据的下载或构建。

当从EA或脚本请求数据时,如果终端在本地没有适当的数据,则会启动从服务器的下载。另外,如果可以从本地历史构建数据,但尚未准备好,则开始构建必要的时间序列。该函数返回超时到期时准备好的数量。

我们将使用该函数的第一个版本,即基于起始位置(y为循环索引)和所需元素数量的访问。

对象结构如下:

多交易品种、多周期指标的基类,包含所有指标通用的主要函数;
从基本对象派生的类,这些类按其类型描述每个指标;
指标的集合–您可以使用此类创建任何指标并将其添加到集合中。该类将为用户提供创建指标和从中接收数据的所有工具。
使用非当前图表中的数据时,为了避免时间序列被释放,您应该至少每两分钟访问一次此时间序列。在这种情况下,时间序列将被“保留”,这将加快对它的访问(不需要每次都等待数据同步)。在类构造函数中,我们将执行构建指标的时间序列的第一次调用。这将允许我们开始下载时间序列(如果无法在本地访问)。然后,每隔90秒,在基类计时器中,我们将访问时间序列来保存它。

资源高效计算

为了计算和显示指标,我们需要资源高效的计算。第一次启动时,将计算所有历史数据的指标,然后将计算所有后续分时的一个或两个柱形。

OnCalculate()处理函数具有预定义的常量变量,这些变量存储(时间序列或数组的)输入数据大小以及在上一次OnCalculate()调用 期间计算的数据量:

基于数据数组的计算

int  OnCalculate(
   const int        rates_total,       // price[] array size
   const int        prev_calculated,   // number of processed bars at the previous call
   const int        begin,             // index number in the price[] array meaningful data starts from
   const double&    price[]            // array of values for calculation
   );
基于当前时间段时间序列的计算

int  OnCalculate(
   const int        rates_total,       // size of input timeseries
   const int        prev_calculated,   // number of processed bars at the previous call
   const datetime&  time{},            // Time array
   const double&    open[],            // Open array
   const double&    high[],            // High array
   const double&    low[],             // Low array
   const double&    close[],           // Close array
   const long&      tick_volume[],     // Tick Volume array
   const long&      volume[],          // Real Volume array
   const int&       spread[]           // Spread array
   );
这种数据的存在使得能够快速、有效地计算指标。例如,让我们考虑“limit”值的计算:

//--- Number of bars for calculation
   int limit=rates_total-prev_calculated;
//--- If limit > 1, then this is the first calculation or change in the history
   if(limit>1)
     {
      //--- specify all the available history for calculation
      limit=rates_total-1;
      //--- If the indicator has any buffers, initialize them here with empty values set for these buffers
     }

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值