English 日本語
preview
Verbessern Sie Ihren Handel mit Smart Money Konzepten (SMC): OB, BOS und FVG

Verbessern Sie Ihren Handel mit Smart Money Konzepten (SMC): OB, BOS und FVG

MetaTrader 5Beispiele |
134 12
Hlomohang John Borotho
Hlomohang John Borotho

Einführung

Manchmal stehen Händler vor der Herausforderung, dass ihre Strategien inkonsistent sind und sie oft zwischen Indikatoren, Setups und Methoden hin- und herspringen, ohne einen soliden Rahmen zu haben, der sie leitet. Dieser Mangel an Struktur kann zu Verwirrung, verpassten Chancen und zunehmender Frustration führen, wenn sich die Marktbedingungen ändern und die traditionellen Instrumente nicht mehr mithalten können. In diesem Thema untersuchen wir die Vorteile eines einzigen EA, der mehrere Smart Money Concept (SMC)-Strategien in einer einzigen leistungsstarken Lösung vereint.

Smart Money Concepts (SMC) bieten einen strukturierten Weg zum Verständnis des Marktverhaltens durch Order Blocks (OB), Break of Structure (BOS) und Fair Value Gaps (FVG). Durch die Kombination dieser Funktionen in einem einzigen EA können Händler ihre Arbeitsabläufe vereinfachen, die Entscheidungsfindung automatisieren und sich auf die aussagekräftigsten Preisaktionssignale konzentrieren. Egal, ob Sie den Automodus für eine nahtlose Ausführung nutzen oder einzelne Konzepte auswählen, dieser Ansatz reduziert das Rätselraten und macht den Handel effizienter, konsistenter und anpassungsfähiger an sich ändernde Marktbedingungen.



Logik des Experten

Order Block:

Ein Order Block (OB) stellt die letzte Auf- oder Abwärtskerze vor einer bedeutenden Marktbewegung dar und zeigt oft an, wo institutionelle Händler ihre Aufträge platziert haben. Wenn der Kurs diese Zonen wieder erreicht, fungieren sie in der Regel als starke Unterstützungs- oder Widerstandsbereiche, die mit hoher Wahrscheinlichkeit Handelsmöglichkeiten bieten. In diesem EA wird die Erkennung von Order Blocks noch verbessert, indem der Fibonacci-Indikator zur Validierung integriert wird, um sicherzustellen, dass die Handelsgeschäfte mit wichtigen Retracement- oder Extension-Levels übereinstimmen. Wie im vorangegangenen Artikel erläutert, werden durch die Kombination von OB und Fibonacci-Bestätigung schwächere Setups herausgefiltert, sodass Händler einen zuverlässigeren Rahmen für den Einstieg in den Handel und die Verwaltung von Handelsgeschäften erhalten.

Fair Value Gap:

Eine Fair Value Gap (FVG) tritt auf, wenn ein Ungleichgewicht in der Kursbewegung besteht, das typischerweise durch eine starke impulsive Bewegung entsteht, bei der eine oder mehrere Kerzen eine Lücke zwischen den Dochten der vorangehenden und der nachfolgenden Kerzen hinterlassen. Diese Lücke spiegelt die Ineffizienz des Marktes wider, auf dem nicht alle Aufträge ausgeführt wurden, und der Preis kehrt oft zurück, um diese Lücke zu „füllen“, bevor er seine beabsichtigte Richtung fortsetzt. Durch das Aufspüren von FVGs und das Handeln um diese herum, können Händler potenzielle Rückschritte in diese Zonen antizipieren und so präzise Einstiegsmöglichkeiten mit klar definiertem Risiko und Ertrag bieten.

Break Of Structure:

Ein Break Of Structure (BOS) tritt auf, wenn der Kurs über einen vorherigen hohen oder tiefen Umkehrpunkt unter einen vorherigen tiefen Umkehrpunkt durchbricht und damit eine potenzielle Richtungsänderung des Marktes signalisiert. Im letzten Artikel haben wir uns darauf konzentriert, zu verkaufen, wenn ein hoher Umkehrpunkt durchbrochen wurde, um das Abwärtsmomentum zu nutzen. Bei diesem Ansatz wird die BOS-Logik jedoch so verfeinert, dass sie mit dem vorherrschenden Markttrend übereinstimmt, d. h., wenn ein hoher Umkehrpunkt durchbrochen wird, suchen wir nach einer Kaufgelegenheit, um die Aufwärtsbewegung zu bestätigen, während ein Durchbruch eines tiefen Umkehrpunktes eine Verkaufsgelegenheit signalisiert. Diese Verschiebung sorgt dafür, dass der Handel der vorherrschenden Marktströmung folgt, anstatt ihr entgegenzuwirken.

Systemarchitektur:



Die ersten Schritte

//+------------------------------------------------------------------+
//|                                                 SMC_ALL_IN_1.mq5 |
//|                        GIT under Copyright 2025, MetaQuotes Ltd. |
//|                     https://www.mql5.com/en/users/johnhlomohang/ |
//+------------------------------------------------------------------+
#property copyright "GIT under Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com/en/users/johnhlomohang/"
#property version   "1.01"
#property description "Unified SMC: FVG + Order Blocks + BOS. Detect + Draw + Trade."

#include <Trade/Trade.mqh>
#include <Trade/PositionInfo.mqh>

CTrade         trade;
CPositionInfo  pos;

enum ENUM_STRATEGY
{
   STRAT_OB,         // Use Order Blocks Only
   STRAT_FVG,        // Use FVGs Only
   STRAT_BOS,        // Use Break of Structure Only
   STRAT_AUTO        // Auto (All SMC Concepts)
};
enum SWING_TYPE{
   SWING_OB,
   SWING_BOS,
};

Der Code enthält die MetaTrader-Handelsbibliotheken, insbesondere CTrade und CPositionInfo, die dem EA das Platzieren und Verwalten von Handelsgeschäften sowie den Zugriff auf Informationen über offene Positionen ermöglichen. Durch die Einrichtung dieser Klassen zu Beginn stellt der EA sicher, dass er über die wichtigsten Werkzeuge verfügt, die für die Auftragsausführung und Positionsverfolgung erforderlich sind.

Im nächsten Teil werden die strategische Flexibilität und die Klassifizierung für eine Umkehrung durch Enumerationen definiert. ENUM_STRATEGY gibt Händlern die Möglichkeit zu wählen, welcher Methode der EA folgen soll: strikt Order Blocks, strikt FVGs, strikt BOS, oder ein vollautomatischer Modus (STRAT_AUTO), der alle drei Konzepte dynamisch nutzt. In ähnlicher Weise unterscheidet die Enumeration SWING_TYPE zwischen Umkehrpunkten, die für Order Blocks verwendet werden, und solchen, die für die Analyse von Break of Structure verwendet werden. Diese Struktur macht den Code modular und anpassungsfähig, sodass Händler mit verschiedenen SMC-Ansätzen experimentieren oder den EA automatisch auf Basis der Marktbedingungen entscheiden lassen können.

//----------------------------- Inputs ------------------------------//
input ENUM_STRATEGY TradeStrategy   = STRAT_AUTO;
input double        In_Lot          = 0.02;
input double        StopLoss        = 3500;   // points
input double        TakeProfit      = 7500;   // points
input long          MagicNumber     = 76543;

input int           SwingPeriod     = 5;      // bars each side to confirm swing
input int           SwingProbeBar   = 5;      // bar index we test for swings (>=SwingPeriod)
input double        Fib_Trade_lvls  = 61.8;   // OB retrace must reach this %
input bool          DrawBOSLines    = true;

input int           FVG_MinPoints   = 3;      // minimal gap in points
input int           FVG_ScanBars    = 20;     // how many bars to scan for FVGs
input bool          FVG_TradeAtEQ   = true;   // trade at 50% of the gap (EQ)
input bool          OneTradePerBar  = true;

//---------------------------- Colors -------------------------------//
#define BullOB   clrLime
#define BearOB   clrRed
#define BullFVG  clrPaleGreen
#define BearFVG  clrMistyRose
#define BOSBull  clrDodgerBlue
#define BOSBear  clrTomato

In diesem Abschnitt des Codes werden die Eingaben definiert, die der Händler an seinen Handelsstil und seine Risikomanagementpräferenzen anpassen kann. Mit der Eingabe der TradeStrategy kann der Nutzer auswählen, ob der EA nur mit Order Blocks, nur mit Fair Value Gaps, nur mit Break of Structure oder automatisch mit einer Kombination aus allen drei Strategien handeln soll. Die Einstellungen für das Risiko- und Geldmanagement werden über In_Lot, StopLoss, TakeProfit und MagicNumber gesteuert, die eine korrekte Losgröße, schützende Stopps, Gewinnziele und eine eindeutige Handelsidentifizierung gewährleisten. Darüber hinaus geben Erkennungsparameter der Umkehrpunkte wie SwingPeriod und SwingProbeBar an, wie viele Balken bei der Identifizierung von hohen oder tiefen Umkehrpunkten berücksichtigt werden, während Fib_Trade_lvls sicherstellt, dass die Handelsgeschäfte des Order Blocks mit der Fibonacci-Retracement-Bestätigung übereinstimmen. Die Option DrawBOSLines bietet Flexibilität bei der Chartdarstellung und ermöglicht es Händlern, Break of Structure-Levels direkt auf dem Chart zu sehen.

Es folgen die Einstellungen von Fair Value Gap (FVG), die eine genauere Kontrolle darüber ermöglichen, wie Lücken erkannt und gehandelt werden. FVG_MinPoints stellt sicher, dass nur signifikante Ungleichgewichte berücksichtigt werden, während FVG_ScanBars festlegt, wie weit zurück in der Historie der EA nach gültigen Gaps suchen soll. Die Option FVG_TradeAtEQ ermöglicht den Handel auf dem Gleichgewichtsniveau (50 % des Gaps), das in der SMC-Theorie häufig als ausgewogener Einstiegspunkt angesehen wird. Schließlich machen Farbdefinitionen wie BullOB, BearOB, BullFVG, BearFVG, BOSBull und BOSBear die Chartobjekte visuell intuitiv, sodass Händler auf einen Blick zwischen Auf- und Abwärts-Setups unterscheiden können.

//---------------------------- Globals ------------------------------//
double   Bid, Ask;
datetime g_lastBarTime = 0;

// OB state
class COrderBlock : public CObject
{
public:
   int      direction;   // +1 bullish, -1 bearish
   datetime time;        // OB candle time
   double   high;        // OB candle high
   double   low;         // OB candle low

   string Key() const { return TimeToString(time, TIME_DATE|TIME_MINUTES); }

   void draw(datetime tmS, datetime tmE, color clr){
      string objOB = " OB REC" + TimeToString(time);
      ObjectCreate( 0, objOB, OBJ_RECTANGLE, 0, time, low, tmS, high);
      ObjectSetInteger( 0, objOB, OBJPROP_FILL, true);
      ObjectSetInteger( 0, objOB, OBJPROP_COLOR, clr);
      
      string objtrade = " OB trade" + TimeToString(time);
      ObjectCreate( 0, objtrade, OBJ_RECTANGLE, 0, tmS, high, tmE, low); // trnary operator
      ObjectSetInteger( 0, objtrade, OBJPROP_FILL, true);
      ObjectSetInteger( 0, objtrade, OBJPROP_COLOR, clr);
   }
};
COrderBlock* OB = NULL;

// OB fib state
// Track if an OB has already been traded
datetime lastTradedOBTime = 0;
bool tradedOB = false;
double fib_low, fib_high;
datetime fib_t1, fib_t2;
bool isBullishOB = false; 
bool isBearishOB = false;
datetime T1;
datetime T2;
color OBClr;
#define FIB_OB_BULL "FIB_OB_BULL"
#define FIB_OB_BEAR "FIB_OB_BEAR"
#define FIBO_OBJ "Fibo Retracement"

// BOS state 
datetime lastBOSTradeTime = 0;
bool Bull_BOS_traded, Bear_BOS_traded;
int lastBOSTradeDirection = 0; // 1 for buy, -1 for sell
double   swng_High = -1.0, swng_Low = -1.0;
datetime bos_tH = 0, bos_tL = 0;

In diesem globalen Abschnitt des Codes werden die Hauptvariablen und -strukturen festgelegt, die den Marktstatus, die Handelsmöglichkeiten und die Chartobjekte verfolgen. Es beginnt mit einfachen globalen Werten wie Bid, Ask und g_lastBarTime, die für die Preisverfolgung in Echtzeit wichtig sind und sicherstellen, dass der Expert Advisor die Logik nur einmal pro neuem Balken ausführt. Von dort aus wird eine spezielle Klasse, COrder Block, erstellt, um die Eigenschaften eines Order Blocks zu kapseln, einschließlich seiner Richtung (Auf- oder Abwärts), der Zeit und der Preisniveaus (Hoch/Tief). Die Klasse enthält auch eine Funktion draw(), die automatisch Rechtecke auf dem Chart erstellt und einfärbt, sodass Händler aktive Orderblöcke und ihre Handelszonen leicht erkennen können. Durch die Zentralisierung dieser Funktionen in einer Klasse bleibt der Code übersichtlich und wiederverwendbar.

