English 日本語
preview
Analytical Volume Profile Trading (AVPT): Liquiditätsarchitektur, Marktgedächtnis und algorithmische Ausführung

Analytical Volume Profile Trading (AVPT): Liquiditätsarchitektur, Marktgedächtnis und algorithmische Ausführung

MetaTrader 5Beispiele |
25 9
Hlomohang John Borotho
Hlomohang John Borotho

Inhaltsverzeichnis

  1. Einführung
  2. Überblick und Verständnis des Systems
  3. Die ersten Schritte
  4. Backtest-Ergebnisse
  5. Schlussfolgerung


Einführung

Da der institutionelle Auftragsfluss die Liquiditätslandschaft ständig neu gestaltet, müssen sich die Händler auf Methoden stützen, die die zugrunde liegende Struktur der Beteiligung abbilden und nicht nur das Rauschen der Preise. Analytical Volume Profile Trading (AVPT) geht weit über einfache Indikatoren hinaus, indem es analysiert, wo der Markt tatsächlich gehandelt hat, und nicht nur, wo er sich bewegt hat. Durch das Zusammenspiel von High-Volume Nodes, Low-Volume Nodes, Value Areas und dem alles entscheidenden Point of Control legt AVPT die verborgenen Schichten des Marktgedächtnisses frei und zeigt genau, wo sich Institutionen einig sind, wo sie sich nicht einig sind und wo sie sich positionieren.

Da der algorithmische Handel die globalen Märkte zunehmend dominiert, wird das Verständnis der Verteilung des Volumens auf die verschiedenen Preisebenen zu einem entscheidenden Vorteil. AVPT kombiniert Mikrostrukturanalyse mit Automatisierung und ermöglicht es Händlern, Liquiditätsungleichgewichte in Echtzeit zu interpretieren und mit chirurgischer Präzision auszuführen. Durch die Umwandlung des Rohvolumens in eine umsetzbare Struktur verwandelt dieser Ansatz die chaotischen Marktaktivitäten in eine lesbare Blaupause für die Trenderkennung, die Antizipation von Ausbrüchen und das Timing von Umkehrungen. 


Überblick und Verständnis des Systems

Schlüsselkomponenten des Volumenprofils:

Komponente  Beschreibung 
Point of Control (POC) Das Kursniveau mit dem höchsten Handelsvolumen, das oft als Dreh- und Angelpunkt für die Kursentwicklung dient.
High-Value Node (HVN) Kursniveaus, auf denen erhebliche Handelsaktivitäten stattfinden, die auf eine starke Unterstützung oder einen starken Widerstand hinweisen.
Low-Value Node (LVN) Preisniveaus mit minimaler Handelsaktivität, bei denen sich die Preise aufgrund der geringen Liquidität schnell bewegen können.
Value Area Der Bereich von Kursniveaus, in dem ein bestimmter Prozentsatz (normalerweise 70 %) des Volumens gehandelt wurde.

Analytical Volume Profile Trading (AVPT) ist ein hochentwickelter Ansatz zur Marktanalyse, der über die traditionellen preisbasierten technischen Indikatoren hinausgeht, indem er sich auf die entscheidende Dimension des Handelsvolumens auf bestimmten Preisniveaus konzentriert. Im Kern visualisiert AVPT den Markt als eine dynamische Landschaft, in der Preisaktionen mit volumenbasierten Unterstützungs- und Widerstandszonen interagieren. Das Histogramm des Volumenprofils, das in der Regel als horizontales Histogramm auf der rechten Seite des Charts angezeigt wird, gibt Aufschluss darüber, wo während eines bestimmten Zeitraums erhebliche Handelsaktivitäten stattgefunden haben. Diese Visualisierung erstellt eine klare Übersicht des Marktkonsenses und zeigt Preisniveaus, auf denen Institutionen und große Händler Positionen angesammelt haben (High-Volume Nodes), im Gegensatz zu Bereichen mit geringer Beteiligung (Low-Volume Nodes). Der Point of Control (POC) fungiert als Gravitationszentrum dieser Landschaft. Er stellt das Preisniveau mit dem höchsten Handelsvolumen dar und dient oft als starker Magnet für Preisrückgaben.

Der strategische Rahmen der AVPT dreht sich darum zu verstehen, wie der Preis mit diesen volumenbasierten Strukturen interagiert. Nähert sich der Kurs den High-Volume Nodes, stößt er in der Regel auf eine starke Unterstützung oder einen starken Widerstand, da diese Zonen Bereiche mit großem institutionellen Interesse und hoher Liquidität darstellen. Umgekehrt fungieren Low-Volume Nodes als Beschleunigungszonen, in denen sich der Preis aufgrund des fehlenden Handelsinteresses schnell bewegen kann. Der Value-Bereich, der etwa 70 % des Volumens des Berichtszeitraums umfasst, definiert den Bereich des „fairen Wertes“, in dem der meiste Handel stattfand. Durch die Visualisierung dieser Komponenten entsteht ein umfassender Handelsplan: Händler können potenzielle Umkehrzonen in der Nähe von Wertgrenzen, Ausbruchschancen durch Bereiche mit geringem Volumen und Gewinnziele am POC identifizieren. Diese dreidimensionale Sicht auf den Markt – die Kombination von Preis, Volumen und Zeit – bietet einen erheblichen Vorteil gegenüber der traditionellen zweidimensionalen Preisanalyse.

Bei der praktischen Umsetzung von AVPT wird überwacht, wie sich das aktuelle Kursgeschehen zu diesen etablierten Volumenstrukturen verhält. In schwankenden Märkten können Händler Strategien der Rückkehr zum Mittelwert anwenden, indem sie in der Nähe des Value Area Low mit Stopps unter nahe gelegenen LVNs kaufen und beim POC Gewinne mitnehmen. Unter Trendbedingungen werden Ausbruchsstrategien praktikabel, wenn sich der Preis mit Schwung durch LVN-Zonen bewegt und auf Ausdehnungen über den Value-Bereich hinaus abzielt. Die Visualisierung macht das Risikomanagement besonders intuitiv – Stop-Losses gehören natürlich jenseits der LVNs, wo Ausbrüche die Handelsprämisse ungültig machen würden, während die Positionsgröße auf der Grundlage der Breite des Value-Bereichs und der Entfernung zu wichtigen Volumenknoten angepasst werden kann. Dieser integrierte Ansatz für Analyse, Einstiegszeitpunkt und Risikomanagement schafft eine systematische Methodik, die sich daran orientiert, wie institutionelle Geldströme die Marktbewegungen tatsächlich beeinflussen.



Die ersten Schritte

//+------------------------------------------------------------------+
//|                                                         AVPT.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.00"
#include <Trade/Trade.mqh>


//+------------------------------------------------------------------+
//| Input Parameters                                                 |
//+------------------------------------------------------------------+
input group "=== Volume Profile Settings ==="
input int      VP_LookbackBars = 500;        // Volume Profile Lookback Bars
input double   VA_Percentage = 70.0;         // Value Area Percentage
input double   HVN_Threshold = 1.5;          // HVN Volume Threshold (x median)
input double   LVN_Threshold = 0.3;          // LVN Volume Threshold (x median)

input group "=== Trading Settings ==="
input double   LotSize = 0.1;                // Trade Lot Size
input bool     UseAtrSL = true;              // Use ATR for Stop Loss
input double   AtrMultiplier = 2.0;          // ATR Multiplier for SL
input int      AtrPeriod = 14;               // ATR Period
input double   RiskRewardRatio = 1.5;        // Risk/Reward Ratio
input bool     UseTrailingStop = true;       // Enable Trailing Stop
input double   TrailingStep = 0.0010;        // Trailing Stop Step

input group "=== Strategy Settings ==="
input bool     EnableReversion = true;       // Enable Reversion Strategy
input bool     EnableBreakout = false;       // Enable Breakout Strategy
input int      MinBarsBetweenTrades = 3;     // Minimum Bars Between Trades

Wir beginnen mit der Definition aller konfigurierbaren Eingaben, die die Funktionsweise der Volume Profile Engine und der Handelslogik bestimmen. Die erste Gruppe spezifiziert profilbezogene Parameter wie die Anzahl der zu analysierenden Rückblickbalken, den Prozentsatz, der zur Berechnung des Wertebereichs verwendet wird, und die Schwellenwerte für die Identifizierung von High-Volume Nodes und Low-Volume Nodes. Der Abschnitt Handelseinstellungen legt dann die Risiko- und Positionsmanagement-Kontrollen fest – einschließlich Losgröße, ATR-basierter Stop-Loss, Risiko-Ertrags-Verhältnis und Trailing-Stop-Verhalten – die dem EA Flexibilität bei der Anpassung an die Volatilität verleihen. Die Gruppe der Strategieeinstellungen schließlich aktiviert oder deaktiviert wichtige AVPT-Modi wie Reversion oder Ausbruchshandel und erzwingt einen Mindestabstand zwischen den Handelsgeschäfte für eine sauberere Ausführung und weniger Signalrauschen.

//+------------------------------------------------------------------+
//| Enumerations                                                     |
//+------------------------------------------------------------------+
enum ENUM_LEVEL_POSITION{
   BELOW,
   ABOVE
};

enum ENUM_DIRECTION{
   UP,
   DOWN
};

//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+
CTrade trade;

// Volume Profile Arrays
double volumeProfile[];
double priceLevels[];
int profileBins;

// Key Levels
double pocPrice;
double vahPrice;
double valPrice;
double hvnLevels[];
double lvnLevels[];

// Trading
datetime lastTradeTime;
int atrHandle;
double currentAtr;

Dann definieren wir wichtige Enumerationen und globale Variablen, die die Logik und Datenstrukturen des EA unterstützen. Die Enum bieten klare Richtungs- und Positionsklassifizierungen, die in der gesamten Strategie verwendet werden, während die globalen Variablen zentrale Handelskomponenten wie das Objekt CTrade, die dynamisch erstellten Volumenprofil-Arrays und Schlüsselebenen wie POC, VAH, VAL, HVNs und LVNs speichern. Zusätzliche Variablen verfolgen die Handelslogistik – einschließlich des Zeitstempels des letzten ausgeführten Handels – und ermöglichen den Zugriff auf Indikatoren wie ATR, um sicherzustellen, dass der EA Volatilitätsdaten in Echtzeit für Stop-Loss- und Risikomanagemententscheidungen heranziehen kann.

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    // Initialize ATR indicator
    atrHandle = iATR(_Symbol, _Period, AtrPeriod);
    if(atrHandle == INVALID_HANDLE)
    {
        Print("Error creating ATR indicator");
        return(INIT_FAILED);
    }
    
    // Initialize volume profile arrays
    InitializeVolumeProfile();
    
    // Set up timer for periodic updates
    EventSetTimer(60); // Update every minute
    
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    IndicatorRelease(atrHandle);
    EventKillTimer();
    CleanUpChartObjects();
}

