1

の2つのバッファーでクオンタイズして実行しようと何度も失敗しています。長い間読んだ後、私はそれを押しつぶすために2つの余分なバッファを入れました:/理由:

インジケーターは現在0.1430〜0.1427の間にありますが、上下が固定されていません

私はそれを口にすることができないようです。クールなインジケーターですが、公平にプレイできません!

#property indicator_separate_window
#property indicator_buffers   4
#property indicator_color1    Lime
#property indicator_color2    Red
#property indicator_color3    CLR_NONE
#property indicator_color4    CLR_NONE
//#property indicator_minimum 0
//#property indicator_maximum 100
extern int    P   =   13;
extern int    T   = 3000;
extern double P2  =    0.001;
//int         MIN =    0;
//int         MAX =  100;
double G[];
double R[];
double B3[];
double B4[];

int init(){
   IndicatorBuffers(4);
   SetIndexBuffer( 0, G  );SetIndexStyle( 0, DRAW_LINE, STYLE_SOLID, 1, Lime );
   SetIndexBuffer( 1, R  );SetIndexStyle( 1, DRAW_LINE, STYLE_SOLID, 1, Red  );
   SetIndexBuffer( 2, B3 );SetIndexStyle( 2, DRAW_NONE );
   SetIndexBuffer( 3, B4 );SetIndexStyle( 3, DRAW_NONE );
   return(0);
}
int start(){
      if (  T >= Bars ) T = Bars;

      SetIndexDrawBegin( 0, Bars - T + P + 1 );
      SetIndexDrawBegin( 1, Bars - T + P + 1 );
      SetIndexDrawBegin( 2, Bars - T + P + 1 );
      SetIndexDrawBegin( 3, Bars - T + P + 1 );

      int Z, C, Opt = IndicatorCounted();

      if (  Bars <= 38 ) return(0);

      if (  Opt  <  P ){
         for ( Z = 1; Z <= 0; Z++ ) G[T-Z] = 0.0;
         for ( Z = 1; Z <= 0; Z++ ) R[T-Z] = 0.0;
      }

      Z = T - P - 1;

      while( Z >= 0 ){
         double A, S1, S2;
         S1 = 0.0; for ( C = 0; C <= P - 1; C++ ){ S1 = S1 + (   High[Z+C] + Low[Z+C] ) / 2;}
         S2 = 0.0; for ( C = 0; C <= P - 1; C++ ){ S2 = S2 + ( ( High[Z+C] + Low[Z+C] ) * ( C+1 ) / 2 );}
         A  = S1 / S2;
         // if (  A < MIN ){ MIN = A;}
         // if (  A > MAX ){ MAX = A;}
         // A = ( MIN / MAX ) * 100;
         G[Z] = A;
         if (  Z > 0 ){ R[Z-1] = A;}
         Z--;
      }
      for ( int N = T-P-2; N >= 0; N-- ){
         if (  N > 0 ){
               if ( G[N-1] > G[N] ){ R[N] = EMPTY_VALUE; continue;}
               if ( G[N-1] < G[N] ){ G[N] = R[N];        continue;}
         }
         B3[0] = G[0] + P2;
         B4[0] = G[0] - P2; //forced quantise using 2 extra buffers
      }
      return(0);
   }
4

1 に答える 1

1

最初にタスクを分割しましょう

0)インジケーターロジック
1)インジケーター量子化ステップ
2)インジケーターパフォーマンス

MQL4MetaTrader4 Terminalカスタムインジケータープログラミングは、基盤となるプラットフォームのより深い理解に依存しています。QUOTE ...取引された商品価格を変更する各外部マーケットイベントは、からのメッセージのネットワーク配信によってlcoalhostに通知されますMetaTrader4 Server。これは別名Tickであり、元々はと呼ばれていた関数の呼び出しをトリガーします。start()新しいNewでは名前が。MQL4.56789に変更されましたOnTick()

以下の変更されたMQL4リストには、コアロジックの曖昧性解消に関する注釈が含まれています。これは、以下にリストされているすべての手順の前に行う必要があります。


1)インジケーターの量子化ステップ

コードはまだ非常に非効率的ですが(以下の[2]のように)、ロジックには、出力が任意の形式に量子化されたストレートハードル形式は含まれていません{binary | 三元| 任意の状態数}-量子化されたシステム。インジケーターのコアロジックがクリアされると、量子化ステップはR(1)からI(1 )への簡単な変換になります。


2)インジケーターのパフォーマンス

ティックの到着は、提案されたカスタムインジケーター計算の唯一の可変部分であるまたはのいずれかを変更できますが、変更する必要はありません。High[0]Low[0]

これは、再計算の範囲を縮小する方法の中心的なアイデアであり、MQL4コードはティックごとに実現する必要があります。MT4の最近のバージョンでは、すべてのカスタムインジケーターが単一のスレッドを共有し、カスタムインジケーターの効率的なアルゴリズム化により多くのストレスがかけられています。これらは、不十分で非効率的なコードループおよび畳み込み/再帰の再実行に関するプラットフォームの取引決定をブロックする可能性があります。

#property indicator_separate_window
#property indicator_buffers   4
#property indicator_color1    Lime
#property indicator_color2    Red
#property indicator_color3    CLR_NONE
#property indicator_color4    CLR_NONE

extern int    P   =   13;
extern int    T   = 3000;
extern double P2  =    0.001;

double G[];                                                         // 0: LINE
double R[];                                                         // 1: LINE
double B3[];                                                        // 2: BUT NEVER PAINTED, NEVER CONSUMED _?_
double B4[];                                                        // 3: BUT NEVER PAINTED, NEVER CONSUMED _?_

