//+------------------------------------------------------------------+ //| DailyBias.mqh — Bias rõ (HH-HL/LH-LL) vs sớm (sau CHoCH) | //+------------------------------------------------------------------+ #ifndef ICT2026_DAILYBIAS_MQH #define ICT2026_DAILYBIAS_MQH #include #include #include #include IctDailyBiasState g_ictDailyBias; IctTrendResolveCtx g_ictDailyCtx; ENUM_ICT_BIAS IctBiasFromTrend(const ENUM_ICT_TREND trend) { if(trend == ICT_TREND_UP) return ICT_BIAS_BULL; if(trend == ICT_TREND_DOWN) return ICT_BIAS_BEAR; return ICT_BIAS_NONE; } void IctUpdateHTFBias(const string sym, const ENUM_TIMEFRAMES tf) { IctHTFBiasState state = g_ictDailyBias.htf; const datetime tf0Time = iTime(sym, tf, 0); if(tf0Time == state.lastUpdateTime) return; state.lastUpdateTime = tf0Time; const double b1Close = iClose(sym, tf, 1); const double b1High = iHigh(sym, tf, 1); const double b1Low = iLow(sym, tf, 1); const double b2High = iHigh(sym, tf, 2); const double b2Low = iLow(sym, tf, 2); state.rangeHigh = 0.0; state.rangeLow = 0.0; if(b1Close > b2High) state.bias = ICT_HTF_UP; else if(b1Close < b2Low) state.bias = ICT_HTF_DOWN; else if(b1High <= b2High && b1Low >= b2Low) { state.bias = ICT_HTF_SIDEWAY; state.rangeHigh = b2High; state.rangeLow = b2Low; } else if(b1Close < b2High && b1Close > b2Low) { state.bias = ICT_HTF_SIDEWAY; state.rangeHigh = b1High; state.rangeLow = b1Low; } else state.bias = ICT_HTF_NONE; g_ictDailyBias.htf = state; } ENUM_ICT_BIAS IctBiasFromHtf(IctHTFBiasState &htf) { if(htf.bias == ICT_HTF_UP) return ICT_BIAS_BULL; if(htf.bias == ICT_HTF_DOWN) return ICT_BIAS_BEAR; if(htf.bias == ICT_HTF_SIDEWAY) return ICT_BIAS_RANGE; return ICT_BIAS_NONE; } string IctBiasText(const ENUM_ICT_BIAS bias) { switch(bias) { case ICT_BIAS_BULL: return "BULL"; case ICT_BIAS_BEAR: return "BEAR"; case ICT_BIAS_RANGE: return "RANGE"; default: return "NONE"; } } string IctStructText(const ENUM_ICT_STRUCT s) { switch(s) { case ICT_STRUCT_BULL: return "BULL"; case ICT_STRUCT_BEAR: return "BEAR"; default: return "NONE"; } } string IctMsEventText(const ENUM_ICT_MS_EVENT ev) { switch(ev) { case ICT_MS_BOS: return "BOS (Continue)"; case ICT_MS_CHOCH: return "CHoCH (Reversal)"; default: return "None"; } } string IctHtfBiasText(const ENUM_ICT_HTF_BIAS bias) { switch(bias) { case ICT_HTF_UP: return "UP"; case ICT_HTF_DOWN: return "DOWN"; case ICT_HTF_SIDEWAY: return "SIDEWAY"; default: return "NONE"; } } string IctBiasDisplayShort(const ENUM_ICT_BIAS bias) { if(bias == ICT_BIAS_BULL) return IctTrendPhaseDisplay(ICT_TREND_UP, g_ictDailyBias.biasPhase); if(bias == ICT_BIAS_BEAR) return IctTrendPhaseDisplay(ICT_TREND_DOWN, g_ictDailyBias.biasPhase); switch(bias) { case ICT_BIAS_RANGE: return "Range"; default: return "None"; } } void IctDailyBias_SyncFromCtx(IctSwingSet &sw, const ENUM_ICT_STRUCT pivotStruct) { g_ictDailyBias.bias = IctBiasFromTrend(g_ictDailyCtx.trend); g_ictDailyBias.biasPhase = g_ictDailyCtx.phase; g_ictDailyBias.lastEvent = g_ictDailyCtx.lastEvent; g_ictDailyBias.lastClearStructural = g_ictDailyCtx.lastClearStructural; g_ictDailyBias.swings = sw; g_ictDailyBias.structural = pivotStruct; if(g_ictDailyBias.bias == ICT_BIAS_BULL || g_ictDailyBias.bias == ICT_BIAS_BEAR) { const ENUM_ICT_STRUCT keyStruct = (g_ictDailyBias.bias == ICT_BIAS_BULL) ? ICT_STRUCT_BULL : ICT_STRUCT_BEAR; if(sw.IsComplete()) IctGetKeyLevels(keyStruct, sw, g_ictDailyBias.keyLv1, g_ictDailyBias.keyLv2); } else { g_ictDailyBias.keyLv1 = 0.0; g_ictDailyBias.keyLv2 = 0.0; } } void IctDailyBias_ApplyHtfFallback() { IctHTFBiasState htfRef = g_ictDailyBias.htf; g_ictDailyBias.bias = IctBiasFromHtf(htfRef); g_ictDailyBias.biasPhase = ICT_TREND_PHASE_NONE; switch(g_ictDailyBias.htf.bias) { case ICT_HTF_UP: g_ictDailyBias.reason = "Fallback: outside day UP (close > prior high)"; break; case ICT_HTF_DOWN: g_ictDailyBias.reason = "Fallback: outside day DOWN (close < prior low)"; break; case ICT_HTF_SIDEWAY: g_ictDailyBias.reason = StringFormat("Fallback: range [%.5f .. %.5f]", g_ictDailyBias.htf.rangeLow, g_ictDailyBias.htf.rangeHigh); break; default: g_ictDailyBias.reason = "Fallback: không đủ structural + HTF indecision"; break; } } string IctBuildDisplayReason(IctDailyBiasState &st, const string sym, const ENUM_TIMEFRAMES tf) { if(st.bias == ICT_BIAS_BULL || st.bias == ICT_BIAS_BEAR) { const ENUM_ICT_TREND trend = (st.bias == ICT_BIAS_BULL) ? ICT_TREND_UP : ICT_TREND_DOWN; string parts = IctBuildTrendDisplayReason(st.swings, st.structural, trend, st.biasPhase, st.lastEvent, "D"); if(st.htf.bias == ICT_HTF_UP) { parts += ", D[1].close > D[2].High"; } else if(st.htf.bias == ICT_HTF_DOWN) { parts += ", D[1].close < D[2].Low"; } return parts; } string parts = IctStructPatternText(st.structural); if(st.htf.bias == ICT_HTF_UP) { if(parts != "") parts += ", "; parts += "D[1].close > D[2].High"; } else if(st.htf.bias == ICT_HTF_DOWN) { if(parts != "") parts += ", "; parts += "D[1].close < D[2].Low"; } else if(st.htf.bias == ICT_HTF_SIDEWAY) { const double b1High = iHigh(sym, tf, 1); const double b1Low = iLow(sym, tf, 1); const double b2High = iHigh(sym, tf, 2); const double b2Low = iLow(sym, tf, 2); if(parts != "") parts += ", "; if(b1High <= b2High && b1Low >= b2Low) parts += "Inside D[1] trong D[2]"; else parts += "Indecision D[1] trong D[2]"; } if(parts == "") parts = "Không xác định"; return parts; } void IctDailyBias_Reset() { g_ictDailyCtx.Reset(); g_ictDailyBias.bias = ICT_BIAS_NONE; g_ictDailyBias.biasPhase = ICT_TREND_PHASE_NONE; g_ictDailyBias.structural = ICT_STRUCT_NONE; g_ictDailyBias.lastEvent = ICT_MS_NONE; g_ictDailyBias.fibOk = false; g_ictDailyBias.swings.Clear(); g_ictDailyBias.keyLv1 = 0.0; g_ictDailyBias.keyLv2 = 0.0; g_ictDailyBias.lastClearStructural = ICT_STRUCT_NONE; g_ictDailyBias.pdh = 0.0; g_ictDailyBias.pdl = 0.0; g_ictDailyBias.pdc = 0.0; g_ictDailyBias.eq = 0.0; g_ictDailyBias.htf.bias = ICT_HTF_NONE; g_ictDailyBias.htf.rangeHigh = 0.0; g_ictDailyBias.htf.rangeLow = 0.0; g_ictDailyBias.htf.lastUpdateTime = 0; g_ictDailyBias.lastBarTime = 0; g_ictDailyBias.reason = ""; g_ictDailyBias.displayReason = ""; } bool IctDailyBias_Init(const string sym) { IctDailyBias_Reset(); if(Bars(sym, InpBiasTf) < 10) return false; g_ictDailyBias.htf.lastUpdateTime = 0; IctDailyBias_Update(sym, true); return true; } bool IctDailyBias_Update(const string sym, const bool force = false) { const ENUM_TIMEFRAMES tf = InpBiasTf; const datetime bar0 = iTime(sym, tf, 0); if(!force && bar0 == g_ictDailyBias.lastBarTime) return false; g_ictDailyBias.lastBarTime = bar0; g_ictDailyBias.pdh = iHigh(sym, tf, 1); g_ictDailyBias.pdl = iLow(sym, tf, 1); g_ictDailyBias.pdc = iClose(sym, tf, 1); g_ictDailyBias.eq = (g_ictDailyBias.pdh + g_ictDailyBias.pdl) * 0.5; IctUpdateHTFBias(sym, tf); IctSwingSet sw; ENUM_ICT_STRUCT pivotStruct = ICT_STRUCT_NONE; sw = IctBuildSwingSet(sym, tf, InpSwingRange, InpSwingLookback, pivotStruct); g_ictDailyBias.fibOk = sw.IsComplete() && IctIsPullbackValid(sw, InpFibMinRatio); if(InpRequireFib && !g_ictDailyBias.fibOk) { sw.Clear(); pivotStruct = ICT_STRUCT_NONE; } IctResolveTrend(sym, tf, sw, pivotStruct, g_ictDailyCtx, 1); IctDailyBias_SyncFromCtx(sw, pivotStruct); if(g_ictDailyBias.bias == ICT_BIAS_NONE) IctDailyBias_ApplyHtfFallback(); else g_ictDailyBias.reason = StringFormat("Structural: %s", IctBiasText(g_ictDailyBias.bias)); g_ictDailyBias.displayReason = IctBuildDisplayReason(g_ictDailyBias, sym, tf); if(InpDebug) { PrintFormat("[ICT2026/DailyBias] %s %s | Bias=%s | Phase=%d | Struct=%s | Event=%s | HTF=%s", sym, EnumToString(tf), IctBiasDisplayShort(g_ictDailyBias.bias), g_ictDailyBias.biasPhase, IctStructText(g_ictDailyBias.structural), IctMsEventText(g_ictDailyBias.lastEvent), IctHtfBiasText(g_ictDailyBias.htf.bias)); if(g_ictDailyBias.swings.IsComplete()) PrintFormat(" H0=%.5f H1=%.5f L0=%.5f L1=%.5f | Key1=%.5f Key2=%.5f | %s", g_ictDailyBias.swings.h0.price, g_ictDailyBias.swings.h1.price, g_ictDailyBias.swings.l0.price, g_ictDailyBias.swings.l1.price, g_ictDailyBias.keyLv1, g_ictDailyBias.keyLv2, g_ictDailyBias.reason); } return true; } void IctDailyBias_Get(IctDailyBiasState &out) { out = g_ictDailyBias; } bool IctDailyBias_IsBull() { return g_ictDailyBias.bias == ICT_BIAS_BULL; } bool IctDailyBias_IsBear() { return g_ictDailyBias.bias == ICT_BIAS_BEAR; } #endif