criando um 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);
  }
//+------------------------------------------------------------------+
leva um pouco mais de tempo do que eu pensava ...
editar : Condição GVget != -1.0 a >= 0.0; editar
 
cameofx:
[...] leva um pouco mais de tempo do que eu pensava...

Isto está se tornando cada vez mais um re-hash (desculpas pelo trocadilho) do tópico anterior que eu já mencionei: https://www.mql5.com/en/forum/120034. Qualquer coisa que envolva variáveis globais levanta questões em torno do backup e da recuperação de desastres. Se a negociação tiver que ser movida à pressa para um novo servidor, então ou é necessário que haja um backup recente de gvariables.dat disponível, ou o usuário precisa estar em condições de recriar as variáveis globais manualmente.

Eu não estudei seu código de perto, mas também não tenho certeza do que acontece se houver múltiplas cópias do EA e MT4 é então reiniciado. Parece que o código pode assumir que as EA serão automaticamente recarregadas na mesma ordem em que foram originalmente carregadas manualmente. Em outras palavras, múltiplas cópias do EA podem obter valores diferentes Esta_EA_qty entre reinicializações, e eu não posso então ver como eles identificam corretamente suas ordens históricas na lista MT4. Mas eu posso estar errado a respeito disso.

 
cameofx:
leva um pouco mais de tempo do que eu pensava ...
editar : condição GVget != -1.0 a >= 0.0
// TimeCurrent() in seconds since 1970 would most probably exceed that 

TimeCurrent() retorna um número inteiro de 32 bits. O tipo datatime é um alias para o tipo int, int também é um inteiro de 32 bits.


A outra coisa que eu não entendo em seu código é por que você está usando um MN diferente para cada comércio aberto? Isto é o oposto do que os MNs são destinados. A idéia de um MN é que você pode identificar todas as negociações por um certo EA simplesmente olhando para o MN. Qual é a razão para a parte aleatória do MN? Como seria o código em sua EA que fecharia todas as negociações abertas desta EA ou rastrearia todas as paradas desta EA?
 
Se eu entendi corretamente - sua solução para 2 especialistas diferentes tendo acidentalmente a mesma identificação é colocar todas as identificações de especialistas no cabeçalho de cada especialista. Isso é um pouco chato... Mesmo se você colocar essa parte em um arquivo de inclusão, então você ainda precisará recompilar todos os especialistas para cada novo especialista que você fizer.

A questão da persistência ainda está aí. Não sei como isso funcionaria corretamente após um reinício de terminal ou após a mudança para um terminal completamente diferente...
 
jjc:

Isto está se tornando cada vez mais um re-hash (desculpas pelo trocadilho) do tópico anterior que eu já mencionei: https://www.mql5.com/en/forum/120034. Qualquer coisa que envolva variáveis globais levanta questões em torno do backup e da recuperação de desastres. Se a negociação tiver que ser movida à pressa para um novo servidor, então ou é necessário que haja um backup recente de gvariables.dat disponível, ou o usuário precisa estar em condições de recriar as variáveis globais manualmente.

Eu não estudei seu código de perto, mas também não tenho certeza do que acontece se houver múltiplas cópias do EA e MT4 é então reiniciado. Parece que o código pode assumir que as EA serão automaticamente recarregadas na mesma ordem em que foram originalmente carregadas manualmente. Em outras palavras, múltiplas cópias do EA podem obter valores diferentes Esta_EA_qty entre reinicializações, e eu não posso então ver como eles identificam corretamente suas ordens históricas na lista MT4. Mas eu posso estar errado a respeito disso.

Este é o tipo de feedback que eu espero... obrigado gordon, 7bit & jjc...

suas respostas precisam ser ponderadas... mas para responder rapidamente:

- se este especialista_EA já estiver anexado uma vez em outro gráfico, o número_mágico então teria valor de : 101-1 time-stamp (traço para maior clareza)

- as informações contidas seriam 101 - identificação de especialista; 1 - Esta_a quantidade_EA operando até o momento; carimbo_de_tempo - hora de envio do pedido

- podemos então escaneá-la com StringSubStr e saber que uma determinada ordem foi aberta por This_EA enquanto havia 1 outra This_EA anexada.

 
7bit:

TimeCurrent() retorna um número inteiro de 32 bits. O tipo datatime é um alias para o tipo int, int também é um inteiro de 32 bits.


A outra coisa que eu não entendo em seu código é por que você está usando um MN diferente para cada comércio aberto? Isto é o oposto do que os MNs são destinados. A idéia de um MN é que você pode identificar todas as negociações por um certo EA simplesmente olhando para o MN. Qual é a razão para a parte aleatória do MN? Como seria o código em sua EA que fecharia todas as negociações abertas desta EA ou rastrearia todas as paradas desta EA?

Desculpe, o que eu queria dizer era que o nome_mágico resultante excederia essa alocação. Vou mover o comentário em código de acordo.

Para equalizar nossa percepção. Eu proporia estes requisitos para este número_mágico "automatizado". O MN teria o seguinte :

- Você pode Identificar com que EA - esta ordem em particular com dito MN - estava aberta.

- Um EA contendo esta técnica - se anexado a inúmeros (mais de 1) não geraria o mesmo número mágico se esse EA abrisse ordens simultaneamente fora de um intervalo de 1 segundo.

