English Русский Español Português
preview
Entwicklung eines Multi-Currency Expert Advisors (Teil 28): Hinzufügen eines Managers zum Schließen von Positionen

Entwicklung eines Multi-Currency Expert Advisors (Teil 28): Hinzufügen eines Managers zum Schließen von Positionen

MetaTrader 5Beispiele |
11 0
Yuriy Bykov
Yuriy Bykov

Einführung

In Teil 12 haben wir dem Multi-Currency EA ein Risikomanager-Modul hinzugefügt, um den täglichen und den gesamten Drawdown zu begrenzen. Es erhöht zwar nicht die Gewinne, ist aber entscheidend für den Schutz der Gelder unter widrigen Bedingungen. Es basiert auf Prop-Trading-Regeln mit flexiblen Einstellungen: Drawdown in Währung, als Prozentsatz des Guthabens oder ab Tagesbeginn.

Das Modul ist als Klasse CVirtualRiskManager implementiert, mit Methoden zur Verfolgung von Guthaben, und Gewinn und zur Überprüfung von Begrenzungen. Eine Gewinnmitnahmefunktion ist ebenfalls vorhanden: Sobald das Ziel erreicht ist, werden alle Positionen geschlossen und der Handel gestoppt.

Für reguläre Konten wäre es vorzuziehen, wenn der Handel automatisch neu gestartet würde, sobald das Gewinnziel erreicht ist. Derzeit erfordert dies ein manuelles Eingreifen. Es ist an der Zeit, auch dies zu automatisieren.

Ich habe zwei Optionen für den Neustart von Handelsstrategien beim Erreichen des Zielgewinns in Betracht gezogen:

  • Erweiterung des aktuellen Risikomanagers,
  • Erstellung eines separaten Moduls.

Ich habe mich für den zweiten Weg entschieden, da der aktuelle Risikomanager unabhängig von den Strategien arbeitet: Er schließt nur reale Positionen, ohne die virtuellen zu beeinflussen. Eine Änderung dieser Logik würde die Architektur verkomplizieren und die modulare Unabhängigkeit verletzen.

Der Risikomanager erzeugt zudem zusätzlichen Testaufwand, daher ist es besser, die neue Funktionalität in ein separates Modul zu verschieben – sie kann auch ohne den laufenden Risikomanager verwendet werden.

Das Ziel ist ein Modul, das alle Strategien automatisch neu starten kann, sobald bestimmte Bedingungen (Gewinn, Verlust, Zeit usw.) erfüllt sind, ohne auf die Handelshistorie angewiesen zu sein und ohne manuelles Eingreifen. Ich werde das neue Modul Closing-Manager nennen, da es ein separates, optionales Modul ist, dessen Hinzufügung jedoch die Ergebnisse verbessern kann und das den Prozess des vollständigen Schließens aller Positionen, sowohl realer als auch virtueller, verwaltet.


Grundanforderungen

Lassen Sie uns die Verantwortlichkeiten und Parameter des Closing-Managers klarer formulieren. 

Der Closing-Manager sollte:

  1. Gewinnmitnahme bedeutet, dass alle virtuellen Positionen geschlossen werden, wenn der festgelegte Gewinn erreicht ist. In diesem Fall werden reale Positionen ebenfalls automatisch geschlossen. Dafür führen wir drei Parameter ein:
    • Basisguthaben: Der Geldbetrag auf dem Handelskonto, der als Referenzguthaben für die Berechnung von Gewinn oder Verlust dient.
    • Gewinnberechnungsmethode: Sie kann einen von mehreren möglichen Werten annehmen, zum Beispiel als Prozentsatz des Basisguthabens oder als fester Betrag in der Kontowährung .
    • Gewinnwert: Der Wert, der zur Berechnung des Gewinns mit der gewählten Methode verwendet wird.
  2. Verlustbegrenzung, was bedeutet, dass alle virtuellen Positionen geschlossen werden, wenn ein festgelegter Verlust erreicht ist. Dieser Prozess erfordert ebenfalls drei Parameter, von denen einer oder zwei mit den Parametern für die Gewinnmitnahme geteilt werden können:
    • Basisguthaben: Der Geldbetrag auf dem Handelskonto, der als Referenzguthaben für die Berechnung von Gewinn oder Verlust dient.
    • Verlustberechnungsmethode: Sie kann ebenfalls einen von mehreren möglichen Werten annehmen, wie bei der Methode zur Gewinnberechnung.
    • Verlustwert: Der Wert, der zur Berechnung des Verlusts mit der gewählten Methode verwendet wird.
  3. Profit-Trailing aktivieren beim Erreichen des festgelegten Gewinns werden virtuelle Positionen nicht geschlossen, sondern ein bestimmtes niedrigeres Gewinnniveau wird gesichert, bei dem die Positionen tatsächlich geschlossen werden. Wenn die Gewinne steigen, sollte auch dieses Niveau steigen. Der Anstieg kann entweder kontinuierlich oder in Schritten mit einem bestimmten Inkrement erfolgen. Für diesen Prozess können die folgenden Parameter hinzugefügt werden:
    • Trailing aktivieren (Ja / Nein).
    • Niveaueinstellungsmethode: In diesem Parameter können wir die bevorzugte Methode zur Einstellung des Trailing-Aktivierungsniveaus auswählen. Zum Beispiel kann das Niveau als Prozentsatz des festen Gewinns oder als absoluter Wert in der Währung des Handelskontos festgelegt werden.
    • Trailing-Startniveau: Die Zahl, die zur Berechnung des Trailing-Startniveaus für die gewählte Methode verwendet wird.
    • SchrittweiteDas Niveau, bei dem die Trailing-Schwelle verschoben wird. Für die Berechnung können wir dieselbe Methode wie für das Trailing-Startniveau verwenden.
  4. Breakeven-Niveau aktivieren wenn der Gewinn diesen Wert erreicht, sichern wir ein bestimmtes kleines positives Gewinnniveau, bei dem die Positionen geschlossen werden. Bei einem weiteren Gewinnanstieg wird dieses Niveau im Gegensatz zum Trailing nicht steigen. Die Parameter, die diesen Prozess steuern, können wie folgt lauten:
    • Breakeven aktivieren (Ja / Nein).
    • Niveaueinstellungsmethode: Dieser Parameter ähnelt dem gleichnamigen Parameter für Trailing, was bedeutet, dass er ebenfalls entweder relativ oder absolut sein kann.
    • Breakeven-AktivierungsniveauDie Zahl, die zur Berechnung des Breakeven-Niveaus für die gewählte Methode verwendet wird.
