Cross-Plattform Expert Advisor: Geldmanagement
Inhaltsverzeichnis
- Einführung
- Ziele
- Basisklasse
- Klassen und Typen des Geldmanagements
- Container der Objekte für das Geldmanagement
- Beispiel
- Schlussfolgerung
Einführung
Das Geldmanagement ist ein gemeinsames Merkmal aller Expert Advisor. Es erlaubt dem Expert Advisor dynamisch die Lotgröße der nächsten Position zu bestimmen. In diesem Artikel stellen wir mehrere Klassen für das Geldmanagement vor, die uns den ganzen Prozess der Berechnung der Lotgröße eines Cross-Plattform Expert Advisors automatisieren.
Ziele
- Verstehen und anwenden der gängigsten Methoden des Geldmanagements im Handel
- Dem Expert Advisor ermöglichen aus eine Liste verfügbarer Methoden des Geldmanagement auszuwählen
- Kompatibilität mit MQL4 und MQL5
Basisklasse
Alle Klassen des Geldmanagements dieses Artikels habe eine bestimmte Basisklasse mit den Namen CMoney, abgeleitet von der Klasse CMoneyBase. Die Klasse CMoneyBase wird durch den folgenden Codeausschnitt definiert:
class CMoneyBase : public CObject { protected: bool m_active; double m_volume; double m_balance; double m_balance_inc; int m_period; bool m_equity; string m_name; CSymbolManager *m_symbol_man; CSymbolInfo *m_symbol; CAccountInfo *m_account; CEventAggregator *m_event_man; CObject *m_container; public: CMoneyBase(void); ~CMoneyBase(void); virtual int Type(void) const {return CLASS_TYPE_MONEY;} //--- Initialisierung virtual bool Init(CSymbolManager*,CAccountInfo*,CEventAggregator*); bool InitAccount(CAccountInfo*); bool InitSymbol(CSymbolManager*); CObject *GetContainer(void); void SetContainer(CObject*); virtual bool Validate(void); //--- Abfragen und Ändern bool Active(void) const; void Active(const bool); void Equity(const bool); bool Equity(void) const; void LastUpdate(const datetime); datetime LastUpdate(void) const; void Name(const string); string Name(void) const; double Volume(const string,const double,const ENUM_ORDER_TYPE,const double); void Volume(const double); double Volume(void) const; protected: virtual void OnLotSizeUpdated(void); virtual bool UpdateLotSize(const string,const double,const ENUM_ORDER_TYPE,const double); };
Die meisten Methoden dieser Klasse ändern oder erfragen verschiedene Klassenmitglieder und sind daher selbsterklärend. Für die praktische Anwendung sind aber nur drei Methoden wirklich wichtig UpdateLotSize, OnLotSizeUpdated, und Volume.
Die Methode UpdateLotSize berechnet das aktuelle Handelsvolumen. Sie ist auch, abgeleitet aus der Basisklasse, die Hauptmethode, und daher finden sich die meisten Unterschiede zwischen den verschiedenen Klassen für das Geldmanagement innerhalb dieser Methode. In der Basisklasse sind das quasi virtuelle Methoden, da sie nur einen Wert zurückgegeben:
bool CMoneyBase::UpdateLotSize(const string,const double,const ENUM_ORDER_TYPE,const double) { return true; }
Manchmal müssen nach dem Berechnen der Handelsvolumens bestimmte Variablen für eine weitere Berechnung aktualisiert werden. In diesem Fall wird die Methode OnLotSizeUpdated verwendet. Diese Methode wird automatisch innerhalb der Methode UpdateLotSize aufgerufen. Der folgende Code zeigt die erwähnte Methode:
void CMoneyBase::OnLotSizeUpdated(void) { m_symbol=m_symbol_man.Get(); double maxvol=m_symbol.LotsMax(); double minvol=m_symbol.LotsMin(); if(m_volume<minvol) m_volume=minvol; if(m_volume>maxvol) m_volume=maxvol; }
Um das aktuelle, von dem Objekt des Geldmanagements berechnete Handelsvolumen abzufragen, muss der Expert Advisor aber nicht UpdateLotSize oder OnLotSizeUpdated aufrufen. Es muss nur die Methode Volume der Klasse aufgerufen werden. Diese Methode selbst ruft automatisch die beiden anderen Methoden auf:
double CMoneyBase::Volume(const string symbol,const double price,const ENUM_ORDER_TYPE type,const double sl=0) { if(!Active()) return 0; if(UpdateLotSize(symbol,price,type,sl)) OnLotSizeUpdated(); return m_volume; }
Klassen und Typen des Geldmanagements
Feste Lotgröße
Das ist die wohl gängigste Methode der Bestimmung der Lotgröße und die, mit der die meisten Händler gut vertraut sind. Durch eine feste Lotgröße haben alle Positionen dieselbe Lotgröße, egal, ob der Kontostand steigt oder fällt.
Für diese Form des Geldmanagements benötigt man nur diese feste Lotgröße. Daher kann der größte Unterschied zwischen CMoney/CMoneyBase im Konstruktor gefunden werden, wo die feste Lotgröße bestimmt wird:
CMoneyFixedLotBase::CMoneyFixedLotBase(double volume) { Volume(volume); }Falls wir jetzt eine dynamische Veränderung des Ergebnisses dieser Methode des Geldmanagements wünschen, müssen wir nur das Klassenmitglied m_volume durch Aufruf der Methode Volume neu festsetzen.
Fixes Risiko (fixer Anteil)
Die Methode des fixen Risikos oder fixen Anteils des Geldmanagements reserviert eine festen Prozentsatz des Kontostandes oder des Eigenkapital je Position. Das ist Teil der Standardbibliothek durch CmoneyFixedRisk. Führt eine Position zu einem Verlust, entspricht dieser Verlust prozentual dem Kontostand zum Zeitpunkt der Eröffnung der Position. Dieser Verlust ist nicht einfach nur irgendein Verlust sondern der maximale Verlust, wenn z.B. der Markt den StopLoss der Position trifft. Diese Methode verlangt einen StopLoss größer als Null, damit sie funktioniert.
Die Berechnung des prozentualen Risikos einer Position berechnet sich nach folgender Formel:
Volume = (balance * account_percentage / ticks) / tick_value
wobei:
- balance – Kontostand oder Eigenkapital
- account_percentage – der zu riskierende Prozentsatz des Kontos (Bereich: 0,0-1,0)
- ticks – der Wert des StopLoss, ausgedrückt in Ticks
- tick_value – der Tick-Wert ist der Wert einer Bewegung um einen Tick des Symbols oder Handelsinstrumentes in der Kontowährung (basierend auf 1.0 Lot)
Ein Tick ist definiert als die kleinste Preisbewegung eines Währungspaars oder Handelsinstrumentes. Zum Beispiel hat der EURUSD (bei einem Broker mit 5 Dezimalen oder Digits) eine Tick-Größe (tick-size) von 0,00001, und das ist die kleinst mögliche Preisbewegung dieses Währungspaars. Wenn der Wert des StopLoss' in Points oder Pips ausgedrückt wird, ist das Ergebnis die Differenz zwischen den Preisen der Eröffnung und dem StopLoss einer Position in Points oder Pips.
Für dasselbe Währungspaar ist der Tick-Wert einer Währung eines 4-Digits-Broker anders als der eines 5-Digits-Broker. Das rührt daher, dass 1 Tick eines 4-Digits-Broker gleich einem Point (oder Pip), wohingegen der Pip einen 5-Digits-Broker 10 Points entspricht.
Als Beispiel eines Geldmanagements mit fixem Risiko, gehen wir von einem Kontostand von 1.000 USD und einem Risiko von 5% für eine neue Position aus. Nehmen wir Tick-Wert von 0,1 und einen StopLoss von 200 Points (20 Pips) einen 5-Digits-Broker:
Volume = (1000 * 0,05 / 200) / 0,1 = 2,5 Lot
Die errechnete Lotgröße steigt mit dem Prozentsatz des Risikos und dem Kontostand und fällt bei steigendem Abstand des StopLoss' oder des Tick-Werts. Der Kontostand, das Risiko und der Tick-Wert sind meistens konstant, sich ändernde StopLoss' (dynamisch berechnet) aber nicht. Dieser Ansatz ist aber in der Regel für Strategien ohne eine Begrenzung des Abstandes der Preise von Eröffnung und dem StopLoss ungeeignet, da das zu sehr kleinen (und vom Broker zurückgewiesenen) Lotgrößen führen würde. Andererseits führen zu kleine Differenzen des StopLoss' zu sehr großen Lotgrößen, eventuell auch zu Problemen mit dem Broker und dessen maximal erlaubter Lotgröße. Das Problem wurde durch den MetaTrader 5 dadurch gelöst, dass er Aufträge, wenn die Größen zu groß sind, in mehrere "Deals" aufteilt. Der MetaTrader 4 jedoch verfügt nicht über diese Fähigkeit – ein großes Handelsvolumen muss vorbereitet werden (aufgeteilt in mehrere kleinere Positionen) oder es wird einfach vermieden, die maximal erlaubte Lotgröße zu überschreiten.
Die Formel der Berechnung findet sich in der Methode UpdateLotSize:
bool CMoneyFixedFractionalBase::UpdateLotSize(const string symbol,const double price,const ENUM_ORDER_TYPE type,const double sl) { m_symbol=m_symbol_man.Get(symbol); double last_volume=m_volume; if(CheckPointer(m_symbol)) { double balance=m_equity==false?m_account.Balance():m_account.Equity(); double ticks=0; if(price==0.0) { if(type==ORDER_TYPE_BUY) ticks=MathAbs(m_symbol.Bid()-sl)/m_symbol.TickSize(); else if(type==ORDER_TYPE_SELL) ticks=MathAbs(m_symbol.Ask()-sl)/m_symbol.TickSize(); } else ticks=MathAbs(price-sl)/m_symbol.TickSize(); m_volume=((balance*(m_risk/100))/ticks)/m_symbol.TickValue(); } return NormalizeDouble(last_volume-m_volume,2)==0; }Zuerst holen wir uns den StopLoss in Ticks. Danach verwenden wir die obige Formel, um m_volume, das Mitglied der Klasse, zu aktualisieren, und verwenden das für den Rückgabewert.
Fixer Anteil
Ein Geldmanagement auf Basis eines fixen Anteils berechnet das Handelsvolumen als Anteil des verfügbaren Kontostandes. Das kann als ein Sonderfall des Geldmanagements mittels einer fixen Lotgröße betrachtet werden, mit dem Unterschied, dass die Lotgröße automatisch und nicht, durch den Händler, manuell angepasst wird. Steigt der Kontostand, erhöht sich die Lotgröße nach Überschreiten eines Schwellenwertes. Fällt der Kontostand, sinkt die Lotgröße entsprechend.
Anders als das Geldmanagement durch ein fixes Risiko, benötigt das eines fixen Anteils keinen StopLoss größer Null. Damit ist er ideal für Positionen ohne StopLoss und die, die in anderer Form (erreichter Gewinn/Verlust in Kontowährung etc.) beendet werden.
Die Berechnung des Positionsvolumens über einen fixen Anteil erfolgt in der Regel nach dieser Formel:
Volume = base_volume + (balance / balance_increase) * volume_increment
wobei:
- base_volume – Volumen, das dem Gesamtvolumen hinzugefügt wird, unabhängig vom Kontostand
- balance – aktueller Kontostand
- balance_increase – Erhöhung des Kontostandes, um die Erhöhung der Lotgröße auszulösen
- volume_increment – Volumen, um das das Gesamtvolumen erhöht/erniedrigt wird, wenn sich der Kontostand um "balance_increase" ändert
Als Beispiel nehmen wir ein Basisvolumen von 0,0 Lot an, und das Volumen soll sich um 0,1 je $1,000 auf dem Konto ändern. Der Kontostand betrage aktuell $2.500. Das Gesamtvolumen berechnet sich daher wie folgt:
Volume = 0 + (2500 / 1000) * 0,1 = 0,25 Lot
Diese Methode verfügt über viele Varianten. Eine von ihnen ändert die Lotgröße nur beim Erreichen festgelegter Level (dies ist das oben erwähnte Geldmanagement über einen fixen Anteil). Im obigen Beispiel errechneten wir ein Volumen von 0,25 Lots, aber es hätte auch bei 0,2 verbleiben können und sich erst ab einem Kontostand von $3.000 auf 0,3 Lot erhöht.
Diese Methode UpdateLotSize kann wie folgt implementiert werden:
bool CMoneyFixedRatioBase::UpdateLotSize(const string symbol,const double price,const ENUM_ORDER_TYPE type,const double sl=0) { m_symbol=m_symbol_man.Get(symbol); double last_volume=m_volume; if(CheckPointer(m_symbol)) { double balance=m_equity==false?m_account.Balance():m_account.Equity(); m_volume=m_volume_base+((int)(balance/m_balance_inc))*m_volume_inc; m_balance=balance; } return NormalizeDouble(last_volume-m_volume,2)==0; }
Fixes Risiko Pro Point (Fixe Marge)
Fixes Risiko Pro Point weist jedem Point des StopLoss einen bestimmten Wert in der Kontowährung zu. Der Algorithmus berechnet die Lotgröße auf Basis des gewünschten Tick-Werts des Händlers. Ist die Kontowährung beispielsweise USD und das fixe Risiko per Point bei 2,0, dann hat jeder Point des StopLoss' einen Wert von $2. Falls der StopLoss der Position 200 Points beträgt, dann beträgt das maximale Risiko der gesamten Position $400 ($400 wenn die Marktpreise den StopLoss der Position auslösen).
Für einen normalen Händler ist diese Form des Geldmanagements einfacher, da das Risiko der Position in einer dem Händler vertrauten Weise, z.B. der Kontowährung, dargestellt werden. Der Händler muss nur den gewünschten Tick-Wert des Vermögenswertes festlegen und dann wird das Handelsvolumen automatisch berechnet. Der Tick-Wert oder die Änderung von Gewinn/Verlust pro kleinster Preisbewegung bleiben gleich, aber das Gesamtrisiko hängt von der Größe des StopLoss' einer Position ab.
Unter Verwendung dieser Formel kann diese Methode des Geldmanagements in folgender Weise in der Methode UpdateLotSize implementiert werden:
bool CMoneyFixedRiskPerPointBase::UpdateLotSize(const string symbol,const double price,const ENUM_ORDER_TYPE type,const double sl=0) { m_symbol=m_symbol_man.Get(symbol); double last_volume=m_volume; if(CheckPointer(m_symbol)) { double balance=m_equity==false?m_account.Balance():m_account.Equity(); m_volume=(m_risk/m_symbol.TickValue()); } return NormalizeDouble(last_volume-m_volume,2)==0; }
Fixes Risiko (Fixe Marge)
Das fixe Risiko per Marge (margin) ist äquivalent zur Klasse CMoneyFixedMargin aus der Standardbibliothek von MQL5. Dies ist ein Sonderfall der Methode des fixen Risikos pro Point des Geldmanagements. Anders aber als das fixe Risiko pro Point berücksichtigt diese Methode den gesamten StopLoss in der Berechnung des Handelsvolumens, so dass das Risiko, unabhängig vom Größe des StopLoss', gleich bleibt. Im vorherigen Beispiel hatten wir einen StopLoss von 200 Points und $400 als maximales Risiko. Würde der StopLoss auf 100 Points reduziert werden, würde sich das maximale Risiko einer Position nach dem fixen Risiko pro Point halbieren ($200), wobei allerdings bei einem Geldmanagement mit fixen Margen das maximale Risiko konstant ($400) bleiben würde.
Mit dieser Formel können wir die Methode UpdateLotSize wie folgt implementieren:
bool CMoneyFixedRiskBase::UpdateLotSize(const string symbol,const double price,const ENUM_ORDER_TYPE type,const double sl) { m_symbol=m_symbol_man.Get(symbol); double last_volume=m_volume; if(CheckPointer(m_symbol)) { double balance=m_equity==false?m_account.Balance():m_account.Equity(); double ticks=0; if(price==0.0) { if(type==ORDER_TYPE_BUY) ticks=MathAbs(m_symbol.Bid()-sl)/m_symbol.TickSize(); else if(type==ORDER_TYPE_SELL) ticks=MathAbs(m_symbol.Ask()-sl)/m_symbol.TickSize(); } else ticks=MathAbs(price-sl)/m_symbol.TickSize(); m_volume=(m_risk/m_symbol.TickValue())/ticks; } return NormalizeDouble(last_volume-m_volume,2)==0; }Diese Formel ist ziemlich ähnlich der der fixen Risikos pro Point, außer, dass wir den Tick-Wert benötigen, um das Ergebnis der vorherigen Formel durch diesen Wert zu teilen.
Container der Objekte für das Geldmanagement
Ähnlich den besprochenen Signalklassen früherer Artikel erhält auch das Objekt für das Geldmanagement einen Container. Das erlaubt einem Expert Advisor dynamisch zwischen verschiedenen, verfügbaren Objekten des Geldmanagements aus einer Liste auszuwählen. Idealerweise agiert der Container als Mediator zwischen den Klassen des Geldmanagements und dem anderen Code des Expert Advisors. Die Basisklasse dieser Objekte ist CMoneysBase, die wie folgt definiert ist:
class CMoneysBase : public CArrayObj { protected: bool m_active; int m_selected; CEventAggregator *m_event_man; CObject *m_container; public: CMoneysBase(void); ~CMoneysBase(void); virtual int Type(void) const {return CLASS_TYPE_MONEYS;} //--- Initialisierung virtual bool Init(CSymbolManager*,CAccountInfo*,CEventAggregator*); CObject *GetContainer(void); void SetContainer(CObject*); virtual bool Validate(void) const; //--- setters and getters virtual bool Active(void) const; virtual void Active(const bool); virtual int Selected(void) const; virtual void Selected(const int); virtual bool Selected(const string); //--- volume calculation virtual double Volume(const string,const double,const ENUM_ORDER_TYPE,const double); };
Da das Objekt mehrere Objekte des Geldmanagements aufnehmen soll, benötigt es zur Verwendung durch einen Expert Advisor zumindest zwei Methoden:
- Entweder auswählen oder zwischen den Methoden des Geldmanagements dynamische wechseln
- Verwenden des Objektes des Geldmanagements und Abfrage des berechneten Handelsvolumens
Die Auswahl geschieht auf zwei Wegen: durch die Zuweisung eines Index des Arrays der Objekte des Geldmanagements (CMoneysBase extends CArrayObj), oder durch das Finden des Objektes auf Grund des Namens (Methode Name aus CMoneyBase/CMoney). Das Folgende zeigt die überladene Methode Selected, die als Argument eine Ganzzahl (oder Index) erwartet:
CMoneysBase::Selected(const int value) { m_selected=value; }
Das Folgende zeigt die überladene Methode Selected, die als Argument eine Zeichenkette (oder Namen des Objektes des Geldmanagements) erwartet: Beachten Sie, dass der Name des Objektes des Geldmanagements nicht 'leer' sein darf.
bool CMoneysBase::Selected(const string select) { for(int i=0;i<Total();i++) { CMoney *money=At(i); if(!CheckPointer(money)) continue; if(StringCompare(money.Name(),select)) { Selected(i); return true; } } return false; }
Die dritte Form der überladenen Methode erwartet kein Argument. Sie liefert einfach den Index des gewählten Objektes des Geldmanagements, das dann nützlich sein kann, wenn der Expert Advisor wissen will, welche Methode des Geldmanagements gerade ausgewählt ist:
int CMoneysBase::Selected(void) const { return m_selected; }Das aktuelle Volumen wird von der Methode Volumen dieses Objekts berechnet. Die Methode holt sich zuerst den Zeiger auf das Objekt der gewählten Methode des Geldmanagements und ruft dann deren Methode Volumen auf. Der Code der Methode Volumen von CMoneysBase folgt:
double CMoneysBase::Volume(const string symbol,const double price,const ENUM_ORDER_TYPE type,const double sl=0) { CMoney *money=At(m_selected); if(CheckPointer(money)) return money.Volume(symbol,price,type,sl); return 0; }
Hier wird greift die Methode auf das Objekt aus der Liste der Objekte zu und sichert den Zugang in einem Zeiger. Um Fehler zu vermeiden, muss man sicherstellen, dass das aktuelle Objekt in der Objektliste an der Stelle des Index existiert.
Beispiel
Als Beispiel verwenden wir das letzte Beispiel aus dem vorherigen Artikel. Wir verändern es so, dass wir in diesem Artikel die Klassen des Geldmanagements einfügen und platzieren sie in einem einzelnen Container und fügen das dem Order-Manager hinzu. Das Meiste wurde in der Funktion OnInit des EAs ergänzt, wie man unten sieht:
int OnInit() { //--- order_manager=new COrderManager(); money_manager = new CMoneys(); CMoney *money_fixed= new CMoneyFixedLot(0.05); //CMoney *money_ff= new CMoneyFixedFractional(5); CMoney *money_ratio= new CMoneyFixedRatio(0,0.1,1000); //CMoney *money_riskperpoint= new CMoneyFixedRiskPerPoint(0.1); //CMoney *money_risk= new CMoneyFixedRisk(100); money_manager.Add(money_fixed); //money_manager.Add(money_ff); money_manager.Add(money_ratio); //money_manager.Add(money_riskperpoint); //money_manager.Add(money_risk); order_manager.AddMoneys(money_manager); //order_manager.Account(money_manager); symbol_manager=new CSymbolManager(); symbol_info=new CSymbolInfo(); if(!symbol_info.Name(Symbol())) Print("symbol not set"); symbol_manager.Add(GetPointer(symbol_info)); order_manager.Init(symbol_manager,new CAccountInfo()); MqlParam params[1]; params[0].type=TYPE_STRING; #ifdef __MQL5__ params[0].string_value="Examples\\Heiken_Ashi"; #else params[0].string_value="Heiken Ashi"; #endif SignalHA *signal_ha=new SignalHA(Symbol(),0,1,params,signal_bar); SignalMA *signal_ma=new SignalMA(Symbol(),(ENUM_TIMEFRAMES) Period(),maperiod,0,mamethod,maapplied,signal_bar); signals=new CSignals(); signals.Add(GetPointer(signal_ha)); signals.Add(GetPointer(signal_ma)); signals.Init(GetPointer(symbol_manager),NULL); //--- return(INIT_SUCCEEDED); }
Wir haben die Zeilen für die Methoden des Geldmanagements des fixen Anteil, des fixen Risikos und des fixen Risikos pro Point eingefügt. Da die Methoden jedoch einen StopLoss größer als Null benötigen und unser EA diesbezüglich keine StopLoss erstellt, werden wir diese Methoden erst einmal übergehen. In der Zwischenzeit verwenden wir nur die Methoden des Geldmanagement der fixen Lotgröße und des fixen Anteils. Falls diese Objekte einen ungültigen StopLoss (kleiner Null) zurückgeben, wird die standardmäßige Lotgröße des Order-Managers verwendet (Standard ist 0,1 Lot des Mitglieds m_lotsize von ofCorderManager/COrderManagerBase) .
COrderManager hat ein eigenes Klassenmitglied, der ein Zeiger auf den Container (CMoney) des Geldmanagements ist. Die Verwendung des COrderManager bedeutet also, dass die Headerdatei des Geldmanagements in den Quellcode inkludiert werden müssen. Falls ein Experte den COrderManager nicht verwendet, dann muss die Direktive #include der Klassen des Geldmanagements im Quellcode angegeben werden.
In der Funktion OnTick ändern wir den EA dahingehend, dass er für Kaufpositionen fixe Lotgrößen und für Verkaufspositionen fixe Anteile für die Lotgrößen verwendet. Beides wird erreicht durch eine Änderung des gewählten Typs des Geldmanagements vor dem Aufruf der Methode TradeOpen des Order-Managers über die Methode Selected aus CMoneys:
void OnTick() { //--- if(symbol_info.RefreshRates()) { signals.Check(); if(signals.CheckOpenLong()) { close_last(); //Print("Entering buy trade.."); money_manager.Selected(0); order_manager.TradeOpen(Symbol(),ORDER_TYPE_BUY,symbol_info.Ask()); } else if(signals.CheckOpenShort()) { close_last(); //Print("Entering sell trade.."); money_manager.Selected(1); order_manager.TradeOpen(Symbol(),ORDER_TYPE_SELL,symbol_info.Bid()); } } }
Da das Geldmanagement im Grunde reine Mathematik ist, ist zu erwarten, dass die berechnete Lotgrößen im MetaTrader 4 und MetaTrader 5 gleich sind. Das Folgende zeigt die Testergebnisse des EAs im MetaTrader 4 (die ersten 10 Positionen):
# | Zeit | Typ | Order | Größe | Preis | S / L | T / P | Gewinn | Kontostand |
1 | 2017.01.02 00:00 | sell | 1 | 1.00 | 1.05100 | 0.00000 | 0.00000 | ||
2 | 2017.01.03 03:00 | close | 1 | 1.00 | 1.04679 | 0.00000 | 0.00000 | 419.96 | 10419.96 |
3 | 2017.01.03 03:00 | buy | 2 | 0.05 | 1.04679 | 0.00000 | 0.00000 | ||
4 | 2017.01.03 10:00 | close | 2 | 0.05 | 1.04597 | 0.00000 | 0.00000 | -4.10 | 10415.86 |
5 | 2017.01.03 10:00 | sell | 3 | 1.00 | 1.04597 | 0.00000 | 0.00000 | ||
6 | 2017.01.03 20:00 | close | 3 | 1.00 | 1.04285 | 0.00000 | 0.00000 | 312.00 | 10727.86 |
7 | 2017.01.03 20:00 | buy | 4 | 0.05 | 1.04285 | 0.00000 | 0.00000 | ||
8 | 2017.01.03 22:00 | close | 4 | 0.05 | 1.04102 | 0.00000 | 0.00000 | -9.15 | 10718.71 |
9 | 2017.01.03 22:00 | sell | 5 | 1.00 | 1.04102 | 0.00000 | 0.00000 | ||
10 | 2017.01.04 02:00 | close | 5 | 1.00 | 1.04190 | 0.00000 | 0.00000 | -89.04 | 10629.67 |
11 | 2017.01.04 02:00 | buy | 6 | 0.05 | 1.04190 | 0.00000 | 0.00000 | ||
12 | 2017.01.04 03:00 | close | 6 | 0.05 | 1.03942 | 0.00000 | 0.00000 | -12.40 | 10617.27 |
13 | 2017.01.04 03:00 | sell | 7 | 1.00 | 1.03942 | 0.00000 | 0.00000 | ||
14 | 2017.01.04 06:00 | close | 7 | 1.00 | 1.04069 | 0.00000 | 0.00000 | -127.00 | 10490.27 |
15 | 2017.01.04 06:00 | buy | 8 | 0.05 | 1.04069 | 0.00000 | 0.00000 | ||
16 | 2017.01.05 11:00 | close | 8 | 0.05 | 1.05149 | 0.00000 | 0.00000 | 54.05 | 10544.32 |
17 | 2017.01.05 11:00 | sell | 9 | 1.00 | 1.05149 | 0.00000 | 0.00000 | ||
18 | 2017.01.05 16:00 | close | 9 | 1.00 | 1.05319 | 0.00000 | 0.00000 | -170.00 | 10374.32 |
19 | 2017.01.05 16:00 | buy | 10 | 0.05 | 1.05319 | 0.00000 | 0.00000 | ||
20 | 2017.01.06 05:00 | close | 10 | 0.05 | 1.05869 | 0.00000 | 0.00000 | 27.52 | 10401.84 |
Im MetaTrader 5 sehen wir folgende Ergebnisse ("Hedging-Mode", die ersten 10 Positionen):
Orders |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Eröffnungszeit | Order | Symbol | Typ | Volumen | Preis | S / L | T / P | Zeit | Status | Kommentar | ||
2017.01.02 00:00:00 | 2 | EURUSD | sell | 1.00 / 1.00 | 1.05100 | 2017.01.02 00:00:00 | filled | |||||
2017.01.03 03:00:00 | 3 | EURUSD | buy | 1.00 / 1.00 | 1.04669 | 2017.01.03 03:00:00 | filled | |||||
2017.01.03 03:00:00 | 4 | EURUSD | buy | 0.05 / 0.05 | 1.04669 | 2017.01.03 03:00:00 | filled | |||||
2017.01.03 10:00:00 | 5 | EURUSD | sell | 0.05 / 0.05 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 10:00:00 | 6 | EURUSD | sell | 1.00 / 1.00 | 1.04597 | 2017.01.03 10:00:00 | filled | |||||
2017.01.03 20:00:00 | 7 | EURUSD | buy | 1.00 / 1.00 | 1.04273 | 2017.01.03 20:00:00 | filled | |||||
2017.01.03 20:00:00 | 8 | EURUSD | buy | 0.05 / 0.05 | 1.04273 | 2017.01.03 20:00:00 | filled | |||||
2017.01.03 22:00:00 | 9 | EURUSD | sell | 0.05 / 0.05 | 1.04102 | 2017.01.03 22:00:00 | filled | |||||
2017.01.03 22:00:00 | 10 | EURUSD | sell | 1.00 / 1.00 | 1.04102 | 2017.01.03 22:00:00 | filled | |||||
2017.01.04 02:00:00 | 11 | EURUSD | buy | 1.00 / 1.00 | 1.04180 | 2017.01.04 02:00:00 | filled | |||||
2017.01.04 02:00:00 | 12 | EURUSD | buy | 0.05 / 0.05 | 1.04180 | 2017.01.04 02:00:00 | filled | |||||
2017.01.04 03:00:00 | 13 | EURUSD | sell | 0.05 / 0.05 | 1.03942 | 2017.01.04 03:00:00 | filled | |||||
2017.01.04 03:00:00 | 14 | EURUSD | sell | 1.00 / 1.00 | 1.03942 | 2017.01.04 03:00:00 | filled | |||||
2017.01.04 06:00:00 | 15 | EURUSD | buy | 1.00 / 1.00 | 1.04058 | 2017.01.04 06:00:00 | filled | |||||
2017.01.04 06:00:00 | 16 | EURUSD | buy | 0.05 / 0.05 | 1.04058 | 2017.01.04 06:00:00 | filled | |||||
2017.01.05 11:00:00 | 17 | EURUSD | sell | 0.05 / 0.05 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 11:00:00 | 18 | EURUSD | sell | 1.00 / 1.00 | 1.05149 | 2017.01.05 11:00:00 | filled | |||||
2017.01.05 16:00:00 | 19 | EURUSD | buy | 1.00 / 1.00 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.05 16:00:00 | 20 | EURUSD | buy | 0.05 / 0.05 | 1.05307 | 2017.01.05 16:00:00 | filled | |||||
2017.01.06 05:00:00 | 21 | EURUSD | sell | 0.05 / 0.05 | 1.05869 | 2017.01.06 05:00:00 | filled |
Da der Order-Manager bereits die Unterschiede zwischen den beiden Plattformen (und Sprachen) berücksichtigt, sollten die Methoden und die Ergebnisse der Berechnung der Lotgrößen gleich sein und irgendwelche Unterschiede, die entstehen könnten, müssten dem Order-Manager selbst zuzuordnen sein.
Schlussfolgerung
Dieser Artikel zeigt wie das Geldmanagement in einem Cross-Plattform Expert Advisor integriert werden kann. Er bespricht 5 verschiedene Methoden des Geldmanagement. Er beschreibt auch einen eigenen Container von Objekten für die Zeiger auf diese Objekte, um dynamisch die Methode des Geldmanagements auszuwählen.
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/3280
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.