Expert Advisors: MQL5 Programming for Traders – Quellcodes aus dem Buch. Teil 6 - Seite 3

 
hini #property tester_set "FrameTransfer.set" (ungültige tester set Dateierweiterung, '*.set' erwartet FrameTransfer.mq5)

Sie muss wie folgt geändert werden, damit sie erfolgreich kompiliert werden kann: #property tester_set "\\Presets\\FrameTransfer.set"

Auch `#property tester_set "/Presets/FrameTransfer.set"` wird fehlschlagen.

Vielleicht könnten Sie die Beschreibung im Algorithmusbuch ändern:


Fix verfügbar in Build 5506.
 
Alain Verleyen #:
Fix verfügbar in Build 5506.
Wir danken Ihnen.
 
Stanislav Korotky Optimierungskriteriums auf R2-Basis - RSquared.mqh- bei, in der die Berechnung für den Fall variabler Lose korrigiert wurde.

Die Qualität der Schätzung wurde deutlich verbessert - nach der Tabelle der Optimierungsergebnisse zu urteilen, wurde die Kombination aus Erholungsfaktor und Sharpe-Parametern erhalten.

Beispiel für die Anwendung.

Achtung! Wenn unterschiedliche Symbole gehandelt werden, sollten diese für eine adäquate Schätzung der Volumina z.B. von Lots auf den Wert in der Depotwährung umgerechnet werden (eine der vereinfachten Varianten):

#include <MQL5Book/DealFilter.mqh>
#include <MQL5Book/RSquared.mqh>

template<typename T>
union Type2Bytes
{
   T d;
   uchar bytes[sizeof(T)];
};

double OnTester()
{
   HistorySelect(0, LONG_MAX);
   
   #define   STAT_PROPS 5
   
   const ENUM_DEAL_PROPERTY_DOUBLE props[STAT_PROPS] =
   {
      DEAL_PROFIT, DEAL_SWAP, DEAL_COMMISSION, DEAL_FEE, DEAL_VOLUME
   };
   double expenses[][STAT_PROPS];
   ulong tickets[]; // wird hier nur verwendet, um den 'select'-Prototyp abzugleichen, aber nützlich für die Fehlersuche
   
   DealFilter filter;
   filter.let(DEAL_TYPE, (1 << DEAL_TYPE_BUY) | (1 << DEAL_TYPE_SELL), IS::OR_BITWISE)
      .let(DEAL_ENTRY, (1 << DEAL_ENTRY_OUT) | (1 << DEAL_ENTRY_INOUT) | (1 << DEAL_ENTRY_OUT_BY), IS::OR_BITWISE)
      .select(props, tickets, expenses);

   const int n = ArraySize(tickets);
   
   double balance[];
   double volumes[]; // Berücksichtigung des Handelsvolumens bei der Anwendung des R2-Kriteriums
   
   ArrayResize(balance, n + 1);
   balance[0] = 0;
   ArrayResize(volumes, n + 1);
   volumes[0] = 0;

   MapArray<ulong,double> sym2value; // Symbolhash zu 1 Lotwert
   
   for(int i = 0; i < n; ++i)
   {
      const string s = HistoryDealGetString(tickets[i], DEAL_SYMBOL);

      double value = 1;
      Type2Bytes<ulong> sym;
      ArrayInitialize(sym.bytes, 0);
      StringToCharArray(s, sym.bytes);
      int idx = sym2value.find(sym.d);
      if(idx == -1) // noch kein Eintrag für Symbolwert pro Los
      {
         const double price = SymbolInfoDouble(s, SYMBOL_ASK);
         const double pt = SymbolInfoDouble(s, SYMBOL_POINT);
         double profit = 1;
         ResetLastError();
         if(!OrderCalcProfit(ORDER_TYPE_BUY, s, 1, price, price + pt, profit)) // NB: annähernd geschätzt, da der aktuelle Kurs der Kontowährung verwendet wird
         {
            // WARN(StringFormat("OrderCalcProfit Fehler: %s %d ", s, _LastError));
         }
         value = profit * (price / pt); // NB: Die Hebelwirkung wird hier nicht angewendet.
         idx = sym2value.put(sym.d, value);
      }
      else
      {
         value = sym2value.getValue(idx);
      }
   
      double result = 0;
      for(int j = 0; j < STAT_PROPS - 1; ++j) // Schleife durch alle angeforderten Requisiten mit Ausnahme des Geschäftsvolumens
      {
         result += expenses[i][j];
      }
      // Volumen als Modell verwenden - mehr Investitionen - mehr erwartete Erträge
      volumes[i + 1] = expenses[i][STAT_PROPS - 1] * value + volumes[i];
      balance[i + 1] = result + balance[i];
   }
   
   const double r2 = RSquaredTest(balance, volumes);
   
   #undef   STAT_PROPS
   
   return r2 * 100;
}

Gelb markiert ist, was im Vergleich zur Berechnung des Handels mit einem Symbol (aus dem vorherigen Beispiel) zu addieren war.

 
Stanislav Korotky #:

Fehlerbehebung MQL5/Include/MQL5Book/TradeUtils.mqh.

Ein weiterer verwandter Bugfix (in der Methode NormalizeLot ):

const double newLotsRounded = MathFloor(nlot * (1 + DBL_EPSILON) / stepLot) * stepLot;
Dateien:
TradeUtils.mqh  12 kb