English Русский 中文 Español Português
preview
Algorithmus für künstliche Atome (A3)

Algorithmus für künstliche Atome (A3)

MetaTrader 5Handelssysteme |
17 7
Andrey Dik
Andrey Dik

Inhalt

  1. Einführung
  2. Implementierung des Algorithmus
  3. Testergebnisse


Einführung

Im algorithmischen Handel ist eine der Schlüsselaufgaben die Optimierung der Parameter von Handelsstrategien. Trader stehen täglich vor der Notwendigkeit, zahlreiche Variablen anzupassen: Indikatorperioden, Stop-Loss- und Take-Profit-Niveaus, Positionsgrößen, Zeitfilter und Dutzende anderer Parameter. Jede Kombination dieser Parameter kann die Leistung der Strategie drastisch verändern, und wir suchen weiterhin nach effektiven Algorithmen, die innerhalb einer angemessenen Zeit die beste Lösung finden können.

In diesem Artikel werden wir uns einen weiteren Optimierungsalgorithmus ansehen, nämlich den künstlichen Atomalgorithmus (A3), bei dem es sich um einen metaheuristischen Optimierungsalgorithmus handelt, der von chemischen Prozessen inspiriert ist. Er wurde von türkischen Wissenschaftlern entwickelt und 2018 erstmals der wissenschaftlichen Gemeinschaft vorgestellt.


Implementierung des Algorithmus

Während der Arbeit an diesem Algorithmus stieß ich auf eine Reihe von Unklarheiten in der ursprünglichen Beschreibung. Einige Operatoren werden nicht ausreichend detailliert dargestellt, was ihre praktische Umsetzung erschwert. In dieser Hinsicht werde ich die ursprüngliche Beschreibung des Algorithmus bereitstellen, die Implementierung erfolgte jedoch nach meinem eigenen Ermessen – basierend auf persönlicher Erfahrung und den für solche Algorithmen charakteristischen Strukturprinzipien. Dies stellt eine erhebliche Lücke in der ursprünglichen Arbeit dar und lässt dem Entwickler beträchtlichen Spielraum für Interpretationen. Darüber hinaus wurden im Laufe der Arbeit Änderungen an der Basisklasse vorgenommen, die ebenfalls nach der Vorstellung der grundlegenden Implementierung des Algorithmus erörtert werden.

Der Algorithmus modelliert die Interaktion von Atomen und Elektronen, um die optimale Lösung zu finden. Die grundlegenden Komponenten sind Atome, die potenzielle Lösungen für das Problem darstellen. Elektronen repräsentieren Entscheidungsvariablen. Kovalente Bindung ist ein Operator zum Speichern und Replizieren der besten Lösungen, ionische Bindung ist ein Operator zur Erkundung des Suchraums und zum Erreichen eines globalen Optimums. 

Der Algorithmus beginnt mit der zufälligen Generierung einer Menge von Atomen, bewertet dann die Qualität jedes Atoms mithilfe der Zielfunktion und wendet anschließend Operatoren für kovalente und ionische Bindungen an, um Lösungen zu verbessern (leider gibt es keine Beschreibung, wie dies geschieht). Als Nächstes ist es notwendig, die Wirkung der Elektronen zu bewerten. Wiederum ist unklar, wie dies zu tun ist. Sowohl Elektronen als auch Atome sollen anschließend sortiert werden. Okay, wir können die Atome (Lösungen) sortieren, aber wie wir die Elektronen sortieren können, ist ein Rätsel (es ist, als würde man versuchen, die Gliedmaßen einer Person zu sortieren, Arme mit Beinen, rechts mit links – das spielt keine Rolle). Der Vorgang wird iterativ wiederholt, bis das Abbruchkriterium erreicht ist. Nun, wie das Sprichwort sagt, man muss mit dem arbeiten, was man hat. Wir müssen versuchen, einen Algorithmus zusammenzustellen, der die Ideen der Autoren anwendet.

Ich präsentiere hier meinen endgültigen überarbeiteten Pseudocode des A3-Algorithmus.

INITIALISIERUNG Eingaben:

popSize – Anzahl der Atome (Standard 10)
covalentRate – Koeffizient für kovalente Bindungen (Standard 0.1)
rangeMin [], rangeMax [] – Suchgrenzen für jede Variable
rangeStep [] – Diskretisierungsschritt

Vorberechnungen:

Berechne die Anzahl der Elite-Atome:
covalentCount = floor (popSize × covalentRate)
Limit: Minimum 1, Maximum (popSize - 1)

Erstelle eine Population aus popSize Atomen
Initialisiere für jedes Atom:
Koordinaten c []
Lokale schlechteste Lösung cW []
Fitness f, schlechteste Fitness fW


GRUNDLEGENDE OPTIMIERUNGSSCHLEIFE
SCHRITT 1: Erste Iteration (wenn revision = false)
FÜR jedes Atom i von 0 bis popSize-1:
    FÜR jede Koordinate j von 0 bis coords-1:
        Generiere einen Zufallswert im Bereich [rangeMin [j], rangeMax [j]]
        Wende Diskretisierung gemäß rangeStep [j] an
        Speichere in a [i].c [j]
    
Setze revision = true
Beende die Iteration

SCHRITT 2: Aktualisierung der Atompositionen (Bewegung)
FÜR jedes Atom i von 0 bis popSize-1:
    
    WENN i ≤ covalentCount (Atom ist Elite):
        FÜR jede Koordinate c von 0 bis coords-1:
            
            WENN random() < covalentRate (mit einer Wahrscheinlichkeit von 10 %):
                // Bewegung in Richtung der global besten Lösung
                step = random() × (cB [c] - a [i].c [c]) × covalentCount
                a [i].c [c] = a [i].c [c] + step
            
            ANDERNFALLS (mit einer Wahrscheinlichkeit von 90 %):
                // Generiere mittels PowerDistribution nahe der besten Lösung
                a[i]. c[c] = PowerDistribution(center=cB [c], min=rangeMin [c], max=rangeMax [c], degree=20)
            Wende Diskretisierung auf a [i].c [c] an
    
    ANDERNFALLS (das Atom ist nicht Elite):
        FÜR jede Koordinate c von 0 bis coords-1:
            // Wähle ein zufälliges Elite-Atom als Stichprobe aus
            ind = random_integer(0, covalentCount)
            
            // Bewegung vom lokalen schlechtesten Wert zur Position des Elite-Atoms
            direction = a [ind].c [c] - a [i].cW [c]
            step = random() × direction × (1.0 - covalentCount)
            a [i].c [c] = a [i].c [c] + step
            Wende Diskretisierung auf a [i].c [c] an

SCHRITT 3: Berechnung der Fitness
FÜR jedes Atom i:
    Berechne die Fitness von a[i].f durch die Zielfunktion

SCHRITT 4: Speicher aktualisieren und sortieren (Revision)
// Aktualisiere die lokalen schlechtesten Lösungen
FÜR jedes Atom i von 0 bis popSize-1:
    WENN a [i].f < a [i].fW:
        a [i].fW = a [i].f
        Kopiere a [i].c nach a [i].cW
        Aktualisiere den globalen schlechtesten Wert fW

// Sortiere die Population in absteigender Reihenfolge der Fitness
Sortiere das Array der Atome a[] nach dem Feld f (vom besten zum schlechtesten)

// Aktualisiere den globalen besten Wert
WENN a [0].f > fB:
    fB = a [0].f
    Kopiere a [0].c nach cB

// Aktualisiere den globalen schlechtesten Wert
WENN a [popSize-1].f < fW:
    fW = a [popSize-1].f
    Kopiere a [popSize-1].c nach cW

SCHRITT 5: Überprüfung des Abbruchkriteriums
WENN die maximale Anzahl der Iterationen erreicht wurde:
    Beende den Algorithmus
SONST:
    Gehe zu SCHRITT 2

Jetzt können wir zur praktischen Implementierung im Code übergehen. Schreiben wir eine Klasse, die die Implementierung eines Algorithmus für ein künstliches Atomsystem auf der Grundlage der Metapher von Atomen und ihren Bindungen darstellt. Diese Klasse erbt die grundlegenden Fähigkeiten der C_AO-Klasse und erweitert sie im Kontext des A3-Algorithmus.

Methoden zur Parametereinstellung: Die Funktion SetParams() liest die aktuellen Werte aus dem Parameter-Array und speichert sie in den entsprechenden Variablen. Dies bietet Flexibilität bei der Anpassung vor der Ausführung des Algorithmus. Initialisierung: Die Methode Init() bereitet die Parameter und die Struktur für die Ausführung vor und empfängt die Wertebereiche und Schritte der Variablen sowie die Anzahl der Iterationen. Die Hauptoperationen des Algorithmus: Die Methoden Moving() und Revision() implementieren die Bewegungs- und Aktualisierungsphasen der Atome innerhalb des Systems, was den Phasen der Suche nach der optimalen Lösung entspricht. Parameter und Variablen:

  • popSize – Populationsgröße der Atome (Anzahl der Elemente in der Population).
  • covalentRate – Koeffizient zur Charakterisierung der Bindungsbildung zwischen Atomen.
  • covalentCount – interne Anzahl der an der Bindungsbildung beteiligten Atome (wird intern für Berechnungen verwendet).

Der allgemeine Zweck der Klasse besteht darin, das Verhalten eines Systems von Atomen unter Berücksichtigung ihrer Verbindungen zu modellieren, was durch Parameter und Methoden implementiert wird. Die Such- und Optimierungslogik werden dann auf Basis dieser Konzepte implementiert.

//————————————————————————————————————————————————————————————————————
class C_AO_A3 : public C_AO
{
  public: //----------------------------------------------------------
  ~C_AO_A3 () { }
  C_AO_A3 ()
  {
    ao_name = "A3";
    ao_desc = "Artificial Atom Algorithm";
    ao_link = "https://www.mql5.com/en/articles/18958";

    popSize      = 10;    // number of atoms (m)
    covalentRate = 0.1;   // covalent bond coefficient (β)

    ArrayResize (params, 2);

    params [0].name = "popSize";      params [0].val = popSize;
    params [1].name = "covalentRate"; params [1].val = covalentRate;
  }

  void SetParams ()
  {
    popSize      = (int)params [0].val;
    covalentRate = params      [1].val;
  }

  bool Init (const double &rangeMinP  [],  // minimum values
             const double &rangeMaxP  [],  // maximum values
             const double &rangeStepP [],  // step change
             const int     epochsP = 0);   // number of epochs

  void Moving   ();
  void Revision ();

  //------------------------------------------------------------------
  double covalentRate;       // covalent bond coefficient (β)

  private: //---------------------------------------------------------
  int    covalentCount;      // number of atoms for covalent bond
};
//————————————————————————————————————————————————————————————————————

Die Methode Init() ist ein entscheidender Schritt bei der Vorbereitung des Algorithmus auf den Betrieb. Ihre Hauptaufgabe besteht darin, alle notwendigen Parameter und Strukturen vor Beginn der Optimierung zu initialisieren. Die Methode erhält vier Eingabeparameter:

  1. rangeMinP [] – Mindestwerte für jede Variable, die der Algorithmus optimieren wird.
  2. rangeMaxP [] – Höchstwerte für jede Variable.
  3. rangeStepP [] – Änderungsschritt für jede Variable. Diese Schritte werden verwendet, um die Suchgenauigkeit zu diskretisieren und zu bestimmen.
  4. epochsP – Anzahl der Durchläufe (Iterationen) der Algorithmusausführung.

Zuerst wird die Methode StandardInit() der Basisklasse (C_AO) aufgerufen, die die für alle Optimierungsalgorithmen gemeinsamen Initialisierungsschritte durchführt. Wenn StandardInit() erfolgreich ist, fährt die Methode mit der Berechnung der für den künstlichen Atom-Algorithmus spezifischen Parameter fort. Insbesondere wird covalentCount berechnet – die Anzahl der Atome, die an kovalenten Bindungen teilnehmen werden. Die Berechnung erfolgt als Produkt aus popSize (der Gesamtzahl der Atome in der Population) und covalentRate (dem Koeffizienten für kovalente Bindungen). Das Ergebnis wird mit MathFloor auf die nächste ganze Zahl abgerundet, da die Anzahl der Atome eine Ganzzahl sein sollte. Anschließend werden Prüfungen durchgeführt, um sicherzustellen, dass der Wert von covalentCount logisch korrekt ist. Wenn alle Initialisierungsschritte erfolgreich abgeschlossen wurden, gibt die Methode true zurück und signalisiert damit, dass der Algorithmus einsatzbereit ist.

Somit stellt die Init-Methode die vollständige Einsatzbereitschaft des künstlichen Atom-Algorithmus sicher, indem sie sowohl die für Optimierungsalgorithmen gemeinsamen Parameter als auch die für ein bestimmtes Modell von Atomen und Bindungen spezifischen Parameter initialisiert.

/————————————————————————————————————————————————————————————————————
//--- Initialization
bool C_AO_A3::Init (const double &rangeMinP  [],
                    const double &rangeMaxP  [],
                    const double &rangeStepP [],
                    const int     epochsP = 0)
{
  if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false;

  //------------------------------------------------------------------
  covalentCount = (int)MathFloor (popSize * covalentRate);
  if (covalentCount < 1) covalentCount = 1;
  if (covalentCount >= popSize) covalentCount = popSize - 1;

  return true;
}
//————————————————————————————————————————————————————————————————————

Die Methode Moving() in der Klasse C_AO_A3 ist einer der wichtigsten Schritte des künstlichen Atom-Algorithmus und implementiert den Prozess des Bewegens oder Änderns der Position von Atomen im Suchraum. Sie modelliert evolutionäre Veränderungen in einer Population von Atomen, die darauf abzielen, eine optimale Lösung zu finden. Zu Beginn jedes Aufrufs der Methode Moving() wird der Revisionsstatus überprüft. Dieses Flag gibt an, ob die Population zuvor initialisiert wurde.

