Emulación de ticks de un EA/indicador - página 3

 
Meat:

Sí, no está claro qué es lo que falla... Prueba esto entonces: En la sección de importación #import "user32.dll" añade una función:

CallWindowProcA(int lpPrevWndFunc[], int hWnd, int Msg, int wParam, int lParam);

Y al final de la función SetMyTimer añadir una línea: CallWindowProcA(code,0,0,0,0);

Y con algún indicador que funcione en paralelo comprobar si se genera un tick en este momento.

Bueno, algo parece haber cambiado, el registro es ahora así:
10:42:52 test EURUSD,H1: cargado con éxito
10:42:54 test EURUSD,H1: llamada de la función 'CallWindowProcA' desde la dll 'user32.dll' error crítico c0000005 en 02C310A8.
10:42:54 test EURUSD,H1: inicializar

¿Dónde hay una garrapata? ;)

 
Meat:

Zhunko, bueno, si todo es no estándar (su propio registro, su propia implementación de indicadores, etc.), entonces ¿por qué estás empezando toda esta conversación? En realidad estamos discutiendo el trabajo específicamente con MT4, no con nuestros propios desarrollos.

En mi primer post señalé específicamente que mi código será útil si la tarea es prescindir de los enlaces externos, es decir, implementar un Asesor Experto/indicador autosuficiente que utilice sólo las librerías del sistema. Y si estás utilizando tus propios desarrollos, entonces no es aplicable a ti.

Y en general, no entiendo por qué tengo que "limpiar manualmente el registro después del trabajo", si es más fácil no desordenarlo. Al fin y al cabo, por lo que he entendido, implementas tus desarrollos en DLL. Entonces, ¿qué le impide instalar el mismo temporizador allí, como sugerí aquí. Pero por alguna razón prefieres todo tipo de bailes con pandereta y limpiar el registro. Mi código te molesta, mientras que a ti te da pereza limpiar el registro todos los días :)

Mi registro sólo se ha llenado después de que haya aumentado mi historial. Ocurre los miércoles y los sábados. Se ha olvidado lo que es por su limpieza automática.

La actualización autónoma de las cartas se realiza desde hace mucho tiempo. Se aplica aquí. Usted ejecuta la función una vez desde cualquier programa y no necesita hacer nada más. Incluso con todos los programas MQL4 descargados, la actualización continúa, la apertura y el cierre del gráfico se monitoriza.

La alternativa a tu código no es la que yo sugerí. Es una solución sencilla para este problema, basada en su tarea. Una línea de código es mucho más simple que tu código. No tienes que limpiar los troncos todos los días. Sólo los fines de semana. El resto del tiempo no necesitas este código. Es racional. De todos modos, hay que limpiar el tronco. Por lo tanto, esta no es la razón.

======================

He ejecutado su código. No funciona en Window 7.

¿Podemos eliminar la función AddBytes()? Inicializa el array así:

  int code[7] = {0x558BEC6A, 0x16A0268, 0, 0, 0, 0, 0x33C05DC3};
  code[2] = MT4InternalMsg;
  code[3] = 0x68000000 + (hWnd >> 8);
  code[4] = (hWnd << 24) + 0x00B80000 + (PostMsgAddr >> 16);
  code[5] = (PostMsgAddr << 16) + 0x0000FFD0;
Es más corto. Aun así, es un trabajo único.
 
Zhunko:

Sólo obtengo un registro después de que el historial haya sido intercambiado. Ocurre los miércoles y los sábados. Se ha olvidado lo que es por su limpieza automática.

La actualización autónoma de los gráficos se hizo hace mucho tiempo. Se aplica aquí. Usted ejecuta la función una vez desde cualquier programa y no necesita hacer nada más. Incluso con todos los programas MQL4 descargados, la actualización continúa, la apertura y el cierre del gráfico se monitoriza.

La alternativa a tu código no es la que yo sugerí. Es una solución sencilla para este problema, basada en su tarea. Una línea de código es mucho más simple que tu código. No tienes que limpiar los troncos todos los días. Sólo los fines de semana. El resto del tiempo no necesitas este código. Es racional. De todos modos, hay que limpiar el tronco. Por lo tanto, esta no es la razón.

======================

He ejecutado su código. No funciona en Window 7.

¿Podemos eliminar la función AddBytes()? Inicializa el array así:

Será más corto. Aun así, es un trabajo único.

Sí, por supuesto, mi código publicado es sólo un código fuente para entender el significado, mientras que es más conveniente utilizarlo en forma de paquete ...Pero resulta que es demasiado pronto para compilarlo, porque por alguna razón no funciona :) Aunque a mí me funciona bien tanto en XP como en 7, no se cuelga nada, y eso que lo he ejecutado durante una hora. Es un poco misterioso...

Una línea de código es mucho más fácil que su código. No tienes que limpiar los troncos todos los días. Sólo los fines de semana. El resto del tiempo no necesitas este código. Es racional.

Puede que no sea crucial para usted personalmente si tiene su propio "limpiador de troncos" trabajando al mismo tiempo, es decir, si tiene su propia cocina allí, pero estamos hablando de un caso general. Imagina un usuario normal que no hace todas estas cosas. Entonces necesitará el "limpiador de registros" para trabajar bien con tu indicador. Es decir. Y debes admitir que es mucho más grande que el tamaño de mi código ;) Así que creo que te equivocas con lo de la racionalidad y la brevedad, sobre todo si tomas mi código de forma empaquetada, como sugieres. Por supuesto, no es una línea única, pero no requiere ningún otro complemento, es decir, es un producto completo.

El tronco debe ser limpiado de todos modos.

¿Por qué debería hacerlo? Si no lo obstruyo, ¿por qué debería limpiarlo?

 

Alexei, el limpiador no tiene por qué ser automático. Por ejemplo, haga clic con el botón derecho del ratón en una carpeta y seleccione"borrar carpeta". Hazlo después de experimentar los fines de semana.

A lo largo de un año, 365 archivos se acumulan en los EA y en los registros. Son 730 archivos. ¿No debería limpiarse? Es extraño escuchar eso. No se obstruye porque no se hace nada. Los troncos crecen mucho en tamaño cuando se trabaja todos los días.

 
Zhunko:

Alexei, el limpiador no tiene por qué ser automático. Por ejemplo, haga clic con el botón derecho del ratón en una carpeta y seleccione "borrar carpeta". Hazlo después de experimentar los fines de semana.

A lo largo de un año, 365 archivos se acumulan en los EA y en los registros. Son 730 archivos. ¿No debería limpiarse? Es extraño escuchar algo así. No se obstruye porque no se hace nada. Los troncos crecen mucho cuando se trabaja a diario.

Bueno, en principio sí, estoy de acuerdo en que después de los experimentos normalmente hay que limpiarlos. Un indicador se crea para trabajar, no para experimentar, así que si un indicador depurado sigue atascando los archivos de registro mientras funciona, no será correcto.

Hablando de borrar los registros antiguos, es una cuestión de preferencias personales, por ejemplo, tuve que buscar alguna información en los registros de hace un año. Así que no los borro. Me refiero a los registros directamente relacionados con el comercio, no a los diferentes experimentos.

 
Meat:

Bueno, en principio sí, estoy de acuerdo en que normalmente hay que limpiarlos después de los experimentos. Pero no sólo hablamos de experimentos. Al fin y al cabo, un indicador se crea para trabajar, no para experimentar. Por lo tanto, si un indicador depurado sigue obstruyendo los registros en el proceso de su trabajo, ya está mal.

Por lo tanto, quiero decir que tal truco es necesario sólo en los fines de semana. El resto del tiempo no lo necesitas.
 

En general, la generación de garrapatas también es necesaria entre semana. Parece que considera un Asesor Experto/indicador que utiliza sólo las cotizaciones de su símbolo. Por supuesto, puede simplemente ejecutarlo en algún símbolo líquido, por ejemplo EURUSD, donde los ticks vienen a menudo... Pero no es una cura para todo, y puede no ser muy conveniente.

 

