エラー、バグ、質問 - ページ 2146

 
fxsaber:

OnCalculate - このチャートでは実行されません。ハンドルネームを作ったからには、そこに住まわなければならない。

これでダメなら......右のサブウィンドウで普通に描画(バッファ描画)されるのはなぜ?

 
A100:

インジケーターに

::ChartWindowFind()が-1を返す(言い換えれば、機能しない)


インジケータは初期化されるまで、動作するサブウィンドウの番号を知りません。初期化に成功した場合のみ、ウィンドウにアタッチされる

つまり、インジケーターのOnInitでChartWindowFind()を呼んでも 意味がないのです

 
Slava:
つまり、インジケーターのOnInitでChartWindowFind()を呼んでも 意味がありません。

インジケーターのOnInitでChartWindowFind() を呼び出す(同じ インジケーター)

void OnStart()
{
        string name = "Test_i";
        int sub_window = 1;
        ChartIndicatorAdd( 0, sub_window, iCustom( NULL, PERIOD_CURRENT, name ));
}

結果:1:true:0
2:1:0

すべてうまく検出されたので、インジケーターのOnInitの コードを思い出してみましょう。

void OnInit()
{
//...
        ResetLastError();
        int sub_window = ChartWindowFind();
        Print( "2:", sub_window, ":", GetLastError());
}
 
A100:

そうでない場合 - 必要なサブウィンドウに正常に描画(バッファ描画)されるのはなぜですか?

つまり、指標の計算と その描画部分は別物なんですね。ChartWindowFindは、インジケータの描画を担当する機構への参照です。つまり、インジケーターそのものでもないのです。

 
Slava:

インジケータは初期化されるまでは、動作するサブウィンドウの番号を知らない。初期化に成功した場合のみ、ウィンドウにアタッチされます。

OnInit後のChartWindowFind() の呼び出し(OnCalculateより)

//Test.mq5//Скрипт
void OnStart()
{
        string name = "Test_i";
        ObjectCreate( 0, name, OBJ_CHART, 0, 0, 0 );
        long chart_id  = ObjectGetInteger( 0, name, OBJPROP_CHART_ID );
        int sub_window = 1;
        ChartIndicatorAdd( chart_id, sub_window, iCustom( NULL, PERIOD_CURRENT, name ));
}
//Test_i.mq5//Индикатор
void OnInit() { Print( __FUNCTION__, ":end" ); }
int OnCalculate( const int, const int, const int, const double& [] )
{
        Print( __FUNCTION__ );
        ResetLastError();
        int sub_window = ChartWindowFind();
        Print( "3:", sub_window, ":", GetLastError());
        return 0;
}

結果:OnInit。終了
OnCalculate
3:-1:4113

つまり、インジケータはすでに動作しているサブウィンドウの番号を知っているが、それを報告することはない
 
A100:

言い換えれば、インジケータはすでに動作中のウィンドウの番号を知っているが、それを報告することはない

ChartID() を知っているか?

 
fxsaber:

ChartID()を知っているか?

必須ではありません -ChartWindowFind()関数、パラメータなし
 
A100:
必須ではありません -ChartWindowFind()関数、パラメータなし

ただ、ChartID()も知らないのは確かです(パラメータなし)。

 
fxsaber:

ChartID()も知らない(パラメータがない)はず。

これは明らかな欠陥であり、特に操作不能は以下の場合にのみ発生します。

        ObjectCreate( 0, name, OBJ_CHART, 0, 0, 0 );
        long chart_id = ObjectGetInteger( 0, name, OBJPROP_CHART_ID );

でないと

        long chart_id = ChartOpen( NULL, PERIOD_CURRENT );

例えば、手動でチャートウィンドウを追加し、そこにインジケータを取り付けた場合、すべてOKです。

しかし、自動でやるとうまくいきません

これは、アルゴトレーディングのコンセプトそのものに反するものです

 
A100:

特に、以下の場合は操作できないので、これは目に余る欠点です。

でないと

例えば、手動でチャートウィンドウを追加し、そこにインジケータを取り付けた場合、すべてOKです。

しかし、自動でやるとうまくいきません

これは、アルゴトレーディングのコンセプトそのものに反するものです

指標のアーキテクチャが明確になってきたのは良いことだと思います。ドキュメントに情報が少ないのが不思議なくらいです。

インジケーターの計算部分と描画部分は別の存在である。ハンドルは計算部分です。計算する方は、描く方のことを何も知らないし、知らないはずです。

ハンドルを作成したが、1つではなく、2つのチャートに配置したと想像してください。明らかに、インジケータは1つですが、ChartIDとSubWindowが異なる2つのチャートに描画されています。ハンドル・インジケータは、このインジケータがどこに描かれているか、描かれているかどうかを全く知らないので、これを気にすることはありません。レンダリングを担当するのはインジケーターではありません。

手動でチャートに配置したり、テンプレートを使ってインジケータを配置すると、全く異なる動作が起こります。ハンドルは描画部分と一緒に作成されます。同じシンボルと期間を持つ別のチャートで、同じ入力パラメータを持つインジケータを手動で起動すると、描画部分で別のハンドルが作成されます。

MQLの場合はそうではありません。1つのインジケータを作成した後、別のインジケータを作成しても、再び何も作成されません。計算部分はそのままです。

MQLでインジケータを実行する場合、新しいチャートまたはOBJ_CHARTなどで、手で実行するのと同じように、LoadTemplateを実行するのが唯一の方法です。