Squeeze_Break_v1

Download script
Author: DesORegan
Squeeze_Break_v1

Overview

The Des_Squeeze_Play script is a professional-grade technical analysis tool designed to help traders identify specific market conditions where price action shifts from "quiet" periods of consolidation into "loud" periods of high volatility. By monitoring the relationship between price stability and momentum, the tool helps identify potential breakout opportunities before they fully develop.

Core Logic and Methodology

The logic of this tool is built upon three primary pillars:

1. Volatility Comparison (The "Squeeze")

The script continuously compares two popular technical frameworks to measure market tension:

  • Bollinger Bands: These react quickly to price fluctuations.
  • Keltner Channels: These provide a smoother, more stable view of price movement.

By comparing these two, the script determines the state of the market:

  • Consolidation Phase (Red Histogram): When the Bollinger Bands are nested inside the Keltner Channels, it indicates that the market is "squeezed." This represents a period of low volatility where price action is tight and potentially building energy.
  • Expansion Phase (Green Histogram): When the Bollinger Bands break outside the Keltner Channels, it signals that the market has released that tension and is moving into a high-volatility trending state. The height of the green bars reflects the strength of this move.

2. Momentum Bias

While identifying a breakout is important, knowing the direction is equally vital. The script incorporates a Momentum Indicator to act as a filter for trade direction:

  • Bullish Bias: If a volatility breakout occurs while the Momentum is above the zero line, it suggests an upward move.
  • Bearish Bias: If a volatility breakout occurs while the Momentum is below the zero line, it suggests a downward move.

3. Automated Alerts and Visual Cues

To ensure traders don't miss these moments, the script provides real-time notifications:

  • Audio Alerts: The tool triggers a sound notification the moment a "Squeeze" releases in alignment with the momentum bias.
  • Visual Markers: It automatically places directional arrows (Blue for potential buys, Red for potential sells) on the chart at the exact moment of the breakout.
  • Market Dashboard: A data summary is displayed in the corner of the screen, providing a quick snapshot of various other market conditions (such as ATR, RSI, and MACD) to give the trader broader context.

Summary for the Trader

In simple terms, this script acts like a "tension gauge." It watches the market for periods where price action is becoming unnaturally still (the Squeeze). When that tension finally snaps and the price begins to move rapidly, the tool alerts you and confirms which direction that movement is likely heading based on current momentum. It is designed as a warning system to highlight high-probability breakout moments, particularly on larger timeframes.

Price Data Components
Series array that contains the highest prices of each barSeries array that contains the lowest prices of each bar
Indicators Used
Indicator of the average true rangeMovement directional indexRelative strength indexMACD HistogramStochastic oscillatorMoving average indicatorBollinger bands indicator
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screen
16 Views
0 Downloads
0 Favorites
Squeeze_Break_v1
//+------------------------------------------------------------------+
//|                                             Des_Squeeze_Play.mq4 |
//|                                                       DesO'Regan |
//|                                   mailto: oregan_des@hotmail.com |
//+------------------------------------------------------------------+
// ===========================================================================================================
// This indicator is based on a strategy mentioned in John Carter's book, Mastering the Trade. The basic idea 
// behind the strategy is that markets tend to move from periods of low volatility to high volatility and
// visa versa. The strategy aims to capture moves from low to high volatility. For gauging this he uses two 
// common indicators - Bollinger Bands and Keltner Channels (ok, not so common!). He also uses the Momentum 
// indicator to provide a trade bias as soon as the Bollinger Bands come back outside the Keltner Channels.
// 
// The Squeeze_Break indicator combines this into a signal indicator and has the following components:
// 	1. A positive green histogram means that the Bollinger Bands are outside the Keltner Channels
// 	and the market is lightly to be trending or volatile. The stronger the histogram the stronger 
// 	the directional price move.
// 	2. A negative red histogram means that the Bollinger Bands are inside the Keltner Channels 
// 	and the market is lightly to be consolidating. The stronger the red histogram the tighter
// 	price action is becoming.
// 	3. Incorporated into the indicator is a Momentum indicator. According to the strategy J. Carter
// 	goes long when the Bollinger Bands break outside the Keltner Bands and the Momentum indicator 
// 	is above the zero line. He goes short when the Momentum indicator is below the zero line on the 
//    break.
// 	4. I've also added other indicator info in the top left hand corner to give a broader idea 
// 	of current market conditions.
// 	5. The indicator provides audio alerts when a potential breakout is occurring.  
// 
// This indicator tends to be better with the larger timeframes. Personally I don't trade on an alert 
// signal alone. It's just a handy tool for warning me of potential breakout trades. 
// ===========================================================================================================