Neben der grundlegenden OB-Identifikation werden zusätzliche Variablen definiert, um die Fibonacci-basierte Validierung von Order Blocks zu handhaben. Zum Beispiel speichern fib_low, fib_high und die Zeitmarken fib_t1 und fib_t2 die Grenzen für Fibonacci-Retracement-Levels, während Flags wie isBullishOB, isBearishOB und tradedOB sicherstellen, dass jeder Order Block nur einmal validiert und gehandelt wird. Diese Variablen ermöglichen es dem EA, Fibonacci-Levels dynamisch zu referenzieren, um sicherzustellen, dass nur gültige Retracements (wie z.B. das 61,8%-Level, das in den Eingaben definiert ist) für Handelseinträge berücksichtigt werden. Um die Visualisierung zu verdeutlichen, definieren Konstanten wie FIB_OB_BULL, FIB_OB_BEAR und FIBO_OBJ die Namen der Chart-Objekte und stellen sicher, dass Fibonacci-Retracements beim Zeichnen unterscheidbar sind.

Schließlich wird die Verwaltung des Zustands Break of Structure (BOS) eingeführt. Die Variablen lastBOSTradeTime, Bull_BOS_traded und Bear_BOS_traded verhindern, dass doppelte Abschlüsse ausgeführt werden, wenn ein BOS-Signal auftritt. Die lastBOSTradeDirection hält fest, ob der letzte BOS-Handel aufwärts (+1) oder abwärts (-1) war, während swng_High und swng_Low die letzten Umkehrpunkte zur Strukturerkennung speichern. Die Zeitmarken bos_tH und bos_tL sind enthalten, um die genauen Zeitpunkte zu identifizieren, zu denen die Schwankungen bestätigt wurden, und um die Übereinstimmung mit den Marktstrukturregeln zu gewährleisten. Durch die globale Verwaltung dieser Zustände stellt der EA die Konsistenz zwischen verschiedenen Strategien (OB, BOS, FVG) sicher und verhindert überlappende Handelsgeschäfte, wodurch eine strukturierte Grundlage für die Handelsautomatisierung des Smart Money Concept geschaffen wird.

//--------------------------- Helpers -------------------------------//
double  getHigh(int i)   { return iHigh(_Symbol, _Period, i);  }
double  getLow(int i)    { return iLow(_Symbol, _Period, i);   }
double  getOpen(int i)   { return iOpen(_Symbol, _Period, i);  }
double  getClose(int i)  { return iClose(_Symbol, _Period, i); }
datetime getTimeBar(int i){ return iTime(_Symbol, _Period, i); }

bool IsNewBar()
{
   datetime lastbar_time = (datetime)SeriesInfoInteger(_Symbol, _Period, SERIES_LASTBAR_DATE);
   if(g_lastBarTime == 0) { g_lastBarTime = lastbar_time; return false; }
   if(g_lastBarTime != lastbar_time) { g_lastBarTime = lastbar_time; return true; }
   return false;
}

void ExecuteTrade(ENUM_ORDER_TYPE type)
{
   double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
   double price = (type==ORDER_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK)
                                         : SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double sl = (type==ORDER_TYPE_BUY) ? price - StopLoss*point
                                      : price + StopLoss*point;
   double tp = (type==ORDER_TYPE_BUY) ? price + TakeProfit*point
                                      : price - TakeProfit*point;
   sl = NormalizeDouble(sl, _Digits);
   tp = NormalizeDouble(tp, _Digits);

   trade.SetExpertMagicNumber(MagicNumber);
   trade.PositionOpen(_Symbol, type, In_Lot, price, sl, tp, "SMC");
}

Die Hilfsfunktionen hier bieten eine saubere und wiederverwendbare Möglichkeit zur Interaktion mit Chart-Daten. Anstatt integrierte Funktionen wie iHigh, iLow oder iClose direkt im Code aufzurufen, erleichtern Wrapper wie getHigh(), getLow() und getClose() den Zugriff auf Balkeninformationen und verbessern gleichzeitig die Lesbarkeit. Die Funktion IsNewBar() spielt eine entscheidende Rolle, wenn es darum geht, dass der EA die Logik nur einmal pro Kerze verarbeitet, um wiederholte Ausführungen innerhalb desselben Balkens zu vermeiden. Dazu wird die letzte bekannte Balkenzeit in g_lastBarTime gespeichert und mit dem Zeitstempel des aktuellen Balkens verglichen. Dieser effiziente Ansatz stellt sicher, dass Signale und Handelsgeschäfte nur dann berücksichtigt werden, wenn ein neuer Balken geöffnet wird, was für Strategien, die sich auf bestätigte Kerzenabschlüsse verlassen, von entscheidender Bedeutung ist.

Die Funktion ExecuteTrade() kapselt die gesamte Logik der Handelsausführung. Es berechnet automatisch den korrekten Einstiegskurs, Stop Loss und Take Profit auf der Grundlage des Auftragstyps (Kauf oder Verkauf) und stellt sicher, dass die Werte so normalisiert werden, dass sie der Dezimalgenauigkeit des Instruments entsprechen. Durch die Zentralisierung dieser Logik vermeidet der EA sich wiederholenden Code und reduziert Fehler bei der Eröffnung von Handelsgeschäften. Die Funktion legt auch die eindeutige MagicNumber des EA zur Nachverfolgung fest und versieht jeden Handel mit dem Kommentar „SMC“, sodass Händler die von diesem System eröffneten Positionen leicht identifizieren können.

//----------------------- Unified Swing Detection -------------------//
// Detects if barIndex is a swing high and/or swing low using len bars on each side.
// If swing high found -> updates fib_high/fib_tH (and swng_High/bos_tH if for BOS).
// If swing low  found -> updates fib_low/fib_tL (and swng_Low/bos_tL if for BOS).
// return: true if at least one swing found.
void DetectSwingForBar(int barIndex, SWING_TYPE type)
{
   const int len = 5;
   bool isSwingH = true, isSwingL = true;   

   for(int i = 1; i <= len; i++){
      int right_bars = barIndex - i;
      int left_bars  = barIndex + i;
      
      if(right_bars < 0) {
         isSwingH = false;
         isSwingL = false;
         break;
      }
      
      if((getHigh(barIndex) <= getHigh(right_bars)) || (left_bars < Bars(_Symbol, _Period) && getHigh(barIndex) < getHigh(left_bars)))
         isSwingH = false;
      
      if((getLow(barIndex) >= getLow(right_bars)) || (left_bars < Bars(_Symbol, _Period) && getLow(barIndex) > getLow(left_bars)))
         isSwingL = false;
   }

   // Assign with ternary operator depending on swing type
   if(isSwingH){
      if(type == SWING_OB) {
         fib_high = getHigh(barIndex);
         fib_t1 = getTimeBar(barIndex);
      } else {
         swng_High = getHigh(barIndex);
         bos_tH = getTimeBar(barIndex);
      }
   }
   if(isSwingL){
      if(type == SWING_OB) {
         fib_low = getLow(barIndex);
         fib_t2 = getTimeBar(barIndex);
      } else {
         swng_Low = getLow(barIndex);
         bos_tL = getTimeBar(barIndex);
      }
   }
}

