Bibliotheken: MultiTester - Seite 3

 
Edgar:

Wenn Sie meinen, wie man sich die Optimierungsergebnisse anschaut, dann meinte ich das programmatische Auslesen der Ergebnisse aus dem Cache.

Das ist nicht das, was ich meinte. Aber Cache-Lesen ist möglich. Sie müssen es nur schreiben.

[Gelöscht]  

Coole Sache!!!

Habe auch Cycles dazu geschraubt und es war genau das, was ich vermisst habe )))))

#include <fxsaber\MultiTester\MultiTester.mqh> // Mehrere Durchläufe/Optimierungen im Tester.

enum CyclNum
{
   n01   = 1,     // 1
   n02,           // 2
   n03,           // 3
   n04,           // 4
   n05,           // 5
   n06,           // 6
   n07,           // 7
   n08,           // 8
   n09,           // 9
   n10,           // 0
};
sinput bool Period_M1 = false;         // M1 einschalten
sinput bool Period_M5 = false;         // M5 einschalten
sinput bool Period_M15 = false;        // M15 einschalten
sinput bool OnlyCustomSymbols = false; // Nur benutzerdefinierte Zeichen
sinput CyclNum number_cycles  = n06;   // Anzahl der Zyklen

// Diese Funktion ist für die Erstellung der Aufgabenliste zuständig.
void SetTesterSettings()
{
   for(int n = 0; n < number_cycles; n++)
   {
      // Suche nach allen Symbolen in der Marktübersicht.
      for (int i = SymbolsTotal(true) - 1; i >= 0; i--)
      {

Danke!

 
Сергей Таболин:

Ich fügte Cycles hinzu und es war genau das, was ich brauchte ))))

Ich brauche Button-Push-Funktionen im Tester. Dann wäre die Automatisierung auf einer anderen Ebene.

 

Ich habe einige Funktionen für die von mir benötigten Steuerelemente hinzugefügt (Depo, Währung, Leverage, OptimisationType, BarsType, Criteria). Aber ich habe es noch nicht getestet. Ich kann es später veröffentlichen.

Ich wollte eine Agentenverwaltung implementieren. Zum Beispiel kann man auf die Liste der Agenten klicken, HOME drücken und jeden Agenten mit VK_DOWN auswählen. Aber ich weiß nicht, wie man das Kontextmenü für die ausgewählte Zeile aufruft. Und dort müsste man 'd'/'e' zum Deaktivieren/Aktivieren drücken.

Kann mir jemand einen Tipp geben?

Noch schwieriger ist es, die Wolke zu aktivieren/deaktivieren (Deaktivieren vor Häkchen oder Kreuzoptimierung). Wenn Sie das Kontextmenü aufrufen, können Sie es nicht explizit aktivieren/deaktivieren, sondern nur umdrehen. Man kann den aktuellen Zustand nicht programmatisch herausfinden. Sie können aus dem Terminalprotokoll lesen "2019.07.31 19:27:35.664 Tester Cloud-Server mit Ausschalten". Es scheint, dass Sie das Protokoll auch nicht programmatisch lesen können, Sie müssen in der Protokolldatei nachsehen.

Es gibt noch eine Möglichkeit für undokumentierte WinAPI-Befehle. Vielleicht wissen einige C++-Programmierer, wie man sie findet?

[Gelöscht]  

