Metatrader 5 automatisiert

 
Hallo zusammen,
habe eine interessante Frage.
Ist es eigentlich möglich von einem anderen Programm auf den Metatrader5 zu zugreifen.
Meine Idee, es wäre doch super wenn ein separates Programm, den Strategie Tester mit neuen Parametern füllt und wieder einschaltet.

Danke für eine schnelle Antwort.

LG Alex
 

Ja das geht.

Ich mache es selber so.

Aus Matlab herraus starte ich den Tester mit einer seperaten Konfig.

Kann jetzt momentan kein Beispiel posten...heute Abend erst.

Gruß

 

Hallo Christian,

ich Danke dir vielmals für deine Antwort.

Der Tipp mit Mathlab ist super, ich verstehe schon den weiteren zusammenhang.

Danke nochmals.


Gruß

Alex

 

Hallo zusammen, mir würde ein Hinweis zu dem Thema auch sehr helfen. Auch gerne im Rahmen von Mathlab....

Suche seit 2 Tagen schon nach "Batch erstellen Backtest MT5/MT4" bin jedoch noch nicht fündig geworden.

Danke :)

 

Erinnert Ihr Euch an die Zaubertaste F1? Sie funzt auch beim Terminal!

Mache ich das und gebe im Tab Suche ein: "start" kriege ich eine Seite die zeigt wie's geht:

Starten mit der Konsole

Die Plattform kann manuell mit verschiedenen Parametern gestartet werden. Dies kann mit verschiedenen Befehlen aus der Konsole oder alternativen Konfigurationsdateien durchgeführt werden.

Die Plattform kann mit Befehlen aus der Kommandozeile gestartet werden. Geben Sie dort den Pfad der ausführbaren Datei an (Pfad zur Datei\terminal.exe) und nach einem Leerzeichen einen oder mehrere der folgenden Befehle:

  • /login:Kontonummer — Plattform mit einer bestimmen Kontonummer starten. Zum Beispiel, terminal.exe / login:100000.
  • /config:path zu einer Konfigurationsdatei — die Plattform mit einer alternativen Konfigurationsdatei starten. Zum Beispiel, terminal.exe /config:c:\myconfiguration.ini. Die standardmäßige Konfigurationsdatei ist common.ini.
  • /profile:Profilname — die Plattform mit einem bestimmten Profil starten. Das Profil muss zu zuvor erstellt und gespeichert werden in /profiles/charts/. Zum Beispiel, terminal.exe /profile:Euro.
  • /portable — starten Sie die Plattform im portablen Modus. Dies ist möglicherweise notwendig, wenn die Plattform zuvor im Hauptmodus gestartet wurde. Um die Plattform im portablen Modus zu starten, benötigt der Nutzer die entsprechenden Rechte im Betriebssystem.

Wenn ein Befehl mit falschen Daten angegeben wurde, wird der Standardwert genutzt.


Mit benutzerdefinierter Konfigurationsdatei starten

Die Plattform kann manuell mit verschiedenen Parametern gestartet werden. Erstellen Sie Ihre eigene Konfigurationsdatei auf Basis der normalen common.ini. Um die Plattform mit einer benutzerdefinierten Konfigurationsdatei zu starten nutzen Sie den folgenden Befehl in der Konsole:

path_to_platform\terminal64.exe /config:c:\myconfiguration.ini

wobei "c:\myconfiguration.ini" der Pfad zur Konfigurationsdatei ist.

Benutzerdefinierte Konfigurationsdateien werden schreibgeschützt, solange die Plattform genutzt wird. Änderungen in den Einstellungen werden nicht in die benutzerdefinierte Konfigurationsdatei geschrieben.

Die Parameter der benutzerdefinierten Konfigurationsdatei sind in verschiedene Blöcke geteilt und korrespondieren mit dem Optionsfenster für die Plattform-Konfiguration in der Handelsplattform. Nachfolgend finden Sie die wichtigsten Einstellungen in der benutzerdefinierten Konfigurationsdatei:

 
Ich versuche mal eine Hilfestellung zu geben. Wie man mit MatLab den MT5 automatisiert aufruft. Kurz zum Ablauf: 1. Ini File generieren 2. MT5 mit ini File aus der CLI starten 3. Prüfen ob gestartet um weiterer Prozesse zu starten ( nur in meinem Fall wichtig, weil eine API gestartet wird) Als erstes braucht man einen Config-Generator für das *.ini File was man als config beim startet übergibt. Ich habe mir dafür eine Klasse gebaut . ich stoppe erstmal hier , irgendwie ist die Website defekt mql5. Buttons fehlen für code einfügen. Igendwie spinnt die ganze Seite auch
 

So 2. Versuch:

Ich wiederhole den Ersten Beitrag

Ich versuche mal eine Hilfestellung zu geben. Wie man mit MatLab den MT5 automatisiert aufruft.

Der Code aus MatLab ist so natürlich nicht lauffähig und dient nur als Wegweiser


Kurz zum Ablauf:

1. Ini File generieren

2. MT5 mit ini File aus der CLI starten

3. Prüfen ob gestartet um weiterer Prozesse zu starten ( nur in meinem Fall wichtig, weil eine API gestartet wird)

Als erstes braucht man einen Config-Generator für das *.ini File was man als beim start übergibt. Ich habe mir dafür eine Klasse gebaut um später flexible zu bleiben.

Das bearbeiten der *.ini Datei ist doch recht komplex. Natürlich gibt es diverse tools um *.ini Datei zu schreiben. Mir waren sie aber alle zu komplex.


ConfigGenerator

classdef MT5ConfigGenerator
    %MT5CONFIG Summary of this class goes here
    %   Detailed explanation goes here
    
    properties
        
        config_default
        config_write
        config_read
        config_modified
        iniFilePath
        
        IniConfig  % handle for Ini File Class
    end
    
    methods
        function obj = MT5ConfigGenerator()
            %MT5CONFIG Construct an instance of this class
            %   Detailed explanation goes here
            obj.IniConfig =  AICore.IniConfig();
            obj.config_default = AICore.MT5Config;
            
        end
        
        function ok = write_Ini(self)
            %METHOD1 Summary of this method goes here
            %   Detailed explanation goes here
            
            props = properties(self.config_default);
            
            for index = 2:length(props)
                 prop = props{index};
                 prop_value = self.config_default.(prop);
                 
                 if prop == "Sections"
                     sections = prop_value;
                     continue;
                 end
                 
                 if strfind(prop,"Section") == 1
                     Section = prop_value;
                     self.IniConfig.AddSections(prop_value);
                     continue;
                 end
                 
                 self.IniConfig.AddKeys(Section,prop,self.config_default.(prop));
                 
                 
%                  fprintf('Propertie: %s    %s  \n',prop,prop_value)
                    
            end
        
            if self.IniConfig.WriteFile(self.iniFilePath)            
             ok = true;
            else
             ok = false;
            end
            
        end
        
        function [ok, opts] = load_defaults_for(self,instance,opts)
            
            switch instance
                
                case 'AA'
                    
                    PreConfig = opts.mt5.Instance.AA.PreConfig;
                    
                    self.config_default.ShutdownTerminal = PreConfig.ShutdownTerminal;
                    self.config_default.Login            = PreConfig.Login;
                    self.config_default.FromDate         = datestr(opts.mt5.FromDate,'yyyy.mm.dd');
                    self.config_default.ToDate           = datestr(opts.mt5.ToDate,'yyyy.mm.dd');
                    
                    
                    ok = true;
                    
                case 'AB'
                    
                   PreConfig = opts.mt5.Instance.AB.PreConfig;
                    
                    self.config_default.ShutdownTerminal = PreConfig.ShutdownTerminal;
                    self.config_default.Login            = PreConfig.Login;
                    self.config_default.Port             = PreConfig.Port;
                    self.config_default.FromDate         = datestr(opts.mt5.FromDate,'yyyy.mm.dd');
                    self.config_default.ToDate           = datestr(opts.mt5.ToDate,'yyyy.mm.dd');
                    
                    
                    ok = true;  
                    
                case 'AC'
                    
                    PreConfig = opts.mt5.Instance.AC.PreConfig;
                    
                    self.config_default.ShutdownTerminal = PreConfig.ShutdownTerminal;
                    self.config_default.Login            = PreConfig.Login;
                    self.config_default.Port             = PreConfig.Port;
                    self.config_default.FromDate         = datestr(opts.mt5.FromDate,'yyyy.mm.dd');
                    self.config_default.ToDate           = datestr(opts.mt5.ToDate,'yyyy.mm.dd');
                    
                    
                    ok = true;  
                    
                case 'AD'
                    
                    PreConfig = opts.mt5.Instance.AD.PreConfig;
                    
                    self.config_default.ShutdownTerminal = PreConfig.ShutdownTerminal;
                    self.config_default.Login            = PreConfig.Login;
                    self.config_default.Port             = PreConfig.Port;
                    self.config_default.FromDate         = datestr(opts.mt5.FromDate,'yyyy.mm.dd');
                    self.config_default.ToDate           = datestr(opts.mt5.ToDate,'yyyy.mm.dd');
                    
                    
                    ok = true; 
                    
                otherwise 
                    error('Wrong Instance Name');
                    ok == false;
            end  
            
        end
        
        function [ok, opts] = generateConfig(self,instance,opts)
            
                 
            ok = true;
            
            switch instance
                
                case 'AA'
        
        
                    self.iniFilePath = strcat(opts.core.path,'\mt5_config.ini');

                    self.write_Ini();

                    opts.mt5.Instance.StartCommand = strcat(opts.mt5.Instance.AA.PathtoTerminal, 'Terminal64_parallel.lnk /config:  ',self.iniFilePath,' &'); 
                    opts.mt5.terminalpath          = strcat(opts.mt5.Instance.AA.PathtoTerminal, 'terminal64.exe');
                    
                case 'AB'
        
        
                    self.iniFilePath = strcat(opts.core.path,'\mt5_config.ini');

                    self.write_Ini();

                    opts.mt5.Instance.StartCommand = strcat(opts.mt5.Instance.AB.PathtoTerminal, 'Terminal64_parallel.lnk /config:  ',self.iniFilePath,' &'); 
                    opts.mt5.terminalpath          = strcat(opts.mt5.Instance.AB.PathtoTerminal, 'terminal64.exe');
                    
                case 'AC'
        
        
                    self.iniFilePath = strcat(opts.core.path,'\mt5_config.ini');

                    self.write_Ini();

                    opts.mt5.Instance.StartCommand = strcat(opts.mt5.Instance.AC.PathtoTerminal, 'Terminal64_parallel.lnk /config:  ',self.iniFilePath,' &');   
                    opts.mt5.terminalpath          = strcat(opts.mt5.Instance.AC.PathtoTerminal, 'terminal64.exe');
                    
                case 'AD'
        
        
                    self.iniFilePath = strcat(opts.core.path,'\mt5_config.ini');

                    self.write_Ini();

                    opts.mt5.Instance.StartCommand = strcat(opts.mt5.Instance.AD.PathtoTerminal, 'Terminal64_parallel.lnk /config:  ',self.iniFilePath,' &');    
                    opts.mt5.terminalpath          = strcat(opts.mt5.Instance.AD.PathtoTerminal, 'terminal64.exe');
                    
                otherwise 
                    error('Wrong Instance Name');
                    ok = false;
            end   
            
        end
        
    end
end


dazu gibt es das Objekt MT5Config welches die Grundeinstellungen der *.ini bereitstellt.

Wer sich fragt was es mit den Instanzen AA AB AC AD auf sich hat das sind 4 verschiedene MT5 Instanzen . Da ich mit MatLab beim Testen 4 x den MT5 benutze.

In jedem Ordner eines MT5 liegt ein Verknüpfung um den MT5 zu minimieren beim Start.

Terminal64_parallel.lnk


Der Tester benötigt um korrekt zu starten folgende Einstellungen. Als Beispiel kopiere ich eine generierte *.ini Datei rein.

[Charts]
ProfileLast=Default
MaxBars=100000
PrintColor=0
SaveDeleted=0
TradeLevels=1
TradeLevelsDrag=0
ObsoleteLasttime=1533222840

[Common]
Login=500004182
ProxyEnable=0
ProxyType=0
ProxyAddress= 
ProxyAuth= 
CertInstall=0
NewsEnable=1
NewsLanguages= 
MQL5Login=collider
MQL5Password=
MQL5UseStorage=2

[Objects]
ShowPropertiesOnCreate=0
SelectOneClick=0
MagnetSens=10
PreciseTime=0
SelectOnCreate=1

[Trades]
LotsMode=0
LotsLast=10000
LotsDefault=10000
SymbolMode=0
SymbolLast= 
SymbolDefault=EURUSD
DeviationMode=0
DeviationDefault=0
DeviationLast=0
StopsMode=0
DealsAutoAddOnChart=0

[Experts]
AllowDllImport=1
Enabled=1
Account=1
Profile=1
Chart=0
DisableOpenCL= 
WebRequest=0
DisableFPExceptionsLog=0
WebRequestUrl= 

[Events]
Enable=0
Connect=connect.wav
ConnectEnable=1
Disconnect=disconnect.wav
DisconnectEnable=1
EmailNotify=email.wav
EmailNotifyEnable=1
Timeout=timeout.wav
TimeoutEnable=1
Ok=ok.wav
OkEnable=1
News=news.wav
Newsenable=1
Expert_Advisor=expert.wav
Expert_AdvisorEnable=1
Alert=alert.wav
AlertEnable=1
Requote=alert.wav
RequoteEnable=1
Trailing_Stop=stops.wav
Trailing_StopEnable=0
Testing_Finished=expert.wav
Testing_FinishedEnable=1

[Tester]
Expert=MT-Api\MtApi5.ex5             Hier trägt man den EA ein der getestet werden soll
ExpertParameters=MtApi5.set          Das passende Parameter File
Symbol=EURUSD
Period=M1
Deposit=10000
Leverage=1:100
Model=4
Visual=0
ExecutionMode=1
FromDate=2018.01.01                           Start Datum des Tests
ToDate=2018.01.12                             End Datum des Tests
Report=Matlab_NeuronalTrader                  Dateiname für die Report Dateien
ReplaceReport=1                               Überschreibe alten Report
ShutdownTerminal=1                            Beende MT5 nach dem Test
Port=3005                                     Port eines Agenten

[Notification]
enable=0
Trade=1
TradeMarginCall=0
PushID=


Leider hat es MQ versäumt eine ordentliche Fehlerbehandlung für das einlesen einer falschen *.ini Datei zu entwickeln.

Bedeutet es gibt keinen Hinweis darauf was in der Config falsch ist. Nur das sie nicht geladen wurden. Also try and error :-)


Um das Start und End Datum zu generieren benutze ich ne kleine Krücke. Soll später aber in den ConfigGenerator einfließen.

Ich teile das Jahr in Wochen ein die ich dann in der parfor Schleife selektieren kann.

Gibt sicher andere Möglichkeiten um die Strings des Datums für eine bestimmt Woche zu bekommen.

Wer ein tool für Matlab kennt was mir Strings der Tage generiert bitte Info an mich

Bin für jeden Tipp dankbar


% Generate Tester Dates
TesterDates.d1 = datetime('2018.01.01','InputFormat','yyyy.MM.dd' );                           // Start Datum der Datumsliste
TesterDates.d2 = datetime('2019.01.01','InputFormat','yyyy.MM.dd' );                           // End Datum der Datumsliste

TesterDates.Mon = dateseries(TesterDates.d1,TesterDates.d2,'Interval','weekly','Day','Mon');   // dateseries generiert alle Montage als Datum des obigen Zeitraums
TesterDates.Tue = dateseries(TesterDates.d1,TesterDates.d2,'Interval','weekly','Day','Tue');   //  usw ..
TesterDates.Wed = dateseries(TesterDates.d1,TesterDates.d2,'Interval','weekly','Day','Wed'); 
TesterDates.Thu = dateseries(TesterDates.d1,TesterDates.d2,'Interval','weekly','Day','Thu'); 
TesterDates.Fri = dateseries(TesterDates.d1,TesterDates.d2,'Interval','weekly','Day','Fri'); 

TesterDates.day(1) = length(TesterDates.Mon);                                                    // Anzahl der Montage speichern
TesterDates.day(2) = length(TesterDates.Tue);
TesterDates.day(3) = length(TesterDates.Wed);
TesterDates.day(4) = length(TesterDates.Thu);
TesterDates.day(5) = length(TesterDates.Fri);

TesterDates.maxweeks = max(TesterDates.day);
TesterDates.Dates  = strings(TesterDates.maxweeks,5);

TesterDates.Dates(1:TesterDates.day(1),1) = TesterDates.Mon;
TesterDates.Dates(1:TesterDates.day(2),2) = TesterDates.Tue;
TesterDates.Dates(1:TesterDates.day(3),3) = TesterDates.Wed;
TesterDates.Dates(1:TesterDates.day(4),4) = TesterDates.Thu;
TesterDates.Dates(1:TesterDates.day(5),5) = TesterDates.Fri;

% Generate list with dates to preselect each worker

StartWeek  = 1;
EndWeek    = 2;
% TestLength = 1; 

TesterDates.preselected = strings( K,2);
for idx=1:1:K
      
    if idx == 1
        add = 0;
    else
        add = idx-1;
    end
    
    TesterDates.preselected(idx,1) = TesterDates.Dates(StartWeek+add,1);
    TesterDates.preselected(idx,2) = TesterDates.Dates(EndWeek+add,5);
end


Und folgende Zeilen sind in der parfor Schleife um jedem job ein anderes Datum zuweisen zu können

    fromdate = datetime(TesterDates.preselected(k,1),'InputFormat','MM/dd/yyyy');    // auswählen des Datums für den job
    todate   = datetime(TesterDates.preselected(k,2),'InputFormat','MM/dd/yyyy');    // auswählen des Datums für den job 

    safeend_dt = todate;

    if (day(todate,'dayofweek') == 6)
      safeend_dt  =   safeend_dt - minutes(65);  
      safeend = System.DateTime.Parse(datestr(safeend_dt));

    else
      safeend_dt  =  safeend_dt - minutes(10);  
      safeend = System.DateTime.Parse(datestr(safeend_dt));
    end

    opts.mt5.FromDate         = fromdate;
    opts.mt5.ToDate           = todate;
    opts.mt5.SafeTesterEnd_dt = safeend_dt;
    opts.mt5.SafeTesterEnd    = safeend;

Am Ende hab ich dann alle Tage des Zeitraumes und zwar nur die Montag-Freitage als String gespeichert.


Die ich dann an die MT5 config weiterleite.

Da ich für jede MT5-Instanz andere Werte in der Config brauche speicher ich noch die Daten manuell ein.

   opts.mt5.Instance.AA.PathtoProfil = 'C:\Users\f12\AppData\Roaming\MetaQuotes\Terminal\85E0500D219F8236428E23AF959\';        // Pfad zum Terminal (gekürzt)
   opts.mt5.Instance.AA.PreConfig.Login = 500004182;                                                                           // Login des Kontos

So nachdem nun die Config vollständig ist kann sie geschrieben werden

ConfigGen = AICore.MT5ConfigGenerator();                 // Generator erstellen                                        
ConfigGen.load_defaults_for(Instance,opts);              // defaults laden


[ok, opts] = ConfigGen.generateConfig(Instance,opts);    // file generieren und speichern

if ~ok; error('Generate Config');end

Die Funktion IniConfig ist als Datei angehängt. Stammt nicht von mir . Sie schreibt das ini File.


Ist das file korrekt geschrieben muss nur noch das StartCommando erstellt werden.

Pfad des MT5 + config file und am ende das & Zeichen . Damit Matlab nicht auf den Befehl wartet.

Beispiel des StartComandos :

C:\Work\MT5-Instanzen\MT5-AA\terminal64.exe /config:C:\Work\NeuronalTrader_matlab\Results\2019_1_11_7_6_45.165\mt5_config.ini &

Ich generiere für jeden Test einen eigenen Ordner der das aktuelle Datum und Uhrzeit als Name trägt.

Jetzt kann der MT5 aus MatLab heraus gestartet werden.

 
    [~,~] = system(opts.mt5.Instance.StartCommand);                                        // Mt5 starten

    trader.cLogger.info('Processdetector waits ')

    found = false;
    cnt = 0;
    while (found == false && cnt < 30)                                                    // Prüfschleife um einen gestartetn MT5 zu melden.
        pause(1);                                                                         // Ist nur für mich wichtig
        cnt=cnt+1;
        p = System.Diagnostics.Process.GetProcessesByName('terminal64');                   // System Info über Processe mit dem Namen 'terminal64' Können natürlich auch mehrer sein
       
        if p.Length > 0                                                                    // wenn p nicht 0 ist haben wir mindestens einen MT5 gefunden
          trader.cLogger.info(sprintf('Found %d Processes of Metatrader5 ',p.Length));     
           for idx=1:1:p.Length
            if p(idx).MainModule.FileName.char == opts.mt5.terminalpath                    // Prüfen ob der Pfad zu dem Process passt
               trader.cLogger.info(sprintf('Found Instance %s ',Instance));                // Wenn ja ist der gewünschte MT5 gestartet
               found = true;
               pause(1);                                                                   
               [status1] = system('"C:\Windows\System32\taskkill.exe" /F  /im cmd.exe &');  // schließen des CMD Fensters,sonst wird der Bildschirm zugemüllt bei großen Tests
            end
           end
        end
    end

   if  found
      trader.cLogger.info('Found Metatrader5 process ! ');
   else
       trader.cLogger.info('cant find Metatrader5 process ! ',1);
       exitCode = 4;
       cleanup(4);

       return;
   end
   


So das war es.

Wer fragen hat ..bitte


Gruß

 
Christian:

So 2. Versuch:

Ich wiederhole den Ersten Beitrag


Danke Christian .. :)!

 

Hab die Files nochmal als zip hochgeladen.

MatLab files löscht das Forum gleich wieder.

 
Christian:

Hab die Files nochmal als zip hochgeladen.

MatLab files löscht das Forum gleich wieder.

Wow! Danke Christian!

Schreib doch einmal einen Artikel darüber?

 
Carl Schreiber:

Wow! Danke Christian!

Schreib doch einmal einen Artikel darüber?

Da könnte ich mit dem Lizensmodell von MatLab in Schwierigkeiten kommen.

Wenn ich es kostenlos ins Forum stelle bin ich auf der sicheren Seite :-)

Habe aber auch wenig Interesse für MQ zu arbeiten.