Die anfängliche Initialisierung (wenn revision false ist) bedeutet, dass die Methode Moving() zum ersten Mal oder nach einem Zurücksetzen des Zustands aufgerufen wird und die Atompopulation noch nicht initialisiert wurde. In diesem Fall geschieht Folgendes: eine Schleife über alle popSize (Anzahl der Atome) und über alle coords (Dimensionen des Suchraums). Für jedes Atom und für jede Koordinate wird dessen Position auf einen Zufallswert innerhalb eines gegebenen Bereichs initialisiert. Nachdem der erste Aufruf initialisiert wurde, wird revision auf true gesetzt, sodass nachfolgende Aufrufe von Moving() den Hauptbewegungsprozess durchführen, anstatt eine erneute Initialisierung vorzunehmen. Die Methode wird beendet, da die Aufgabe des ersten Aufrufs abgeschlossen ist.

Der grundlegende Prozess der Bewegung von Atomen (wenn revision true ist), nachdem die Population initialisiert wurde, beginnt die Methode Moving mit der Aktualisierung der Positionen der Atome und simuliert deren Bewegung, wobei die Atome abhängig von ihrem i-Index und dem Wert covalentCount in zwei Gruppen unterteilt werden. 

Gruppe 1: Atome, die an einer kovalenten Bindung beteiligt sind (i <= covalentCount). Für jedes Atom in dieser Gruppe und für jede seiner Koordinaten wird eine Zufallszahl generiert. Wenn diese Zahl kleiner als der Koeffizient für kovalente Bindungen ist, ändert das Atom seine Koordinate gemäß einer Formel, die eine Anziehung oder Interaktion mit der aktuell besten Lösung cB[c] simuliert, wobei cB die in der Population gefundenen besten Koordinaten sind und covalentCount berücksichtigt wird.

Wenn die Zufallszahl größer oder gleich covalentRate ist, ändert das Atom seine Koordinate mithilfe der Funktion u.PowerDistribution. Die Funktion generiert einen Wert, der in Richtung cB[c] tendiert, jedoch mit einer gewissen zufälligen Streuung, was eine zufälligere Suche oder ein Streuen simuliert.

Unabhängig davon, wie die Koordinate geändert wurde, wird sie erneut durch die Funktion u.SeInDiSp verarbeitet, um sie in den zulässigen Bereich und das diskrete Raster zu bringen. 

Gruppe 2: Atome, die nicht an einer kovalenten Bindung beteiligt sind (i > covalentCount): Für jedes Atom in dieser Gruppe und für jede seiner Koordinaten wird ein zufälliger Index ind aus dem Bereich von 0 bis covalentCount ausgewählt. Dies bedeutet, dass das ungebundene Atom mit einem der an der kovalenten Bindung beteiligten Atome interagiert.

Die Atomkoordinate wird modifiziert, um eine Interaktion oder Abstoßung mit dem ausgewählten gebundenen Atom sowie der lokal schlechtesten Position des aktuellen Atoms zu simulieren, und die Koordinate wird erneut durch u.SeInDiSp verarbeitet, um die Einschränkungen zu erfüllen.

Die Methode Moving() ist der Kern des Suchprozesses. Sie implementiert stochastische Regeln zur Aktualisierung der Atompositionen, die von einem physikalischen Modell inspiriert sind. Atome, die an einer kovalenten Bindung beteiligt sind, tendieren dazu, sich in Richtung der gefundenen besten Lösung zu bewegen, während andere Atome den Raum erkunden und mit kovalent gebundenen Atomen interagieren.

//————————————————————————————————————————————————————————————————————
//--- The main step of the algorithm
void C_AO_A3::Moving ()
{
  // Initial population setup
  if (!revision)
  {
    for (int i = 0; i < popSize; i++)
    {
      for (int j = 0; j < coords; j++)
      {
        a [i].c [j] = u.RNDfromCI (rangeMin [j], rangeMax [j]);
        a [i].c [j] = u.SeInDiSp (a [i].c [j], rangeMin [j], rangeMax [j], rangeStep [j]);
      }
    }

    revision = true;
    return;
  }

  //------------------------------------------------------------------
  int    ind = 0;

  for (int i = 0; i < popSize; i++)
  {
    if (i <= covalentCount)
    {
      for (int c = 0; c < coords; c++)
      {
        if (u.RNDprobab () < covalentRate)
        {
          a [i].c [c] = a [i].c [c] + u.RNDprobab () * (cB [c] - a [i].c [c]) * covalentCount;//(1.0 - covalentCount);
        }
        else
        {
          a [i].c [c] = u.PowerDistribution (cB [c], rangeMin [c], rangeMax [c], 20);
        }
        a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
      }
    }
    else
    {
      for (int c = 0; c < coords; c++)
      {
        ind = u.RNDintInRange (0, covalentCount);

        a [i].c [c] = a [i].c [c] + u.RNDprobab () * (a [ind].c [c] - a [i].cW [c]) * (1.0 - covalentCount);//covalentCount;
        a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
      }
    }
  }
}
//————————————————————————————————————————————————————————————————————

Die Methode Revision() in der Klasse C_AO_A3 ist für die Aktualisierung der Informationen über die besten und schlechtesten Lösungen verantwortlich, die in der Population der Atome in der aktuellen Iteration des Algorithmus gefunden wurden. Dies ist ein wichtiger Schritt, da diese besten und schlechtesten Werte (sowohl populationsweit als auch individuell für jedes Atom) verwendet werden, um die weitere Suche im nächsten Schritt zu steuern. Aktualisierung der individuellen schlechtesten lokalen Lösung für jedes Atom. Die Funktion u.Sorting() wird aufgerufen, wodurch die gesamte Population von a-Atomen basierend auf ihrer f-Fitness sortiert wird.

Nach dem Sortieren repräsentiert das Atom a[0] das beste Atom in der aktuellen Population. Dann wird fB mit dem Wert von a[0].f aktualisiert. Die Koordinaten a[0].c werden nach cB (global beste Koordinaten) kopiert. Das Atom a [popSize - 1] repräsentiert das schlechteste Atom in der aktuellen Population (nach dem Sortieren). Die Fitness von a [popSize - 1].f wird mit fW (der bisher gefundenen global schlechtesten Fitness) verglichen. Wenn a[popSize - 1].f tatsächlich schlechter ist, dann wird fW mit dem Wert von a[popSize - 1].f aktualisiert und die Koordinaten von a[popSize - 1].c werden nach cW (die global schlechtesten Koordinaten) kopiert.

Die Methode Revision überwacht systematisch den Optimierungsfortschritt. Sie aktualisiert sowohl die individuellen „schlechtesten“ Zustände für jeden Agenten (Atom) als auch die global besten und schlechtesten Zustände der gesamten Population. 

//————————————————————————————————————————————————————————————————————
//--- Update the best and worst solutions
void C_AO_A3::Revision ()
{
  // Update the local worst solution
  for (int i = 0; i < popSize; i++)
  {
    if (a [i].f < a [i].fW)
    {
      fW = a [i].f;
      ArrayCopy (a [i].cW, a [i].c, 0, 0, WHOLE_ARRAY);
    }
  }

  static S_AO_Agent aT []; ArrayResize (aT, popSize);
  u.Sorting (a, aT, popSize);

  if (a [0].f > fB)
  {
    fB = a [0].f;
    ArrayCopy (cB, a [0].c, 0, 0, WHOLE_ARRAY);
  }

  if (a [popSize - 1].f < fW)
  {
    fW = a [popSize - 1].f;
    ArrayCopy (cW, a [popSize - 1].c, 0, 0, WHOLE_ARRAY);
  }
}
//————————————————————————————————————————————————————————————————————

Die resultierende Implementierung ist relativ kompakt. Kommen wir nun zur Basisklasse, von der alle Optimierungsalgorithmen abgeleitet sind. Wie ich oben bereits sagte, haben sich darin Änderungen ergeben, und wir werden die Klasse beschreiben.

Eine einfache Struktur zum Speichern von Algorithmusparametern. Sie ermöglicht es uns, die Einstellungen jedes Optimierungsalgorithmus dynamisch zu verwalten.

//——————————————————————————————————————————————————————————————————————————————
struct S_AlgoParam
{
    double val;
    string name;
};
//——————————————————————————————————————————————————————————————————————————————

Die Struktur S_AO_Agent soll einen einzelnen Agenten darstellen, der eine potenzielle Lösung für ein Optimierungsproblem repräsentiert und sich durch einen mehrdimensionalen Suchraum bewegt. Die Struktur S_AO_Agent enthält eine Reihe von Feldern, die in mehrere Kategorien unterteilt werden können: 1. Koordinaten (Position im Suchraum):

  • c – aktuelle Koordinaten des Agenten. Dies ist das Haupt-Array, das die aktuelle Agentenposition speichert.
  • cP – vorherige Agentenkoordinaten. Wird verwendet, um die Bewegung des Agenten zu verfolgen.
  • cB – beste Koordinaten, die dieser spezielle Agent jemals erreicht hat. Diese Information hilft dem Agenten, sich an seine erfolgreichsten Positionen zu erinnern und zu ihnen zurückzukehren oder sie für weitere Suchen zu verwenden.
  • cW – schlechteste Agentenkoordinaten.

2. Fitness (Lösungsqualität):

  • f – aktuelle Fitness des Agenten. Dies ist der Wert der Zielfunktion, der für die aktuellen c-Koordinaten berechnet wurde.
  • fP – vorherige Fitness des Agenten. Wird verwendet, um Änderungen der Fitness ähnlich wie bei cP zu verfolgen.
  • fB – beste jemals von diesem Agenten erreichte Fitness. Entspricht den cB-Koordinaten.
  • fW – schlechteste Fitness des Agenten. Entspricht den cW-Koordinaten.

3. Hilfsdaten: cnt – ganzzahliger Zähler. 

Die Struktur enthält auch die öffentliche Methode Init(), die zur Initialisierung des Agenten verwendet wird. Sie nimmt einen Ganzzahl-Parameter coords entgegen, der die Dimensionalität des Suchraums angibt (d. h. die Anzahl der Koordinaten, die der Agent haben sollte).

Wenn Init aufgerufen wird, finden die folgenden Aktionen statt: Die Koordinaten-Arrays (c, cP, cB, cW) werden dynamisch auf die angegebenen coords angepasst. Dies stellt sicher, dass jeder Agent die korrekte Anzahl an Dimensionen hat, um ein bestimmtes Problem zu bearbeiten. Die Fitnesswerte (f, fP, fB, fW) werden initialisiert, f, fP, fB werden auf minus DBL_MAX (den kleinstmöglichen Double-Wert) und fW auf DBL_MAX (den größtmöglichen) gesetzt. Dies ist gängige Praxis bei der Suche nach dem Maximum (für f, fP, fB wird der aktuelle Wert dann fast immer größer als der ursprüngliche sein), und für fW (schlechtester) wird der größte Wert so eingestellt, dass jeder erste gefundene Wert besser (kleiner) ist. Der Zähler cnt wird auf null initialisiert.

Insgesamt bietet S_AO_Agent eine umfassende Datenstruktur für jedes Mitglied der Population in einem evolutionären und Populationsoptimierungsalgorithmus, die es ermöglicht, sowohl seinen aktuellen Zustand als auch seine Erfolgs- und Misserfolgshistorie zu verfolgen.

//——————————————————————————————————————————————————————————————————————————————
struct S_AO_Agent
{
    double c  []; //coordinates
    double cP []; //previous coordinates
    double cB []; //best coordinates
    double cW []; //worst coordinates

    double f;     //fitness
    double fP;    //previous fitness
    double fB;    //best fitness
    double fW;    //worst fitness

    int    cnt;   //counter

    void Init (int coords)
    {
      ArrayResize (c,  coords);
      ArrayResize (cP, coords);
      ArrayResize (cB, coords);
      ArrayResize (cW, coords);

      f  = -DBL_MAX;
      fP = -DBL_MAX;
      fB = -DBL_MAX;
      fW =  DBL_MAX;

      cnt = 0;
    }
};
//——————————————————————————————————————————————————————————————————————————————

Betrachten wir die Basisklasse C_AO. Allgemeine Struktur der Klasse C_AO. Öffentliche Mitglieder. Dies sind Felder und Methoden, auf die von außerhalb der Klasse zugegriffen werden kann. 

Daten, die den Gesamtzustand der besten/schlechtesten Lösung beschreiben:

  • cB [] – Array der Koordinaten der besten Lösung, die vom gesamten Algorithmus (global) gefunden wurde.
  • cW [] – Array der Koordinaten der schlechtesten Lösung, die vom gesamten Algorithmus (global) gefunden wurde.
  • fB – Fitnesswert für die beste globale Lösung (entspricht cB).
  • fW – Fitnesswert für die schlechteste globale Lösung (entspricht cW).

Beachten Sie, dass dies globale beste/schlechteste Lösungen sind, im Gegensatz zu fB, fW innerhalb von S_AO_Agent, die agentspezifisch sind. 

Daten zur Population und zu den Parametern:

  • a [] – Array von S_AO_Agent-Objekten. Dies ist eine Population von Agenten, von denen jeder eine potenzielle Lösung darstellt.
  • params [] – Array von S_AlgoParam-Objekten. Hier werden algorithmusspezifische Parameter (z. B. Einflusskoeffizienten, Wahrscheinlichkeiten usw.) gespeichert und können konfiguriert werden.
  • revision – Flag, das die Notwendigkeit anzeigt, den Zustand zu überarbeiten und zu aktualisieren. 
