Emulation von Ticks aus einem EA/Indikator - Seite 3

 
Meat:

Ja, es ist nicht klar, was falsch ist... Versuchen Sie dies: in der Import-Sektion #import "user32.dll" eine Funktion hinzufügen:

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

Und fügen Sie am Ende der Funktion SetMyTimer eine Zeile hinzu: CallWindowProcA(code,0,0,0,0);

Und mit einem parallel laufenden Indikator prüfen, ob in diesem Moment ein Tick erzeugt wird.

Nun, etwas scheint sich geändert zu haben, das Protokoll sieht jetzt so aus:
10:42:52 test EURUSD,H1: erfolgreich geladen
10:42:54 test EURUSD,H1: Funktion 'CallWindowProcA' Aufruf von dll 'user32.dll' kritischer Fehler c0000005 bei 02C310A8.
10:42:54 test EURUSD,H1: initialisieren

Wo ist eine Zecke? ;)

 
Meat:

Zhunko, nun, wenn alles nicht standardisiert ist (Ihr eigenes Protokoll, Ihre eigene Implementierung von Indikatoren, etc.), warum beginnen Sie dann diese ganze Diskussion? Wir diskutieren eigentlich die Arbeit speziell mit MT4, nicht mit unseren eigenen Entwicklungen.

In meinem ersten Beitrag habe ich ausdrücklich darauf hingewiesen, dass mein Code nützlich sein wird, wenn die Aufgabe darin besteht, auf externe Links zu verzichten, d.h. einen autarken Expert Advisor/Indikator zu implementieren, der nur Systembibliotheken verwendet. Und wenn Sie Ihre eigenen Entwicklungen verwenden, dann ist er für Sie nicht anwendbar.

Und im Allgemeinen verstehe ich nicht, warum ich das Protokoll nach der Arbeit manuell bereinigen muss", wenn es einfacher ist, es nicht zu überladen. Denn soweit ich verstanden habe, implementieren Sie Ihre Entwicklungen in DLL. Was hindert Sie dann daran, dort denselben Timer einzustellen, wie ich es hier vorgeschlagen habe? Aber aus irgendeinem Grund bevorzugen Sie alle möglichen Tänze mit Tamburin und das Aufräumen des Logs. Mein Code stört Sie, während Sie zu faul sind, das Log jeden Tag aufzuräumen :)

Mein Logbuch hat sich erst gefüllt, nachdem ich meinen Verlauf aufgepumpt habe. Findet mittwochs und samstags statt. Ich habe vergessen, was es ist, weil es automatisch gereinigt wird.

Die autonome Aktualisierung der Karten wird schon seit langem durchgeführt. Sie wird hier umgesetzt. Sie führen die Funktion einmal aus einem beliebigen Programm aus und brauchen nichts weiter zu tun. Auch wenn alle MQL4-Programme entladen sind, wird die Aktualisierung fortgesetzt, das Öffnen und Schließen des Charts wird überwacht.

Die Alternative zu Ihrem Code ist nicht die, die ich vorgeschlagen habe. Es ist eine einfache Lösung für dieses Problem, die sich an Ihrer Aufgabe orientiert. Eine Zeile Code ist viel einfacher als Ihr Code. Sie müssen die Stämme nicht jeden Tag reinigen. Nur an Wochenenden. In der übrigen Zeit brauchen Sie diesen Code nicht. Es ist rational. Sie müssen das Protokoll ohnehin reinigen. Das ist also nicht der Grund.

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

Ich habe Ihren Code ausgeführt. Es funktioniert nicht unter Windows 7.

Können wir die Funktion AddBytes() abschaffen? Initialisieren Sie das Array wie folgt:

  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;
Sie ist kürzer. Trotzdem ist es ein einmaliger Auftrag.
 
Zhunko:

Ich erhalte nur ein Protokoll, nachdem der Verlauf ausgetauscht wurde. Sie findet mittwochs und samstags statt. Ich habe vergessen, was es ist, weil es automatisch gereinigt wird.

