文章 "创建多交易品种、多周期指标"

 

新文章 创建多交易品种、多周期指标已发布:

在本文中,我们将研究创建多交易品种、多周期指标的原则。我们还将了解如何从 EA 交易和其他指标中获取此类指标的数据。我们将探讨在 EA 交易和指标中使用多指标的主要功能,并将了解如何通过自定义指标缓冲区绘制它们。

编译测试指标后,我们将在周期为M1的图表上启动它,在设置中我们将选择指标M5的当前交易品种和计算周期。在这种情况下,将创建在指标设置中选择的两个移动平均线。其中一个将使用当前图表数据进行计算,第二个将基于五分钟图表周期的数据。通过切换图表时间框架,您可以看到M1上画了两条线:一条线对应M1上计算的移动平均线,第二条线对应M5上计算的移动平均线。如果将图表切换到M5,则只会创建一个指标,因为第二个指标与第一个指标相同,并且不会创建。如果将图表切换到M15,则将为M15计算一个指标,为M5计算第二个指标,并且该指标也将显示在图表上。


正如您所看到的,声明的功能是有效的,我们可以在主图表窗口中看到指标。可以使用一个缓冲区创建多个指标。

作者:Artyom Trishkin

 

感谢作者。有一点需要考虑...

我认为,如果该类是基本类,那么它的名称应该是CBaseIndMSTF。 甚至是CBaseIndMSMTF。MSMTF -多符号多 时间框架。

按名称。

ENUM_IND_CATEGORY 很好。

以下几种方法不太好。

enum_compare_mode --> enum_ind_compare_mode

enum_line_state --> enum_ind_line_state

enum_err_type --> enum_ind_calc_err_type


enum ENUM_ERR_TYPE            // 指标计算中的错误类型
  {
   ERR_TYPE_NO_ERROR,         // 无错误
   ERR_TYPE_NO_CYNC,          // 数据未同步
   ERR_TYPE_NO_DATA,          // 数据未加载
   ERR_TYPE_NO_CALC,          // 计算未完成
  };

err_type_no_cync--> err_type_no_sync

 
Denis Kirichenko 多符号多 时间框架。

按名称。

ENUM_IND_CATEGORY 可以。

以下情况不好。

enum_compare_mode --> enum_ind_compare_mode

enum_line_state --> enum_ind_line_state

enum_err_type --> enum_ind_calc_err_type


err_type_no_cync--> err_type_no_sync

我同意这一条。其他是特定的

 
同步/ 同步
 
Denis Kirichenko #:
同步/ 同步

我看不懂。两个 "s "突出显示,那又怎样?

"没有同步"--没有同步。怎么了?"错误:未同步

我在最后一刻看到了 C 而不是 S...好的,谢谢我会修好的

 

Artem, 欧元兑美元图表上 运行TestMSTFMovingAverages 指标。当日关闭。Tf1 = M15,Tf2 = H1

输入参数:

InpIndicator=26
InpSymbol=
InpTimeframe=16385
InpPrice=1
InpMethod=0
InpShift=0
InpAsSeries=true

结果如下:

日志:

HD      0       20:22:12.149    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::AddNewMA: MA(10) indicator (handle 10) added to the collection
PJ      0       20:22:12.150    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::AddNewMA: MA(EURUSD,H1:10) indicator (handle 11) added to the collection
CG      0       20:22:12.179    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Start downloading data by EURUSD/H1. Waiting for the next tick...
OG      0       20:22:12.179    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data not loaded
HQ      0       20:22:12.179    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
QH      0       20:22:12.224    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::DataToBuffer::MA(EURUSD,H1:10) First start, or historical data has been changed. Initialize Buffer(0)


用十字线突出显示 23:00 蜡烛。您可以看到,红色 SMA10 线仅在 23:00 之后的下一根蜡烛上改变其值。也就是说,23:00 和 23:15 时 的值发生了转换

根据我的理解,Tf2 上当前值到下一个值的转换应该发生22:45 和 23:00。


这就是我得到的结果。我在一个单独的EURUSD-H1 图表 上运行 SMA10 指标,偏移 = 1。

我打开一个新图表,运行 TestMSTFMovingAverages。奇迹出现了,我看到图片似乎得到了修正。


日志:

2023.10.29 20:38:42.583 TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::AddNewMA: MA(10) indicator (handle 10) added to the collection
2023.10.29 20:38:42.584 TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::AddNewMA: MA(EURUSD,H1:10) indicator (handle 11) added to the collection
2023.10.29 20:38:42.622 TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::DataToBuffer::MA(10) First start, or historical data has been changed. Initialize Buffer(0)
2023.10.29 20:38:42.654 TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::DataToBuffer::MA(EURUSD,H1:10) First start, or historical data has been changed. Initialize Buffer(0)


在第一种情况和第二种情况下,23:00 时面板上的MA(EURUSD,H1:10) = 1.056959。我认为这是正确的。显然,在第一种情况下,MA(EURUSD,H1:10) 的缓冲填充出了问题。

 
Denis Kirichenko 欧元兑美元-H1 图表 上运行 SMA10 指标,偏移 = 1。

我打开一个新图表,运行 TestMSTFMovingAverages。奇迹出现了,我看到图片似乎得到了修正。


日志:


此外,在第一种情况和第二种情况下,23:00 时面板上的MA(EURUSD,H1:10)= 1.056959。我认为这是正确的。显然,在第一种情况下,MA(EURUSD,H1:10) 的缓冲填充出了问题。

谢谢,丹尼斯。我稍后会看看 - 我正忙着继续这个话题,很遗憾现在还没有时间。
 

...При работе с данными не текущего графика для исключения "освобождения" таймсерии, необходимо не реже. чем раз в две минуты обращаться к этой таймсерии. В этом случае будет происходить "удержание" таймсерии, что ускорит к ней обращение (не нужно будет каждый раз дожидаться синхронизации данных)...

你是如何得出这个 频率值的?是通过实验确定的吗?

 
Denis Kirichenko #:

你是如何得出这个 频率值的?是通过实验确定的吗?

开发人员在论坛上的留言。

 

有这样一种结构:

//--- 结构
struct SBuffer                // 指示器缓冲区的结构
  {
   double            array[];    // 指标数组缓冲区
   double            init_value; // 初始化数值
   int               shift;      // 水平移动缓冲区
   string            descript;   // 缓冲区说明
   //--- (1) 设置,(2) 返回初始化值、
   void              SetInitValue(const double value) { init_value=value;                             }
   double            InitValue(void)                  { return init_value;                            }
   //--- (1) 设置,(2) 返回缓冲区偏移量
   void              SetShift(const int value)        { shift=value;                                  }
   int               Shift(void)                      { return shift;                                 }
//--- (1) 更改缓冲数组的大小,(2) 返回缓冲数组的大小、
//--- (3) 用设定的 "空 "值初始化数组
   bool              BuffResize(const int new_size)   { return(ArrayResize(array,new_size)==new_size);}
   uint              BufferSize(void)                 { return array.Size();                          }
   int               InitBuffer(void)                 { return ArrayInitialize(array,init_value);     }
  };

既然有 set\get-methods 方法,那么在我看来就缺少了private access specifier:

//--- 结构
struct SBuffer                // 指示器缓冲区的结构
   {
   private:
      double            array[];    // 指标数组缓冲区
      double            init_value; // 初始化数值
      int               shift;      // 水平移动缓冲区
      string            descript;   // 缓冲区说明
   public:
      //--- (1) 设置,(2) 返回初始化值、
      void              SetInitValue(const double value)
         {
         init_value = value;
         }
      double            InitValue(void)
         {
         return init_value;
         }
      //--- (1) 设置,(2) 返回缓冲区偏移量
      void              SetShift(const int value)
         {
         shift = value;
         }
      int               Shift(void)
         {
         return shift;
         }
//--- (1) 更改缓冲数组的大小,(2) 返回缓冲数组的大小、
//--- (3) 用设定的 "空 "值初始化数组
      bool              BuffResize(const int new_size)
         {
         return(ArrayResize(array, new_size) == new_size);
         }
      uint              BufferSize(void)
         {
         return array.Size();
         }
      int               InitBuffer(void)
         {
         return ArrayInitialize(array, init_value);
         }
   };


我们还需要处理缓冲区的方法...

 
Denis Kirichenko #:

有这样一种结构:

既然存在 set\get-methods 方法,那么我认为就缺少了私有 访问 规范:


我们还需要处理缓冲区的方法...

起初,我试图不把事情复杂化。