Diskussion zum Artikel "Fortgeschrittene Algorithmen für die Auftragsausführung in MQL5: TWAP, VWAP und Eisberg-Aufträge"
Toller Artikel!
Welche Paare empfehlen Sie für diesen Algo?
Welche Zeitrahmen? M5, M30 usw.
Welche Session?
Vielen Dank und herzliche Grüße
Testing your algo.
IN file, ExecutionAlgorithm.mqh, added this line request.type_filling = ORDER_FILLING_IOC; in placing order to fix order placing issue.
Zurück getestet es auf M5, es öffnete nur 1 Handel für 2 Monate Zeitraum, keine partielle Bestellung geöffnet.
Getestet es auf H1, es nie angewendet, die SL oder TP und alle Trades geschlossen in Verlust.
auch während der Kompilierung erzeugt es Warnungen
schlagen Sie vor, wie der Algo getestet werden soll,
Zeitrahmen. und andere Empfehlungen.
auch beim Kompilieren werden Warnungen erzeugt
Ich habe die Codezeile
m_volumeProfile[intervalIndex] += rates[i].tick_volu
in
geändert.
Es behebt die Warnungen
Jetzt brauchen Sie guidence in Bezug auf meine anderen Fragen, wie
Zeitrahmen
und auch
warum alle Trades während Backtest Ergebnis in Verlust
wie man diese große Arbeit von Ihnen zu testen.
schlagen Sie vor, wie der Algo getestet werden soll,
Zeitrahmen. und andere Empfehlungen.
Die Warnungen sind nicht das Problem, könnten aber schnell behoben werden. Aber ja, es wäre toll, wenn der Autor Schritt für Schritt zeigen könnte, welche Einstellungen und Eingaben er für den Backtest verwendet hat.
Ich stimme Dominic zu, da die Warnungen nur Warnungen sind. Die Ergebnisse von I_Virgo sind wahrscheinlich darauf zurückzuführen, dass er den falschen Zeitrahmen und das falsche Währungspaar verwendet hat. Aus dem Backtest-Bericht mit fast 2000 Bars geht hervor, dass es entweder M1 oder M5 als Zeitrahmen mit einem unbekannten Paar war.
Es wäre schön, wenn MQ den Zeitrahmen und das Währungspaar oder die Währungspaare hinzufügen und auch die Paar-Ergebnisse in mehr Details zum Back-Test-Bericht trennen würde, so dass wir die Back-Test-Ergebnisse des Autors genauer replizieren und seine Anwendbarkeit auf die Forex-Paare bestimmen könnten. Außerdem wäre es äußerst hilfreich, wenn der EA Text auf das Diagramm schreiben könnte, während er läuft.
Ich denke auch, dass es ein großartiger Artikel ist und plane, ihn gründlich zu studieren, um seine Techniken auf andere EAs zu übertragen.
CapeCoddah
//+------------------------------------------------------------------+ //| Basisklasse für alle Ausführungsalgorithmen| //+------------------------------------------------------------------+ class CExecutionAlgorithm { protected: string m_symbol; // Handelssymbol double m_totalVolume; // Gesamtvolumen für die Ausführung double m_executedVolume; // Volumen bereits ausgeführt double m_remainingVolume; // Verbleibendes Volumen zur Ausführung datetime m_startTime; // Startzeitpunkt der Ausführung datetime m_endTime; // Endzeitpunkt der Ausführung int m_slippage; // Erlaubter Schlupf in Punkten bool m_isActive; // Ist der Algorithmus derzeit aktiv // Statistik double m_avgExecutionPrice; // Durchschnittlicher Ausführungspreis int m_totalOrders; // Gesamtzahl der erteilten Aufträge int m_filledOrders; // Anzahl der ausgeführten Aufträge public: // Konstrukteur CExecutionAlgorithm(string symbol, double volume, datetime startTime, datetime endTime, int slippage); // Destruktor virtual ~CExecutionAlgorithm(); // Virtuelle Methoden, die von abgeleiteten Klassen implementiert werden müssen virtual bool Initialize(); virtual bool Execute() = 0; virtual bool Update() = 0; virtual bool Terminate() = 0; // Gemeinsame Methoden bool IsActive() { return m_isActive; } double GetExecutedVolume() { return m_executedVolume; } double GetRemainingVolume() { return m_remainingVolume; } double GetAverageExecutionPrice() { return m_avgExecutionPrice; } // Hilfsmethoden bool PlaceOrder(ENUM_ORDER_TYPE orderType, double volume, double price = 0.0); bool ModifyOrder(ulong ticket, double price, double sl, double tp); bool CancelOrder(ulong ticket); void UpdateAverageExecutionPrice(double price, double volume); // Hilfsmethode zur Ermittlung des geeigneten Füllmodus ENUM_ORDER_TYPE_FILLING GetFillingMode(); }; //+------------------------------------------------------------------+ //| Konstruktor| //+------------------------------------------------------------------+ CExecutionAlgorithm::CExecutionAlgorithm(string symbol, double volume, datetime startTime, datetime endTime, int slippage) { m_symbol = symbol; m_totalVolume = volume; m_executedVolume = 0.0; m_remainingVolume = volume; m_startTime = startTime; m_endTime = endTime; m_slippage = slippage; m_isActive = false; m_avgExecutionPrice = 0.0; m_totalOrders = 0; m_filledOrders = 0; } //+------------------------------------------------------------------+ //| Destruktor| //+------------------------------------------------------------------+ CExecutionAlgorithm::~CExecutionAlgorithm() { // Ressourcen bereinigen, falls erforderlich } //+------------------------------------------------------------------+ //| Initialisierung des Algorithmus| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::Initialize() { // Eingaben validieren if(m_symbol == "" || m_totalVolume <= 0.0) { Print("Invalid inputs for execution algorithm"); return false; } // Prüfen, ob das Symbol existiert if(!SymbolSelect(m_symbol, true)) { Print("Symbol not found: ", m_symbol); return false; } // Statistik zurücksetzen m_executedVolume = 0.0; m_remainingVolume = m_totalVolume; m_avgExecutionPrice = 0.0; m_totalOrders = 0; m_filledOrders = 0; return true; } //+------------------------------------------------------------------+ //| Geeigneten Füllmodus für das Symbol holen | //+------------------------------------------------------------------+ ENUM_ORDER_TYPE_FILLING CExecutionAlgorithm::GetFillingMode() { // Abrufen von Symbolfüllmodi int filling_modes = (int)SymbolInfoInteger(m_symbol, SYMBOL_FILLING_MODE); // Prüfen Sie die verfügbaren Befüllungsmodi in der Reihenfolge ihrer Präferenz if((filling_modes & SYMBOL_FILLING_FOK) == SYMBOL_FILLING_FOK) return ORDER_FILLING_FOK; else if((filling_modes & SYMBOL_FILLING_IOC) == SYMBOL_FILLING_IOC) return ORDER_FILLING_IOC; else return ORDER_FILLING_RETURN; } //+------------------------------------------------------------------+ //| Eine Bestellung aufgeben| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::PlaceOrder(ENUM_ORDER_TYPE orderType, double volume, double price = 0.0) { // Eingaben validieren if(volume <= 0.0) { Print("Invalid order volume"); return false; } // Vorbereiten der Anfrage MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.symbol = m_symbol; request.volume = volume; request.type = orderType; request.deviation = m_slippage; request.magic = 123456; // Magische Zahl zur Identifizierung // Geeignete Aktion und Preis je nach Auftragsart festlegen if(orderType == ORDER_TYPE_BUY || orderType == ORDER_TYPE_SELL) { // Marktauftrag request.action = TRADE_ACTION_DEAL; request.type_filling = GetFillingMode(); if(orderType == ORDER_TYPE_BUY) request.price = SymbolInfoDouble(m_symbol, SYMBOL_ASK); else request.price = SymbolInfoDouble(m_symbol, SYMBOL_BID); } else { // Schwebende Bestellung request.action = TRADE_ACTION_PENDING; if(price <= 0.0) { Print("Price must be specified for pending orders"); return false; } request.price = price; } // Senden Sie die Bestellung if(!OrderSend(request, result)) { Print("OrderSend error: ", GetLastError()); return false; } // Prüfen Sie das Ergebnis if(result.retcode != TRADE_RETCODE_DONE) { Print("OrderSend failed with code: ", result.retcode, " - ", result.comment); return false; } // Statistiken aktualisieren m_totalOrders++; // Bei Marktaufträgen wird die Ausführungsstatistik sofort aktualisiert. if(orderType == ORDER_TYPE_BUY || orderType == ORDER_TYPE_SELL) { m_filledOrders++; UpdateAverageExecutionPrice(request.price, volume); m_executedVolume += volume; m_remainingVolume -= volume; } Print("Order placed successfully. Ticket: ", result.order, " Volume: ", volume, " Price: ", request.price); return true; } //+------------------------------------------------------------------+ //| Ändern einer bestehenden Bestellung| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::ModifyOrder(ulong ticket, double price, double sl, double tp) { // Vorbereiten der Anfrage MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.action = TRADE_ACTION_MODIFY; request.order = ticket; request.price = price; request.sl = sl; request.tp = tp; // Senden Sie die Änderungsanfrage if(!OrderSend(request, result)) { Print("OrderModify error: ", GetLastError()); return false; } // Prüfen Sie das Ergebnis if(result.retcode != TRADE_RETCODE_DONE) { Print("OrderModify failed with code: ", result.retcode, " - ", result.comment); return false; } Print("Order modified successfully. Ticket: ", ticket); return true; } //+------------------------------------------------------------------+ //| Stornieren einer bestehenden Bestellung| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::CancelOrder(ulong ticket) { // Vorbereiten der Anfrage MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.action = TRADE_ACTION_REMOVE; request.order = ticket; // Senden Sie die Stornierungsanfrage if(!OrderSend(request, result)) { Print("OrderCancel error: ", GetLastError()); return false; } // Prüfen Sie das Ergebnis if(result.retcode != TRADE_RETCODE_DONE) { Print("OrderCancel failed with code: ", result.retcode, " - ", result.comment); return false; } Print("Order cancelled successfully. Ticket: ", ticket); return true; } //+------------------------------------------------------------------+ //| Aktualisierung des durchschnittlichen Ausführungspreises| //+------------------------------------------------------------------+ void CExecutionAlgorithm::UpdateAverageExecutionPrice(double price, double volume) { // Berechnen Sie den neuen durchschnittlichen Ausführungspreis if(m_executedVolume > 0.0) { // Gewogener Durchschnitt der alten und neuen Preise m_avgExecutionPrice = (m_avgExecutionPrice * m_executedVolume + price * volume) / (m_executedVolume + volume); } else { // Erste Ausführung m_avgExecutionPrice = price; } } //+------------------------------------------------------------------+
- 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.
Neuer Artikel Fortgeschrittene Algorithmen für die Auftragsausführung in MQL5: TWAP, VWAP und Eisberg-Aufträge :
„Sicher“, könnten Sie mit den Schultern zucken, „aber ich werde keine institutionellen Summen verschieben“. Der Clou: Das müssen Sie nicht. Ganz gleich, ob Sie ein halbes Los oder eine Handvoll Minilose einsetzen, die Volatilität kann Ihre Ausführung immer noch beeinträchtigen. Diese Werkzeuge helfen Ihnen:
Fliegen Sie unter dem Radar: Vor allem Eisberg-Aufträge verschleiern Ihre wahre Auftragsgröße und lassen neugierige Algos im Dunkeln.
Die heutige demokratisierte Landschaft bedeutet, dass die gleiche Ausführungstechnologie, die früher Millionenbudgets erforderte, jetzt auf Ihrer persönlichen Handelsstation laufen kann. Indem Sie den ausgefeilten MQL5-Code für TWAP-, VWAP- und Iceberg-Strategien in Ihre Plattform einfügen, rüsten Sie sich mit institutioneller Feuerkraft aus - ohne jemals den Einzelhandelsbereich zu verlassen.
Autor: N Soumik