記事"任意のインジケータの計算部分をEAのコードに転送する方法"についてのディスカッション - ページ 3

 

自分用に修正したIndicator.mqhを共有することにした。もしかしたら、誰かがインジケーターをクラスに翻訳する時間を節約できるかもしれない。

ファイル:
 

過去の記事です。

実に興味深い記事だ!しかし、私は配布されたソフトウェアに間違いがあることを恐れている。


メソッド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ではなく(m_data_len - 1)ですね?

 

rf、https://www.mql5.com/ja/articles/261カスタム・インジケータでの作業 セクション

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.
 
どうもありがとう。
 

記事をありがとう!不安定な従来のインジケーターから脱却するために勉強しています。

しかし、チャート上でインジケータを 視覚化できることは私にとって重要です。どなたか導入された方はいらっしゃいますか?

 

なぜインジケータからExpert Advisorに計算を転送する必要があるのでしょうか?

多くの人はEAを使わずにインディケータを使用しています。

単純に計算を段階に分けることができます。

例えば、このように:

//+------------------------------------------------------------------+
//|FutData.mq5
//|著作権:2020年-2021年、プロストトレーダー|。
//|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 #:

なぜインジケータからExpert Advisorに計算を転送する必要があるのですか?

多くの人は、Expert Advisorを全く使用せずにインジケーターを使用しています。

単純に計算を段階に分けることができます。

例えば、このように:

インジケータの通常のメカニズムが切り株を介して動作するという事実のために、例えば:https://www.mql5.com/ru/forum/372612、これは彼らの実装によるものです。

インジケータの複雑化に伴い、私のExpert Advisorは "泥沼 "に陥った。テスターでは、インジケータの動作で他の多くのバグをキャッチしたが、それは役に立たないので、私はそれらを説明しませんでした。

私はあなたの考えを理解していませんでした。

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

通常のインジケーター機構が切り株を通して機能するという事実のため , e.g.: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

つまり、インジケーターは、各段階で最小限の遅延で必要なアクションをすべて実行するまで、初期段階にあります。

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

現実にはもっと速くなると?-現実にはそうなる。あるトラックではエキスパート、別のトラックではインジケーター(そしておそらく異なるコアでも)。しかし、これはストラテジーテスターによる 人為的な制限に過ぎません。

 
記事を読んでもよくわからなかったのですが、クラス・インジケータはバーの欠落に対する保護機能を持っているのでしょうか?例えば、5小節の接続中断があり、その後履歴が読み込まれた場合、class-indicatorはドリルの最後の値のみを補充するのでしょうか、それとも完全な再計算を行うのでしょうか?