Чтение буферов индикатора, установленного на чарт - страница 3

 
comp:

Подопытный:

Пишите правильно , и будет вам счастье
 
Dmitry Fedoseev:
Ну и что?

Запускаете индикатор, затем - советник

#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;
}

Наблюдаете, что значения буфера индикатора (CTRL+D) не совпадают со значениями iCustom (выводятся в комментарий чарта советником).

iCustom в случае с нашим подопытным будет выдавать либо EMPTY_VALUE, либо ноль. 

 

Проверил. Не то, чтобы не совпадало, его вообще нет. Прикольненько. 

 
comp:

Судя по молчанию, более, чем за семь лет, как эта проблема была озвучена публично еще на четвертом форуме (гугл помнит), разработчики функционала так и не создали.

По какой-то причине до сих пор нельзя по-человечески сделать считывание данных индикатора с чарта! Звучит бредово, но это так.

Проблема в постановке задачи.

Вы просто не для того используете индикаторы. Они не предназначены для работы по таймеру и реакции на события, они предназначены для экономного перелопачивания тайм-серий.

Подойдите к своей задаче с другой стороны, и найдете красивое и экономное решение. 

 
Дело не в чтении буферов, а в том, что у индикатра вызванного через iCustom() не работает таймер и нет событий чарта.
 
Dmitry Fedoseev:
Дело не в чтении буферов, а в том, что у индикатра вызванного через iCustom() не работает таймер и нет событий чарта.

А зачем они?

Ну, серьезно, зачем? 

 
Andrey Khatimlianskii:

А зачем они?

Ну, серьезно, зачем? 

Мне ненадо. Но вот тут кому-то понадобилось, оказывается.
 
Andrey Khatimlianskii:

Проблема в постановке задачи.

Вы просто не для того используете индикаторы. Они не предназначены для работы по таймеру и реакции на события, они предназначены для экономного перелопачивания тайм-серий.

Подойдите к своей задаче с другой стороны, и найдете красивое и экономное решение. 

Как обухом по голове такое заявление. Решил поискать индикаторы в кодобазе. Не нашел НИ ОДНОГО, в котором бы использовалось то, к чему привык: событийная модель + ООП.

Сложно сказать, чего больше: расстройства или разочарования от такого положения вещей. Индикаторы, оказывается, НЕОБХОДИМО писать примитивно.

Кто-нибудь использует в индикаторах событийную модель + ООП?

Ну и это все же не отменяет недоумение, что программно нельзя получить то, что вижу глазами на чарте! 

 
При написании проверочного советника с iCustom столкнулся с неразрешимой проблемой MQL. Узнать имя файла (см. код) индикатора и значения входных параметров - не вопрос. Но после этого вставить эти входные параметры индикатора в iCustom - никак. Вызов iCustom устроен так, что универсальное решение для любого индикатора подходит только в случае с дефолтными входными параметрами. Иначе - приходится лезть в код. Какое-то кривое решение. Можно же было передавать входы индикатора в виде структуры с соответствующими string-полями. Но сделали через многоточие, что убило всю универсальность вызова. Еще одно непонятное ограничение!
 
comp:

Как обухом по голове такое заявление. Решил поискать индикаторы в кодобазе. Не нашел НИ ОДНОГО, в котором бы использовалось то, к чему привык: событийная модель + ООП.

Сложно сказать, чего больше: расстройства или разочарования от такого положения вещей. Индикаторы, оказывается, НЕОБХОДИМО писать примитивно.

Кто-нибудь использует в индикаторах событийную модель + ООП?

Ну и это все же не отменяет недоумение, что программно нельзя получить то, что вижу глазами на чарте! 

Зачем? Там уже все украдено до нас, есть функция OnCalculate - событие приходя тика. Хочется использовать ООП - используйте, только зачем оно там, куда его там девать?
Причина обращения: