MetaTrader 5 herunterladen

Verwendung der TesterWithdrawal() Funktion zur Nachahmung der Gewinnentnahme

9 März 2016, 12:13
Andrey Voytenko
0
263

Einleitung

Das Ziel jedes spekulativen Handels ist Gewinn zu erwirtschaften. Wenn ein Handelssystem getestet wird, werden normalerweise alle Aspekte analysiert, außer diesem - die Entnahme eines Teils des erwirtschafteten Geldes zum Leben. Selbst wenn Trading nicht die einzige Einnahmequelle des Börsenhändlers ist, stellt sich früher oder später dennoch die Frage nach dem geplanten Gewinn für eine Handelsperiode (Monat, Quartal, Jahr). Die TesterWithdrawal() Funktion in MQL5 dient zur Nachahmung der Geldentnahme aus dem Account.


1. Was können wir alles prüfen?

Es gibt Ansichten zum Handel und zu Handelssystemen, die die Entnahme von überschüssigem Geld in riskanten Situationen implizieren. Es verbleibt nur noch ein kleiner Teil des Gesamtkapitals im Handels-Account. Man schützt sich also vor dem Verlust des gesamten Geldes infolge unvorhergesehener Umstände.

Praktisch gesehen ist dies ein Beispiel der Money Management Strategien (Geldverwaltung). Viele Fonds, die MM-Investitionen akzeptieren, geben jedem Händler eine gewisse Quote (einen Teil des Gesamtkapitals), doch nie erhalten sie das gesamte Kapital. Mit anderen Worten: zusätzlich zu den Beschränkungen des Volumens der eröffneten Positions, gibt es auch noch Beschränkungen auf dem Kapital, mit dem ein Händler agieren kann. Sodass am Ende jeder Händler nur über einen kleinen Teil des Vermögens verfügen und riskante Spekulationen machen kann.

Ein weiteres Problem ist die aggressive Re-Investition von erwirtschaftetem Vermögen während des Tests. Händler wollen gerne ein Gleichgewicht schaffen, und während der Optimierung gehen die Eigenkapitallinien senkrecht nach oben. Zwar sieht jeder ein, dass es bei jedem Geldlevel gewisse Regeln gibt, und es ist absolut unsinnig zu glauben, dass ein ertragreiches System beim Handeln mit 0,1 Posten auch noch genauso gut funktioniert, wenn 100 Posten gehandelt werden.

Und dann kommt noch ein psychologisches Problem hinzu: jeder aktive Händler wird sicherlich eingestehen, dass er bei einem gewissen Geldlevel in die Arbeit des Handelssystems eingegriffen hat, obwohl er versprochen hat, dies nicht zu tun. Und genau von diesem Standpunkt aus ist die Entnahme von Überschüssen ein stabilisierender Faktor beim Handeln.

Es gibt in MQL5 eine Funktion zur Implementierung der Geldentnahme während des Tests eines Expert Advisors. Und die schauen wir uns jetzt mal genauer an


2. Wie wird diese Funktion eingesetzt?

Die TesterWithdrawal() Funktion dient der Nachahmung der Geldentnahme aus dem Account im Strategie-Tester und beeinflusst die Arbeit des Experts Advisors im normalen Dienstmodus überhaupt nicht.

bool TesterWithdrawal(double money);

Der Eingabeparameter Geld soll den Geldbetrag angeben, der in der Depotwährung entnommen werden soll. Anhand des gelieferten Werts erkennen Sie, ob dieser Vorgang erfolgreich war oder nicht. Jeder, während des Tests durchgeführte Entnahmevorgang wird mit dem entsprechenden Eintrag in der "Logbuch"- und auch der "Ergebnisse"-Registerkarte angezeigt, so wie in Abb. 1 dargestellt.

Einträge über erfolgreiche Geldentnahme während Tests

Abb. 1 Einträge über erfolgreiche Geldentnahme während Tests

Sollte die Höhe der Entnahme die Höhe der freien Marge überschreiten und die Geldentnahme nicht durchgeführt worden sein, erscheint der folgende Eintrag im "Logbuch":

Eintrag über einen nicht erfolgreichen Entnahmevorgang während Tests

Abb. 2 Eintrag über einen nicht erfolgreichen Entnahmevorgang während Tests

Wird diese Funktion aufgerufen, nimmt die Höhe des aktuellen Saldos und Eigenkapitals um den Betrag des entnommenen Geldes ab. Der Strategie-Tester berücksichtigt bei der Berechnung von Profit und Loss jedoch diese Entnahme nicht, sondern errechnet die Gesamtsumme aller Entnahmen in der "Entnahme"-Rate, wie in Abb. 3 gezeigt.

Rate der Gesamtsumme aller Entnahmen im Bericht

Abb. 3 Rate der Gesamtsumme aller Entnahmen im Bericht

Hier sei darauf hingewiesen, dass die Umkehr-Funktion, nämlich Geld in einen Handels-Account einzuzahlen, in MQL5 noch nicht existiert, und wahrscheinlich auch nicht implementiert werden wird. Wer braucht schon Systeme, die ein dauerndes Füttern des Depots erfordern?

Im nächsten Abschnitt beschäftigen wir uns mit dem Beispiel eines Expert Advisors, nicht nur mit implementierter Handelsstrategie, sondern mit einem Toolkit zur Nachahmung von Geldentnahme mit Hilfe der von uns beobachteten Funktion.


3. Versuchskaninchen für Testzwecke

Wir führen jetzt einen Test bei einem eher einfachen Expert Advisor durch. All diejenigen, die an den Arbeitsprinzipien eines Expert Adviors interessiert sind, finden weiter unten eine entsprechende Beschreibung seines Handelssystems.

Die Maximal- und Minimalwerte des Preises werden in einem spezifizierten Zeitraum von 5M-Daten berechnet, der mit Hilfe der PERIOD Eingabe-Variable eingerichtet wird. Berechnete Levels bilden den waagrechten Kanal mit seinen Unterstützungs- (CalcLow Variable) und Widerstandslinien (CalcHigh Variable). Pending Orders werden an die Ränder des Kanals platziert. Das Spiel findet am Schneideweg des Kanals statt.

Eine pending Order wird platziert, sobald der Preis in den Kanal geht, und zwar für nicht weniger als der Wert der INSIDE_LEVEL Eingabe-Variable. Darüber hinaus kann nur eine Position oder pending Order in einer Richtung eröffnet werden.

Wird der Kanal enger, wenn die Levels neu berechnet werden und bleibt der Preis immer noch drin, dann wird die pending Order näher an den Marktkurs verschoben. Diese Verschiebung von pending Orders wird mit Hilfe der ORDER_STEP Eingabe-Variable eingerichtet.

Die Höhe des Gewinns aus einem Abschluss wird in der TAKE_PROFIT Eingabe-Variable festgelegt; der Maximalverlust mit Hilfe von STOP_LOSS.

Der Expert Advisor impliziert die Verschiebung von Stop Loss mit einem in der TRAILING_STOP Eingabe-Variable festgelegten Schritt.

Sie können nun sowohl mit einem fixen Posten oder mit einem Posten handeln, der als Prozentwert des Depots berechnet ist. Mit Hilfe der LOT Eingabe-Variable wird der Wert des Postens gesetzt und mit Hilfe der LOT_TYPE Variable die Methode zu seiner Berechnung. Der Posten kann durchaus noch korrigiert werden (LOT_CORRECTION = true). Falls Sie mit einem fixen Posten handeln und seine Größe die, zur Eröffnung einer Position maximal zulässige Grenze, überschreitet, dann wird die Größe des Postens am nächsten erlaubten Wert korrigiert.

Zur Feinabstimmung des Algorithmus des Expert Advisors können Sie die Funktion zum Schreiben des Protokolls anstellen (WRITE_LOG_FILE = true). Somit werden die Einträge über alle Handelsoperationen in die Textdatei log.txt geschrieben.

Fügen wir zur Verwaltung der Geldentnahmen dem Expert Advisor noch mehrere Eingabe-Variablen hinzu.

Die ersten Parameter dienen als Flagge der Möglichkeit, Vermögen abzuziehen.

input bool WDR_ENABLE = true; // Allow withdrawal

Der zweite Parameter legt die Periodizität der Entnahmen fest.

enum   wdr_period
  {
   days      = -2, // Day
   weeks     = -1, // Week 
   months    =  1, // Month  
   quarters  =  3, // Quarter
   halfyears =  6, // Half a year    
   years     = 12  // Year    
  };
input wdr_period WDR_PERIOD = weeks; // Periodicity of withdrawals

Der dritte Parameter legt den zu entnehmenden Geldbetrag fest.

input double WDR_VALUE = 1; // Amount of money to be withdrawn

Der vierte Parameter bestimmt die Berechnungsmethode des Betrags, der entnommen werden soll.

enum lot_type 
   {
      fixed,  // Fixed
      percent // Percentage of deposit
   };
input lot_type WDR_TYPE = percent; // Method of calculation of the withdrawal amount

