MQL4、MQL5に関する初心者からの質問、アルゴリズムやコードに関するヘルプ、ディスカッションなど。 - ページ 683

 
Igor Makanu:

最初でもどこでも初期化せず、ただ宣言しただけなんですね

使用前に書いたことですが、つまり、配列の値の合計として変数SredRazmax, SredRazmin, Srednがある場合、正しく合計を計算するためには、変数をゼロにしてから配列の値を足してこの変数に保存しておく必要があります。

即ち

次に、ご質問の件ですが、このインジケータでは、1ティックごとにOnCalculate() が呼び出され、1ティックごとに、つまり1秒間に40~60回程度、常にZigZagの先頭をカウント することになるのです。

しかし、私はそれらをゼロにし、OnCalculate() の代わりにOnStartを 使用して みました値はまだジャンプしており、ww=0(配列値が常に表示されている)場合、なぜ値が途中でジャンプ するのか私にはわかりません。

 
Dmitry Belov:

ありがとうございます。でも、ゼロにしたり、OnCalculate() の代わりにOnStartを使って みたりしました。

なぜそうなるのか説明できないと思いますが、問題はOnStart()がスクリプトで、OnCalculate()がインジケータで使われていることです。 MQLのスクリプトとインジケータの違いを理解する必要があります。

このコードでは、ZigZagのピークが位置する価格をチャート全体で合計し、出力に「平均スプレッド」と書いて、値(SredRazmax-SredRazmin)/nnを表示し、すべてのバーについて計算を実行します。

インジケータバッファを 描画に使用しないのであれば、なぜインジケータが必要なのでしょうか? インジケータバッファはバーに取り付けられており、新しいバーが現れると同時にその値が移動します

 
Igor Makanu:

なぜそうなるのか説明できないと思います。ポイントは、OnStart()はスクリプトで、OnCalculate()はインジケータで使われていることで、MQLではスクリプトとインジケータがどう違うかを理解する必要があります。

このコードでは、ZigZagのピークが位置する価格をチャート全体で合計し、出力に「平均スプレッド」と書いて、値(SredRazmax-SredRazmin)/nnを表示し、すべてのバーについて計算を実行します。

インジケータバッファを 描画に使用しないのであれば、なぜインジケータが必要なのでしょうか? インジケータバッファはバーに取り付けられており、新しいバーが表示されるとすぐにその値が移動します。

正直なところ、問題を単純化した(元の計算式は少し違うようです)のは、配列の0値が一定なのに平均値の値がジャンプする理由がわかると思ったからです。2つのループがあり、1つは配列を埋めるため、もう1つは平均を計算するためで、nnの限界があります。実はグラフを出力したかったのですが、標準のジグザグですが、iCustomは地獄を描いていて、平均は...ゼロノードから、前のノードより大きければ、前のノードとその前のノードを引き(マイナス記号になるので、マイナス1を掛ける)、これをすべて合計して、与えられたnn個のノード数で割る必要があります。頂点の平均的なスパンを得ることができる。さらに、ジグザグに他の平均値を求めたかったのですが、「ジャンプ」の値で引っかかってしまいました。

元々は大体こんな感じです。

//+------------------------------------------------------------------+
//|                                                           01.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

#property indicator_buffers 1
#property indicator_color1 Red
#property indicator_width1 1

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

extern int ExtDepth=12;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
extern int nn=30;

int shift, ww=0;
double zz, SredRazmax=0.0; 
double HZZ[];


int OnInit()
  {
//--- indicator buffers mapping
    SetIndexBuffer(0,HZZ);
  SetIndexStyle(0,DRAW_SECTION);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
  for(shift = 0; shift <= Bars-1; shift++){
      zz = iCustom(NULL, 0, "ZigZag", ExtDepth, ExtDeviation, ExtBackstep, 0, shift);
           if(zz > 0.0)   {
           HZZ[ww]=zz;
            ww++;          }
           else {
           continue;
           }
    }
//---------------------------------------------+
//расчет среднего значения           
//---------------------------------------------+      
  for(ww=0;ww<=nn;ww++){
       if(HZZ[ww]>HZZ[ww+1]){
          SredRazmax += (HZZ[ww]- HZZ[ww+1]);      
         }     
        else if(HZZ[ww]<HZZ[ww+1]){
         SredRazmax += (HZZ[ww]- HZZ[ww+1])*(-1);
        }
        else{
        continue;
           }
     }  
        
  if(SredRazmax>0){    
   
      Comment("Средний размах = ", SredRazmax/nn,",",HZZ[0],",",HZZ[1],",",HZZ[2],",",HZZ[3],",",HZZ[4]);      
        }
   
       
//--- return value of prev_calculated for next call
 return(0);

  
 
  }
 
Dmitry Belov:

正直、問題を単純化しただけなのですが(本来はもう少し違う式になる)、配列の0値が一定であれば、平均値の値がジャンプする理由がわかるような気がしたのです。2つのループがあり、1つは配列を埋めるため、もう1つは平均を計算するためで、nnの制限があります。実はグラフも出力したかったのですが、標準のジグザグですが、iCustomは地獄を描き、平均は...ゼロノードから、前のノードより大きければ前のノードを引き、前のノードから前のノードを引き(マイナス記号になるので、マイナス1を掛ける)、これらを合計して、与えられた数nnで割ればよいのです。頂点の平均的なスパンを得ることができる。さらに、ジグザグに他の平均値を求めたかったのですが、「ジャンプ」の値で引っかかってしまいました。

元々はだいたいこんな感じです。

よくわからない、もう遅い、眠い、見たままいじった、ゼロバーでインジケーターがどう動くか疑問(確認してない)、でも先生の計算式通りに描画してコメント表示する

//+------------------------------------------------------------------+
//|                                                           01.mq4 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

#property indicator_buffers 1
#property indicator_color1 Red
#property indicator_width1 1

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

extern int ExtDepth=12;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
extern int nn=30;

int  ww=0;
double zz,SredRazmax;
double HZZ[];
bool up,dn;
double lastzz;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,HZZ);
   SetIndexStyle(0,DRAW_SECTION);
   SetIndexEmptyValue(0,0.0);
   up = false;
   dn = false;
   lastzz=0.0;
   SredRazmax=0.0;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   int shift,limit;
//--- Первый вызов индикатора или смена таймфрейма или подгрузка данных из истории
   if(prev_calculated==0)
     {
      limit=rates_total-1;
      up = false;
      dn = false;
      lastzz=0.0;
      SredRazmax=0.0;
      ArrayInitialize(HZZ,0.0);
     }
   else limit=rates_total-prev_calculated+1;
   for(shift=limit; shift>=0; shift--)
     {
      zz=iCustom(NULL,0,"ZigZag",ExtDepth,ExtDeviation,ExtBackstep,0,shift);
      if(zz>0.0)
        {
         HZZ[shift]=zz;
         if(lastzz>zz) {up=true;  dn=false;}
         if(lastzz<zz) {up=false; dn=true;}
         if(up) SredRazmax+=zz-lastzz;
         if(dn) SredRazmax+=(zz- lastzz)*(-1);
         lastzz=zz;
        }
      else HZZ[shift]=0.0;
     }
   Comment("Средний размах = ",SredRazmax/nn,",",HZZ[0],",",HZZ[1],",",HZZ[2],",",HZZ[3],",",HZZ[4]);
   return(rates_total);
  }
//+------------------------------------------------------------------+
 

このような問題を解決することは可能でしょうか?(可能であれば)

Expert Advisor は、特定の条件下でアラートを 発行します。Alertを発生させたウィンドウもアクティブにすることは可能ですか?

 
Vatal:

このような問題を解決することは可能でしょうか?(可能であれば)

Expert Advisor は、特定の条件下でアラートを発行します。Alertを発生させたウィンドウもアクティブにすることは可能ですか?

ドキュメントに例があります。EAが動作しているチャートのIDを取得し、...
Примеры работы с графиком - Константы графиков - Константы, перечисления и структуры - Справочник MQL4
Примеры работы с графиком - Константы графиков - Константы, перечисления и структуры - Справочник MQL4
  • docs.mql4.com
В этом разделе представлены примеры для работы со свойствами графика. Для каждого свойства приведены одна или две законченные функции, которые позволяют задавать/получать значение этого свойства. Эти функции можно использовать в своих MQL4 программах как есть. На рисунке показана графическая панель для наглядной демонстрации того, как изменение...
 
Igor Makanu:

ゼロバーでインジケータがどのように動作するかは疑問ですが(確認していません)、描画は行い、コメントを出力するためにあなたの計算式を使用します。

はい、ありがとうございます!うまくいきました!何か間違ったことをしたのでしょう。しかし、コメントで配列が出力されない(頂点しかないはずですよね)、マイナスや数字のカウントがおかしい...、ジグザグは頂点間の広がりが違う。つまり、最後にできた大きな頂点から、その前の小さな頂点を引き、さらにその前の小さな頂点から、大きくなった頂点を引くと、マイナス記号がつくので、それに(-1)などをかけて、これをnn回合計して、nnで割ると、平均の出方がわかるというものです。およそ4本の時計でUSDJPYの1.69(から)となります。さらに、トップとトップの間の平均バー 数を計算したかった。これから、あなたのコードを理解して、何が間違っていたのか、なぜ描画されなかったのか、なぜ正しく計算されないのか...を理解しようと思います。

 
Dmitry Belov:
はい、ありがとうございます。本当にうまくいくんですね。何か間違ったことをしたのでしょう。しかし、コメントにある配列が出力されない(頂点しかないはずですよね)、マイナスや数字のカウントがおかしい...、ジグザグは頂点の広がりが違う。つまり、最後にできた大きな頂点から、その前の小さな頂点を引き、さらにその前の小さな頂点から、大きくなった頂点を引くと、マイナス記号がつくので、それに(-1)などをかけて、これをnn回合計して、nnで割ると、平均の出方が出てくるというものです。およそ4本の時計でUSDJPYの1.69(から)となります。さらに、トップとトップの間の平均バー 数を計算したかった。これから、あなたのコードを理解し、何が間違っていたのか、なぜ描画されないのか、なぜ正しく計算されないのか...を理解しようと思います。

コメント中のtopsは、インジケータバッファHZZ[]にインジケータバッファZigZagのコピー値が格納されて いるため、出力されません、そうしないと描画できないので、あえて頂点検出の条件を上下の2 つに分けました。

if(up) SredRazmax+=zz-lastzz;
if(dn) SredRazmax+=(zz- lastzz)*(-1);

もし、ZZのいくつかの頂点を知る必要があるなら、このデータを格納するために別の配列を作成しなければなりません。 新しい指標バッファは、新しいバーが現れると、指標バッファに接続されたすべての配列がチャートと一緒に「スライド」するので、それを複雑に するでしょう。

ZS:コードは私の例であり、私はそれが最初のバーではなく、0にループする必要があると思いますが、常にSredRazmaxの値を再計算します、私は今、PCのない端末をチェックすることはできません。

 
Igor Makanu:

コメント中のtopsは、インジケータバッファHZZ[]にインジケータバッファZigZagのコピー値が格納されて いるため、出力されません、そうしないと描画できないので、あえて頂点検出の条件を上下の2 つに分けました。

もし、ZZのいくつかの頂点を知る必要があるなら、このデータを格納するために別の配列を作成しなければなりません。 新しい指標バッファは、新しいバーが現れると、指標バッファに接続されたすべての配列がチャートと一緒に「スライド」するので、それを複雑に するでしょう。

SZY:コードは私の例であり、私はそれが最初のバーではなく、0にループする必要があると思いますが、常にSredRazmaxの値を再計算します、私は今、PCのない端末をチェックすることはできません。

私のインジケータはロードされるとすぐに正しい値を表示し、その後、ジグザグ配列の出力値ではトップの変化はありませんが、すべてのティックは、平均の値を増加させます。そこが理解できない、なぜこうなんだ?経験も知識も不足している。描画は諦めます。iCustumで取った普通のジグザグです(グラフに配列を重ねることができないので、地獄のような描画をするのだと今になって理解しました。)。配列は "クロール "しますが、その後、値は再計算されるだけですよね? ということですね。やってみる・・・学習・・・。
 
EA(標準マ)に、平均がクロスしたときだけ買い(売り)、一般的にはma_1>ma_2のときは買わない、と説明するにはどうしたらいいのでしょう?しかし、それは常に買い続け、止めることができない。