Add support for Golden Zone inside XPV indicator and it's Helper ...
This commit is contained in:
@@ -0,0 +1,275 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| OrderBlockDetector.mq5|
|
||||
//| Copyright 2023, MetaQuotes Software Corp. |
|
||||
//| https://www.mql5.com|
|
||||
//+------------------------------------------------------------------+
|
||||
#property strict
|
||||
|
||||
//
|
||||
// Input Parameters
|
||||
input int ConsolidationPeriod = 20; // Bars for consolidation detection
|
||||
input int AtrPeriod = 14; // ATR period for volatility
|
||||
input double AtrMultiplier = 2.0; // Threshold multiplier (ATR * multiplier)
|
||||
input int VolumeThreshold = 1000; // Minimum volume for breakout
|
||||
input bool RequireRetest = true; // Retest confirmation required?
|
||||
input int VpvrBars = 50; // Bars for VPVR calculation
|
||||
input int TrendCheckPeriod = 30; // Bars for trend structure analysis
|
||||
input int MACDFast = 12; // MACD Fast EMA period
|
||||
input int MACDSlow = 26; // MACD Slow EMA period
|
||||
input int MACDSignal = 9; // MACD Signal period
|
||||
input int RSIPeriod = 14; // RSI period
|
||||
input double RSILevel = 50; // RSI threshold level
|
||||
|
||||
// Global Variables
|
||||
int ObjectId = 0;
|
||||
string Prefix = "OrderBlock_";
|
||||
|
||||
//
|
||||
enum ENUM_X_DIRECTION
|
||||
{
|
||||
X_DIRECTION_NONE,
|
||||
X_DIRECTION_BULISH,
|
||||
X_DIRECTION_BEARISH,
|
||||
};
|
||||
|
||||
//
|
||||
int atrHandler = INVALID_HANDLE;
|
||||
double atrBuffer[];
|
||||
|
||||
//
|
||||
int rsiHandler = INVALID_HANDLE;
|
||||
double rsiBuffer[];
|
||||
|
||||
//
|
||||
int macdHandler = INVALID_HANDLE;
|
||||
double macdMainBuffer[];
|
||||
double macdSignalBuffer[];
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
ArraySetAsSeries(atrBuffer, true);
|
||||
atrHandler = iATR(_Symbol, _Period, AtrPeriod);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(rsiBuffer, true);
|
||||
rsiHandler = iRSI(_Symbol, _Period, RSIPeriod, PRICE_CLOSE);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(macdMainBuffer, true);
|
||||
ArraySetAsSeries(macdSignalBuffer, true);
|
||||
macdHandler = iMACD(_Symbol, _Period, MACDFast, MACDSlow, MACDSignal, PRICE_CLOSE);
|
||||
|
||||
//
|
||||
ObjectsDeleteAll(0, Prefix);
|
||||
return (INIT_SUCCEEDED);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//
|
||||
IndicatorRelease(atrHandler);
|
||||
ObjectsDeleteAll(0, Prefix);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert tick function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTick()
|
||||
{
|
||||
DetectOrderBlocks();
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Detect Order Blocks with ATR Dynamic Threshold |
|
||||
//+------------------------------------------------------------------+
|
||||
void DetectOrderBlocks()
|
||||
{
|
||||
double high, low, vpvrPrice, atr, dynamicThreshold;
|
||||
datetime startTime, endTime;
|
||||
bool isBullish, isBearish;
|
||||
int bars = Bars(_Symbol, _Period);
|
||||
|
||||
for (int i = ConsolidationPeriod; i < bars; i++)
|
||||
{
|
||||
//
|
||||
// Get consolidation range
|
||||
high = iHigh(_Symbol, _Period, iHighest(_Symbol, _Period, MODE_HIGH, ConsolidationPeriod, i));
|
||||
low = iLow(_Symbol, _Period, iLowest(_Symbol, _Period, MODE_LOW, ConsolidationPeriod, i));
|
||||
double range = high - low;
|
||||
|
||||
//
|
||||
// Calculate dynamic threshold using ATR
|
||||
CopyBuffer(atrHandler, MAIN_LINE, i, 2, atrBuffer);
|
||||
atr = atrBuffer[0];
|
||||
dynamicThreshold = atr * AtrMultiplier;
|
||||
|
||||
// Check if consolidation range is within ATR-based threshold
|
||||
if (range <= dynamicThreshold)
|
||||
{
|
||||
// VPVR Integration
|
||||
vpvrPrice = CalculateVPVR(i, ConsolidationPeriod);
|
||||
bool validVPVR = (vpvrPrice > low && vpvrPrice < high);
|
||||
|
||||
// Check breakout direction
|
||||
isBullish = iClose(_Symbol, _Period, i - ConsolidationPeriod) > high;
|
||||
isBearish = iClose(_Symbol, _Period, i - ConsolidationPeriod) < low;
|
||||
|
||||
// Trend Verification
|
||||
ENUM_X_DIRECTION trend = CheckTrendStructure(TrendCheckPeriod);
|
||||
|
||||
// MACD/RSI Verification
|
||||
bool macdValid = CheckMACD(trend);
|
||||
bool rsiValid = CheckRSI(trend);
|
||||
|
||||
// Validate all conditions
|
||||
if ((isBullish || isBearish) && validVPVR &&
|
||||
(trend != -1) && macdValid && rsiValid)
|
||||
{
|
||||
double breakoutVolume = (double)iVolume(_Symbol, _Period, i - ConsolidationPeriod);
|
||||
if (breakoutVolume < VolumeThreshold)
|
||||
continue;
|
||||
|
||||
// Define order block time window
|
||||
startTime = iTime(_Symbol, _Period, i);
|
||||
endTime = iTime(_Symbol, _Period, i + ConsolidationPeriod);
|
||||
|
||||
// Check retest (if required)
|
||||
if (RequireRetest)
|
||||
{
|
||||
bool retestFound = false;
|
||||
for (int j = i - ConsolidationPeriod; j > 0; j--)
|
||||
{
|
||||
if ((isBullish && iLow(_Symbol, _Period, j) <= low && iLow(_Symbol, _Period, j) >= high) ||
|
||||
(isBearish && iHigh(_Symbol, _Period, j) >= high && iHigh(_Symbol, _Period, j) <= low))
|
||||
{
|
||||
retestFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!retestFound)
|
||||
continue;
|
||||
}
|
||||
|
||||
// Draw order block with ATR annotation
|
||||
string name = Prefix + IntegerToString(ObjectId++);
|
||||
DrawOrderBlock(name, startTime, endTime, low, high,
|
||||
isBullish ? clrGreen : clrRed, vpvrPrice, dynamicThreshold);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Trend Detection using Price Structure |
|
||||
//+------------------------------------------------------------------+
|
||||
ENUM_X_DIRECTION CheckTrendStructure(int period)
|
||||
{
|
||||
int currentStart = 1;
|
||||
int previousStart = period + 1;
|
||||
|
||||
double currentHigh = iHigh(_Symbol, _Period, iHighest(_Symbol, _Period, MODE_HIGH, period, currentStart));
|
||||
double previousHigh = iHigh(_Symbol, _Period, iHighest(_Symbol, _Period, MODE_HIGH, period, previousStart));
|
||||
double currentLow = iLow(_Symbol, _Period, iLowest(_Symbol, _Period, MODE_LOW, period, currentStart));
|
||||
double previousLow = iLow(_Symbol, _Period, iLowest(_Symbol, _Period, MODE_LOW, period, previousStart));
|
||||
|
||||
if (currentHigh > previousHigh && currentLow > previousLow)
|
||||
return (X_DIRECTION_BULISH); // Uptrend
|
||||
else if (currentHigh < previousHigh && currentLow < previousLow)
|
||||
return (X_DIRECTION_BEARISH); // Downtrend
|
||||
else
|
||||
return (X_DIRECTION_NONE); // No clear trend
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| MACD Trend Verification |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CheckMACD(ENUM_X_DIRECTION trend)
|
||||
{
|
||||
//
|
||||
CopyBuffer(macdHandler, MAIN_LINE, 0, 1, macdMainBuffer);
|
||||
CopyBuffer(macdHandler, SIGNAL_LINE, 0, 1, macdSignalBuffer);
|
||||
double macdMain = macdMainBuffer[0];
|
||||
double macdSignal = macdSignalBuffer[0];
|
||||
|
||||
//
|
||||
if (trend == X_DIRECTION_BULISH)
|
||||
return (macdMain > macdSignal);
|
||||
if (trend == X_DIRECTION_BEARISH)
|
||||
return (macdMain < macdSignal);
|
||||
return (false);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| RSI Trend Verification |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CheckRSI(ENUM_X_DIRECTION trend)
|
||||
{
|
||||
//
|
||||
CopyBuffer(rsiHandler, MAIN_LINE, 0, 1, rsiBuffer);
|
||||
double rsiValue = rsiBuffer[0];
|
||||
|
||||
//
|
||||
if (trend == X_DIRECTION_BULISH)
|
||||
return (rsiValue > RSILevel);
|
||||
if (trend == X_DIRECTION_BEARISH)
|
||||
return (rsiValue < RSILevel);
|
||||
return (false);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Calculate VPVR High Volume Node |
|
||||
//+------------------------------------------------------------------+
|
||||
double CalculateVPVR(int startIdx, int period)
|
||||
{
|
||||
double maxVolume = 0;
|
||||
double vpvrPrice = 0;
|
||||
double price, volume;
|
||||
|
||||
for (int i = startIdx; i < startIdx + period; i++)
|
||||
{
|
||||
price = (iHigh(_Symbol, _Period, i) + iLow(_Symbol, _Period, i)) / 2;
|
||||
volume = (double)iVolume(_Symbol, _Period, i);
|
||||
if (volume > maxVolume)
|
||||
{
|
||||
maxVolume = volume;
|
||||
vpvrPrice = price;
|
||||
}
|
||||
}
|
||||
return (vpvrPrice);
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Draw Order Block with ATR Annotation |
|
||||
//+------------------------------------------------------------------+
|
||||
void DrawOrderBlock(string name, datetime startTime, datetime endTime,
|
||||
double bottom, double top, color clr, double vpvrPrice, double atrThreshold)
|
||||
{
|
||||
// Draw rectangle
|
||||
ObjectCreate(0, name + "_rect", OBJ_RECTANGLE, 0, startTime, top, endTime, bottom);
|
||||
ObjectSetInteger(0, name + "_rect", OBJPROP_COLOR, clr);
|
||||
ObjectSetInteger(0, name + "_rect", OBJPROP_FILL, true);
|
||||
ObjectSetInteger(0, name + "_rect", OBJPROP_BACK, true);
|
||||
ObjectSetInteger(0, name + "_rect", OBJPROP_WIDTH, 2);
|
||||
|
||||
// Draw VPVR marker
|
||||
if (vpvrPrice > 0)
|
||||
{
|
||||
ObjectCreate(0, name + "_vpvr", OBJ_HLINE, 0, 0, vpvrPrice);
|
||||
ObjectSetInteger(0, name + "_vpvr", OBJPROP_COLOR, clrYellow);
|
||||
ObjectSetInteger(0, name + "_vpvr", OBJPROP_WIDTH, 1);
|
||||
}
|
||||
|
||||
// Add ATR threshold label
|
||||
string atrLabel = StringFormat("ATR Threshold: %.5f", atrThreshold);
|
||||
ObjectCreate(0, name + "_atr", OBJ_TEXT, 0, startTime, top);
|
||||
ObjectSetString(0, name + "_atr", OBJPROP_TEXT, atrLabel);
|
||||
ObjectSetInteger(0, name + "_atr", OBJPROP_COLOR, clrWhite);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Reference in New Issue
Block a user