Mit dem Problem des Stromausfalls konfrontiert. Jetzt weiß ich nicht, wie viel Optimierung durchgeführt wurde ((((

Wenn ich Zeit habe, werde ich versuchen, eine Überprüfung des Prozentsatzes der gesamten Optimierung und der bearbeiteten Zeichen hinzuzufügen. Ich hoffe, der Autor hat nichts dagegen? ))) Oder will er es selbst machen?

 
Сергей Таболин:

Ich bin mit dem Problem des Stromausfalls konfrontiert. Jetzt weiß ich nicht, wie viel Optimierung vorgenommen wurde (((

MultiTester spiegelt seine Schritte in den Protokollen wider. Wenn das Terminal die Logs gespeichert hat, können Sie dort alles sehen.

Außerdem werden die Optimierungs-Caches zu 100% gespeichert. Sie können also sehen, was ausgeführt wurde.

 
Edgar:

Ich habe einige Funktionen für die von mir benötigten Steuerelemente hinzugefügt (Depo, Währung, Leverage, OptimisationType, BarsType, Criteria). Aber ich habe es noch nicht getestet. Ich kann es später veröffentlichen.

Bevor Sie private Probleme lösen, wäre es gut, Szenarien für die Verwendung ihrer Lösungen zu beschreiben.

 
fxsaber:

Vor der Lösung privater Probleme ist es ratsam, Szenarien für die Anwendung ihrer Lösungen zu entwerfen.

Ich habe mein Szenario auf der vorherigen Seite beschrieben.

Clicker ist kein Ersatz für alles, sondern eines von mehreren Werkzeugen, die zur Automatisierung der Optimierung benötigt werden. Es ermöglicht Ihnen, alles in einem Terminal zu erledigen, ohne ein zusätzliches Terminal zu starten. Ich würde Frames für die Analyse der Ergebnisse hinzufügen (Ihre neue Bibliothek zum Lesen des Optimierungscaches ist für den gleichen Zweck geeignet), Funktionen für die Verwaltung von Eingabevariablen, SQLITE zum Speichern von Zuständen und Statistiken. Und Sie können intelligente Optimierungsskripte schreiben. Universalität kann nicht erreicht werden, jeder Expert Advisor hat sein eigenes Skript. Und Sie müssen es manuell erstellen und erst dann wiederholt anwenden.

Frames sind bereits hinzugefügt worden. Ich habe Erfahrung mit SQLITE.

Ich habe einfach Ihre Lib für meine Bedürfnisse erweitert. Ich bin sicher, dass Sie es selbst geplant haben, aber ich habe nicht gewartet. Dies ist die einzige der oben genannten Technologien, für die ich keine fertige Lösung hatte. Übrigens, ich habe meine Add-ons überprüft, sie funktionieren. Die Fragen der Agentenverwaltung sind immer noch relevant. Spy++ kann einem erfahrenen Systemingenieur beim Abfangen von Nachrichten helfen, aber ich hatte wenig Hilfe, ich muss wissen, was ich filtern muss. Ich hoffe, dass die Leute mitziehen werden. Das Thema ist seit 2008 immer wieder aufgetaucht.

 
Edgar:

Hier ist, wie ich es gerne verbessern würde. Mein typisches Optimierungsszenario:

N genetische Läufe für OHLC durchführen. Nehmen Sie das beste Ergebnis von jedem von ihnen nach einem benutzerdefinierten Kriterium.

Führen Sie eine langsame Optimierung für jede Parametergruppe durch (jede Gruppe hat 2-3 voneinander abhängige Parameter).

Wiederholen Sie iterativ langsame Optimierungen für jede Gruppe, bis das Optimum erreicht ist (Parameter schweben nicht mehr).

Wechseln Sie zu echten Ticks und führen Sie die gleichen langsamen Optimierungen durch.

Wechseln Sie zu einem anderen Symbol und wiederholen Sie alles.

Ich habe eine solche Aufgabe nicht vor mir. Natürlich wäre es gut, wenn die Automatisierung dies ermöglichen würde.

Ich selbst bemühe mich, ein Kriterium für die Robustheit des TS durch Auto-Optimierungsindikatoren zu entwickeln. Es fehlt sehr an mehr Objektivität in der Forschung.

Das Schema des Auto-Optimierers ist komplett durchdacht, es gibt keine technischen Hindernisse für die Umsetzung.

Bibla muss auf jeden Fall mit Funktionalität ergänzt werden. Bitte schlagen Sie also Ihre Vorstellungen vor.

 
enum eOptType   { eOptOff, eOptSlow, eOptGen, eOptAllSym };
enum eBars      { eBarsEvery, eBarsReal, eBarsOHLC, eBarsOpen, eBarsMath };
enum eCriteria  { eCritBal, eCritPF, eCritEPO, eCritDD, eCritRF, eCritSR, eCritCust };



class MTTESTER {
public:

        static bool 
        SetOptType(eOptType opt) {
                const bool rc = MTTESTER::IsReady();
                if (rc) {
                        static const int ControlID[] = { 0xE81E, 0x804E, 0x28EC, 0x28FB };
                        GET_HANDLE
                        user32::SendMessageW(Handle, WM_KEYDOWN, VK_HOME, 0);
                        for (int i = 0; i < opt; i++)
                                user32::SendMessageW(Handle, WM_KEYDOWN, VK_DOWN, 0);
                }
                return rc;
        }



        static bool 
        SetBars(eBars type) {
                const bool rc = MTTESTER::IsReady();
                if (rc) {
                        static const int ControlID[] = { 0xE81E, 0x804E, 0x28EC, 0x2913 };
                        GET_HANDLE
                        user32::SendMessageW(Handle, WM_KEYDOWN, VK_HOME, 0);
                        for (int i = 0; i < type; i++)
                                user32::SendMessageW(Handle, WM_KEYDOWN, VK_DOWN, 0);
                }
                return rc;
        }



        static bool 
        SetCriteria(eCriteria type) {
                const bool Res = MTTESTER::IsReady();
                if (Res) {
                        static const int ControlID[] = { 0xE81E, 0x804E, 0x28EC, 0x290B };
                        GET_HANDLE
                        user32::SendMessageW(Handle, WM_KEYDOWN, VK_HOME, 0);
                        for (int i = 0; i < type; i++)
                                user32::SendMessageW(Handle, WM_KEYDOWN, VK_DOWN, 0);
                }
                return Res;
        }



        static bool 
        SetCurrency(const string name) {
                const bool Res = MTTESTER::IsReady();
                if (Res) {
                        static const int ControlID[] = { 0xE81E, 0x804E, 0x28EC, 0x293F, 0x03E9 };
                        GET_HANDLE
                        user32::SendMessageW(Handle, WM_LBUTTONDOWN, 0, 0);
                        user32::SendMessageW(Handle, WM_KEYDOWN, VK_DELETE, 0);
                        char Chars[];
                        const int Size = ::StringToCharArray(name, Chars);
                        for (int i = 0; i < Size; i++)
                                user32::SendMessageW(Handle, WM_CHAR, Chars[i], 0);
                }
                return Res;
        }



        static bool 
        SetDepo(const long depo) {
                const bool Res = MTTESTER::IsReady();
                if (Res) {
                        static const int ControlID[] = { 0xE81E, 0x804E, 0x28EC, 0x28F9, 0x03E9 };
                        GET_HANDLE
                        user32::SendMessageW(Handle, WM_LBUTTONDOWN, 0, 0);
                        user32::SendMessageW(Handle, WM_KEYDOWN, VK_DELETE, 0);
                        string s = IntegerToString(depo);
                        char Chars[];
                        const int Size = ::StringToCharArray(s, Chars);
                        for (int i = 0; i < Size; i++)
                                user32::SendMessageW(Handle, WM_CHAR, Chars[i], 0);
                }
                return Res;
        }



        static bool 
        SetLeverage(const long leverage) {
                const bool Res = MTTESTER::IsReady();
                if (Res) {
                        static const int ControlID[] = { 0xE81E, 0x804E, 0x28EC, 0x28E9, 0x03E9 };
                        GET_HANDLE
                        user32::SendMessageW(Handle, WM_LBUTTONDOWN, 0, 0);
                        user32::SendMessageW(Handle, WM_KEYDOWN, VK_DELETE, 0);
                        string s = "1:" + IntegerToString(leverage);
                        char Chars[];
                        const int Size = ::StringToCharArray(s, Chars);
                        for (int i = 0; i < Size; i++)
                                user32::SendMessageW(Handle, WM_CHAR, Chars[i], 0);
                }
                return Res;
        }