Virtuelle Methoden (erfordern eine Implementierung in abgeleiteten Klassen). Diese Methoden sind als virtuell deklariert und können in abgeleiteten Klassen überschrieben werden, um die spezifische Logik einer bestimmten Version des Algorithmus zu implementieren.
  • SetParams () – Methode zum Festlegen spezifischer Algorithmusparameter; in den abgeleiteten Klassen füllt sie das params-Array.
  • Init () – Hauptmethode zur Initialisierung des Algorithmus. Sie akzeptiert Suchbereiche (Minimum, Maximum, Schritt) und die Anzahl der Iterationen. Gibt bei erfolgreicher Initialisierung true zurück.
  • Moving () – Methode, die die Logik der Bewegung oder Evolution von Agenten im Suchraum implementiert. Dies ist der Kern des Algorithmus.
  • Revision () – Methode für die Revisions- oder Aktualisierungs-Phase des Algorithmuszustands.
  • Injection () – Methode zum Injizieren eines bestimmten Wertes in die Koordinate eines spezifischen Agenten. 

Suchraumparameter, Arrays zur Speicherung von:

  • rangeMin [] – Mindestwerte für jede Koordinate des Suchraums.
  • rangeMax [] – Höchstwerte für jede Koordinate des Suchraums.
  • rangeStep [] – Schritte für jede Koordinate (nützlich für diskrete Räume oder zur Bestimmung der Granularität der Suche).

Interne Parameter des Algorithmus:

  • coords – Anzahl der Dimensionen (Koordinaten) im Suchraum.
  • popSize – Populationsgröße (Anzahl der Agenten) im Algorithmus.

Hilfsprogramme: u – Objekt einer Hilfsklasse, das allgemeine Funktionen wie Zufallszahlengenerierung, mathematische Operationen usw. enthält.

Standard-Initialisierungsmethode (geschützt): StandardInit () ist dafür ausgelegt, einen allgemeinen, standardmäßigen Initialisierungsteil für alle abgeleiteten Algorithmen durchzuführen. Die Methode initialisiert zunächst den Zufallszahlengenerator unter Verwendung der aktuellen Systemzeit als Startwert. Anschließend setzt fB auf negative Unendlichkeit und fW auf positive Unendlichkeit, um die beste/schlechteste globale Lösung weiter zu verfolgen. Es setzt außerdem das revision-Flag auf false, prüft und setzt die Anzahl der Koordinaten (Raumdimension), ändert die Größe der internen Arrays (rangeMin, rangeMax, rangeStep, cB, cW) entsprechend der Anzahl der Koordinaten und ändert die Größe des Agenten-Arrays a entsprechend der Populationsgröße popSize, wobei jeder Agent seine eigene Init-Methode aufruft, um die internen Koordinaten-Arrays des Agenten zu initialisieren. Die Methode kopiert die eingegebenen Suchbereiche in ihre internen Variablen, gibt bei erfolgreicher Initialisierung true zurück und false im Fehlerfall (zum Beispiel bei einer Nichtübereinstimmung der Größen der Eingabebereichs-Arrays).

Die Klasse C_AO dient als Basisklasse für konkrete Implementierungen von Optimierungsalgorithmen. Jeder neue Algorithmus (spezifische Version von AO) erbt von C_AO und überschreibt virtuelle Methoden (SetParams, Init, Moving, Revision, Injection), um seine einzigartige Logik zu implementieren, während StandardInit dabei hilft, Code-Duplizierung für allgemeine Initialisierungsschritte zu vermeiden.

//——————————————————————————————————————————————————————————————————————————————
class C_AO
{
  public: //--------------------------------------------------------------------
  C_AO () { }
  ~C_AO () { }

  double      cB     []; //best coordinates
  double      cW     []; //worst coordinates
  double      fB;        //FF of the best coordinates
  double      fW;        //FF of the worst coordinates
  S_AO_Agent  a      []; //agents
  S_AlgoParam params []; //algorithm parameters
  bool        revision;

  virtual void SetParams () { }
  virtual bool Init (const double &rangeMinP  [], //minimum search range
                     const double &rangeMaxP  [], //maximum search range
                     const double &rangeStepP [], //step search
                     const int     epochsP = 0)   //number of epochs
  { return false;}

  virtual void Moving    () { }
  virtual void Revision  () { }
  virtual void Injection (const int popPos, const int coordPos, const double value) { }

  string GetName   () { return ao_name;}
  string GetDesc   () { return ao_desc;}
  string GetLink   () { return ao_link;}
  string GetParams ()
  {
    string str = "";
    for (int i = 0; i < ArraySize (params); i++)
    {
      str += (string)params [i].val + "|";
    }
    return str;
  }


  protected: //-----------------------------------------------------------------
  string ao_name;      //ao name;
  string ao_desc;      //ao description
  string ao_link;      //ao link

  double rangeMin  []; //minimum search range
  double rangeMax  []; //maximum search range
  double rangeStep []; //step search

  int    coords;       //coordinates number
  int    popSize;      //population size

  C_AO_Utilities u;     //auxiliary functions

  bool StandardInit (const double &rangeMinP  [], //minimum search range
                     const double &rangeMaxP  [], //maximum search range
                     const double &rangeStepP []) //step search
  {
    int seed = (int)GetTickCount64 ();
    MathSrand (seed); //reset of the generator

    fB       = -DBL_MAX;
    fW       =  DBL_MAX;
    revision =  false;

    coords  = ArraySize (rangeMinP);
    if (coords == 0 || coords != ArraySize (rangeMaxP) || coords != ArraySize (rangeStepP)) return false;

    ArrayResize     (rangeMin,  coords);
    ArrayResize     (rangeMax,  coords);
    ArrayResize     (rangeStep, coords);
    ArrayResize     (cB,        coords);
    ArrayResize     (cW,        coords);

    ArrayResize (a, popSize);
    for (int i = 0; i < popSize; i++) a [i].Init (coords);

    ArrayCopy (rangeMin,  rangeMinP,  0, 0, WHOLE_ARRAY);
    ArrayCopy (rangeMax,  rangeMaxP,  0, 0, WHOLE_ARRAY);
    ArrayCopy (rangeStep, rangeStepP, 0, 0, WHOLE_ARRAY);

    return true;
  }
};
//——————————————————————————————————————————————————————————————————————————————


Testergebnisse

Schauen wir uns nun an, wie der A3-Algorithmus funktioniert. Durchschnittliche Ergebnisse für eine kleine Population.

A3|Artificial Atom Algorithm|30.0|0.2|
=============================
5 Hilly's; Func runs: 10000; result: 0.7074464987418227
25 Hilly's; Func runs: 10000; result: 0.49461443027863367
500 Hilly's; Func runs: 10000; result: 0.27674325929370214
=============================
5 Forest's; Func runs: 10000; result: 0.8910275237236067
25 Forest's; Func runs: 10000; result: 0.43888040941642725
500 Forest's; Func runs: 10000; result: 0.17553299655770818
=============================
5 Megacity's; Func runs: 10000; result: 0.5323076923076923
25 Megacity's; Func runs: 10000; result: 0.3270769230769231
500 Megacity's; Func runs: 10000; result: 0.11430769230769337
=============================
All score: 3.95794 (43.98%)

