Número mágico automático - página 2

 
jjc:

Me falta algo aquí. Si abro dos gráficos para, por ejemplo, USDJPY H1, y añado una instancia del EA a cada uno de ellos, entonces ambos utilizan el número mágico 9999033.

Sí, esa opción no estaba incorporada porque nunca la he utilizado. La única posibilidad de distinguir entre dos gráficos idénticos (que yo pueda ver) sería hacer un hash en el mango de la ventana...

pero entonces se perdería la persistencia sobre los reinicios y el cierre de los gráficos, y por lo tanto las órdenes huérfanas pueden o serán creadas como resultado.

 
BarrowBoy:

Entonces, ¿es la aplicación de terminal MT un 'contenedor' - con un solo hWnd para <todo el asunto>?

Sí, es una aplicación MDI bastante típica. Hay una ventana de nivel superior que contiene cosas como barras de herramientas, paneles y el área de cliente MDI. Esta última contiene cada gráfico, y cada gráfico consiste en realidad en dos ventanas: un contenedor con el área de dibujo dentro de él. Cada una de estas cosas tiene su propio manejador hWnd. La función WindowHandle() devuelve el manejador del área de dibujo, y por lo tanto usando la llamada a la API GetParent() tres veces se obtiene el hWnd de la ventana de nivel superior de MT4.

 

fwiw, yo uso abajo y nunca he tenido duplicados. El mismo EA en hasta 10 [cualquier tipo] gráficos.

No tengo ninguna respuesta a la basura masivamente real entregado a la función de hash. Acabo de empujado en todo, incluyendo el fregadero de la cocina. es decir, no soy una persona de matemáticas ..., sólo martillo 'n cincelado lejos hasta que nunca se repite - incluso en el inicio de la terminal con 10 perfil gráfico todo mismo EA ...

Obviamente, me gustaría tener un método mejor y más descriptible / lógica... así que empezar a romper en pedazos :O)

#define EMPTYSTRING     ""
#define EAIDMIN         1
#define EAIDMAX         21473


  //+------------------------------------------------------------------+
//
int iMakeHash (string s1, string s2=EMPTYSTRING, string s3=EMPTYSTRING, string s4=EMPTYSTRING, string s5=EMPTYSTRING
              ,string s6=EMPTYSTRING, string s7=EMPTYSTRING, string s8=EMPTYSTRING, string s9=EMPTYSTRING, string s10=EMPTYSTRING)
{
  /*
  Produce 32bit string hash code from  a string composed of up to TEN concatenated input strings.
  WebRef: http://www.cse.yorku.ca/~oz/hash.html
  KeyWrd: "djb2"
  FirstParaOnPage:
  "  Hash Functions
    A comprehensive collection of hash functions, a hash visualiser and some test results [see Mckenzie
    et al. Selecting a Hashing Algorithm, SP&E 20(2):209-224, Feb 1990] will be available someday. If
    you just want to have a good hash function, and cannot wait, djb2 is one of the best string hash
    functions i know. it has excellent distribution and speed on many different sets of keys and table
    sizes. you are not likely to do better with one of the "well known" functions such as PJW, K&R[1],
    etc. Also see tpop pp. 126 for graphing hash functions.
  "

  NOTES:
  0. WARNING - mql4 strings maxlen=255 so... unless code changed to deal with up to 10 string parameters
     the total length of contactenated string must be <=255
  1. C source uses "unsigned [char|long]", not in MQL4 syntax
  //
  Downside?
    original code uses UNSIGNED - MQL4 not support this, presume could use type double and then cast back to type int.
  */
  string s = StringConcatenate(s1,s2,s3,s4,s5,s6,s7,s8,s9,s10);
  int iHash = 5381;
  int iLast = StringLen(s)-1;
  int iPos=0;

  while( iPos <= iLast )    //while (c = *str++)  [ consume str bytes until EOS hit {isn't C concise!} ]
  {
    //original C code: hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
    iHash = ((iHash << 5) + iHash) + StringGetChar(s,iPos);    //StringGetChar() returns int
    iPos++;
  }
  return(MathAbs(iHash));
  
}//iMakeHash()




  //+------------------------------------------------------------------+