Konzentrieren wir uns vorerst auf diese grundlegende Funktionalität, die weiterentwickelt werden kann. Es ist möglich, dass wir während der Implementierung den Parametern etwas hinzufügen oder deren Zusammensetzung anderweitig ändern müssen. Aber zunächst konzentrieren wir uns auf diese Aufgabenbeschreibung.


Projekt-Repository

In Teil 25 haben wir eine neue Strategie hinzugefügt und uns angesehen, wie man ein Projekt erstellt, um die ausgewählte Strategie automatisch zu optimieren und einen endgültigen EA zu erstellen, der mehrere Instanzen von Handelsstrategien mit unterschiedlichen Parametern enthält. Der gesamte Code wurde in zwei Teile unterteilt Bibliothek und Projekt. Für den Bibliotheksteil enthält Teil 26 bereits das öffentliche Code-Repository Adwizard im Speicher von MQL5-Algo-Forge. Für das Projekt wurde dies jedoch noch nicht getan.

Korrigieren wir dies nun und erstellen das neue Repository SimpleCandles. Dieses Repository wird den Projektteil für die Erstellung des endgültigen EA unter Verwendung von Strategien mit demselben Namen enthalten. Neben dem Branch main werden wir auch einen Entwicklungs-Branch namens develop einführen. Wenn dieses Projekt mehreren Artikeln gewidmet ist, werden die Bearbeitungen, die sich auf verschiedene Artikel beziehen, auf verschiedene Branches verteilt, die aus dem Branch develop generiert werden. Sobald sie fertig sind, werden sie wieder in die Branches develop und main zusammengeführt.

Erstellen wir einen lokalen Ordner, der den Projektordner enthält, zum Beispiel MQL5/Experts/Articles/17608. Wir klonen dieses Repository in den ausgewählten Ordner und erstellen darin den Ordner Include. In diesem Ordner platzieren wir das Repository des Bibliotheksteils, von dem dieses Projekt abhängt. Der Ordner Include enthält den Klon des Repositorys der Adwizard-Bibliothek.

Schließlich erhalten wir ungefähr die folgende Ordnerstruktur im Terminalordner:

Abb. 1. Die Ordnerstruktur im Projekt-Repository nach dem Klonen der Projekt- und Bibliotheksteile

Wechseln wir im geklonten Ordner des Adwizard-Repositorys, zum Branch develop. Dieser Branch wird gemeinsam von allen Artikeln verwendet. Da wir jedoch an diesem Projekt arbeiten, werden wir Änderungen an der Adwizard-Bibliothek vornehmen. Daher werden wir in diesem Repository einen neuen Branch erstellen, der aus dem develop-Branch generiert wird.

Erstellen wir danach einen separaten Branch für die Arbeit an diesem Artikel im SimpleCandles-Projekt-Repository und beginnen Sie mit der Entwicklung.


Vorbereiten des Bibliothekscodes

Bereiten wir den Boden für die Implementierung des Closing-Managers. Zunächst sollten wir anmerken, dass die neuesten MetaTrader-Builds eine strengere Überprüfung der Variablentypen hinzugefügt haben, weshalb zuvor kompilierter Code nun Fehler des folgenden Typs erzeugt:

parameter convertion type 'short[260]' to 'ushort[] &' is not allowed   MTTester.mqh    
   int user32::GetClassNameW(long,ushort&[],int)        winuser.mqh     

Glücklicherweise trat dies im verwendeten Code nur einmal auf und wurde durch Ändern des Array-Typs behoben: 

static string GetClassName( const HANDLE Handle )
  {
    string Str = NULL;

    ushort Buffer[MAX_PATH] = {0};

    if (user32::GetClassNameW(Handle, Buffer, ::ArraySize(Buffer)))
      Str = ::ShortArrayToString(Buffer);

    return(Str);
  }

Nach dem nächsten Terminal-Update wurde diese Datei jedoch vollständig durch die neueste Version aus der MultiTester-Bibliothek ersetzt, um ein fehlerhaftes Verhalten zu beheben, das eine andere Ursache hat.

Die nächste Änderung bezieht sich auf die Notwendigkeit für den Closing-Manager, das Schließen aller Positionen zu initiieren. Fügen wir der EA-Klasse CVirtualAdvisor eine separate Methode zum Schließen aller Positionen hinzu, damit der Closing-Manager sie bei Bedarf aufrufen kann.

Um diese Methode zu implementieren, haben wir bereits alles, was wir brauchen: Jede von CVirtualStrategy abgeleitete Strategie verfügt über eine Methode zum Schließen all ihrer virtuellen Positionen. Daher müssen wir in der EA-Klasse diese Methode nur für jede Strategie aufrufen:

//+------------------------------------------------------------------+
//| Close positions of all strategies                                |
//+------------------------------------------------------------------+
void CVirtualAdvisor::Close(void) {
// For all strategies, we call the method for closing virtual positions
   FOREACH(m_strategies) ((CVirtualStrategy *)m_strategies[i]).Close();
}

In Teil 27 haben wir eine Komponente zur Anzeige von mehrzeiligem Text in einem Fenster erstellt, das sich über das gesamte Chart erstreckt, an das der EA angehängt ist. Sie wurde als Teil eines anderen Projekts erstellt, wird uns hier aber ebenfalls nützlich sein. Verschieben wir sie also in die Adwizard-Bibliothek und legen die Datei mit der CConsoleDialog-Klasse im Ordner Adwizard/Utils ab. Um sie zu verwenden, fügen wir die Erstellung eines Objekts dieser Klasse in der Datei Adwizard/Experts/Expert.mqh der EA-Klasse hinzu:

CConsoleDialog      *dialog;             // Dialog for displaying text with results

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
// ...

// Create and launch a dialog to display the results
   dialog = new CConsoleDialog();
   dialog.Create(__NAME__ + ":" + (string) magic_);
   dialog.Run();

// Successful initialization
   return(INIT_SUCCEEDED);
}

In der Funktion zur Verarbeitung eines neuen Ticks in derselben Datei fügen wir das Setzen von neuem Text für dieses Objekt hinzu. Den Text selbst erhalten wir aus der CVirtualAdvisor-Klasse, indem wir deren Text()-Methode aufrufen, die wir im weiteren Verlauf implementieren werden:

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {
   expert.Tick();

// ...

// Display text with information about the EA operation
   if (IsNewBar(Symbol(), PERIOD_M1)) {
      dialog.Text(expert.Text());
   }
}

Um zu verhindern, dass die Linien für das Öffnen virtueller Positionen vor dem Hintergrund des Textes gezeichnet werden, deaktivieren wir vorübergehend deren Visualisierung, indem wir die CVirtualChartOrder::Show()-Methode leer lassen:

//+------------------------------------------------------------------+
//| Show virtual position (order)                                    |
//+------------------------------------------------------------------+
void CVirtualChartOrder::Show() {
   return;

   // ...
}


IsActive-Eigenschaft für alle Nachfahren von CFactorable

Wenn eine Optimierung bei Handelsinstrumenten durchgeführt wird, die Kryptowährungen beinhalten, und der Start bei einem Broker erfolgt, der keine Kryptowährungen unterstützt, kann beim Starten des endgültigen EAs ein Fehler auftreten. Dies beinhaltet den Versuch, die Handelshistorie und die Eigenschaften eines Symbols abzurufen, das nicht in der Marktübersicht enthalten ist. In diesem Fall, wenn der endgültige EA eine große Anzahl von Handelsstrategie-Instanzen enthält, die auf den verfügbaren Symbolen arbeiten, können wir einfach Strategien für die Instrumente deaktivieren, die nicht in der Marktübersicht enthalten sind.

Derzeit sind alle Handelsstrategien Nachfahren der Klasse CFactorable, was es ermöglicht, Objekte dieser Strategien aus dem Initialisierungs-String zu erstellen. Diese Klasse berücksichtigt die Möglichkeit, dass der Initialisierungs-String möglicherweise nicht vollständig korrekt ist. Dann werden dieses Objekt und alle vorherigen Objekte aus dem gemeinsamen Initialisierungs-String als ungültig betrachtet. In dieser Situation wird der EA nicht in der Lage sein, zu initialisieren und seine Arbeit fortzusetzen.

Was wir uns wünschen, ist, dass eine bestimmte Art von „Fehler“ im Initialisierungs-String es uns ermöglicht, einen Teil des Initialisierungs-Strings einfach zu ignorieren und letztendlich ein EA-Objekt aus dem vollständigen Initialisierungs-String zu erstellen. Um dies zu erreichen, fügen wir der Klasse CFactorable eine neue Eigenschaft namens m_isActive sowie die Methode IsActive() zum Lesen ihres Wertes hinzu:

//+------------------------------------------------------------------+
//| Base class of objects created from a string                      |
//+------------------------------------------------------------------+
class CFactorable {
private:
   // ...

protected:
   // ...
   
   bool              m_isActive; // Is the object active?

   // ...

public:
   // ...

   bool              IsActive();                         // Is the object active?

   // ...
};

Eine solche Eigenschaft existierte bereits für einige Klassen, wie z. B. die CVirtualRiskManager Risikomanager-Klasse. Daher werden wir in diesen Klassen ihre Deklaration entfernen, da sie in der Basisklasse vorgenommen wird. Dies gilt auch für die zukünftige Closing-Manager-Klasse, die diese Eigenschaft ebenfalls verwenden wird, um zu prüfen, ob sie aktiv ist.

Gleichzeitig haben wir die Angabe des Risikomanagers und des Closing-Managers im Initialisierungs-String optional gemacht, indem wir eine Überprüfung auf deren Vorhandensein beim Starten des EA im Konstruktor der Klasse CVirtualAdvisor hinzugefügt haben:

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CVirtualAdvisor::CVirtualAdvisor(string p_params) {
// Save the initialization string
   m_params = p_params;

// Read the initialization string of the strategy group object
   string groupParams = ReadObject(p_params);

// Read the initialization string of the risk manager object
   string riskManagerParams = NULL;

   if(IsObjectOf(p_params, "CVirtualRiskManager")) {
      riskManagerParams = ReadObject(p_params);
   }

// Read the initialization string of the closing manager object
   string closeManagerParams = NULL;
   if(IsObjectOf(p_params, "CVirtualCloseManager")) {
      closeManagerParams = ReadObject(p_params);
   }

// Read the magic number
   ulong p_magic = ReadLong(p_params);

// Read the EA name
   string p_name = ReadString(p_params);

// Read the work flag only at the bar opening
   m_useOnlyNewBar = (bool) ReadLong(p_params);

// If there are no read errors,
   if(IsValid()) {
// Create a strategy group
      CREATE(CVirtualStrategyGroup, p_group, groupParams);

      // Initialize the symbol monitor with a static symbol monitor
      m_symbols = CSymbolsMonitor::Instance();

      // Initialize the receiver with the static receiver
      m_receiver = CVirtualReceiver::Instance(p_magic);

      // Initialize the interface with the static interface
      m_interface = CVirtualInterface::Instance(p_magic);

      // Form the name of the EA database file for saving the state from the EA name and parameters
      m_fileName = FileName(p_name, p_magic);

      // Save the work (test) start time
      m_fromDate = TimeCurrent();

      // Reset the last save time
      m_lastSaveTime = 0;

      // Add the contents of the group to the EA
      Add(p_group);

      // Remove the group object
      delete p_group;

      // Create the risk manager object
      if(riskManagerParams != NULL) {
         m_riskManager = NEW(riskManagerParams);
      }

      // Create the closing manager object
      if(closeManagerParams != NULL) {
         m_closeManager = NEW(closeManagerParams);
         m_closeManager.Expert(&this);
      }
   }
}

Nachdem wir die Änderungen vorgenommen haben, kommen wir zum Hauptteil der Erstellung des Closing-Managers.


Erstellung des Closing-Managers

Zunächst wollen wir einige mögliche Zustände hervorheben, in denen sich der Closing-Manager befinden kann. In einem normalen Zustand wurden weder der geplante Gewinn noch der maximale Verlust erreicht. Während er sich in diesem Zustand befindet, muss der Closing-Manager nur auf den Übergang in einen von mehreren nachfolgenden Zuständen warten. Beim Erreichen eines festgelegten Gewinns oder Verlusts wird ein Übergang in zwei entsprechende Zustände durchgeführt. In diesen Zuständen sollte der Closing-Manager alle Positionen schließen, sich die neuen Niveaus des festgelegten Gewinns und Verlusts merken und in den normalen Zustand zurückkehren.

Wenn das Trailing aktiviert ist, schaltet der Closing-Manager beim Erreichen des festgelegten Gewinnniveaus in einen anderen Zustand um. Der Übergang zurück in einen normalen Zustand erfordert komplexere Aktionen, daher werden wir diese vorerst nicht im Detail beschreiben.

Wir implementieren alle Zustände als Aufzählungstyp ENUM_CM_STATE.

Um die Methoden zur Berechnung von geplantem Gewinn und Verlust zu definieren, erstellen wir außerdem zwei separate Aufzählungstypen: ENUM_CM_CALC_LOSS und ENUM_CM_CALC_PROFIT. Betrachten wir zwei Optionen: einen festen Wert in monetären Einheiten und einen relativen Wert als Prozentsatz eines bestimmten Basisguthabens.

// Possible states of the closing manager
enum ENUM_CM_STATE {
   CM_STATE_OK,            // Limits are not exceeded
   CM_STATE_LOSS,          // Overall limit exceeded
   CM_STATE_PROFIT,        // Total profit reached
   CM_STATE_TRAIL_PROFIT   // Profit trailing
};

// Possible methods for calculating total loss
enum ENUM_CM_CALC_LOSS {
   CM_CALC_LOSS_MONEY_BB,           // [$] Fixed Money
   CM_CALC_LOSS_PERCENT_BB,         // [%] of Base Balance
};

// Possible methods for calculating total profit
enum ENUM_CM_CALC_PROFIT {
   CM_CALC_PROFIT_MONEY_BB,           // [$] Fixed Money
   CM_CALC_PROFIT_PERCENT_BB,         // [%] of Base Balance
};

Die Closing-Manager-Klasse selbst wird von der Basisklasse CFactorable abgeleitet, um die Möglichkeit zu bieten, das Closing-Manager-Objekt aus der Initialisierungszeichenfolge zu erstellen. Gleichzeitig verfügt sie sofort über eine vererbte Aktivitätseigenschaft, um den Closing-Manager einfach zu aktivieren oder zu deaktivieren.

Um diese Aufgabe ausführen zu können, muss sich der Closing-Manager das Niveau des Basisguthabens merken, von dem aus der resultierende Gewinn oder Verlust berechnet wird. Beim Realisieren eines Gewinns oder Verlusts sollte sich dieses Niveau ebenfalls auf den Wert des aktuellen Guthabens ändern, der nach dem Schließen aller Positionen erreicht wurde. Dies ist der Unterschied zwischen diesem Parameter und dem gleichnamigen Parameter im Risikomanager. Dort bleibt das Niveau des Basisguthabens immer unverändert.

Die nächste Gruppe von Eigenschaften wird verwendet, um die Berechnungsmethode und die Berechnung des geplanten Gewinns und Verlusts selbst auszuwählen. Sie werden in den Berechnungsmethoden LossMoney() und ProfitMoney() verwendet, die einen Wert in monetären Einheiten zurückgeben.

Um Positionen zu schließen, sollte der Closing-Manager in der Lage sein, das Objekt des EAs zum Schließen aufzufordern. Daher fügen wir der Liste der Eigenschaften des Closing-Managers den Zeiger auf das EA-Objekt und die Methode zu dessen Festlegung hinzu.

Wir fügen eine weitere Eigenschaft hinzu, um den aktuellen Status des Closing-Manager-Objekts zu speichern.

Die Erstellung auf Basis von CFactorable erfordert, dass der Konstruktor in einem privaten Bereich platziert wird und zwei spezielle Makros hinzugefügt werden, wie in Teil 24 beschrieben.

Als Ergebnis erhalten wir eine Beschreibung der Closing-Manager-Klasse, die in etwa so aussieht:

//+------------------------------------------------------------------+
//| Closing manager class (profit and loss taking)                   |
//+------------------------------------------------------------------+
class CVirtualCloseManager : public CFactorable {
protected:
// Main constructor parameters
   double            m_baseBalance;          // Base balance

   ENUM_CM_CALC_LOSS m_calcLossLimit;        // Method of calculating the maximum overall loss
   double            m_maxLossLimit;         // Parameter of calculating the maximum total loss

   ENUM_CM_CALC_PROFIT m_calcProfitLimit;    // Method for calculating maximum overall profit
   double            m_maxProfitLimit;       // Parameter for calculating the maximum overall profit

   CVirtualAdvisor*  m_expert;               // Pointer to the EA object

// Current state
   ENUM_CM_STATE     m_state;                // State

// Updated values
   double            m_balance;              // Current balance
   double            m_equity;               // Current equity
   double            m_profit;               // Current floating profit
   double            m_overallProfit;        // Current total profit relative to base balance

// Protected methods
   double            LossMoney();            // Maximum total loss
   double            ProfitMoney();          // Maximum profit

   void              UpdateProfit();         // Update current profit values
   void              CheckLimits();          // Check whether acceptable profit/loss levels have been achieved 
  
   CVirtualCloseManager(string p_params);    // Private constructor

public:
   STATIC_CONSTRUCTOR(CVirtualCloseManager); // Static object creation method
   virtual void      Tick();                 // Handle tick in the closing manager

   virtual string    Text();                 // Information about the current state

   // Bind the EA to the closing manager
   void              Expert(CVirtualAdvisor* p_expert);

   virtual bool      Save();      // Save status
   virtual bool      Load();      // Load status

   virtual string    operator~() override;   // Convert object to string
};

REGISTER_FACTORABLE_CLASS(CVirtualCloseManager); // Register a new CFactorable child

Betrachten wir die beiden Hauptmethoden der Klasse: den Konstruktor und die Methode zur Tick-Verarbeitung.

Im Konstruktor lesen wir wie üblich die Parameterwerte nacheinander aus der Initialisierungszeichenfolge aus und weisen sie den entsprechenden Eigenschaften zu, setzen den aktuellen Status auf normal, aktualisieren die aktuellen Gewinnwerte und speichern den aktuellen Guthaben als Basiswert, falls dieser nicht direkt festgelegt wurde:

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CVirtualCloseManager::CVirtualCloseManager(string p_params) {
// Save the initialization string
   m_params = p_params;

// Read the initialization string and set the property values
   m_isActive = (bool) ReadLong(p_params);
   m_baseBalance = ReadDouble(p_params);
   m_calcLossLimit = (ENUM_CM_CALC_LOSS) ReadLong(p_params);
   m_maxLossLimit = ReadDouble(p_params);
   m_calcProfitLimit = (ENUM_CM_CALC_PROFIT) ReadLong(p_params);
   m_maxProfitLimit = ReadDouble(p_params);

// Set the state: Limits are not exceeded
   m_state = CM_STATE_OK;

// Update the current profit values
   UpdateProfit();

// Adjust the base balance if it is not set
   if(m_baseBalance == 0) {
      m_baseBalance = m_balance;
   }
}

In der grundlegenden Tick-Verarbeitungsmethode analysieren wir den aktuellen Status und prüfen je nach Status entweder, ob die Zielgewinn- oder Verlustniveaus erreicht wurden, wenn sich der Manager in einem normalen Status befand, oder wir leiten das Schließen aller Positionen ein und gehen anschließend in einen normalen Status über:

//+------------------------------------------------------------------+
//| Tick processing in the risk manager                              |
//+------------------------------------------------------------------+
void CVirtualCloseManager::Tick() {
// If the risk manager is inactive, exit
   if(!m_isActive) {
      return;
   }

// Update the current profit values
   UpdateProfit();

// If the manager is in the trailing state,
   if(m_state == CM_STATE_TRAIL_PROFIT) {
      // immediately take the profit
      // switching the manager to the corresponding state
      if(true) {
         m_state = CM_STATE_PROFIT;
      }
   }

// If the manager is in normal condition,
   if(m_state == CM_STATE_OK) {
      // Check for exceeding loss and profit limits
      CheckLimits();
   }

// If the manager is in a state of achieved loss or profit,
   if(m_state == CM_STATE_LOSS || m_state == CM_STATE_PROFIT) {
      // Close all positions
      m_expert.Close();

      // If all positions are closed,
      if(PositionsTotal() == 0) {
         // Switch to normal state
         m_state = CM_STATE_OK;
         
         // Update the base balance value
         m_baseBalance = m_balance;
      } else {
         // Wait for all positions to close
      }

      // Save the EA state
      m_expert.Save();
   }
}

Zunächst haben wir beschlossen, uns auf diese Funktionalität des Closing-Managers zu beschränken, daher wird der Profit-Trailing-Status vorerst nicht verwendet.


Eingabeparameter übergeben

Nachdem wir die Closing-Manager-Klasse erstellt haben, müssen wir sie mit dem EA verbinden. Dazu müssen wir Eingaben hinzufügen, über die wir die Erstellung der Initialisierungszeichenfolge für den Closing-Manager steuern können. Dies muss in der Datei Adwizard/Experts/Expert.mqh erfolgen:

// ...

//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
input group "::: Use a strategy group"
sinput int        groupId_       = 0;     // - ID of the group from the new library (0 - last)
sinput bool       useAutoUpdate_ = true;  // - Use auto update?

input group "::: Money management"
sinput double expectedDrawdown_  = 10;    // - Maximum risk (%)
sinput double fixedBalance_      = 10000; // - Used deposit (0 - use all) in the account currency
input  double scale_             = 1.00;  // - Group scaling multiplier

input group ":::  Closing manager"
input bool        cmIsActive_                = true;  // - Active?
input double      cmStartBaseBalance_        = 0;     // - Basic balance
input ENUM_CM_CALC_LOSS
cmCalcLossLimit_           = CM_CALC_LOSS_MONEY_BB;   // - Loss calculation method
input double      cmLossLimit_       = 100;           // - Threshold loss value
input ENUM_CM_CALC_PROFIT
cmCalcProfitLimit_                    = CM_CALC_PROFIT_MONEY_BB;  // - Method for calculating total profit
input double      cmProfitLimit_   = 1000000;                     // - Profit target

// ...

Diese Datei wird beim Kompilieren des finalen EAs eingebunden, sodass die hinzugefügten Eingabeparameter darin verfügbar werden. Standardmäßig legen wir fest, dass die Werte für Gewinnmitnahme und Verlust in Geld (in der Kontowährung ) angegeben werden. Wir müssen die Werte selbst noch auswählen, daher ist das, was in den Standardwerten angegeben ist, vorerst nicht wichtig.


Erste Tests

Schauen wir mal, was wir erhalten haben. Überprüfen wir zunächst die korrekte Funktionsweise des Mechanismus zum Schließen von Positionen ohne Berücksichtigung des erzielten Gewinns. Wenn alles korrekt funktioniert, können wir im nächsten Schritt mit der Optimierung des erzielten Gewinns beginnen.

Verwenden wir die Datenbank des finalen EAs aus Teil 25, um den finalen EA im Tester zu starten. Wir haben dann eine beschleunigte Optimierung über mehrere Intervalle von jeweils 1 Jahr durchgeführt und zwölf Strategiegruppen erhalten, die in der Tabelle strategy_groups gespeichert sind:

Die Datenbankdatei hieß SimpleCandles-27183.test.db.sqliteDamit der finale EA diese Datenbank verwenden kann, muss sich diese Datei im gemeinsamen Datenordner der MetaTrader 5-Terminals im Unterordner Files befinden. Zudem sollte der finale EA SimpleCandles.ex5 heißen, und der Wert der Magic Number 27183 sollte in den Eingabeparametern beibehalten werden.

Starten wir zunächst den EA ohne Verwendung des Closing-Managers mit der allerersten Strategiegruppe mit id_group=20. Stellen wir dazu die folgenden Werte für die Eingabeparameter ein:

Wir verwenden denselben Zeitraum, in dem die automatische Optimierung durchgeführt wurde, als Testzeitraum, d. h. das gesamte Jahr 2022. Wir erhalten die folgenden Ergebnisse:

Abb. 2. Ergebnisse des finalen EAs mit id_group=20 ohne Closing-Manager für 2022

Wie Sie sehen, hat die Optimierung recht gute Parameterkombinationen für verschiedene Instanzen einfacher Handelsstrategien gefunden, um einen signifikanten Gewinn über einen bestimmten Zeitraum zu erzielen und dabei innerhalb des festgelegten Drawdowns von 10 % zu bleiben.

Schalten wir nun den Closing-Manager ein und setzen einen kleinen Wert, zum Beispiel 10 USD, als erwarteten Gewinn für die Gewinnmitnahme fest:


Lassen Sie uns den EA im visuellen Testmodus ausführen. Da wir die Anzeige der Betriebsdaten zum endgültigen EA hinzugefügt haben, können wir in diesem Modus sehen, welche Symbole und wie viele Strategien in der Gruppe mit der ID 20 aus der EA-Datenbank verwendet werden (drei Symbole GBPUSD, EURUSD, EURGBP und 48 Strategien), den Wert des Basisguthabens des Closing-Managers sowie das Zielniveau für Gewinn und Verlust für das Schließen.