Die einheitliche Erkennungsfunktion der Umkehrpunkte dient dazu, potenzielle hohe und tiefe Umkehrpunkte auf dem Chart zu identifizieren, indem ein bestimmter Balken untersucht und mit einer bestimmten Anzahl von benachbarten Balken verglichen wird. Bei einem symmetrischen Bereich (len Balken auf jeder Seite) prüft die Funktion, ob der aktuelle Balken ein lokales Extremum bildet, d. h. ob sein Hoch über dem linken und rechten Balken liegt (hoher Umkehrpunkt) oder ob sein Tief unter beiden Seiten liegt (tiefer Umkehrpunkt). Wenn ein Balken auf der linken oder rechten Seite diese Bedingungen ungültig macht, wird die Umkehr-Kennzeichnung zurückgewiesen. Diese Methode stellt sicher, dass Ausschläge nicht fälschlicherweise durch geringfügige Schwankungen ausgelöst werden, sondern sich auf aussagekräftige Drehpunkte in der Marktstruktur konzentrieren.

Sobald ein Umkehrpunkt bestätigt wird, aktualisiert die Funktion die Schlüsselvariablen je nach Typ des Umkehrpunktes. Für die Erkennung von Order Blocks (SWING_OB) werden den Fibonacci-Ankerpunkten (fib_high und fib_low) hohe und tiefe Umkehrpunkte zusammen mit ihren Zeitstempeln zugeordnet, die später für die Retracement-Validierung verwendet werden. Für die BOS-Logik (Break of Structure) werden dieselben Schwankungspegel swng_High oder swng_Low zugewiesen, gepaart mit ihren jeweiligen Zeitstempeln (bos_tH oder bos_tL). Durch die Verarbeitung von OB und BOS in einer einzigen Funktion hält der EA die Erkennung von Umkehrpunkten schlank und vermeidet redundante Logik, sodass sowohl die Strukturvalidierung als auch die Fibonacci-Retracement-Setups denselben konsistenten Erkennungsprozess von Umkehrpunkten nutzen.

void DetectAndDrawOrderBlocks()
{
   static datetime lastDetect = 0;
   datetime lastBar = (datetime)SeriesInfoInteger(_Symbol, _Period, SERIES_LASTBAR_DATE);
   
   // Reset OB detection on new bar
   if(lastDetect != lastBar)
   {
      if(OB != NULL) 
      { 
         delete OB; 
         OB = NULL; 
      }
      lastDetect = lastBar;
   }
   
   // Only detect new OB if we don't have one already
   if(OB == NULL)
   {
      for(int i = 1; i < 100; i++)
      {
         // Bullish OB candidate
         if(getOpen(i) < getClose(i) && 
            getOpen(i+2) < getClose(i+2) &&
            getOpen(i+3) > getClose(i+3) && 
            getOpen(i+3) < getClose(i+2))
         {
            OB = new COrderBlock();
            OB.direction = 1;
            OB.time = getTimeBar(i+3);
            OB.high = getHigh(i+3);
            OB.low = getLow(i+3);
            OBClr = BullOB;
            T1 = OB.time;
            Print("Bullish Order Block detected at: ", TimeToString(OB.time));
            break;
         }
         
         // Bearish OB candidate
         if(getOpen(i) > getClose(i) && 
            getOpen(i+2) > getClose(i+2) &&
            getOpen(i+3) < getClose(i+3) && 
            getOpen(i+3) > getClose(i+2)) // Fixed condition
         {
            OB = new COrderBlock();
            OB.direction = -1;
            OB.time = getTimeBar(i+3);
            OB.high = getHigh(i+3);
            OB.low = getLow(i+3);
            OBClr = BearOB;
            T1 = OB.time;
            Print("Bearish Order Block detected at: ", TimeToString(OB.time));
            break;
         }
      }
   }

   if(OB == NULL) return;
   
   // Check if we already traded this OB
   if(lastTradedOBTime == OB.time) return;

   // If price retraces inside OB zone
   Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

   bool inBullZone = (OB.direction > 0 && Ask <= OB.high && Ask >= OB.low);
   bool inBearZone = (OB.direction < 0 && Bid >= OB.low && Bid <= OB.high);

   if(!inBullZone && !inBearZone) return;

   // Use your DetectSwing function to find swings
   // We need to call it multiple times to find the most recent swings
   double mostRecentSwingHigh = 0;
   double mostRecentSwingLow = EMPTY_VALUE;
   datetime mostRecentSwingHighTime = 0;
   datetime mostRecentSwingLowTime = 0;
   
   // Scan recent bars to find the most recent swings
   for(int i = 0; i < 20; i++) // Check the last 20 bars
   {
      // Reset swing variables
      fib_high = 0;
      fib_low = 0;
      fib_t1 = 0;
      fib_t2 = 0;
      
      DetectSwingForBar(i, SWING_OB);
      
      if(fib_high > 0 && (mostRecentSwingHighTime == 0 || fib_t1 > mostRecentSwingHighTime))
      {
         mostRecentSwingHigh = fib_high;
         mostRecentSwingHighTime = fib_t1;
      }
      
      if(fib_low < EMPTY_VALUE && (mostRecentSwingLowTime == 0 || fib_t2 > mostRecentSwingLowTime))
      {
         mostRecentSwingLow = fib_low;
         mostRecentSwingLowTime = fib_t2;
      }
   }
   
   // Ensure we found both swing points
   if(mostRecentSwingHighTime == 0 || mostRecentSwingLowTime == 0) return;
   
   // Draw Fibonacci before trading to validate
   if(OB.direction > 0 && inBullZone)
   {
      // Draw Fibonacci from recent swing low to recent swing high
      ObjectDelete(0, "FIB_OB_BULL");
      if(ObjectCreate(0, "FIB_OB_BULL", OBJ_FIBO, 0, mostRecentSwingLowTime, mostRecentSwingLow, 
                     mostRecentSwingHighTime, mostRecentSwingHigh))
      {
         // Format Fibonacci
         ObjectSetInteger(0, "FIB_OB_BULL", OBJPROP_COLOR, clrBlack);
         for(int i = 0; i < ObjectGetInteger(0, "FIB_OB_BULL", OBJPROP_LEVELS); i++)
         {
            ObjectSetInteger(0, "FIB_OB_BULL", OBJPROP_LEVELCOLOR, i, clrBlack);
         }
         
         double entLvlBull = mostRecentSwingHigh - (mostRecentSwingHigh - mostRecentSwingLow) * (Fib_Trade_lvls / 100.0);
         
         if(Ask <= entLvlBull)
         {
            T2 = getTimeBar(0);
            OB.draw(T1, T2, BullOB);
            ExecuteTrade(ORDER_TYPE_BUY);
            lastTradedOBTime = OB.time; // Mark this OB as traded
            delete OB;
            OB = NULL;
         }
      }
   }
   else if(OB.direction < 0 && inBearZone)
   {
      // Draw Fibonacci from recent swing high to recent swing low
      ObjectDelete(0, "FIB_OB_BEAR");
      if(ObjectCreate(0, "FIB_OB_BEAR", OBJ_FIBO, 0, mostRecentSwingHighTime, mostRecentSwingHigh, 
                     mostRecentSwingLowTime, mostRecentSwingLow))
      {
         // Format Fibonacci
         ObjectSetInteger(0, "FIB_OB_BEAR", OBJPROP_COLOR, clrBlack);
         for(int i = 0; i < ObjectGetInteger(0, "FIB_OB_BEAR", OBJPROP_LEVELS); i++)
         {
            ObjectSetInteger(0, "FIB_OB_BEAR", OBJPROP_LEVELCOLOR, i, clrBlack);
         }
         
         double entLvlBear = mostRecentSwingLow + (mostRecentSwingHigh - mostRecentSwingLow) * (Fib_Trade_lvls / 100.0);
         
         if(Bid >= entLvlBear)
         {
            T2 = getTimeBar(0);
            OB.draw(T1, T2, BearOB);
            ExecuteTrade(ORDER_TYPE_SELL);
            lastTradedOBTime = OB.time; // Mark this OB as traded
            delete OB;
            OB = NULL;
         }
      }
   }
}

Die Funktion DetectAndDrawOrder Blocks() ist für die Identifizierung, Validierung und den Handel von Order Blocks verantwortlich, wobei die Fibonacci-Konfluenz in den Entscheidungsprozess integriert wird. Zunächst wird die Erkennung bei jedem neuen Balken zurückgesetzt, und dann werden die letzten Kerzen auf Aufwärts- oder Abwärtsmuster der Order Blocks untersucht. Sobald ein gültiger Auftragsblock gefunden wurde, wird geprüft, ob der aktuelle Kurs in die Zone zurückgeht, was eine potenzielle Handelsmöglichkeit signalisiert. Vor der Ausführung ruft die Funktion die Umkehr-Erkennung auf, um den letzten hohen und den letzten tiefen Umkehrpunkt zu ermitteln und sicherzustellen, dass ein Fibonacci-Retracement zwischen diesen beiden Werten eingezeichnet werden kann.

Das Fibonacci-Tool wird dann zur Validierung des Einstiegs verwendet, wobei der Kurs an ein vordefiniertes Retracement-Level angepasst werden muss, bevor der Handel bestätigt wird. Auf diese Weise vermeidet das System verfrühte Eingaben und stellt sicher, dass Handelsgeschäfte nur dann ausgeführt werden, wenn sowohl die Zone des Order Blocks als auch das Fibonacci-Retracement übereinstimmen, wodurch die Genauigkeit und Konsistenz bei der Handelsvalidierung verstärkt wird.

//============================== FVG ================================//
// Definition (ICT-style):
// Let C=i, B=i+1, A=i+2.
// Bullish FVG if Low(A) > High(C) -> gap [High(C), Low(A)]
// Bearish FVG if High(A) < Low(C) -> gap [High(A), Low(C)]
struct SFVG
{
   int      dir;    // +1 bull, -1 bear
   datetime tLeft;  // left time anchor
   double   top;    // zone top price
   double   bot;    // zone bottom price

   string Name() const
   {
      string k = TimeToString(tLeft, TIME_DATE|TIME_MINUTES);
      return (dir>0 ? "FVG_B_" : "FVG_S_") + k + "_" + IntegerToString((int)(top*1000.0));
   }
};

bool FVGExistsAt(const string &name){ return ObjectFind(0, name) != -1; }

void DetectAndDrawFVGs()
{
   double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
   int counted = 0;

   for(int i=2; i<MathMin(FVG_ScanBars, Bars(_Symbol, _Period))-2; i++)
   {
      // Build A,B,C
      double lowA  = getLow(i+2);
      double highA = getHigh(i+2);
      double highC = getHigh(i);
      double lowC  = getLow(i);

      // Bullish FVG: Low of A > High of C
      if(lowA > highC && (lowA - highC >= FVG_MinPoints * point))
      {
         SFVG z;
         z.dir   = +1;
         z.tLeft = getTimeBar(i+2);  // Changed from getTimeBar to getTime
         z.top   = lowA;
         z.bot   = highC;
         DrawFVG(z);
         counted++;
      }
      // Bearish FVG: High of A < Low of C
      else if(highA < lowC && (lowC - highA >= FVG_MinPoints * point))
      {
         SFVG z;
         z.dir   = -1;
         z.tLeft = getTimeBar(i+2);  // Changed from getTimeBar to getTime
         z.top   = lowC;          // Fixed: should be lowC for bearish FVG top
         z.bot   = highA;         // Fixed: should be highA for bearish FVG bottom
         DrawFVG(z);
         counted++;
      }
      
      if(counted > 15) break; // avoid clutter
   }

   // --- Simplified trading for FVGs ---
   Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

   // scan drawn objects and trade on first valid touch of EQ (50%)
   int total = ObjectsTotal(0, 0, -1);
   static datetime lastTradeBar = 0;
   
   if(OneTradePerBar)
   {
      datetime barNow = (datetime)SeriesInfoInteger(_Symbol, _Period, SERIES_LASTBAR_DATE);
      if(lastTradeBar == barNow) return; // already traded this bar
   }

   for(int idx=0; idx<total; idx++)
   {
      string name = ObjectName(0, idx);
      if(StringFind(name, "FVG_", 0) != 0) continue; // only our FVGs

      // Get object coordinates
      datetime t1 = (datetime)ObjectGetInteger(0, name, OBJPROP_TIME, 0);
      double y1 = ObjectGetDouble(0, name, OBJPROP_PRICE, 0);
      datetime t2 = (datetime)ObjectGetInteger(0, name, OBJPROP_TIME, 1);
      double y2 = ObjectGetDouble(0, name, OBJPROP_PRICE, 1);

      double top = MathMax(y1, y2);
      double bot = MathMin(y1, y2);
      bool isBull = (StringFind(name, "FVG_B_", 0) == 0);
      double mid  = (top + bot) * 0.5;

      if(isBull)
      {
         // trade when Ask is inside the gap and at/under EQ
         if(Ask <= top && Ask >= bot && (!FVG_TradeAtEQ || Ask <= mid))
         {
            ExecuteTrade(ORDER_TYPE_BUY);
            lastTradeBar = (datetime)SeriesInfoInteger(_Symbol, _Period, SERIES_LASTBAR_DATE);
            break;
         }
      }
      else
      {
         // trade when Bid is inside the gap and at/over EQ
         if(Bid <= top && Bid >= bot && (!FVG_TradeAtEQ || Bid >= mid))
         {
            ExecuteTrade(ORDER_TYPE_SELL);
            lastTradeBar = (datetime)SeriesInfoInteger(_Symbol, _Period, SERIES_LASTBAR_DATE);
            break;
         }
      }
   }
}

Diese Funktion erkennt, zeichnet und handelt Fair Value Gaps (FVGs) auf der Grundlage der ICT-Logik. Zunächst werden die letzten Balken gescannt, um Aufwärts-Lücken zu erkennen, bei denen das Tief der Kerze A höher ist als das Hoch von Kerze C, und Abwärts-Lücken, bei denen das Hoch der Kerze A niedriger ist als das Tief von Kerze C, sofern die Lücke eine Mindestgröße in Punkten erreicht. Sobald ein FVG erkannt wird, wird es in einer Struktur gespeichert, visuell auf dem Chart dargestellt und für den Handel verfolgt. Das System überwacht dann aktive FVG-Zonen und prüft, wann der Preis in die Lücke eintritt und sich am Gleichgewichtsniveau (50 % der Zone) ausrichtet, sofern dies möglich ist. Wenn die Bedingungen erfüllt sind, führt die Funktion einen Handel aus, wobei sie bei Aufwärts-FVGs kauft und bei Abwärts-FVGs verkauft, wobei sie sicherstellt, dass nur ein Handelsgeschäft pro Balken durchgeführt wird, um Overtrading zu vermeiden. Diese Kombination aus Erkennung, Visualisierung und Ausführung macht das FVG-Tool sowohl analytisch als auch direkt handelbar.

//=============================== BOS ===============================//
// Use unified swings (no RSI). Trading logic mirrors your earlier code:
// - Sell when price breaks above last swing high (liquidity run idea)
// - Buy  when price breaks below last swing low
void DetectAndDrawBOS()
{
   // Use DetectSwingForBar to find the most recent swing points
   double mostRecentSwingHigh = 0;
   double mostRecentSwingLow = EMPTY_VALUE;
   datetime mostRecentSwingHighTime = 0;
   datetime mostRecentSwingLowTime = 0;
   
   // Scan recent bars to find the most recent swings for BOS
   for(int i = 0; i < 20; i++) // Check the last 20 bars
   {
      // Reset swing variables
      swng_High = 0;
      swng_Low = 0;
      bos_tH = 0;
      bos_tL = 0;
      
      // Detect swing at this bar for BOS
      DetectSwingForBar(i, SWING_BOS);
      
      if(swng_High > 0 && (mostRecentSwingHighTime == 0 || bos_tH > mostRecentSwingHighTime))
      {
         mostRecentSwingHigh = swng_High;
         mostRecentSwingHighTime = bos_tH;
      }
      
      if(swng_Low < EMPTY_VALUE && (mostRecentSwingLowTime == 0 || bos_tL > mostRecentSwingLowTime))
      {
         mostRecentSwingLow = swng_Low;
         mostRecentSwingLowTime = bos_tL;
      }
   }
   
   // Update the global BOS variables with the most recent swings
   if(mostRecentSwingHighTime > 0)
   {
      if(mostRecentSwingHighTime != bos_tH)
         Bull_BOS_traded = false;
      swng_High = mostRecentSwingHigh;
      bos_tH = mostRecentSwingHighTime;
   }
   
   if(mostRecentSwingLowTime > 0)
   {
      if(mostRecentSwingLowTime != bos_tL)
         Bear_BOS_traded = false;
      swng_Low = mostRecentSwingLow;
      bos_tL = mostRecentSwingLowTime;
   }
   
   // Now check for break of structure
   Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   
   // Get current bar time to prevent multiple trades on same bar
   datetime currentBarTime = iTime(_Symbol, _Period, 0);
   
   // SELL on break above swing high
   if(swng_High > 0 && Ask > swng_High && Bull_BOS_traded == false)
   {
      // Check if we haven't already traded this breakout
      if(lastBOSTradeTime != currentBarTime || lastBOSTradeDirection != -1)
      {
         if(DrawBOSLines)
            DrawBOS("BOS_H_" + TimeToString(bos_tH), bos_tH, swng_High,
                    TimeCurrent(), swng_High, BOSBear, -1);
         
         ExecuteTrade(ORDER_TYPE_BUY);
         
         // Update trade tracking
         lastBOSTradeTime = currentBarTime;
         lastBOSTradeDirection = -1;
         Bull_BOS_traded = true;
         
         // Reset the swing high to prevent immediate re-trading
         swng_High = -1.0;
      }
   }
   
   // BUY on break below swing low
   if(swng_Low > 0 && Bid < swng_Low && Bear_BOS_traded == false)
   {
      // Check if we haven't already traded this breakout
      if(lastBOSTradeTime != currentBarTime || lastBOSTradeDirection != 1)
      {
         if(DrawBOSLines)
            DrawBOS("BOS_L_" + TimeToString(bos_tL), bos_tL, swng_Low,
                    TimeCurrent(), swng_Low, BOSBull, +1);
         
         ExecuteTrade(ORDER_TYPE_SELL);
         
         // Update trade tracking
         Bear_BOS_traded = true;
         lastBOSTradeTime = currentBarTime;
         lastBOSTradeDirection = 1;
         
         // Reset the swing low to prevent immediate re-trading
         swng_Low = -1.0;
      }
   }   
}
Die BOS-Funktion erkennt und handelt BOS-Ereignisse (Break of Structure) mit Hilfe der einheitlichen Umkehr-Logik. Sie scannt die letzten 20 Balken, um den letzten hohen und den letzten tiefen Umkehrpunkt zu identifizieren, aktualisiert globale BOS-Variablen und stellt sicher, dass doppelte Handelsgeschäfte auf demselben Balken vermieden werden. Bricht der Kurs über den letzten hohen Umkehrpunkt, wird ein Kauf ausgeführt (Liquidität steigt über die Höchststände), bricht der Kurs unter den letzten tiefen Umkehrpunkt, wird verkauft. Optional können BOS-Linien zur Visualisierung eingezeichnet werden, und interne Flags verhindern ein sofortiges Re-Trading beim gleichen Ausbruch.
//---------------------------- BOS UI -------------------------------//
void DrawBOS(const string name, datetime t1, double p1, datetime t2, double p2, color col, int dir)
{
   if(ObjectFind(0, name) == -1)
   {
      ObjectCreate(0, name, OBJ_TREND, 0, t1, p1, t2, p2);
      ObjectSetInteger(0, name, OBJPROP_COLOR, col);
      ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);

      string lbl = name + "_lbl";
      ObjectCreate(0, lbl, OBJ_TEXT, 0, t2, p2);
      ObjectSetInteger(0, lbl, OBJPROP_COLOR, col);
      ObjectSetInteger(0, lbl, OBJPROP_FONTSIZE, 10);
      ObjectSetString(0,  lbl, OBJPROP_TEXT, "Break");
      ObjectSetInteger(0, lbl, OBJPROP_ANCHOR, (dir>0)?ANCHOR_RIGHT_UPPER:ANCHOR_RIGHT_LOWER);
   }
}

Die Funktion DrawBOS ist für die visuelle Markierung eines Strukturbruchs (Break of Structure, BOS) in einem Chart verantwortlich, indem sie eine Trendlinie zwischen zwei Punkten (t1, p1) und (t2, p2) mit einer bestimmten Farbe und Breite erstellt. Wenn das Objekt mit dem angegebenen Namen noch nicht existiert, wird zunächst die Trendlinie erstellt, ihre Farbe und Dicke festgelegt und dann eine Textbeschriftung am Endpunkt mit der Angabe „Break“ hinzugefügt. Die Position der Kennzeichnung wird je nach Richtung verankert, sodass es bei einem Aufwärtstrend oben rechts und bei einem Abwärtstrend unten rechts platziert wird, sodass ein klarer visueller Hinweis auf Veränderungen der Marktstruktur direkt im Chart angezeigt wird.

void DrawFVG(const SFVG &z)
{
   string name = z.Name();
   datetime tNow = (datetime)SeriesInfoInteger(_Symbol, _Period, SERIES_LASTBAR_DATE);
   
   // Delete existing object if it exists
   if(ObjectFind(0, name) != -1) 
      ObjectDelete(0, name);
   
   // Create rectangle object for FVG
   if(!ObjectCreate(0, name, OBJ_RECTANGLE, 0, z.tLeft, z.bot, tNow, z.top))
   {
      Print("Error creating FVG object: ", GetLastError());
      return;
   }
   
   // Set object properties
   ObjectSetInteger(0, name, OBJPROP_COLOR, z.dir>0 ? BullFVG : BearFVG);
   ObjectSetInteger(0, name, OBJPROP_FILL, true);
   ObjectSetInteger(0, name, OBJPROP_BACK, true);
   ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
   ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
   
   // Set Z-order to make sure it's visible
   ObjectSetInteger(0, name, OBJPROP_ZORDER, 0);
}

Die Funktion DrawFVG visualisiert ein Fair Value Gap (FVG) im Chart, indem sie zunächst prüft, ob ein Objekt mit dem Namen des FVG bereits existiert, und es dann löscht, um Duplikate zu vermeiden. Anschließend wird ein Rechteck erstellt, das sich vom linken Zeitpunkt tLeft der Lücke bis zum aktuellen Balken und vom unteren Ende bis zum oberen Ende der Lücke erstreckt. Das Rechteck wird mit einer auf der Richtung der Lücke basierenden Farbe gestaltet, gefüllt, an den hinteren Teil des Charts gesendet und mit einem festen Rahmen versehen. Wenn die Z-Reihenfolge auf 0 gesetzt wird, bleibt das FVG hinter anderen Chart-Elementen sichtbar und bietet Händlern eine klare visuelle Echtzeit-Referenz für Preisineffizienzen.

void OnTick()
{
   if(!IsNewBar()) return;

   // Strategy switch
   if(TradeStrategy == STRAT_FVG || TradeStrategy == STRAT_AUTO)
      DetectAndDrawFVGs();

   if(TradeStrategy == STRAT_OB  || TradeStrategy == STRAT_AUTO)
      DetectAndDrawOrderBlocks();

   if(TradeStrategy == STRAT_BOS || TradeStrategy == STRAT_AUTO)
      DetectAndDrawBOS();
}

Die Funktion OnTick wird bei jedem Markttick ausgeführt, aber nur, wenn ein neuer Balken gebildet wird, sodass die Berechnungen nur einmal pro Kerze durchgeführt werden. Anschließend wird die ausgewählte Handelsstrategie überprüft: Wenn Fair Value Gaps (FVG) oder der automatische Modus aktiv ist, wird DetectAndDrawFVGs aufgerufen; wenn Order Blocks (OB) oder der automatische Modus aktiv ist, wird DetectAndDrawOrder Blocks aufgerufen; und wenn Break of Structure (BOS) oder der automatische Modus aktiv ist, wird DetectAndDrawBOS aufgerufen. Diese Struktur ermöglicht es dem EA oder Indikator, verschiedene Marktstrukturen dynamisch zu erkennen und in Echtzeit auf der Grundlage der gewählten Strategie zu visualisieren.


Backtest-Ergebnisse

Die Backtests wurde für den 1H-Zeitrahmen über ein etwa zweimonatiges Testfenster (01. Juli 2025 bis 01. September 2025) ausgewertet, wobei die Standardeinstellungen mit der BOS-Strategie verwendet wurden.



Schlussfolgerung

Zusammenfassend haben wir ein einheitliches Smart Money Concepts (SMC)-Handelskonzept entwickelt, das drei wichtige Säulen integriert: Order Blocks (OBs), Break of Structure (BOS), und Fair Value Gaps (FVGs). Jedes Konzept wurde mit einer Erkennungs-, Zeichen- und Handelslogik kodiert. OBs wurden als institutionelle Fußabdrücke mit Fibonacci-Retracement-Validierung identifiziert, BOS erfassten Liquiditätsläufe, wenn der Preis hohe und tiefe Umkehrpunkte durchlief, und FVGs zeigten Ineffizienzen bei der Preislieferung auf, die oft als starke Reaktionszonen fungieren. Durch die Kombination dieser Elemente in einem einzigen System gewährleistet der Code die dynamische Erkennung von Setups mit hoher Wahrscheinlichkeit direkt auf dem Chart, komplett mit visuellen Hilfen und automatischer Ausführung.

Zusammenfassend lässt sich sagen, dass dieser einheitliche Ansatz den Händlern eine systematische Anwendung der SMC-Prinzipien ermöglicht, ohne das Rätselraten, das oft mit der manuellen Chartanalyse einhergeht. Der EA markiert und verfolgt nicht nur Marktstrukturverschiebungen, sondern führt auch Handelsgeschäfte in Echtzeit aus, wenn sich der Preis an vordefinierten SMC-Bedingungen orientiert. Dies bietet Händlern eine disziplinierte, regelbasierte Methode, die emotionale Voreingenommenheit reduziert, die Konsistenz erhöht und einen professionellen Vorteil bei der Nutzung von Chancen im institutionellen Stil unter verschiedenen Marktbedingungen bietet.

Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/16340

Beigefügte Dateien |
SMC_ALL_IN_1.mq5 (21.41 KB)
Letzte Kommentare | Zur Diskussion im Händlerforum (12)
Hlomohang John Borotho
Hlomohang John Borotho | 16 Sept. 2025 in 15:59
Stanislav Korotky #:

Die Fair-Value-Lücke ist falsch beschrieben und dargestellt, bitte sehen Sie sich das richtige Bild in diesem Artikel an.

Sie irren sich, es ist dasselbe, ich habe das FVG mit dem Preis/Candlesticks dargestellt, die bereits innerhalb der FVG-Zone zurückgegangen sind.
Hlomohang John Borotho
Hlomohang John Borotho | 16 Sept. 2025 in 16:00
Yata Tema Gea #:

Wow, Ihr Artikel ist großartig. Ich weiß nur, dass es Indonesier in dem Artikel sind. Unser Konzept ist das gleiche, aber der Unterschied ist, dass ich Python für SMC+GPT verwende.


Ich sehe das :)
Stanislav Korotky
Stanislav Korotky | 16 Sept. 2025 in 17:37
Hlomohang John Borotho #:
Sie irren sich, es ist das Gleiche, ich habe das FVG mit dem Preis / Candlesticks bereits innerhalb der FVG-Zone zurückgegangen dargestellt.

Sie liegen falsch oder haben Ihre Grafik schlecht vorbereitet. Da die 1. und 3. Kerze (von links) rot dargestellt sind, sind sie bärisch und bilden 2 große Lücken vor und nach der 2. Kerze (wo vermutlich das FVG stattfand).

Wenn Sie im Internet nach FVG suchen, werden Sie feststellen, dass es sich bei dieser Formation um einen großen unidirektionalen Kurssprung/eine große Lücke handelt und nicht um einen Zickzackkurs mit mehreren Sprüngen, der den gesamten Effekt für mögliche künftige Rücksetzer verdunkeln würde, weil man nicht weiß, welche (der drei Lücken) sich zuerst schließen wird (in Ihrem Bild ist es die letzte Lücke entlang der dritten Kerze, nicht die zweite - sie wird von der vierten Kerze geschlossen).
Bao Thuan Thai
Bao Thuan Thai | 28 Sept. 2025 in 11:06
Ich muss nicht wissen, wie es funktioniert, aber ich danke Ihnen sehr für Ihren Beitrag und Ihre Freundlichkeit.
ritik pathak
ritik pathak | 4 Okt. 2025 in 11:01
großartige Arbeit, es kann noch besser werden, wenn der Stop unter/über dem FVG liegt oder der Order-Block kein Fixpunkt-Stop-Loss ist.
Statistische Arbitrage durch kointegrierte Aktien (Teil 4): Modellaktualisierung in Echtzeit Statistische Arbitrage durch kointegrierte Aktien (Teil 4): Modellaktualisierung in Echtzeit
Dieser Artikel beschreibt eine einfache, aber umfassende statistische Arbitrage-Pipeline für den Handel mit einem Korb von kointegrierten Aktien. Es enthält ein voll funktionsfähiges Python-Skript zum Herunterladen und Speichern von Daten, Korrelations-, Kointegrations- und Stationaritätstests sowie eine Beispielimplementierung des Metatrader 5 Service zur Aktualisierung der Datenbank und des entsprechenden Expert Advisors. Einige Designentscheidungen werden hier zu Referenzzwecken und als Hilfe bei der Reproduktion des Experiments dokumentiert.
Automatisieren von Handelsstrategien in MQL5 (Teil 28): Erstellen eines Price Action Bat Harmonic Patterns mit visuellem Feedback Automatisieren von Handelsstrategien in MQL5 (Teil 28): Erstellen eines Price Action Bat Harmonic Patterns mit visuellem Feedback
In diesem Artikel entwickeln wir ein Bat-Pattern-System in MQL5, das Auf- und Abwärtsmuster von Bat-Harmonic unter Verwendung von Umkehrpunkten und Fibonacci-Verhältnissen identifiziert und Handelsgeschäfte mit präzisen Einstiegs-, Stop-Loss- und Take-Profit-Levels auslöst, ergänzt durch visuelles Feedback durch Chart-Objekte
Automatisieren von Handelsstrategien in MQL5 (Teil 29): Erstellung eines Preisaktionssystems mit dem harmonischen Muster von Gartley Automatisieren von Handelsstrategien in MQL5 (Teil 29): Erstellung eines Preisaktionssystems mit dem harmonischen Muster von Gartley
In diesem Artikel entwickeln wir ein System des Gartley-Musters in MQL5, das harmonische Auf- und Abwärtsmuster von Gartley mit Hilfe von Umkehrpunkten und Fibonacci-Verhältnissen identifiziert und Handelsgeschäfte mit präzisen Einstiegs-, Stop-Loss- und Take-Profit-Levels ausführt. Wir verbessern den Einblick des Händlers mit visuellem Feedback durch Chart-Objekte wie Dreiecke, Trendlinien und Beschriftungen, um die XABCD-Musterstruktur klar darzustellen.
MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 79): Verwendung von Gator-Oszillator und Akkumulations-/Distributions-Oszillator mit überwachtem Lernen MQL5-Assistenten-Techniken, die Sie kennen sollten (Teil 79): Verwendung von Gator-Oszillator und Akkumulations-/Distributions-Oszillator mit überwachtem Lernen
Im letzten Beitrag haben wir die Paarung von Gator-Oszillator und Akkumulations-/Distributions-Oszillator in ihrer typischen Einstellung der von ihnen erzeugten Rohsignale betrachtet. Diese beiden Indikatoren sind als Trend- bzw. Volumenindikatoren zu verstehen. Im Anschluss an diesen Teil untersuchen wir die Auswirkungen, die das überwachte Lernen auf die Verbesserung einiger der von uns untersuchten Merkmalsmuster haben kann. Unser überwachter Lernansatz ist ein CNN, der mit Kernelregression und Skalarproduktähnlichkeit arbeitet, um seine Kernel und Kanäle zu dimensionieren. Wie immer tun wir dies in einer nutzerdefinierten Signalklassendatei, die mit dem MQL5-Assistenten arbeitet, um einen Expert Advisor zusammenzustellen.