Zur Berechnung des Betrags für eine einmalige Geldentnahme aus dem Account wird wdr_value verwendet. Die Variable wdr_summa wird zur Berechnung des Gesamtbetrags verwendet, der entnommen werden soll.

Und mit Hilfe der Variable wdr_count berechnen wir auch noch die Gesamtzahl aller erfolgreichen Geldentnahmen. Die Werte dieser Variablen sind notwendig für unseren eigenen Bericht über das Ergebnis des Tests. Die komplette Funktionalität der Entnahme von Geld ist in der unten stehenden Funktion implementiert.

//--- Function of withdrawing assets from the account
//+------------------------------------------------------------------+
bool TimeOfWithDrawal()
//+------------------------------------------------------------------+
  {
   if(!WDR_ENABLE) return(false); // exit if withdrawal is prohibited
   
   if( tick.time > dt_debit + days_delay * DAY) // periodic withdrawals with specified period
     {
      dt_debit = dt_debit + days_delay * DAY;
      days_delay = Calc_Delay();// Updating the value of period-number of days between withdrawal operations
      
      if(WDR_TYPE == fixed) wdr_value = WDR_VALUE;
      else wdr_value = AccountInfoDouble(ACCOUNT_BALANCE) * 0.01 * WDR_VALUE;

      if(TesterWithdrawal(wdr_value))
        {
         wdr_count++;
         wdr_summa = wdr_summa + wdr_value;
         return(true);
        }
     }
   return(false);
  }

Jetzt müssen wir den Expert Advisor für den Test im Optimierungs-Modus vorbereiten. Hier gibt es verschiedene Optimierungs-Parameter, daher deklarieren wir eine Eingabe-Variable mit deren Hilfe wir den jeweils notwendigen Parameter auswählen können.

enum opt_value
{
   opt_total_wdr,      // Total sum of withdrawal
   opt_edd_with_wdr,   // Drawdown with consideration of withdrawal
   opt_edd_without_wdr // Drawdown without consideration of withdrawal
};
input opt_value OPT_PARAM = opt_total_wdr; // Optimization by the parameter

Außerdem müssen wir den Expert Advisor noch um eine weitere wichtige Funktion ergänzen - OnTester() - der gelieferte Wert dieser Funktion legt das Optimierungskriterium fest.

//--- Displaying information about testing
//+------------------------------------------------------------------+
double OnTester(void)
//+------------------------------------------------------------------+
  {
   //--- Calculation of parameters for the report
   CalculateSummary(initial_deposit);
   CalcEquityDrawdown(initial_deposit, true, false);
   //--- Creation of the report
   GenerateReportFile("report.txt");

   //--- Returned value is the optimization criterion
   if (OPT_PARAM == opt_total_wdr) return(wdr_summa);
   else return(RelEquityDrawdownPercent);
  }

Im folgenden Abschnitt geht es um eine Detailbetrachtung des Tests unseres Expert Advisors.


4. Den Expert Advisor testen

Zur Integrität des Tests brauchen wir zunächst die Ergebnisse des Tests unseres Expert Advisors bei deaktivierter Geldentnahme-Funktion. Um das vor dem Testen zu machen, stellen Sie den Parameter "Entnahme zulassen" auf false, so wie in Abb. 5 gezeigt.

Für alle, die die Testergebnisse gerne wiederholen möchten, zeigen Abbildungen 4 und 5 unten die Einstellungen und Werte der Eingabeparameters des Expert Advisors.

Einstellungen für den Test des Expert Advisors

Abb. 4 Einstellungen für den Test des Expert Advisors

Parameter des Expert Advisors bei deaktivierter Geldentnahme-Funktion

Abb. 5 Parameter des Expert Advisors bei deaktivierter Geldentnahme-Funktion

Die Ergebnisse, die wir nach dem Test erhalten haben, sind in Abbildungen 6 und 7 dargestellt.

Saldo-Veränderung für 6 Monate Test des Expert Advisors

Abb. 6 Saldo-Veränderung für 6 Monate Test des Expert Advisors

Ergebnistabelle der Arbeit des Expert Advisors

Abb. 7 Ergebnistabelle der Arbeit des Expert Advisors

Uns interessiert der Parameter 'relative Inanspruchnahme des Eigenkapitals'. Er entspricht hier 4,75%.

Schauen wir mal, wie er sich verändert, sobald wir die Möglichkeit der Geldentnahme aktivieren. Führen wir nun Tests bei unterschiedlichen Beträgen und Periodizität von Entnahmen durch.

Abb. 8 zeigt die Parameter des Expert Advisors bei aktivierter Optimierung und Geldentnahme. Abb. 9 zeigt uns die Ergebnisse eines solchen Tests.

Der Parameter des Expert Advisor bei aktivierter Optimierung und Geldentnahme

Abb. 8 Der Parameter des Expert Advisor bei aktivierter Optimierung und Geldentnahme

Ergebnisse der Berechnung der relativen Inanspruchnahme von Eigenkapital

Abb. 9 Ergebnisse der Berechnung der relativen Inanspruchnahme von Eigenkapital

Die Testergebnisse überraschen etwas, da die Inanspruchnahme bei einer Entnahmeperiode von 1 Tag oder 1 Woche geringer ist, als bei komplett deaktivierten Entnahme insgesamt.

Darüber hinaus steigt die Linie der täglichen Inanspruchnahme auf 100% an, sinkt dann auf 8% und fällt weiter. Um diese Ergebnisse korrekt interpretieren zu können, muss man wissen, wie die relative Inanspruchnahme von Eigenkapital im Strategie-Tester berechnet wird. Und damit sind wir beim Thema des nächsten Abschnitts.


5. Berechnung der Inanspruchnahme von Eigenkapital

Wissbegierige Menschen möchten natürlich wissen, wie die Berechnung des Eigenkapitals im Strategie-Tester abläuft und wie sie diesen Parameter selbst berechnen können.

Wird die TesterWithdrawal() Funktion in Ihrem Expert Advisor nicht verwendet, dann unterscheidet sich die Berechnung des Parameters, den wir nun analysieren, in keiner Weise von der in MetaTrader 4 und ist im Beitrag "Was die Zahlen im Expert Testbericht aussagen" beschrieben. Den Quellcode sowie viele andere Parameter des daraus folgenden Tester-Berichts finden Sie im Beitrag "Wie man die Expert-Testergebnisse bewertet".

Eine visuelle Beschreibung der Berechnung von relativer und maximaler Inanspruchnahme im Strategie-Tester wird in Abb. 10 gezeigt.

Berechnung der Inanspruchnahme von Eigenkapital ohne Berücksichtigung von Geldentnahme

Abb. 10 Berechnung der Inanspruchnahme von Eigenkapital ohne Berücksichtigung von Geldentnahme

Während seiner Arbeit legt der Strategie-Tester den aktuellen Maximal- und Minimalwert des Eigenkapitals fest Beim Auftauchen eines neuen Eigenkapital-Maximums, das auf dem Chart mit dem blauen Häkchen gekennzeichnet ist, werden die Maximal- und Minimal-Inanspruchnahmen neu berechnet und der größte Wert wird zur Anzeige in den sich daraus ergebenden Bericht gespeichert.

Das Wichtigste hierbei ist die Neuberechnung der Parameter am Ende des Tests, da es zu einer Situation kommen kann, wenn das letzte, nicht registrierte Extrem des Eigenkapitals den Maximalwert der Inanspruchnahme ergeben kann. Veränderungen der Maximalwerte der Inanspruchnahme sind jeweils rot bzw. blau markiert. Die Farbe grau kennzeichnet die Inanspruchnahme, die bei jedem Auftauchen eines neuen Maximums registriert wird.

Hier muss darauf hingewiesen werden, dass der Aufruf der TesterWithDrawal() Funktion den Berechnungsalgorithmus der Inanspruchnahme im Strategie-Tester verändert. Die Differenz der vorherigen Variante ist die Neuberechnung der Inanspruchnahme-Werte, nicht nur beim Auftauchen neuer Eigenkapital-Maxima, sondern auch bei Kapitalentnahmen. Abb. 11 zeigt das entsprechende Schaubild.

Berechnung der Inanspruchnahme von Eigenkapital unter Berücksichtigung von Geldentnahme

Abb. 11 Berechnung der Inanspruchnahme von Eigenkapital unter Berücksichtigung von Geldentnahme

Der Augenblick der Entnahme von Vermögen ist in der obigen Abbildung mit grünen Häkchen gekennzeichnet. Hier wurde ziemlich häufig Geld entnommen, sodass die Maximalwerte der Inanspruchnahme, die von den Extrema auf dem Chart festgelegt sind, nicht festgesetzt werden können. Als Folge kann die sich daraus ergebende Inanspruchnahme unter Berücksichtigung von Geldentnahme geringer sein als die ohne solche Berücksichtigung, worauf in Abb. 9 hingewiesen wurde.

