Diskussion zum Artikel "Dekodierung von Intraday-Handelsstrategien des Opening Range Breakout"

 

Neuer Artikel Dekodierung von Intraday-Handelsstrategien des Opening Range Breakout :

Die Strategien des Opening Range Breakout (ORB) basieren auf der Idee, dass die erste Handelsspanne, die sich kurz nach der Markteröffnung bildet, wichtige Preisniveaus widerspiegelt, bei denen sich Käufer und Verkäufer auf einen Wert einigen. Durch die Identifizierung von Ausbrüchen über oder unter einer bestimmten Spanne können Händler von der Dynamik profitieren, die oft folgt, wenn die Marktrichtung klarer wird. In diesem Artikel werden wir drei ORB-Strategien untersuchen, die von der Concretum Group übernommen wurden.

Die Strategien des Opening Range Breakout (ORB) basieren auf der Idee, dass die erste Handelsspanne, die sich kurz nach der Markteröffnung bildet, wichtige Preisniveaus widerspiegelt, bei denen sich Käufer und Verkäufer auf einen Wert einigen. Durch die Identifizierung von Ausbrüchen über oder unter einer bestimmten Spanne können Händler von der Dynamik profitieren, die oft folgt, wenn die Marktrichtung klarer wird. 

In diesem Artikel werden wir drei ORB-Strategien untersuchen, die aus den Papieren der Concretum Group übernommen wurden. Zunächst werden wir den Forschungshintergrund, einschließlich der Schlüsselkonzepte und der verwendeten Methodik, behandeln. Dann werden wir für jede Strategie erklären, wie sie funktioniert, ihre Signalregeln auflisten und ihre Leistung statistisch analysieren. Schließlich werden wir sie aus einer Portfolioperspektive betrachten und uns dabei auf das Thema Diversifizierung konzentrieren.  

Dieser Artikel geht nicht näher auf die Programmierung ein, sondern konzentriert sich stattdessen auf den Forschungsprozess, einschließlich der Nachbildung, Analyse und Prüfung der Strategien aus diesen drei Arbeiten. Dieses Buch ist für Leser geeignet, die auf der Suche nach potenziellen Handelsvorteilen sind oder sich dafür interessieren, wie diese Strategien untersucht und repliziert wurden. Dennoch wird der gesamte MQL5-Code für die EAs offengelegt werden. Die Leserinnen und Leser sind eingeladen, den Rahmen selbst zu erweitern.


Autor: Zhuo Kai Chen

 
Großartiger Artikel

Lohnenswert für jeden Trader, der diese Strategie verfolgt

Ich spreche aus meiner eigenen Erfahrung
 
Timmy T #:
Großartiger Artikel

Lohnenswert für jeden Trader, der diese Ziele verfolgt

Ich spreche aus meiner eigenen Erfahrung

Vielen Dank, Timmy.

 

In der Tat großer Artikel, schätzen die Zeit und Mühe, die Sie in das Schreiben des Codes investiert haben und teilen Sie es mit der Gemeinschaft.

Habe eine einfache Frage um"In den Studien, die wir anpassen, konzentrieren sie sich auf Strategien, die zwischen Markt öffnen und schließen (9:30 AM bis 4:00 PM Eastern Time) handeln.Da unser Broker UTC+2/3 verwendet, bedeutet dies 18:30-24:00 Uhr Serverzeit - stellen Sie sicher, dass Sie beim Testen die Zeitzone Ihres eigenen Brokers berücksichtigen.

Können Sie mir Ihren Gedankengang bei der Zeitumstellung erläutern? Ich habe hier eindeutig etwas übersehen.

Wenn ich einen allgemeinen Zeitkonverter benutze - meine Konvertierung von 09:30 Eastern Time endet bei 16:30, wenn mt5 in GMT+2 ist, und 17:30, wenn mt5 in GMT+3 ist. 18:30 fühlt sich an wie 1-2 Stunden nach der Markteröffnung.

Ich schätze die Unterstützung und danke nochmals.

Dateien:
NY_GMT.png  12 kb
 
Sunjoo Serverzeit - stellen Sie sicher, dass Sie beim Testen die Zeitzone Ihres Brokers berücksichtigen .

Können Sie mir Ihre Überlegungen zur Zeitumstellung erläutern? Ich übersehe hier eindeutig etwas.

Mit einem allgemeinen Zeitkonverter - meine Konvertierung von 09:30 Eastern Time endet als 16:30, wenn mt5 in GMT+2 ist, und 17:30, wenn mt5 in GMT+3 ist. 18:30 fühlt sich an, als wäre es 1-2 Stunden nach Marktöffnung.

Ich schätze die Unterstützung und danke nochmals.

Sie haben Recht, ich habe die Serverzeit im Artikel für die New Yorker Börsenöffnungszeit falsch umgerechnet. Sie sollte 17:30 Uhr statt 18:30 Uhr lauten. Damit können Sie davon ausgehen, dass alle meine Strategieregeln im Artikel 1 Stunde nach Börseneröffnung gehandelt werden sollten. Vielen Dank für den Hinweis und Entschuldigung für die Verwirrung.

 

Danke für den Beitrag, sehr interessant!

Eine Frage zum Code:

In deiner MarketOpened Funktion verwendest du:

"if (currentHour >= startHour && currentMinute>=startMinute)return true;" <- Das sieht so aus, als ob nur ein Teil der Stunde gehandelt wird, wenn der Markt geöffnet ist, da es false zurückgibt, wenn Sie am Anfang jeder Stunde sind, auch wenn der Markt geöffnet ist. Es funktioniert nur, wenn die Minute bei 0 ist, was nicht der Beginn der Marktsitzung ist.

 
Digitus #:

Danke für den Beitrag, sehr interessant!

Eine Frage zum Code:

In Ihrer Funktion MarketOpened verwenden Sie:

"if (currentHour >= startHour && currentMinute>=startMinute)return true;" <- Das sieht so aus, als ob nur ein Teil der Stunde gehandelt wird, wenn der Markt geöffnet ist, da es false zurückgibt, wenn Sie am Anfang jeder Stunde sind, auch wenn der Markt geöffnet ist. Es funktioniert nur, wenn die Minute bei 0 ist, was nicht der Beginn der Marktsitzung ist.

OMG, ich kann nicht glauben, dass ich das übersehen habe. Es sollte so sein:

    if ((currentHour >= startHour &&currentMinute>=startMinute)||currentHour>startHour)return true;

Ich entschuldige mich aufrichtig für den Flüchtigkeitsfehler. Danke, dass Sie so aufmerksam gelesen und mich darauf hingewiesen haben.

 

Ps. Für ORB3 habe ich die Zeit für die Markteröffnung auf 9:30 Uhr fest einprogrammiert. Sie können diese Funktionen so ändern, dass sie mit der Serverzeit der New Yorker Marktöffnungszeit übereinstimmen.

//+------------------------------------------------------------------+
//| Ermittelt den oberen Concretum-Band-Wert|
//+------------------------------------------------------------------+
double getUpperBand(int target_hour = 17, int target_min = 30) {
    // Abfrage der Uhrzeit des aktuellen Taktes
    datetime current_time = iTime(_Symbol, PERIOD_CURRENT, 0);
    MqlDateTime current_dt;
    TimeToStruct(current_time, current_dt);
    int current_hour = current_dt.hour;
    int current_min = current_dt.min;
    
    // Ermitteln Sie den heutigen Eröffnungskurs zur Zielzeit (z. B. 17:30 Uhr Serverzeit)
    datetime today_start = iTime(_Symbol, PERIOD_D1, 0);
    int bar_at_target_today = getBarShiftForTime(today_start, target_hour, target_min);
    if (bar_at_target_today < 0) return 0; // Rückgabe 0, wenn kein Zielbalken existiert
    double open_target_today = iOpen(_Symbol, PERIOD_M1, bar_at_target_today);
    if (open_target_today == 0) return 0; // Kein gültiger Preis
    
    // Berechnung von Sigma auf der Grundlage der letzten 14 Tage
    double sum_moves = 0;
    int valid_days = 0;
    for (int i = 1; i <= 14; i++) {
        datetime day_start = iTime(_Symbol, PERIOD_D1, i);
        int bar_at_target = getBarShiftForTime(day_start, target_hour, target_min);
        int bar_at_HHMM = getBarShiftForTime(day_start, current_hour, current_min);
        if (bar_at_target < 0 || bar_at_HHMM < 0) continue; // Überspringen, wenn keine Balken vorhanden sind
        double open_target = iOpen(_Symbol, PERIOD_M1, bar_at_target);
        double close_HHMM = iClose(_Symbol, PERIOD_M1, bar_at_HHMM);
        if (open_target == 0) continue; // Überspringen, wenn kein gültiger Eröffnungskurs
        double move = MathAbs(close_HHMM / open_target - 1);
        sum_moves += move;
        valid_days++;
    }
    if (valid_days == 0) return 0; // Rückgabe 0, wenn keine gültigen Daten
    double sigma = sum_moves / valid_days;
    
    // Berechnung der oberen Bandbreite
    double upper_band = open_target_today * (1 + sigma);
    
    // Zeichnen Sie einen blauen Punkt auf der oberen Bandebene
    string obj_name = "UpperBand_" + TimeToString(current_time, TIME_DATE|TIME_MINUTES|TIME_SECONDS);
    ObjectCreate(0, obj_name, OBJ_ARROW, 0, current_time, upper_band);
    ObjectSetInteger(0, obj_name, OBJPROP_ARROWCODE, 159); // Punkt-Symbol
    ObjectSetInteger(0, obj_name, OBJPROP_COLOR, clrBlue);
    ObjectSetInteger(0, obj_name, OBJPROP_WIDTH, 2);
    
    return upper_band;
}

//+------------------------------------------------------------------+
//| Ermittelt den unteren Concretum-Band-Wert|
//+------------------------------------------------------------------+
double getLowerBand(int target_hour = 17, int target_min = 30) {
    // Abfrage der Uhrzeit des aktuellen Taktes
    datetime current_time = iTime(_Symbol, PERIOD_CURRENT, 0);
    MqlDateTime current_dt;
    TimeToStruct(current_time, current_dt);
    int current_hour = current_dt.hour;
    int current_min = current_dt.min;
    
    // Ermitteln Sie den heutigen Eröffnungskurs zur Zielzeit (z. B. 17:30 Uhr Serverzeit)
    datetime today_start = iTime(_Symbol, PERIOD_D1, 0);
    int bar_at_target_today = getBarShiftForTime(today_start, target_hour, target_min);
    if (bar_at_target_today < 0) return 0; // Rückgabe 0, wenn kein Zielbalken existiert
    double open_target_today = iOpen(_Symbol, PERIOD_M1, bar_at_target_today);
    if (open_target_today == 0) return 0; // Kein gültiger Preis
    
    // Berechnung von Sigma auf der Grundlage der letzten 14 Tage
    double sum_moves = 0;
    int valid_days = 0;
    for (int i = 1; i <= 14; i++) {
        datetime day_start = iTime(_Symbol, PERIOD_D1, i);
        int bar_at_target = getBarShiftForTime(day_start, target_hour, target_min);
        int bar_at_HHMM = getBarShiftForTime(day_start, current_hour, current_min);
        if (bar_at_target < 0 || bar_at_HHMM < 0) continue; // Überspringen, wenn keine Balken vorhanden sind
        double open_target = iOpen(_Symbol, PERIOD_M1, bar_at_target);
        double close_HHMM = iClose(_Symbol, PERIOD_M1, bar_at_HHMM);
        if (open_target == 0) continue; // Überspringen, wenn kein gültiger Eröffnungskurs
        double move = MathAbs(close_HHMM / open_target - 1);
        sum_moves += move;
        valid_days++;
    }
    if (valid_days == 0) return 0; // Rückgabe 0, wenn keine gültigen Daten
    double sigma = sum_moves / valid_days;
    
    // Berechnen Sie die untere Bandbreite
    double lower_band = open_target_today * (1 - sigma);
    
    // Zeichnen Sie einen roten Punkt auf der unteren Bandebene
    string obj_name = "LowerBand_" + TimeToString(current_time, TIME_DATE|TIME_MINUTES|TIME_SECONDS);
    ObjectCreate(0, obj_name, OBJ_ARROW, 0, current_time, lower_band);
    ObjectSetInteger(0, obj_name, OBJPROP_ARROWCODE, 159); // Punkt-Symbol
    ObjectSetInteger(0, obj_name, OBJPROP_COLOR, clrRed);
    ObjectSetInteger(0, obj_name, OBJPROP_WIDTH, 2);
    
    return lower_band;
}

Die Änderung der Berechnungszeit könnte ein Weg sein, die Strategie weiter zu optimieren :)

 
Zhuo Kai Chen #:

OMG, ich kann nicht glauben, dass ich das übersehen habe. Es sollte sein:

Ich entschuldige mich aufrichtig für den Flüchtigkeitsfehler. Danke, dass Sie so aufmerksam gelesen und mich darauf hingewiesen haben.

Keine Sorge, ich habe den offenen und den geschlossenen Markt bereits in einer Funktion zusammengeführt.

bool MarketState()
{
   MqlDateTime structTime;
   TimeCurrent(structTime);
   structTime.sec = 0;
   structTime.hour = startHour;
   structTime.min = startMinute; 
   datetime timeStart = StructToTime(structTime);
   structTime.hour = endHour;
   structTime.min = endMinute;   
   datetime timeEnd = StructToTime(structTime);
   if(TimeCurrent() >= timeStart && TimeCurrent() < timeEnd)return true;
   else return false;
}


Noch eine Sache: Sie verwenden die OHLC-Daten des Brokers für Backtests, ohne Verzögerung. Diese Backtests scheinen etwas optimistisch zu sein, verglichen mit Backtests, die mit echten Tickdaten mit zufälliger Verzögerung für Slippage und Requotes durchgeführt werden.

Nochmals vielen Dank für Ihre Bemühungen!

 
Digitus #:

Keine Sorge, ich habe den offenen und den geschlossenen Markt bereits in einer Funktion zusammengefasst.


Eine weitere Sache: Sie verwenden Broker OHLC Daten für Backtesting, keine Verzögerung. Diese Backtests scheinen ein bisschen optimistisch im Vergleich zu Backtests auf echte Tick-Daten mit zufälliger Verzögerung für Slippage und requotes getan.

Nochmals vielen Dank für Ihre Bemühungen!

Gut gemacht mit Ihrer Änderung! Ich habe den gesamten Code in meinem Github aktualisiert.

Für Ihr Anliegen, die Handelslogik tritt jede neue Bar und beinhaltet nicht Tick-Bewegung. Außerdem beträgt die durchschnittliche Haltedauer nur ein paar Stunden, was meiner Meinung nach kein signifikantes Slippage-Problem darstellen wird. Ich würde sagen, nur sehr wenige Makler bieten echte Tick-Daten für mehr als 5 Jahre, und 1 min OHLC ist genug.

 
Großartiger Artikel