[ARCHIVE!] フォーラムを散らかさないように、どんなルーキーの質問でも。プロフェッショナルは、通り過ぎないでください。あなたなしではどこにも行けない - 4. - ページ 479

 
SetIndexDrawBegin(0,Bars-30);//первый бар отрисовки индикатора 

あなたのロジックがどのようなものかわかりませんが、私の場合、この設定はインジケータの最後の30本のバーを描画します。

もう一度、SetIndexDrawBegin()は、チャートの左端からバーを計算します。

は、議論する前にチェックしてください。

 
merkulov.artem:

OKです。私は問題の本質を概説しようと思います、多分誰かが提案するか、より簡単な方法でそれを実装するのを助けるでしょう。

分表に取り組んでいます。29/10/12チャートの00:00の1分足バー(高値+安値/2-バーの平均値)を参考にしましょう。

そして、この価格から10ピップ上方への乖離を確認します(正しい乖離は1回につき+1)。

スタート地点からの乖離が10ポイントに達すると、+1カウンターになり、さらに乖離をチェックし始めますが、10ポイントに達した地点から、次の10ポイントの値上がりを待ちます。

例えば、次のようになる。

(開始点) + 10 pips <= 価格 (開始点から続く全てのバーの価格を使用します。) カウンター = カウンター +1; を取得し、開始点は既にこの点 -(開始点 + 10 pips) から開始されます。

(開始点+10pips)+10pips <= 価格 (基準点から続く全てのバーの価格が使用される)の場合、counter=Counter+1; となり、この点から開始 します -(開始点+10pips)+10pips.

(スタートポイント+10pips+10pips)+10pips<=価格(基準点からその後の全てのバーの価格を使用します。)の場合、カウンター=カウンター+1となり、この点からスタートします-(スタートポイント+10pips+ 10pips)+10pips.

などなど...。

カウンタが10になるまで(counter == 10)。

そして、新しく形成された1分足のバー(high+low/2 - バーの平均値)ごとに、この条件をチェックし、 カウンターが10に 達するまで待ちますカウンター== 10仮に2日経過して、新しいバーができるたびに、条件が合っているかどうかをチェックしてシフトしていった・・・・・。

そして、counter =10になったとき - "Counter == 10 "というメッセージを出力するのです。最初のユーザー定義ポイントから2日先に開始ポイントを移動させる。つまり、2012年10月29日00:00から2012年10月31日00:00に移動させ、このサイクルを繰り返す

このサイクルを繰り返すことで、スケジュールを進めていきます。

つまり、新しく形成されたバーを取り、(高値+低値/2 - バーの平均値)を描画する必要があります。そして、その状態を確認し、正しければ上記のようにシフトします。

配列で実装しようとしたのですが、非常にわかりにくく、間違った値を与えてしまいます。このアルゴリズムを実装する方法を教えてください。


ここでは配列は全く必要ありません。これはExpert Advisorやスクリプト、インジケーターでもあるのでしょうか?問題は、このタスクの実装のために、Expert Advisorのコードとインジケーターのコードが異なることです。

そして、ここには大きなデメリットがあります。見てください、私たちはスタート地点に印をつけました。それはちょうど上昇トレンドのピークにあたります。我々は10ポイントのさらなるフェッチでこのろうそくの読書を考慮しないとする - それは開始のキャンドルと呼ぶことにしましょう。つまり、次のローソク足が下降して、どちらのレベルもつかめなかった場合=起点+10pips:価格は下降する。つまり、長い間、身動きがとれない状態、つまり、価格が下がって、どうせ上下する可能性がある、どうせ起点のレベルには達しない、熊が強く押している、と言えるのではないでしょうか。しかし、運良く5,000本のローソク足の後に価格がスタート地点のレベルに戻り、さらに10ピップス上昇したとしましょう。今までの時間は無駄だったが、今度は開始点+10ポイントに相当する価格を変数に入れ、価格がレベル=変数のレベル+10ポイントに達するまで待てばいいのだ...。要するに、そんなものは必要ないのです。あなたの説明から判断すると、レベル=スタート地点+10*10=スタート地点+100pipsをキャッチしているのです。このレベルをキャッチしたら、開始日を2日先にずらし、新たな開始点を計算する。これは複雑ですね。もっと簡単な方法があるはずです。

カスタム変数に開始日を設定しています(コード中ではexternが先行します)。datetime 型の変数を宣言する。仮に変数dt_StartDate(開始日)とし、初期化ブロックで、カスタム変数に格納されている値を代入します。そして、この日付に一致するローソク足を探し、あなたの計算式で起点を算出します。ただし、スタート地点ではなく、スタート時の価格水準です。double 型の変数 d_StartLevel(開始レベル)を宣言し、算出されたレベルの値を変数に入力する。また、もっと簡単な方法もあります。変数を宣言せず、算出された開始価格を水平線で 結ぶのです。StartLevelと呼ぶことにしましょう。ここで、開始レベルから距離=100ポイント上にあるチャート上に2本目の線を引きます。これをOtlovLevelと呼びます。さらに、配列は必要ありません。毎ティックごとに、価格がOtlovLevelより高いかどうかを見るだけです。となった時点で、変数dt_StartDateの値を2日分増やし、再度スタートレベルを計算し、そこにスタートラインを移動させるのです。その後、再びスタートラインから100ポイントアップし、そこにOtlovLevelのラインをドラッグします。以上で、課題は解決です。毎回、任意のラインが設定された価格を要求し、現在の価格または現在のローソク足の高値と比較することができます。

 
midorum:

あなたのロジックがどのようなものかわかりませんが、私の場合、この設定はインジケータの最後の30本のバーを描画します。

もう一度、SetIndexDrawBegin()は、チャートの左端からバーを計算します。

を確認してから反論してください。

だから論外です。ここでは、その様子をご紹介します。標準的なCCIインジケータを例にとってみましょう。SetIndexDrawBegin 関数でCCIPeriodを(Bars- CCIPeriod)に置き換えてみました。コード中の黄色くハイライトされている部分だけ変更したのですが...。

以下はそのコードです。

//+------------------------------------------------------------------+
//|                                                          CCI.mq4 |
//|                      Copyright © 2004, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
//----
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 LightSeaGreen
//---- input parameters
extern int CCIPeriod = 14;
//---- buffers
double CCIBuffer[];
double RelBuffer[];
double DevBuffer[];
double MovBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string short_name;
//---- 3 additional buffers are used for counting.
   IndicatorBuffers(4);
   SetIndexBuffer(1, RelBuffer);
   SetIndexBuffer(2, DevBuffer);
   SetIndexBuffer(3, MovBuffer);
//---- indicator lines
   SetIndexStyle(0, DRAW_LINE);
   SetIndexBuffer(0, CCIBuffer);
//----
   if(CCIPeriod <= 0)
       CCIPeriod = 14;
//----
   SetIndexDrawBegin(0, Bars - CCIPeriod);
  
//---- name for DataWindow and indicator subwindow label
   short_name="CCI(" + CCIPeriod + ")";
   IndicatorShortName(short_name);
   SetIndexLabel(0, short_name);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Commodity Channel Index                                          |
//+------------------------------------------------------------------+
int start()
  {
   int    i, k, counted_bars = IndicatorCounted();
   double price, sum, mul; 
   if(CCIPeriod <= 1)
       return(0);
   if(Bars <= CCIPeriod) 
       return(0);
//---- initial zero
   if(counted_bars < 1)
     {
       for(i = 1; i <= CCIPeriod; i++) 
           CCIBuffer[Bars-i] = 0.0;
       for(i = 1; i <= CCIPeriod; i++) 
           DevBuffer[Bars-i] = 0.0;
       for(i = 1; i <= CCIPeriod; i++) 
           MovBuffer[Bars-i] =0.0;
     }
//---- last counted bar will be recounted
   int limit = Bars - counted_bars;
   if(counted_bars > 0) 
       limit++;
//---- moving average
   for(i = 0; i < limit; i++)
       MovBuffer[i] = iMA(NULL, 0, CCIPeriod, 0, MODE_SMA, PRICE_TYPICAL, i);
//---- standard deviations
   i = Bars - CCIPeriod + 1;
   if(counted_bars > CCIPeriod - 1) 
       i = Bars - counted_bars - 1;
   mul = 0.015 / CCIPeriod;
   while(i >= 0)
     {
       sum = 0.0;
       k = i + CCIPeriod - 1;
       while(k >= i)
        {
          price =(High[k] + Low[k] + Close[k]) / 3;
          sum += MathAbs(price - MovBuffer[i]);
          k--;
        }
       DevBuffer[i] = sum*mul;
       i--;
     }
   i = Bars - CCIPeriod + 1;
   if(counted_bars > CCIPeriod - 1) 
       i = Bars - counted_bars - 1;
   while(i >= 0)
     {
       price = (High[i] + Low[i] + Close[i]) / 3;
       RelBuffer[i] = price - MovBuffer[i];
       i--;
     }
//---- cci counting
   i = Bars - CCIPeriod + 1;
   if(counted_bars > CCIPeriod - 1) 
       i = Bars - counted_bars - 1;
   while(i >= 0)
     {
       if(DevBuffer[i] == 0.0) 
           CCIBuffer[i] = 0.0;
       else 
           CCIBuffer[i] = RelBuffer[i] / DevBuffer[i];
       i--;
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+

論理的には、CCIPeriodが14の 場合。そしてSetIndexDrawBegin(0,Bars- CCIPeriod) は、最後の14本のバーを描画します。値(Bar - 14)から始まります。しかし、画面にはこのように表示されています。

 
hoz:

だから論外です。ここでは、その様子をご紹介します。標準的なCCIインジケータを例にとります。SetIndexDrawBegin 関数のCCIPeriodを(Bars- CCIPeriod)に置き換えてみました。コード中の黄色くハイライトされている部分だけ変更したのですが...。

以下はそのコードです。

論理的には、CCIPeriodが14の 場合。そしてSetIndexDrawBegin(0,Bars- CCIPeriod) は、最後の14本のバーを描画します。値(Bar - 14)から始まります。しかし、画面にはこのように表示されています。

画面にはこのように表示されています。

上部のネイティブインジケータ、下部のSetIndexDrawBegin(0, Bars-CCIPeriod)に変更しました。

 
midorum さん、失礼しました。私の失態です。MetaEditorで 別の端末を開くと...。今は動いています。ありがとうございました。
 
hoz:
midorum さん、失礼しました。私の失態です。MetaEditorで 別の端末を開くと...。今は動いています。ありがとうございました。
そうなんです、私もいつも悩んでいるんです。3つの端子があって、Editorではフォルダがごちゃごちゃになってしまうんです。ターミナルのボタンから実行し、その中のファイルを 手動で開くのがベターです。
 

皆さんこんにちは、回答をお願いします、15分足のローソクが開いたと判断する方法ですが、気の遠くなるような文字列を使いましたが、結論から言うと、時間によってローソクが開くとは限りません・・・もっと簡単な方法があると思うのですが、よくわかりません・・・・・。

if ((TimeMinute(TimeCurrent())==0 && TimeSeconds(TimeCurrent())==0)|| (TimeMinute(TimeCurrent())==15及び&)TimeSeconds(TimeCurrent())==0) || (TimeMinute(TimeCurrent())==30 && TimeSeconds(TimeCurrent())==0) || (TimeMinute(TimeCurrent())==45 && TimeSeconds(TimeCurrent())==0)

 
stater:

皆さんこんにちは、回答をお願いします、15分足のローソクが開いたと判断する方法ですが、気の遠くなるような文字列を使いましたが、結論から言うと、時間によってローソクが開くとは限りません・・・もっと簡単な方法があると思うのですが、よくわかりません・・・・・。

if ((TimeMinute(TimeCurrent())==0 && TimeSeconds(TimeCurrent())==0)|| (TimeMinute(TimeCurrent())==15及び&)TimeSeconds(TimeCurrent())==0) || (TimeMinute(TimeCurrent())==30 && TimeSeconds(TimeCurrent())==0) || (TimeMinute(TimeCurrent())==45 && TimeSeconds(TimeCurrent())==0)


https://www.mql5.com/ru/forum/131853/page4#504607
 
stater:

皆さんこんにちは、回答をお願いします、15分足のローソクが開いたと判断する方法ですが、気の遠くなるような文字列を使いましたが、結論から言うと、時間によってローソクが開くとは限りません・・・もっと簡単な方法があると思うのですが、よくわかりません・・・・・。

if ((TimeMinute(TimeCurrent())==0 && TimeSeconds(TimeCurrent())==0)|| (TimeMinute(TimeCurrent())==15及び&)TimeSeconds(TimeCurrent())==0) || (TimeMinute(TimeCurrent())==30 && TimeSeconds(TimeCurrent())==0) || (TimeMinute(TimeCurrent())==45 && TimeSeconds(TimeCurrent())==0)


bool CheckOpenM15()
{
   static int PrevTime=0;
   if (PrevTime==iTime(NULL, PERIOD_M15,0)) return(false);
   PrevTime=iTime(NULL, PERIOD_M15,0);
   return(true);
}
この関数は、M15に新しいバーが 出現したときに真を返す
 
Vinin:

この関数は、M15に新しいバーが出現したときに真を返す
ありがとうございました。