Ist die Entnahme von Geld viel höher als das Eigenkapitalwachstum infolge erwirtschafteten Gewinns, kann dies niedrige Inanspruchnahme-Raten zur Folge haben. Der Grund dafür liegt darin, dass diese Situation den Extrema nicht gestattet, sich auf dem Chart abzubilden und im Grenzfall sich eine direkt absteigende Linie zeigt, in der die relative Inanspruchnahme gegen Null läuft. Dieser Effekt hat begonnen, als es zu täglichen Entnahmen von mehr als USD1000 auf dem in Abb. 9 gezeigten Chart kam.

Versuchen wir die Berechnung der maximalen und relativen Inanspruchnahme von Eigenkapital in MQL5 nachzuvollziehen, indem wir den gesamten Algorithmus in einen einzigen CalcEquityDrawdown Vorgang packen, wie unten beschrieben.

double RelEquityDrawdownPercent; // relative drawdown of equity in percentage terms
double MaxEquityDrawdown;        // maximal drawdown of equity
//--- Calculation of the drawdown of equity
//+------------------------------------------------------------------+
void CalcEquityDrawdown(double initial_deposit, // initial deposit
                        bool finally)          // flag of calculation that registers extremums
//+------------------------------------------------------------------+
  {
   double drawdownpercent;
   double drawdown;
   double equity;
   static double maxpeak = 0.0, minpeak = 0.0;

   //--- exclusion of consideration of profit withdrawals for the calculation of drawdowns
   if(wdr_ignore) equity = AccountInfoDouble(ACCOUNT_EQUITY) + wdr_summa;
   else equity = AccountInfoDouble(ACCOUNT_EQUITY);

   if(maxpeak == 0.0) maxpeak = equity;
   if(minpeak == 0.0) minpeak = equity;

   //--- check of conditions of extremum
   if((maxpeak < equity)||(finally))
    {
      //--- calculation of drawdowns
      drawdown = maxpeak - minpeak;
      drawdownpercent = drawdown / maxpeak * 100.0;

      //--- Saving maximal values of drawdowns
      if(MaxEquityDrawdown < drawdown) MaxEquityDrawdown = drawdown;
      if(RelEquityDrawdownPercent < drawdownpercent) RelEquityDrawdownPercent = drawdownpercent;
    
      //--- nulling the values of extremums
      maxpeak = equity;
      minpeak = equity;
    }

   if(minpeak > equity) minpeak = equity;
 }

Damit die Berechnungen exakt bleiben, müssen wir den oben geschriebenen Vorgang mit den unten gezeigten Parametern vom Korpus unseres Expert Advisors aus aufrufen, und war jedes Mal, wenn eine neue Kursschwankung auftritt.

CalcEquityDrawdown(initial_deposit, false);

Und um zusätzlich die zuverlässigen Werte der Inanspruchnahmen zu bekommen, sollte er zudem am Ende des Expert Advisors in der OnTester() Funktion mit den finally = true Parametern aufgerufen werden, um anzuzeigen, dass die Berechnung abgeschlossen ist. Und sollte die aktuell nicht festgelegte Inanspruchnahme größer als der registrierte Maximalwert sein, wird dieser Wert dadurch ersetzt und erscheint im sich ergebenden Bericht.

CalcEquityDrawdown(initial_deposit, true);

Wird der Entnahme-Algorithmus in einen Expert Advisor implementiert, muss für eine korrekte Berechnung der Inanspruchnahmen die CalcEquityDrawdown-Funktion mit dem finally=true Parameter jedes Mal dann aufgerufen werden, wenn eine solche Entnahme durchgeführt wird. Die Reihenfolge der Aufrufe kann folgendermaßen aussehen:

//--- Withdrawing assets and calculating drawdowns of equity
if(TimeOfWithDrawal())
    CalcEquityDrawdown(initial_deposit, true);
else 
    CalcEquityDrawdown(initial_deposit, false);

Um bei der oben beschriebenen Methode auch wirklich sicherzugehen, dass sie korrekt ist, vergleichen wir die errechneten Daten mit den Daten des Strategie-Testers. Dazu müssen wir die OnTester() Funktion veranlassen, den Wert des Parameters zu liefern, den wir überprüfen wollen - die relative Inanspruchnahme von Eigenkapital, der in der Variable RelEquityDrawdownPercent gepeichert ist.

Sie wird in den Expert Advisor-Code implementiert, indem wir für den "Optimierung durch Parameter" Eingabeparameter den Wert "Inanspruchnahme unter Berücksichtigung der Entnahme" setzen. Alle übrigen Parameter sollten, so wie in Abb. 8 gezeigt, unverändert bleiben. Die Ergebnisse dieses Tests sind in Abb. 12 gezeigt.

Vergleich der Ergebnisse unserer Berechnungen mit den Daten des Strategie-Testers

Abb. 12 Vergleich der Ergebnisse unserer Berechnungen mit den Daten des Strategie-Testers

Der Vergleich der erhaltenen Ergebnisse zeigt, dass der Berechnungsalgorithmus der relativen Inanspruchnahme korrekt ist.

Ergänzen wir die Berechnung der Inanspruchnahme noch durch eine weitere Variante. In ihr werden wir die Auswirkung von Geldentnahmen auf das Eigenkapital ausschließen und die Änderungen der relativen Inanspruchnahme von Eigenkapital beobachten.

Dazu müssen wir den Expert Advisor um eine Variable ergänzen, die wir zur Bestimmung verwenden, ob es notwendig ist, die Geldentnahmen bei der Berechnung der Parameter des Expert Advisors zu berücksichtigen.

bool wdr_ignore; // calculation of rate without the consideration of withdrawals

Der Wert von wdr_ignore = true, wenn die "Optimierung durch den Parameter" Variable auf "Inanspruchnahme ohne Berücksichtigung der Entnahme" gesetzt ist.

Übrigens müssen Sie hier den Berechnungsvorgang der Inanspruchnahme CalcEquityDrawdown korrigieren, indem Sie die Bearbeitung des Parameters durch ihn, wo wie unten gezeigt, hinzufügen.

if (wdr_ignore) 
  equity = AccountInfoDouble(ACCOUNT_EQUITY) + wdr_summa;
else 
  equity = AccountInfoDouble(ACCOUNT_EQUITY);

so jetzt stimmt alles und wir sind gespannt, welche neuen Werte für Inanspruchnahme wir erhalten. Führen wir jetzt einen Test mit dem neuen Berechnungsalgorithmus aktiviert, durch. Das Testergebnis sehen Sie in Abb. 13.

Ergebnisse der Berechnung von Inanspruchnahme ohne Berücksichtigung von Geldentnahme

Abb. 13 Ergebnisse der Berechnung von Inanspruchnahme ohne Berücksichtigung von Geldentnahme

Die Ergebnisse zeigen, dass weder die Tatsache, dass Vermögen entnommen wurde, noch der entnommene Betrag von der Inanspruchnahme abhängen. Somit haben wir einen reinen Faktor erhalten, der nicht von der TesterWithDrawal() Funktion beeinflusst wird. Um jedoch diese Art der Berechnung verwenden zu können, müssen wir die Werte von Profit und Loss berichtigen, da sich ihre echten Werte verändert haben - und diese Faktoren im sich ergebenden Bericht des Testers nicht korrekt sein werden.

Berechnen wir also Profit, Loss und ihr Verhältnis (Rentabilität) und speichern die erhaltenen Werte als Bericht in einer Textdatei ab. Der Berechnungsvorgang der aufgeführten Parameter ist unten gezeigt.

double SummaryProfit;     // Total net profit
double GrossProfit;       // Gross profit
double GrossLoss;         // Gross loss
double ProfitFactor;      // Profitability
//--- Calculation of parameters for the report
//+------------------------------------------------------------------+
void CalculateSummary(double initial_deposit)
//+------------------------------------------------------------------+
  {
   double drawdownpercent, drawdown;
   double maxpeak = initial_deposit, 
          minpeak = initial_deposit, 
          balance = initial_deposit;
          
   double profit = 0.0;
   
   //--- Select entire history
   HistorySelect(0, TimeCurrent());
   int trades_total = HistoryDealsTotal();

   //--- Searching the deals in the history
   for(int i=0; i < trades_total; i++)
     {
      long ticket = HistoryDealGetTicket(i);
      long type   = HistoryDealGetInteger(ticket, DEAL_TYPE);

      //--- Initial deposit is not considered
      if((i == 0)&&(type == DEAL_TYPE_BALANCE)) continue;

      //--- Calculation of profit
      profit = HistoryDealGetDouble(ticket, DEAL_PROFIT) +
                 HistoryDealGetDouble(ticket, DEAL_COMMISSION) +
               HistoryDealGetDouble(ticket, DEAL_SWAP);
      
      balance += profit;

      if(minpeak > balance) minpeak = balance;

      //---
      if((!wdr_ignore)&&(type != DEAL_TYPE_BUY)&&(type != DEAL_TYPE_SELL)) continue;

      //---
      if(profit < 0) GrossLoss   += profit;
      else           GrossProfit += profit;
      SummaryProfit += profit;
     }

   if(GrossLoss < 0.0) GrossLoss *= -1.0;
   //--- Profitability
   if(GrossLoss > 0.0) ProfitFactor = GrossProfit / GrossLoss;
  }

