Emulação de carrapatos de um EA/indicador - página 3

 
Meat:

Sim, não está claro o que está errado... Tente isto então: Na seção de importação #importar "user32.dll" adicionar uma função:

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

E ao final da função SetMyTimer adicionar uma linha: CallWindowProcA(code,0,0,0,0,0);

E com alguma verificação do indicador de funcionamento paralelo se um tick é gerado neste momento.

Bem, algo parece ter mudado, o tronco agora está assim:
10:42:52 teste EURUSD,H1: carregado com sucesso
10:42:54 teste EURUSD,H1: função 'CallWindowProcA' chamada da dll 'user32.dll' erro crítico c0000005 em 02C310A8.
10:42:54 teste EURUSD,H1: inicializar

Onde há um carrapato? ;)

 
Meat:

Zhunko, bem, se tudo não é padrão (seu próprio registro, sua própria implementação de indicadores, etc.), então por que você está começando toda esta conversa? Na verdade, estamos discutindo o trabalho especificamente com o MT4, não com nossos próprios desenvolvimentos.

Em meu primeiro post eu indiquei especificamente que meu código será útil se a tarefa for fazer sem links externos, ou seja, implementar um Expert Advisor/indicador auto-suficiente que usa apenas bibliotecas de sistema. E se você estiver usando seus próprios desenvolvimentos, então ele não é aplicável a você.

E, em geral, não entendo por que tenho que "limpar manualmente o tronco depois do trabalho", se é mais fácil não desarrumá-lo. Afinal, pelo que entendi, você implementa seus desenvolvimentos em DLL. Então, o que o impede de definir ali o mesmo temporizador, como eu sugeri aqui. Mas por alguma razão você prefere todo tipo de dança com pandeiro e limpeza do tronco. Meu código o incomoda, enquanto você é preguiçoso demais para limpar o tronco todos os dias :)

Meu tronco só está cheio depois de ter bombeado minha história. Acontece às quartas e sábados. Esqueci o que é por causa de sua limpeza automática.

A atualização autônoma dos gráficos tem sido feita há muito tempo. Ela é implementada aqui. Você executa a função uma vez a partir de qualquer programa e não precisa fazer mais nada. Mesmo com todos os programas MQL4 descarregados, a atualização continua, a abertura e o fechamento do gráfico é monitorado.

A alternativa ao seu código não é aquela que eu sugeri. É uma solução simples para este problema, com base em sua tarefa. Uma linha de código é muito mais simples do que seu código. Não é necessário limpar os troncos todos os dias. Somente nos fins de semana. O resto do tempo você não precisa deste código. É racional. Você tem que limpar o tronco de qualquer maneira. Portanto, esta não é a razão.

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

Eu executei seu código. Não funciona no Window 7.

Podemos nos livrar da função AddBytes()? Inicialize a matriz desta forma:

  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;
É mais curto. Mesmo assim, é um trabalho único.
 
Zhunko:

Eu só recebo um registro depois que a história foi trocada. Isso acontece às quartas e sábados. Esqueci o que é por causa de sua limpeza automática.

A atualização autônoma dos gráficos foi feita há muito tempo. Ela é implementada aqui. Você executa a função uma vez a partir de qualquer programa e não precisa fazer mais nada. Mesmo com todos os programas MQL4 descarregados, a atualização continua, a abertura e o fechamento do gráfico é monitorado.

A alternativa ao seu código não é aquela que eu sugeri. É uma solução simples para este problema, com base em sua tarefa. Uma linha de código é muito mais simples do que seu código. Não é necessário limpar os troncos todos os dias. Somente nos fins de semana. O resto do tempo você não precisa deste código. É racional. Você tem que limpar o tronco de qualquer maneira. Portanto, esta não é a razão.

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

Eu executei seu código. Não funciona no Window 7.

Podemos nos livrar da função AddBytes()? Inicialize a matriz desta forma:

Será mais curto. Mesmo assim, é um trabalho único.

Sim, claro, meu código postado é apenas um código fonte para entender o significado, enquanto é mais conveniente usá-lo de forma embalada ...Mas, ao que parece, é muito cedo para compilá-lo, porque por alguma razão não funciona :) Embora funcione bem para mim tanto em XP quanto em 7, nada cai, mesmo que eu o tenha executado por cerca de uma hora. É um pouco de mistério...

Uma linha de código é muito mais fácil do que seu código. Não é necessário limpar os troncos todos os dias. Somente nos fins de semana. O resto do tempo você não precisa deste código. É racional.

Pode não ser crucial para você pessoalmente se você tiver seu próprio "limpador de madeira" trabalhando ao mesmo tempo, ou seja, você tem sua própria cozinha lá, mas estamos falando de um caso geral. Imagine um usuário normal que não faz todas essas coisas. Então ele precisará do "limpador de toras" para um bom trabalho com seu indicador, ou seja E você deve admitir que é muito maior do que o tamanho do meu código ;) Portanto, acho que você está errado sobre racionalidade e brevidade, especialmente se você pegar meu código de uma forma embalada, como você sugere. É claro que não é uma linha única, mas não requer nenhum outro complemento, ou seja, é um produto completo.

O tronco deve ser limpo de qualquer forma.

Por que eu deveria? Se eu não entupir, por que eu deveria limpá-lo?

 

Alexei, o limpador pode não ser necessariamente automático. Por exemplo, clique com o botão direito do mouse em uma pasta e selecione"limpar pasta". Faça isso depois de experimentar nos fins de semana.

Ao longo de um ano, 365 arquivos se acumulam em EAs e logs. Ou seja, 730 arquivos. Não deve ser limpo? É estranho ouvir isso. Você não fica entupido porque não faz nada. Os troncos crescem muito quando se trabalha todos os dias.

 
Zhunko:

Alexei, o limpador pode não ser necessariamente automático. Por exemplo, clique com o botão direito do mouse em uma pasta e selecione "limpar pasta". Faça isso depois de experimentar nos fins de semana.

Ao longo de um ano, 365 arquivos se acumulam em EAs e logs. Ou seja, 730 arquivos. Não deve ser limpo? É estranho ouvir uma coisa dessas. Você não fica entupido porque não faz nada. Os troncos crescem muito se você trabalha todos os dias.

Bem, em princípio sim, concordo que depois de experimentos eles geralmente têm que ser limpos. Mas não estamos falando apenas de experimentação. Um indicador está sendo criado para funcionar, não para experimentação, portanto se um indicador depurado ainda entupir os arquivos de registro enquanto trabalha, ele não será correto.

Falando em apagar os toros antigos, é uma questão de preferências pessoais, por exemplo, tive que procurar algumas informações nos toros de um ano atrás. Portanto, eu não os excluo. Refiro-me aos registros diretamente relacionados ao comércio, não a experimentos diferentes.

 
Meat:

Bem, em princípio, sim, concordo que eles geralmente precisam ser limpos após experimentos. Mas não estamos falando apenas de experimentos. Afinal, um indicador é criado para funcionar, não para experimentação. Portanto, se um indicador de depuração continuar a entupir os registros no processo de seu trabalho, ele já está errado.

Por isso, quero dizer que tal artifício só é necessário nos fins de semana. O resto do tempo você não precisa dele.
 

Em geral, a geração de carrapatos também é necessária nos dias de semana. Você parece considerar um Consultor/indicador especializado que usa apenas citações de seu símbolo. É claro que você pode simplesmente rodá-lo em alguns símbolos líquidos, por exemplo EURUSD, onde os carrapatos estão chegando com freqüência... Mas não é uma cura para tudo, e pode não ser muito conveniente.

 

Em qualquer caso, quando se quer ver o resultado antes que o carrapato tenha chegado.

Ou seja, - para fins de pesquisa.

 

Descobri qual era o problema. A matriz deveria ser declarada globalmente e não localmente.

Estou postando a versão corrigida. Eu encurtei o código ao mesmo tempo. A variante proposta por Zhunko, embora fosse 3 linhas mais curta do que esta, era muito complicada e inconveniente para entender o algoritmo). Portanto, acho que não se deve ir a extremos por causa da redução do 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:

Em geral, a geração de carrapatos também é necessária nos dias de semana. Você parece considerar um Consultor/indicador especializado que usa apenas citações de seu símbolo. É claro que você pode simplesmente rodá-lo em alguns símbolos líquidos, por exemplo EURUSD, onde os carrapatos estão chegando com freqüência... Mas não é uma panaceia, e pode não ser muito conveniente.

Você tem apenas um exemplo?

Desde que o escrevo e uso, nunca precisei dele, exceto nos fins de semana.

Consultor especializado + indicador. Resolve-se "congelando" o Expert Advisor. O resultado é o mesmo que para você. Para receber os dados a tempo, é suficiente reagir às mudanças de tempo do servidor. Você não precisa do WinAPI para isso.

O único caso, quando é necessário, é iniciar o Expert Advisor no fim de semana. Mesmo isso pode ser implementado com a linha que eu dei acima. Somente para o Consultor Especialista.

Razão: