Ist der Strategietester vom MT4 multicorefähig? - Seite 2

 
Mein EA ist sehr sehr umfangreich. Mein Programmierer meinte, dass er alles neuschreiben müsste, wenn ich ihn in MQL5 haben möchte. 
 
Otto Pauser:

Noch ein sehr brauchbarer link: https://www.mql5.com/en/articles/81

Manches wird allerdings sehr umständlich umgesetzt, was in Geschwindigkeitseinbußen resultiert.
Und auch die Übersichtlichkeit des Codes kann leiden.

Beispiel um 'Ask' zu erhalten:

in den Beispielen:

Viel einfacher:


Große Unterschiede gibt es beim Auslesen der Indikatoren in EAs und bei den Handelsfunktionen. Hier hilft allerdings die Systembibliothek enorm.

Auch ein Umdenken ist erforderlich. MT4 kennt nur Positionen, MT5 hat Orders, Deals und Positionen. Eine Order geht durch einen Deal in eine Position über, oder wird abgelehnt.

Also ganz so einfach ist es auch wieder nicht.

Ist das SymbolInfoDouble soviel schneller als MqlTick Otto?

ich definiere mir immer in OnTick die MqlTick tick, und dann verwendie ich tick.bid und tick.ask über den gesamten code, in funktionen übergebe ich immer die tick

 
amando:

Ist das SymbolInfoDouble soviel schneller als MqlTick Otto?

ich definiere mir immer in OnTick die MqlTick tick, und dann verwendie ich tick.bid und tick.ask über den gesamten code, in funktionen übergebe ich immer die tick

Den Unterschied hab ich noch nicht getestet. Du machst das ähnlich wie ich. Die Systeminformationen abzufragen ist sehr langsam. Das habe ich mit GetTickCount() getestet.

Hier habe ich den Unterschied bei unterschiedlichem Zugriff auf Indikatoren getestet.

int    handle;
double buffer[];

void OnStart()
{
    int n=1000;
   uint start,time;

   start=GetTickCount();
   for(int i=0; i<n; i++)
      slow();
   time=GetTickCount()-start;
   Print("Elapsed time for ",n," calculations slow: ",time," msec");

   start=GetTickCount();
   init();
   for(int i=0; i<n; i++)
      fast();
   time=GetTickCount()-start;
   Print("Elapsed time for ",n," calculations fast: ",time," msec");
}

void init(void)
{
   //handle=iMA(_Symbol,_Period,14,0,MODE_EMA,PRICE_TYPICAL);
   handle=iCustom(_Symbol,_Period,"Examples/RSI");
   ArraySetAsSeries(buffer, true);
}

void slow(void)
{
   //handle=iMA(_Symbol,_Period,14,0,MODE_EMA,PRICE_TYPICAL);
   handle=iCustom(_Symbol,_Period,"Examples/RSI");
   ArraySetAsSeries(buffer, true);
   CopyBuffer(handle,0,0,3,buffer);
}

void fast(void)
{
   CopyBuffer(handle,0,0,3,buffer);
}

Das kann man leicht für Anderes adaptieren. Ich hab das mal für einen Typen(R.B.) auf einem YT-Kanal gemacht, damit er endlich begreift wofür die OnInit() gut ist. Er hat's nicht begriffen.

Ich hol mir die Systemwerte mit jedem tick so:

//+------------------------------------------------------------------+
//| CTradeExt implementation                                         |
//+------------------------------------------------------------------+
void CTradeExt::CTradeExt(void)        // Constructor - get static information from account and symbol
{
   ProgName          = MQLInfoString    (MQL_PROGRAM_NAME);
   Magic             = StringToMagic    (_Symbol);
   VolMin            = SymbolInfoDouble (_Symbol,SYMBOL_VOLUME_MIN);
   VolMax            = SymbolInfoDouble (_Symbol,SYMBOL_VOLUME_MAX);
   VolStep           = SymbolInfoDouble (_Symbol,SYMBOL_VOLUME_STEP);
   TickSize          = SymbolInfoDouble (_Symbol,SYMBOL_TRADE_TICK_SIZE);
   StopsLevel        = (int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
   FreezeLevel       = (int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_FREEZE_LEVEL);
   AccLeverage       = (int)AccountInfoInteger(ACCOUNT_LEVERAGE);
   TickIndex         = WRONG_VALUE;    // tick counter
   TickIndexWait     = WRONG_VALUE;    // 
   TickRemainWait    = NULL;           // 
   BarsIndex         = WRONG_VALUE;    // bars counter
   BarsIndexWait     = WRONG_VALUE;    // 
   BarsRemainWait    = NULL;           // 
   TimeIndex         = WRONG_VALUE;    // time counter
   TimeIndexWait     = WRONG_VALUE;    // 
   TimeRemainWait    = NULL;           // 
   testing           = (bool)MQLInfoInteger(MQL_TESTER);
   optimizing        = (bool)MQLInfoInteger(MQL_OPTIMIZATION);
   finalbuild        =!(bool)MQLInfoInteger(MQL_DEBUG);
   OnTick();                           // complete initialisation
}

bool CTradeExt::OnTick()               // get dynamic information from symbol, account and position
{
   TickIndex++;
   CheckBarTime();                           // check BarTime/NewBar
   AccBalance     = AccountInfoDouble(ACCOUNT_BALANCE);                 
   AccEquity      = AccountInfoDouble(ACCOUNT_EQUITY);                  
   AccMarginFree  = AccountInfoDouble(ACCOUNT_MARGIN_FREE);             
   AccMarginLevel = AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);            
   TickValue      = SymbolInfoDouble (_Symbol,SYMBOL_TRADE_TICK_VALUE); 
   SwapLong       = SymbolInfoDouble (_Symbol,SYMBOL_SWAP_LONG);        
   SwapShort      = SymbolInfoDouble (_Symbol,SYMBOL_SWAP_SHORT);       
   Ask            = SymbolInfoDouble (_Symbol,SYMBOL_ASK);
   Bid            = SymbolInfoDouble (_Symbol,SYMBOL_BID); 
   Spread         = SymbolInfoInteger(_Symbol,SYMBOL_SPREAD);
   PosOpened      = PositionSelect(_Symbol);

   if(PosOpened)
      {                                      // position is open, update common values
         PosType      = (POSTYPE )PositionGetInteger(POSITION_TYPE);
         PosTicket    =           PositionGetInteger(POSITION_TICKET);
         PosOpenTime  = (datetime)PositionGetInteger(POSITION_TIME);
         PosVolume    = PositionGetDouble (POSITION_VOLUME);
         PosPriceOpen = PositionGetDouble (POSITION_PRICE_OPEN);
         PosPriceCurr = PositionGetDouble (POSITION_PRICE_CURRENT);
         PosProfit    = PositionGetDouble (POSITION_PROFIT);
         PosSL        = PositionGetDouble (POSITION_SL);       
         PosTP        = PositionGetDouble (POSITION_TP);
      }
   else                                      // no position opened
      {
         PosType      = WRONG_VALUE;
         PosTicket    = WRONG_VALUE;
         PosOpenTime  = NULL;
         PosVolume    = NULL;
         PosPriceOpen = NULL;
         PosPriceCurr = NULL;
         PosProfit    = NULL;
         PosSL        = NULL;       
         PosTP        = NULL;
      }

   DoInfo();                                 // show info

   if(WaitBars())
      return(false);
      
   return(true);
}

Ich hänge die Datei hier dran. Die kann sehr viel. Dazu gehört auch die Info.mqh.

Gehoren beide in MQL5\Include

Nachdem ich vor habe das in die Codebase zu stellen, kann ich es ja vorab hier auch posten.

Ein EA sieht dann zB. so aus:

//#define MINI_TRADE // kleine info trade
#define INFO_TRADE // ausführliche info trade

#include <Trade\TradeExt.mqh>

void OnTick()
{
   if(!Trade.OnTick())   // ! wichtig ! muss erste funktion sein
      return;

   // weiterer code

}

Lass das mal laufen und du wirst staunen!

Viel Erfolg damit!

PS: Großer Trick: Trade wird IN der TradeExt.mqh instantiiert. Alle Module können dann mit #include auf die selbe Instanz zugreifen. Das gleiche gilt für Info.

Edit: He, den Link da unten hab nicht ich hinzugefügt, das war die Platform!

Die Grundlagen für Tests in MetaTrader 5
Die Grundlagen für Tests in MetaTrader 5
  • www.mql5.com
Die Vorstellung des automatischen Handels ist sehr reizvoll, da ein Handels-Roboter ununterbrochen arbeiten kann - 24 Stunden pro Tag und 7 Tage die Woche. Ein Roboter wird niemals müde, unsicher oder verschreckt, da er psychologische Probleme schlicht weg nicht kennt. Ihm genügt es, wenn die Handelsregeln ausreichend formalisiert und in...
Dateien:
TradeExt.mqh  68 kb
Info.mqh  49 kb
 

