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

 
皆さん、こんにちは。
この掲示板は初めてです、もし私が掲示板で何か間違ったことをしていたら、あらかじめご容赦ください。
ずっとインジケーター付きのチャートを見ています。最近、預金が2つなくなりました。新規に口座を開設する前に、履歴でストラテジーの収益性を確認したい。MT4でデモ口座を使っています。
私はプログラマーでは全くありません。MT4にインジケータをインストールし、MetaEditorでインジケータの線の 太さを変更することしかできません(インジケータコードで色を変更できない可能性が高く、ターミナルでのみ変更できます)。
私のような知識で、どこからステップバイステップでテストしていけばいいのか、わかりやすい情報はありませんか(わかりやすく言えば「黒人にトイレの使い方を教える」)?MA(3種類の単純なもの)、ストキャスティクス(標準レベル)、CCI(5レベル)の3つの指標を搭載しています。指標のレベルを上から下へ越えてから短い取引を開始し、長い取引はその逆(私はそれが明確だと思う...)です。テイクアンドロスの設定。
自動モードだけでなく、視覚的にストラテジーを追跡して、インジケーターや注文のパラメーターを選択できるように視覚化しないでも済むようにしたいです。
 
ZebStamp:
皆さん、こんにちは。
この掲示板は初めてです、もし私が掲示板で何か間違ったことをしていたら、あらかじめご容赦ください。
ずっとインジケーター付きのチャートを見ています。最近、預金が2つなくなりました。新規に口座を開設する前に、履歴でストラテジーの収益性を確認したい。MT4でデモ口座を使っています。
私はプログラマーでは全くありません。MT4にインジケータをインストールし、MetaEditorでインジケータの線の 太さを変更することしかできません(インジケータコードで色を変更できない可能性が高く、ターミナルでのみ変更できます)。
私のような知識で、どこからステップバイステップ(英語で「黒人のためのトイレの使い方の説明書」)でテストすればいいのか、わかりやすい情報はないでしょうか?MA(3種類の単純なもの)、ストキャスティクス(標準レベル)、CCI(5レベル)の3つの指標を搭載しています。指標のレベルを上から下へ越えてから短い取引を開始し、長い取引はその逆(私はそれが明確だと思う...)です。テイクアンドロスの設定。
自動モードでのストラテジーのトラッキングを視覚的に行えるようにしたい。また、インジケーターやオーダーのパラメーターを選択するための視覚化を行わないようにしたい。

トレンドラインなどのグラフィカルオブジェクト(GO)を作成する際に、色を選択します。トレンドラインを再作成すると、同じ色で作成されます。Hlineの場合は-色を選んで-次はこんな感じです。黄色、青、...

CSがExpert Advisor、インジケータ、スクリプトを作成する場合 - あなたがプログラムに書き込むように。パラメータを選択することもある

 
STARIJ:

もし、あなたのコードを見た人が、すぐにエラーを見つけられると思ったら、それは間違いです。コンパイラはエラーを探します。プログラムテキストは整形する必要があります。MetaEditorにはそのためのスタイリング ツールがあります。別のスタイルがお好みなら、たとえばAStyle.exeプログラムをお使いください。スタイリング後、すぐにプログラム1)に余分な閉じ括弧があることがわかります。2)宣言された変数: datetime date_Buf_1; // インジケータ日付配列 - これが配列であるためには、[size]か動的配列の[]を指定し、サイズをArrayResizeに設定しなければならないようです。そして、配列を使用する前にそれを行う必要があります - それについては、上記の投稿を参照してください。3) FileOpen(InpDirectoryName+"//"+InpFileName - スティックを他の方向に傾ける必要があるように思えます。また、InpDirectoryName+"//"は付けない方が良いでしょう - いずれにせよ、ファイルはFilesフォルダーで見つかります。

int copied=CopyTime(NULL,0,0,0,date_Buf_1); コンパイラは怒って、start=0=0にします。


ありがとうございます。何とか直したが、理解するというより直感的に。しかし、まだアレイに関する3つのエラーがあります。

'Buf_1' - array required 111.mq4 93 21

'date_Buf_1' - array required 111.mq4 94 21

'Buf_1' - array required 111.mq4 100 16


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
input string             InpFileName="111.csv";      // Имя файла 
input string             InpDirectoryName="Data";     // Имя каталога 

datetime Время=0;   // Время прошлого бара
double Bid1;
double   Buf_1[];
// double ExtBuffer;
long V1; // объем для текущего тика вверх
long V2; // накопленный объем для всех тиков вверх текущего бара
long V3; // объем текущего тика вниз
long V4; // накопленный объем для всех тиков вниз для текущего бара
long V5;  // отрицательные и положительные iVolume нарастающим итогом
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnInit()
  {
   IndicatorDigits(0);
   SetIndexBuffer(0,Buf_1);
//SetIndexBuffer(1,Buf_2);
   Bid1=Bid;
   V5=0;

  }
//+------------------------------------------------------------------+
//| 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[])
  {
   datetime Вр=Time[0];   // Время текущего бара
   if(Вр>Время)           // Если новый бар
     {
      Время=Вр;           // Запомнить
                          //      Buf_1[0]=0;         // и обнулить последний элемент буфера
     }

   datetime date_Buf_1[]; // массив дат индикатора 
   datetime time_Buf_1[]; // массив времени 
                          // --- считаю объем для положительных и отрицательных тиков      
   if(Bid>=Bid1)
     {
      if(Bid>Bid1) // если тик положительный..
        {
         V1=iVolume(NULL,0,0); // если повышающий цену тик, то находим его объем
         V2= V1 + V2;
        }
      else
        {
         V1=0;                // если Bid1 = Bid2, т.е. изменение цены = 0, то iVolume этого тика присваиваем 0;
         V2= V1 + V2;
        }
     }
   else
     {
      V3 = iVolume(NULL, 0, 0); // если понижающий цену тик 
      V4 = V3 + V4;             // то находим его объем  
     }

   V5=V2-V4;               // определяем разницу (дельту) между объемами положительных и отрицательных тиков
   Bid1=Bid;
   Buf_1[0]=V5; // в буфер сгружаем  дельту

                //   ExtBuffer = Buf_1 [0];
//   double macurrent=iMAOnArray(ExtBuffer,0,5,0,MODE_LWMA,0); 

// запись в файл данных буфера


//--- установим для массивов признак таймсерии 
   ArraySetAsSeries(Buf_1[0],true);
   ArraySetAsSeries(date_Buf_1[0],true);

//--- скопируем таймсерию 
   int copied=CopyTime(NULL,0,10000,0,date_Buf_1);

//--- подготовим массив Buf_1 
   ArrayResize(Buf_1[0],copied);

//--- скопируем значения линии индикатора  
   for(int i=0;i<copied;i++)
     {
      Buf_1[i]=V5;
     }
//--- откроем файл для записи значений индикатора 
   ResetLastError();
   int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_CSV);
   if(file_handle!=INVALID_HANDLE)
     {
      PrintFormat("Файл %s открыт для записи",InpFileName);
      PrintFormat("Путь к файлу: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
      //--- сначала запишем значения индикатора 
      FileWrite(file_handle,Buf_1[0]);
      //--- запишем время и значения в файл 
      for(int i=0;i<Buf_1[0];i++)
         FileWrite(file_handle,time_Buf_1[0],Buf_1[0]);
      //--- закрываем файл 
      FileClose(file_handle);
      PrintFormat("Данные записаны, файл %s закрыт",InpFileName);
     }
   else
      PrintFormat("Не удалось открыть файл %s, Код ошибки = %d",InpFileName,GetLastError());

   return(rates_total);
  }
//+------------------------------------------------------------------+


コメントの実装方法がよくわからない。でも、余ったホッチキスを見つけたんです :)
 
YarTrade:

ありがとうございます。何とか直したが、理解するというより直感的に。しかし、まだアレイに関する3つのエラーがあります。

