MQL5で学び、共に書く - ページ 35

 

クラスのメンバーでない 関数を、クラスのメンバーでない別の関数の参照(アドレス)の引数として渡すことができるかどうか、ご存知の方はいらっしゃいますか?

あるいは、クラスのメンバである関数に、まったくクラスのメンバではない別の関数への参照(アドレス)を引数として渡すことはできるのでしょうか?

Документация по MQL5: Основы языка / Типы данных / Структуры и классы
Документация по MQL5: Основы языка / Типы данных / Структуры и классы
  • www.mql5.com
Основы языка / Типы данных / Структуры и классы - Документация по MQL5
 
victorg:

クラスのメンバーでない 関数を、クラスのメンバーでない別の関数の参照(アドレス)の引数として渡すことができるかどうか、ご存知の方はいらっしゃいますか?

あるいは、あるクラスのメンバーである関数に、まったくクラスのメンバーではない別の関数への参照(アドレス)を引数として渡すことはできるのでしょうか?

いいえ、いいえ。

無理でしょう。MQL5では、「関数アドレス」「関数参照」という概念はありません。

 

ありがとうございました。

もうひとつ質問です。

mql5 には2つのファイルが あり、1つ目の ファイルはメインとなるインジケータやスクリプト です。2つ目の ファイルはmqh です

// f_01.mqh
double extfunc(int a);
//-------------------------------------
double example(void)
  {
  double a;
  a=extfunc(35);
  return(a);
  }
//-------------------------------------
2番目のmqh-fileは、一番最初にmainの mqh-fileに接続されています。 mainファイルのコンパイルは、エラーや警告を出さずに 進みます。しかし mqhファイルを個別にコンパイル しようとすると、function must have a body」と 表示されます。質問ですが、関数には何の問題もないのに、その本体が別のファイルにあることをコンパイラに伝えるには どうしたらいいのでしょうか?


Документация по MQL5: Файловые операции / FileMove
Документация по MQL5: Файловые операции / FileMove
  • www.mql5.com
Файловые операции / FileMove - Документация по MQL5
 
victorg:

2番目のmqh-fileはメインファイルの先頭に含まれています。 メインファイルのコンパイルはエラーや警告を出さずに 進みます。しかし mqhファイルを個別にコンパイル しようとすると、function must have a body」となって しまいます。私の質問は、関数には何の問題もないが、その本体が別のファイルにあることをコンパイラに伝えるにはどう したらいいのか、ということです。
ありえません。バラバラにしないでください、コードを読むときにわかりやすくなりません。
 
Yedelkin:

大袈裟かもしれませんが、ここでまた質問です。成行注文を出す(ポジションを持つ)前に,取引券をゼロにリセットする,つまりresult.deal=0にするのです。MqlTradeResult レスポンス構造でサーバーが null 取引チケットを返しますが、少し後に取引が実行され、ポジションが開かれることを期待してもよいでしょうか。それとも、サーバーがNullのトレードチケットを返すことで、ポジションを開くことができなかったことを保証し、この要求に基づいてさらに開くことはないのでしょうか?

OK、反応がないことと、このセリフによって

struct MqlTradeResult
{
ulong deal;// 取引が行われた場合、そのチケット
};

サーバーがNullのディールチケットを返すことは、そのポジションがオープンできないことを保証するものであり、このリクエストに基づいてさらにオープンされることはないと結論付けています。

 

私はよくフォーラムの構造を理解していない、そこにない場合は、正しい方向に私を導くください。

私は専門家ではありませんが、プログラミングに興味があり、トレーニングの過程で自分の傾向から進めているため、既存のコードを解析して理解しようとしています。

簡単のために、MAのカスタムコードの一部を取り出して、その中で何が起こっているかを理解しようとしました(コメントで反映させました)。

一般的に、困難でなければ、コードにコメントしてください、私は、各コマンドの後に何が起こるかを理解したいです。ありがとうございます。

