Diskussion zum Artikel "Entwicklung eines Expertenberaters für mehrere Währungen (Teil 3): Überarbeitung der Architektur"

 

Neuer Artikel Entwicklung eines Expertenberaters für mehrere Währungen (Teil 3): Überarbeitung der Architektur :

Wir haben bereits einige Fortschritte bei der Entwicklung eines Mehrwährungs-EAs mit mehreren parallel arbeitenden Strategien gemacht. In Anbetracht der gesammelten Erfahrungen sollten wir die Architektur unserer Lösung überprüfen und versuchen, sie zu verbessern, bevor wir zu weit vorpreschen.

Wir haben ein EA-Objekt (der Klasse CAdvisor oder ihrer Nachkommen) zugewiesen, das ein Aggregator von Handelsstrategieobjekten (Klasse CStrategy oder ihrer Abkömmlinge) ist. Zu Beginn der EA-Operation geschieht Folgendes in OnInit():

  • EA-Objekt wird erstellt.
  • Objekte von Handelsstrategien werden erstellt und dem EA in seinem Array für Handelsstrategien hinzugefügt.

In OnTick() geschieht Folgendes:

  • Die Methode CAdvisor::Tick() wird für das EA-Objekt aufgerufen.
  • Diese Methode durchläuft alle Strategien und ruft deren Methode CStrategy::Tick() auf.
  • Die Strategien innerhalb von CStrategy::Tick() führen alle notwendigen Operationen zum Öffnen und Schließen von Marktpositionen aus.

Dies kann schematisch wie folgt dargestellt werden:

Abb. 1. Betriebsart des ersten Artikels

Der Vorteil dieses Modus war, dass es möglich war, den EA über eine Reihe relativ einfacher Operationen mit anderen Instanzen von Handelsstrategien arbeiten zu lassen, vorausgesetzt, man hatte den Quellcode eines EA, der einer bestimmten Handelsstrategie folgte.

Der größte Nachteil hat sich jedoch schnell herausgestellt: Bei der Kombination mehrerer Strategien müssen wir die Größe der Positionen, die von jeder Instanz der Strategie eröffnet werden, mehr oder weniger reduzieren. Dies kann dazu führen, dass einige oder sogar alle Strategiefälle vollständig vom Handel ausgeschlossen werden. Je mehr Strategieinstanzen wir in die parallele Arbeit einbeziehen oder je kleiner die anfängliche Einlage ist, desto wahrscheinlicher ist ein solches Ergebnis, da die Mindestgröße der offenen Marktpositionen festgelegt ist.

Autor: Yuriy Bykov

 
FOREACH(m_orders, if(m_orders[i].IsOpen()) { m_ordersTotal += 1; })

Manchmal treibt einen etwas Inneres dazu an, so zu schreiben.

FOREACH(m_orders, m_ordersTotal += m_orders[i].IsOpen())
 
Ich habe noch nicht alles bis zum Ende gelesen. Aber ich habe das Gefühl, dass die Arbeit mit den anhängigen (nicht im Tester) nicht wirklich in diese, in der Tat, viel verbesserte Architektur passt.
 

Es wäre gut, eine Maske zum Ein- und Ausschalten einer Strategie hinzuzufügen, um den Volumetricianer (Empfänger von virtuellen Volumina) zu berücksichtigen.

Zum Beispiel müssen Sie einige TS aus dem Portfolio für eine Weile ausschalten: es weiterhin virtuell zu handeln, aber nicht auf die reale Umgebung. Ähnlich verhält es sich mit seinem umgekehrten Einschalten.

 
Ich kann mir nicht vorstellen, wie man diese Architektur auf Anhieb verfeinern kann. Das ist die einzige Möglichkeit, es jetzt zu tun.
//+------------------------------------------------------------------+
//|| Experten-Basisklasse|
//+------------------------------------------------------------------+
class CAdvisor {
protected:
   CStrategy         *m_strategies[];  // Palette von Handelsstrategien

Aber irgendwo muss es eine kompetente Einbettung von etwas Ähnlichem geben.

 CAdvisor *m_advisors[];  // Array mit virtuellen Portfolios

mit seinen eigenen Magiern.

 
Оповещение получателя и стратегии должно происходить только при открытии или закрытии виртуальной позиции.

Selbst im Tester kann es zu Schwierigkeiten kommen, wenn die Kurssitzung nicht mit der Handelssitzung übereinstimmt.

Das Kennzeichen, dass die Volumensynchronisierung erfolgreich war, kann Sie retten.

 
//+------------------------------------------------------------------+
//| Klasse der virtuellen Aufträge und Positionen |
//+------------------------------------------------------------------+
class CVirtualOrder {
private:
//--- Statische Felder ...
   
//--- Verwandte Empfänger- und Strategieobjekte
   CVirtualReceiver  *m_receiver;
   CVirtualStrategy  *m_strategy;

Es ist eine fragwürdige Lösung, eine völlig andere Einheit in einen virtuellen Auftrag einzufügen.

Es scheint, dass bei der Erstellung der Architektur das Leistungsproblem parallel gelöst wurde. Ich habe selbst eine solche Sünde.


Wahrscheinlich ist es immer noch richtig, ohne Rücksicht auf die Leistung zu entwerfen. Und dann zu überlegen, wie man das Ganze beschleunigen kann.

 
fxsaber #:
Ich habe noch nicht alles bis zum Ende gelesen. Aber ich habe das Gefühl, dass die Arbeit mit schwebenden Aufträgen (nicht im Tester) nicht wirklich in diese, in der Tat, viel verbesserte Architektur passt.

Ich arbeite nicht mit echten schwebenden Aufträgen, es scheint zu reichen, Marktpositionen zu eröffnen, wenn virtuelle schwebende Aufträge ausgelöst werden. Mir ist klar, dass dies aufgrund von Slippage und Requotes im realen Handel mit nicht ganz exakten Eingaben verbunden sein kann. Aber in der Praxis ist mir das noch nicht begegnet. Die Unterstützung für virtuelle Pending Orders wird im nächsten Teil enthalten sein.

Wenn Sie sich weiterhin mit realen Pending-Orders herumschlagen wollen, dann erlaubt es die Architektur im Prinzip: Sie müssen eine weitere Implementierung der Klasse CVirtualSymbolReceiver schreiben. Die aktuelle Implementierung ignoriert virtuelle schwebende Aufträge einfach.

 
fxsaber #:

Es wäre eine gute Idee, eine Ein/Aus-Strategie-Maske hinzuzufügen, um den Volumetrician (Empfänger virtueller Volumen) zu berücksichtigen.

Wenn Sie z.B. einen TS für eine Weile aus dem Portfolio ausschalten müssen, wird er virtuell weiter gehandelt, hat aber keine Auswirkungen auf die reale Umgebung. Ähnlich verhält es sich mit seinem umgekehrten Einschalten.

Es ist nicht schwer, so etwas zu realisieren, aber ohne es zu benutzen, brauchen Sie klare Ein- und Ausschaltkriterien für jede Strategie. Das ist eine komplexere Aufgabe, an die ich mich noch nicht herangewagt habe; wahrscheinlich werde ich es auch nicht tun.

 
fxsaber #:

Und irgendwo muss es eine kompetente Einbindung von so etwas geben.

CAdvisor *m_advisors[];  // Array mit virtuellen Portfolios

mit ihren eigenen Magiern.

Dafür gibt es keine Pläne. Die Zusammenführung in Portfolios wird auf einer Zwischenebene zwischen CAdvisor und CStrategy erfolgen. Es gibt einen Lösungsentwurf, der sich aber während des laufenden Refactorings noch stark verändern dürfte.

 
fxsaber Handelssitzung liegt.

Das Kennzeichen, dass die Volumensynchronisierung erfolgreich war, kann Sie retten.

Es scheint bereits vorhanden zu sein:

class CVirtualSymbolReceiver : public CReceiver {
  ...
   bool              m_isChanged;      // Gibt es Änderungen in der Zusammensetzung der virtuellen Positionen?

Es wird nur zurückgesetzt, wenn das erforderliche reale Volumen für jedes Symbol erfolgreich geöffnet wurde.