Wir sind zwar schon sehr vom ursprünglichen Thema abgekommen, aber zu vorgehendem noch eine kleine Ergänzung:

Der Debugger kann #defines nicht auflösen(evaluieren). Ebenso kann er Funktionen zB. 'SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE)' nicht auswerten, mit dem muss man halt leben.

Man kann aber Trade.TichSize, Trade.Bid, Trade.PosTP, Trade.PosSL usw. im Debugger überwachen, Ein grosser Vorteil-

 

PS: Großer Trick: Trade wird IN der TradeExt.mqh instantiiert. Alle Module können dann mit #include auf die selbe Instanz zugreifen. Das gleiche gilt für Info.



@Otto, wie man bei uns daham sogt, net bled 

also das über die #include zu implementieren und dann abzufragen, also das erleichtert meinen Code um hunderte Zeichen, wenn ich das nicht mehr übergeben muss.

Deine Ideen sind ja wirklich oft die besten ;-)

 
amando:


@Otto, wie man bei uns daham sogt, net bled 

also das über die #include zu implementieren und dann abzufragen, also das erleichtert meinen Code um hunderte Zeichen, wenn ich das nicht mehr übergeben muss.

Deine Ideen sind ja wirklich oft die besten ;-)

Danke für die Blumen ;)

Du hast dich also damit auseiandergesetzt, gut. Steckt auch viel Arbeit da drin. Ist für Netting Accounts gedacht.

Für Hedging Accounts ist da grad was im Entstehen.

 
Otto Pauser:

Danke für die Blumen ;)

Du hast dich also damit auseiandergesetzt, gut. Steckt auch viel Arbeit da drin. Ist für Netting Accounts gedacht.

Für Hedging Accounts ist da grad was im Entstehen.

Also da ich ja nur Hedge verwende, wäre ich da sehr daran interessiert ;-)

 
Revilo2200:
Mein EA ist sehr sehr umfangreich. Mein Programmierer meinte, dass er alles neuschreiben müsste, wenn ich ihn in MQL5 haben möchte. 

Bleib mal ruhig bei MQL4. Gerade, wenn du einen Programmierer hast, also jemand was von Programmieren versteht, und du tatsächlich die Strategie und nicht nur die Logik testen willst, solltest du den alten Tester bevorzugen. Die Datenqualität im MT4 Tester läßt sich nämlich von deinem Programmierer nach Lust und Laune anpassen, was im MT5 Tester nicht mehr geht.

Zu den verwendeten Cores sei unbesorgt, und halte dich wieder an deinen Programmierer. Der MT4 Tester wird immer und unter allen Umständen nur einen Core verwenden, und wird das allein verwalten. Nichts, was du tun müßtest. Als Richtlinie: Ein 1-Jahres-Test auf Basis von BarOpen Preisen sollte 1-3 Minuten daueren. Dauert ein Test wesentlich länger, sag deinem Programmierer, daß er nachbessern soll. Der wird dann schon wissen, was zu tun ist. Mit den angegebenen Zeiten läßt sich eine Optimierung in überschaubaren Zeitspannen ausführen. Allerdings wird sie nur dann etwas nützen, wenn du den MT4 mit qualitativ wirklich hochwertigen Daten fütterst. Im MT4 ist das aufwendig, doch möglich. Im MT5 ist es mit vertretbarem Aufwand nicht mehr möglich. Das ist der Hauptgrund, warum ich rate, bei MQL4 zu bleiben.

Aussagekräftige Optimierung mit MetaTrader allgemein ist eine echte Herausforderung, egal mit welcher Version.

PS: Es ist ein allgemeiner Irrglaube, daß man für einen aussagefähigen Test Tickdaten (evt. sogar Real-Tickdaten) verwenden sollte. Je nach Strategie können BarOpen-Preise völlig ausreichend sein. Wichtig ist nicht der Datentyp, sondern die Datenqualität. Sprich: Du mußt sicher gehen, daß deine Daten keine Gaps oder Spikes enthalten, und sie vollständig sind. So etwas läßt sich nur automatisiert sicherstellen. Eines ist jedoch sicher: Der Datentyp "ControlPoints" ist völlig für die Tonne, und kann nur zum testen der Logik verwendet werden.
 
alphatrading:

Bleib mal ruhig bei MQL4. Gerade, wenn du einen Programmierer hast, also jemand was von Programmieren versteht, und du tatsächlich die Strategie und nicht nur die Logik testen willst, solltest du den alten Tester bevorzugen. Die Datenqualität im MT4 Tester läßt sich nämlich von deinem Programmierer nach Lust und Laune anpassen, was im MT5 Tester nicht mehr geht.