Funktion zur Erzeugung des Berichts in einer Textdatei ist ebenfalls unten gezeigt.

//--- Forming the report  
//+------------------------------------------------------------------+
void GenerateReportFile(string filename)
//+------------------------------------------------------------------+
  {
   string str, msg;

   ResetLastError();
   hReportFile = FileOpen(filename, FILE_READ|FILE_WRITE|FILE_TXT|FILE_ANSI);
   if(hReportFile != INVALID_HANDLE)
     {

      StringInit(str,65,'-'); // separator

      WriteToReportFile(str);
      WriteToReportFile("| Period of testing: " + TimeToString(first_tick.time, TIME_DATE) + " - " +
                        TimeToString(tick.time,TIME_DATE) + "\t\t\t|");
      WriteToReportFile(str);

      //----
      WriteToReportFile("| Initial deposit \t\t\t"+DoubleToString(initial_deposit, 2));
      WriteToReportFile("| Total net profit    \t\t\t"+DoubleToString(SummaryProfit, 2));
      WriteToReportFile("| Gross profit     \t\t\t"+DoubleToString(GrossProfit, 2));
      WriteToReportFile("| Gross loss      \t\t\t"+DoubleToString(-GrossLoss, 2));
      if(GrossLoss > 0.0)
         WriteToReportFile("| Profitability       \t\t\t"+DoubleToString(ProfitFactor,2));
      WriteToReportFile("| Relative drawdown of equity \t"+
                        StringFormat("%1.2f%% (%1.2f)", RelEquityDrawdownPercent, MaxEquityDrawdown));

      if(WDR_ENABLE)
        {
         StringInit(msg, 10, 0);
         switch(WDR_PERIOD)
           {
            case day:     msg = "day";    break;
            case week:    msg = "week";  break;
            case month:   msg = "month";   break;
            case quarter: msg = "quarter"; break;
            case year:    msg = "year";     break;
           }

         WriteToReportFile(str);
         WriteToReportFile("| Periodicity of withdrawing       \t\t" + msg);

         if(WDR_TYPE == fixed) msg = DoubleToString(WDR_VALUE, 2);
         else msg = DoubleToString(WDR_VALUE, 1) + " % from deposit " + DoubleToString(initial_deposit, 2);

         WriteToReportFile("| Amount of money withdrawn     \t\t" + msg);
         WriteToReportFile("| Number of withdrawal operations \t\t" + IntegerToString(wdr_count));
         WriteToReportFile("| Withdrawn from account          \t\t" + DoubleToString(wdr_summa, 2));
        }

      WriteToReportFile(str);
      WriteToReportFile(" ");

      FileClose(hReportFile);
     }
  }

Das Ergebnis der Ausführung dieser Funktion ist die Erzeugung einer Textdatei voller Informationen, wie Abb. 14 es zeigt.

Durch den GenerateReportFile Vorgang erzeugte Berichtsdatei

Abb. 14 Durch den GenerateReportFile Vorgang erzeugte Berichtsdatei

Die Funktion ist so geschrieben, dass jeder neue Bericht dem bereits bestehenden Inhalt der Datei hinzugefügt werden kann. Aufgrund dieser Tatsache können wir nun die Werte der Ergebnisse der Tests des Expert Advisors mit unterschiedlichen Eingabeparameters vergleichen.

Und wie aus dem Bericht klar ersichtlich, ist der gesamte Netto-Gewinn bei der Berechnung ohne Berücksichtigung der Entnahmen (untere Tabelle) kleiner und der Brutto-Verlust ist um den entnommenen Geldbetrag Größer, verglichen mit der Berechnung des Testers (obere Tabelle). Hier muss darauf hingewiesen werden, dass man den Wert des "Entnahme" Parameters vom gesamten Netto-Gewinn abziehen und zum Brutto-Verlust addieren muss, wenn man den echten Wert von Gewinn und Verlust bei der Entnahme von Vermögen im Strategie-Tester erhalten möchte.


6. Analyse des Ergebnisses