'Buf_1' - array required 111.mq4 93 21

'date_Buf_1' - array required 111.mq4 94 21

'Buf_1' - array required 111.mq4 100 16



コメントの実装方法がよくわからない。しかし、余分なブラケットを発見してしまった :)
配列の変数名のみを残す。コンパイラが指し示すコード行の"[]"を削除する。
 
Artyom Trishkin:
変数配列の名前だけを残す。コンパイラが指し示すコード行の"[]"を削除する。

ありがとうございます。実際にどうなるかは見てのお楽しみです。ファイルに何か書き込まれるのか、大いに疑問があります :)

 

いろいろと疑問が出てきましたので、よろしくお願いします。テスト時とリアルタイム時のEAのパフォーマンスが大きく異なるという、とても悲しいことがわかりましたので、よくある典型的なエラーを分析したいと思います。まず、私が遭遇したものについて書きます。 プログラマーが何を心がけ、何をコードに残すべきかを知るために、あなたの経験を共有していただければ幸いです。

1.ゼロによる除算 はコードに存在せず、バックテストでも発生していないにもかかわらず、実際の取引モードではゼロによる除算の エラーが表示されていました。プログラマは、各約数をNormalizeDouble(x,Digits)と記述することで問題を解決しました。

2.取引は開始されなかった。金曜日の日はバックテスト実行時に取引が成立したが、実取引時には取引が成立しなかった。さらに、Expert Advisorのジャーナルにはエラーが表示されていない。何が問題かもわからないが、いくつかある。まず、「'ordersend'の戻り値を確認する必要があります」といった警告が表示されましたが、私の理解が正しければ、これはコードの実行に影響しないはずですよね?それともスリッページが原因?私の値は1ですが、これは小さすぎるわけではありません。そして、私がエントリーを行うべきバーがギャップなしで開いたのです。

スリップのある標準例から「if(Volume[0]>1) return;」という行を取り出して、コードの先頭に挿入しました。つまり、私のコードは新しいバーが表示された最初のティックの間だけ実行されます。バーがボリュームで開き、私のコードが実行されないということはあり得るのでしょうか?

4.EAで履歴やリアルタイムで作業する際に注意すべき点や典型的なエラーについて、アドバイスをお願いします。


 
LuckySith:

いろいろと疑問が出てきましたので、よろしくお願いします。テスト時とリアルタイム時のEAのパフォーマンスが大きく異なるという、とても悲しいことがわかりましたので、よくある典型的なエラーを分析したいと思います。まず、私が遭遇したものについて書きます。 プログラマーが何を心がけ、何をコードに残すべきかを知るために、あなたの経験を共有していただければ幸いです。

1.ゼロによる除算 はコードに存在せず、バックテストでも発生していないにもかかわらず、実際の取引モードではゼロによる除算の エラーが表示されていました。プログラマは、各約数をNormalizeDouble(x,Digits)と記述することで問題を解決しました。

2.取引は開始されなかった。金曜日の日はバックテスト実行時に取引が成立したが、実取引時には取引が成立しなかった。さらに、Expert Advisorのジャーナルにはエラーが表示されていない。何が問題かもわからないが、いくつかある。まず、「'ordersend'の戻り値を確認する必要があります」といった警告が表示されましたが、私の理解が正しければ、これはコードの実行に影響しないはずですよね?それとも滑り止めのため?私の値は1ですが、これは小さすぎるということはありません。そして、私がエントリーを行うべきバーがギャップなしで開いたのです。

スリップのある標準例から「if(Volume[0]>1) return;」という行を取り出して、コードの先頭に挿入しました。つまり、私のコードは新しいバーが表示された最初のティックの間だけ実行されます。バーがボリュームで開き、私のコードが実行されないということはあり得るのでしょうか?

4.EAで履歴やリアルタイムを扱う際に注意すべき点や典型的なミスについて、アドバイスをお願いします。