- assim, não entraria em conflito no manuseio da ordem, mas ao mesmo tempo a origem do MN ainda pode ser rastreada

- Por favor, acrescente se minha lista não estiver completa...

 
cameofx:
- as informações contidas seriam 101 - identificação de especialista; 1 - Esta_EA quantidade operando até o momento; carimbo_de_tempo - hora de envio do pedido

- podemos então escaneá-la com StringSubStr e saber que uma determinada ordem foi aberta por This_EA enquanto havia 1 outra This_EA anexada.

Mas para que é a parte do tempo no MN? Por que não usar apenas os números EA? e não usar substrato? O uso de substrato precisaria da int para ser convertido em uma string, depois algumas operações de string e uma comparação de string, a parte do tempo do MN é jogada fora porque nunca é necessário. Operações de cordas com inteiros geralmente tendem a parecer amadores porque na maioria dos casos se poderia ser melhor resolvido codificando as informações em diferentes bits da palavra 32 bits e usar operações bitwise para manipulá-las ou verificá-las que seriam ordens de magnitude mais rápidas e mais elegantes.

Por que não usar apenas um valor int (EA-instance-unique) para o mn e usar uma simples comparação inteira para comparar o número inteiro ou certos bits dele?

Por exemplo, deixe os primeiros 28 bits serem o ID e os últimos quatro bits um número de 0,15 para identificar diferentes tipos de negócios (por exemplo, se ele pode abrir 3 tipos diferentes de ordens: inicial, nível 1, nível 2 e hedge)

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:
Se eu entendi corretamente - sua solução para 2 especialistas diferentes tendo acidentalmente a mesma identificação é colocar todas as identificações de especialistas no cabeçalho de cada especialista. Isso é um pouco chato... Mesmo se você colocar essa parte em um arquivo de inclusão, então você ainda precisará recompilar todos os especialistas para cada novo especialista que você fizer.

A questão da persistência ainda está aí. Não sei como isso funcionaria corretamente após um reinício de terminal ou após a mudança para um terminal completamente diferente...

Não, você não :) por favor, leia os comentários em código relativos a WindowExpertName().

Se chamado por um especialista, ele recuperaria o nome do arquivo expert/script/indicator sem o ".mq4" ou ".ex4", você não precisa colocar nenhum nome de especialista em conformidade.

PS : desculpe pela resposta de spammy :)

 
7bit:

Mas para que é a parte do tempo no MN? Por que não usar apenas os números EA? e não usar substrato? O uso de substrato precisaria da int para ser convertido em uma string, depois algumas operações de string e uma comparação de string, a parte do tempo do MN é jogada fora porque nunca é necessário. Operações de cordas com números inteiros geralmente tendem a parecer amadores porque na maioria dos casos se poderia ser melhor resolvido codificando as informações em diferentes bits da palavra 32 bits e usar operações bitwise para manipulá-las ou verificá-las que seriam ordens de magnitude mais rápidas e mais elegantes.

Por que não usar apenas um valor int (EA-instance-unique) para o mn e usar uma simples comparação inteira para comparar o número inteiro ou certos bits?

Por exemplo, deixe os primeiros 28 bits serem o ID e os últimos quatro bits um número de 0...15 para identificar diferentes tipos de negócios (por exemplo, se ele pode abrir 3 tipos diferentes de ordens: inicial, nível 1, nível 2 e hedge)


hmm... Uso a parte do tempo porque pensei que o MN para cada ordem aberta por uma EA deve ser único em relação a outras ordens abertas ao mesmo tempo com a mesma EA em gráficos diferentes.

a premissa seria: se um EA abrisse duas (mais) ordens simultaneamente com o mesmo número mágico. eles não podem ter o mesmo MN ou então isso entraria em conflito no tratamento de ordens e ou

Ordem identificando... talvez eu tenha confundido erroneamente com OrderTicket grabbing (ou não?).

- incorporar a estratégia ao MN seria o próximo passo naturalmente

- Vejo que sua habilidade me excede em anos-luz: ))). Ainda não tenho a capacidade de otimizar as operações, por isso afixei isto... Agora eu sei que verificar com operações bitwise seria mais rápido.

Obrigado. Talvez eu precise lhe perguntar como explicar mais tarde :)))

 
cameofx:

hmm... Uso a parte do tempo porque pensei que o MN para cada pedido aberto por uma EA deve ser único em relação a outros pedidos

Não, eles podem ser o que você quiser. assim como o comentário. veja-os como uma espécie de comentário numérico. Todas as negociações manuais abertas com a interface de usuário MT4 normal terão o número mágico 0, de modo que você pode, por exemplo, loopar sobre todas as ordens e fechar/eliminar todas as negociações e ordens manuais, deixando todas as negociações EA intocadas.

Todas as minhas EA criam seu próprio número, único para (nome EA + símbolo + prazo), por isso gastei tanto esforço para encontrar uma função de hash boa e fácil para criar este número. O hash é tão bom que eu posso cortar facilmente os últimos pedaços deste hash para dar espaço para subnúmeros (se eu precisar, mas raramente preciso disto) e ainda assim seria bastante seguro contra colisões.

Mas a maioria dos meus EAs usa o hash diretamente e não tem uma subnumeração porque eles têm apenas um tipo de comércio e tratam todos os seus negócios de forma idêntica.

Para identificar apenas uma única ordem específica, há sempre o número do bilhete.