#property copyright "DesORegan"
#property link      "mailto: oregan_des@hotmail.com"



// ====================
// indicator properties
// ====================
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 ForestGreen
#property indicator_color2 Red
#property indicator_color3 Blue


// ===================
// User Inputs
// ===================
extern int       Boll_Period=20;
extern double    Boll_Dev=2.0;
extern int       Keltner_Period=20;
extern double    Keltner_Mul=1.5;
extern int       Momentum_Period=12;
extern int       Back_Bars=1000;
extern bool      Alert_On=true;
extern bool      On_Screen_Info=true;


// =========================
// Buffer Array Declarations
// =========================
double Pos_Diff[];   // Pos Histogram
double Neg_Diff[];   // Neg Histogram
double Momentum[];   // Momentum Indicator 


// ===========================
// Internal Array Declarations
// ===========================
double   Squeeze[];  // Used to track which "i" (index value) is above 
                     // and below zero line. 0 followed by 1 triggers alert 
                     
// =========================                        
// Internal Global Variables
// =========================

datetime    Last_Alert_Time = 0;  // Used to prevent continuous alerts on current bar                         


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
   {
   
   IndicatorDigits(4);  // indicator value precision
     
   
   //======================
   // Indicator Setup
   //======================
   SetIndexStyle(0,DRAW_HISTOGRAM,EMPTY,3);
   SetIndexBuffer(0,Pos_Diff);
   SetIndexStyle(1,DRAW_HISTOGRAM,EMPTY,3);
   SetIndexBuffer(1,Neg_Diff);
   SetIndexStyle(2,DRAW_LINE,STYLE_DOT);
   SetIndexBuffer(2,Momentum);   


   // ===================
   // Indicator Labels
   // ===================
   IndicatorShortName("Squeeze_Break (Boll:"+Boll_Period+","+DoubleToStr(Boll_Dev,1)+";Kelt:"+Keltner_Period+","+DoubleToStr(Keltner_Mul,1)+";Mom:"+Momentum_Period+")");  
   
   
   // ====================
   // Array Initialization
   // ====================
   ArrayResize(Squeeze, Back_Bars); // Stores whether histogram is above/below zero line
   ArrayInitialize(Squeeze, 0);  // initialises array with 0's
                                
   


   return(0);
  }
  
  
  
  
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
   {

   ObjectsDeleteAll();   
   Comment("                                          ","\n",
            "                                          ","\n",
            "                                          ","\n",
            "                                          ","\n",
            "                                          ");
      

   return(0);
   }
  
  
  
  
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
   {  
   
   //=======================
   // Indicator Optimization
   //=======================
   int Counted_Bars = IndicatorCounted();
   if(Counted_Bars < 0) return;
   if(Counted_Bars > 0) Counted_Bars = Counted_Bars - Keltner_Period;
   int limit = Bars - Counted_Bars;
   

   //=======================
   // On-Screen Information
   //=======================  
   if (On_Screen_Info == true)
      { 
      double ATR =iATR(Symbol(),PERIOD_D1,14,0);
      double Todays_Range = iHigh(Symbol(),PERIOD_D1,0) - iLow(Symbol(),PERIOD_D1,0);
      double ADX = iADX(Symbol(),0,12,PRICE_CLOSE,MODE_MAIN,0);
      double RSI = iRSI(Symbol(),0,12,PRICE_CLOSE,0);  
      double MACD_Main = iMACD(Symbol(),0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
      double MACD_Signal = iMACD(Symbol(),0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);
      double Sto_Main = iStochastic(Symbol(),0,10,3,3,MODE_SMA,1,MODE_MAIN,0);    
      double Sto_Signal = iStochastic(Symbol(),0,10,3,3,MODE_SMA,1,MODE_SIGNAL,0);
   
   
      Comment("-----------------------------------------------------------------",
              "\nDaily ATR(14): ",ATR," Todays Range: ",Todays_Range,
              "\nADX(12): ",NormalizeDouble(ADX,2)," RSI(12): ",NormalizeDouble(RSI,2),
              "\nMACD(12,26,9): ",MACD_Main,", ",MACD_Signal,
              "\nStochastic(10,3,3): ",NormalizeDouble(Sto_Main,2),", ",NormalizeDouble(Sto_Signal,2),
              "\n-----------------------------------------------------------------");
      }
   

            
          
   //======================
   // Main Indicator Loop
   //======================
   
   for(int i = limit; i >= 0; i--) //main indicator FOR loop
      {   
      
      // ======================
      // Indicator Calculations
      // ======================
      double MA_Hi = iMA(Symbol(),0,Keltner_Period,0,MODE_SMA,PRICE_HIGH,i);
      double MA_Lo = iMA(Symbol(),0,Keltner_Period,0,MODE_SMA,PRICE_LOW,i);
      double Kelt_Mid_Band = iMA(Symbol(),0,Keltner_Period,0,MODE_SMA,PRICE_TYPICAL,i);
      double Kelt_Upper_Band = Kelt_Mid_Band + ((MA_Hi - MA_Lo)*Keltner_Mul);
      double Kelt_Lower_Band = Kelt_Mid_Band - ((MA_Hi - MA_Lo)*Keltner_Mul);
      double Boll_Upper_Band = iBands(Symbol(),0, Boll_Period,Boll_Dev,0,PRICE_CLOSE, MODE_UPPER,i);
      double Boll_Lower_Band = iBands(Symbol(),0, Boll_Period,Boll_Dev,0,PRICE_CLOSE, MODE_LOWER,i);

      
      // ======================
      // Buffer Calculations
      // ======================
      
      Momentum[i] = (Close[i] - Close[i+Momentum_Period]);
   
      
      if (Boll_Upper_Band >= Kelt_Upper_Band || Boll_Lower_Band <= Kelt_Lower_Band)
         {
         Pos_Diff[i] = (MathAbs(Boll_Upper_Band - Kelt_Upper_Band)+MathAbs(Boll_Lower_Band - Kelt_Lower_Band));
         Squeeze[i] = 1;
         }
      else  
         {
         Pos_Diff[i] = 0;
         }   
         
     
      if (Boll_Upper_Band < Kelt_Upper_Band && Boll_Lower_Band > Kelt_Lower_Band)
         {
         Neg_Diff[i] = -(MathAbs(Boll_Upper_Band - Kelt_Upper_Band)+MathAbs(Boll_Lower_Band - Kelt_Lower_Band));
         Squeeze[i] = 0;
         }
      else  
         {
         Neg_Diff[i] = 0;
         }         

      
      // ======================
      // Trigger Check
      // ======================
      if (Squeeze[i] == 1 && Squeeze[i+1] == 0 && Momentum[i] > 0 && i == 0) // a cross above zero line and Mom > 0
         {         
         if (Last_Alert_Time != Time[0]) 
            {
            if (Alert_On == true) Alert("Alert: Possible Breakout - "+Symbol()+" - "+TimeToStr(TimeLocal()));
            Last_Alert_Time = Time[0];       
            ObjectCreate("Breakout"+Time[0],OBJ_ARROW,0,Time[0],Ask);
            ObjectSet("Breakout"+Time[0],OBJPROP_ARROWCODE,1);
            ObjectSet("Breakout"+Time[0],OBJPROP_COLOR,Blue);
            ObjectSet("Breakout"+Time[0],OBJPROP_WIDTH,2);        
            }
         }
         
         
      if (Squeeze[i] == 1 && Squeeze[i+1] == 0 && Momentum[i] < 0 && i == 0 )   // a cross above zero line and Mom < 0
         {
         if (Last_Alert_Time != Time[0]) 
            {
            if (Alert_On == true) Alert("Alert: Possible Breakout - "+Symbol()+" - "+TimeToStr(TimeLocal())); 
            Last_Alert_Time = Time[0];          
            ObjectCreate("Breakout"+Time[0],OBJ_ARROW,0,Time[0],Bid);
            ObjectSet("Breakout"+Time[0],OBJPROP_ARROWCODE,1);
            ObjectSet("Breakout"+Time[0],OBJPROP_COLOR,Red);
            ObjectSet("Breakout"+Time[0],OBJPROP_WIDTH,2);               
            }
         }         
         
                 
            
      } // end of main indicator FOR loop
      
      
          
  
      
      
   return(0);
   }
   
   
   
//+------------------------------------------------------------------+

Comments