Emulazione di tick da un EA/indicatore - pagina 3

 
Meat:

Sì, non è chiaro cosa c'è che non va... Prova questo allora: nella sezione importazione #import "user32.dll" aggiungere una funzione:

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

E alla fine della funzione SetMyTimer aggiungete una linea: CallWindowProcA(codice,0,0,0,0,0);

E con qualche indicatore in esecuzione parallela controllare se un tick è generato in questo momento.

Bene, qualcosa sembra essere cambiato, il registro è ora come questo:
10:42:52 test EURUSD,H1: caricato con successo
10:42:54 test EURUSD,H1: funzione 'CallWindowProcA' chiamata dalla dll 'user32.dll'errore critico c0000005 a 02C310A8.
10:42:54 test EURUSD,H1: inizializzare

Dov'è una zecca? ;)

 
Meat:

Zhunko, beh, se tutto è non-standard (il tuo log, la tua implementazione degli indicatori, ecc.), allora perché stai iniziando tutta questa conversazione? In realtà stiamo discutendo del lavoro specifico con MT4, non dei nostri sviluppi.

Nel mio primo post ho specificamente sottolineato che il mio codice sarà utile se il compito è quello di fare a meno di collegamenti esterni, vale a dire, per implementare un Expert Advisor/indicatore autosufficiente che utilizza solo le librerie di sistema. E se stai utilizzando i tuoi sviluppi, allora non è applicabile a te.

E in generale, non capisco perché devo "pulire manualmente il registro dopo il lavoro", se è più facile non ingombrarlo. Dopo tutto, per quanto ho capito, voi implementate i vostri sviluppi in DLL. Allora cosa ti impedisce di installare lo stesso timer lì, come ho suggerito qui. Ma per qualche ragione tu preferisci tutti i tipi di balli con il tamburello e la pulizia del log. Il mio codice ti dà fastidio, mentre tu sei troppo pigro per pulire il log ogni giorno :)

Il mio registro si è riempito solo dopo aver pompato la storia. Succede il mercoledì e il sabato. Ha dimenticato cos'è a causa della sua pulizia automatica.

L'aggiornamento autonomo dei grafici è stato fatto per molto tempo. È implementato qui. Si esegue la funzione una volta da qualsiasi programma e non c'è bisogno di fare altro. Anche con tutti i programmi MQL4 scaricati l'aggiornamento continua, l'apertura e la chiusura del grafico è monitorata.

L'alternativa al tuo codice non è quella che ho suggerito. È una soluzione semplice a questo problema, basata sul vostro compito. Una linea di codice è molto più semplice del vostro codice. Non è necessario pulire i tronchi ogni giorno. Solo nei fine settimana. Il resto del tempo non avete bisogno di questo codice. È razionale. Dovete comunque pulire il registro. Quindi non è questa la ragione.

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

Ho eseguito il tuo codice. Non funziona su Window 7.

Possiamo eliminare la funzione AddBytes()? Inizializza l'array in questo modo:

  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;
È più breve. Tuttavia, è un lavoro unico.
 
Zhunko:

Ricevo un log solo dopo che la cronologia è stata scambiata. Succede il mercoledì e il sabato. Ha dimenticato cos'è a causa della sua pulizia automatica.

L'aggiornamento autonomo dei grafici è stato fatto molto tempo fa. È implementato qui. Si esegue la funzione una volta da qualsiasi programma e non c'è bisogno di fare altro. Anche con tutti i programmi MQL4 scaricati l'aggiornamento continua, l'apertura e la chiusura del grafico è monitorata.

L'alternativa al tuo codice non è quella che ho suggerito. È una soluzione semplice a questo problema, basata sul vostro compito. Una linea di codice è molto più semplice del vostro codice. Non è necessario pulire i tronchi ogni giorno. Solo nei fine settimana. Il resto del tempo non avete bisogno di questo codice. È razionale. Dovete comunque pulire il registro. Quindi non è questa la ragione.

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

Ho eseguito il tuo codice. Non funziona su Window 7.

Possiamo eliminare la funzione AddBytes()? Inizializza l'array in questo modo:

Sarà più breve. Tuttavia, è un lavoro unico.

Sì, certo, il mio codice postato è solo un codice sorgente per capire il significato, mentre è più conveniente usarlo in forma confezionata...Ma a quanto pare, è troppo presto per compilarlo, perché per qualche motivo non funziona :) Anche se funziona bene per me sia in XP che in 7, non si blocca nulla, anche se l'ho eseguito per circa un'ora. È un po' un mistero...

Una linea di codice è molto più facile del vostro codice. Non è necessario pulire i tronchi ogni giorno. Solo nei fine settimana. Il resto del tempo non hai bisogno di questo codice. È razionale.

Potrebbe non essere cruciale per te personalmente se hai il tuo "pulitore di registro" che lavora allo stesso tempo, cioè hai la tua cucina lì, ma stiamo parlando di un caso generale. Immaginate un utente normale che non fa tutte queste cose. Allora avrà bisogno del "pulitore di log" per lavorare bene con il vostro indicatore. E devi ammettere che è molto più grande della dimensione del mio codice ;) Quindi penso che ti sbagli sulla razionalità e la brevità, soprattutto se prendi il mio codice in forma confezionata, come suggerisci. Certo, non è una linea singola, ma non richiede altri componenti aggiuntivi, cioè è un prodotto completo.

Il registro deve essere pulito comunque.

Perché dovrei? Se non lo intaso, perché dovrei pulirlo?

 

Alexei, il pulitore non è necessariamente automatico. Per esempio, cliccate con il tasto destro del mouse su una cartella e selezionate"cancella cartella". Fallo dopo aver sperimentato nei fine settimana.

Nel corso di un anno, 365 file si accumulano negli EA e nei log. Sono 730 file. Non dovrebbe essere pulito? È strano sentire questo. Non ci si intasa perché non si fa nulla. I tronchi diventano molto grandi quando si lavora ogni giorno.

 
Zhunko:

Alexei, il pulitore non è necessariamente automatico. Per esempio, cliccate con il tasto destro del mouse su una cartella e selezionate "cancella cartella". Fallo dopo aver sperimentato nei fine settimana.

Nel corso di un anno, 365 file si accumulano negli EA e nei log. Sono 730 file. Non dovrebbe essere pulito? È strano sentire una cosa del genere. Non ci si intasa perché non si fa nulla. I tronchi crescono molto quando si lavora ogni giorno.

Beh, in linea di principio sì, sono d'accordo che dopo gli esperimenti di solito devono essere puliti. Ma non stiamo parlando solo di sperimentazione. Un indicatore viene creato per funzionare, non per la sperimentazione, quindi se un indicatore debuggato intasa ancora i file di log mentre lavora, non sarà corretto.

A proposito della cancellazione dei vecchi log, è una questione di preferenze personali, per esempio, ho dovuto cercare alcune informazioni nei log di un anno fa. Quindi non li cancello. Intendo registri direttamente legati al commercio, non a diversi esperimenti.

 
Meat:

Beh, in linea di principio sì, sono d'accordo che di solito hanno bisogno di essere puliti dopo gli esperimenti. Ma non stiamo parlando solo di esperimenti. Dopo tutto, un indicatore è creato per lavorare, non per sperimentare. Quindi, se un indicatore debuggato continuerà a intasare i log nel corso del suo lavoro, è già sbagliato.

Quindi, voglio dire che un tale espediente è necessario solo nei fine settimana. Il resto del tempo non ne hai bisogno.
 

In generale, la generazione di zecche è necessaria anche nei giorni feriali. Sembra che tu consideri un Expert Advisor/indicatore che utilizza solo le quotazioni del suo simbolo. Naturalmente puoi semplicemente eseguirlo su alcuni simboli liquidi, per esempio EURUSD, dove i tick arrivano spesso... Ma non è una panacea, e potrebbe non essere molto conveniente.

 

In ogni caso, quando si vuole vedere il risultato prima che il tick sia arrivato.

Cioè, - per scopi di ricerca.

 

Ho capito qual era il problema: l'array dovrebbe essere dichiarato globalmente, non localmente.

Sto pubblicando la versione corretta. Ho accorciato il codice allo stesso tempo. La variante proposta da Zhunko, anche se era 3 righe più corta di questa, era troppo complicata e scomoda per capire l'algoritmo). Quindi, non credo che si debba andare agli estremi per il bene della riduzione del codice.

#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:

In generale, la generazione di zecche è necessaria anche nei giorni feriali. Sembra che tu consideri un Expert Advisor/indicatore che utilizza solo le quotazioni del suo simbolo. Naturalmente puoi semplicemente eseguirlo su qualche simbolo liquido, per esempio EURUSD, dove i tick arrivano spesso... Ma non è una panacea, e potrebbe non essere molto conveniente.

Solo un esempio?

Da quando scrivo e lo uso, non ne ho mai avuto bisogno, tranne nei fine settimana.

Expert Advisor + indicatore. Si risolve "congelando" l'Expert Advisor. Il risultato è lo stesso che per voi. Per ricevere i dati in tempo, è sufficiente reagire ai cambiamenti di tempo del server. Non avete bisogno di WinAPI per questo.

L'unico caso in cui è necessario, è quello di avviare l'Expert Advisor nel fine settimana. Anche questo può essere implementato con la linea che ho dato sopra. Solo per l'Expert Advisor.