Abb. 3. Starten des EA-Visualtests mit aktiviertem Closing-Manager

Abbildung 3 zeigt, dass der Basisguthaben des Closing-Managers bereits 10009.89 USD erreicht hat, was bedeutet, dass alle Positionen geschlossen wurden, sobald der Zielgewinn von 10 USD erreicht war.

Wir sehen die folgende Zeile im Protokoll:

2022.01.03 02:31:00   CVirtualCloseManager::CheckLimits | CLOSE PROFIT Profit = 12.94 | OverallProfit = 10.54 (10.00)

Der Closing-Manager wurde ausgelöst, als der Gesamtgewinn (OverallProfit = 10.54) relativ zum anfänglichen Basisguthaben von 10.000 USD 10 USD überstieg. Aufgrund des Testmodus nur zu Beginn jedes Minuten-Bars (1 Minute OHLC) erstreckte sich das Schließen aller offenen Positionen über zwei benachbarte Minuten, sodass das aufgezeichnete neue Basisniveau etwas niedriger als 10.010 USD ausfiel. Wir beobachten solche Diskrepanzen nicht mehr, wenn der Modus für jeden Tick aktiviert ist.

Testen wir nun den Closing-Manager zur Verlustbegrenzung . Lassen Sie uns einen kleinen Wert für die Verlusttoleranz festlegen, zum Beispiel 20 USD, während wir den Wert für die Gewinnmitnahme groß wählen, sodass wir höchstwahrscheinlich einen Verlust erleiden, anstatt einen Gewinn zu erzielen.

Bei anderen Parametern deaktivieren wir die Ausführung nur zur Bar-Eröffnung, sodass der EA bei aktiviertem Simulationsmodus für jeden Tick alle erforderlichen Aktionen bei jedem Tick ausführt und nicht nur zu Beginn des Minuten-Bars:


Wir starten den Test für ein kurzes Intervall von einem Tag (2022.01.03). Durch Filtern der Protokollmeldungen wählen wir nur die Zeilen aus, die angezeigt werden, wenn der festgelegte Verlust von 20 USD erreicht ist:

2022.01.03 17:11:33   CVirtualCloseManager::CheckLimits | CLOSE LOSS Profit = -33.13 | OverallProfit = -20.06 (-20.00)
2022.01.03 17:30:39   CVirtualCloseManager::CheckLimits | CLOSE LOSS Profit = -20.51 | OverallProfit = -20.51 (-20.00)
2022.01.03 19:13:31   CVirtualCloseManager::CheckLimits | CLOSE LOSS Profit = -21.20 | OverallProfit = -20.11 (-20.00)

Wir können sehen, dass dies während des Testtages dreimal aufgetreten ist. Im Modus für jeden Tick liegt der Gesamtgewinn (Overall Profit), der das Schließen von Positionen beim Erreichen eines festgelegten Verlusts auslöst, viel näher an dem in den Parametern angegebenen Wert. 

Bitte beachten Sie, dass der erste Protokolleintrag oben den folgenden Teil enthält:

Profit = -33.13

Dies ist der Wert des aktuellen Gewinns bei offenen Positionen (ein negativer Gewinn ist ein Verlust). In diesem Fall unterscheidet er sich vom Wert von USD -20, da mehrere Positionen ursprünglich mit einem Gewinn von etwa USD 13 geschlossen wurden. Daher wurde ein Verlust von USD 20 relativ zum anfänglichen Basisguthaben mit genau diesem Gewinnwert bei offenen Positionen erzielt.

Die ersten Tests haben also gezeigt, dass der entwickelte Closing-Manager den grundlegenden Teil seiner Arbeit bereits ausführen kann.


Schlussfolgerung

Wir machen hier eine kurze Pause und werden die Entwicklung des Closing-Managers in einem der nächsten Teile fortsetzen. Die Pläne für die weitere Entwicklung seiner Funktionalität umfassen in erster Linie das Hinzufügen einer Profit-Trailing-Funktion für offene Positionen sowie die Möglichkeit, ein Breakeven-Niveau festzulegen.

Die Verbesserungen enden hier jedoch nicht. Zum Beispiel prüft der Closing-Manager derzeit, ob alle Positionen geschlossen wurden, indem er einfach darauf wartet, dass die Anzahl der offenen Positionen Null erreicht. Dies kann jedoch auch geschehen, wenn offene virtuelle Positionen vorhanden sind. Lassen Sie uns also prüfen, ob wir hier eine zuverlässigere Überprüfungsmethode benötigen. Möglicherweise müssen wir auch die Interaktion zwischen dem Risikomanager und dem Closing-Manager organisieren: Beim Schließen sollte der Status des Risikomanagers aktualisiert werden und umgekehrt.

Dennoch ist die erste Version damit fertiggestellt, und der nächste Schritt wird nicht bei Null beginnen.

Vielen Dank für Ihre Aufmerksamkeit! Bis bald!


Wichtige Warnung

Alle in diesem Artikel und in allen vorangegangenen Artikeln dieser Reihe vorgestellten Ergebnisse beruhen lediglich auf historischen Testdaten und sind keine Garantie für zukünftige Gewinne. Die Arbeiten im Rahmen dieses Projekts haben Forschungscharakter. Alle veröffentlichten Ergebnisse können von jedermann auf eigenes Risiko verwendet werden.

Inhalt des Archivs

#
 Name
Version  Beschreibung  Jüngste Änderungen
  SimpleCandles     Arbeitsordner des Projekts (sollte sich innerhalb von MQL5/Experts befinden)  
SimpleCandles.mq5
1.01
Endgültiger EA für den Parallelbetrieb mehrerer Gruppen von Modellstrategien. Die Parameter werden aus der integrierten Gruppenbibliothek übernommen.
Teil 25
  └ Optimization
  Ordner für Projektoptimierungs-EAs  
2    CreateProject.mq5 1.02 EA-Skript zur Erstellung eines Projekts mit Phasen, Aufträgen und Optimierungsaufgaben.
Teil 25
3    Optimization.mq5 1.00
EA für die automatische Optimierung von Projekten
 
4    Stage1.mq5 1.02
Handelsstrategie Einzelinstanzoptimierung EA (Phase 1)
Teil 25
5    Stage2.mq5 1.01
EA zur Optimierung einer Gruppe von Handelsstrategie-Instanzen (Phase 2)
Teil 25
6 Stage3.mq5 1.01
Der EA, der eine generierte standardisierte Gruppe von Strategien in einer EA-Datenbank mit einem bestimmten Namen speichert.  Teil 25
  └ Strategies   Ordner Projektstrategien
Teil 25
7    SimpleCandlesStrategy.mqh
1.01
Handelsstrategieklasse SimpleCandles
Teil 25
  └ Include/Adwizard   Bibliotheksordner Adwizard  
    └ Base
  Basisklassen, von denen andere Projektklassen erben    
8       Advisor.mqh 1.04 EA-Basisklasse Teil 10
9       Factorable.mqh
1.06
Basisklasse von Objekten, die aus einer Zeichenkette erstellt werden
Teil 28
10       FactorableCreator.mqh
1.00 Klasse von Erzeugern, die Namen und statische Konstruktoren von CFactorable-Nachfolgeklassen binden Teil 24
11       Interface.mqh 1.01
Basisklasse zur Visualisierung verschiedener Objekte
Teil 4
12       Receiver.mqh
1.04  Basisklasse für die Umwandlung von offenen Volumina in Marktpositionen
Teil 12
13       Strategy.mqh
1.04
Handelsstrategie-Basisklasse
Teil 10
     └ Database
  Dateien für den Umgang mit allen Arten von Datenbanken, die von Projekt-EAs verwendet werden
 
14       Database.mqh 1.12 Klasse für den Umgang mit der Datenbank Teil 25
15       db.adv.schema.sql 1.00
Endgültige Datenbankstruktur von EA Teil 22
16       db.cut.schema.sql
1.00 Struktur der verkürzten Optimierungsdatenbank
Teil 22
17       db.opt.schema.sql
1.05  Struktur der Optimierungsdatenbank
Teil 22
18       Storage.mqh   1.01
Klasse zur Handhabung der Schlüssel-Wert-Speicherung für den endgültigen EA in der EA-Datenbank
Teil 23
     └ Experts
  Dateien mit gemeinsamen Teilen der verwendeten EAs verschiedener Typen
 
19       Expert.mqh  1.24 Die Bibliotheksdatei für den endgültigen EA. Gruppenparameter können aus der EA-Datenbank übernommen werden
Teil 28
20       Optimization.mqh  1.04 Bibliotheksdatei für den EA, der den Start von Optimierungsaufgaben verwaltet
Teil 23
21       Stage1.mqh
1.19 Bibliotheksdatei für die Einzelinstanz der Handelsstrategieoptimierung EA (Stage 1)
Teil 23
22       Stage2.mqh 1.04 Bibliotheksdatei für den EA, der eine Gruppe von Handelsstrategieinstanzen optimiert (Stage 2)   Teil 23
23       Stage3.mqh
1.04 Bibliotheksdatei für den EA, die eine generierte standardisierte Gruppe von Strategien in einer EA-Datenbank mit einem bestimmten Namen speichert. Teil 23
     └ Optimization
  Für die automatische Optimierung zuständige Klassen
 
24       OptimizationJob.mqh 1.00 Jobklasse für die Optimierungsphase des Projekts
Teil 25
25       OptimizationProject.mqh 1.00 Klasse für ein Optimierungsprojekt Teil 25
26       OptimizationStage.mqh 1.00 Klasse für eine Optimierungsprojektphase Teil 25
27       OptimizationTask.mqh 1.00 Optimierungsaufgabenklasse (Erstellung) Teil 25
28       Optimizer.mqh
1.03  Klasse für den Projektautooptimierungsmanager
Teil 22
29       OptimizerTask.mqh
1.03
Optimierungsaufgabenklasse (Pipeline)
Teil 22
     └ Strategies    Beispiele für Handelsstrategien, die die Funktionsweise des Projekts veranschaulichen
 
24       HistoryStrategy.mqh 
1.00 Klasse der Handelsstrategie für die Wiederholung der Handelshistorie
Teil 16
25       SimpleVolumesStrategy.mqh
1.11
Klasse der Handelsstrategie mit Tick-Volumen
Teil 22
     └ Utils
  Hilfsprogramme, Makros zur Code-Reduzierung

26        ConsoleDialog.mqh 1.01 Klasse zur Anzeige von Textdaten in einem Chart Teil 28
26       ExpertHistory.mqh 1.00 Klasse für den Export der Handelshistorie in eine Datei Teil 16
27       Macros.mqh 1.07 Nützliche Makros für Array-Operationen Teil 26
28        MTTester.mqh 
Datei für die Arbeit mit dem Strategietester aus der Bibliothek  MultiTester
Teil 28
29       NewBarEvent.mqh 1.00  Klasse zur Erkennung einer neuen Bar eines bestimmten Symbols  Teil 8
30       SymbolsMonitor.mqh  1.01 Klasse zur Beschaffung von Informationen über Handelsinstrumente (Symbole) Teil 28
     └ Virtual
  Klassen zur Erstellung verschiedener Objekte, die durch ein System virtueller Handelsaufträge und -positionen verbunden sind

31       Money.mqh 1.01  Basisklasse für das Money-Management
Teil 12
32       TesterHandler.mqh  1.07 Klasse zur Behandlung von Optimierungsereignissen  Teil 23
33       VirtualAdvisor.mqh  1.12  Klasse des EA, der virtuelle Positionen (Aufträge) bearbeitet Teil 28
34       VirtualChartOrder.mqh  1.02  Grafische virtuelle Positionsklasse Teil 28
35       VirtualCloseManager.mqh 1.00 Klasse des Closing-Managers Teil 28
36       VirtualHistoryAdvisor.mqh 1.00  Die Klasse des EA zur Wiedergabe der Handelshistorie  Teil 16
37       VirtualInterface.mqh  1.00  EA GUI-Klasse  Teil 4
38       VirtualOrder.mqh 1.09  Klasse der virtuellen Aufträge und Positionen  Teil 22
39       VirtualReceiver.mqh 1.04 Klasse für die Umwandlung von offenen Volumina in Marktpositionen (Empfänger)  Teil 23
40       VirtualRiskManager.mqh  1.06 Risikomanagement-Klasse (Risikomanager)  Teil 28
41       VirtualStrategy.mqh 1.09  Klasse einer Handelsstrategie mit virtuellen Positionen  Teil 23
42       VirtualStrategyGroup.mqh  1.04  Klasse der Handelsstrategiegruppe(n) Teil 28
43       VirtualSymbolReceiver.mqh  1.00 Empfängerklasse für Symbole  Teil 3
  Common/Files   Gemeinsamer Ordner für MetaTrader 5-Terminaldaten  