Zu den verwendeten Cores sei unbesorgt, und halte dich wieder an deinen Programmierer. Der MT4 Tester wird immer und unter allen Umständen nur einen Core verwenden, und wird das allein verwalten. Nichts, was du tun müßtest. Als Richtlinie: Ein 1-Jahres-Test auf Basis von BarOpen Preisen sollte 1-3 Minuten daueren. Dauert ein Test wesentlich länger, sag deinem Programmierer, daß er nachbessern soll. Der wird dann schon wissen, was zu tun ist. Mit den angegebenen Zeiten läßt sich eine Optimierung in überschaubaren Zeitspannen ausführen. Allerdings wird sie nur dann etwas nützen, wenn du den MT4 mit qualitativ wirklich hochwertigen Daten fütterst. Im MT4 ist das aufwendig, doch möglich. Im MT5 ist es mit vertretbarem Aufwand nicht mehr möglich. Das ist der Hauptgrund, warum ich rate, bei MQL4 zu bleiben.

Aussagekräftige Optimierung mit MetaTrader allgemein ist eine echte Herausforderung, egal mit welcher Version.

PS: Es ist ein allgemeiner Irrglaube, daß man für einen aussagefähigen Test Tickdaten (evt. sogar Real-Tickdaten) verwenden sollte. Je nach Strategie können BarOpen-Preise völlig ausreichend sein. Wichtig ist nicht der Datentyp, sondern die Datenqualität. Sprich: Du mußt sicher gehen, daß deine Daten keine Gaps oder Spikes enthalten, und sie vollständig sind. So etwas läßt sich nur automatisiert sicherstellen. Eines ist jedoch sicher: Der Datentyp "ControlPoints" ist völlig für die Tonne, und kann nur zum testen der Logik verwendet werden.

Deine Aussagen sind sehr wiedersprüchlich.

Bleib mal ruhig bei MQL4..........Die Datenqualität im MT4 Tester läßt sich nämlich von deinem Programmierer nach Lust und Laune anpassen. Ja geht's noch? Wozu dann testen? Und warum bei MQL4 bleiben? Damit's der Programmierer manipuliert?

Der MT4 Tester wird immer und unter allen Umständen nur einen Core verwenden, und wird das allein verwalten. Ja was soll er denn da verwalten bitte?

Im MT4 ist das aufwendig, doch möglich. Im MT5 ist es mit vertretbarem Aufwand nicht mehr möglich. Sorry: volkommener Unsinn. Mein Broker liefert beste historiche Daten.

Es ist ein allgemeiner Irrglaube, daß man für einen aussagefähigen Test Tickdaten (evt. sogar Real-Tickdaten) verwenden sollte. Sorry: Noch mehr Schwachsinn. Es ist der einzig wirklich aussgekräftige Test . TP,SL,pending Orders,etc. werden sonst zu anderenLevels gerissen.

-------------------------------------------------------------------------------------------------------------------------------------------------------

Fazit: MT5 verwendet alle cores die vorhanden sind. Die leistungsfähigsten, erschwinglichen PCs haben derzeit 32 cores. https://www.amd.com/de/products/cpu/amd-ryzen-threadripper-2990wx

Ich verstehe einfach nicht warum du beim MT4 bleiben willst. Es könnte natürlich auch sein, daß du das ironisch gemeint hast und ich es einfach nicht verstanden habe.

Und der Start des Testers im MT4 ist wirkich mühsam. Im MT5-Editor brauch ich nur auf den Kopf zu drücken und der Tester ist mit der richtigen Datei sofort da.

So: genug Zeit für diesen Schwachsinn aufgewendet.

 

Auch MT5 kann (Tick-) Daten Dritter für die Backtest verwenden!

- Bei MT4 muss man alle Tickdaten in das MT4-Format der historischen Kurse übersetzen.

- Bei MT5 muss man seit 2018 ein nutzerdefiniertes Symbol erstellen und dafür die Kurse Dritter einlesen (https://www.mql5.com/en/forum/262863). In der Codebase gibt es dazu auch den Code!

Man muss nur suchen zB nach "synthetic" (vorher auf Englisch stellen).

New MetaTrader 5 platform build 1880: Calculation of the complete history of synthetic symbols
New MetaTrader 5 platform build 1880: Calculation of the complete history of synthetic symbols
  • 2018.07.04
  • www.mql5.com
New MetaTrader 5 platform build 1880: Calculation of the complete history of synthetic symbols The updated version of the MetaTrader 5 platform wil...
Grund der Beschwerde: