Hey all, I made a pivot study based off of an interesting idea I saw on TradingView which filters out "weak" pivots, and instead only tries to select stronger pivots based on more extreme/volatile action. In addition to the usual pivot or swing high/low logic that looks for the highest high and lowest low within X number of bars, this indicator also has an added ATR multiplier tacked on top of the average price within a set period, so pivots should generally only be established from strong price action.
Here is QQQ from 8/14/23, as you can see there were existing pivots from the prior trading day that acted both as support right off open and then a solid resistance break after. Then the new pivot that forms at the end of the morning run acts as a strong resistance for the rest of the day:
Another great example of how this can be used is from today, 8/16/23 -- Again, the morning resistance holds strong for a triple top and the support pivots hold solid as well for a breakdown play as well as a double bottom:
In the code, I've added functionality for all time frames, as well as a filter for pivots to only form within regular trading hours and more. I don't believe that it "repaints", as it shouldn't paint until after the LB number of bars, but let me know if you see anything I don't. Hope some of you find this useful as I have, happy trading!
http://tos.mx/QdcFPDO
Here is QQQ from 8/14/23, as you can see there were existing pivots from the prior trading day that acted both as support right off open and then a solid resistance break after. Then the new pivot that forms at the end of the morning run acts as a strong resistance for the rest of the day:
Another great example of how this can be used is from today, 8/16/23 -- Again, the morning resistance holds strong for a triple top and the support pivots hold solid as well for a breakdown play as well as a double bottom:
In the code, I've added functionality for all time frames, as well as a filter for pivots to only form within regular trading hours and more. I don't believe that it "repaints", as it shouldn't paint until after the LB number of bars, but let me know if you see anything I don't. Hope some of you find this useful as I have, happy trading!
http://tos.mx/QdcFPDO
Code:
# Filter out Weak pivot highs/lows
input lb = 15; # pivots: lookback/forward
input atrlen = 30;
input atrMult = 1.5; # Spikeyness Index
input useSpikeyCond = yes; # use spikey condition
input confirmOnClose = yes; # wait 1x bar to confirm (avoid repainting)
input project_pivots = yes;
input show_arrows = no;
input usecharttime = yes;
input agg = aggregationperiod.fifteen_min;
input add_boundClouds = yes;
input pivot_margin = 0.25;
input use_rth = yes;
input rth_start = 0930;
input rth_end = 1600;
def rth = SecondsFromTime(rth_start) >= 0 and SecondsTillTime(rth_end) >= 0;
def x = if confirmOnClose then 1 else 0;
def atr = ATR(atrlen);
#//MTF
def TFLow;
def TFHigh;
def TFClose;
if UseChartTime
then {
TFLow = low;
TFHigh = high;
TFClose = close;
} else {
TFLow = low(period = agg);
TFHigh = high(period = agg);
TFClose = close(period = agg);
}
# Pivot highs & Pivot lows: filtering out the rounded/unimpressive pivot highs
def pivHigh = if use_rth then (if rth and (Highest(TFHigh, lb) <= TFHigh and highest(TFHigh[-lb], lb) <= TFHigh ) then TFHigh else double.nan) else if (Highest(TFHigh, lb) <= TFHigh and highest(TFHigh[-lb], lb) <= TFHigh ) then TFHigh else double.nan;
def isPivHigh = !IsNaN(pivHigh);
def maH = Average(TFHigh, 2 * lb);
def spikyH = if useSpikeyCond then pivHigh > maH + (atrMult * atr) else pivHigh and TFHigh > maH;;
plot ph = (isPivHigh[x] and spikyH[x]);
ph.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
ph.sethiding(!show_arrows);
def pivothigh = if isPivHigh and spikyH then TFHigh else Double.NaN;
def pivothigh1 = if !IsNaN(pivothigh[1]) then pivothigh[1] else pivothigh1[1];
plot project_ph = pivothigh1;
project_ph.setpaintingstrategy(paintingstrategy.horizontal);
project_ph.setdefaultcolor(color.green);
project_ph.sethiding(!project_pivots);
addcloud(if add_boundClouds then project_ph - pivot_margin else double.nan, project_ph + pivot_margin, color.light_green, color.light_green);
### Pivot Lows
def pivLow = if use_rth then (if rth and (Lowest(TFLow, lb) >= TFLow and lowest(TFLow[-lb], lb) >= TFLow) then TFLow else double.nan) else if (Lowest(TFLow, lb) >= TFLow and lowest(TFLow[-lb], lb) >= TFLow) then TFLow else double.nan;
def isPivLow = !IsNaN(pivLow);
def maL = Average(TFLow, 2 * lb);
def spikyL = if useSpikeyCond then pivLow < maL - (atrMult * atr) else pivLow and TFLow < maL;;
plot pl = isPivLow[x] and spikyL[x];
pl.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
pl.sethiding(!show_arrows);
def pivotlow = if isPivLow and spikyL then TFLow else Double.NaN;
def pivotlow1 = if !IsNaN(pivotlow[1]) then pivotlow[1] else pivotlow1[1];
plot project_pl = pivotlow1;
project_pl.setpaintingstrategy(paintingstrategy.horizontal);
project_pl.setdefaultcolor(color.red);
project_pl.sethiding(!project_pivots);
addcloud(if add_boundClouds then project_pl - pivot_margin else double.nan, project_pl + pivot_margin, color.light_red, color.light_red);