Reading indicator buffers set to chart - page 3

 
comp:

Subject:

Spell it right and you'll be happy.
 
Dmitry Fedoseev:
So?

Start the indicator, then - the Expert Advisor

#property strict

#define  PAUSE 100

sinput int BufferIndex = 0;     // Номер буфера индикатора
sinput bool TimerEvent = FALSE; // Использование события Timer

string IndicatorName;

string GetBetweenString( string &SourceString, const string BeginString, const string EndString = "" )
{
  string Str = SourceString;
  int Pos1 = 0;
  int Pos2 = 0;

  if (BeginString != "")
    Pos1 = StringFind(SourceString, BeginString);

  if (Pos1 >= 0)
  {
    Pos1 += StringLen(BeginString);

    Pos2 = StringFind(SourceString, EndString, Pos1);

    if (Pos2 != Pos1)
      Str = StringSubstr(SourceString, Pos1, Pos2 - Pos1);
    else
      Str = "";
  }

  SourceString = StringSubstr(SourceString, Pos2 + StringLen(EndString));

  return(Str);
}

string FileToString( const string FileName )
{
  string Res = "";

  const int handle = FileOpen(FileName, ::FILE_READ|::FILE_BIN);

  if (handle != INVALID_HANDLE)
  {
    uchar Array[];

    FileReadArray(handle, Array);

    Res = CharArrayToString(Array);

    FileClose(handle);
  }

  return(Res);
}

string GetIndicatorName( const long Chart_ID = 0 )
{
  string Res = "";

  const string FileName = ::WindowExpertName() + ".tpl";

  if (ChartSaveTemplate(Chart_ID, "..\\MQL4\\Files\\" + FileName))
  {
    string Str = FileToString(FileName);

    if (StringFind(Str, "name=Custom Indicator") > 0)
      Res = GetBetweenString(Str, "<indicator>\r\nname=Custom Indicator\r\n<expert>\r\nname=", "\r\n");
  }

  return(Res);
}

string GetIndicatorString( const int Pos = -1 )
{
  static int PrevPos = 0;

  if (Pos != -1)
    PrevPos = Pos;

  const string Str = ((PrevPos < 0) || (IndicatorName == "")) ? "" : IndicatorName + "[" + (string)BufferIndex + "][" + (string)PrevPos + " - " + (string)Time[PrevPos] +
                                                                     "] = " + (string)iCustom(Symbol(), Period(), IndicatorName, BufferIndex, Pos);
  return(Str);
}

void OnInit( void )
{
  IndicatorName = GetIndicatorName();

  ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, TRUE);

  if (TimerEvent)
    EventSetMillisecondTimer(PAUSE);

  return;
}

void OnDeinit( const int reason )
{
  if (TimerEvent)
    EventKillTimer();

  Comment("");

  return;
}

void OnTimer( void )
{
  Comment(GetIndicatorString());

  return;
}

void OnChartEvent( const int id, const long& lparam, const double& dparam, const string& sparam )
{
  if (id == CHARTEVENT_MOUSE_MOVE)
  {
    datetime time;
    double price;
    int SubWindow;

    ChartXYToTimePrice(0, (int)lparam, (int)dparam, SubWindow, time, price);
    const int Pos = iBarShift(Symbol(), Period(), time, TRUE);

    Comment(GetIndicatorString(Pos));
  }

  return;
}

You notice that the indicator buffer values (CTRL+D) do not coincide with iCustom values (they are printed in the Expert Advisor's chart comment).

In case of our test, iCustom will give either EMPTY_VALUE or zero.

 

Checked. It's not that it doesn't match, it's not there at all. Pretty cool.

 
comp:

Judging by the silence, more than seven years since this problem was publicly announced in the fourth forum (google remembers), the developers have not created a functionality.

For some reason they still can't do a human readout of the indicator data from the chart! It sounds crazy, but it is.

The problem is in the problem statement.

You're just using the indicators for the wrong purpose. They're not designed to be timed and react to events, they're designed to economically rework time-series.

Approach your task from the other side and you will find a nice and economical solution.

 
It's not about reading buffers, it's about the fact that the indicator called via iCustom() has no timer and no chart events.
 
Dmitry Fedoseev:
It's not about reading buffers, it's about the fact that the indicator called via iCustom() has no timer and no chart events.

What are they for?

Well, seriously, what for?

 
Andrey Khatimlianskii:

What are they for?

Well, seriously, why?

I don't need it. But here someone needed it, it turns out.
 
Andrey Khatimlianskii:

The problem is in the problem statement.

You are simply using the indicators for the wrong purpose. They are not designed to be timed and react to events, they are designed to economically rework time-series.

Approach your task from the other side and you will find a nice and economical solution.

It's like a hammer on the head to make such a statement. I decided to look for indicators in kodobase. I haven't found ANY that uses the usual approach: event-driven model + OOP.

It's hard to say what's more: frustration or disappointment with this state of affairs. Indicators, it turns out, MUST be written primitively.

Does anyone use the event model + OOP in indicators?

Well it still doesn't negate the perplexity that you can't programmatically get what you see with your eyes on a chart!

 
When writing a test Expert Advisor with iCustom, I have faced an unsolvable MQL problem. To know the file name (see the code) of the indicator and the values of the input parameters - no problem. But after that it is impossible to insert the indicator's input parameters into iCustom. The way iCustom is called is that a universal solution for any indicator is suitable only in the case of the default input parameters. Otherwise we have to go into the code. This solution is not convenient. We could pass the indicator inputs as a structure with the appropriate string-fields. But we used the ellipsis, which killed the universality of the call. Another strange restriction!
 
comp:

It's like a kick in the head to make a statement like that. I decided to look for indicators in kodobase. I haven't found ANY that uses what I'm used to: event-driven model + OOP.

It's hard to say what's more: frustration or disappointment with this state of affairs. Indicators, it turns out, MUST be written primitively.

Does anyone use the event model + OOP in indicators?

Well it still doesn't negate the perplexity that you can't programmatically get what you see with your eyes on a chart!

Why? Everything has already been stolen there before us, there is OnCalculate function - tick event. If you want to use OOP - use it, but what for is it there, where to put it?