In der Initialisierungsphase richtet der EA alle wesentlichen Komponenten ein, indem er zunächst den ATR-Indikator erstellt, der für volatilitätsbasierte Stop-Loss-Berechnungen verwendet wird, und überprüft, ob er korrekt geladen wird. Anschließend werden die Volume-Profil-Arrays durch eine spezielle Initialisierungsfunktion vorbereitet und ein sich wiederholender Timer eingerichtet, damit das System sein Profil und seine Logik jede Minute aktualisieren kann. Während der Deinitialisierung gibt der EA den ATR-Indikator sicher frei, stoppt den Timer und entfernt alle während der Ausführung erstellten Chart-Objekte, um ein sauberes Herunterfahren zu gewährleisten und Ressourcenlecks zu vermeiden.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    // Update ATR value
    UpdateAtrValue();
    
    // Update volume profile every new bar
    if(IsNewBar())
    {
        UpdateVolumeProfile();
        CalculateKeyLevels();
        UpdateChartObjects();
        
        // Check for trading signals
        CheckTradingSignals();
    }
    
    // Manage open positions
    ManagePositions();
}

//+------------------------------------------------------------------+
//| Volume Profile Engine                                           |
//+------------------------------------------------------------------+
void InitializeVolumeProfile()
{
    profileBins = 200; // Number of price bins
    ArrayResize(volumeProfile, profileBins);
    ArrayResize(priceLevels, profileBins);
    ArrayInitialize(volumeProfile, 0);
}

In der Hauptausführungsschleife aktualisiert der EA den ATR-Wert kontinuierlich bei jedem Tick, um genaue Volatilitätsmetriken zu erhalten. Wenn sich ein neuer Balken bildet, werden die wichtigsten Verarbeitungsschritte ausgelöst: Aktualisierung des Volumenprofils, Neuberechnung von Schlüsselebenen wie POC und Value Area-Grenzen und Aktualisierung der visuellen Objekte im Chart. Nachdem die Strukturanalyse aktualisiert wurde, bewertet der EA, ob die Handelsbedingungen auf der Grundlage der neuesten Volumenprofilsignale erfüllt sind, und verwaltet dann alle derzeit offenen Positionen separat, um sicherzustellen, dass sich Stopps, Trailing-Logik und Ausstiege mit den Marktbedingungen entwickeln.

Die Volume Profile Engine beginnt mit der Initialisierung der Datenstruktur, in der die Verteilung des gehandelten Volumens auf die Preisniveaus gespeichert wird. Durch die Festlegung einer festen Anzahl von Bereichen (bins) und die entsprechende Größenanpassung der Arrays bereitet der EA einen sauberen Container für die Erfassung von Volumendaten zur Laufzeit vor. Dadurch wird sichergestellt, dass jeder neue Balken in ein konsistentes Volumenhistogramm eingeordnet werden kann, was eine genaue Erkennung von Schlüsselebenen wie HVNs, LVNs und dem Point of Control im weiteren Verlauf des Prozesses ermöglicht.

void UpdateVolumeProfile()
{
    // Clear previous profile
    ArrayInitialize(volumeProfile, 0);
    
    // Get price range for current lookback
    double highPrice = GetHighestPrice(VP_LookbackBars);
    double lowPrice = GetLowestPrice(VP_LookbackBars);
    double priceRange = highPrice - lowPrice;
    double binSize = priceRange / profileBins;
    
    // Initialize price levels
    for(int i = 0; i < profileBins; i++)
    {
        priceLevels[i] = lowPrice + (i * binSize);
    }
    
    // Distribute volume across price bins
    for(int bar = 0; bar < VP_LookbackBars; bar++)
    {
        double open = iOpen(_Symbol, _Period, bar);
        double high = iHigh(_Symbol, _Period, bar);
        double low = iLow(_Symbol, _Period, bar);
        double close = iClose(_Symbol, _Period, bar);
        long volume = iVolume(_Symbol, _Period, bar);
        
        DistributeVolumeToBins(open, high, low, close, volume, lowPrice, binSize);
    }
}

void DistributeVolumeToBins(double open, double high, double low, double close, 
                           long volume, double basePrice, double binSize)
{
    double bodyLow = MathMin(open, close);
    double bodyHigh = MathMax(open, close);
    
    for(int i = 0; i < profileBins; i++)
    {
        double binLow = basePrice + (i * binSize);
        double binHigh = binLow + binSize;
        
        // Check if price bin was touched by this candle
        if(!(high < binLow || low > binHigh))
        {
            // Weight volume by time spent in price zone (simplified)
            double overlap = MathMin(high, binHigh) - MathMax(low, binLow);
            double candleRange = high - low;
            
            if(candleRange > 0)
            {
                double weight = overlap / candleRange;
                // Additional weight for body area
                if(binLow <= bodyHigh && binHigh >= bodyLow)
                {
                    double bodyOverlap = MathMin(bodyHigh, binHigh) - MathMax(bodyLow, binLow);
                    weight += (bodyOverlap / candleRange) * 0.3;
                }
                
                volumeProfile[i] += volume * weight;
            }
        }
    }
}

Die Funktion UpdateVolumeProfile() baut die gesamte Volumenverteilung für das definierte Rückblickfenster neu auf, indem sie zunächst das Histogramm zurücksetzt und dann den Preisbereich bestimmt, der profiliert werden muss. Es berechnet die Größe des Bereichs auf der Grundlage dieser Spanne und initialisiert jede Preisstufe, die einem Volumensbereich entspricht. Nach der Festlegung dieser strukturellen Grenzen werden die historischen Balken innerhalb des Rückblickszeitraums durchlaufen und die OHLC-Werte und das Volumen jeder Kerze extrahiert, bevor sie an die Distributions-Engine weitergegeben werden. Auf diese Weise wird sichergestellt, dass das Profil immer die neuesten und relevantesten Aktivitäten auf dem Markt widerspiegelt.

Die Funktion DistributeVolumeToBins() führt die Kernlogik der Zuweisung des Kerzenvolumens zu den entsprechenden Preisbereich aus. Für jeden Bereich wird geprüft, ob die Kerzenspanne mit ihm interagiert hat, und wenn ja, wird geschätzt, wie viel Handelsaktivität wahrscheinlich innerhalb dieser Preiszone stattgefunden hat. Bei dieser Schätzung wird eine gewichtete Methode verwendet, die auf der proportionalen Überschneidung zwischen dem Bereich und dem Hoch-Tief-Bereich der Kerze basiert, wobei der Kerzenkörper, in dem in der Regel eine größere Handelskonzentration stattfindet, zusätzlich betont wird. Durch die Kumulierung dieser gewichteten Beiträge erstellt der EA ein realistischeres und detaillierteres Volumenprofil, das die institutionellen Fußabdrücke auf der gesamten Preisleiter erfasst.

//+------------------------------------------------------------------+
//| Key Levels Calculation                                           |
//+------------------------------------------------------------------+
void CalculateKeyLevels()
{
    CalculatePOC();
    CalculateValueArea();
    CalculateHVNLVN();
}

void CalculatePOC()
{
    double maxVolume = 0;
    int pocIndex = 0;
    
    for(int i = 0; i < profileBins; i++)
    {
        if(volumeProfile[i] > maxVolume)
        {
            maxVolume = volumeProfile[i];
            pocIndex = i;
        }
    }
    
    pocPrice = priceLevels[pocIndex];
}

void CalculateValueArea()
{
    double totalVolume = 0;
    for(int i = 0; i < profileBins; i++)
    {
        totalVolume += volumeProfile[i];
    }
    
    double targetVolume = totalVolume * (VA_Percentage / 100.0);
    int pocIndex = FindPriceIndex(pocPrice);
    
    double currentVolume = volumeProfile[pocIndex];
    int upperIndex = pocIndex;
    int lowerIndex = pocIndex;
    
    while(currentVolume < targetVolume && (upperIndex < profileBins - 1 || lowerIndex > 0))
    {
        bool canExpandUp = (upperIndex < profileBins - 1);
        bool canExpandDown = (lowerIndex > 0);
        
        double upVolume = canExpandUp ? volumeProfile[upperIndex + 1] : 0;
        double downVolume = canExpandDown ? volumeProfile[lowerIndex - 1] : 0;
        
        if(upVolume > downVolume && canExpandUp)
        {
            upperIndex++;
            currentVolume += upVolume;
        }
        else if(canExpandDown)
        {
            lowerIndex--;
            currentVolume += downVolume;
        }
        else if(canExpandUp)
        {
            upperIndex++;
            currentVolume += upVolume;
        }
    }
    
    vahPrice = priceLevels[upperIndex];
    valPrice = priceLevels[lowerIndex];
}

void CalculateHVNLVN()
{
    ArrayResize(hvnLevels, 0);
    ArrayResize(lvnLevels, 0);
    
    // Calculate median volume
    double tempVolumes[];
    ArrayCopy(tempVolumes, volumeProfile);
    ArraySort(tempVolumes);
    double medianVolume = tempVolumes[profileBins / 2];
    
    double hvnThreshold = medianVolume * HVN_Threshold;
    double lvnThreshold = medianVolume * LVN_Threshold;
    
    for(int i = 0; i < profileBins; i++)
    {
        if(volumeProfile[i] >= hvnThreshold)
        {
            int size = ArraySize(hvnLevels);
            ArrayResize(hvnLevels, size + 1);
            hvnLevels[size] = priceLevels[i];
        }
        else if(volumeProfile[i] <= lvnThreshold && volumeProfile[i] > 0)
        {
            int size = ArraySize(lvnLevels);
            ArrayResize(lvnLevels, size + 1);
            lvnLevels[size] = priceLevels[i];
        }
    }
}

Die Berechnungsmaschine auf Schlüsselebene beginnt mit der Orchestrierung der drei Kernkomponenten des Volumenprofils: Bestimmung des Kontrollpunkts, Berechnung der Wertbereichsgrenzen und Identifizierung von High-Volume Nodes und Low-Volume Nodes. Dieser modulare Ansatz ermöglicht es jeder Methode, sich auf ein bestimmtes Strukturelement zu konzentrieren, wodurch sichergestellt wird, dass der EA eine genaue und saubere Hierarchie der Liquiditätsebenen beibehält. Durch die Trennung der Logik bleibt das System einfach zu debuggen, zu erweitern und zu optimieren, wenn neue Strategien oder Filter hinzugefügt werden.

