Define HTF Market Structure, KeyLevels
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| KeyLevels.mqh — Key LV1/L2, supply/demand OB (body break) |
|
||||
//+------------------------------------------------------------------+
|
||||
#ifndef HYPERICT_KEYLEVELS_MQH
|
||||
#define HYPERICT_KEYLEVELS_MQH
|
||||
|
||||
#include <HyperICT/Types.mqh>
|
||||
#include <HyperICT/Config.mqh>
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
class CKeyLevels
|
||||
{
|
||||
public:
|
||||
static double BodyTop(const string sym, const ENUM_TIMEFRAMES tf, const int shift)
|
||||
{
|
||||
return MathMax(iOpen(sym, tf, shift), iClose(sym, tf, shift));
|
||||
}
|
||||
|
||||
static double BodyBottom(const string sym, const ENUM_TIMEFRAMES tf, const int shift)
|
||||
{
|
||||
return MathMin(iOpen(sym, tf, shift), iClose(sym, tf, shift));
|
||||
}
|
||||
|
||||
static bool IsBearCandle(const string sym, const ENUM_TIMEFRAMES tf, const int shift)
|
||||
{
|
||||
return iClose(sym, tf, shift) < iOpen(sym, tf, shift);
|
||||
}
|
||||
|
||||
static bool IsBullCandle(const string sym, const ENUM_TIMEFRAMES tf, const int shift)
|
||||
{
|
||||
return iClose(sym, tf, shift) > iOpen(sym, tf, shift);
|
||||
}
|
||||
|
||||
// Nến đỏ cuối cùng trước/at swing low (supply @ L0)
|
||||
static bool FindSupplyOB(const string sym, const ENUM_TIMEFRAMES tf,
|
||||
const SwingPoint &swingLow,
|
||||
OrderBlockZone &out)
|
||||
{
|
||||
out.Clear();
|
||||
if(swingLow.shift < 1)
|
||||
return false;
|
||||
|
||||
const int from = swingLow.shift + 8;
|
||||
const int to = MathMax(1, swingLow.shift - 1);
|
||||
for(int sh = from; sh >= to; sh--)
|
||||
{
|
||||
if(!IsBearCandle(sym, tf, sh))
|
||||
continue;
|
||||
const double l = iLow(sym, tf, sh);
|
||||
if(l > swingLow.price + 20 * _Point)
|
||||
continue;
|
||||
out.valid = true;
|
||||
out.swingPrice = swingLow.price;
|
||||
out.obHigh = iHigh(sym, tf, sh);
|
||||
out.obLow = iLow(sym, tf, sh);
|
||||
out.obTime = iTime(sym, tf, sh);
|
||||
out.obShift = sh;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Nến xanh cuối cùng tại swing high (demand @ H0)
|
||||
static bool FindDemandOB(const string sym, const ENUM_TIMEFRAMES tf,
|
||||
const SwingPoint &swingHigh,
|
||||
OrderBlockZone &out)
|
||||
{
|
||||
out.Clear();
|
||||
if(swingHigh.shift < 1)
|
||||
return false;
|
||||
|
||||
const int from = swingHigh.shift + 8;
|
||||
const int to = MathMax(1, swingHigh.shift - 1);
|
||||
for(int sh = from; sh >= to; sh--)
|
||||
{
|
||||
if(!IsBullCandle(sym, tf, sh))
|
||||
continue;
|
||||
const double h = iHigh(sym, tf, sh);
|
||||
if(h < swingHigh.price - 20 * _Point)
|
||||
continue;
|
||||
out.valid = true;
|
||||
out.swingPrice = swingHigh.price;
|
||||
out.obHigh = iHigh(sym, tf, sh);
|
||||
out.obLow = iLow(sym, tf, sh);
|
||||
out.obTime = iTime(sym, tf, sh);
|
||||
out.obShift = sh;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void BuildKeyLevels(const string sym, const ENUM_TIMEFRAMES tf,
|
||||
const ENUM_STRUCT_BIAS bias,
|
||||
const SwingSet &sw,
|
||||
KeyLevelPair &lv1, KeyLevelPair &lv2)
|
||||
{
|
||||
lv1.zone.Clear();
|
||||
lv2.zone.Clear();
|
||||
if(!sw.IsComplete())
|
||||
return;
|
||||
|
||||
if(bias == STRUCT_BULL)
|
||||
{
|
||||
lv1.price = sw.l0.price;
|
||||
lv2.price = sw.h0.price;
|
||||
FindSupplyOB(sym, tf, sw.l0, lv1.zone);
|
||||
FindDemandOB(sym, tf, sw.h0, lv2.zone);
|
||||
}
|
||||
else if(bias == STRUCT_BEAR)
|
||||
{
|
||||
lv1.price = sw.h0.price;
|
||||
lv2.price = sw.l0.price;
|
||||
FindDemandOB(sym, tf, sw.h0, lv1.zone); // Key LV1 bear = H0 (demand side OB at H0)
|
||||
FindSupplyOB(sym, tf, sw.l0, lv2.zone);
|
||||
}
|
||||
}
|
||||
|
||||
static bool BodyBreakBelow(const string sym, const ENUM_TIMEFRAMES tf,
|
||||
const int shift, const double level)
|
||||
{
|
||||
return BodyBottom(sym, tf, shift) < level - _Point;
|
||||
}
|
||||
|
||||
static bool BodyBreakAbove(const string sym, const ENUM_TIMEFRAMES tf,
|
||||
const int shift, const double level)
|
||||
{
|
||||
return BodyTop(sym, tf, shift) > level + _Point;
|
||||
}
|
||||
|
||||
static bool PriceBetween(const double price, const double a, const double b)
|
||||
{
|
||||
const double lo = MathMin(a, b);
|
||||
const double hi = MathMax(a, b);
|
||||
return price >= lo - _Point && price <= hi + _Point;
|
||||
}
|
||||
|
||||
static void ZoneRectBounds(const OrderBlockZone &z,
|
||||
const bool supplyAtLow,
|
||||
double &top, double &bottom)
|
||||
{
|
||||
if(!z.valid)
|
||||
{
|
||||
top = bottom = z.swingPrice;
|
||||
return;
|
||||
}
|
||||
if(supplyAtLow)
|
||||
{
|
||||
top = MathMax(z.swingPrice, z.obHigh);
|
||||
bottom = MathMin(z.swingPrice, z.obLow);
|
||||
}
|
||||
else
|
||||
{
|
||||
top = MathMax(z.swingPrice, z.obHigh);
|
||||
bottom = MathMin(z.swingPrice, z.obLow);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // HYPERICT_KEYLEVELS_MQH
|
||||
Reference in New Issue
Block a user