Die autonome Aktualisierung der Diagramme wurde vor langer Zeit vorgenommen. Sie wird hier umgesetzt. Sie führen die Funktion einmal aus einem beliebigen Programm aus und brauchen nichts weiter zu tun. Auch wenn alle MQL4-Programme entladen sind, wird die Aktualisierung fortgesetzt, das Öffnen und Schließen des Charts wird überwacht.

Die Alternative zu Ihrem Code ist nicht die, die ich vorgeschlagen habe. Es ist eine einfache Lösung für dieses Problem, die sich an Ihrer Aufgabe orientiert. Eine Zeile Code ist viel einfacher als Ihr Code. Sie müssen die Stämme nicht jeden Tag reinigen. Nur an Wochenenden. In der übrigen Zeit brauchen Sie diesen Code nicht. Es ist rational. Sie müssen das Protokoll ohnehin reinigen. Das ist also nicht der Grund.

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

Ich habe Ihren Code ausgeführt. Es funktioniert nicht unter Windows 7.

Können wir die Funktion AddBytes() abschaffen? Initialisieren Sie das Array wie folgt:

Es wird kürzer sein. Trotzdem ist es ein einmaliger Auftrag.

Ja, natürlich, mein geposteter Code ist nur ein Quellcode, um die Bedeutung zu verstehen, während es bequemer ist, ihn in einer gepackten Form zu verwenden ...Aber wie sich herausstellt, ist es zu früh, um es zu kompilieren, weil es aus irgendeinem Grund nicht funktioniert :) Obwohl es bei mir sowohl unter XP als auch unter 7 gut funktioniert, stürzt nichts ab, obwohl ich es etwa eine Stunde lang laufen ließ. Es ist ein bisschen ein Rätsel...

Eine Zeile Code ist viel einfacher als Ihr Code. Sie müssen die Stämme nicht jeden Tag reinigen. Nur an Wochenenden. In der übrigen Zeit brauchen Sie diesen Code nicht. Es ist rational.

Es mag für Sie persönlich nicht entscheidend sein, wenn Sie gleichzeitig einen eigenen "Logging Cleaner" haben, d.h. Sie haben dort Ihre eigene Küche, aber wir sprechen hier von einem allgemeinen Fall. Stellen Sie sich einen normalen Benutzer vor, der all diese Dinge nicht tut. Dann braucht er den "Log Cleaner", um gut mit Ihrem Indikator arbeiten zu können. D.h. Und Sie müssen zugeben, dass er viel größer ist als der Umfang meines Codes ;) Ich glaube also, dass Sie sich in Bezug auf Rationalität und Kürze irren, vor allem, wenn Sie meinen Code in gepackter Form nehmen, wie Sie vorschlagen. Natürlich handelt es sich nicht um eine einzige Zeile, aber es sind keine weiteren Zusatzmodule erforderlich, d. h. es handelt sich um ein vollständiges Produkt.

Der Stamm muss ohnehin gereinigt werden.

Warum sollte ich sie reinigen, wenn sie nicht verstopft?

 

Alexej, die Reinigung muss nicht unbedingt automatisch erfolgen. Klicken Sie zum Beispiel mit der rechten Maustaste auf einen Ordner und wählen Sie"Ordner löschen". Tun Sie dies, nachdem Sie an den Wochenenden experimentiert haben.

Im Laufe eines Jahres sammeln sich 365 Dateien in EAs und Protokollen an. Das sind 730 Dateien. Es sollte nicht gereinigt werden? Es ist seltsam, das zu hören. Sie werden nicht verstopft, weil Sie nichts tun. Stämme werden sehr groß, wenn man jeden Tag arbeitet.

 
Zhunko:

Alexej, die Reinigung muss nicht unbedingt automatisch erfolgen. Klicken Sie zum Beispiel mit der rechten Maustaste auf einen Ordner und wählen Sie "Ordner löschen". Tun Sie dies, nachdem Sie an den Wochenenden experimentiert haben.

Im Laufe eines Jahres sammeln sich 365 Dateien in EAs und Protokollen an. Das sind 730 Dateien. Es sollte nicht gereinigt werden? Es ist seltsam, so etwas zu hören. Sie werden nicht verstopft, weil Sie nichts tun. Stämme werden sehr groß, wenn man jeden Tag arbeitet.

Nun, im Prinzip ja, ich stimme zu, dass sie nach Experimenten normalerweise gereinigt werden müssen. Ein Indikator wird erstellt, um zu funktionieren, nicht um zu experimentieren; wenn also ein fehlerbereinigter Indikator während der Arbeit immer noch die Protokolldateien verstopft, ist er nicht korrekt.

Was das Löschen der alten Protokolle angeht, so ist dies eine Frage der persönlichen Vorlieben. Ich musste zum Beispiel nach einigen Informationen in den Protokollen von vor einem Jahr suchen. Ich lösche sie also nicht. Ich meine Protokolle, die sich direkt auf den Handel beziehen, nicht auf verschiedene Experimente.

 
Meat:

Im Prinzip stimme ich zu, dass sie nach Experimenten gereinigt werden müssen. Aber wir reden nicht nur über Experimente. Schließlich soll ein Indikator funktionieren und nicht zum Experimentieren da sein. Wenn also ein fehlerhafter Indikator im Laufe seiner Arbeit weiterhin Protokolle verstopft, ist er bereits falsch.

Ich meine also, dass ein solches Gimmick nur an Wochenenden benötigt wird. In der übrigen Zeit brauchen Sie es nicht.
 

Im Allgemeinen ist die Erzeugung von Zecken auch an Wochentagen notwendig. Sie scheinen einen Expert Advisor/Indikator in Erwägung zu ziehen, der nur Zitate seines Symbols verwendet. Natürlich können Sie es einfach auf einem liquiden Symbol laufen lassen, z.B. EURUSD, wo die Ticks oft kommen... Aber es ist kein Allheilmittel, und es ist vielleicht auch nicht sehr praktisch.

 

Auf jeden Fall, wenn man das Ergebnis sehen will, bevor das Häkchen gesetzt ist.

Das heißt, - zu Forschungszwecken.

 

Ich habe herausgefunden, was das Problem war: Das Array sollte global und nicht lokal deklariert werden.

Ich stelle die korrigierte Fassung ein. Gleichzeitig habe ich den Code gekürzt. Die von Zhunko vorgeschlagene Variante war zwar 3 Zeilen kürzer als diese, aber zu kompliziert und unbequem für das Verständnis des Algorithmus). Ich denke also nicht, dass man um der Code-Reduzierung willen zum Äußersten gehen sollte.

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

Im Allgemeinen ist die Erzeugung von Zecken auch an Wochentagen notwendig. Sie scheinen einen Expert Advisor/Indikator in Erwägung zu ziehen, der nur Zitate seines Symbols verwendet. Natürlich können Sie es einfach auf einigen liquiden Symbolen laufen lassen, z.B. EURUSD, wo die Ticks oft kommen... Aber es ist kein Allheilmittel, und es ist vielleicht auch nicht sehr praktisch.

Haben Sie ein einziges Beispiel?

Solange ich schreibe und es benutze, habe ich es nie gebraucht, außer an den Wochenenden.

Expert Advisor + Indikator. Das Problem wird durch "Einfrieren" des Expert Advisors gelöst. Das Ergebnis ist das gleiche wie bei Ihnen. Um Daten rechtzeitig zu empfangen, reicht es aus, auf Zeitänderungen des Servers zu reagieren. Dafür brauchen Sie keine WinAPI.

Der einzige Fall, in dem dies erforderlich ist, ist der Start des Expert Advisors am Wochenende. Auch das kann mit der oben genannten Zeile realisiert werden. Nur für den Expert Advisor.