Lectura de los búferes de los indicadores fijados en el gráfico - página 3

 
comp:

Asunto:

Deletréalo bien y serás feliz.
 
Dmitry Fedoseev:
¿Y qué?

Inicie el indicador, luego - el Asesor Experto

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

Se observa que los valores del buffer del indicador (CTRL+D) no coinciden con los valores de iCustom (se imprimen en el comentario del gráfico del Asesor Experto).

En el caso de nuestra prueba, iCustom dará EMPTY_VALUE o cero.

 

Comprobado. No es que no coincida, es que no está en absoluto. Bastante bien.

 
comp:

A juzgar por el silencio, más de siete años desde que se anunció públicamente este problema en el cuarto foro (google recuerda), los desarrolladores no han creado una funcionalidad.

¡Por alguna razón todavía no pueden hacer una lectura humana de los datos del indicador desde el gráfico! Parece una locura, pero lo es.

El problema está en el planteamiento del problema.

Sólo estás usando los indicadores para el propósito equivocado. No están diseñadas para ser cronometradas y reaccionar a los acontecimientos, sino para rehacer económicamente las series temporales.

Aborde su tarea desde el otro lado y encontrará una solución agradable y económica.

 
No se trata de leer los buffers, sino de que el indicador llamado a través de iCustom() no tiene temporizador ni eventos de gráfico.
 
Dmitry Fedoseev:
No se trata de leer los buffers, sino de que el indicador llamado a través de iCustom() no tiene temporizador ni eventos de gráfico.

¿Para qué sirven?

Bueno, en serio, ¿para qué?

 
Andrey Khatimlianskii:

¿Para qué sirven?

Bueno, en serio, ¿por qué?

No lo necesito. Pero resulta que aquí alguien lo necesitaba.
 
Andrey Khatimlianskii:

El problema está en el planteamiento del problema.

Simplemente estás utilizando los indicadores para un propósito equivocado. No están diseñadas para ser cronometradas y reaccionar ante los acontecimientos, sino para reelaborar económicamente las series temporales.

Aborde su tarea desde el otro lado y encontrará una solución agradable y económica.

Es como un martillo en la cabeza para hacer tal declaración. Decidí buscar indicadores en kodobase. No he encontrado NINGUNO que utilice lo que estoy acostumbrado: modelo dirigido por eventos + OOP.

Es difícil decir qué es más: la frustración o la decepción por este estado de cosas. Resulta que los indicadores DEBEN escribirse de forma primitiva.

¿Alguien utiliza el modelo de eventos + OOP en los indicadores?

Bueno, eso sigue sin negar la perplejidad de que no se pueda obtener programáticamente lo que se ve con los ojos en un gráfico.

 
Al escribir un Asesor Experto de prueba con iCustom, me he enfrentado a un problema MQL irresoluble. Para conocer el nombre del archivo (ver el código) del indicador y los valores de los parámetros de entrada - no hay problema. Pero después es imposible insertar los parámetros de entrada del indicador en iCustom. La forma en que se llama iCustom es que una solución universal para cualquier indicador es adecuada sólo en el caso de los parámetros de entrada por defecto. Si no, tenemos que entrar en el código. Esta solución no es conveniente. Podríamos pasar las entradas del indicador como una estructura con los campos de cadena adecuados. Pero usamos la elipsis, lo que mató la universalidad de la llamada. Otra extraña restricción.
 
comp:

Es como una patada en la cabeza hacer una declaración así. Decidí buscar indicadores en kodobase. No he encontrado NINGUNO que utilice lo que estoy acostumbrado: modelo dirigido por eventos + OOP.

Es difícil decir qué es más: la frustración o la decepción por este estado de cosas. Resulta que los indicadores DEBEN escribirse de forma primitiva.

¿Alguien utiliza el modelo de eventos + OOP en los indicadores?

Bueno, eso sigue sin negar la perplejidad de que no se pueda obtener programáticamente lo que se ve con los ojos en un gráfico.

¿Por qué? Todo ya ha sido robado allí antes de nosotros, hay función OnCalculate - evento de garrapatas. Si quieres usar la POO, úsala, pero ¿para qué está ahí, dónde ponerla?