crear un número mágico - página 3

 
//|                                                      This_EA.mq4 |
//|                      Copyright © 2010, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+

#define This_EA  101
#define That_EA  102
#define Other_EA 103 // put this list of ea names to each of your ea's header, or...
                     // .. alternatively you can use a number suffix to your ea's file name 
                     // so it can be identified with --> StringSubstr(WindowExpertName(),x,y);
double This_EA_qty;
string magic_prefix;

int init()
  {

   if(GlobalVariableGet(This_EA_qty) >= 0.0){
            GlobalVariableSet("This_EA_qty", This_EA_qty + 1);
   }
   magic_prefix = StringConcatenate(This_EA, DoubleToStr(This_EA_qty,0));

   return(0);
  }

int deinit()
  {

      GlobalVariableSet("This_EA_qty", This_EA_qty - 1);
   
   return(0);
  }

int start()
  {
      double lots, SL, TP; int slip, time_stamp ;
      bool BuyCondition;
   
      if( BuyCondition == true )
      {
         time_stamp  = TimeCurrent(); 
         string magic_name = StringConcatenate(magic_prefix, time_stamp );
         int magic = StrToInteger(magic_name);
         
                                      // Integers range from -2147483648 to 2147483647
                                      // the resulting magic integer would most probably exceed that 
                                      // so we cut the number returned with TimeCurrent() short with 
                                      // MathMod(time_stamp,x) x being years, months not necessary for 
                                      // magic unique-ness. I don't include this calculation, 
                                      // since I'm short in time for testing it...
      
      
         OrderSend(Symbol(),0, lots, Ask, slip, SL, TP, NULL, magic, 0, CLR_NONE);
      }
//----
   return(0);
  }
//+------------------------------------------------------------------+
tarda un poco más de lo que pensaba ...
edit : Condición GVget != -1.0 a >= 0.0; edit
 
cameofx:
[...] tarda un poco más de lo que pensaba...

Esto se está convirtiendo cada vez más en un refrito (perdón por el juego de palabras) del tema anterior que ya he mencionado: https://www.mql5.com/en/forum/120034. Todo lo que implique variables globales plantea problemas en relación con las copias de seguridad y la recuperación de desastres. Si el comercio tiene que ser trasladado a toda prisa a un nuevo servidor, entonces tiene que haber una copia de seguridad reciente de gvariables.dat disponible, o el usuario tiene que estar en condiciones de recrear las variables globales manualmente.

No he estudiado su código de cerca, pero tampoco estoy seguro de lo que sucede si hay varias copias de la EA y MT4 se reinicia. Parece que el código puede asumir que los EAs se recargarán automáticamente en el mismo orden en que fueron cargados manualmente. En otras palabras, múltiples copias del EA pueden obtener diferentes valores de This_EA_qty a través de reinicios, y no puedo entonces ver cómo identifican correctamente sus órdenes históricas en la lista de MT4. Pero podría estar equivocado en esto.

 
cameofx:
tarda un poco más de lo que pensaba ...
editar : condición GVget != -1.0 a >= 0.0
// TimeCurrent() in seconds since 1970 would most probably exceed that 

TimeCurrent() devuelve un entero de 32 bits. El tipo datatime es un alias del tipo int, int es también un entero de 32 bits.


La otra cosa que no entiendo en tu código es ¿por qué estás usando un MN diferente para cada operación abierta? Esto es lo contrario de lo que los MNs están destinados. La idea de un MN es que puedas identificar todas las operaciones de un determinado EA simplemente mirando el MN. ¿Cuál es la razón de la parte aleatoria del MN? ¿Cómo se vería el código en su EA que cerraría todas las operaciones abiertas de este EA o rastrearía todas las paradas de este EA?
 
Si he entendido bien, su solución para que dos expertos diferentes tengan accidentalmente el mismo ID es poner todos los ID de los expertos en la cabecera de cada uno de ellos. Eso es una especie de dolor en el culo ... Incluso si pones esa parte en un archivo de inclusión, todavía tendrías que recompilar todos los expertos para cada nuevo experto que hagas.

La cuestión de la persistencia sigue ahí. No sé cómo funcionaría esto correctamente después de un reinicio de la terminal o después de cambiar a una terminal completamente diferente...
 
jjc:

Esto se está convirtiendo cada vez más en un refrito (perdón por el juego de palabras) del tema anterior que ya he mencionado: https://www.mql5.com/en/forum/120034. Todo lo que implique variables globales plantea problemas en relación con las copias de seguridad y la recuperación de desastres. Si el comercio tiene que ser trasladado a toda prisa a un nuevo servidor, entonces tiene que haber una copia de seguridad reciente de gvariables.dat disponible, o el usuario tiene que estar en condiciones de recrear las variables globales manualmente.

No he estudiado su código de cerca, pero tampoco estoy seguro de lo que sucede si hay varias copias de la EA y MT4 se reinicia. Parece que el código puede asumir que los EAs se recargarán automáticamente en el mismo orden en que fueron cargados manualmente. En otras palabras, múltiples copias del EA pueden obtener diferentes valores de This_EA_qty a través de reinicios, y no puedo entonces ver cómo identifican correctamente sus órdenes históricas en la lista de MT4. Pero podría estar equivocado en esto.

Estos son los comentarios que espero... gracias gordon, 7bit & jjc..

tus respuestas necesitan algo de reflexión .. pero para responder rápidamente :

- si el experto This_EA ya se adjunta una vez en otro gráfico, magic_number entonces tendría el valor de : 101-1-time_stamp (guión para mayor claridad)

- la información contenida sería 101 - id de experto; 1 - cantidad de This_EA operando al momento; time_stamp - hora de OrderSend

- podemos entonces escanearlo con StringSubStr y saber que una orden particular fue abierta por This_EA mientras había 1 otro This_EA adjunto.

 
7bit:

TimeCurrent() devuelve un entero de 32 bits. El tipo datatime es un alias del tipo int, int es también un entero de 32 bits.


La otra cosa que no entiendo en tu código es ¿por qué estás usando un MN diferente para cada operación abierta? Esto es lo contrario de lo que los MN están destinados. La idea de un MN es que puedas identificar todas las operaciones de un determinado EA simplemente mirando el MN. ¿Cuál es la razón de la parte aleatoria del MN? ¿Cómo se vería el código en su EA que cerraría todas las operaciones abiertas de este EA o rastrearía todas las paradas de este EA?

Perdón, lo que quise decir es que el int resultante nombre_magia excedería esa asignación. Voy a mover el comentario en el código en consecuencia.

Para igualar nuestra percepción. Yo propondría estos requisitos para este magic_number 'automatizado'. El MN tendría lo siguiente :

- Puede identificar con qué EA - esta orden particular con dicho MN - estaba abierta.

- Un EA que contenga esta técnica - si está unido a numerosos (más de 1) no generaría el mismo número mágico si esos EAs abren órdenes simultáneamente fuera de un lapso de 1 segundo

- por lo tanto, no entraría en conflicto en el manejo de órdenes, pero al mismo tiempo el origen de la MN todavía puede ser rastreado

- por favor, añadir si mi lista no está completa...

 
cameofx:
- la información contenida sería 101 - id del experto; 1 - cantidad de This_EA operando al momento; time_stamp - hora de OrderSend

- entonces podemos escanearlo con StringSubStr y saber que una orden en particular fue abierta por This_EA mientras había otra This_EA adjunta.

Pero, ¿para qué sirve la parte del tiempo en el MN? ¿Por qué no utilizar sólo los números de EA? y no utilizar substr? El uso de substr necesitaría que el int se convirtiera en una cadena, luego algunas operaciones de cadena y una comparación de cadenas, la parte de tiempo del MN se desecha porque nunca se necesita. Las operaciones de cadena con enteros generalmente tienden a parecer amateurs porque en la mayoría de los casos podrían resolverse mejor codificando la información en diferentes bits de la palabra de 32 bits y utilizar operaciones bitwise para manipularlas o comprobarlas, lo que sería órdenes de magnitud más rápidas y elegantes.

¿Por qué no usar un valor int (único en la instancia de EA) para el mn y usar una simple comparación de enteros para comparar el número completo o ciertos bits del mismo?

Por ejemplo, dejemos que los primeros 28 bits sean el ID y los últimos cuatro bits un número de 0..15 para identificar diferentes tipos de operaciones (por ejemplo, si puede abrir 3 tipos diferentes de órdenes: inicial, nivel1, nivel2 y cobertura)

ID = hash & 0xFFFFFFF0  // this has the 4 low bits always zero


// generate the mn for level 1 trades
MN = (ID + 1);
OrderSend(..., MN, "level 1");


// generate the mn for hedge trades
MN = (ID + 15);
OrderSend(..., MN, "hedge the whole mess");


// this strategy may not make any sense, only to illustrate the code:
// close the hedge trades and trail the stops of all levels
for(...){
   if (OrderMagicNumber() & 0xFFFFFFF0 == ID){  // this trade belongs to us
      if (OrderMagicNumber() & 0x0000000F == 15){ // this is a hedge trade
         OrderClose(...)
      }else{ // this is one of the other levels
         Trail(OrderTicket());
      }
   }
}

// or even easier:
MN = (ID + 15); // all our hedge trades have this MN
for(...){
   if (OrderMagicNumber() == MN){
      OrderClose(...)
   }
}
 
gordon:
Si he entendido bien - su solución a 2 expertos diferentes que accidentalmente tienen el mismo ID es poner todos los ID de expertos en la cabecera de cada experto. Eso es una especie de dolor en el culo ... Incluso si pones esa parte en un archivo de inclusión, todavía tendrías que recompilar todos los expertos para cada nuevo experto que hagas.

La cuestión de la persistencia sigue ahí. No sé cómo funcionaría esto correctamente después de un reinicio de la terminal o después de cambiar a una terminal completamente diferente...

No, no lo has hecho :) por favor, lee los comentarios en el código sobre WindowExpertName().

Si se llama desde el experto se recuperaría el nombre del archivo experto/script/indicador sin el ".mq4" o ".ex4" no tienes que poner ningún include solo nombrar tus EAs como corresponde.

PS : perdón por la respuesta spam :)

 
7bit:

¿Pero para qué sirve la parte del tiempo en el MN? ¿Por qué no usar sólo los números EA y no usar substr? El uso de substr necesitaría que el int se convirtiera en una cadena, luego algunas operaciones de cadena y una comparación de cadena, la parte de tiempo de la MN se desecha porque nunca se necesita. Las operaciones de cadena con enteros generalmente tienden a parecer amateurs porque en la mayoría de los casos podrían resolverse mejor codificando la información en diferentes bits de la palabra de 32 bits y utilizar operaciones bitwise para manipularlas o comprobarlas, lo que sería órdenes de magnitud más rápidas y elegantes.

¿Por qué no usar un valor int (EA-instancia-única) para el mn y usar una simple comparación de enteros para comparar el número entero o ciertos bits del mismo?

Por ejemplo, dejar que los primeros 28 bits sean el ID y los últimos cuatro bits un número de 0..15 para identificar diferentes tipos de operaciones (por ejemplo, si puede abrir 3 tipos diferentes de órdenes: inicial, nivel1, nivel2 y cobertura)


hmm... Utilizo la parte del tiempo porque pensé que la MN de cada orden abierta por un EA debe ser única respecto a otras órdenes que se abran al mismo tiempo con el mismo EA en diferentes gráficos.

La premisa sería : Si un EA abre dos(más) órdenes simultáneamente con el mismo número mágico. no pueden tener el mismo MN o de lo contrario entraría en conflicto en el manejo de la Orden y o

Identificación de órdenes... quizás confundí esto con la captura de OrderTicket (¿o no?).

- Incorporar la estrategia al MN sería el siguiente paso naturalmente

- Veo que tu habilidad me supera en años luz: )). Todavía no tengo la capacidad de optimizar las operaciones, por eso he posteado esto.. Ahora sé que la comprobación con operaciones a nivel de bits sería más rápida.

Gracias. Puede que tenga que pedirte una explicación de cómo hacerlo más tarde :)))

 
cameofx:

hmm... Uso la parte del tiempo porque pensé que los MN de cada orden abierta por un EA deben ser únicos respecto a otras órdenes

No, pueden ser lo que quieras. al igual que el comentario. verlos como una especie de comentario numérico. Todas las operaciones manuales abiertas con la interfaz de usuario normal de MT4 tendrán el número mágico 0, por lo que puede, por ejemplo, hacer un bucle sobre todas las órdenes y cerrar/borrar todas las operaciones y órdenes manuales mientras deja todas las operaciones de los EAs sin tocar.

Todos mis EAs crean su propio número, único para (nombre del EA + símbolo + marco de tiempo), es por eso que pasé tanto esfuerzo para encontrar una buena y fácil función hash para crear este número. El hash es incluso tan bueno que puedo cortar fácilmente los últimos bits de este hash para hacer espacio para sub-números (si lo necesito, pero rara vez necesito esto) y todavía sería bastante seguro contra las colisiones.

Pero la mayoría de mis EAs utilizan el hash directamente y no tienen una sub-numeración porque sólo tienen un tipo de operaciones y tratan todas sus operaciones de forma idéntica.

Para identificar de forma única una determinada orden siempre está el número de entrada.