int init(){
   IndicatorBuffers(4);
   SetIndexBuffer( 0, G  );SetIndexStyle( 0, DRAW_LINE, STYLE_SOLID, 1, Lime );
   SetIndexBuffer( 1, R  );SetIndexStyle( 1, DRAW_LINE, STYLE_SOLID, 1, Red  );
   SetIndexBuffer( 2, B3 );SetIndexStyle( 2, DRAW_NONE );
   SetIndexBuffer( 3, B4 );SetIndexStyle( 3, DRAW_NONE );
   return(0);
}
int start(){

    if (  Bars <= 38 ) return(0);                                   // JIT/RET in case Bars < 39 --^ --^ --^ --^

    if (  T >= Bars ) T = Bars;                                     // (TRIM´d) T < Bars .OR. = Bars

    int aDrawBegins     = Bars - T + P + 1;                         // ( extern P = 13 ) + 1 + ( Bars - ( extern T = 3000 if T < Bars else Bars ) )
    //tIndexDrawBegin( 0, Bars - T + P + 1 );                       // PREF: ( reused 4x )
    SetIndexDrawBegin( 0, aDrawBegins );                            // Draw  14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw?
    SetIndexDrawBegin( 1, aDrawBegins );                            // Draw  14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw?
    SetIndexDrawBegin( 2, aDrawBegins );                            // Draw  14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw?
    SetIndexDrawBegin( 3, aDrawBegins );                            // Draw  14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw?

    double A, S1, S2;                                               // auxiliary var for bar-mid-price calculi
    int    Z;                                                       // auxiliary stepper
    int    Opt = IndicatorCounted();                                // Opt ( NEVER RE-USED )

    if (  Opt  <  P ){                                              // if ( ( extern P = 13 ) > IndicatorCounted() )
       // ----------------------- ??? ----------------------------------------------------- NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 )
       for ( Z = 1; Z <= 0; Z++ ) G[T-Z] = 0.0;                     // .STO G[T-Z], 0., BUT NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 )
       for ( Z = 1; Z <= 0; Z++ ) R[T-Z] = 0.0;                     // .STO R[T-Z], 0., BUT NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 )
       // ----------------------- ??? ----------------------------------------------------- NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 )
    }

    Z = T - P - 1;                                                  // .STO Z, ( T = Bars (TRIM´d) ) - ( extern P = 13 ) - 1

    while( Z >= 0 ){                                                // .DEC Z
       //        !!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PERF: very inefficient to RE-calc STATIC ( ( extern P = 13 ) - 1 )-DEEP CONVOLUTIONS per tick !!
       S1 = 0.0; for ( int C = 0; C <= P - 1; C++ ){ S1 = S1 + (   High[Z+C] + Low[Z+C] )           / 2;  }
       S2 = 0.0; for ( int C = 0; C <= P - 1; C++ ){ S2 = S2 + ( ( High[Z+C] + Low[Z+C] ) * ( C+1 ) / 2 );}
       //        !!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PERF: very inefficient to RE-calc STATIC ( ( extern P = 13 ) - 1 )-DEEP CONVOLUTIONS per tick !!
       A  = S1 / S2;
       G[Z] = A;                                                    // .STO G[Z],   A if Z >= 0
       if (  Z > 0 ){ R[Z-1] = A;}                                  // .STO R[Z-1], A if Z >  0
       Z--;
    }

    for ( int N = T - P - 2; N >= 0; N-- ){                         // .STO N, ( T = Bars (TRIM´d) ) - ( extern P = 13 ) - 2
       if (   N > 0 ){                                              // N > 0:
              if ( G[N-1] > G[N] ){ R[N] = EMPTY_VALUE; continue;}  // .BLNK R[N], EMPTY if G[N-1] > G[N]
              if ( G[N-1] < G[N] ){ G[N] = R[N];        continue;}  // .SET  G[N], R[N]  if G[N-1] < G[N]
       }
    // ?? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // WHY MANY-TIMES RE-ASSIGNED A CONST. VALUE HERE, INSIDE A FOR(){...}-loop body? -------------- ??
       B3[0] = G[0] + P2;                                           // .STO B3[0], G[0] + ( extern P2 = 0.001 )
       B4[0] = G[0] - P2;                                           // .STO B4[0], G[0] - ( extern P2 = 0.001 )
                                                                    // forced quantise using 2 extra buffers
    // ?? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // WHY MANY-TIMES RE-ASSIGNED A CONST. VALUE HERE, INSIDE A FOR(){...}-loop body? -------------- ??
    }
    return(0);
}

新規-MQL4.56789構文

このOnCalculate()関数は、によってインジケーター値を計算する必要がある場合にのみ、カスタムインジケーターで呼び出されますCalculate event。これは通常、インジケーターが計算されるシンボルに対して新しいティックが受信されたときに発生します。このインジケーターは、このシンボルの価格チャートに添付する必要はありません。

最初のrates_totalパラメーターには、bars計算用のインジケーターで使用可能なの数が含まれ、チャートで使用可能なバーの数に対応します。

OnCalculate()の戻り値と2番目の入力パラメータの関係に注意する必要がありますprev_calculatedOnCalculate()関数呼び出し中に、パラメーターには前の呼び出し中にprev_calculated返された値が含まれます。これにより、カスタムインジケーターを計算するための経済的なアルゴリズムが可能になり、この関数の前回の実行以降に変更されていないバーの繰り返し計算を回避できます。OnCalculate()

このためには、通常rates_total、現在の関数呼び出しのバーの数を含むパラメーターの値を返すだけで十分です。価格データの最後の呼び出しOnCalculate()が変更された場合(より深い履歴がダウンロードされたか、履歴ブランクが埋められた場合)、入力パラメーターの値はprev_calculated 端末によってゼロに設定されます。

//+------------------------------------------------------------------+ 
//| Custom indicator iteration function                              | 
//+------------------------------------------------------------------+ 
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[]
                  )
  {
  // Get the number of bars available now for the current Symbol and chart period 
     int barsNow = Bars( _Symbol, PERIOD_CURRENT );

  // .RET value of prev_calculated for a next call
     return( rates_total );
  }
于 2016-07-18T11:17:59.503 に答える