last ...
This commit is contained in:
@@ -0,0 +1,186 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| SMC_Indicator.mq5 |
|
||||||
|
//| Smart Money Concepts Indicator for MT5 |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5";
|
||||||
|
|
||||||
|
#property indicator_chart_window
|
||||||
|
#property indicator_buffers 8
|
||||||
|
#property indicator_color1 clrGreen // BOS Up
|
||||||
|
#property indicator_color2 clrRed // BOS Down
|
||||||
|
#property indicator_color3 clrBlue // Order Block
|
||||||
|
#property indicator_color4 clrOrange // FVG
|
||||||
|
#property indicator_color5 clrPurple // Liquidity Zones
|
||||||
|
#property indicator_color6 clrMagenta // Premium/Discount Levels
|
||||||
|
#property indicator_color7 clrYellow // Equal Highs
|
||||||
|
#property indicator_color8 clrCyan // Equal Lows
|
||||||
|
|
||||||
|
// Indicator buffers
|
||||||
|
double BosUpBuffer[];
|
||||||
|
double BosDownBuffer[];
|
||||||
|
double OrderBlockBuffer[];
|
||||||
|
double FvgBuffer[];
|
||||||
|
double LiquidityBuffer[];
|
||||||
|
double PremiumBuffer[];
|
||||||
|
double EqualHighBuffer[];
|
||||||
|
double EqualLowBuffer[];
|
||||||
|
|
||||||
|
// Input parameters for customization
|
||||||
|
input int swingRange = 2; // Range to detect swing highs/lows
|
||||||
|
input int orderBlockLookback = 20; // Bars to look back for order blocks
|
||||||
|
input int fvgDepth = 3; // Depth for fair value gaps
|
||||||
|
input bool enableAlerts = true; // Enable alerts for SMC signals
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Initialization |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
SetIndexBuffer(0, BosUpBuffer, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(1, BosDownBuffer, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(2, OrderBlockBuffer, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(3, FvgBuffer, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(4, LiquidityBuffer, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(5, PremiumBuffer, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(6, EqualHighBuffer, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(7, EqualLowBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME, "Smart Money Concepts Indicator");
|
||||||
|
|
||||||
|
return INIT_SUCCEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Swing High and Low Detection |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool isSwingHigh(int index)
|
||||||
|
{
|
||||||
|
double high = iHigh(_Symbol, _Period, index);
|
||||||
|
for (int i = 1; i <= swingRange; i++)
|
||||||
|
{
|
||||||
|
if (iHigh(_Symbol, _Period, index + i) >= high || iHigh(_Symbol, _Period, index - i) >= high)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool isSwingLow(int index)
|
||||||
|
{
|
||||||
|
double low = iLow(_Symbol, _Period, index);
|
||||||
|
for (int i = 1; i <= swingRange; i++)
|
||||||
|
{
|
||||||
|
if (iLow(_Symbol, _Period, index + i) <= low || iLow(_Symbol, _Period, index - i) <= low)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Detect Order Blocks |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void detectOrderBlocks(int rates_total)
|
||||||
|
{
|
||||||
|
ArrayInitialize(OrderBlockBuffer, 0);
|
||||||
|
|
||||||
|
for (int i = rates_total - orderBlockLookback - 1; i >= swingRange; i--)
|
||||||
|
{
|
||||||
|
if (isSwingHigh(i))
|
||||||
|
{
|
||||||
|
OrderBlockBuffer[i] = iHigh(_Symbol, _Period, i); // Bullish Order Block
|
||||||
|
}
|
||||||
|
else if (isSwingLow(i))
|
||||||
|
{
|
||||||
|
OrderBlockBuffer[i] = iLow(_Symbol, _Period, i); // Bearish Order Block
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Detect Fair Value Gaps |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void detectFairValueGaps(int rates_total)
|
||||||
|
{
|
||||||
|
ArrayInitialize(FvgBuffer, 0);
|
||||||
|
|
||||||
|
for (int i = rates_total - fvgDepth - 1; i >= swingRange; i--)
|
||||||
|
{
|
||||||
|
if (iHigh(_Symbol, _Period, i) < iLow(_Symbol, _Period, i - fvgDepth))
|
||||||
|
{
|
||||||
|
FvgBuffer[i] = (iHigh(_Symbol, _Period, i) + iLow(_Symbol, _Period, i - fvgDepth)) / 2.0; // FVG midpoint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Detect Liquidity Zones |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void detectLiquidityZones(int rates_total)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ArrayInitialize(LiquidityBuffer, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
double points = GetPoints(_Symbol);
|
||||||
|
|
||||||
|
//
|
||||||
|
for (int i = rates_total - swingRange - 1; i >= swingRange; i--)
|
||||||
|
{
|
||||||
|
if (isSwingHigh(i))
|
||||||
|
{
|
||||||
|
LiquidityBuffer[i] = iHigh(_Symbol, _Period, i) + (points * 10); // Above swing high for liquidity pool
|
||||||
|
}
|
||||||
|
else if (isSwingLow(i))
|
||||||
|
{
|
||||||
|
LiquidityBuffer[i] = iLow(_Symbol, _Period, i) - (points * 10); // Below swing low for liquidity pool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Detect Equal Highs and Lows |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void detectEqualHighsLows(int rates_total)
|
||||||
|
{
|
||||||
|
ArrayInitialize(EqualHighBuffer, 0);
|
||||||
|
ArrayInitialize(EqualLowBuffer, 0);
|
||||||
|
|
||||||
|
for (int i = rates_total - swingRange - 1; i >= swingRange; i--)
|
||||||
|
{
|
||||||
|
if (isSwingHigh(i) && iHigh(_Symbol, _Period, i) == iHigh(_Symbol, _Period, i + swingRange))
|
||||||
|
{
|
||||||
|
EqualHighBuffer[i] = iHigh(_Symbol, _Period, i);
|
||||||
|
}
|
||||||
|
else if (isSwingLow(i) && iLow(_Symbol, _Period, i) == iLow(_Symbol, _Period, i + swingRange))
|
||||||
|
{
|
||||||
|
EqualLowBuffer[i] = iLow(_Symbol, _Period, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Main Calculation Loop |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
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[])
|
||||||
|
{
|
||||||
|
|
||||||
|
detectOrderBlocks(rates_total);
|
||||||
|
detectFairValueGaps(rates_total);
|
||||||
|
detectLiquidityZones(rates_total);
|
||||||
|
detectEqualHighsLows(rates_total);
|
||||||
|
|
||||||
|
return rates_total;
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
@@ -347,6 +347,229 @@ class XCZone : public XCBasePOI
|
|||||||
//
|
//
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// From To Zone ...
|
||||||
|
class XCFromToZone : public XCBasePOI
|
||||||
|
{
|
||||||
|
//
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor ...
|
||||||
|
void XCFromToZone()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
void ~XCFromToZone()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
bool InitFromTo(
|
||||||
|
ENUM_XPOIS type,
|
||||||
|
string title,
|
||||||
|
datetime from //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = type != X_POI_NONE &&
|
||||||
|
IsSpecifiedValid(from) &&
|
||||||
|
IsSpecifiedValid(title);
|
||||||
|
|
||||||
|
//
|
||||||
|
mType = type;
|
||||||
|
mFrom = from;
|
||||||
|
mTitle = title;
|
||||||
|
mTo = TimeCurrent();
|
||||||
|
|
||||||
|
//
|
||||||
|
result = IsValid();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InitFromTo(
|
||||||
|
ENUM_XPOIS type,
|
||||||
|
string title,
|
||||||
|
datetime from,
|
||||||
|
datetime to //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = IsValid();
|
||||||
|
|
||||||
|
//
|
||||||
|
result = InitFromTo(
|
||||||
|
type,
|
||||||
|
title,
|
||||||
|
from //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
to = NormalizeTime(to);
|
||||||
|
mTo = to;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = IsValid();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Getter(s) / Setter(s) ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Zone Start Time ...
|
||||||
|
*
|
||||||
|
* @return ( datetime )
|
||||||
|
*/
|
||||||
|
datetime From()
|
||||||
|
{
|
||||||
|
return mFrom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Zone Start Time ...
|
||||||
|
*
|
||||||
|
* @param value: Datetime
|
||||||
|
*/
|
||||||
|
void From(datetime value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
value = NormalizeTime(value);
|
||||||
|
|
||||||
|
//
|
||||||
|
mFrom = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Zone End Time ...
|
||||||
|
*
|
||||||
|
* @return ( datetime )
|
||||||
|
*/
|
||||||
|
datetime To()
|
||||||
|
{
|
||||||
|
return mTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Zone End Time ...
|
||||||
|
*
|
||||||
|
* @param value: Datetime
|
||||||
|
*/
|
||||||
|
void To(datetime value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
value = NormalizeTime(value);
|
||||||
|
|
||||||
|
//
|
||||||
|
mTo = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Title ...
|
||||||
|
*
|
||||||
|
* @return ( string )
|
||||||
|
*/
|
||||||
|
string Title()
|
||||||
|
{
|
||||||
|
return mTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Title ...
|
||||||
|
*
|
||||||
|
* @param value: String ...
|
||||||
|
*/
|
||||||
|
// void Title(string value)
|
||||||
|
// {
|
||||||
|
// mTitle = value;
|
||||||
|
// }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Overrides ...
|
||||||
|
|
||||||
|
void Clean() override
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mTo = NULL;
|
||||||
|
mFrom = NULL;
|
||||||
|
mType = X_POI_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsValid() override
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
mType != X_POI_NONE &&
|
||||||
|
IsSpecifiedValid(mTo) &&
|
||||||
|
IsSpecifiedValid(mFrom) &&
|
||||||
|
IsSpecifiedValid(mTitle)
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string GetTag() override
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string result = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!IsValid())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
string hash = TypeAsString() + mSep + ToString(From()) + mSep + Title();
|
||||||
|
hash = ToMD5(hash);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = TypeAsString() + "[" + Title() + "]" + mSep + hash;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
datetime mFrom; // Start Date
|
||||||
|
datetime mTo; // End Date
|
||||||
|
string mTitle; // Zone Title
|
||||||
|
|
||||||
|
//
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Bar Zone ...
|
// Bar Zone ...
|
||||||
class XCBarZone : public XCZone
|
class XCBarZone : public XCZone
|
||||||
@@ -1820,7 +2043,7 @@ class XCFVG : public XCTwoBarZone
|
|||||||
|
|
||||||
//
|
//
|
||||||
result = InitTwoBarZone(
|
result = InitTwoBarZone(
|
||||||
firstBar,
|
startBar,
|
||||||
endBar,
|
endBar,
|
||||||
mTT,
|
mTT,
|
||||||
useFistForUpper,
|
useFistForUpper,
|
||||||
@@ -1887,7 +2110,7 @@ class XCFVG : public XCTwoBarZone
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
result = IsValidBarZone() &&
|
result = IsValidTwoBarZone() &&
|
||||||
(mType == X_POI_BULLISH_ORDERBLOCK ||
|
(mType == X_POI_BULLISH_ORDERBLOCK ||
|
||||||
mType == X_POI_BEARISH_ORDERBLOCK);
|
mType == X_POI_BEARISH_ORDERBLOCK);
|
||||||
|
|
||||||
@@ -1906,6 +2129,18 @@ class XCFVG : public XCTwoBarZone
|
|||||||
//
|
//
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Implement this ...
|
||||||
|
class XCDay : public XCFromToZone
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Implement this ...
|
||||||
|
class XCSession : public XCFromToZone
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user