194 lines
5.7 KiB
Plaintext
194 lines
5.7 KiB
Plaintext
//+------------------------------------------------------------------+
|
|
//| StructureTrend.mqh — trend rõ (HH-HL/LH-LL) vs sớm (sau CHoCH) |
|
|
//+------------------------------------------------------------------+
|
|
#ifndef ICT2026_STRUCTURETREND_MQH
|
|
#define ICT2026_STRUCTURETREND_MQH
|
|
|
|
#include <ICT2026/Types.mqh>
|
|
#include <ICT2026/Swing.mqh>
|
|
#include <ICT2026/StructureCore.mqh>
|
|
|
|
struct IctTrendResolveCtx
|
|
{
|
|
ENUM_ICT_TREND trend;
|
|
ENUM_ICT_TREND_PHASE phase;
|
|
ENUM_ICT_STRUCT lastClearStructural;
|
|
ENUM_ICT_MS_EVENT lastEvent;
|
|
|
|
void Reset()
|
|
{
|
|
trend = ICT_TREND_NONE;
|
|
phase = ICT_TREND_PHASE_NONE;
|
|
lastClearStructural = ICT_STRUCT_NONE;
|
|
lastEvent = ICT_MS_NONE;
|
|
}
|
|
};
|
|
|
|
ENUM_ICT_STRUCT IctPickDetectStructural(const ENUM_ICT_STRUCT pivotStruct,
|
|
const IctTrendResolveCtx &ctx)
|
|
{
|
|
if(pivotStruct != ICT_STRUCT_NONE)
|
|
return pivotStruct;
|
|
if(ctx.phase == ICT_TREND_PHASE_EARLY)
|
|
{
|
|
if(ctx.trend == ICT_TREND_UP)
|
|
return ICT_STRUCT_BULL;
|
|
if(ctx.trend == ICT_TREND_DOWN)
|
|
return ICT_STRUCT_BEAR;
|
|
}
|
|
return ctx.lastClearStructural;
|
|
}
|
|
|
|
void IctResolveTrend(const string sym, const ENUM_TIMEFRAMES tf,
|
|
IctSwingSet &sw,
|
|
const ENUM_ICT_STRUCT pivotStruct,
|
|
IctTrendResolveCtx &ctx,
|
|
const int shift = 1)
|
|
{
|
|
ctx.lastEvent = ICT_MS_NONE;
|
|
|
|
if(!sw.IsComplete())
|
|
{
|
|
if(ctx.phase == ICT_TREND_PHASE_EARLY && ctx.trend != ICT_TREND_NONE)
|
|
return;
|
|
ctx.trend = ICT_TREND_NONE;
|
|
ctx.phase = ICT_TREND_PHASE_NONE;
|
|
return;
|
|
}
|
|
|
|
const ENUM_ICT_STRUCT detectStruct = IctPickDetectStructural(pivotStruct, ctx);
|
|
ENUM_ICT_MS_EVENT ev = ICT_MS_NONE;
|
|
if(detectStruct != ICT_STRUCT_NONE)
|
|
{
|
|
double k1 = 0.0, k2 = 0.0;
|
|
IctGetKeyLevels(detectStruct, sw, k1, k2);
|
|
ev = IctDetectStructureEvent(sym, tf, detectStruct, k1, k2, shift);
|
|
}
|
|
ctx.lastEvent = ev;
|
|
|
|
// CHoCH ưu tiên trước HH-HL/LH-LL — pivot vẫn LH-LL nhưng phá H0 → Bull sớm
|
|
if(ev == ICT_MS_CHOCH)
|
|
{
|
|
if(detectStruct == ICT_STRUCT_BEAR)
|
|
{
|
|
ctx.trend = ICT_TREND_UP;
|
|
ctx.phase = ICT_TREND_PHASE_EARLY;
|
|
ctx.lastClearStructural = ICT_STRUCT_NONE;
|
|
return;
|
|
}
|
|
if(detectStruct == ICT_STRUCT_BULL)
|
|
{
|
|
ctx.trend = ICT_TREND_DOWN;
|
|
ctx.phase = ICT_TREND_PHASE_EARLY;
|
|
ctx.lastClearStructural = ICT_STRUCT_NONE;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if(pivotStruct == ICT_STRUCT_BULL)
|
|
{
|
|
ctx.trend = ICT_TREND_UP;
|
|
ctx.phase = ICT_TREND_PHASE_CLEAR;
|
|
ctx.lastClearStructural = ICT_STRUCT_BULL;
|
|
return;
|
|
}
|
|
if(pivotStruct == ICT_STRUCT_BEAR)
|
|
{
|
|
ctx.trend = ICT_TREND_DOWN;
|
|
ctx.phase = ICT_TREND_PHASE_CLEAR;
|
|
ctx.lastClearStructural = ICT_STRUCT_BEAR;
|
|
return;
|
|
}
|
|
|
|
if(ev == ICT_MS_BOS)
|
|
{
|
|
if(detectStruct == ICT_STRUCT_BEAR)
|
|
{
|
|
ctx.trend = ICT_TREND_DOWN;
|
|
ctx.phase = ICT_TREND_PHASE_EARLY;
|
|
return;
|
|
}
|
|
if(detectStruct == ICT_STRUCT_BULL)
|
|
{
|
|
ctx.trend = ICT_TREND_UP;
|
|
ctx.phase = ICT_TREND_PHASE_EARLY;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if(ctx.phase == ICT_TREND_PHASE_EARLY && ctx.trend != ICT_TREND_NONE)
|
|
return;
|
|
|
|
ctx.trend = ICT_TREND_NONE;
|
|
ctx.phase = ICT_TREND_PHASE_NONE;
|
|
}
|
|
|
|
string IctTrendPhaseDisplay(const ENUM_ICT_TREND trend, const ENUM_ICT_TREND_PHASE phase)
|
|
{
|
|
if(trend == ICT_TREND_UP)
|
|
return (phase == ICT_TREND_PHASE_EARLY) ? "Bull sớm" : "Up";
|
|
if(trend == ICT_TREND_DOWN)
|
|
return (phase == ICT_TREND_PHASE_EARLY) ? "Bear sớm" : "Down";
|
|
return "None";
|
|
}
|
|
|
|
string IctStructPatternText(const ENUM_ICT_STRUCT structural)
|
|
{
|
|
switch(structural)
|
|
{
|
|
case ICT_STRUCT_BULL: return "HH-HL";
|
|
case ICT_STRUCT_BEAR: return "LH-LL";
|
|
default: return "";
|
|
}
|
|
}
|
|
|
|
string IctBuildTrendDisplayReason(const IctSwingSet &sw,
|
|
const ENUM_ICT_STRUCT pivotStruct,
|
|
const ENUM_ICT_TREND trend,
|
|
const ENUM_ICT_TREND_PHASE phase,
|
|
const ENUM_ICT_MS_EVENT ev,
|
|
const string barTag)
|
|
{
|
|
string parts = "";
|
|
|
|
if(phase == ICT_TREND_PHASE_CLEAR)
|
|
parts = IctStructPatternText(pivotStruct);
|
|
else if(phase == ICT_TREND_PHASE_EARLY)
|
|
{
|
|
if(trend == ICT_TREND_UP)
|
|
parts = "Bull sớm";
|
|
else if(trend == ICT_TREND_DOWN)
|
|
parts = "Bear sớm";
|
|
}
|
|
|
|
if(ev == ICT_MS_CHOCH && sw.IsComplete())
|
|
{
|
|
if(parts != "")
|
|
parts += ", ";
|
|
if(trend == ICT_TREND_UP || pivotStruct == ICT_STRUCT_BEAR)
|
|
parts += StringFormat("CHoCH %s[1].close > H0(%.2f)", barTag, sw.h0.price);
|
|
else if(trend == ICT_TREND_DOWN || pivotStruct == ICT_STRUCT_BULL)
|
|
parts += StringFormat("CHoCH %s[1].close < L0(%.2f)", barTag, sw.l0.price);
|
|
else
|
|
parts += StringFormat("CHoCH %s[1]", barTag);
|
|
}
|
|
else if(ev == ICT_MS_BOS && sw.IsComplete())
|
|
{
|
|
if(parts != "")
|
|
parts += ", ";
|
|
if(trend == ICT_TREND_UP || pivotStruct == ICT_STRUCT_BULL)
|
|
parts += StringFormat("BOS %s[1].close > H0(%.2f)", barTag, sw.h0.price);
|
|
else if(trend == ICT_TREND_DOWN || pivotStruct == ICT_STRUCT_BEAR)
|
|
parts += StringFormat("BOS %s[1].close < L0(%.2f)", barTag, sw.l0.price);
|
|
else
|
|
parts += StringFormat("BOS %s[1]", barTag);
|
|
}
|
|
|
|
if(parts == "")
|
|
parts = "Không xác định cấu trúc";
|
|
|
|
return parts;
|
|
}
|
|
|
|
#endif
|