Die Berechnungen von POC und Value Area arbeiten zusammen, um den Schwerpunkt des Marktes zu definieren. Der POC wird ermittelt, indem das Volumenhistogramm nach dem Preisbereich mit dem höchsten gehandelten Volumen durchsucht wird, was die maximale Marktakzeptanz widerspiegelt. Der Wertebereich wird dann ausgehend von diesem POC durch Akkumulation des Volumens in beide Richtungen erweitert, bis die kumulierte Summe den angegebenen Prozentsatz erreicht. Diese Expansionslogik priorisiert Preisniveaus mit höherem Volumen und ermöglicht es dem EA, den Value Area High (VAH) und den Value Area Low (VAL) als Grenzen zu definieren, die die Region darstellen, in der die meisten Handelsaktivitäten stattfanden.

Schließlich werden bei der HVN/LVN-Berechnung Zonen mit außergewöhnlich hoher und ungewöhnlich niedriger Beteiligung im Vergleich zum Medianvolumen ermittelt. Nach der Berechnung des Medians aus einer sortierten Kopie des Profils wendet der EA nutzerdefinierte Multiplikatoren an, um sinnvolle Cluster (HVNs) und Ablehnungszonen (LVNs) zu erkennen. HVNs stehen für eine starke Akzeptanz, bei der die Preise dazu neigen, zu pausieren, ins Stocken zu geraten oder sich umzukehren, während LVNs auf Bereiche mit geringer Liquidität hinweisen, in denen die Preise häufig anziehen oder ausbrechen. Zusammen verankern diese Ebenen die Entscheidungsfindung des EA und ermöglichen adaptive Strategien, die auf der Liquiditätsstruktur und dem Marktgedächtnis beruhen.

//+------------------------------------------------------------------+
//| Trading Signal Logic                                             |
//+------------------------------------------------------------------+
void CheckTradingSignals()
{
    if(!IsTradeAllowed()) return;
    
    // Check minimum bars between trades
    if(Bars(_Symbol, _Period, lastTradeTime, TimeCurrent()) < MinBarsBetweenTrades) 
        return;
    
    double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_LAST);
    
    if(EnableReversion)
    {
        CheckReversionSignals(currentPrice);
    }
    
    if(EnableBreakout)
    {
        CheckBreakoutSignals(currentPrice);
    }
}

void CheckReversionSignals(double currentPrice)
{
    MqlRates currentRates[];
    CopyRates(_Symbol, _Period, 0, 3, currentRates);
    
    // Buy signal: Price rejects VAL with bullish confirmation
    if(IsNearLevel(currentPrice, valPrice) && 
       IsBullishRejection(currentRates))
    {
        double sl = FindNearestLVN(BELOW);
        double tp = pocPrice;
        OpenTrade(ORDER_TYPE_BUY, sl, tp);
    }
    
    // Sell signal: Price rejects VAH with bearish confirmation
    if(IsNearLevel(currentPrice, vahPrice) && 
       IsBearishRejection(currentRates))
    {
        double sl = FindNearestLVN(ABOVE);
        double tp = pocPrice;
        OpenTrade(ORDER_TYPE_SELL, sl, tp);
    }
}

void CheckBreakoutSignals(double currentPrice)
{
    // Breakout above VAH with confirmation
    if(currentPrice > vahPrice && IsBreakoutConfirmed(UP))
    {
        double sl = FindNearestHVN(BELOW);
        double tp = CalculateBreakoutTP(UP);
        OpenTrade(ORDER_TYPE_BUY, sl, tp);
    }
    
    // Breakout below VAL with confirmation
    if(currentPrice < valPrice && IsBreakoutConfirmed(DOWN))
    {
        double sl = FindNearestHVN(ABOVE);
        double tp = CalculateBreakoutTP(DOWN);
        OpenTrade(ORDER_TYPE_SELL, sl, tp);
    }
}

Die Handelssignallogik stellt dann sicher, dass die Bedingungen für die Ausführung geeignet sind – sie bestätigt, dass der Handel erlaubt ist, prüft, ob seit dem letzten Handel genügend Balken vergangen sind, und erfasst den aktuellen Marktpreis. Sobald diese Sicherheitsvorkehrungen erfüllt sind, wertet der EA aus, welche Strategiemodi aktiviert sind, und leitet die Preisaktion durch die entsprechenden Logikblöcke. Wenn das Reversionsmodell aktiv ist, prüft der EA, ob der Preis mit den Grenzen der Value Area in einer Weise interagiert, die eine Ablehnung nahelegt; wenn das Breakout-Modell aktiv ist, sucht er nach entscheidenden Bewegungen über die Value Levels hinaus, die durch eine strukturelle Bestätigung unterstützt werden.

Innerhalb jeder Strategie führt der EA detailliertere Prüfungen durch, um Handels-Setups zu validieren. Bei Umkehrungen sucht es nach steigenden oder fallenden Ablehnungsmustern in der Nähe des VAL oder VAH und berechnet dann Stop-Loss- und Take-Profit-Levels unter Verwendung der nächstgelegenen LVNs und des POC als natürlichen Magneten. Bei Ausbrüchen bestätigt die Logik, dass sich der Kurs sauber über VAH oder VAL hinaus bewegt hat, verwendet dann nahe gelegene HVNs als Schutzstopps und berechnet Richtungsziele auf der Grundlage der Ausbruchsstärke. Diese mehrschichtige Struktur stellt sicher, dass die Signale in der durch das Volumenprofil definierten Liquiditätsarchitektur verankert sind und zu Abschlüssen führen, die sowohl mit der Marktstruktur als auch dem volumenbasierten Kontext übereinstimmen.

//+------------------------------------------------------------------+
//| Trade Execution & Risk Management                                |
//+------------------------------------------------------------------+
void OpenTrade(ENUM_ORDER_TYPE type, double sl, double tp)
{
    double price = (type == ORDER_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) 
                                           : SymbolInfoDouble(_Symbol, SYMBOL_BID);
    
    if(UseAtrSL)
    {
        double atrSl = currentAtr * AtrMultiplier;
        sl = (type == ORDER_TYPE_BUY) ? price - atrSl : price + atrSl;
        
        // Calculate TP based on risk/reward
        double risk = MathAbs(price - sl);
        tp = (type == ORDER_TYPE_BUY) ? price + (risk * RiskRewardRatio) 
                                     : price - (risk * RiskRewardRatio);
    }
    
    // Execute trade using CTrade
    if(trade.PositionOpen(_Symbol, type, LotSize, price, sl, tp, "VolumeProfileEA"))
    {
        lastTradeTime = iTime(_Symbol, _Period, 0);
        Print("Trade executed: ", EnumToString(type), " Price: ", price, " SL: ", sl, " TP: ", tp);
    }
    else
    {
        Print("Trade failed: ", trade.ResultRetcodeDescription());
    }
}

void ManagePositions()
{
    for(int i = PositionsTotal() - 1; i >= 0; i--)
    {
        ulong ticket = PositionGetTicket(i);
        if(PositionSelectByTicket(ticket) && PositionGetString(POSITION_COMMENT) == "VolumeProfileEA")
        {
            if(UseTrailingStop)
            {
                ApplyTrailingStop(ticket);
            }
            
            // Check exit condition: price re-enters Value Area
            if(ShouldExitEarly(ticket))
            {
                ClosePosition(ticket);
            }
        }
    }
}

void ApplyTrailingStop(ulong ticket)
{
    if(PositionSelectByTicket(ticket))
    {
        double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_LAST);
        double currentSL = PositionGetDouble(POSITION_SL);
        ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
        
        double newSL = currentSL;
        double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
        
        if(type == POSITION_TYPE_BUY)
        {
            newSL = currentPrice - (currentAtr * TrailingStep);
            if(newSL > currentSL + point && newSL < currentPrice - point)
            {
                if(trade.PositionModify(ticket, newSL, PositionGetDouble(POSITION_TP)))
                {
                    Print("Trailing SL updated for BUY: ", newSL);
                }
            }
        }
        else if(type == POSITION_TYPE_SELL)
        {
            newSL = currentPrice + (currentAtr * TrailingStep);
            if(newSL < currentSL - point && newSL > currentPrice + point)
            {
                if(trade.PositionModify(ticket, newSL, PositionGetDouble(POSITION_TP)))
                {
                    Print("Trailing SL updated for SELL: ", newSL);
                }
            }
        }
    }
}

void ClosePosition(ulong ticket)
{
    if(PositionSelectByTicket(ticket))
    {
        ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
        double volume = PositionGetDouble(POSITION_VOLUME);
        
        if(type == POSITION_TYPE_BUY)
        {
            trade.PositionClose(ticket);
        }
        else if(type == POSITION_TYPE_SELL)
        {
            trade.PositionClose(ticket);
        }
        
        Print("Position closed early: ", ticket);
    }
}

Die Handelsausführungslogik beginnt mit der Erstellung eines sauberen, risikokontrollierten Auftrags auf der Grundlage der Signalart, des aktuellen Marktpreises und der dynamischen Volatilitätsbedingungen. Wenn der ATR-basierte Stop-Loss aktiviert ist, berechnet der EA sowohl SL als auch TP unter Verwendung des ATR-Multiplikators und des konfigurierten Risiko-Ertrags-Verhältnisses neu, um sicherzustellen, dass sich jede Position an die aktuelle Volatilität anpasst, anstatt sich auf feste Abstände zu verlassen. Sobald die endgültigen Parameter festgelegt sind, verwendet der EA das Objekt CTrade, um den Auftrag an den Server zu senden, und protokolliert, ob die Ausführung erfolgreich war oder nicht. Dieser strukturierte Arbeitsablauf stellt sicher, dass Handelsgeschäfte mit konsistenter Größernanpassung, volatilitätsangepasstem Schutz und logischen Gewinnzielen eingegeben werden, die in der Architektur der Strategie verankert sind.

Die Positionsmanagement-Engine überwacht dann alle aktiven Handelsgeschäfte des VolumeProfileEA, wendet dynamische Trailing-Stops an und bewertet, ob ein vorzeitiger Ausstieg erforderlich ist. Der Trailing-Stop passt sich anhand der ATR-Bewegung an, so dass der Stop-Loss den Preis effizient verfolgen kann, ohne den Handel zu früh zu beenden. In der Zwischenzeit überwacht die Logik des frühzeitigen Ausstiegs, ob der Preis wieder in den Wertbereich eintritt – was darauf hindeutet, dass die ursprüngliche Handelsthese schwächer wird – und schließt die Position, um das Kapital zu erhalten. Dieses zweistufige Ausstiegssystem, das eine Trailing-Logik mit strukturellen Ungültigkeitsprüfungen kombiniert, stellt sicher, dass sich jede Position auf intelligente Weise mit den Marktbedingungen entwickelt, während das Risiko begrenzt und die Gewinne gesichert werden.


