Files
Bell-PriceActionWithEma-EA/Include/ICT2026/StructureCore.mqh
T
2026-05-27 03:18:59 +07:00

134 lines
5.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//+------------------------------------------------------------------+
//| StructureCore.mqh — body break primitives + BOS/CHoCH detector |
//+------------------------------------------------------------------+
//| Helpers cho cả Daily + Intraday — phá level dùng THÂN NẾN (body), |
//| không dùng wick. |
//| |
//| IctBodyTop / IctBodyBot — body top/bot của nến shift |
//| IctBodyBreakBuffer(sym) — N × spread (≥ _Point) |
//| IctBodyBreakAbove(level) — body close > level + buffer |
//| IctBodyBreakBelow(level) — body close < level buffer |
//| |
//| Buffer (v1.186): siết chặt — thân nến phải đóng vượt level ≥ |
//| InpBodyBreakSpreadMult × (AskBid) (mặc định 10 spread). |
//| Áp dụng cho mọi callsite: BOS/CHoCH (Daily, Intraday), MSS |
//| confirm, H1 FVG body-invalidate. |
//| |
//| BOS vs CHoCH (cùng rule, khác bản chất): |
//| BOS = phá Key tiếp diễn xu hướng |
//| CHoCH= phá Key NGƯỢC xu hướng (đảo chiều) |
//| |
//| Bear (LH-LL): Key1=H0, Key2=L0 |
//| - Phá H0 ⇒ CHoCH (chuyển sang Bull sớm) |
//| - Phá L0 ⇒ BOS |
//| Bull (HH-HL): Key1=L0, Key2=H0 |
//| - Phá L0 ⇒ CHoCH (chuyển sang Bear sớm) |
//| - Phá H0 ⇒ BOS |
//| |
//| Detection: trên bar đã đóng (shift=1) — KHÔNG dùng bar đang chạy. |
//| |
//| Public API: |
//| double IctBodyTop/Bot(sym, tf, shift) |
//| bool IctBodyBreakAbove/Below(sym, tf, shift, level) |
//| ENUM_ICT_MS_EVENT IctDetectStructureEvent(sym, tf, &set, |
//| structural, shift) |
//+------------------------------------------------------------------+
#ifndef ICT2026_STRUCTURECORE_MQH
#define ICT2026_STRUCTURECORE_MQH
#include <ICT2026/Config.mqh>
double IctBodyTop(const string sym, const ENUM_TIMEFRAMES tf, const int shift)
{
return MathMax(iOpen(sym, tf, shift), iClose(sym, tf, shift));
}
double IctBodyBottom(const string sym, const ENUM_TIMEFRAMES tf, const int shift)
{
return MathMin(iOpen(sym, tf, shift), iClose(sym, tf, shift));
}
// Buffer xác nhận phá level: N × spread hiện tại (fallback _Point khi spread = 0).
// Siết chặt body-break để loại các close-through "sát mép" do biến động nhỏ/spike.
// N = InpBodyBreakSpreadMult (mặc định 10).
double IctBodyBreakBuffer(const string sym)
{
const double sp = MathMax(0.0,
SymbolInfoDouble(sym, SYMBOL_ASK) -
SymbolInfoDouble(sym, SYMBOL_BID));
const double unit = (sp > 0.0) ? sp : _Point;
const double mult = MathMax(0.0, (double)InpBodyBreakSpreadMult);
return MathMax(_Point, unit * mult);
}
bool IctBodyBreakAbove(const string sym, const ENUM_TIMEFRAMES tf,
const int shift, const double level)
{
return IctBodyTop(sym, tf, shift) > level + IctBodyBreakBuffer(sym);
}
bool IctBodyBreakBelow(const string sym, const ENUM_TIMEFRAMES tf,
const int shift, const double level)
{
return IctBodyBottom(sym, tf, shift) < level - IctBodyBreakBuffer(sym);
}
// BOS = Continue (Key LV2) | CHoCH = Reversal (Key LV1)
ENUM_ICT_MS_EVENT IctDetectStructureEvent(const string sym, const ENUM_TIMEFRAMES tf,
const ENUM_ICT_STRUCT structural,
const double keyLv1, const double keyLv2,
const int shift = 1)
{
if(structural == ICT_STRUCT_NONE || keyLv1 <= 0.0 || keyLv2 <= 0.0)
return ICT_MS_NONE;
if(structural == ICT_STRUCT_BULL)
{
if(IctBodyBreakBelow(sym, tf, shift, keyLv1))
return ICT_MS_CHOCH;
if(IctBodyBreakAbove(sym, tf, shift, keyLv2))
return ICT_MS_BOS;
}
else if(structural == ICT_STRUCT_BEAR)
{
if(IctBodyBreakAbove(sym, tf, shift, keyLv1))
return ICT_MS_CHOCH;
if(IctBodyBreakBelow(sym, tf, shift, keyLv2))
return ICT_MS_BOS;
}
return ICT_MS_NONE;
}
// BOS/CHoCH trên swing cũ H1/L1 theo trend hiện tại (body close shift=1)
// UP: BOS = phá H1 | CHoCH = phá L1
// DOWN: BOS = phá L1 | CHoCH = phá H1
ENUM_ICT_MS_EVENT IctDetectTrendSwingEvent(const string sym, const ENUM_TIMEFRAMES tf,
const ENUM_ICT_TREND trend,
const double swingHighH1,
const double swingLowL1,
const int shift = 1)
{
if(trend == ICT_TREND_NONE || swingHighH1 <= 0.0 || swingLowL1 <= 0.0)
return ICT_MS_NONE;
if(trend == ICT_TREND_UP)
{
if(IctBodyBreakBelow(sym, tf, shift, swingLowL1))
return ICT_MS_CHOCH;
if(IctBodyBreakAbove(sym, tf, shift, swingHighH1))
return ICT_MS_BOS;
}
else if(trend == ICT_TREND_DOWN)
{
if(IctBodyBreakAbove(sym, tf, shift, swingHighH1))
return ICT_MS_CHOCH;
if(IctBodyBreakBelow(sym, tf, shift, swingLowL1))
return ICT_MS_BOS;
}
return ICT_MS_NONE;
}
#endif