Die Visualisierung zeigt eine Streuung der Ergebnisse für niedrigdimensionale Funktionen (grüne Linien), obwohl die gute Abdeckung des Raums durch die Lösungen erwähnenswert ist.

Hilly

A3 mit der Testfunktion Hilly

Forest

A3 mit der Testfunktion Forest

Megacity

A3 mit der Testfunktion Megacity

Unsere Bewertungstabelle stellt den A3-Algorithmus nur zu Informationszwecken dar.

# AO Beschreibung Hilly Hilly
Final
Forest Forest
Final
Megacity (discrete) Megacity
Final
Final
Result
% of
MAX
10 p (5 F) 50 p (25 F) 1000 p (500 F) 10 p (5 F) 50 p (25 F) 1000 p (500 F) 10 p (5 F) 50 p (25 F) 1000 p (500 F)
1 ANS Suche über Nachbarschaft 0.94948 0.84776 0.43857 2.23581 1.00000 0.92334 0.39988 2.32323 0.70923 0.63477 0.23091 1.57491 6.134 68.15
2 CLA Code-Lock-Algorithmus (joo) 0.95345 0.87107 0.37590 2.20042 0.98942 0.91709 0.31642 2.22294 0.79692 0.69385 0.19303 1.68380 6.107 67.86
3 AMOm Optimierung der Tiermigration M 0.90358 0.84317 0.46284 2.20959 0.99001 0.92436 0.46598 2.38034 0.56769 0.59132 0.23773 1.39675 5.987 66.52
4 (P+O)ES (P+O) Evolutionsstrategien 0.92256 0.88101 0.40021 2.20379 0.97750 0.87490 0.31945 2.17185 0.67385 0.62985 0.18634 1.49003 5.866 65.17
5 CTA Kometenschweif-Algorithmus (joo) 0.95346 0.86319 0.27770 2.09435 0.99794 0.85740 0.33949 2.19484 0.88769 0.56431 0.10512 1.55712 5.846 64.96
6 TETA Zeit-Evolutions-Reise-Algorithmus (Joo) 0.91362 0.82349 0.31990 2.05701 0.97096 0.89532 0.29324 2.15952 0.73462 0.68569 0.16021 1.58052 5.797 64.41
7 SDSm stochastische Diffusionssuche M 0.93066 0.85445 0.39476 2.17988 0.99983 0.89244 0.19619 2.08846 0.72333 0.61100 0.10670 1.44103 5.709 63.44
8 BOAm Billard-Optimierungsalgorithmus M 0.95757 0.82599 0.25235 2.03590 1.00000 0.90036 0.30502 2.20538 0.73538 0.52523 0.09563 1.35625 5.598 62.19
9 AAm Algorithmus für das Bogenschießen M 0.91744 0.70876 0.42160 2.04780 0.92527 0.75802 0.35328 2.03657 0.67385 0.55200 0.23738 1.46323 5.548 61.64
10 ESG Entwicklung sozialer Gruppen (joo) 0.99906 0.79654 0.35056 2.14616 1.00000 0.82863 0.13102 1.95965 0.82333 0.55300 0.04725 1.42358 5.529 61.44
11 SIA Simuliertes isotropes Glühen (Joo) 0.95784 0.84264 0.41465 2.21513 0.98239 0.79586 0.20507 1.98332 0.68667 0.49300 0.09053 1.27020 5.469 60.76
12 EOm extremal_optimization_M 0.76166 0.77242 0.31747 1.85155 0.99999 0.76751 0.23527 2.00277 0.74769 0.53969 0.14249 1.42987 5.284 58.71
13 BBO biogeografisch basierte Optimierung 0.94912 0.69456 0.35031 1.99399 0.93820 0.67365 0.25682 1.86867 0.74615 0.48277 0.17369 1.40261 5.265 58.50
14 ACS künstliche, kooperative Suche 0.75547 0.74744 0.30407 1.80698 1.00000 0.88861 0.22413 2.11274 0.69077 0.48185 0.13322 1.30583 5.226 58.06
15 DA dialektischer Algorithmus 0.86183 0.70033 0.33724 1.89940 0.98163 0.72772 0.28718 1.99653 0.70308 0.45292 0.16367 1.31967 5.216 57.95
16 BHAm Algorithmus für schwarze Löcher M 0.75236 0.76675 0.34583 1.86493 0.93593 0.80152 0.27177 2.00923 0.65077 0.51646 0.15472 1.32195 5.196 57.73
17 ASO Anarchische Gesellschaftsoptimierung 0.84872 0.74646 0.31465 1.90983 0.96148 0.79150 0.23803 1.99101 0.57077 0.54062 0.16614 1.27752 5.178 57.54
18 RFO Optimierung des Royal Flush (joo) 0.83361 0.73742 0.34629 1.91733 0.89424 0.73824 0.24098 1.87346 0.63154 0.50292 0.16421 1.29867 5.089 56.55
19 AOSm Suche nach atomaren Orbitalen M 0.80232 0.70449 0.31021 1.81702 0.85660 0.69451 0.21996 1.77107 0.74615 0.52862 0.14358 1.41835 5.006 55.63
20 TSEA Schildkrötenpanzer-Evolutionsalgorithmus (joo) 0.96798 0.64480 0.29672 1.90949 0.99449 0.61981 0.22708 1.84139 0.69077 0.42646 0.13598 1.25322 5.004 55.60
21 BSA Backtracking-Suchalgorithmus 0.97309 0.54534 0.29098 1.80941 0.99999 0.58543 0.21747 1.80289 0.84769 0.36953 0.12978 1.34700 4.959 55.10
22 DE differentielle Evolution 0.95044 0.61674 0.30308 1.87026 0.95317 0.78896 0.16652 1.90865 0.78667 0.36033 0.02953 1.17653 4.955 55.06
23 SRA Algorithmus für erfolgreiche Gastronomen (joo) 0.96883 0.63455 0.29217 1.89555 0.94637 0.55506 0.19124 1.69267 0.74923 0.44031 0.12526 1.31480 4.903 54.48
24 CRO Optimierung chemischer Prozesse 0.94629 0.66112 0.29853 1.90593 0.87906 0.58422 0.21146 1.67473 0.75846 0.42646 0.12686 1.31178 4.892 54.36
25 BIO Optimierung der Blutvererbung (joo) 0.81568 0.65336 0.30877 1.77781 0.89937 0.65319 0.21760 1.77016 0.67846 0.47631 0.13902 1.29378 4.842 53.80
26 BSA Vogelschwarm-Algorithmus 0.89306 0.64900 0.26250 1.80455 0.92420 0.71121 0.24939 1.88479 0.69385 0.32615 0.10012 1.12012 4.809 53.44
27 DEA Algorithmus zur Echoortung bei Delfinen 0.75995 0.67572 0.34171 1.77738 0.89582 0.64223 0.23941 1.77746 0.61538 0.44031 0.15115 1.20684 4.762 52.91
28 HS Harmoniesuche 0.86509 0.68782 0.32527 1.87818 0.99999 0.68002 0.09590 1.77592 0.62000 0.42267 0.05458 1.09725 4.751 52.79
29 SSG Setzen, Säen und Wachsen 0.77839 0.64925 0.39543 1.82308 0.85973 0.62467 0.17429 1.65869 0.64667 0.44133 0.10598 1.19398 4.676 51.95
30 BCOm Optimierung mit der bakteriellen Chemotaxis M 0.75953 0.62268 0.31483 1.69704 0.89378 0.61339 0.22542 1.73259 0.65385 0.42092 0.14435 1.21912 4.649 51.65
31 ABO Optimierung des afrikanischen Büffels 0.83337 0.62247 0.29964 1.75548 0.92170 0.58618 0.19723 1.70511 0.61000 0.43154 0.13225 1.17378 4.634 51.49
32 (PO)ES (PO) Evolutionsstrategien 0.79025 0.62647 0.42935 1.84606 0.87616 0.60943 0.19591 1.68151 0.59000 0.37933 0.11322 1.08255 4.610 51.22
33 FBA Fraktal-basierter Algorithmus 0.79000 0.65134 0.28965 1.73099 0.87158 0.56823 0.18877 1.62858 0.61077 0.46062 0.12398 1.19537 4.555 50.61
34 TSm Tabu-Suche M 0.87795 0.61431 0.29104 1.78330 0.92885 0.51844 0.19054 1.63783 0.61077 0.38215 0.12157 1.11449 4.536 50.40
35 BSO Brainstorming-Optimierung 0.93736 0.57616 0.29688 1.81041 0.93131 0.55866 0.23537 1.72534 0.55231 0.29077 0.11914 0.96222 4.498 49.98
36 WOAm Wal-Optimierungsalgorithmus M 0.84521 0.56298 0.26263 1.67081 0.93100 0.52278 0.16365 1.61743 0.66308 0.41138 0.11357 1.18803 4.476 49.74
37 AEFA Algorithmus für künstliche elektrische Felder 0.87700 0.61753 0.25235 1.74688 0.92729 0.72698 0.18064 1.83490 0.66615 0.11631 0.09508 0.87754 4.459 49.55
38 AEO Algorithmus zur Optimierung auf der Grundlage künstlicher Ökosysteme 0.91380 0.46713 0.26470 1.64563 0.90223 0.43705 0.21400 1.55327 0.66154 0.30800 0.28563 1.25517 4.454 49.49
39 CAm Kamel-Algorithmus M 0.78684 0.56042 0.35133 1.69859 0.82772 0.56041 0.24336 1.63149 0.64846 0.33092 0.13418 1.11356 4.444 49.37
40 ACOm Ameisen-Kolonie-Optimierung M 0.88190 0.66127 0.30377 1.84693 0.85873 0.58680 0.15051 1.59604 0.59667 0.37333 0.02472 0.99472 4.438 49.31
41 CMAES Anpassung der Kovarianzmatrix mittels Evolutionsstrategie 0.76258 0.72089 0.00000 1.48347 0.82056 0.79616 0.00000 1.61672 0.75846 0.49077 0.00000 1.24923 4.349 48.33
42 BFO-GA Optimierung der bakteriellen Futtersuche – ga 0.89150 0.55111 0.31529 1.75790 0.96982 0.39612 0.06305 1.42899 0.72667 0.27500 0.03525 1.03692 4.224 46.93
43 SOA einfacher Optimierungsalgorithmus 0.91520 0.46976 0.27089 1.65585 0.89675 0.37401 0.16984 1.44060 0.69538 0.28031 0.10852 1.08422 4.181 46.45
44 ABHA Algorithmus für künstliche Bienenstöcke 0.84131 0.54227 0.26304 1.64663 0.87858 0.47779 0.17181 1.52818 0.50923 0.33877 0.10397 0.95197 4.127 45.85
45 ACMO Optimierung atmosphärischer Wolkenmodelle 0.90321 0.48546 0.30403 1.69270 0.80268 0.37857 0.19178 1.37303 0.62308 0.24400 0.10795 0.97503 4.041 44.90
A3 Algorithmus_künstliches_Atom 0.70744 0.49461 0.27674 1.47879 0.89102 0.43888 0.17553 1.50543 0.53230 0.32707 0.11431 0.97368 3.958 43.98
RW Random Walk 0.48754 0.32159 0.25781 1.06694 0.37554 0.21944 0.15877 0.75375 0.27969 0.14917 0.09847 0.52734 2.348 26.09