Backtest-Ergebnisse

Der Backtest wurde für den Zeitrahmen H4 über ein etwa zweimonatiges Testfenster (01. September 2025 bis 03. November 2025) mit den folgenden Einstellungen ausgewertet:


Hier sehen Sie die Kapitalkurve und die Backtest-Ergebnisse:



Schlussfolgerung

Zusammenfassend lässt sich sagen, dass wir das Analytical Volume Profile Trading (AVPT) entwickelt haben, indem wir aufgeschlüsselt haben, wie die Liquiditätsarchitektur, die Volumenverteilung und das Marktgedächtnis die wahre Struktur hinter den Preisbewegungen formen. Wir haben untersucht, wie Volume Nodes, Bereiche mit hoher Liquidität und Ineffizienzen mit geringem Volumen eine wiederholbare Blaupause dafür bilden, wo Märkte pausieren, expandieren oder umkehren. Anschließend haben wir diese strukturelle Logik in die algorithmische Ausführung übersetzt – und aufgezeigt, wie ein EA Volumenprofilzonen lesen, Liquiditätsereignisse antizipieren und Eingänge auf die tiefsten institutionellen Fußabdrücke statt auf oberflächliche Preisbewegungen abstimmen kann.

Zusammenfassend lässt sich sagen, dass AVPT den Händlern einen intelligenteren und kontextbewussten Ansatz für die Ausführung bietet: Handelsgeschäfte werden nicht mehr nur durch Muster oder Indikatoren ausgelöst, sondern durch das Verständnis, wo die tatsächliche Liquidität liegt und wie sich die Märkte an vergangene Ungleichgewichte „erinnern“. Durch die Integration von Marktgedächtnis, Volumenclustering und algorithmischer Entscheidungsfindung erhalten Händler einen Rahmen, der die Präzision verbessert, die Risikoplatzierung erhöht und rauschbedingte Signale reduziert.

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

Beigefügte Dateien |
AVPT.mq5 (25.64 KB)
Letzte Kommentare | Zur Diskussion im Händlerforum (9)
Hlomohang John Borotho
Hlomohang John Borotho | 28 Nov. 2025 in 14:55
Cédric Olivier Unterstützungs-/Widerstandsniveau

- Der Kurs neigt dazu, sich auf dieses Niveau zurückzuziehen

- **VAH (Value Area High)**: Die **obere gestrichelte grüne Linie** - obere Begrenzung der Value Zone
- **VAL (Value Area Low)**: Die **untere gestrichelte grüne Linie** - untere Grenze der Value Zone
- Der Raum zwischen VAH und VAL stellt den Bereich dar, in dem 70 % des Volumens gehandelt wurden.

- Dies wird als der "faire Wert" des Marktes für den analysierten Zeitraum angesehen.

- **HVN (High Volume Nodes)**: Die **gestrichelten blauen Linien** - Kursniveaus mit sehr hohem Volumen (1,5x das Medianvolumen)

- Bereiche mit starkem institutionellem Interesse

- Sehr gute Unterstützungs-/Widerstandsniveaus

- **LVN (Low Volume Nodes)**: Die **gestrichelten gelben Linien** - Kursniveaus mit sehr geringem Volumen (0,3x das mittlere Volumen)

- Bereiche mit geringem institutionellem Interesse

- Der Kurs durchbricht diese Niveaus im Allgemeinen schnell.

## Wie man diesen Indikator für den Handel verwendet

1. **Identifizierung von Schlüsselbereichen**:

- Der POC ist die wichtigste Ebene, die Sie überwachen müssen.

- Die Value Zone (zwischen VAH und VAL) ist der Bereich des "fairen Wertes".

2. **Handelsstrategien**:

- **Kaufen**: In der Nähe der Value Zone (VAL) oder des Point of Change (POC), wenn sich der Markt in einem Aufwärtstrend befindet

- **Verkaufen**: In der Nähe der Average Value Zone (AVT) oder des Point of Change (POC), wenn sich der Markt in einem Abwärtstrend befindet
- **Ziel**: Wenn der Kurs ein Durchschnittswertniveau (LVN) überschreitet, neigt er dazu, bis zum nächsten Hochwertniveau (HVN) weiterzugehen.
- **Stop-Loss**: Wird jenseits eines signifikanten HVN platziert

3. **Bestätigung**:

- Wenn der Kurs in die Value Zone zurückkehrt, nachdem er sie verlassen hat, ist dies oft ein gutes Signal für eine Rückkehr zum "fairen Wert".

- Ein Kurs oberhalb des AVT deutet auf Kaufdruck hin, unterhalb des VAL auf Verkaufsdruck

## Anpassbare Parameter (innerhalb des Indikators)
- Sie können den Prozentsatz der Value Zone anpassen (standardmäßig 70%)
- Sie können die Schwellenwerte für die HVN und LVN nach Ihren Wünschen ändern
- Sie können die Anzeige des Histogramms nach Bedarf aktivieren/deaktivieren.

Dieser Indikator ist besonders nützlich. Er hilft zu erkennen, wo Institutionen am aktivsten gehandelt haben (HVN), wo es wenig Aktivität gab (LVN) und wo der "faire" Preis liegt (Value Zone). Er wird von Händlern, die Smart Money-Konzepte verfolgen, sehr geschätzt.

Nochmals vielen Dank. Gemeinsam als Gemeinschaft sind wir schlauer!

Vielen Dank für den Indikator Cédric Olivier.

Hlomohang John Borotho
Hlomohang John Borotho | 28 Nov. 2025 in 14:56
Ryan L Johnson #:

Was für ein epischer Artikel und was für eine Diskussion... und das alles innerhalb von nur 3 Tagen.

@Hlomohang John Borotho, Vielen Dank.

@Cédric Olivier, Vielen Dank.


Ich würde mir keine Sorgen um das getestete Symbol machen. Zu Ihrer Information: Es handelte sich wahrscheinlich nicht um eine Sicherheit im technischen Sinne des Wortes, da iRealVolume() aus dem Code ausgeschlossen ist. Der Code verwendet iVolume(), das die gleichen Werte wie iTickVolume() zurückgibt - diese werden im Allgemeinen für OTC-Märkte verwendet, z. B. FX, CFDs usw.

Danke Ryan und Ihnen allen für das Feedback, Sie sind herzlich willkommen.
Hlomohang John Borotho
Hlomohang John Borotho | 28 Nov. 2025 in 14:59
Bryan John Aldridge Backtest durchgeführt wurde, um die vorgelegten Ergebnisse zu validieren.

Hey, das getestete Symbol ist XAUUSD, und bitte verweisen Sie auf den Testzeitraum und die Einstellungen, die verwendet wurden, um die gleichen Ergebnisse zu erzielen.

DecentOne
DecentOne | 1 Dez. 2025 in 07:43
Gibt es dafür einen EA, den ich herunterladen und verwenden kann?ich bin kein Programmierer
Ryan L Johnson
Ryan L Johnson | 1 Dez. 2025 in 13:11
DecentOne #:
Gibt es dafür einen EA, den ich herunterladen und benutzen kann?

Er befindet sich am Ende des Artikels, der oben in dieser Diskussion verlinkt ist:

Analytical Volume Profile Trading (AVPT): Liquiditätsarchitektur, Marktspeicher und algorithmische Ausführung

(So funktionieren alle Artikeldiskussionen, die automatisch im Forum veröffentlicht werden).

EA

Implementierung von praktischen Modulen aus anderen Sprachen in MQL5 (Teil 04): Zeit-, Datums- und Datetime-Module aus Python Implementierung von praktischen Modulen aus anderen Sprachen in MQL5 (Teil 04): Zeit-, Datums- und Datetime-Module aus Python
Im Gegensatz zu MQL5 bietet die Programmiersprache Python Kontrolle und Flexibilität, wenn es um den Umgang mit und die Manipulation von Zeit geht. In diesem Artikel werden wir ähnliche Module zur besseren Handhabung von Datum und Uhrzeit in MQL5 wie in Python implementieren.
Kagi-Charts in MQL5 beherrschen (Teil I): Erstellen des Indikators Kagi-Charts in MQL5 beherrschen (Teil I): Erstellen des Indikators
Lernen Sie, wie man eine komplette Kagi-Chart-Engine in MQL5 aufbaut – Preisumkehrungen konstruieren, dynamische Liniensegmente erzeugen und Kagi-Strukturen in Echtzeit aktualisieren. In diesem ersten Teil lernen Sie, wie Sie Kagi-Charts direkt auf dem MetaTrader 5 rendern können, sodass Händler einen klaren Überblick über Trendverschiebungen und Marktstärke erhalten. Gleichzeitig bereiten Sie sich auf die automatisierte Kagi-basierte Handelslogik in Teil 2 vor.
Eine alternative Log-datei mit der Verwendung der HTML und CSS Eine alternative Log-datei mit der Verwendung der HTML und CSS
In diesem Artikel werden wir eine sehr einfache, aber leistungsfähige Bibliothek zur Erstellung der HTML-Dateien schreiben, dabei lernen wir auch, wie man eine ihre Darstellung einstellen kann (nach seinem Geschmack) und sehen wir, wie man es leicht in seinem Expert Advisor oder Skript hinzufügen oder verwenden kann.
MetaTrader 5 Machine Learning Blueprint (Teil 6): Entwicklung eines produktionsgerechten Caching-Systems MetaTrader 5 Machine Learning Blueprint (Teil 6): Entwicklung eines produktionsgerechten Caching-Systems
Sind Sie es leid, Fortschrittsbalken zu beobachten, anstatt Handelsstrategien zu testen? Die herkömmliche Zwischenspeicherung versagt bei Financial ML, sodass Sie mit verlorenen Berechnungen und frustrierenden Neustarts konfrontiert werden. Wir haben eine ausgeklügelte Caching-Architektur entwickelt, die den besonderen Herausforderungen von Finanzdaten gerecht wird: zeitliche Abhängigkeiten, komplexe Datenstrukturen und die ständige Gefahr einer Verzerrung durch Vorausschau. Unser dreischichtiges System sorgt für drastische Geschwindigkeitsverbesserungen, während es veraltete Ergebnisse automatisch ungültig macht und kostspielige Datenlecks verhindert. Warten Sie nicht länger auf Berechnungen, sondern beginnen Sie mit der Iteration in dem Tempo, das der Markt verlangt.