En cualquier caso, cuando se quiere ver el resultado antes de que llegue la garrapata.

Es decir, - con fines de investigación.

 

He descubierto cuál era el problema: el array debería declararse globalmente, no localmente.

Voy a publicar la versión corregida. He acortado el código al mismo tiempo. La variante propuesta por Zhunko, aunque era 3 líneas más corta que ésta, era demasiado complicada e inconveniente para entender el algoritmo). Por lo tanto, no creo que haya que ir a los extremos en aras de la reducción del código.

#property indicator_chart_window

#import "user32.dll"
  int   RegisterWindowMessageA(string lpString);
  int   SetTimer(int hWnd,int nIDEvent,int uElapse,int& lpTimerFunc[]);
  bool  KillTimer(int hWnd,int uIDEvent);
#import "kernel32.dll"
  int   GetModuleHandleA(string lpModuleName);
  int   GetProcAddress(int hModule,string lpProcName);
  
int TimerId=666;
int TimerCode[7];

//----------------------------------------------------------------------

int init()
{
  SetMyTimer(1000);  // интервал в миллисекундах
}
//----------------------------------------------------------------------

int deinit()
{
  KillMyTimer();
  Comment("");
}  

//+------------------------------------------------------------------+
//| program start function                                           |
//+------------------------------------------------------------------+
int start()
{
  static int n=0;
  n++; 
  Comment("tick:  ",n);
  PlaySound("tick.wav");
}
//-------------------------------------------------------------------

int SetMyTimer(int interval)
{    
  int MT4InternMsg= RegisterWindowMessageA("MetaTrader4_Internal_Message");
  int hWnd= WindowHandle(Symbol(),Period());
  int PostMsgAddr= GetProcAddress(GetModuleHandleA("user32.dll"),"PostMessageA");
  if (PostMsgAddr==0) return(0);
  // push ebp; move ebp,esp; push 01; push 02; push MT4InternMsg; push hWnd; mov eax,PostMsgAddr; call eax; pop ebp; ret;    
  int value[]={ 0x55, 0x8B,0xEC, 0x6A,01, 0x6A,02, 0x68,0000, 0x68,0000, 0xB8,0000, 0xFF,0xD0, 0x5D, 0xC3 };
  int len[]=  { 1,    1,   1,    1,   1,  1,   1,  1,   4,    1,   4,    1,   4,    1,   1,    1,    1    };
  value[8]=MT4InternMsg;  value[10]=hWnd;  value[12]=PostMsgAddr; 
  int byte=0;
  for (int i=0; i<ArraySize(value); i++)
    for (int j=0;  j<len[i];  j++, byte++)
      TimerCode[byte/4] += (value[i]>>(8*j)&0xFF) <<(byte%4*8);
  
  return ( SetTimer(hWnd, TimerId, interval, TimerCode) );
}

//---------------------------------------------------

bool KillMyTimer()
{
  return( KillTimer(WindowHandle(Symbol(),Period()), TimerId) );
}
 
Meat:

En general, la generación de garrapatas también es necesaria entre semana. Parece que considera un Asesor Experto/indicador que utiliza sólo las cotizaciones de su símbolo. Por supuesto, puede simplemente ejecutarlo en algún símbolo líquido, por ejemplo EURUSD, donde los ticks vienen a menudo... Pero no es una panacea, y puede no ser muy conveniente.

¿Tiene un solo ejemplo?

Desde que escribo y lo uso, nunca lo he necesitado, salvo los fines de semana.

Asesor experto + indicador. Se soluciona "congelando" el Asesor Experto. El resultado es el mismo que para ti. Para recibir los datos a tiempo, basta con reaccionar a los cambios de hora del servidor. Para ello no se necesita WinAPI.

El único caso, cuando se necesita, es para iniciar el Asesor Experto en el fin de semana. Incluso eso se puede implementar con la línea que di arriba. Sólo para el Asesor Experto.

Razón de la queja: