remove bkp ...

This commit is contained in:
2025-03-08 22:03:50 +03:30
parent 3b7ce3816a
commit f428892c6d
14 changed files with 0 additions and 39580 deletions
-196
View File
@@ -1,196 +0,0 @@
//+------------------------------------------------------------------+
//| HH_LH_LL_HL.mq5 |
//| Indicator for detecting HH, LH, LL, HL |
//| Created by [Your Name] |
//+------------------------------------------------------------------+
#property copyright "Your Name"
#property link "yourwebsite.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots 4
//--- Input parameters
input int LookbackPeriod = 20; // Number of bars to look back for pattern detection
//--- Buffer declarations
double HH_Buffer[]; // Buffer for Higher Highs
double HL_Buffer[]; // Buffer for Higher Lows
double LH_Buffer[]; // Buffer for Lower Highs
double LL_Buffer[]; // Buffer for Lower Lows
//--- Plot settings
#property indicator_label1 "Higher Highs"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_label2 "Higher Lows"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrBlue
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
#property indicator_label3 "Lower Highs"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrRed
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
#property indicator_label4 "Lower Lows"
#property indicator_type4 DRAW_ARROW
#property indicator_color4 clrYellow
#property indicator_style4 STYLE_SOLID
#property indicator_width4 1
//+------------------------------------------------------------------+
//| Initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Set buffer properties
SetIndexBuffer(0, HH_Buffer);
SetIndexBuffer(1, HL_Buffer);
SetIndexBuffer(2, LH_Buffer);
SetIndexBuffer(3, LL_Buffer);
// Clear buffers at each bar
ArrayInitialize(HH_Buffer, 0.0);
ArrayInitialize(HL_Buffer, 0.0);
ArrayInitialize(LH_Buffer, 0.0);
ArrayInitialize(LL_Buffer, 0.0);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Cleanup if necessary
}
//+------------------------------------------------------------------+
//| Calculate function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
// Start from the last calculated bar
int start_bar = MathMax(prev_calculated - 1, 0);
// Loop through bars
for (int i = start_bar; i < rates_total; i++)
{
// Get current high and low
double current_high = high[i];
double current_low = low[i];
// Check for Higher High (HH)
if (IsHigherHigh(i, high, LookbackPeriod))
{
HH_Buffer[i] = current_high;
HL_Buffer[i] = 0.0; // Reset other buffers
LH_Buffer[i] = 0.0;
LL_Buffer[i] = 0.0;
}
// Check for Higher Low (HL)
else if (IsHigherLow(i, low, LookbackPeriod))
{
HL_Buffer[i] = current_low;
HH_Buffer[i] = 0.0;
LH_Buffer[i] = 0.0;
LL_Buffer[i] = 0.0;
}
// Check for Lower High (LH)
else if (IsLowerHigh(i, high, LookbackPeriod))
{
LH_Buffer[i] = current_high;
HH_Buffer[i] = 0.0;
HL_Buffer[i] = 0.0;
LL_Buffer[i] = 0.0;
}
// Check for Lower Low (LL)
else if (IsLowerLow(i, low, LookbackPeriod))
{
LL_Buffer[i] = current_low;
HH_Buffer[i] = 0.0;
HL_Buffer[i] = 0.0;
LH_Buffer[i] = 0.0;
}
else
{
// Reset all buffers if no pattern is detected
HH_Buffer[i] = 0.0;
HL_Buffer[i] = 0.0;
LH_Buffer[i] = 0.0;
LL_Buffer[i] = 0.0;
}
}
//
return rates_total;
}
//+------------------------------------------------------------------+
//| Function to detect Higher High |
//+------------------------------------------------------------------+
bool IsHigherHigh(int index, const double &high[], int lookback)
{
for (int i = 1; i <= lookback; i++)
{
if (index - i < 0) continue; // Ensure we don't go out of bounds
if (high[index] <= high[index - i]) return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Function to detect Higher Low |
//+------------------------------------------------------------------+
bool IsHigherLow(int index, const double &low[], int lookback)
{
for (int i = 1; i <= lookback; i++)
{
if (index - i < 0) continue; // Ensure we don't go out of bounds
if (low[index] <= low[index - i]) return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Function to detect Lower High |
//+------------------------------------------------------------------+
bool IsLowerHigh(int index, const double &high[], int lookback)
{
for (int i = 1; i <= lookback; i++)
{
if (index - i < 0) continue; // Ensure we don't go out of bounds
if (high[index] >= high[index - i]) return false;
}
return true;
}
//+------------------------------------------------------------------+
//| Function to detect Lower Low |
//+------------------------------------------------------------------+
bool IsLowerLow(int index, const double &low[], int lookback)
{
for (int i = 1; i <= lookback; i++)
{
if (index - i < 0) continue; // Ensure we don't go out of bounds
if (low[index] >= low[index - i]) return false;
}
return true;
}
-10874
View File
File diff suppressed because it is too large Load Diff
-243
View File
@@ -1,243 +0,0 @@
//+------------------------------------------------------------------+
//| Test.mq5 |
//| Copyright 2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
//
#include "../Classes/x-saherelm.x-bar.analyser.class.mq5"
#include "../Classes/x-saherelm.x-poi.class.mq5"
#include "../Classes/x-saherelm.x-poi.drawer.class.mq5"
//
XCPOIDrawer *mPOIDrawer;
XCPOIDetector *mPOIDetector;
XCBarAnalyser *mBarAnalyser;
//
XBarTracker mBarTracker;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
mPOIDetector = new XCPOIDetector(
_Symbol,
_Period //
);
mPOIDetector.Init();
//---
mPOIDrawer = new XCPOIDrawer();
//---
mBarAnalyser = new XCBarAnalyser();
//---
mBarTracker.Init(
_Symbol,
_Period //
);
//---
return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
ZeroMemory(mPOIDrawer);
ZeroMemory(mBarAnalyser);
ZeroMemory(mPOIDetector);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//
bool isNewBar = mBarTracker.IsNewBar();
if (!isNewBar)
{
return;
}
//
ENUM_XPOI_EVENTS mPOIEvents[];
mPOIDetector.Update(mPOIEvents);
//
XPOIState mPOIState;
mPOIDetector.GetState(mPOIState);
//
bool has = Contains(
X_BULLISH_FVG_DETECTED,
mPOIEvents //
) ||
Contains(
X_BEARISH_FVG_DETECTED,
mPOIEvents //
);
if (has)
{
//
XCFVG *fvg;
int idx = GetYoungest(mPOIState.fairValueGaps);
has = IsValidIndex(idx);
if (has)
{
//
fvg = mPOIState.fairValueGaps[idx];
//
XCBaseObject *iObj;
has = mPOIDrawer.CreateFairValueGap(
fvg,
iObj //
);
//
if (has)
{
//
Print("New Fair Value Gap ...");
}
}
}
// //
// bool has = mPOIState.HasFairValueGaps();
// if (has)
// {
// //
// int count = mPOIState.CountFairValueGaps();
// for (int i = 0; i < count; i++)
// {
// //
// mPOIState.fairValueGaps[i].To(TimeCurrent());
// //
// XCBaseObject *iObj;
// bool isCreated = mPOIDrawer.CreateFairValueGap(
// mPOIState.fairValueGaps[i],
// iObj //
// );
// }
//
// Print("Salam");
//
return;
// //
// XOHCL bar;
// bool isInited = bar.Init(
// _Symbol,
// _Period,
// 0 //
// );
// if (!isInited)
// {
// return;
// }
// //
// int index = 0;
// ENUM_X_DIRECTION sameBarDir;
// bool hasSameBars = mBarAnalyser.HasSameBars(
// bar,
// sameBarDir,
// index,
// 3 //
// );
// if (hasSameBars)
// {
// }
// //
// // Detect Fair Value Gap ...
// XOHCL fvgEndBar;
// XOHCL fvgStartBar;
// ENUM_X_DIRECTION fvgDir;
// bool hasFVG = mBarAnalyser.HasFairValueGap(
// bar,
// fvgStartBar,
// fvgEndBar,
// fvgDir,
// 3 //
// );
// if (hasFVG)
// {
// //
// XCFVG *fvg;
// fvg = new XCFVG();
// bool isInit = fvg.Init(
// fvgStartBar,
// fvgEndBar,
// fvgDir //
// );
// // if (isInit)
// // {
// // //
// // XCBaseObject *iObj;
// // bool isCreated = mPOIDrawer.CreateFairValueGap(
// // fvg,
// // iObj //
// // );
// //
// // //
// // if (isCreated)
// // {
// // }
// // }
// }
// //
// XOHCL obBar;
// ENUM_X_DIRECTION obDir;
// bool hasOB = mBarAnalyser.HasOrderBlock(
// bar,
// obBar,
// obDir,
// 3 //
// );
// if (hasOB)
// {
// //
// XCOrderBlock *ob;
// ob = new XCOrderBlock();
// bool isInit = ob.Init(
// obBar,
// obDir //
// );
// if (isInit)
// {
// // //
// // XCBaseObject *iObj;
// // bool isCreated = mPOIDrawer.CreateOrderBlock(
// // ob,
// // iObj //
// // );
// // //
// // if (isCreated)
// // {
// // Print("Order Block ...");
// // }
// // }
// }
// //
// }
}
//+------------------------------------------------------------------+
-418
View File
@@ -1,418 +0,0 @@
//+------------------------------------------------------------------+
//| SMC_OrderBlock_EA.mq5|
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#include <Trade/AccountInfo.mqh>
#include <Trade/Trade.mqh>
//
// Input parameters
input ENUM_TIMEFRAMES TimeFrame = PERIOD_M15; // Timeframe for analysis
input double RiskPercent = 1.0; // Risk per trade (1-2%)
input int ATR_Period = 14; // ATR period for volatility
input int OrderBlockLength = 20; // Bars for consolidation
input int ConfirmationCandles = 3; // Candles to confirm breakout
input double StopLossMultiplier = 1.5; // Stop loss buffer
input double TakeProfitRatio = 2.0; // Risk:Reward ratio
input int TrailingStopPips = 50; // Trailing stop in pips
//
CTrade trade;
CAccountInfo accountInfo;
//
double Ask = 0;
double Bid = 0;
//
// Order Block structure
struct OrderBlock
{
datetime startTime;
double high;
double low;
};
//
int atrHandler = INVALID_HANDLE;
int maFastHandler = INVALID_HANDLE;
int maSlowHandler = INVALID_HANDLE;
//
double atrs[];
double fastMAs[];
double slowMAs[];
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//
trade.SetExpertMagicNumber(123456); // Unique magic number
//
atrHandler = iATR(_Symbol, TimeFrame, ATR_Period);
maFastHandler = iMA(_Symbol, TimeFrame, 20, 0, MODE_SMA, PRICE_CLOSE);
maSlowHandler = iMA(_Symbol, TimeFrame, 50, 0, MODE_SMA, PRICE_CLOSE);
//
bool isValid =
atrHandler != INVALID_HANDLE &&
maFastHandler != INVALID_HANDLE &&
maSlowHandler != INVALID_HANDLE;
if (!isValid)
{
return (INIT_FAILED);
}
//
return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//
// Cleanup code if needed ...
IndicatorRelease(atrHandler);
IndicatorRelease(maFastHandler);
IndicatorRelease(maSlowHandler);
//
ZeroMemory(atrs);
ZeroMemory(fastMAs);
ZeroMemory(slowMAs);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Avoid multiple orders
if (CheckOpenOrders())
return;
//
CopyBuffer(atrHandler, MAIN_LINE, 0, 200, atrs);
//
CopyBuffer(maFastHandler, MAIN_LINE, 0, 2, fastMAs);
CopyBuffer(maSlowHandler, MAIN_LINE, 0, 2, slowMAs);
//
Ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits); // Get the Ask Price
Bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits); // Get the Bid Price
//
// Check for trend and execute trades
if (IsUptrend())
{
OrderBlock block = FindBullishOrderBlock();
if (block.startTime != 0 && IsPriceInBlock(block))
{
if (ConfirmBullishEntry())
ExecuteTrade(block, ORDER_TYPE_BUY);
}
}
else if (IsDowntrend())
{
OrderBlock block = FindBearishOrderBlock();
if (block.startTime != 0 && IsPriceInBlock(block))
{
if (ConfirmBearishEntry())
ExecuteTrade(block, ORDER_TYPE_SELL);
}
}
// Manage trailing stops
TrailStop();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Check if price is within the order block |
//+------------------------------------------------------------------+
bool IsPriceInBlock(OrderBlock &block)
{
double currentPrice = (Ask + Bid) / 2; // Mid-price
return (currentPrice >= block.low && currentPrice <= block.high);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Detect uptrend using moving averages |
//+------------------------------------------------------------------+
bool IsUptrend()
{
//
double maFast = fastMAs[0];
double maSlow = slowMAs[0];
//
return (maFast > maSlow);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Detect downtrend using moving averages |
//+------------------------------------------------------------------+
bool IsDowntrend()
{
//
double maFast = fastMAs[0];
double maSlow = slowMAs[0];
//
return (maFast < maSlow);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Find bullish order blocks |
//+------------------------------------------------------------------+
OrderBlock FindBullishOrderBlock()
{
//
OrderBlock block;
block.startTime = 0;
//
for (int i = 1; i < 100; i++)
{
double prevHigh = iHigh(NULL, TimeFrame, i);
double prevLow = iLow(NULL, TimeFrame, i);
double prevClose = iClose(NULL, TimeFrame, i);
double prevOpen = iOpen(NULL, TimeFrame, i);
double atr = atrs[i];
if (prevClose - prevOpen > 1.5 * atr)
{ // Strong bullish candle
double consolidationHigh = prevHigh;
double consolidationLow = prevLow;
bool isConsolidation = true;
for (int j = 1; j <= OrderBlockLength; j++)
{
double newHigh = iHigh(NULL, TimeFrame, i - j);
double newLow = iLow(NULL, TimeFrame, i - j);
consolidationHigh = MathMax(consolidationHigh, newHigh);
consolidationLow = MathMin(consolidationLow, newLow);
if ((consolidationHigh - consolidationLow) > 0.5 * atr)
{
isConsolidation = false;
break;
}
}
if (isConsolidation)
{
block.high = consolidationHigh;
block.low = consolidationLow;
block.startTime = iTime(NULL, TimeFrame, i);
return block;
}
}
}
return block;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Find bearish order blocks |
//+------------------------------------------------------------------+
OrderBlock FindBearishOrderBlock()
{
//
OrderBlock block;
block.startTime = 0;
//
for (int i = 1; i < 100; i++)
{
double prevHigh = iHigh(NULL, TimeFrame, i);
double prevLow = iLow(NULL, TimeFrame, i);
double prevClose = iClose(NULL, TimeFrame, i);
double prevOpen = iOpen(NULL, TimeFrame, i);
double atr = atrs[i];
if (prevOpen - prevClose > 1.5 * atr)
{ // Strong bearish candle
double consolidationHigh = prevHigh;
double consolidationLow = prevLow;
bool isConsolidation = true;
for (int j = 1; j <= OrderBlockLength; j++)
{
double newHigh = iHigh(NULL, TimeFrame, i - j);
double newLow = iLow(NULL, TimeFrame, i - j);
consolidationHigh = MathMax(consolidationHigh, newHigh);
consolidationLow = MathMin(consolidationLow, newLow);
if ((consolidationHigh - consolidationLow) > 0.5 * atr)
{
isConsolidation = false;
break;
}
}
if (isConsolidation)
{
block.high = consolidationHigh;
block.low = consolidationLow;
block.startTime = iTime(NULL, TimeFrame, i);
return block;
}
}
}
return block;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Confirm bullish entry with candle pattern |
//+------------------------------------------------------------------+
bool ConfirmBullishEntry()
{
//
int shift = iBarShift(NULL, TimeFrame, TimeCurrent());
double prevLow = iLow(NULL, TimeFrame, shift + 1);
double currentClose = iClose(NULL, TimeFrame, shift);
return (currentClose > prevLow && iOpen(NULL, TimeFrame, shift) < currentClose);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Confirm bearish entry with candle pattern |
//+------------------------------------------------------------------+
bool ConfirmBearishEntry()
{
//
int shift = iBarShift(NULL, TimeFrame, TimeCurrent());
double prevHigh = iHigh(NULL, TimeFrame, shift + 1);
double currentClose = iClose(NULL, TimeFrame, shift);
return (currentClose < prevHigh && iOpen(NULL, TimeFrame, shift) > currentClose);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Execute trade with risk management |
//+------------------------------------------------------------------+
void ExecuteTrade(OrderBlock &block, ENUM_ORDER_TYPE orderType)
{
//
double atr = atrs[0];
double stopLoss, takeProfit, lotSize;
double entryPrice = (orderType == ORDER_TYPE_BUY) ? Ask : Bid;
// Calculate stop loss and take profit
if (orderType == ORDER_TYPE_BUY)
{
stopLoss = block.low - StopLossMultiplier * atr;
takeProfit = entryPrice + (entryPrice - stopLoss) * TakeProfitRatio;
}
else
{
stopLoss = block.high + StopLossMultiplier * atr;
takeProfit = entryPrice - (stopLoss - entryPrice) * TakeProfitRatio;
}
// Calculate lot size based on risk
lotSize = CalculateLotSize(stopLoss, entryPrice, orderType);
if (lotSize <= 0)
return;
// Place order
if (orderType == ORDER_TYPE_BUY)
{
trade.Buy(lotSize, _Symbol, entryPrice, stopLoss, takeProfit, "SMC Bullish Order Block");
}
else
{
trade.Sell(lotSize, _Symbol, entryPrice, stopLoss, takeProfit, "SMC Bearish Order Block");
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Calculate lot size based on risk per trade |
//+------------------------------------------------------------------+
double CalculateLotSize(double stopLoss, double entryPrice, ENUM_ORDER_TYPE orderType)
{
double riskAmount = AccountBalance() * RiskPercent / 100;
double stopLossPips = MathAbs((entryPrice - stopLoss) / SymbolInfoDouble(_Symbol, SYMBOL_POINT));
if (stopLossPips == 0)
return 0;
double pipValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double lotSize = riskAmount / (stopLossPips * pipValue);
lotSize = NormalizeDouble(lotSize, 2); // Adjust to symbol's lot precision
return MathMax(lotSize, SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN));
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Check for existing open orders |
//+------------------------------------------------------------------+
bool CheckOpenOrders()
{
for (int i = 0; i < PositionsTotal(); i++)
{
if (PositionGetSymbol(i) == _Symbol)
return true;
}
return false;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Trailing stop logic |
//+------------------------------------------------------------------+
void TrailStop()
{
for (int i = 0; i < PositionsTotal(); i++)
{
if (PositionGetSymbol(i) != _Symbol)
continue;
ulong ticket = PositionGetInteger(POSITION_TICKET);
ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
double currentPrice = (type == POSITION_TYPE_BUY) ? Bid : Ask;
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
double stopLoss = PositionGetDouble(POSITION_SL);
double trailingStopPrice = (type == POSITION_TYPE_BUY)
? currentPrice - TrailingStopPips * SymbolInfoDouble(_Symbol, SYMBOL_POINT)
: currentPrice + TrailingStopPips * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
// Update stop loss if price moves favorably
if ((type == POSITION_TYPE_BUY && trailingStopPrice > stopLoss) ||
(type == POSITION_TYPE_SELL && trailingStopPrice < stopLoss))
{
trade.PositionModify(ticket, trailingStopPrice, PositionGetDouble(POSITION_TP));
}
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Calculate Account Balance |
//+------------------------------------------------------------------+
double AccountBalance()
{
return accountInfo.Balance();
}
//+------------------------------------------------------------------+
-275
View File
@@ -1,275 +0,0 @@
//+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff