0

Speed.mq4次のようにカスタムインジケーターを作成しました。

double         SpeedBuffer[];                     // a Custom Indicator BUFFER
int OnInit() {
    SetIndexBuffer( 0, SpeedBuffer );             // an access INDEX 0->BUFFER
    ...
    }
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[] 
                 ) {
   int start;
   if (   prev_calculated == 0 ) start = 1;
   else                          start = prev_calculated - 1;

   for ( int i = start; i < rates_total - 1 ; i++ ) {                   // CPU-WASTED BY AN INEFFICIENT BACK-STEPPING IN TIME
         double curTypical  = typical( high[i],  low[i],  close[i]   );
         double prevTypical = typical( high[i+1],low[i+1],close[i+1] ); // CPU-WASTED, NO NEED TO RECALC ...
         double curSpeed    = curTypical - prevTypical;
         SpeedBuffer[i]     = curSpeed;
     }
//--- return value of prev_calculated for next call
   return( rates_total );
  }

インジケーターはアプリケーションで正常に機能し、チャートは正しくプロットされます。

ExpertAdvisor で最後の値を取得しようとすると、常に同じ値を受け取ります。

double speed = iCustom( NULL, 0, "Speed", 2, 0, 0 );
Print( "speed is: " + speed );

プリント:

速度は: 2147483647

いつも同じ数字です。どこに問題があるのか​​ わかりません。

インジケーターからPrint、値が正しく計算されていることがわかります。しかし、iCustom を使用すると、その値しか受け取りません。

4

3 に答える 3

2

MQL4 カスタム インジケーターのiCustom()仕組み

MQL4 および New-MQL4 (MQL4.5 と呼ばれることもあります) でさえ、かなり複雑なインターフェース モデルを使用して、Expert Advisor 呼び出し/カスタム インジケーターの計算を処理します。

最初に認識すべきことは、これiCustom()は関数の呼び出しではなく、「事前計算された」DataSTOREから 1 つの特定の値を取得するために、ファイル名で参照されるカスタム インジケーターに間接的に「要求」するメソッドであるということです。 .

複雑に聞こえるかもしれませんが、MQL4 の世界の初期にカスタム指標が設計されたのは、まさに CPU 効率の高い計算ファクトリの性質です。

iCustom()したがって、取得メソッドを開始するための単なる構文糖であり、事前に計算された値の関連部分を Expert Advisor の手に戻します。

カスタム インジケーターは、事前に計算されたすべての値をBUFFER (s) に入れ、DataSTORE セルの順序付けの TimeSeries スタイル ( [0] == "現在のバー"、前方に進みます [1]、[2] 、[3]、... 歴史をどんどん深く遡る )

iCustom()値をバーの数として渡します。shiftつまり、それぞれの BUFFER から要求された値を取得するために、取得メソッドが履歴をどれだけ深く掘り下げなければならないか、および BUFFER 識別 INDEX (上記の場合は 0 、 INDEX == を持つ単一の BUFFER しかないため0)。これは、EA がカスタム インジケーターの内部変数名などに完全に依存しないようにするために使用されます。

どのBarNUMBER のどの BufferINDEXから値を読み取るか尋ねるだけです。

バッファは、(間違った)値のせいにされるべき人です

コードの最初の行は次のように述べています。

double         SpeedBuffer[];                     // a Custom Indicator BUFFER

OnInit(){}SpeedBuffer 内のすべてのセルで別の方法で処理されない場合は、EMPTY_VALUE

== 2147483647 (0x7FFFFFFF)上記で反論されたように、指標バッファの空の値はデフォルトでこの値を持ちます。

QED

セルの初期化OnInit(){ ArrayInitialize( SpeedBuffer, 0.123456 ); }に他の値を指定することもできます (TimeSeries で調整された BUFFER の場合、各 new-Bar イベントで発生します (すべてのセルが 1 つ後方に再シャッフルされ、セル [0] が「空」になり、事前にロードされます)。ここで説明されているデフォルト値を使用 ) ) 。

OnCalculate(){ ... SpeedBuffer[0] = -9.87654; ...}また、セル [0] が「ちょうど」初期化された状態/値ではなく、コンテキスト不一致の状態のままになるのを避けるために、インジケーターにステップを追加することもできます。


呼び出し側インターフェース (弱い統合インターフェースのリスクを軽減する方法)

iCustom()それにもかかわらず、値の取得の責任は、インターフェイス プロキシのパラメーターを満たすため、Expert Advisor 側にあります。

>>> https://stackoverflow.com/a/26389823/3666197に示されている予防手順を使用 して、一連の値を取得するために外部のカスタム インジケーターを呼び出すと、不適切なパラメーターの順序付けや値のリスクを最小限に抑えることができます。

この単純な方法は、「間違った」番号externを提供するために、複数のインジケーター バッファーを持つ豊富なパラメーター化されたカスタム インジケーターが疑わしいと判断された場合(呼び出しパラメーターが見えないためだけに)、テスト/デバッグにかかる​​工数を文字通り数十日節約できます。適切な順序/コンテキストの )iCustom()

于 2014-10-22T13:11:26.327 に答える
0

私は自分のコードを見直し、最終的にそれを考え出した:

 double speed=iCustom(NULL,0,"Speed",2,0,0);

カスタムインジケーターによってまだ計算されていない最後の値を使用していた、

それを次のように変更します。

 double speed=iCustom(NULL,0,"Speed",2,0,1);

トリックをしました。

于 2014-10-21T18:50:14.320 に答える