この「if(Volume[0]>1) return;」という乱暴な構成を、通常の「New Bar」チェックに置き換えてみてください。

ordersend' の戻り値を確認する必要があります」という類の警告は、今のところエラーではなく、将来的なエラーの可能性があるものです。コードに警告が出ることはないはずで、ましてやオンラインで作業しているときは、警告が出ることはないはずです。

「新しいバーを開くとき、特に30分や1時間のオープニングで、この時点でスプレッドが大幅に拡大します。

必要なこと:新しいバーのチェックをすること、そしてそれが新しいものであれば、エントリーの条件を見ること、それらが一致すれば - 取引をすることです。その後、バーがうまくいったことを記録して、新しいバーを待つことになります。

今あるもの: if(Volume[0]>1) return; = 新しいバーがあれば、条件を探す、条件が合わなかった == 大きなスプレッド = OnTick()で再度終了、次のティックでif(Volume[0]>1) return; それ以上は進まないので、スプレッドが0.0001でもすでに取引は失敗している。

 

こんにちは。下記をコードで記述する方法を教えてください。上下の水平線で 囲まれた平面があります。Expert Advisorが自ら検出し、設定します。

平坦なゾーンから離れた後、このゾーンに戻ったときにEAが検出される必要があります。そして、その後に初めてポジションをオープンするのです。

ノイズを除去するために、私はパラメータ2または3のムービングターゲットを使用しています。

 
Vitaly Muzichenko:

if(Volume[0]>1) return;」という乱暴な構文を、通常の「新しいバー」のチェックに置き換えてください。

ordersend' の戻り値を確認する必要があります」のような警告が出ますが、これはまだエラーではなく、将来的に起こりうるエラーです。コードに警告が出ることはないはずで、ましてやオンラインで作業しているときは、警告が出ることはないはずです。

「新しいバーを開くとき、特に30分や1時間のオープニングで、この時点でスプレッドが大幅に拡大します。

必要なこと:新しいバーのチェックをすること、そしてそれが新しいものであれば、エントリーの条件を見ること、それらが一致すれば - 取引をすることです。その後、バーがうまくいったことを記録して、新しいバーを待つことになります。

今あるもの: if(Volume[0]>1) return; = 新しいバーがあれば、次に条件を見て、条件が合わない == 大きなスプレッド = OnTick()で再度終了、次のティックでif(Volume[0]>1) return; それ以上は見逃さないので、スプレッドが0.0001でも取引は見逃すことになります。


バーの新規 出店について。良いのでしょうか?:

datetime counted_bar = 0;

int OnInit()
{
   counted_bar = 0; // если нужно, чтоб при перезапуске последний бар был проанализирован
   ...

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      counted_bar = iTime( _Symbol, _Period, 0 );

      // Анализируем индикаторы
      ...
   }
 
LuckySith:

バーの新規 出店について。それは良い選択肢でしょうか?:

最初はこんな感じにしておきましょう。

次に、バーが鍛えられていることをきちんと固定する必要がありますが、ここでは、TORへのアプローチ全体を計算する必要があります。

あなたの投稿を見る限り、この方法でやるしかないですね。

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      // Анализируем индикаторы
      if(SpreadMax > текущий спред) return;

      counted_bar = iTime( _Symbol, _Period, 0 );
      ...
   }

スプレッドが通常より大きい場合、OnTickに 戻り、新しいティックでスプレッドをチェックし、通常であれば、注文を送信し、このバーで取引があったことを記憶します。

また、第二の道もあります。

void OnTick()
{
   // Если появился новый бар
   if ( iTime( _Symbol, _Period, 0 ) > counted_bar )
   {
      if(SpreadMax > текущий спред) return;
      // Анализируем индикаторы
      ...
      result = OrderSend(...);
      // если открылась позиция, то result будет тикет позиции
       if(result>0) counted_bar = iTime( _Symbol, _Period, 0 );
   }

一般的には、ロジックを定義し、いつ記録し、「新しいバー」が形成される前に再度チェックしないようにする必要があります。