{
int i,limit;
//--- first calculation or number of bars was changedif(prev_calculated==0)// first calculation
{
limit=InpMAPeriod+begin; //почему переменная begin=0 ???//--- set empty value for first limit barsfor(i=0;i<limit-1;i++) ExtLineBuffer[i]=0.0; //здесь инициализируются значения индикатора на барах с индексами от 0 до limit-1 ??? крайне правых на графике???//--- calculate first visible valuedouble 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 loopfor(i=limit;i<rates_total && !IsStopped();i++) //цикл для индикатора на баре с индексами от limit до последнего на графике
ExtLineBuffer[i]=ExtLineBuffer[i-1]+(price[i]-price[i-InpMAPeriod])/InpMAPeriod;
//---
}
クラスのメンバーでない 関数を、クラスのメンバーでない別の関数の参照(アドレス)の引数として渡すことができるかどうか、ご存知の方はいらっしゃいますか?
あるいは、クラスのメンバである関数に、まったくクラスのメンバではない別の関数への参照(アドレス)を引数として渡すことはできるのでしょうか?
クラスのメンバーでない 関数を、クラスのメンバーでない別の関数の参照(アドレス)の引数として渡すことができるかどうか、ご存知の方はいらっしゃいますか?
あるいは、あるクラスのメンバーである関数に、まったくクラスのメンバーではない別の関数への参照(アドレス)を引数として渡すことはできるのでしょうか?
いいえ、いいえ。
無理でしょう。MQL5では、「関数アドレス」「関数参照」という概念はありません。
ありがとうございました。
もうひとつ質問です。
mql5 には2つのファイルが あり、1つ目の ファイルはメインとなるインジケータやスクリプト です。2つ目の ファイルはmqh です。
大袈裟かもしれませんが、ここでまた質問です。成行注文を出す(ポジションを持つ)前に,取引券をゼロにリセットする,つまり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[].
プリントアウトしてみると、ExtLineBufferの 値は 、インデックスlimit-1からインデックスrates_total-1まで割り当てられていますが、チャートでは、インジケータは全空間に描かれて います。
私はよくフォーラムの構造を理解していない、そこにない場合は、正しい方向に私を導くください。
私は専門家ではありませんが、プログラミングに興味があり、トレーニングの過程で自分の傾向から進めているため、既存のコードを解析して理解しようとしています。
簡単のために、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の間のインジケータバッファに割り当てられた 値はどこ でしょう。
ご感想ありがとうございました)
配列の指向性の順番や、ヘルプで指向性を明示的に指定することを推奨しているのを読みましたが、疑問があり、変数に中間データをアンセットしたら解消されました。
今のところ、方向性のみが決定されています。つまり、初期化に関するコメントが正しくなく、チャートの左側の指定した範囲にインジケータ・バッファの値が初期化されています。
については、まだ疑問が残ります。
1.変数beginは、その値がイベントハンドラに渡されるのは、端末の責任ですか?
2.double型の変数をint型に渡すことはできるのか?
3. 端末が変数prev_calculatedの値にも責任を負っているようです。
4.0からlimit-1までの区間での指標計算が どこで行われているのかが明確でない。
については、まだ疑問が残ります。
1.変数beginは、その値がイベントハンドラに送られるのは、端末の責任か?
3.変数prev_calculatedの値も端末の原因になっているようです。
おそらく、この関数は、OnCalculate()関数呼び出しの最初のフォームのために書かれたものだと思われます。参考までにご覧ください。
については、まだ疑問があります。
2.double型の変数をint型の値に置き換えることは可能ですか?
はい、できます。暗黙の型変換の項を参照。暗黙の型変換を行った場合、コンパイラはしばしばデータ損失の可能性について警告を出します。
それでも疑問があるのは
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 ... и далее по коду
?ご感想ありがとうございました)
配列の指向性の順番や、ヘルプで指向性を明示的に指定することを推奨しているのを読みましたが、疑問があり、変数に中間データをアンセットしたら解消されました。
今のところ、方向性のみが決定されています。つまり、初期化に関するコメントが正しくなく、チャートの左側の指定した範囲にインジケータ・バッファの値が初期化されています。
については、まだ疑問が残ります。
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の値も端末が担っているようです
4. 0からlimit-1までの区間のどこで指標を計算 するのかが明確でない。
この場合、これらの値は正しく計算できない(計算のための十分な履歴がない)ため、単純にゼロ値が割り当てられています。
// 対応する入力データを割り当てるのが望ましいが、本質は変わらない。