void CalculateSimpleMA(int rates_total,int prev_calculated,int begin,const double&price[])//わかったぞ &price[].

  {
   int i,limit;
//--- first calculation or number of bars was changed
   if(prev_calculated==0)// first calculation
     {
      limit=InpMAPeriod+begin;                                               //почему переменная begin=0 ???
      //--- set empty value for first limit bars
      for(i=0;i<limit-1;i++) ExtLineBuffer[i]=0.0;                            //здесь инициализируются значения индикатора на барах с индексами от 0 до limit-1 ??? крайне правых на графике???
      //--- calculate first visible value
      double firstValue=0;                                                    //при инициализации переменной имеющей тип double не обязательно использовать значения типа double???
      for(i=begin;i<limit;i++)
         firstValue+=price[i];                                               //разобрался, здесь идет накопление переданной цены
      firstValue/=InpMAPeriod;
      ExtLineBuffer[limit-1]=firstValue;                                      
     }
   else limit=prev_calculated-1;                                              //в результате чего prev_calcutated не должно равняться 0, если индикатор поместили на оффлайн график?
//--- main loop
   for(i=limit;i<rates_total && !IsStopped();i++)                              //цикл для индикатора на баре с индексами от limit до последнего на графике
      ExtLineBuffer[i]=ExtLineBuffer[i-1]+(price[i]-price[i-InpMAPeriod])/InpMAPeriod;
//---
  }

プリントアウトしてみると、ExtLineBufferの 値は 、インデックスlimit-1からインデックスrates_total-1まで割り当てられていますが、チャートでは、インジケータは全空間に描かれて います。

Документация по MQL5: Основы языка / Операции и выражения / Операции присваивания
Документация по MQL5: Основы языка / Операции и выражения / Операции присваивания
  • www.mql5.com
Основы языка / Операции и выражения / Операции присваивания - Документация по MQL5
 
Profi_R:

私はよくフォーラムの構造を理解していない、そこにない場合は、正しい方向に私を導くください。

私は専門家ではありませんが、プログラミングに興味があり、トレーニングの過程で自分の傾向から進めているため、既存のコードを解析して理解しようとしています。

簡単のために、MAのカスタムコードの一部を取り出して、そこで何が起こっているかを理解しようとしました(コメントで反映させました)。

各コマンドの後に何が起こるかを理解したい。ありがとうございます。

詳しくはコメントしません、あなたの認識の基本的な誤りを正すだけで十分かもしれません、そして、あなた自身でパズルを組み立ててください-その方がずっと有益です。

つまり、mql5の多くのインディケータ(特にこのインディケータ)は、インディケータバッファのインデックスを付けずに、つまりAsSeries=falseという値で書かれていることが混乱の元になっているのです。

これは、ヒストリー上の最も古いバーのインデックス=0、「最も新しい」バー=RatesTotal-1であることを意味します。

// 何か明確なものはありますか?

この方法のポイントは、バッファにアクセスする際にインデックス作成が[隠れた]再計算を必要としないため、ある程度の速度が得られることです(それは「ハードウェア」のままです)。

//おそらく、インジケータバッファのインデックス作成は、歴史の終わりから始まりまで常に発生するという(誤った)信念が あるのでしょう。mql4では常にそうなっていますが、mql5では必要 ありません。

// ここで、インデックスの方向は、デフォルトでは常にヒストリの先頭から最後までを指す。 インデックスを逆にするには、SetAsSeries(...) 関数を明示的に使用する必要がある。

// また、インデックスの方向を設定するには、必ず SetAsSeries() 関数を 使用してください。

void CalculateSimpleMA(int rates_total,int prev_calculated,int begin,const double&price[])//$price[]をソートして みた。

をプリントアウトしてみると、ExtLineBufferの値は、インデックスlimit-1からインデックスrates_total-1まで割り当てられていますが、チャートでは空間全体にインジケータが描かれています、うーん、では1〜 limit-1の間のインジケータバッファに割り当てられた 値はどこ でしょ

自力で解決できると思いますが、念のため、明日にでも確認してみます。
 
MetaDriver: ..

ご感想ありがとうございました)

配列の指向性の順番や、ヘルプで指向性を明示的に指定することを推奨しているのを読みましたが、疑問があり、変数に中間データをアンセットしたら解消されました。

今のところ、方向性のみが決定されています。つまり、初期化に関するコメントが正しくなく、チャートの左側の指定した範囲にインジケータ・バッファの値が初期化されています。

については、まだ疑問が残ります。

1.変数beginは、その値がイベントハンドラに渡されるのは、端末の責任ですか?

2.double型の変数をint型に渡すことはできるのか?

3. 端末が変数prev_calculatedの値にも責任を負っているようです。

4.0からlimit-1までの区間での指標計算が どこで行われているのかが明確でない。

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
Основы языка / Функции / Функции обработки событий - Документация по MQL5
 
Profi_R:

については、まだ疑問が残ります。

1.変数beginは、その値がイベントハンドラに送られるのは、端末の責任か?

3.変数prev_calculatedの値も端末の原因になっているようです。

おそらく、この関数は、OnCalculate()関数呼び出しの最初のフォームのために書かれたものだと思われます。参考までにご覧ください。

Profi_R

については、まだ疑問があります。

2.double型の変数をint型の値に置き換えることは可能ですか?

はい、できます。暗黙の型変換の項を参照。暗黙の型変換を行った場合、コンパイラはしばしばデータ損失の可能性について警告を出します。

Profi_R

それでも疑問があるのは

4.インジケータが 0からlimit-1までの区間で計算されるところがよくわからないのですが。

このセリフは、あなたの質問に答えているのでしょうか。

//--- set empty value for first limit bars
      for(i=0;i<limit-1;i++) ExtLineBuffer[i]=0.0;                            
//--- calculate first visible value
... и далее по коду
?
 
Profi_R:

ご感想ありがとうございました)

配列の指向性の順番や、ヘルプで指向性を明示的に指定することを推奨しているのを読みましたが、疑問があり、変数に中間データをアンセットしたら解消されました。

今のところ、方向性のみが決定されています。つまり、初期化に関するコメントが正しくなく、チャートの左側の指定した範囲にインジケータ・バッファの値が初期化されています。

OKです。

については、まだ疑問が残ります。

1.変数beginは、その値がイベントハンドラに送られるのは、端末の責任か?

はい、端末はインジケーターへの送信を担当します。


このパラメータは、入力系列の履歴の初期値が不正確であるため、無視(スキップ)すべき数を指示します。 このような不正確さはどこから来るのでしょうか、その起源は何なのでしょうか?価格データではなく、他のインディケータが提供するデータに基づいて計算されるインディケータを作成する可能性に関連しています。 MT5では、インディケータ入力のために他のインディケータのデータを受信することができる3つのメカニズムが存在します。

方法1.手順の順序

iIndicator(...) 関数またはIndicatorCreate(...) のいずれかを使用して、入力インジケータ用のハンドルを作成します。

2. 必要に応じて、CopyBuffer(...) 関数を使用して、そのバッファから値を取得します。

2つ目の方法。これは、価格系列ではなく、指標系列を入力 指標に渡したい場合に必要です。 つまり、この場合、別の指標(1)のデータを入力する入力指標(2)が計算した値を受け取ることになります。 つまり、指標-全体-指標のチェーンを構築したいのです。

ステップの順序

1.iIndicator(...) 関数またはIndicatorCreate(...) 関数のいずれかを使用して、最初の(1)入力指標用のハンドルを作成する。

2. 同じ方法で2つ目(2)のインジケータのハンドルを作成しますが、作成時に最後のパラメータ(applied_price )として1つ目(1)のハンドルを指定します。

CopyBuffer(...) 関数を使用して、必要に応じてインジケータ・バッファからその値を取得します。

3つ目の方法は、指標連鎖の構築にも使われる方法ですが、前の方法とは異なり、データソース(入力配列)をコンパイル前に固定せず、ユーザーが端末で直接設定することができます。 指標開始の時点で 適切なパラメータを指定することで、指標を構築することができます。

これらの仕組みについては、ご自身で理解していただくことにして、前文では、そのために役立つドキュメントの重要な箇所への直接リンクをたくさん用意しました。