Zusammenfassung

Der Artikel präsentierte die Implementierung des Algorithmus für künstliche Atome A3 in der Sprache MQL5 zur Lösung von Problemen bei der Optimierung von Handelsstrategien. Trotz der Unvollständigkeit der theoretischen Beschreibung durch die Autoren in der Originalarbeit ist es uns gelungen, eine funktionale praktische Implementierung zu erstellen. Die durchgeführten Tests zeigten, dass A3 ein gutes Gleichgewicht zwischen Rechengeschwindigkeit und Lösungsqualität aufweist. Nur zwei einstellbare Parameter vereinfachen den Prozess der Anpassung des Algorithmus an eine spezifische Aufgabe erheblich, was für Trader, die keine Optimierungsspezialisten sind, entscheidend ist. 

Der A3-Algorithmus könnte eine gewisse Nische unter den Optimierungsalgorithmen einnehmen. Der Algorithmus für künstliche Atome zeigt, dass selbst relativ einfache Metaheuristiken recht effektiv sein können, wenn sie ordnungsgemäß an ein bestimmtes Fachgebiet angepasst werden. Die Kombination aus konzeptioneller Einfachheit, rechnerischer Effizienz und ausreichender Lösungsqualität macht A3 zu einem guten Werkzeug im Werkzeugkasten des algorithmischen Traders.

Der Quellcode für den Algorithmus und Beispiele für seine Anwendung sind im Anhang des Artikels verfügbar, sodass Interessierte die Effizienz der Methode unabhängig bewerten und damit experimentieren können.

Tabelle

Abbildung 1. Farbabstufung der Algorithmen in den entsprechenden Tests

Histogramm

Abbildung 2. Histogramm der Algorithmus-Testergebnisse (Skala von 0 bis 100, je höher, desto besser, wobei 100 das maximal mögliche theoretische Ergebnis ist; im Archiv befindet sich ein Skript zur Berechnung der Bewertungstabelle)

A3 Vor- und Nachteile:

Vorteile:

  1. Schnell.
  2. Wenige Parameter.

Nachteile:

  1. Geringe Konvergenzgenauigkeit.

