Squeeze_Break





//+------------------------------------------------------------------+
//|                                             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 White


// ===================
// 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=false;
extern bool      On_Screen_Info=false;


// =========================
// 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,2);
   SetIndexBuffer(0,Pos_Diff);
   SetIndexStyle(1,DRAW_HISTOGRAM,EMPTY,2);
   SetIndexBuffer(1,Neg_Diff);
   SetIndexStyle(2,DRAW_LINE,STYLE_SOLID);
   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,14,PRICE_CLOSE,MODE_MAIN,0);
      double RSI = iRSI(Symbol(),0,14,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,14,3,3,MODE_SMA,1,MODE_MAIN,0);    
      double Sto_Signal = iStochastic(Symbol(),0,14,3,3,MODE_SMA,1,MODE_SIGNAL,0);
   
   
      Comment("-----------------------------------------------------------------",
              "\nDaily ATR(14): ",ATR," Todays Range: ",Todays_Range,
              "\nADX(14): ",NormalizeDouble(ADX,2)," RSI(14): ",NormalizeDouble(RSI,2),
              "\nMACD(12,26,9): ",MACD_Main,", ",MACD_Signal,
              "\nStochastic(14,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);
   }
   
   
   
//+------------------------------------------------------------------+



Sample





Analysis



Market Information Used:

Series array that contains the highest prices of each bar
Series array that contains the lowest prices of each bar
Series array that contains close prices for each bar
Series array that contains open time of each bar


Indicator Curves created:

Implements a curve of type DRAW_HISTOGRAM

Implements a curve of type DRAW_LINE

Indicators Used:

Indicator of the average true range
Movement directional index
Relative strength index
MACD Histogram
Stochastic oscillator
Moving average indicator
Bollinger bands indicator


Custom Indicators Used:

Order Management characteristics:

Other Features:

It issuies visual alerts to the screen