OnCalculate()の呼び出しの短い形式のパラメータだけに注目しましょう。

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])

その目的は、かなり明確に記されています。ここでは、この関数に渡す必要性(合理性)を説明したいだけです。 最初と最後のパラメータで、すべてが十分に明らかになると思います。計算を行うためには、入力データ(price[])を格納したバッファを用意し、その現在の 長さを知っておく必要があります。(引用符で端末が埋まるとその長さが長くなることをお忘れなく)

しかし、それに加えて、入力行のデータが厳密に正しいか、あるいは初期値が不正確である(可能性がある、あるいは保証されている)ために無視されるべきかを、最初から知っておく必要があるのです。ほとんどの場合 入力データが他の指標の出力 である場合、不正確さが保証 されますが、それ以外の場合はどうでしょうか?多くのインジケータは、任意のバーでの値を計算するために、ある程度のヒストリーデータを使用しなければならない。 しかし、「時間の始まり」のどこにあるかというと、そこにはヒストリーデータが存在しないため、開始時のヒストリーバーからではなく、後に(右側に)、すでに必要な量のヒストリーデータが存在する左側のバーから出力値を生成しなければならなくなっている。

さて、ここまで説明した内容のおかげで、質問の答えは

その値はどこから来るのか // パラメータ begin について話しています。

答えは、このパラメータは端末が関数内で渡すにもかかわらず、入力インジケータがその内容を管理 する必要があります!端末自体は価格入力行のみをチェックできます(この場合、beginの値は0となり、これは正しい値です)。したがって、何らかのインジケータを作成する場合(純粋に実験的なものを除く)、 その出力バッファの正しいデータの開始のインデックスをターミナルに通知 することを確認する必要があります。 それは明確ですか?そうしないと、このインジケーターの「子孫」が非常に不愉快な不正なデータを食べてしまい、場合によっては病気になってしまうことも...。:) さて、どうやるかというと、PLOT_DRAW_BEGINプロパティの識別子を指定して、PlotIndexSetInteger()関数を使用します。 重要!生成されるインジケータプロパティを100%正しくするために、PlotIndexSetInteger(.Prot)を一回呼び出すと、そのプロパティの識別子が表示されます。...PLOT_DRAW_BEGIN, ...) をOnInit()で実行します!なぜそうするかというと、我々のインジケータは、それ自体が履歴上の初期インデントを持つ他のインジケータのデータで形成されることができるからです。つまり、入力履歴にゼロでないbeginの値があり、OnInit()でそれを受け取る可能性がないのです。

  PlotIndexSetInteger(MySymbol,PLOT_DRAW_BEGIN,MyBeginPeriod-1+begin);

そして、OnInitではbeginの値が不明なので、OnCalculate()で(できれば一度だけ)作る必要があるのです。

もちろん、私たちにも予備的な(あまり意味のない)電話をかける権利が残されているわけですが

  PlotIndexSetInteger(MySymbol,PLOT_DRAW_BEGIN,MyBeginPeriod);

をOnInit()内で使用します。

これはまさに、あなたが勉強のためにサンプルを取ったそのインジケータ(Custom Moving Average.mq5)で行われていることです。

2. double型の変数がint型になることはあるのでしょうか?

はい、double 型の変数が定数で定義 されていれば、int 型の値で苦労せずに初期化することができます。// これは、まさにあなたの例でできることです。

3.変数prev_calculatedの値も端末が担っているようです

ここには、繊細さがあります。ほとんどの場合、この値は前の呼び出しでOnCalculate()関数が返した値と同じになる。つまり、事実、あなたの手の中にあるのです。また, 端末が希望すれば,常にゼロにリセット することも可能です。例えば、ブローカーによる相場修正時、通信中断後の再開時、以前の(入力)インジケーターの再初期化時などに発生することがあります。

4. 0からlimit-1までの区間のどこで指標を計算 するのかが明確でない。

この場合、これらの値は正しく計算できない(計算のための十分な履歴がない)ため、単純にゼロ値が割り当てられています。

// 対応する入力データを割り当てるのが望ましいが、本質は変わらない。