Ein Archiv mit den neuesten Versionen des Algorithmus-Codes ist dem Artikel beigefügt. Der Autor des Artikels übernimmt keine Verantwortung für die absolute Richtigkeit der Beschreibung der kanonischen Algorithmen. An vielen von ihnen wurden Änderungen vorgenommen, um die Suchmöglichkeiten zu verbessern. Die in den Artikeln dargelegten Schlussfolgerungen und Urteile beruhen auf den Ergebnissen der Experimente.


Im Artikel verwendete Programme

# Name Typ Beschreibung
1 #C_AO.mqh
Include
Übergeordnete Klasse von Populationsoptimierungsalgorithmen
2 #C_AO_enum.mqh
Include
Enumeration der Algorithmen zur Populationsoptimierung
3 TestFunctions.mqh
Include
Bibliothek mit Testfunktionen
4
TestStandFunctions.mqh
Include
Bibliothek mit Funktionen für die Testumgebung
5
Utilities.mqh
Include
Bibliothek mit Hilfsfunktionen
6
CalculationTestResults.mqh
Include
Skript zur Berechnung der Ergebnisse in der Vergleichstabelle
7
Testing AOs.mq5
Skript Die einheitliche Testumgebung für alle Algorithmen zur Populationsoptimierung
8
Simple use of population optimization algorithms.mq5
Skript
Ein einfaches Beispiel für die Verwendung von Algorithmen zur Populationsoptimierung ohne Visualisierung
9
Test_AO_A3.mq5
Skript A3-Testumgebung

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

Beigefügte Dateien |
A3.zip (258.97 KB)
Letzte Kommentare | Zur Diskussion im Händlerforum (7)
Auvoria Prime
Auvoria Prime | 26 Juni 2026 in 16:54

Mir geht es genauso, beim ersten Lesen war es nicht ganz einfach, lol. Die Idee klingt interessant, aber wenn die Regeln für kovalente/ionische Bindungen und die Elektronenverteilung nicht ganz klar sind, ist es schwer, den Algorithmus richtig einzuschätzen.

Für mich wäre ein einfaches Schritt-für-Schritt-Beispiel mit vielleicht zwei Atomen und ein paar Variablen hilfreich, das dann genau zeigt, wie eine Iteration die Lösung verändert. Ohne das wirkt es eher wie ein Konzept als wie etwas, das Trader wirklich verstehen oder testen können.

Chacha Ian Maroa
Chacha Ian Maroa | 29 Juni 2026 in 18:04
Was für ein verrücktes Konzept. Bitte schreib als Nächstes über das Optimierungskonzept der Urknalltheorie.
Ryan L Johnson
Ryan L Johnson | 29 Juni 2026 in 21:25
Chacha Ian Maroa #:
Was für ein verrücktes Konzept. Bitte schreib als Nächstes über das Optimierungskonzept der Urknalltheorie
Der Typ hatte genug von Roskosmos und ist stattdessen bei mql5.com gelandet.
Robson Bruno Teixeira De Sousa
Robson Bruno Teixeira De Sousa | 2 Juli 2026 in 00:15

Meine Bewertung

Stellen Sie sich eine Gruppe von 100 Kindern vor, die in einem Park nach einem versteckten Spielzeug suchen.

Jedes Kind beginnt an einer anderen Stelle.

Der Algorithmus funktioniert folgendermaßen:

  1. In der ersten Runde verteilt er alle Kinder an zufälligen Stellen im Park.
  2. Danach, in jeder Runde:
    • Schauen einige Kinder , wer dem Spielzeug am nächsten ist, und gehen ein Stück in dessen Richtung.
    • Andere Kinder folgen einem zufällig ausgewählten Kind aus der Gruppe derer, die gut vorankommen.
    • Von Zeit zu Zeit beschließt ein Kind, einen völlig neuen Ort zu erkunden, um zu sehen, ob es einen besseren Weg findet.
  3. Immer wenn ein Kind versucht, den Park zu verlassen, sagt der Algorithmus:

    „Nein! Bleib innerhalb der Grenzen des Parks.“

  4. Dieser Vorgang wiederholt sich mehrmals.

Am Ende kommt die gesamte Gruppe dem Spielzeug immer näher, da alle von denen lernen, die bessere Wege finden.

Kurz gesagt:

Der Algorithmus lässt mehrere „Personen“ versuchen, ein Problem zu lösen, wobei sie von den besten Lösungen lernen und manchmal neue Orte erkunden, um eine noch bessere Lösung zu finden.


Anmerkung: Der Code befindet sich noch in einem Zwischenstadium und bedarf einiger Anpassungen.


Andrey Dik
Andrey Dik | 14 Juli 2026 in 10:43
Chacha Ian Maroa #:
Was für eine verrückte Idee. Bitte schreib das nächste Mal etwas über das Konzept der Optimierung der Urknalltheorie

;D

https://www.mql5.com/de/articles/16963

Die Übertragung der Trading-Signale in einem universalen Expert Advisor. Die Übertragung der Trading-Signale in einem universalen Expert Advisor.
In diesem Artikel wurden die verschiedenen Möglichkeiten beschrieben, um die Trading-Signale von einem Signalmodul des universalen EAs zum Steuermodul der Positionen und Orders zu übertragen. Es wurden die seriellen und parallelen Interfaces betrachtet.
Marktsimulation: Positionsdarstellung (III) Marktsimulation: Positionsdarstellung (III)
In früheren Artikeln haben wir erwähnt, dass wir manchmal einen Wert für die Eigenschaft ZOrder festlegen müssen. Aber warum? Der Grund dafür ist, dass viele Codeteile, die Objekte in einem Chart hinzufügen, einfach keinen Wert für diese Eigenschaft verwenden oder, genauer gesagt, nicht definieren. Es geht mir nicht darum, zu sagen, was Programmierer tun oder lassen sollen und wie sie ihren Code schreiben sollten. Ich bin hier, um Ihnen, lieber Leser, und jedem, der wirklich verstehen will, wie diese Prozesse intern funktionieren, zu zeigen, was tatsächlich hinter den Kulissen passiert.
Eine alternative Log-datei mit der Verwendung der HTML und CSS Eine alternative Log-datei mit der Verwendung der HTML und CSS
In diesem Artikel werden wir eine sehr einfache, aber leistungsfähige Bibliothek zur Erstellung der HTML-Dateien schreiben, dabei lernen wir auch, wie man eine ihre Darstellung einstellen kann (nach seinem Geschmack) und sehen wir, wie man es leicht in seinem Expert Advisor oder Skript hinzufügen oder verwenden kann.
Risk Manager für Handelsroboter (Teil I): Include-Datei zur Risikokontrolle für Expert Advisors Risk Manager für Handelsroboter (Teil I): Include-Datei zur Risikokontrolle für Expert Advisors
Der Handel ist durch hohe Anforderungen an die Disziplin beim Risikomanagement gekennzeichnet. Der Artikel präsentiert eine Analyse der Hauptgründe für das Scheitern von Tradern und schlägt eine technische Lösung in Form der Klasse CEnhancedRiskManager für die MQL5-Plattform vor. Er beinhaltet praktische Tests mit einem aggressiven Grid-EA.