CHoCH + CHoCH strategy

 

Hello traders 


How knows this strategy and can explain to us. It used 2 chOch. 

One from Htf and second by LTF

 
I changed the topic title (the original title was "Who can explain more this strategy") and moved this topic to the Trading Systems category.
 

Thinking of trading as an only temporality is a type of thiking:

- All the factors that are considered are based on the same graph, all the information is biased by the same timeframe...

But what if you could get more information such as other timeframes:

  • H4-M15
  • H1-M5
  • M15-M3

You could use the movement of the higher timeframe and use a confirmation on the lower timeframe.


In this particular case you find a higher time frame other block caused by a choch, then when price approach this order block, you go to lower timeframes and wait for a choch, using the 2 timeframe chochs as confirmations.

 

1️⃣ Understanding

This strategy uses TWO CHoCH events:

🔹 First CHoCH (Higher Timeframe – Bias)

  • Happens on H4 or H1

  • Purpose: Direction only (Bias shift)

  • ❌ You do NOT enter here

🔹 Second CHoCH (Lower Timeframe – Entry)

  • Happens on M15 or M5

  • Purpose: Precise entry with low risk

  • ✅ You enter here

So the idea is:

HTF tells you WHERE & DIRECTION → LTF tells you WHEN to enter

This avoids random trades and fake breakouts.


2️⃣Entry rules (Buy & Sell)


🟢 BUY ENTRY (Bullish Setup)

Higher Timeframe (H4 / H1)

  1. Bearish → Bullish CHoCH (bias shift)

  2. Mark:

    • Demand zone

    • Previous high

  3. Wait for:

    • Retracement into POI (order block / demand / 50–61.8%)

    • Sell-side liquidity taken

Lower Timeframe (M15 / M5)
4. Price enters HTF POI
5. Bullish CHoCH on LTF
6. Break of LTF lower high
7. Entry:

  • At LTF bullish order block

Buy Entry:

LTF Bullish Order Block after LTF CHoCH


🔴 SELL ENTRY (Bearish Setup)

Higher Timeframe (H4 / H1)

  1. Bullish → Bearish CHoCH

  2. Mark:

    • Supply zone

    • Previous low

  3. Wait for:

    • Retracement into POI

    • Buy-side liquidity taken

Lower Timeframe (M15 / M5)
4. Price enters HTF POI
5. Bearish CHoCH on LTF
6. Break of LTF higher low
7. Entry:

  • At LTF bearish order block

Sell Entry:

LTF Bearish Order Block after LTF CHoCH


3️⃣ Take Profit (Buy & Sell)

🟢 BUY Take Profit

  • TP1: Previous LTF High

  • TP2: Buy-side liquidity (equal highs)

  • TP3: HTF High (main target)

🔴 SELL Take Profit

  • TP1: Previous LTF Low

  • TP2: Sell-side liquidity (equal lows)

  • TP3: HTF Low (main target)

4️⃣ Stop Loss (Buy & Sell)

🟢 BUY Stop Loss

  • Below LTF swing low

  • Or below LTF bullish order block

🔴 SELL Stop Loss

  • Above LTF swing high

  • Or above LTF bearish order block

⚠️ SL is structure-based, not fixed pips.


5️⃣ MQL5

#property strict
#property version   "1.00"
#property description "CHoCH + CHoCH Double Confirmation EA (SMC)"

#include <Trade/Trade.mqh>
CTrade trade;

// ===== INPUTS
input ENUM_TIMEFRAMES HTF = PERIOD_H1;
input ENUM_TIMEFRAMES LTF = PERIOD_M15;
input double Lots = 0.10;
input int MagicNumber = 20260129;
input double RR_TP = 3.0;
input int MaxBars = 200;

// ===== GLOBAL
bool BuyBias = false;
bool SellBias = false;

// ===== ARRAYS
double HighHTF[], LowHTF[], CloseHTF[];
double HighLTF[], LowLTF[], CloseLTF[];

// ===== SWING FUNCTIONS
bool IsSwingHigh(const double &high[], int i)
{
   return (high[i] > high[i-1] && high[i] > high[i+1]);
}

bool IsSwingLow(const double &low[], int i)
{
   return (low[i] < low[i-1] && low[i] < low[i+1]);
}

// ===== COPY PRICE DATA
bool CopyData()
{
   if(CopyHigh(_Symbol, HTF, 0, MaxBars, HighHTF) <= 0) return false;
   if(CopyLow (_Symbol, HTF, 0, MaxBars, LowHTF)  <= 0) return false;
   if(CopyClose(_Symbol, HTF, 0, MaxBars, CloseHTF)<= 0) return false;

   if(CopyHigh(_Symbol, LTF, 0, MaxBars, HighLTF) <= 0) return false;
   if(CopyLow (_Symbol, LTF, 0, MaxBars, LowLTF)  <= 0) return false;
   if(CopyClose(_Symbol, LTF, 0, MaxBars, CloseLTF)<= 0) return false;

   ArraySetAsSeries(HighHTF, true);
   ArraySetAsSeries(LowHTF, true);
   ArraySetAsSeries(CloseHTF, true);

   ArraySetAsSeries(HighLTF, true);
   ArraySetAsSeries(LowLTF, true);
   ArraySetAsSeries(CloseLTF, true);

   return true;
}

// ===== HTF CHoCH (BIAS)
void DetectHTFChoCH()
{
   BuyBias = false;
   SellBias = false;

   for(int i = 2; i < MaxBars-2; i++)
   {
      if(IsSwingHigh(HighHTF, i))
      {
         if(CloseHTF[1] > HighHTF[i])
         {
            BuyBias = true;
            return;
         }
      }

      if(IsSwingLow(LowHTF, i))
      {
         if(CloseHTF[1] < LowHTF[i])
         {
            SellBias = true;
            return;
         }
      }
   }
}

// ===== LTF CHoCH (ENTRY)
bool LTFBullishChoCH()
{
   for(int i = 2; i < MaxBars-2; i++)
   {
      if(IsSwingHigh(HighLTF, i))
         if(CloseLTF[1] > HighLTF[i])
            return true;
   }
   return false;
}

bool LTFBearishChoCH()
{
   for(int i = 2; i < MaxBars-2; i++)
   {
      if(IsSwingLow(LowLTF, i))
         if(CloseLTF[1] < LowLTF[i])
            return true;
   }
   return false;
}

// ===== POSITION CHECK
bool HasOpenPosition()
{
   for(int i = 0; i < PositionsTotal(); i++)
   {
      if(PositionGetTicket(i))
      {
         if(PositionGetInteger(POSITION_MAGIC) == MagicNumber &&
            PositionGetString(POSITION_SYMBOL) == _Symbol)
            return true;
      }
   }
   return false;
}

// ===== TRADE EXECUTION
void ExecuteTrade(bool buy)
{
   double sl, tp;
   double price;

   trade.SetExpertMagicNumber(MagicNumber);

   if(buy)
   {
      price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      sl = LowLTF[1];
      tp = price + (price - sl) * RR_TP;
      trade.Buy(Lots, _Symbol, price, sl, tp, "CHoCH BUY");
   }
   else
   {
      price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      sl = HighLTF[1];
      tp = price - (sl - price) * RR_TP;
      trade.Sell(Lots, _Symbol, price, sl, tp, "CHoCH SELL");
   }
}

// ===== ON TICK
void OnTick()
{
   static datetime lastBarTime = 0;
   datetime currentBarTime = iTime(_Symbol, LTF, 0);
   if(currentBarTime == lastBarTime) return;
   lastBarTime = currentBarTime;

   if(!CopyData()) return;

   DetectHTFChoCH();

   if(HasOpenPosition()) return;

   if(BuyBias && LTFBullishChoCH())
      ExecuteTrade(true);

   if(SellBias && LTFBearishChoCH())
      ExecuteTrade(false);
}