Auf Grundlage der aus allen durchgeführten Experimenten erhaltenen Ergebnisse, können wir mehrere Schlussfolgerungen ziehen

  1. Die Verwendung der TesterWithDrawal() Funktion führt zu den Veränderungen im Berechnungsalgorithmus der Inanspruchnahmen im Strategie-Tester. Ein Vergleich verschiedener Expert Advisors vor dem Hintergrund des Werts der relativen Inanspruchnahme kann inkorrekt sein, sobald einer dieser Experts den Mechanismus zur Entnahme von Geld enthält. Mit Hilfe dieser Funktion können Sie eine eine pragmatische Berechnung aufstellen, wie viel Geld Sie in regelmäßigen Intervallen vom Account entnehmen, abhängig vom festgelegten, akzeptablen Prozentsatz der Inanspruchnahme von Eigenkapital.
  2. Mit Hilfe dieser Funktion können Sie einen synthetischen, destabilisierenden Handelsfaktor implementieren, der zur Prüfung der stabilen Arbeit Ihres Expert Advisors verwendet wird und zur Anpassung der Logik des Codes, der für die Geldverwaltung verantwortlich ist. Falls Ihr Expert Advisor eine Logik besitzt, Entscheidungen auf Basis von Saldo- oder Eigenkapitallevels zu treffen, bietet der Einsatz dieser Funktion noch zusätzliche Möglichkeiten für Tests und Feinabstimmung.
  3. Bei der Berechnung der relativen Inanspruchnahme ohne Berücksichtigung von Geldentnahmen unter Verwendung des in diesem Beitrag beschriebnen Algorithmus, erhalten Sie den reinen Wert der relativen Inanspruchnahme, die nicht von der Verwendung dieser Funktion betroffen ist.


Fazit

Dieser Beitrag hat die Verwendung der TesterWithdrawal() Funktion zur Nachahmung des Entnahmevorgangs von Vermögen aus einem Account sowie ihren Einfluss auf den Berechnungsalgorithmus der Inanspruchnahme von Eigenkapital im Strategie-Tester behandelt.

Übersetzt aus dem Russischen von MetaQuotes Software Corp.
Originalartikel: https://www.mql5.com/ru/articles/131

Beigefügte Dateien |
testexpert.mq5 (33.95 KB)
Der Einsatz von MQL5 Standard Library Handelsklassen beim Schreiben eines Expert Advisors Der Einsatz von MQL5 Standard Library Handelsklassen beim Schreiben eines Expert Advisors

Dieser Beitrag beschreibt die Verwendung der Hauptfunktionalitäten der MQL5 Standard Library Handelsklassen beim Schreiben des Expert Advisors, die das Schließen und die Änderung von Positions, Platzierung und Löschung von pending Orders sowie die Prüfung nach Margen vor dem Platzieren eines Handels implementieren. Es wird auch gezeigt, wie man mit Hilfe von Handelsklassen Details zu Orders und Abschlüssen bekommen kann.

Test-Performance der Berechnung von gleitenden Mittelwerten in MQL5 Test-Performance der Berechnung von gleitenden Mittelwerten in MQL5

Seit der Erstellung des ersten Moving-Average-Indikators ist eine Vielzahl von Indikatoren erschienen. Viele von ihnen nutzen ähnliche Glättungsmethoden, doch die Glättung der unterschiedlichen Algorithmen von gleitenden Mittelwerten wurde nie eingehend studiert. In diesem Beitrag betrachten wir Möglichkeiten zur Nutzung der gleitenden Mittelwerte in MQL5 und vergleichen ihre Performance.

Die optimale Berechnungsmethode für das Gesamtvolumen an Positions nach der festgelegten Magischen Zahl Die optimale Berechnungsmethode für das Gesamtvolumen an Positions nach der festgelegten Magischen Zahl

In diesem Beitrag geht es um das Problem der Berechnung des Gesamtvolumen an Positions nach festgelegtem Symbol und magischer Zahl. Die hier vorgestellte Methode verlangt nur den minimal notwendigen Teil der Abschluss-History, ermittelt den nächsten Zeitpunkt, als die Gesamtposition gleich Null war und führt Berechnungen an den jüngsten Abschlüssen aus. Des Weiteren wird hier ebenfalls die Arbeit mit globalen Variablen des Client-Terminals behandelt.

Prinzipien der wirtschaftlichen Berechnung von Indikatoren Prinzipien der wirtschaftlichen Berechnung von Indikatoren

Aufrufe von benutzerdefinierten und technischen Indikatoren nehmen im Programmcode von automatisierten Handelssystemen nur wenig Platz ein. Oft sind es nur ein paar Codezeilen. Doch oft sind es genau diese paar Codezeilen, die die meiste Zeit beim Testen des Expert Advisors benötigen. Deshalb muss alles, was mit der Berechnung von Daten in einem Indikator zusammenhängt, viel eingehender betrachtet werden, als es auf den ersten Blick als nötig erscheint. Genau das ist das Thema dieses Beitrags.