JMA BBSQUEEZE
Download scriptThis script is designed to analyze market trends and volatility to help traders identify specific momentum shifts and periods of "market compression." It achieves this by combining three primary mathematical concepts: trend direction, volatility measurement, and a squeeze detection mechanism.
Core Components of the Logic
1. Trend Directional Analysis The script first establishes whether the current market price is moving in an upward or downward direction. It uses a specialized version of linear regression—a statistical method that finds the "best fit" line through a series of data points.
- By calculating the slope and intercept of this line based on recent price history, the tool determines the current momentum.
- If the calculated value is positive, it indicates upward pressure; if negative, it indicates downward pressure. This is visualized as a histogram that helps you see which way the "weight" of the market is leaning.
2. Volatility and Range Measurement To understand how much the price is actually moving (or staying still), the script looks at two different types of variance:
- It measures the Average True Range (ATR), which tracks how much the price fluctuates over a set period.
- It simultaneously calculates the Standard Deviation, which shows how much the prices are deviating from their average movement.
3. The Squeeze Detection Logic The most unique part of this script is how it identifies a "Squeeze." It creates a ratio between the current volatility (Standard Deviation) and the price range (ATR).
- When the market becomes very tight—meaning prices are moving sideways with very little expansion—the script recognizes this as a state of compression.
- The tool monitors these conditions to signal when the market is "coiling" like a spring. When this compression reaches a specific threshold, the script identifies a potential breakout point.
How it appears on your chart
Instead of just showing simple lines, this indicator provides visual cues:
- Trend Histograms: These show the immediate direction of the price movement (Up vs. Down).
- Signal Arrows: The script uses specific markers to alert you when the "Squeeze" conditions are met. These arrows serve as a notification that the market's current period of low volatility may be about to give way to a significant move in one direction or the other.
In summary, this tool helps traders filter out "noisy" sideways markets by highlighting periods where price action is being squeezed into a narrow range, potentially signaling an upcoming expansion in momentum.
//+------------------------------------------------------------------+
//| bbsqueeze.mq4 |
//| Copyright © 2005, Nick Bilak, beluck[AT]gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, Nick Bilak"
#property link "http://metatrader.50webs.com/"
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 Lime
#property indicator_color2 Red
#property indicator_color3 Magenta
#property indicator_color4 Aqua
//---- input parameters
extern int bolPrd=20;
extern double bolDev=2.0;
extern int keltPrd=20;
extern double keltFactor=1.5;
extern int momPrd=12;
//---- buffers
double upB[];
double loB[];
double upK[];
double loK[];
int i,j,slippage=3;
double breakpoint=0.0;
double ema=0.0;
int peakf=0;
int peaks=0;
int valleyf=0;
int valleys=0, limit=0;
double ccis[61],ccif[61];
double delta=0;
double ugol=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_HISTOGRAM);
SetIndexBuffer(0,upB);
SetIndexEmptyValue(0,EMPTY_VALUE);
SetIndexStyle(1,DRAW_HISTOGRAM);
SetIndexBuffer(1,loB);
SetIndexEmptyValue(1,EMPTY_VALUE);
SetIndexStyle(2,DRAW_ARROW);
SetIndexBuffer(2,upK);
SetIndexEmptyValue(2,EMPTY_VALUE);
SetIndexArrow(2,159);
SetIndexStyle(3,DRAW_ARROW);
SetIndexBuffer(3,loK);
SetIndexEmptyValue(3,EMPTY_VALUE);
SetIndexArrow(3,159);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
int shift,limit;
double diff,d,std,bbs;
if (counted_bars<0) return(-1);
if (counted_bars>0) counted_bars--;
limit=Bars-31;
if(counted_bars>=31) limit=Bars-counted_bars-1;
for (shift=limit;shift>=0;shift--) {
//d=iMomentum(NULL,0,momPrd,PRICE_CLOSE,shift);
d=LinearRegressionValue(bolPrd,shift);
if(d>0) {
upB[shift]=d;
loB[shift]=0;
} else {
upB[shift]=0;
loB[shift]=d;
}
diff = iATR(NULL,0,keltPrd,shift)*keltFactor;
std = iStdDev(NULL,0,bolPrd,MODE_SMA,0,PRICE_CLOSE,shift);
bbs = bolDev * std / diff;
if(bbs<1) {
upK[shift]=0;
loK[shift]=EMPTY_VALUE;
} else {
loK[shift]=0;
upK[shift]=EMPTY_VALUE;
}
}
return(0);
}
//+------------------------------------------------------------------+
double LinearRegressionValue(int Len,int shift) {
double SumBars = 0;
double SumSqrBars = 0;
double SumY = 0;
double Sum1 = 0;
double Sum2 = 0;
double Slope = 0;
SumBars = Len * (Len-1) * 0.5;
SumSqrBars = (Len - 1) * Len * (2 * Len - 1)/6;
for (int x=0; x<=Len-1;x++) {
double HH = Low[x+shift];
double LL = High[x+shift];
for (int y=x; y<=(x+Len)-1; y++) {
HH = MathMax(HH, High[y+shift]);
LL = MathMin(LL, Low[y+shift]);
}
Sum1 += x* (Close[x+shift]-((HH+LL)/2 + iCustom(NULL,0,"JMA",Len,0,0,x+shift))/2);
SumY += (Close[x+shift]-((HH+LL)/2 + iCustom(NULL,0,"JMA",Len,0,0,x+shift))/2);
}
Sum2 = SumBars * SumY;
double Num1 = Len * Sum1 - Sum2;
double Num2 = SumBars * SumBars-Len * SumSqrBars;
if (Num2 != 0.0) {
Slope = Num1/Num2;
} else {
Slope = 0;
}
double Intercept = (SumY - Slope*SumBars) /Len;
//debugPrintln(Intercept+" : "+Slope);
double LinearRegValue = Intercept+Slope * (Len - 1);
return (LinearRegValue);
}
Comments