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.
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.
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 &¤tMinute>=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 :)
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!
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.
- 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 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 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