//
int iMakeExpertId ()
{
  int i1a,i2a,i1b,i2b;
  int iExpertId = EAIDMAX+1;
  while(iExpertId<EAIDMIN || iExpertId>EAIDMAX)
  {
    i1a=TimeLocal(); i2a=GetTickCount();
    Sleep(500);
    i1b=TimeLocal(); i2b=GetTickCount();
    MathSrand(iMakeHash(Symbol()
                        ,DoubleToStr(Period(),Digits)
                        ,DoubleToStr(i2a*WindowBarsPerChart()/Period(),Digits-1)
                        ,DoubleToStr(WindowTimeOnDropped()/i2b,Digits+1)
                        ,StringConcatenate(i2a/Period()
                                          ,Symbol()
                                          ,Period()
                                          ,i1a
                                          ,i2b*WindowBarsPerChart()/Period()
                                          ,i1b/WindowBarsPerChart()
                                          ,WindowTimeOnDropped()
                                          )
                        )
              );

    iExpertId = MathRand();  //here, on 2nd rand call, is even btr (tests seem to say this...)
  }

  return(iExpertId);

}//iMakeExpertId()

daaaaamn... these results are when had diff EAIDMAX! Anyway, just can't get the staff these days 0 lol
  /*test extract:
12:06:22 "EXPERT ID = "19736
12:06:21 "EXPERT ID = "16236
12:06:20 "EXPERT ID = "4633
12:06:19 "EXPERT ID = "26753
12:06:18 "EXPERT ID = "28286
12:06:16 "EXPERT ID = "23335
12:06:15 "EXPERT ID = "4036
12:06:14 "EXPERT ID = "12879
12:06:13 "EXPERT ID = "8095

12:06:08 "EXPERT ID = "7940
12:06:07 "EXPERT ID = "10700
12:06:06 "EXPERT ID = "24889
12:06:05 "EXPERT ID = "16055
12:06:04 "EXPERT ID = "12774
12:06:03 "EXPERT ID = "10058
12:06:02 "EXPERT ID = "29346
12:06:01 "EXPERT ID = "14624
12:06:00 "EXPERT ID = "18432
*/
 
fbj:

fwiw, yo uso abajo y nunca he tenido duplicados. El mismo EA en hasta 10 [cualquier tipo] gráficos.

No tengo ninguna respuesta a la basura masivamente real entregado a la función de hash. Acabo de empujado en todo, incluyendo el fregadero de la cocina. es decir, no soy una persona de matemáticas ..., sólo martillo 'n cincelado lejos hasta que nunca se repite - incluso en el inicio de la terminal con 10 perfil gráfico todo mismo EA ...

Obviamente, me gustaría tener un método mejor y más descriptible/lógico... así que empieza a destrozarlo :O)

Me gusta. Sobre todo el bueno de djb2 hash.

 

Impresionante, chicos :)

Los contenedores MDI me retrotraen <suspiro>.

Sigo diciendo que, en mi opinión, los números mágicos son demasiado importantes para aplicarlos al azar.

Estoy seguro de que CB confirmaría que la recuperación predecible en el reinicio es un elemento extremadamente importante en un sistema robusto..

FWIW

-BB-

 

Con este código un EA es capaz de reconocer sus propias órdenes si la plataforma se apaga. Utiliza Variables Globales por lo que si se quiere hacer que el EA sea "inmune" al cierre del PC se podría reescribir para utilizar archivos en lugar de Variables Globales. He adjuntado también un ejemplo que abre una posición justo en el momento de init y la cierra en la siguiente barra, puedes cargar el experto en 1M timeframe, apagar metatrader y volver a abrirlo, solo hay que esperar a la siguiente barra para ver como el EA cierra su orden. No se ha probado con múltiples gráficos ni se ha trucado con múltiples órdenes, pero ¿qué os parece?

int MagicNumber;
 
int init()
{
   // Unique sting id.    
   string id = WindowExpertName() + Symbol() + Period();
    
    
   // If there isn't already a Global Variable with the id in wich search for the MagicNumber create it  
   if(!GlobalVariableCheck( id))
   {
      MagicNumber = WindowHandle(Symbol(),0);   
      GlobalVariableSet( id, MagicNumber);
   }
   else // Just get the MagicNumber for the unique id
   {
      MagicNumber = GlobalVariableGet( id);
   }
      
}
Archivos adjuntos:
 
jjc wrote >>

Me gusta. Particularmente el buen djb2 hash.

gracias - pero realmente me siento avergonzado por un poco de codificación tan desinformada en makeexpertid...

Es pronto todavía, pero tal vez alguien se dará cuenta de la falla (s ) ... en caso de que estén presentes

 
BarrowBoy wrote >>

Impresionante, chicos :)

Los contenedores MDI me retrotraen <suspiro>.

Sigo diciendo que, en mi opinión, los números mágicos son demasiado importantes para aplicarlos al azar.

Estoy seguro de que CB confirmaría que la recuperación predecible en el reinicio es un elemento extremadamente importante en un sistema robusto..


FWIW

-BB-

Sigo diciendo que, en mi opinión, los números mágicos son demasiado importantes para aplicarlos al azar.

por supuesto BB, datos vip. Pasé demasiado tiempo tratando de descubrir un dato único que múltiples instancias de un EA pudieran utilizar. Este dato tenía que ser repetible de tal manera que todos los archivos abiertos fueran mapeables en la recuperación/reinicio. Quería permitir la posibilidad de que cualquier número de instancias del mismo ccy+per chart EA abrieran "de alguna manera" un único nombre de archivo y al reiniciar volvieran a abrirlo mágicamente...


¿Los datos de la manilla de la ventana podrían ser ese "factor X"?

 
fbj:

por supuesto BB, vip datums. Pasé demasiado tiempo intentando descubrir un dato único que varias instancias de un EA pudieran utilizar. Este dato tenía que ser repetible de tal manera que todos los archivos abiertos fueran mapeables en la recuperación/reinicio. Quería permitir la posibilidad de que cualquier número de instancias del mismo ccy+per chart EA abrieran "de alguna manera" un nombre de archivo único y al reiniciar volvieran a abrirse mágicamente...

No puedo ver cómo esto es posible sin que MT4 o el usuario asigne un ID a cada EA. O, más exactamente, no puedo ver nada que no implique algo muy desagradable como generar un ID único y luego modificar el archivo .chr del EA para almacenar el ID como parte de los parámetros externos del EA.


Y, para entretenimiento general, lo siguiente no avanza realmente la discusión de ninguna manera, pero reemplaza la entrada al hash djb2 con un valor que está garantizado para ser único (a costa de requerir llamadas DLL). No sé qué tan bueno es djb2 en cosas como GUIDs, pero acabo de intentar generar 1,000,000 IDs sin ninguna colisión. Pero sigue sin resolver el problema del reinicio.


#import "ole32.dll"
   int CoCreateGuid(int & Bytes[]);
#import

int GenerateMagicNumber()
{
   // Generate a 16-byte GUID
   int Bytes[4];
   CoCreateGuid( Bytes);
   
   // Hash the GUID using djb2
   int iHash = 5381;
   for (int i = 0; i < 4; i++) {
      //original C code: hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
      iHash = (( iHash << 5) + iHash) + Bytes[ i];
   }
   return (MathAbs( iHash));
}
 
fbj wrote >>

Los datos de la manilla de la ventana podrían ser ese "factor X"?

¿Si no estuvieras cerrando parcialmente ninguna orden, podrías utilizar el comentario de la orden para almacenar la información del par/marco de tiempo de origen?

Así el EA, al reiniciar, podría averiguar si tenía alguna orden anterior y qué número mágico se supone que debe utilizar?

NB

Mantener los comentarios a < 25 y comprobar en el LEFT(OrderComments(), 24) de lo contrario las cosas [sl] o [tp] podrían afectar a las cosas

¡Asume que <todo el historial> se deja disponible en la pestaña del historial de la cuenta!

FWIW

-BB-