6️⃣ MQL4

#property strict

// ===== INPUTS
input ENUM_TIMEFRAMES HTF = PERIOD_H1;
input ENUM_TIMEFRAMES LTF = PERIOD_M15;
input double Lots = 0.10;
input int Magic = 20260129;
input double RR_TP1 = 1.0;
input double RR_TP2 = 2.0;
input double RR_TP3 = 3.0;

// ===== GLOBAL
bool BuyBias = false;
bool SellBias = false;

// ===== SWING FUNCTIONS
bool IsSwingHigh(string sym, ENUM_TIMEFRAMES tf, int i)
{
   return (iHigh(sym, tf, i) > iHigh(sym, tf, i+1) &&
           iHigh(sym, tf, i) > iHigh(sym, tf, i-1));
}

bool IsSwingLow(string sym, ENUM_TIMEFRAMES tf, int i)
{
   return (iLow(sym, tf, i) < iLow(sym, tf, i+1) &&
           iLow(sym, tf, i) < iLow(sym, tf, i-1));
}

// ===== HTF CHoCH
void DetectHTFChoCH()
{
   BuyBias = false;
   SellBias = false;

   for(int i = 3; i < 100; i++)
   {
      if(IsSwingHigh(Symbol(), HTF, i))
      {
         double swingHigh = iHigh(Symbol(), HTF, i);
         if(iClose(Symbol(), HTF, 1) > swingHigh)
         {
            BuyBias = true;
            return;
         }
      }

      if(IsSwingLow(Symbol(), HTF, i))
      {
         double swingLow = iLow(Symbol(), HTF, i);
         if(iClose(Symbol(), HTF, 1) < swingLow)
         {
            SellBias = true;
            return;
         }
      }
   }
}

// ===== LTF ENTRY SIGNAL
bool LTFBullishChoCH()
{
   for(int i = 3; i < 50; i++)
   {
      if(IsSwingHigh(Symbol(), LTF, i))
      {
         if(iClose(Symbol(), LTF, 1) > iHigh(Symbol(), LTF, i))
            return true;
      }
   }
   return false;
}

bool LTFBearishChoCH()
{
   for(int i = 3; i < 50; i++)
   {
      if(IsSwingLow(Symbol(), LTF, i))
      {
         if(iClose(Symbol(), LTF, 1) < iLow(Symbol(), LTF, i))
            return true;
      }
   }
   return false;
}

// ===== ORDER EXECUTION
void ExecuteTrade(int type)
{
   double sl, tp;

   if(type == OP_BUY)
   {
      sl = iLow(Symbol(), LTF, 1);
      tp = Ask + (Ask - sl) * RR_TP3;
      OrderSend(Symbol(), OP_BUY, Lots, Ask, 5, sl, tp, "CHoCH BUY", Magic);
   }

   if(type == OP_SELL)
   {
      sl = iHigh(Symbol(), LTF, 1);
      tp = Bid - (sl - Bid) * RR_TP3;
      OrderSend(Symbol(), OP_SELL, Lots, Bid, 5, sl, tp, "CHoCH SELL", Magic);
   }
}

// ===== ON TICK
void OnTick()
{
   static datetime lastTime;
   if(TimeCurrent() == lastTime) return;
   lastTime = TimeCurrent();

   DetectHTFChoCH();

   if(BuyBias && LTFBullishChoCH())
      ExecuteTrade(OP_BUY);

   if(SellBias && LTFBearishChoCH())
      ExecuteTrade(OP_SELL);
}
 
Shanmugi #:

Thanks for this good example of using AI to generate code from a strategy.

Which AI did you use ?

 
Alain Verleyen #:

Thanks for this good example of using AI to generate code from a strategy.

Which AI did you use ?

ChatGTP. Ai Generated and refined manually by me. ChatGTP is not really good with MQL (specially MQL5).