Errors, bugs, questions - page 2146

 
fxsaber:

OnCalculate - does not run on this chart. You have created a handle, that's where it lives.

If not on this one - then why does it draw normally (buffer drawing) in the right sub-window?

 
A100:

In the indicator.

::ChartWindowFind() returns -1 (in other words does not work)


Until the indicator is initialized, it doesn't know the number of the subwindow it works in. It attaches to the window only after successful initialization

In other words, it's useless to call ChartWindowFind() in the indicator OnInit

 
Slava:
In other words, it is useless to call ChartWindowFind() in the indicator OnInit

Calling ChartWindowFind() in the indicator OnInit ( same indicator)

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

Result: 1:true:0
2:1:0

All is well detected, let me remind you of the code of the indicator OnInit

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

If it's not - why does it draw normally (buffer drawing) in the required subwindow?

So the calculation of the indicator and its drawing part are different things. ChartWindowFind is a reference to the mechanism that is responsible for drawing the indicator. I.e. it is not even the indicator itself.

 
Slava:

Until the indicator is initialised, it does not know the subwindow number in which it operates. It attaches to the window only after successful initialization.

Call ofChartWindowFind() after OnInit (from 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;
}

Result: OnInit:end
OnCalculate
3:-1:4113

In other words, the indicator already knows the subwindow number in which it operates, but does not report it
 
A100:

In other words, the indicator already knows the number of the window it is working in, but does not report it

Does it know ChartID()?

 
fxsaber:

Does it know ChartID()?

It is not required - ChartWindowFind() function without parameters
 
A100:
It is not required - ChartWindowFind() function without parameters

Just pretty sure it doesn't know ChartID() either (no parameters).

 
fxsaber:

I'm pretty sure it doesn't know ChartID() either (no parameters).

This is an obvious flaw, especially since the inoperability occurs not only if

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

but if

        long chart_id = ChartOpen( NULL, PERIOD_CURRENT );

I.e. if I manually add a chart window and attach the indicator to it, everything is OK

But if I do it automatically, it does not work

This is contrary to the very concept of algotrading

 
A100:

This is a glaring flaw, especially as it is not only inoperative if

but if

I.e. if I manually add a chart window and attach the indicator to it - everything is OK

But if I do it automatically, it does not work

This is contrary to the very concept of algotrading

It's good that the architecture of indicators has become clearer. It's strange that there is so little information about it in the documentation.

The calculation part of the indicator and the drawing part are different entities. The handle is the calculation part. The calculating one doesn't know anything about the drawing one and it shouldn't.

Imagine that you've created a handle, but you've placed it on not one, but two charts. Obviously, there is one indicator, but it is drawn on two charts with different ChartID and SubWindow. The Handle Indicator doesn't care about this, because it doesn't know where this indicator is drawn and whether it is drawn at all. It's not the indicator that is responsible for rendering.

When you place the indicator manually to the chart or through a template, quite a different action happens. A handle is created together with the drawing part. If you manually launch the indicator with the same input parameters on another chart with the same symbol and period, another handle will be created with the drawing part.

This is not the case with MQL. If you create one indicator and then another one, nothing is created again. The calculation part is left untouched.

The only way to run the indicator in MQL, the same way as you run it by hand, for example on a new chart or OBJ_CHART, is LoadTemplate.

Reason: