文章 "在 EA 交易代码中实现指标的计算" - 页 3

 

我决定与大家分享我自己修改的 Indicator.mqh,也许它能为别人节省将指标翻译成类的时间。

附加的文件:
 
MetaQuotes:

新文章《在 Expert Advisor 代码中实施指标计算》已发布:

作者: Dmitriy GizlykDmitriy Gizlyk

这里是过去的爆炸。

这篇文章确实非常有趣!概念很好听......但我担心分布式软件中存在错误,而且留下错误也不好。


方法 GetData。分布式代码为

double CIndicator::GetData(const uint buffer_num,const uint shift)
  {
   if(!Calculate())
      return EMPTY_VALUE;
//---
   if((int)buffer_num>=m_buffers)
      return EMPTY_VALUE;
//---
   return ar_IndBuffers[buffer_num].At(m_data_len-shift);
  }

更正后的代码应为

double CIndicator::GetData(const uint buffer_num,const uint shift)
  {
   if(!Calculate())
      return EMPTY_VALUE;
//---
   if((int)buffer_num>=m_buffers)
      return EMPTY_VALUE;
//---
   return ar_IndBuffers[buffer_num].At(m_data_len-shift - 1);
  }

数组索引从 0 开始,最后一个元素的索引为 (m_data_len -1),而不是 m_data_len,对吗?

 
Use of Resources in MQL5
Use of Resources in MQL5
  • www.mql5.com
MQL5 programs not only automate routine calculations, but also can create a full-featured graphical environment. The functions for creating truly interactive controls are now virtually the same rich, as those in classical programming languages. If you want to write a full-fledged stand-alone program in MQL5, use resources in them. Programs with resources are easier to maintain and distribute.
 
你好,非常感谢
 

感谢您的文章!我正在学习它,以摆脱不稳定的传统指标。

但能在图表上 直观地显示指标 对我来说很重要。有人实施过吗?

 

为什么需要将计算从指标转移到智能交易系统?

很多人在使用指标时根本不使用 EA。

您只需将计算分成几个阶段即可。

例如

//+------------------------------------------------------------------+
//|FutData.mq5
//|版权所有 2020 - 2021, prostotrader ||
//|https://www.mql5.com ||
//+------------------------------------------------------------------+
#property copyright "Copyright 2020-2021, prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.001"
//---
#property indicator_separate_window
#property indicator_plots   1
#property indicator_buffers 1
//---
enum IND_STAGE
{
  LOAD_TICKS = 0,
  READ_TICKS = 1,
  READ_DEALS = 2,
  FILL_DATA = 3
} stage;
//+------------------------------------------------------------------+
//| 自定义指标 OnInit 函数|
//+------------------------------------------------------------------+
int OnInit()
{
  stage = LOAD_TICKS;  
//---
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 自定义指标加载刻度线功能
//+------------------------------------------------------------------+
bool LoadTicks(const datetime &a_times[])
{
  return(false);
}
//+------------------------------------------------------------------+
//| 自定义指标读取主要刻度线功能
//+------------------------------------------------------------------+
bool ReadTicks()
{
  return(false);
}
//+------------------------------------------------------------------+
//| 自定义指标 读取二级刻度线功能
//+------------------------------------------------------------------+
bool ReadDeals()
{
  return(false);
}
//+------------------------------------------------------------------+
//| 自定义指标填充数据函数
//+------------------------------------------------------------------+
void FillData()
{
//---
}
//+------------------------------------------------------------------+
//| 自定义指标计算功能
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,  
                 const int prev_calculated, 
                 const datetime& time[], 
                 const double& open[], 
                 const double& high[], 
                 const double& low[], 
                 const double& close[], 
                 const long& tick_volume[], 
                 const long& volume[],
                 const int& spread[]  
)
{
    
  if(prev_calculated == 0)
  {
      switch (stage)
      {
        case LOAD_TICKS:
          if(LoadTicks(time) == true)
          {
            stage = READ_TICKS;
          }
          return(0);
        break;
        case READ_TICKS:
          if(ReadTicks() == true)
          {
            stage = READ_DEALS;
          }  
          return(0);
        break;
        case READ_DEALS:
          if(ReadDeals() == true)
          {
            stage = FILL_DATA;
          }  
          return(0);
        break;
        case FILL_DATA:
          stage = LOAD_TICKS;
        break;
      }
  }
  else
  {
    //
  }    
  //---
  return(rates_total);
}
//+------------------------------------------------------------------+
 
prostotrader #:

为什么需要将计算从指标转移到智能交易系统?

很多人使用指标时根本不使用智能交易系统。

您只需将计算分为几个阶段即可。

例如,像这样

由于指标的常规机制是通过树桩工作的,例如:https://www.mql5.com/ru/forum/372612,这是由于它们的实施。

随着指标的复杂性不断增加,我的 Expert Advisor "陷入困境"。在测试器中,我还发现了许多指标工作中的其他错误,但我没有描述它们,因为这毫无用处。

我不明白您的想法。

Некорректная инициализация индикаторов в визуальном тестере
Некорректная инициализация индикаторов в визуальном тестере
  • 2021.07.04
  • www.mql5.com
Если делаю инициализацию индикаторов в OnInit() { } эксперта, то в визуальном тестере индикатор обычно не появляется и не отрисовывается...
 
Sunriser #:

由于常规指标机制通过树桩发挥作用,例如:https://www.mql5.com/ru/forum/372612,这是由于它们的实施。

随着指标越来越复杂,我的 Expert Advisor 也 "陷入困境"。在测试器中,我还发现了指标工作中的许多其他错误,但我没有对它们进行描述,因为这毫无用处。

我不明白您的想法。

首先,您的代码不太正确。

我会这样写:

int OnInit()
  {int  TicksTesterIndicatorHandle = INVALID_HANDLE;
   bool InitComplite=false;
   if(IndicatorInitialization() == false) return(INIT_FAILED);
    return(INIT_SUCCEEDED);
 }
void OnDeinit(const int reason)
{
     if(TicksTesterIndicatorHandle != INVALID_HANDLE) IndicatorRelease(TicksTesterIndicatorHandle);
}
void OnTick()   { //if(!InitComplite)
 // { // IndicatorInitialisation();
 // }   } //+------------------------------------------------------------------+
bool IndicatorInitialization()
   { //--获取 TicksTesterIndicator 指标句柄
    TicksTesterIndicatorHandle=iCustom(NULL, _Period, "OnInit_TestIndicator");
 //--- 需要检查是否返回了无效句柄值 
  if(TicksTesterIndicatorHandle == INVALID_HANDLE)
      {       Print("创建 TicksTesterIndicator 指标时出错 - 错误编号:",GetLastError(),"!!!");
      
   }
    else
      { 
      Print("TicksTesterIndicator 已初始化,句柄:", TicksTesterIndicatorHandle);
       ArraySetAsSeries(Buf, true);
     InitComplite=true;
     return(true);
   }
    return(false);  
 }

此外,由于指标中的函数应该以最小的延迟执行,因此复杂的过程(历史记录加载、复杂计算等)

分为几个部分,返回

OnCalculate

零值(return(0) ),也就是说,指标处于初始阶段,直到我们执行所有必要的操作,并将每个阶段的延迟降到最低。

 
В архитектуре MetaTrader 5 организован асинхронный доступ к значениям индикаторов. Иными словами, при получении хэндла индикатора он прикрепляется к графику. Далее этот индикатор производит свои расчеты вне потока советника. Они взаимодействуют лишь на этапе передачи данных, аналогично получению данных тайм-серий. Поэтому и время на выполнение этих операций сопоставимо.

你是说现实中会更快?-因为实际情况就是这样。专家在一个轨道上,指标在另一个轨道上(甚至可能在不同的内核上)。只有在串行处理的情况下,速度才会变慢,但这只是策略测试仪 的人为限制。

 
我不太明白文章中的问题,类指标是否具有保护功能?例如,连接中断了 5 个交易日,然后加载了历史记录,那么分类指示器是只重新填充钻孔中的最后一个值,还是会进行全面重新计算?