44 SimpleCandles-27183.test.db.sqlite Finale EA-Datenbank Teil 25

Der Quellcode ist auch unter SimpleCandles und Adwizard verfügbar.


Verwendung von Open-Source-Repositories

Während wir schrittweise zum neuen Algo Forge-Speicher übergehen, arbeiten wir noch an der besten und bequemsten Art und Weise, ihn zu nutzen. Die Einschränkung des MetaEditors auf die Verwendung eines einzigen Repositorys, das dem MQL5-Stammordner entspricht, ist nicht besonders komfortabel. Andere Repositories sind nur als Unterordner des Ordners „Shared Projects“ verfügbar, was die Sache etwas überschaubarer macht, aber nicht ausreicht, um diesen Ansatz sofort zu rechtfertigen.

Darüber hinaus wurde während des Übergangs das einzige Haupt-Repository zweimal im Namen des Superadmins erstellt, und beim zweiten Mal zerstörte dessen Erstellung aus irgendeinem Grund andere zusätzliche Repositories, die zuvor vom Benutzer erstellt worden waren. Glücklicherweise ermöglicht uns eine lokale Kopie des Repositorys, es erneut auf den Server hochzuladen, aber diese Art von erzwungener Aktion ist nicht besonders wünschenswert. Daher warten wir vorerst auf die weitere Entwicklung der MetaEditor-Funktionalität zur Handhabung von Repositories, ohne diese direkt zu verwenden.

Daran ist nichts kompliziert: Während wir weiterhin im MetaEditor arbeiten, verlagern wir vorerst einfach alle speicherbezogenen Vorgänge auf externe Anwendungen.

Wir können zum Beispiel eine Kopie aller Dateien, die den Code für diesen Artikel enthalten, auf unserem lokalen Computer abrufen, indem wir das folgende Skript in der Konsole ausführen, nachdem wir zuvor einen Ordner innerhalb des MQL5-Ordners des gewünschten MetaTrader-Terminals als aktuellen Ordner festgelegt haben:

# Erstellen eines Projektordners
mkdir SimpleCandles

# Zum Projektordner wechseln
cd SimpleCandles

# Das Projekt-Repository in den aktuellen Ordner klonen
git clone https://forge.mql5.io/antekov/SimpleCandles.git .

# Wechseln Sie das Repository auf den gewünschten Branch (für diesen Artikel - „article-17608-close-manager“)
git checkout article-17608-close-manager

# Stellen Sie sicher, dass wir auf den Branch gewechselt haben
git status

# Erstellen Sie einen Ordner für den Bibliotheksteil
mkdir Include

# Wechseln Sie dorthin
cd Include

# Klonen Sie das Adwizard-Repository in den Bibliotheksordner
git clone https://forge.mql5.io/antekov/Adwizard.git 

# Wechseln Sie in den erstellten Ordner
cd Adwizard

# Wechseln Sie das Repository auf den gewünschten Branch (für diesen Artikel - „article-17608-close-manager“)
git checkout article-17608-close-manager

# Stellen Sie sicher, dass wir auf den Branch gewechselt haben
git status

# Gehen Sie zwei Ebenen nach oben zum ursprünglichen Projektordner
cd ./../..

Das Einzige, was in diesen Repositories fehlt, ist eine Datei mit der Datenbank des fertigen EAs, da der Code im Repository es uns ermöglicht, diese durch automatische Optimierung zu erhalten. Falls erforderlich, kann diese Datei aus dem Archiv in den Artikel übernommen und im gemeinsamen Terminal-Ordner im Ordner Files abgelegt werden.

Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/17608

Beigefügte Dateien |
SimpleCandles.zip (483.1 KB)
Neuronale Netze im Trading: Zeitreihenprognose mittels adaptiver Modenzerlegung (ACEFormer) Neuronale Netze im Trading: Zeitreihenprognose mittels adaptiver Modenzerlegung (ACEFormer)
Wir laden Sie ein, die ACEFormer-Architektur zu erkunden – eine moderne Lösung, die die Effektivität probabilistischer Aufmerksamkeit mit adaptiver Zeitreihenzerlegung kombiniert. Dieser Artikel richtet sich an alle, die ein Gleichgewicht zwischen Berechnungseffizienz und Prognosegenauigkeit auf den Finanzmärkten suchen.
Von der Grundstufe bis zur Mittelstufe: Objektereignisse (I) Von der Grundstufe bis zur Mittelstufe: Objektereignisse (I)
In diesem Artikel werden wir uns drei der sechs Ereignisse ansehen, die MetaTrader 5 generieren kann, wenn eine Änderung an einem Objekt im Chart auftritt. Diese Ereignisse sind aus Sicht der Benutzerinteraktion sehr nützlich. Der Grund dafür ist, dass wir ohne das Verständnis dieser Ereignisse viel mehr Aufwand betreiben müssten, um eine bestimmte Chart-Konfiguration beizubehalten, wenn wir versuchen, Objekte für bestimmte Zwecke zu verwalten.
Von der Grundstufe bis zur Mittelstufe: Objektereignisse (III) Von der Grundstufe bis zur Mittelstufe: Objektereignisse (III)
In diesem Artikel schaffen wir die Grundlage für die Themen der nächsten Veröffentlichung. Wir werden uns auch ansehen, wie sich ein OBJ_LABEL-Objekt zum Bearbeiten und Verschieben vollständig interaktiv machen lässt. Mit anderen Worten: Wir können sowohl den Text als auch die Position des OBJ_LABEL-Objekts ändern, ohne das Dialogfenster „Objekteigenschaften“ zu öffnen.
Neuronale Netze in der Praxis: Übung macht den Meister Neuronale Netze in der Praxis: Übung macht den Meister
Im heutigen Artikel werden wir sehen, wie eine einfache Codeänderung, die ein Neuron etwas spezialisierter macht, die Trainingsphase erheblich beschleunigen kann. Schließlich arbeitet ein Neuron oder ein neuronales Netz – wie wir später sehen werden – deutlich schneller, sobald es trainiert wurde. Wir werden auch ein Problem diskutieren, das existiert, aber selten erwähnt wird.