記事"インディケーターを別のインディケーターに適用"についてのディスカッション

 

新しい記事 インディケーターを別のインディケーターに適用 はパブリッシュされました:

OnCalculate() 関数呼び出しショートフォームのインディケーターを書くとき、インディケーターが価格データだけでなく、他のインディケーターデータによっても計算できる事実を見逃すかもしれません。 (内蔵またはカスタムのインディケーターにかかわらず)。他のインディケーターデータに正しく適用するためにインディケーターを改善したいですか?本記事ではそのような修正に必要なステップを復習します。

作者: MetaQuotes Software Corp.

 

今回も良い記事をありがとう。従来、MQL Communityの記事は私が中等 教育(内蔵のMQLエディターズガイドを意味する)を受けるための手段となっていた

その点、私はコードに小さな欠陥があることに気づいた。著者の考えによると

//--- price[]の値を1回だけ出力するフラグ

変数

   bool printed=false;

変数はOnCalculate()関数の 外側に移動させるべきで、そうしないとイベントごとに配列の印刷が発生してしまう。

ここにも誤植がある。

Правило передачи PLOT_DRAW_BEGIN в параметр begin: Значение входного параметра begin в OnCalculate(), при расчетах пользовательского индикатора A на данных другого (базового) индикатора B, всегда равно значению свойства PLOT_DRAW_BEGIN  нулевого графического построения базового индикатора B.

このように、周期が14のRSI インディケータ(インディケータA)を 作成し、RSI(14)インディケータデータでカスタムインディケータTrue Strength Index(インディケータB)を構築したとします:

ルールとロジックから判断すると、インディケータAはカスタムTSIで、インディケータB(基本)はRSIです

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
Основы языка / Функции / Функции обработки событий - Документация по MQL5
 

この記事には詳細な知識が含まれている。

ありがとう。

 

こんにちは、

この記事は本当に興味深く、インジケーターを管理する新しい機会を与えてくれます。

私はMQL5の初心者なので、あるインディケータを別のインディケータに適用する可能性を実装しようとしました。私は小さなコードを書きました。

アダプティブ移動平均を チャートのどのインジケータにも使用できることを期待しています。

残念ながら、インジケータを起動したときに表示されるパラメータのリストには、「apply to : previuos indicator's data」という項目がありません。

別のインジケーターに適用するには、どのようにコードを構成すればよいでしょうか?

以下は私のコードです:

#property indicator_separate_window
#property indicator_minimum             1.3
#property indicator_maximum             1.35
//#プロパティ indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   1
//--- プロットdMA
#property indicator_label1  "dAMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- 入力パラメータ
input int      AMAPeriod=9;
input int      FastEMA=2;
input int      SlowEMA=20;
//--- インジケータ・バッファ
double         AMABuffer[];
double         dAMABuffer[];

int            h_dAMA;
int            h_AMA;
//+------------------------------------------------------------------+
//| カスタムインジケータ初期化関数
//+------------------------------------------------------------------+
int OnInit()
  {
//--- インジケータ・バッファのマッピング
   SetIndexBuffer(0,dAMABuffer,INDICATOR_DATA);
   SetIndexBuffer(1,AMABuffer,INDICATOR_CALCULATIONS);
   
   
   
   //PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MAPeriod+1);
   
   h_AMA=iAMA(_Symbol,PERIOD_CURRENT,AMAPeriod,FastEMA,SlowEMA,0,PRICE_CLOSE);
   if(h_AMA == INVALID_HANDLE)
    {
      Print("AMA indicator initialization error, Code = ", GetLastError());
      return(-1);
    }
   ArraySetAsSeries(AMABuffer,true);
   ArraySetAsSeries(dAMABuffer,true);
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MathMax(AMAPeriod,SlowEMA));
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| カスタム・インジケータ反復関数|
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,    // 価格[]配列のサイズ
                const int prev_calculated,// 前の呼び出しで処理されたバーの数
                const int begin,          // 重要なデータがどこから始まるか
                const double &price[]     // 計算のための配列
                )
  {
   
   if(BarsCalculated(h_AMA)<rates_total) return(0);
//--- すべてのデータをコピーできるわけではない
   int to_copy;
   if(prev_calculated>rates_total || prev_calculated<=0) 
     {
      to_copy=rates_total;
      if(CopyBuffer(h_AMA,0,0,to_copy,AMABuffer)<=0) return(0);
      for (int i=0;i<to_copy-MathMax(AMAPeriod,SlowEMA);i++)
          {
            dAMABuffer[i]=AMABuffer[i];
          }
     }
   else
     {
      to_copy=rates_total-prev_calculated+MathMax(AMAPeriod,SlowEMA)-1;
      //--- 最後の値が常にコピーされる
      to_copy++;
      if(CopyBuffer(h_AMA,0,0,to_copy,AMABuffer)<=0) return(0); 
      for (int i=0;i<to_copy;i++)
         {
            dAMABuffer[i]=AMABuffer[i];
         }
     }
//--- コピーしてみる
   
   Print(dAMABuffer[0]); //最後まで行けるかどうか
//--- 次の呼び出しのためにprev_calculatedの値を返す
//---
//--- 次の呼び出しのためにprev_calculatedの値を返す
   return(rates_total);
  }
//+------------------------------------------------------------------+
 

こんにちは、

一つのインジケータを 同じ ウィンドウにある別のインジケータに 適用することしかできません。

メイン・ウィンドウにある別のインジケータに、1つのインジケータを適用する(別のウィンドウに表示する)方法をご存知ですか?

ありがとうございます。

ベスト

 

プログラムでインジケータを作成し(例えばiCustomで)、別のインジケータからデータを入力するように指示することはできますか?あるいは、インジケータを構築するためのデータの配列を直接インジケータに 渡すこともできます。

 
ds2:

プログラムでインジケータを作成し(例えばiCustomで)、別のインジケータからデータを入力するように指示することはできますか?あるいは、さらに良い方法として、インジケータを構築するためのデータ配列を直接インジケータに与えることは可能でしょうか?

iCustom 関数を参照してください:

最初の呼び出し形式が インジケータで使用されている場合、「Parameters」 タブでカスタム・インジケータを起動する際に、どのデータを基に計算す るかを追加で指定することができます。Apply to (適用先)」パラメータが明示的に選択されていない場合、デフォ ルトでは「Close (終値)」値によって計算が実行されます。

mql5プログラムからカスタムインジケータを呼び出す場合、Applied_Priceパラメータまたは別のインジケータのハンドルは、カスタムインジケータが提供するすべての入力変数の後で最後に渡す必要があります

 

こんにちは、

とても良い記事ですが、いくつか質問があります。

1.OnCalculate() 関数コールの ショート フォームを 使用するインジケーターだけを 別のインジケーターにアプライ する ことができますか? もしそうなら、OnCalculate() 関数コールの 長い フォームを 使用するインジケータを 別の インジケータに適用 できますか?

2.あるインディケータを別のインディケータに適用すると(RSIよりTSI)、表示上の問題が発生します(添付画像参照)。RSIは0から100までプロットされていますが、2つ目のインジケータ(TSI)は0以下の値も持っています。Wichが問題で、なぜチャートが両方のインジケータを正しく表示するように調整できないのでしょうか。MetaTraderのバグでしょうか?

ファイル:
RSIcTSI.png  32 kb
 
Rosh:

インジケーターからインジケーターを 作ることにしたのですが、混乱に出くわしました。

どちらのインジケータも

int OnCalculate (const int rates_total,      // 価格[]配列のサイズ
                 const int prev_calculated,  // 前の呼び出しで処理されたバー
                 const int begin,            // 重要なデータが始まるインデックス в массиве price[]
                 const double& price[]       // 計算のための配列
   );

したがって、ユーザーはパラメータにapplied_priceフィールドを設定することができます。

私が困っているのは、applied_priceフィールドを内部インジケータ(外部インジケータが構築される元)にどのように渡すかということです。

最も簡単な解決策は、入力を作成し、applied_price入力とapplied_priceパラメータが同じであるべきであることをユーザーに警告することですが、これはちょっと曲者です。

 

OnCalculate()の 例をご覧になりましたか?

Для получения значений пользовательского индикатора из других mql5-программ используется функция iCustom(), возвращающая хэндл индикатора для последующих операций. При этом также можно указать необходимый массив  price[] или хэндл другого индикатора. Этот параметр должен передаваться последним в списке  входных переменных пользовательского индикатора.
 
Пример:

void OnStart()
  {
//---
   string terminal_path=StatusInfoString(STATUS_TERMINAL_PATH);
   int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL);
   if(handle_customMA>0)
      Print("handle_customMA = ",handle_customMA);
   else
      Print("Cannot open or not EX5 file '"+terminal_path+"\\MQL5\\Indicators\\"+"Custom Moving Average.ex5'");
  }

この例では、最後に渡されるパラメータは PRICE_TYPICAL 値 (ENUM_APPLIED_PRICE 列挙からの) で、これはカスタム・インディケータが (High+Low+Close)/3 として得られる典型的な価格によって構築されることを示します。このパラメータが指定されない場合、インジケータはPRICE_CLOSE値、すなわち各バーの終値によって構築されます。

 
Rosh:

OnCalculate() の例を見ましたか?


はい、

int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL);

applied_priceはiCustomが呼び出されるときに明示的に指定されますが、iCustomが呼び出されるインジケータでは、どこで取得するのですか?

なぜなら、ユーザーが入力ではなくパラメータで設定するからです。

int OnInit()
  {
//--- インジケータ・バッファのマッピング
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   hndl=iCustom(_Symbol,_Period,"MyInd",param_ind,???? вот тут нужно указать аплиед_прайс который будет задавать пользователь);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| カスタム・インジケータ反復関数
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
 //...
 return(rates_total);
}

PSトリックは、ユーザーが一度applied_priceパラメータを設定し、それ以上、この値が呼び出しのピラミッド全体を通過したことを気にしなかったということです。