Ошибки, баги, вопросы - страница 2146

A100
2094
A100  
fxsaber:

OnCalculate - запускается не на этом чарте. Вы хэндл создали, там он и живет.

Если не на этом - почему он тогда нормально рисует (буферное рисование) в нужном подокне?

Slava
Модератор
13446
Slava  
A100:

В индикаторе

::ChartWindowFind() возвращает -1 (другими словами не работает)


Пока индикатор не проинициализирован, он не знает номера подокна, в котором работает. Так как прикрепляется к окну только после удачной инициализации

Другими словами, вызывать ChartWindowFind() в OnInit индикатора - бесполезно

A100
2094
A100  
Slava:
Другими словами, вызывать ChartWindowFind() в OnInit индикатора - бесполезно

Вызов ChartWindowFind() в OnInit индикатора (индикатор тот же)

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());
}
fxsaber
16698
fxsaber  
A100:

Если не на этом - почему он тогда нормально рисует (буферное рисование) в нужном подокне?

Так расчет индикатора и его рисующая часть - это разные вещи. ChartWindowFind - это обращение к механизму, который отвечает за рисование индикатора. Т.е. это не сам индикатор даже.

A100
2094
A100  
Slava:

Пока индикатор не проинициализирован, он не знает номера подокна, в котором работает. Так как прикрепляется к окну только после удачной инициализации

Вызов ChartWindowFind() после OnInit (из 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:end
                 OnCalculate
                 3:-1:4113

Другими словами индикатор уже знает номер подокна, в котором работает, но не сообщает его
fxsaber
16698
fxsaber  
A100:

Другими словами индикатор уже знает номер окна, в котором работает, но не сообщает его

А знает ли он ChartID()?

A100
2094
A100  
fxsaber:

А знает ли он ChartID()?

Он не требуется - функция ChartWindowFind() без параметров
fxsaber
16698
fxsaber  
A100:
Он не требуется - функция ChartWindowFind() без параметров

Просто почти уверен, что он и ChartID() не знает (без параметров).

A100
2094
A100  
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 );

Т.е. если я вручную добавил окно графика и прикрепил на него индикатор - то все нормально

А если автоматическим способом - то не работает

Это противоречит самой концепции алготрейдинга

fxsaber
16698
fxsaber  
A100:

Это явная недоработка тем более что неработоспособность проявляется не только если

но и если

Т.е. если я вручную добавил окно графика и прикрепил на него индикатор - то все нормально

А если автоматическим способом - то не работает

Это противоречит самой концепции алготрейдинга

Это очень хорошо, что стала понятна архитектура индикаторов. Странно, что об этом так мало в документации.

Расчетная часть индикатора и рисующая - разные сущности. Хэндл - это расчетная часть. И расчетная ничего не знает про рисующую и не должна.

Представим, что Вы создали хэндл, но поместили его не на один, а на два чарта. Очевидно, что индикатор один, а рисуется на двух чартах с разными ChartID и SubWindow. И хэндл-индикатору на это плевать, т.к. он знать не знает, где его кто-то там отрисовает и отрисовывает ли вообще. За отрисовку отвечает не индикатор.

Когда же Вы помещаете индикатор вручную на чарт или через шаблон, то происходит совсем иное действие. Создается хэндл вместе с рисующей частью. Если точно с такими входными  параметрами индикатор запустить вручную на другом чарте с тем же символом и периодом, то будет создан еще один хэндл с рисующей частью.

Через MQL же совсем иначе. Если создали один индикатор и затем второй такой же, то ничего не создается повторно. Расчетная часть остается нетронутой.

Единственный способ запустить через MQL индикатор так же, как руками на, например, новом чарте или OBJ_CHART - это LoadTemplate.