SMA and Accumulation Divergence Scan or Indicator?

jphilli11

Member
Is anyone aware of a scan or indicator that compares the 1) slope of the price action to the 2) the slope of accumulation? Using a dynamic period of time to identify when they diverge? I.E. price is falling but accumulation is rising?

Specifically I'm hoping to find a scanner that uses criteria similar to this:

1. Daily chart
2. SMA 9
3. Accumulation length=14 (for smoothing)
4. Identifies starting position of the comparison as the bar of the last pivot down on price
5. identifies the ending position of the comparison as the bar in which accumulation ceases or drastically decreases
6. triggers based on the relationship between the two slopes. such as SMA -xx, Accumulation +xx (i don't know what the values would actually be and could probably experiment if the other components were working)

Below is a picture of NRXP from 4/26/2021 to 5/24/2021. You can see that as soon as the price began to fall on 4/27 the accumulation began rising. Then accumulation halted on 5/14/2021 and the price jumped on 5/20/2021. I've drawn an arrow on the two indicators to illustrate the pattern I'm looking for.

Hopefully this makes sense!


0U4sWc1ThBtedbw?width=669&height=638&cropmode=none.png
 
Solution
Here's a new version of this indicator as a lower study with up to 4 Accumulation Lengths to allow better visibility into what's going on. I use the first 3 at lengths of 3, 9, and 14. This paints up arrows at the divergence points on the lower study which helps keep my main chart from getting too crowded. Here are a few examples of this at work. This should definitely be used with other indicators for entry but it's a great addition to the toolbox.

Ch1Z7QVafKEvDh?width=1012&height=609&cropmode=none.png


Ouc998U1Ci37Zn?width=1035&height=591&cropmode=none.png


0_lrR5_WBVy6gp?width=1053&height=618&cropmode=none.png



Code:
declare lower;

#=======================================================
#               ACCUMULATION LINES
#=======================================================
input length_1 = 4; 
input length_2 = 9;
input length_3 = 14;
input length_4 =...
ver2 of accumulation divergent clouds,

changed formulas for price direction. used ttm_trend(2) to determine price direction
add an average line of accumulation
add a row of dots at 1 to represent accumulation direction, based on the average
add a row of arrows at 2 to represent price direction
add white down arrows, when accumulation drops by x%

if a x% drop happens , it overrides the accumulation signal and changes the dot to red
draw vertical clouds when accumulation and price are divergent, moving in opposite directions

inputs
levels for accumulation
...lowlevel = 0.75
...highlevel = 1.75
...drop_percent = 20

ttmtrend length for price direction
...compBars = 2

AccumulationDistribution
...accumlength = 14
create an average to determine direction
...accumavg2_len = 4
...accumavg2_type = SIMPLE

Ruby:
# diverg_smaaccum_02


# https://usethinkscript.com/threads/sma-and-accumulation-divergence-scan-or-indicator.7305/#post-70878
# 1) timeframe is always on the daily
# 2) Accumulation threshold
#   [ ] begins to climb from below .75. at the same time as the price begins to fall
#   [ ] will exceed 1.75 before it releases
#   [ ] drops by roughly 20% or more to signal release
# 3) There's no real pattern to the price action other than its descending but can have green days which is why i'm wanting to watch the slope
# 4) this pattern doesn't seem to last longer than 2 or 3 weeks before triggering


declare lower;

def na = Double.NaN;

input lowlevel = 0.75;
plot r1 = lowlevel;
r1.SetDefaultColor(Color.GRAY);

input highlevel = 1.75;
plot r2 = highlevel;
r2.SetDefaultColor(Color.GRAY);

input drop_percent = 20;

# ============================

# price movement

# use a short average of ttm trend, to determine price slope
input compBars = 2;
def ttmtrendup = reference ttm_trend( compBars = compBars ).trendup;
def ttmtrenddwn = reference ttm_trend( compBars = compBars ).trenddown;

# draw arrows for price direction
def rowy = 2;
plot tup = if ttmtrendup then rowy else na;
tup.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
tup.SetDefaultColor(Color.GREEN);
# x.setlineweight(1);
tup.hidebubble();

plot tdwn = if ttmtrenddwn then rowy else na;
tdwn.SetPaintingStrategy(PaintingStrategy.ARROW_down);
tdwn.SetDefaultColor(Color.red);
tdwn.hidebubble();

def trndsign = if ttmtrendup then 1 else -1;


# ============================

# code from AccumulationDistribution
input accumlength = 14;
#input factor = 0.0;
def  range = Highest(high, accumlength) - Lowest(low, accumlength);
plot RangeRatio = range / range[accumlength];
RangeRatio.SetDefaultColor(Color.CYAN);

# smooth out accu line with an avg
input accumavg2_len = 4;
input accumavg2_type = AverageType.SIMPLE;
def RangeRatioavg = MovingAverage(accumavg2_type, RangeRatio, accumavg2_len);
plot RangeRatioavg2 = RangeRatioavg;

# calc bar to bar change
def RangeRatioavgchg = RangeRatioavg - RangeRatioavg[1];
def accsign = Sign(RangeRatioavgchg);

# ============================

# use original accum signal to test for drop
def accdrop2 = ( RangeRatio[1] -  RangeRatio ) >  ( drop_percent / 100 ) ;

plot accdrop = if accdrop2 then RangeRatio else na;
accdrop.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
accdrop.SetDefaultColor(Color.WHITE);

def RangeRatioavgchg2 = if accdrop2 then -1 else RangeRatioavgchg;
def accsign2 = Sign(RangeRatioavgchg2);

# ============================

# draw dots for the accum/dist signal
def row1 = 1;
plot accdisup = if RangeRatioavgchg2 > 0 then row1 else na;
accdisup.SetPaintingStrategy(PaintingStrategy.points);
accdisup.SetDefaultColor(Color.GREEN);
accdisup.setlineweight(3);
accdisup.hidebubble();

plot accdisdwn = if RangeRatioavgchg2 < 0 then row1 else na;
accdisdwn.SetPaintingStrategy(PaintingStrategy.points);
accdisdwn.SetDefaultColor(Color.red);
accdisdwn.setlineweight(3);
accdisdwn.hidebubble();

# ===================================================

#def diverg2 =  accsign <> smasign;
#def diverg2 =  accsign <> trndsign;

# if (sign * sign2 ) < 0 then opp
def diverg2 = (accsign2 * trndsign) < 0;

# ------------------------------------------

#addchartbubble(1, 1, accsign + "\n" + accsign[1] + "\n" + smasign + "\n" + smasign[1] , color.cyan, no);

def top = if diverg2 and RangeRatioavgchg < 0 then Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY;
def bot = if diverg2 and RangeRatioavgchg > 0 then Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY;
AddCloud( top, bot, Color.GREEN, Color.RED);

#


test FB , day chart

RKoHE4J.jpg



the arrows on the upper chart are a modified ttm trend. what i used in the lower.

Ruby:
def na = double.nan;
input compBars = 2;
def ttmtrendup = reference ttm_trend( compBars = compBars ).trendup;
def ttmtrenddwn = reference ttm_trend( compBars = compBars ).trenddown;

plot tup = if ttmtrendup then low else na;
tup.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
tup.SetDefaultColor(Color.green);
plot tdwn = if ttmtrenddwn then high else na;
tdwn.SetPaintingStrategy(PaintingStrategy.ARROW_down);
tdwn.SetDefaultColor(Color.red);
#

This is AMAZING! On just the first few examples it works like a charm. One thing that might be an opportunity is to not use the TTM_UP in determining an upward reversal since the price action tends to lag the accumulation dip. Waiting for price action changes seems to create a slightly late entry and missed %.

2 questions:
1) can we test this without the ttm_up?
2) can we strip away all the plots and only add a arrow for the "top" and bottom, then declare upper? I'd like to be able to use this on my mobile device and am really only looking for entry exit signals in that format. ---this also makes it easier to convert to a scan since you can only have 1 plot for that.


And THANK YOU for this!
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

ver2 of accumulation divergent clouds,

changed formulas for price direction. used ttm_trend(2) to determine price direction
add an average line of accumulation
add a row of dots at 1 to represent accumulation direction, based on the average
add a row of arrows at 2 to represent price direction
add white down arrows, when accumulation drops by x%

if a x% drop happens , it overrides the accumulation signal and changes the dot to red
draw vertical clouds when accumulation and price are divergent, moving in opposite directions

inputs
levels for accumulation
...lowlevel = 0.75
...highlevel = 1.75
...drop_percent = 20

ttmtrend length for price direction
...compBars = 2

AccumulationDistribution
...accumlength = 14
create an average to determine direction
...accumavg2_len = 4
...accumavg2_type = SIMPLE

Ruby:
# diverg_smaaccum_02


# https://usethinkscript.com/threads/sma-and-accumulation-divergence-scan-or-indicator.7305/#post-70878
# 1) timeframe is always on the daily
# 2) Accumulation threshold
#   [ ] begins to climb from below .75. at the same time as the price begins to fall
#   [ ] will exceed 1.75 before it releases
#   [ ] drops by roughly 20% or more to signal release
# 3) There's no real pattern to the price action other than its descending but can have green days which is why i'm wanting to watch the slope
# 4) this pattern doesn't seem to last longer than 2 or 3 weeks before triggering


declare lower;

def na = Double.NaN;

input lowlevel = 0.75;
plot r1 = lowlevel;
r1.SetDefaultColor(Color.GRAY);

input highlevel = 1.75;
plot r2 = highlevel;
r2.SetDefaultColor(Color.GRAY);

input drop_percent = 20;

# ============================

# price movement

# use a short average of ttm trend, to determine price slope
input compBars = 2;
def ttmtrendup = reference ttm_trend( compBars = compBars ).trendup;
def ttmtrenddwn = reference ttm_trend( compBars = compBars ).trenddown;

# draw arrows for price direction
def rowy = 2;
plot tup = if ttmtrendup then rowy else na;
tup.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
tup.SetDefaultColor(Color.GREEN);
# x.setlineweight(1);
tup.hidebubble();

plot tdwn = if ttmtrenddwn then rowy else na;
tdwn.SetPaintingStrategy(PaintingStrategy.ARROW_down);
tdwn.SetDefaultColor(Color.red);
tdwn.hidebubble();

def trndsign = if ttmtrendup then 1 else -1;


# ============================

# code from AccumulationDistribution
input accumlength = 14;
#input factor = 0.0;
def  range = Highest(high, accumlength) - Lowest(low, accumlength);
plot RangeRatio = range / range[accumlength];
RangeRatio.SetDefaultColor(Color.CYAN);

# smooth out accu line with an avg
input accumavg2_len = 4;
input accumavg2_type = AverageType.SIMPLE;
def RangeRatioavg = MovingAverage(accumavg2_type, RangeRatio, accumavg2_len);
plot RangeRatioavg2 = RangeRatioavg;

# calc bar to bar change
def RangeRatioavgchg = RangeRatioavg - RangeRatioavg[1];
def accsign = Sign(RangeRatioavgchg);

# ============================

# use original accum signal to test for drop
def accdrop2 = ( RangeRatio[1] -  RangeRatio ) >  ( drop_percent / 100 ) ;

plot accdrop = if accdrop2 then RangeRatio else na;
accdrop.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
accdrop.SetDefaultColor(Color.WHITE);

def RangeRatioavgchg2 = if accdrop2 then -1 else RangeRatioavgchg;
def accsign2 = Sign(RangeRatioavgchg2);

# ============================

# draw dots for the accum/dist signal
def row1 = 1;
plot accdisup = if RangeRatioavgchg2 > 0 then row1 else na;
accdisup.SetPaintingStrategy(PaintingStrategy.points);
accdisup.SetDefaultColor(Color.GREEN);
accdisup.setlineweight(3);
accdisup.hidebubble();

plot accdisdwn = if RangeRatioavgchg2 < 0 then row1 else na;
accdisdwn.SetPaintingStrategy(PaintingStrategy.points);
accdisdwn.SetDefaultColor(Color.red);
accdisdwn.setlineweight(3);
accdisdwn.hidebubble();

# ===================================================

#def diverg2 =  accsign <> smasign;
#def diverg2 =  accsign <> trndsign;

# if (sign * sign2 ) < 0 then opp
def diverg2 = (accsign2 * trndsign) < 0;

# ------------------------------------------

#addchartbubble(1, 1, accsign + "\n" + accsign[1] + "\n" + smasign + "\n" + smasign[1] , color.cyan, no);

def top = if diverg2 and RangeRatioavgchg < 0 then Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY;
def bot = if diverg2 and RangeRatioavgchg > 0 then Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY;
AddCloud( top, bot, Color.GREEN, Color.RED);

#


test FB , day chart

RKoHE4J.jpg



the arrows on the upper chart are a modified ttm trend. what i used in the lower.

Ruby:
def na = double.nan;
input compBars = 2;
def ttmtrendup = reference ttm_trend( compBars = compBars ).trendup;
def ttmtrenddwn = reference ttm_trend( compBars = compBars ).trenddown;

plot tup = if ttmtrendup then low else na;
tup.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
tup.SetDefaultColor(Color.green);
plot tdwn = if ttmtrenddwn then high else na;
tdwn.SetPaintingStrategy(PaintingStrategy.ARROW_down);
tdwn.SetDefaultColor(Color.red);
#


forgive me if this is redundant but I keep trying to post and then I can't see it after I hit "post reply".......

First, this is AMAZING! It hits all the examples I provided and more right where we want. I really appreciate the thought and effort you put into this. I noticed 1 possible opportunity in that it seems like waiting for the TTM_UP trend is delaying entry and we could probably capture more upside (without additional risk) if we simply entered at the Accumulation dip. The price action seems to lag this by a few bars and, ideally, that's when we'd want to enter. So I have 2 questions:

1) can we eliminate the TTM_UP trend and trigger earlier?
2) can we build a scaled-down version that is mobile friendly? Ideally remove all the plots and simply have an Up Arrow at the beginning of any "top" and a down arrow at the beginning of any "bot"? This will also make it easy to deploy this as a scan.

Thank you again!
 
Here's my attempt at mutilating your gorgeous work to make it mobile friendly. I changed

1) the TTM trend to simply sum the down/up signals over the last 10 bars and used a countdowns > 5 to infer a declining share price.
2) highlevel to 1 instead of 1.75
3) redefined "top" by 6 variables (mostly so I could test it by adding/removing as I went)
4) removed pretty much everything else and set it to an orange dot. I have chart bubble commented out in case it's being used on the desktop

I figure I can combine this with the sophisticated lower study when I'm at the desk and make quick decisions from my phone when I'm travelling.

Here it is as a scanner too (which is where the money's made :) )

Accumulation Divergence Scanner
 
forgive me if this is redundant but I keep trying to post and then I can't see it after I hit "post reply".......

First, this is AMAZING! It hits all the examples I provided and more right where we want. I really appreciate the thought and effort you put into this. I noticed 1 possible opportunity in that it seems like waiting for the TTM_UP trend is delaying entry and we could probably capture more upside (without additional risk) if we simply entered at the Accumulation dip. The price action seems to lag this by a few bars and, ideally, that's when we'd want to enter. So I have 2 questions:

1) can we eliminate the TTM_UP trend and trigger earlier?
2) can we build a scaled-down version that is mobile friendly? Ideally remove all the plots and simply have an Up Arrow at the beginning of any "top" and a down arrow at the beginning of any "bot"? This will also make it easy to deploy this as a scan.

Thank you again!
replying to post #21

you're welcome.
1.. yes and no. i picked ttm and used a small number, thinking it would be a reasonable quick response to price movements, while slightly smoothing them out, to avoid little jumps that might stop a trend.
i can replace the ttmtrend formulas, but something will be needed to determine a peak or a dip, if that is what starts and stops a sloped segment. most ( all ?) codes will look at some future bars to determine a peak or dip, otherwise how would you know it happened.
i can use code that looks for a peak within +- 2 bars, but then it will be 2 bars behind. ( i haven't tested ver2 to see what the delay is)

2.. yes. i can add inputs , to turn off some of the visuals. and/or a choice 'mobile/simple' mode to turn off most and just show a few arrows.
 
Here's my attempt at mutilating your gorgeous work to make it mobile friendly. I changed

1) the TTM trend to simply sum the down/up signals over the last 10 bars and used a countdowns > 5 to infer a declining share price.
2) highlevel to 1 instead of 1.75
3) redefined "top" by 6 variables (mostly so I could test it by adding/removing as I went)
4) removed pretty much everything else and set it to an orange dot. I have chart bubble commented out in case it's being used on the desktop

I figure I can combine this with the sophisticated lower study when I'm at the desk and make quick decisions from my phone when I'm travelling.

Here it is as a scanner too (which is where the money's made :) )

Accumulation Divergence Scanner

Would you be able to please share a link of the changes you made? Thank you!!!
 
Would you be able to please share a link of the changes you made? Thank you!!!
Absolutely. I've been playing with it ever since halcyonguy figured out the solution. I've made a few changes since my last post including:
1. an override to some of the paramaters if the Accumulation drops by more than 200%
2. set up a long and short accumulation period for comparison/confirmation.
long = 10
short = 3
3. changed the drop% trigger to a 5 bar span for the long acc and within 2 bars on the short
4. moved it to upper study and removed all the cloud and other indications that are not mobile friendly - thought those are really helpful and I use it on my desktop whenever I can.


I've noticed it gives false alerts if there's a large red or green bar within the study range so I just visually verify that there's been steady decline in price over the last 10 bars or so.

here's the study:
https://tos.mx/NIVsMIW
here's the scanner:
https://tos.mx/tNNoyvN







Code:
declare upper;

#============================================================
#          DIVERGENCE CODE
#============================================================

input showbubble = no;
def na = Double.NaN;
input lowlevel = 0.75;
input highlevel = 1.25;
input fallbelow = 1.25;
input drop_percent = 75;
input override_drop_percent = 200;

# ============================

# price movement

# use a short average of ttm trend, to determine price slope
input compBars = 5;
def ttmtrendup = reference ttm_trend( compBars = compBars ).trendup;
def ttmtrenddwn = reference ttm_trend( compBars = compBars ).trenddown;

def countups = sum(ttmtrendup > 0, compBars );  # num of upsignals in last 10
def countdwn = sum(ttmtrenddwn > 0, compBars ); #num of downsignals in last 10

def trndsign = if countups >= compBars *.75 then 1 else -1; #more than half upsignals
#def redcandle = open > close;
#def countred = sum(redcandle, compbars);

# code from AccumulationDistribution
input accumlength1 = 10;
def  range = Highest(high, accumlength1) - Lowest(low, accumlength1);
def RangeRatio = range / range[accumlength1];

input accumlength2 = 3;
def  range2 = Highest(high, accumlength2) - Lowest(low, accumlength2);
def RangeRatio2 = range2 / range2[accumlength2];

# smooth out accu line with an avg
input accumavg2_len = 4;
input accumavg2_type = AverageType.SIMPLE;
def RangeRatioavg = MovingAverage(accumavg2_type, RangeRatio, accumavg2_len);
def RangeRatioavg2 = RangeRatioavg;

# calc bar to bar4 change
def RangeRatioavgchg = RangeRatioavg[1] - RangeRatioavg;
def accsign = Sign(RangeRatioavgchg);

# ============================
def range2true = rangeratio2 - rangeratio2[1] > 0;
# use original accum signal to test for drop

def ratiomax = highest(RangeRatio, 5);

def accdrop2 = if
                ( Ratiomax -  RangeRatio ) >  ( drop_percent / 100 )
                and range2true within 2 bars   #added 8/5/21
                then 1 else 0;
def drop_max = (Ratiomax - rangeratio) * 100;

# ===================================================
def top = if
            accdrop2
            and RangeRatioavgchg > 0
            and accsign > 0
            and trndsign < 0
           # and reference ttm_trend().trenddown
            and RangeRatio[1] > highlevel
            and rangeratio < fallbelow
            and countdwn > compbars *.75
            #and countred > compbars *.75
            then 1 else
         if drop_max >= override_drop_percent
            and trndsign < 0
            and reference ttm_trend().trenddown
            and RangeRatio[1] > highlevel
            and rangeratio < fallbelow
            and countdwn > compbars *.75
            #and countred > compbars *.75
            then 1 else
            0;


plot toparrow = top;
toparrow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
toparrow.SetDefaultColor(Color.orange);
toparrow.SetLineWeight(5);

AddChartBubble(top and showbubble, close, "Enter Below " + Close, Color.CYAN, yes);
 
Now I could use some new help. I'm trying to anchor these studies to the last price pivot point. I can get the bar number and distance between the last pivot point and the current bar but the ttm trend and other studies won't accept a variable - they require a constant. So the question becomes:

How do I trick TOS into using my bar count as the length in TTM and Accumulation studies? I can't figure it out. Here's the code (mix of Halcyonguy and Ben10 code):

Code:
declare upper;
 
#=======================================================
#               pivot points code
#=======================================================
#Inputs
input showbubble = no;
input n = 10;
input showLines = yes;
input showValues = no;
input showBarNumbers = no;
input ExtensionLengthBars = 20; # added to control length of Entension
input UpperExtensionPercentLimit = 5;
input LowerExtensionPercentLimit = 5;
input DisplayLabel = yes;    #JQ 7.8.2018 added
    addlabel (DisplayLabel, "Projection Pivots n:" + n + " " , color.WHITE);    #JQ 7.8.2018 added
 
def vHigh = high;  # creates the variable vHigh.  Use of the variable reduce data calls to tos iData server
def vLow = low;
def vOpen = open;
def vClose = close;
def vVolume = volume;
def nan = Double.NaN;
# Bar Time & Date
def bn = BarNumber();
def currentBar = HighestAll(if !IsNaN(vHigh) then bn else nan);


def PH;
def hh =
    fold i = 1 to n + 1
    with p = 1
    while p
    do vHigh > getValue(vHigh, -i);
PH =
    if (bn > n and
        vHigh == highest(vHigh, n) and
        hh)
    then
        vHigh
    else
        double.NaN;
def PHBar = if !isNaN(PH)
               then bn
               else PHBar[1];
def PHL = if !isNaN(PH)
             then PH
             else PHL[1];
def priorPHBar = if PHL != PHL[1]
                    then PHBar[1]
                    else priorPHBar[1];
def HighPivots = bn >= highestAll(priorPHBar);

plot pivotHigh = PH;
pivothigh.SetPaintingStrategy(PaintingStrategy.BOOLEAN_aRROW_DOWN);
pivothigh.SetDefaultColor(Color.orange);
pivothigh.SetLineWeight(5);

def DynamicLength = bn-phbar;
def bigpivot = highestall(priorPHBar);

#AddChartBubble(PH, close, "PH: " + PH
#                            + "\n" + "PHL: " + PHL
#                            + "\n" + "PHBar: " + PHBar  
#                            + "\n" + "hh: " + hh
#                            + "\n" + "PriorPH: " + PriorPHBar
#                            , Color.CYAN, yes);



#============================================================
#          DIVERGENCE CODE
#============================================================

def na = Double.NaN;
input lowlevel = 0.75;
input highlevel = 1.25;
input fallbelow = 1.25;
input drop_percent = 75;
input override_drop_percent = 200;

# price movement

# use a short average of ttm trend, to determine price slope


input compbars = 5;

# *************HOW DO I GET THESE STUDIES TO ACCEPT DYNAMICLENGTH?

def ttmtrendup = reference ttm_trend( compBars = compbars ).trendup;
def ttmtrenddwn = reference ttm_trend( compBars = compBars ).trenddown;

def countups = sum(ttmtrendup > 0, compBars );  # num of upsignals in last 10
def countdwn = sum(ttmtrenddwn > 0, compBars ); #num of downsignals in last 10

def trndsign = if countups >= compBars *.75 then 1 else -1; #more than half upsignals

# code from AccumulationDistribution
input accumlength1 = 10;
def  range = Highest(high, accumlength1) - Lowest(low, accumlength1);
def RangeRatio = range / range[accumlength1];

input accumlength2 = 3;
def  range2 = Highest(high, accumlength2) - Lowest(low, accumlength2);
def RangeRatio2 = range2 / range2[accumlength2];

# smooth out accu line with an avg
input accumavg2_len = 4;
input accumavg2_type = AverageType.SIMPLE;
def RangeRatioavg = MovingAverage(accumavg2_type, RangeRatio, accumavg2_len);
def RangeRatioavg2 = RangeRatioavg;

# calc bar to bar4 change
def RangeRatioavgchg = RangeRatioavg[1] - RangeRatioavg;
def accsign = Sign(RangeRatioavgchg);

# ============================
def range2true = rangeratio2 - rangeratio2[1] > 0;
# use original accum signal to test for drop

def ratiomax = highest(RangeRatio, 5);

def accdrop2 = if
                ( Ratiomax -  RangeRatio ) >  ( drop_percent / 100 )
                and range2true within 2 bars   #added 8/5/21
                then 1 else 0;

def drop_max = (Ratiomax - rangeratio) * 100;

# ===================================================
def top = if
            accdrop2
            and RangeRatioavgchg > 0
            and accsign > 0
            and trndsign < 0
           # and reference ttm_trend().trenddown
            and RangeRatio[1] > highlevel
            and rangeratio < fallbelow
            and countdwn > compbars *.75
            #and countred > compbars *.75
            then 1 else
#         if drop_max >= override_drop_percent
#            and trndsign < 0
#            and reference ttm_trend().trenddown
#            and RangeRatio[1] > highlevel
#            and rangeratio < fallbelow
#            and countdwn > compbars *.75
            #and countred > compbars *.75
#            then 1 else
            0;

plot toparrow = top;
toparrow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
toparrow.SetDefaultColor(Color.orange);
toparrow.SetLineWeight(5);

AddChartBubble(top and showbubble, close,
                            #"Enter Below " + Close
                             "BarNum: " + bn
                            + "\n" + "PHBar: " + PHBar  
                            + "\n" + "Diff: " + DynamicLength
                            #+ "\n" + "BigPiv: " + bigpivot
                            #+ "\n" + "BigDiff: " + bigpivot - bn
                            #+ "\n" + percent
                            , Color.orange, yes);
 
Last edited:
Awesome, can’t wait to test it out. Thanks for getting back 🙏
Hey Doc, I've been making more changes to this and fine-tuning it a bit more. I'd love to have you try it and give me any feedback/changes you think would make it more accurate. Below is the new code and a link to the indicator and scanner:

Changes:
1. pivot down is now tied to PPS signal instead of the pivot point of highest price
2. I've set up 3 separate timeframes that look at accumulation and price action on those scales. i.e 1 week, 2 week and 3 week+
3. fixed a slope and sign error from last version
4. changed TTM down % to 50% or more instead of 75%
5. 3-week drop only requires a 10% change since it has a longer average. 2 week still requires 20%
6. there is a 3 day overlap between 2 and 3 week timeframes to help capture movements on the fringes


Indicator:
http://tos.mx/2P85Cho

Scanner:
https://tos.mx/HNxcHmv


Code:
declare upper;
 #=======================================================
#               pivot points code
#=======================================================
#Inputs


#addchartbubble(PercentOfDayAvg > 200, close, PercentofDayAvg + "%", color.red, no);

input     showbubble = no;
input     Pivot_length = 10;
input     Show_Pivot = yes;
input     DisplayLabel = no;    #JQ 7.8.2018 added

def     RVSD = RelativeVolumeStDev()."RelVol";
def     Mobo = FW_DPO_MOBO()."DPO";
def     vHigh = high;  # creates the variable vHigh.  Use of the variable reduce data calls to tos iData server
def     vLow = low;
def     vOpen = open;
def     vClose = close;
def     vVolume = volume;
def     nan = Double.NaN;
# Bar Time & Date
def     bn = BarNumber();
def     currentBar = HighestAll(if !IsNaN(vHigh) then bn else nan);
def     PPS = IsNaN("value" = PPS().sellsignal) is false;
# pivot points
def     PH;
def     hh =
        fold i = 1 to  Pivot_length + 1
        with p = 1
        while p      
        do PPS > getValue(PPS, -i);
PH =
        if (bn >  Pivot_length and
            PPS == highest(PPS,  Pivot_length) and
            hh)
        then
            PPS
        else
            double.NaN;
def     PHBar = if !isNaN(PH)
                   then bn
                   else PHBar[1];
def     PHL = if !isNaN(PH)
                 then PH
                 else PHL[1];
def     priorPHBar = if PHL != PHL[1]
                        then PHBar[1]
                        else priorPHBar[1];
def     HighPivots = bn >= highestAll(priorPHBar);



def     DynamicLength =
                        if
                        bn - phbar < 2
                        then bn - priorPHBar
                        else bn - phbar;

#AddChartBubble(PH, close, "PH: " + PH
#                            + "\n" + "PHL: " + PHL
#                            + "\n" + "PHBar: " + PHBar  
#                            + "\n" + "hh: " + hh
#                            + "\n" + "PriorPH: " + PriorPHBar
#                            , Color.CYAN, yes);

plot Pivot = PH and show_pivot;
pivot.SetPaintingStrategy(PaintingStrategy.BOOLEAN_aRROW_DOWN);
pivot.SetDefaultColor(Color.orange);
pivot.SetLineWeight(5);

#============================================================
#          DIVERGENCE CODE
#============================================================

def na = Double.NaN;
input lowlevel = 0.75;
input highlevel = 1.25;
input fallbelow = 1.5;
input drop_percent = 75;
input override_drop_percent = 200;


input compbars = 20;  # pull in trend for longest period.  reduce within the specific groupings below
def ttmtrendup = reference ttm_trend( compBars = compbars ).trendup;
def ttmtrenddwn = reference ttm_trend( compBars = compBars ).trenddown;


#======= 1 week - 5 bar factors (fast length manipulation)  *probably won't use because too volatile and unreliable
def     w1_length = 3;
def     w1_Range = Highest(high,w1_length) - Lowest(low, w1_length);
def     w1_Ratio = w1_Range / w1_Range[w1_length];

def     w1_RatioMax = highest(w1_Ratio, 2);
def     w1_Drop = if
                ( w1_RatioMax - w1_Ratio ) >  ( drop_percent / 100 )
                #and w1_Ratio > w2_Ratio
                then 1 else 0;

def     w1_Slope = w1_Ratio[6] - w1_Ratio[1];
def     w1_Sign = sign(w1_Slope);

def     w1_trendup = sum(ttmtrendup > 0, w1_length );  # num of upsignals in last 5
def     w1_TrendDwn = sum(ttmtrenddwn > 0, w1_length ); #num of downsignals in last 5

#==================================================================
#======= 2 week - 10 bar factors (medium length manipulation)
#==================================================================
def     w2_length = 9;
def     w2_Range = Highest(high, w2_length) - Lowest(low, w2_length);
def     w2_Ratio = w2_Range / w2_Range[w2_length];

def     w2_RatioMax = highest(w2_Ratio, 5);
def     w2_Drop = if
                ( w2_RatioMax - w2_Ratio ) / w2_RatioMax > .2
                and w1_Ratio > w2_Ratio
                then 1 else 0;

def     w2_Slope = w2_Ratio[w2_length + 1] - w2_Ratio[1];
def     w2_Sign = sign(w2_Slope);

def     w2_trendup = sum(ttmtrendup > 0, w2_length );  # num of upsignals in last 9
def     w2_TrendDwn = sum(ttmtrenddwn > 0,w2_length ); #num of downsignals in last 9

def     w2_Diverge = if
            dynamiclength > w1_length #and dynamiclength <= w2_length + 3
            and w2_Drop
            and w2_Sign < 0
            and w2_ratiomax >= highlevel * .9
            and w2_ratio <= fallbelow
            and w2_TrendDwn >= w2_length *.5
            and mobo > mobo[1]
            and RVSD <= 1
            then 1 else
            0;
 

AddChartBubble(w2_Diverge and showbubble, close,
                            "W2 " + Close
#                             "BarNum: " + bn
#                            + "\n" + "start: " + w2_Ratio[w2_length]
#                           + "\n" + "end: " + w2_Ratio[1]
#                          + "\n" + "sign: " + w2_sign                          
#                         + "\n" + "slope: " + w2_slope
#                            + "\n" + "D%: " +  ( w2_RatioMax - w2_Ratio ) / w2_ratiomax
#                            + "\n" + "D%: min " +  drop_percent
#                            + "\n" + "drop: " +  ( w2_RatioMax - w2_Ratio )
#                            + "\n" + "max: " + w2_RatioMax
#                            + "\n" + "cur: " + w2_Ratio
                            , Color.orange, yes);


#======= 3 week - 15 bar factors (slow length manipulation)
def     w3_length = 14;
def     w3_Range = Highest(high,w3_length) - Lowest(low, w3_length);
def     w3_Ratio = w3_Range / w3_Range[w3_length];

def     w3_RatioMax = highest(w3_Ratio, 3);
def     w3_Drop = if
                (w3_Ratio / w3_RatioMax ) / W3_RatioMax  >  .1
                #and w2_Ratio > w3_Ratio
                then 1 else
                #if ( w2_RatioMax - w2_Ratio ) / w2_ratiomax >  .35 then 1 else
                0;

def     w3_Slope = w3_Ratio[w2_length + 1] - w3_Ratio;
def     w3_Sign = sign(w3_Slope);

def     w3_trendup = sum(ttmtrendup > 0, w3_length );  # num of upsignals in last 10
def     w3_TrendDwn = sum(ttmtrenddwn > 0,w3_length ); #num of downsignals in last 10

def     w3_Diverge = if
            dynamiclength >= w3_length -3
            and w3_Drop
            and w3_Sign < 0        
            and w3_ratiomax >= highlevel
            and w2_ratio <= fallbelow    #w3 ratio too slow to use this but w2 is still good indication
            and w3_TrendDwn >= w3_length *.5
            and RVSD <= 2
            then 1 else
            0;
 
           
AddChartBubble(w3_Diverge and showbubble, close,
                            "W3 " + Close
#                            + "BarNum: " + bn
#                            + "\n" + "down: " + w3_TrendDwn
#                            + "\n" + "sign: " + w3_sign                          
#                            + "\n" + "slope: " + w3_slope
#                            + "\n" + "D%: " +  (w3_Ratio / w3_RatioMax ) / W3_RatioMax
#                            + "\n" + "drop: " +  ( w3_RatioMax - w3_Ratio )
#                            + "\n" + "max: " + w3_RatioMax
#                            + "\n" + "cur: " + w3_Ratio
                            , Color.orange, yes);



# ============================




def divergealert = if w2_diverge then 1 else    #for the scanner version
                   if w3_diverge then 1 else 0;

plot w2_alert = w2_diverge;
w2_alert.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
w2_alert.SetDefaultColor(Color.BLUE);
w2_alert.SetLineWeight(5);

plot w_3alert = w3_diverge;
w_3alert.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
w_3alert.SetDefaultColor(Color.orange);
w_3alert.SetLineWeight(5);
 
Last edited:
Hey Doc, I've been making more changes to this and fine-tuning it a bit more. I'd love to have you try it and give me any feedback/changes you think would make it more accurate. Below is the new code and a link to the indicator and scanner:

Changes:
1. pivot down is now tied to PPS signal instead of the pivot point of highest price
2. I've set up 3 separate timeframes that look at accumulation and price action on those scales. i.e 1 week, 2 week and 3 week+
3. fixed a slope and sign error from last version
4. changed TTM down % to 50% or more instead of 75%
5. 3-week drop only requires a 10% change since it has a longer average. 2 week still requires 20%
6. there is a 3 day overlap between 2 and 3 week timeframes to help capture movements on the fringes


Indicator:
http://tos.mx/2P85Cho

Scanner:
https://tos.mx/HNxcHmv


Code:
declare upper;
 #=======================================================
#               pivot points code
#=======================================================
#Inputs


#addchartbubble(PercentOfDayAvg > 200, close, PercentofDayAvg + "%", color.red, no);

input     showbubble = no;
input     Pivot_length = 10;
input     Show_Pivot = yes;
input     DisplayLabel = no;    #JQ 7.8.2018 added

def     RVSD = RelativeVolumeStDev()."RelVol";
def     Mobo = FW_DPO_MOBO()."DPO";
def     vHigh = high;  # creates the variable vHigh.  Use of the variable reduce data calls to tos iData server
def     vLow = low;
def     vOpen = open;
def     vClose = close;
def     vVolume = volume;
def     nan = Double.NaN;
# Bar Time & Date
def     bn = BarNumber();
def     currentBar = HighestAll(if !IsNaN(vHigh) then bn else nan);
def     PPS = IsNaN("value" = PPS().sellsignal) is false;
# pivot points
def     PH;
def     hh =
        fold i = 1 to  Pivot_length + 1
        with p = 1
        while p     
        do PPS > getValue(PPS, -i);
PH =
        if (bn >  Pivot_length and
            PPS == highest(PPS,  Pivot_length) and
            hh)
        then
            PPS
        else
            double.NaN;
def     PHBar = if !isNaN(PH)
                   then bn
                   else PHBar[1];
def     PHL = if !isNaN(PH)
                 then PH
                 else PHL[1];
def     priorPHBar = if PHL != PHL[1]
                        then PHBar[1]
                        else priorPHBar[1];
def     HighPivots = bn >= highestAll(priorPHBar);



def     DynamicLength =
                        if
                        bn - phbar < 2
                        then bn - priorPHBar
                        else bn - phbar;

#AddChartBubble(PH, close, "PH: " + PH
#                            + "\n" + "PHL: " + PHL
#                            + "\n" + "PHBar: " + PHBar 
#                            + "\n" + "hh: " + hh
#                            + "\n" + "PriorPH: " + PriorPHBar
#                            , Color.CYAN, yes);

plot Pivot = PH and show_pivot;
pivot.SetPaintingStrategy(PaintingStrategy.BOOLEAN_aRROW_DOWN);
pivot.SetDefaultColor(Color.orange);
pivot.SetLineWeight(5);

#============================================================
#          DIVERGENCE CODE
#============================================================

def na = Double.NaN;
input lowlevel = 0.75;
input highlevel = 1.25;
input fallbelow = 1.5;
input drop_percent = 75;
input override_drop_percent = 200;


input compbars = 20;  # pull in trend for longest period.  reduce within the specific groupings below
def ttmtrendup = reference ttm_trend( compBars = compbars ).trendup;
def ttmtrenddwn = reference ttm_trend( compBars = compBars ).trenddown;


#======= 1 week - 5 bar factors (fast length manipulation)  *probably won't use because too volatile and unreliable
def     w1_length = 3;
def     w1_Range = Highest(high,w1_length) - Lowest(low, w1_length);
def     w1_Ratio = w1_Range / w1_Range[w1_length];

def     w1_RatioMax = highest(w1_Ratio, 2);
def     w1_Drop = if
                ( w1_RatioMax - w1_Ratio ) >  ( drop_percent / 100 )
                #and w1_Ratio > w2_Ratio
                then 1 else 0;

def     w1_Slope = w1_Ratio[6] - w1_Ratio[1];
def     w1_Sign = sign(w1_Slope);

def     w1_trendup = sum(ttmtrendup > 0, w1_length );  # num of upsignals in last 5
def     w1_TrendDwn = sum(ttmtrenddwn > 0, w1_length ); #num of downsignals in last 5

#==================================================================
#======= 2 week - 10 bar factors (medium length manipulation)
#==================================================================
def     w2_length = 9;
def     w2_Range = Highest(high, w2_length) - Lowest(low, w2_length);
def     w2_Ratio = w2_Range / w2_Range[w2_length];

def     w2_RatioMax = highest(w2_Ratio, 5);
def     w2_Drop = if
                ( w2_RatioMax - w2_Ratio ) / w2_RatioMax > .2
                and w1_Ratio > w2_Ratio
                then 1 else 0;

def     w2_Slope = w2_Ratio[w2_length + 1] - w2_Ratio[1];
def     w2_Sign = sign(w2_Slope);

def     w2_trendup = sum(ttmtrendup > 0, w2_length );  # num of upsignals in last 9
def     w2_TrendDwn = sum(ttmtrenddwn > 0,w2_length ); #num of downsignals in last 9

def     w2_Diverge = if
            dynamiclength > w1_length #and dynamiclength <= w2_length + 3
            and w2_Drop
            and w2_Sign < 0
            and w2_ratiomax >= highlevel * .9
            and w2_ratio <= fallbelow
            and w2_TrendDwn >= w2_length *.5
            and mobo > mobo[1]
            and RVSD <= 1
            then 1 else
            0;
 

AddChartBubble(w2_Diverge and showbubble, close,
                            "W2 " + Close
#                             "BarNum: " + bn
#                            + "\n" + "start: " + w2_Ratio[w2_length]
#                           + "\n" + "end: " + w2_Ratio[1]
#                          + "\n" + "sign: " + w2_sign                         
#                         + "\n" + "slope: " + w2_slope
#                            + "\n" + "D%: " +  ( w2_RatioMax - w2_Ratio ) / w2_ratiomax
#                            + "\n" + "D%: min " +  drop_percent
#                            + "\n" + "drop: " +  ( w2_RatioMax - w2_Ratio )
#                            + "\n" + "max: " + w2_RatioMax
#                            + "\n" + "cur: " + w2_Ratio
                            , Color.orange, yes);


#======= 3 week - 15 bar factors (slow length manipulation)
def     w3_length = 14;
def     w3_Range = Highest(high,w3_length) - Lowest(low, w3_length);
def     w3_Ratio = w3_Range / w3_Range[w3_length];

def     w3_RatioMax = highest(w3_Ratio, 3);
def     w3_Drop = if
                (w3_Ratio / w3_RatioMax ) / W3_RatioMax  >  .1
                #and w2_Ratio > w3_Ratio
                then 1 else
                #if ( w2_RatioMax - w2_Ratio ) / w2_ratiomax >  .35 then 1 else
                0;

def     w3_Slope = w3_Ratio[w2_length + 1] - w3_Ratio;
def     w3_Sign = sign(w3_Slope);

def     w3_trendup = sum(ttmtrendup > 0, w3_length );  # num of upsignals in last 10
def     w3_TrendDwn = sum(ttmtrenddwn > 0,w3_length ); #num of downsignals in last 10

def     w3_Diverge = if
            dynamiclength >= w3_length -3
            and w3_Drop
            and w3_Sign < 0       
            and w3_ratiomax >= highlevel
            and w2_ratio <= fallbelow    #w3 ratio too slow to use this but w2 is still good indication
            and w3_TrendDwn >= w3_length *.5
            and RVSD <= 2
            then 1 else
            0;
 
          
AddChartBubble(w3_Diverge and showbubble, close,
                            "W3 " + Close
#                            + "BarNum: " + bn
#                            + "\n" + "down: " + w3_TrendDwn
#                            + "\n" + "sign: " + w3_sign                         
#                            + "\n" + "slope: " + w3_slope
#                            + "\n" + "D%: " +  (w3_Ratio / w3_RatioMax ) / W3_RatioMax
#                            + "\n" + "drop: " +  ( w3_RatioMax - w3_Ratio )
#                            + "\n" + "max: " + w3_RatioMax
#                            + "\n" + "cur: " + w3_Ratio
                            , Color.orange, yes);



# ============================




def divergealert = if w2_diverge then 1 else    #for the scanner version
                   if w3_diverge then 1 else 0;

plot w2_alert = w2_diverge;
w2_alert.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
w2_alert.SetDefaultColor(Color.BLUE);
w2_alert.SetLineWeight(5);

plot w_3alert = w3_diverge;
w_3alert.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
w_3alert.SetDefaultColor(Color.orange);
w_3alert.SetLineWeight(5);
can you upload "EYEG" daily chart or go over it. It has the lowest o/s shares (showed up in the scan in post #30).

I have set show bubbles "yes", so 8/9 the bubble reads w2 2.27, start: 8.122, end: 4.96, sign: -1 , slope: -2.89. how would you interpret it? thanks
 
can you upload "EYEG" daily chart or go over it. It has the lowest o/s shares (showed up in the scan in post #30).

I have set show bubbles "yes", so 8/9 the bubble reads w2 2.27, start: 8.122, end: 4.96, sign: -1 , slope: -2.89. how would you interpret it? thanks
Absolutely, so first off I would comment out all the extra stuff on the bubble as it's really just there for me to test the values of all the criteria - it doesn't help much in making a decision to enter. What I'm seeing on EYEG on 8/9 is the following:

1. it triggered from the 9-day accumulation range with a significant drop > 20%
2. as the 10-day range was dropping the 14-day was increasing (dramatically) which tells me it's likely going to continue and now is not the time to get in.
3. Also, the DPO_MOBO shows a significant drop on 8/9 which is a bearish signal - telling me to wait a little more.
4. finally, there is a significant trading range and volume on 7/27 (which inside the window of analysis) which is throwing off the accumulation range. One of the problems I've found is big red or green candles with significant volume can distort the results.

A few days after the first alert you see (on my screen shot) that the next alert triggers (the 14-day, called w3) and the MOBO begins to climb. This is likely the best entry for this ticker as as both mid and slow lengths on accumulation are decreasing and you can see the price action leveling out. It's likely to get a pop in the next few days. I would target 2.41 - 3.73 as a range based on other examples.

On the RelativeVolumeStDev in my picture you can see the three lengths of accumulation as follows:
green = 3 day
yellow = 9 day
red = 14 day.


If anyone could suggest a good tool for editing these screen shots I'd be much obliged - the snip and sketch I use kind of ****s.

ObIBfOG99E8dwR?width=1053&height=987&cropmode=none.png


i'm constantly tinkering with the code to try get it as accurate as possible. Here's the most recent version:

Code:
declare upper;
#=======================================================
#               pivot points code
#=======================================================
#Inputs
input     showbubble     = no;
input     Pivot_length   = 10;
input     Show_Pivot     = yes;
input     DisplayLabel   = no; 
input     compbars       = 20;  # pull in trend for longest period.  reduce within the specific groupings below
def        ttmtrenddwn  = reference ttm_trend( compBars = compBars ).trenddown;

input     lowlevel       = 0.75;
input     highlevel      = 1.25;
input     fallbelow      = 1.5;
input     drop_percent   = 20;
input     override_drop_percent = 70;

def     VChaikin     = ChaikinOscillator().COSC / 1000;
def     vCCI         = CCI().CCI;
def     aggperiod    = if getaggregationperiod() == aggregationperiod.day then 1 else 0;
def     RVSD         = RelativeVolumeStDev()."RelVol";
def     Mobo         = FW_DPO_MOBO()."DPO";
def     vHigh        = high;
def     nan          = Double.NaN;
def     bn           = BarNumber();
def     PPS          = IsNaN("value" = PPS().sellsignal) is false;

#=================================================
#            PPS Pivot Point
#================================================

def     hh =
        fold i = 1 to  Pivot_length + 1
        with p = 1
        while p     
        do PPS > getValue(PPS, -i);
def     PH =
            if (bn >  Pivot_length
                and PPS == highest(PPS,  Pivot_length)
                and hh)
            then PPS
            else double.NaN;
def     PHBar       = if !isNaN(PH) then bn else PHBar[1];
def     PHL         = if !isNaN(PH) then PH else PHL[1];
def     priorPHBar  = if PHL != PHL[1] then PHBar[1] else priorPHBar[1];
def     HighPivots  = bn >= highestAll(priorPHBar);

def     DynamicLength = if bn - phbar < 2  then bn - priorPHBar else bn - phbar;

plot Pivot = PH and show_pivot;
pivot.SetPaintingStrategy(PaintingStrategy.BOOLEAN_aRROW_DOWN);
pivot.SetDefaultColor(Color.orange);
pivot.SetLineWeight(5);

#============================================================
#          DIVERGENCE CODE
#============================================================


#==================================================================
#         1 week - 3 bar factors (short length manipulation)
#==================================================================

def     w1_length     = 3;
#wasn't using so removed most of this content

#==================================================================
#        2 week - 10 bar factors (medium length manipulation)
#==================================================================
def     w2_length = 9;
def     w2_Range = Highest(high, w2_length) - Lowest(low, w2_length);
def     w2_Ratio = w2_Range / w2_Range[w2_length];
def     w2_RatioMax = highest(w2_Ratio, 5);
def     w2_Drop_Percent = ( w2_RatioMax - w2_Ratio ) / w2_RatioMax * 100;

def     w2_Drop = if w2_RatioMax == w2_Ratio then 0 else if
                w2_Drop_Percent >  drop_percent                 
                then 1 else 0;

def     w2_Slope = w2_Ratio[w2_length + 1] - w2_Ratio[1];
def     w2_Sign =
                If w2_Drop_Percent > override_drop_percent
                and w2_ratio <= lowlevel
                then -1
                else sign(w2_Slope);
        #override sign if the drop% > 70 and falls below lowlevel


def     w2_TrendDwn = sum(ttmtrenddwn > 0,w2_length );

def     w2_Diverge = if
            dynamiclength > w1_length #and dynamiclength <= w2_length + 3
            and w2_Drop
            and w2_Sign < 0
            and w2_ratiomax >= highlevel * .9
            and w2_ratio <= fallbelow
            and w2_TrendDwn >= w2_length *.5
            and mobo > mobo[1]
            and RVSD <= 1
            and VChaikin > VChaikin[1]
            and vCCi > vCCI[1]
            then 1 else
            0;


AddChartBubble(w2_Diverge and !w2_Diverge[1] and showbubble and aggperiod, close,
                            "W2 " + Close
#                             "BarNum: " + bn
#                            + "\n" + "start: " + w2_Ratio[w2_length]
#                            + "\n" + "end: " + w2_Ratio[1]
#                            + "\n" + "sign: " + w2_sign                         
#                            + "\n" + "slope: " + w2_slope
#                            + "\n" + "D%: " +  ( w2_RatioMax - w2_Ratio ) / w2_ratiomax
#                            + "\n" + "D%: min " +  drop_percent
#                            + "\n" + "drop: " +  ( w2_RatioMax - w2_Ratio )
#                            + "\n" + "max: " + w2_RatioMax
#                            + "\n" + "cur: " + w2_Ratio
#                            + "\n" + "Chkn diff: " + (vchaikin[1] - vchaikin)
#                            + "\n" + "Chaikin[1]: " + vchaikin[1]
#                            + "\n" + "CCI diff: " + (vcci[1] -  vcci)
#                            + "\n" + "CCI[1]: " + vcci[1]
                            , Color.CYAN, yes);

#==================================================================
#======= 3 week - 15+ bar factors (long length manipulation)
#==================================================================
def     w3_length = 14;
def     w3_Range = Highest(high,w3_length) - Lowest(low, w3_length);
def     w3_Ratio = w3_Range / w3_Range[w3_length];

def     w3_RatioMax = highest(w3_Ratio, 3);
def     w3_Drop_Percent = ( w3_RatioMax - w3_Ratio ) / w3_RatioMax * 100;
def     w3_Drop = if
                w3_RatioMax ==  w3_Ratio then 0 else if
                w3_Drop_Percent > drop_percent / 2   
                then 1 else             
                0;

def     w3_Slope = w3_Ratio[w3_length + 1] - w3_Ratio;
def     w3_Sign = sign(w3_Slope);


def     w3_TrendDwn = sum(ttmtrenddwn > 0,w3_length ); #num of downsignals in last 10
def     w3_Diverge = if
            dynamiclength >= w3_length -3
            and w3_Drop
            and w3_Sign < 0       
            and w3_ratiomax >= highlevel * .9
            #and w2_ratio <= fallbelow     #w3 ratio too slow to use this but w2 is still good indication
            and w3_TrendDwn >= w3_length *.5
            and RVSD <= 2.1
           # and vChaikin > vChaikin[1]
           # and vCCI > vCCI[1]
            then 1 else
            0;
          
AddChartBubble(w3_Diverge and !w3_Diverge[1] and showbubble and aggperiod, close,
                            "W3 " + Close
#                            + "BarNum: " + bn
#                            + "\n" + "down: " + w3_TrendDwn
#                            + "\n" + "sign: " + w3_sign                         
#                            + "\n" + "slope: " + w3_slope
#                            + "\n" + "D%: " +  (w3_Ratio / w3_RatioMax ) / W3_RatioMax
#                            + "\n" + "drop: " +  ( w3_RatioMax - w3_Ratio )
#                            + "\n" + "max: " + w3_RatioMax
#                            + "\n" + "cur: " + w3_Ratio
#                            + "\n" + "beg: " + w3_Ratio[w3_length + 1]
                            , Color.PINK, yes);



#==================================================================
#                    PLOT POINTS
#==================================================================

plot w2_alert = w2_diverge;
w2_alert.SetPaintingStrategy(PaintingStrategy.boolean_ARROW_UP);
w2_alert.SetDefaultColor(Color.CYAN);
w2_alert.SetLineWeight(5);

plot w_3alert = w3_diverge;
w_3alert.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
w_3alert.SetDefaultColor(Color.PINK);
w_3alert.SetLineWeight(5);
 
Last edited:
Absolutely, so first off I would comment out all the extra stuff on the bubble as it's really just there for me to test the values of all the criteria - it doesn't help much in making a decision to enter. What I'm seeing on EYEG on 8/9 is the following:

1. it triggered from the 9-day accumulation range with a significant drop > 20%
2. as the 10-day range was dropping the 14-day was increasing (dramatically) which tells me it's likely going to continue and now is not the time to get in.
3. Also, the DPO_MOBO shows a significant drop on 8/9 which is a bearish signal - telling me to wait a little more.
4. finally, there is a significant trading range and volume on 7/27 (which inside the window of analysis) which is throwing off the accumulation range. One of the problems I've found is big red or green candles with significant volume can distort the results.

A few days after the first alert you see (on my screen shot) that the next alert triggers (the 14-day, called w3) and the MOBO begins to climb. This is likely the best entry for this ticker as as both mid and slow lengths on accumulation are decreasing and you can see the price action leveling out. It's likely to get a pop in the next few days. I would target 2.41 - 3.73 as a range based on other examples.

On the RelativeVolumeStDev in my picture you can see the three lengths of accumulation as follows:
green = 3 day
yellow = 9 day
red = 14 day.


If anyone could suggest a good tool for editing these screen shots I'd be much obliged - the snip and sketch I use kind of ****s.

ObIBfOG99E8dwR?width=1053&height=987&cropmode=none.png


i'm constantly tinkering with the code to try get it as accurate as possible. Here's the most recent version:

Code:
declare upper;
#=======================================================
#               pivot points code
#=======================================================
#Inputs
input     showbubble     = no;
input     Pivot_length   = 10;
input     Show_Pivot     = yes;
input     DisplayLabel   = no; 
input     compbars       = 20;  # pull in trend for longest period.  reduce within the specific groupings below
def        ttmtrenddwn  = reference ttm_trend( compBars = compBars ).trenddown;

input     lowlevel       = 0.75;
input     highlevel      = 1.25;
input     fallbelow      = 1.5;
input     drop_percent   = 20;
input     override_drop_percent = 70;

def     VChaikin     = ChaikinOscillator().COSC / 1000;
def     vCCI         = CCI().CCI;
def     aggperiod    = if getaggregationperiod() == aggregationperiod.day then 1 else 0;
def     RVSD         = RelativeVolumeStDev()."RelVol";
def     Mobo         = FW_DPO_MOBO()."DPO";
def     vHigh        = high;
def     nan          = Double.NaN;
def     bn           = BarNumber();
def     PPS          = IsNaN("value" = PPS().sellsignal) is false;

#=================================================
#            PPS Pivot Point
#================================================

def     hh =
        fold i = 1 to  Pivot_length + 1
        with p = 1
        while p     
        do PPS > getValue(PPS, -i);
def     PH =
            if (bn >  Pivot_length
                and PPS == highest(PPS,  Pivot_length)
                and hh)
            then PPS
            else double.NaN;
def     PHBar       = if !isNaN(PH) then bn else PHBar[1];
def     PHL         = if !isNaN(PH) then PH else PHL[1];
def     priorPHBar  = if PHL != PHL[1] then PHBar[1] else priorPHBar[1];
def     HighPivots  = bn >= highestAll(priorPHBar);

def     DynamicLength = if bn - phbar < 2  then bn - priorPHBar else bn - phbar;

plot Pivot = PH and show_pivot;
pivot.SetPaintingStrategy(PaintingStrategy.BOOLEAN_aRROW_DOWN);
pivot.SetDefaultColor(Color.orange);
pivot.SetLineWeight(5);

#============================================================
#          DIVERGENCE CODE
#============================================================


#==================================================================
#         1 week - 3 bar factors (short length manipulation)
#==================================================================

def     w1_length     = 3;
#wasn't using so removed most of this content

#==================================================================
#        2 week - 10 bar factors (medium length manipulation)
#==================================================================
def     w2_length = 9;
def     w2_Range = Highest(high, w2_length) - Lowest(low, w2_length);
def     w2_Ratio = w2_Range / w2_Range[w2_length];
def     w2_RatioMax = highest(w2_Ratio, 5);
def     w2_Drop_Percent = ( w2_RatioMax - w2_Ratio ) / w2_RatioMax * 100;

def     w2_Drop = if w2_RatioMax == w2_Ratio then 0 else if
                w2_Drop_Percent >  drop_percent                 
                then 1 else 0;

def     w2_Slope = w2_Ratio[w2_length + 1] - w2_Ratio[1];
def     w2_Sign =
                If w2_Drop_Percent > override_drop_percent
                and w2_ratio <= lowlevel
                then -1
                else sign(w2_Slope);
        #override sign if the drop% > 70 and falls below lowlevel

def     w2_trendup = sum(ttmtrendup > 0, w2_length );
def     w2_TrendDwn = sum(ttmtrenddwn > 0,w2_length );

def     w2_Diverge = if
            dynamiclength > w1_length #and dynamiclength <= w2_length + 3
            and w2_Drop
            and w2_Sign < 0
            and w2_ratiomax >= highlevel * .9
            and w2_ratio <= fallbelow
            and w2_TrendDwn >= w2_length *.5
            and mobo > mobo[1]
            and RVSD <= 1
            and VChaikin > VChaikin[1]
            and vCCi > vCCI[1]
            then 1 else
            0;


AddChartBubble(w2_Diverge and !w2_Diverge[1] and showbubble and aggperiod, close,
                            "W2 " + Close
#                             "BarNum: " + bn
#                            + "\n" + "start: " + w2_Ratio[w2_length]
#                            + "\n" + "end: " + w2_Ratio[1]
#                            + "\n" + "sign: " + w2_sign                         
#                            + "\n" + "slope: " + w2_slope
#                            + "\n" + "D%: " +  ( w2_RatioMax - w2_Ratio ) / w2_ratiomax
#                            + "\n" + "D%: min " +  drop_percent
#                            + "\n" + "drop: " +  ( w2_RatioMax - w2_Ratio )
#                            + "\n" + "max: " + w2_RatioMax
#                            + "\n" + "cur: " + w2_Ratio
#                            + "\n" + "Chkn diff: " + (vchaikin[1] - vchaikin)
#                            + "\n" + "Chaikin[1]: " + vchaikin[1]
#                            + "\n" + "CCI diff: " + (vcci[1] -  vcci)
#                            + "\n" + "CCI[1]: " + vcci[1]
                            , Color.CYAN, yes);

#==================================================================
#======= 3 week - 15+ bar factors (long length manipulation)
#==================================================================
def     w3_length = 14;
def     w3_Range = Highest(high,w3_length) - Lowest(low, w3_length);
def     w3_Ratio = w3_Range / w3_Range[w3_length];

def     w3_RatioMax = highest(w3_Ratio, 3);
def     w3_Drop_Percent = ( w3_RatioMax - w3_Ratio ) / w3_RatioMax * 100;
def     w3_Drop = if
                w3_RatioMax ==  w3_Ratio then 0 else if
                w3_Drop_Percent > drop_percent / 2   
                then 1 else             
                0;

def     w3_Slope = w3_Ratio[w3_length + 1] - w3_Ratio;
def     w3_Sign = sign(w3_Slope);

def     w3_trendup = sum(ttmtrendup > 0, w3_length );  # num of upsignals in last 10
def     w3_TrendDwn = sum(ttmtrenddwn > 0,w3_length ); #num of downsignals in last 10
def     w3_Diverge = if
            dynamiclength >= w3_length -3
            and w3_Drop
            and w3_Sign < 0       
            and w3_ratiomax >= highlevel * .9
            #and w2_ratio <= fallbelow     #w3 ratio too slow to use this but w2 is still good indication
            and w3_TrendDwn >= w3_length *.5
            and RVSD <= 2.1
           # and vChaikin > vChaikin[1]
           # and vCCI > vCCI[1]
            then 1 else
            0;
          
AddChartBubble(w3_Diverge and !w3_Diverge[1] and showbubble and aggperiod, close,
                            "W3 " + Close
#                            + "BarNum: " + bn
#                            + "\n" + "down: " + w3_TrendDwn
#                            + "\n" + "sign: " + w3_sign                         
#                            + "\n" + "slope: " + w3_slope
#                            + "\n" + "D%: " +  (w3_Ratio / w3_RatioMax ) / W3_RatioMax
#                            + "\n" + "drop: " +  ( w3_RatioMax - w3_Ratio )
#                            + "\n" + "max: " + w3_RatioMax
#                            + "\n" + "cur: " + w3_Ratio
#                            + "\n" + "beg: " + w3_Ratio[w3_length + 1]
                            , Color.PINK, yes);



#==================================================================
#                    PLOT POINTS
#==================================================================

plot w2_alert = w2_diverge;
w2_alert.SetPaintingStrategy(PaintingStrategy.boolean_ARROW_UP);
w2_alert.SetDefaultColor(Color.CYAN);
w2_alert.SetLineWeight(5);

plot w_3alert = w3_diverge;
w_3alert.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
w_3alert.SetDefaultColor(Color.PINK);
w_3alert.SetLineWeight(5);


I've also noticed that this version is EXTREMELY accurate on the 10-min charts. Take a look at EYEG on 10min. If you have the time from intra-day trading this could be a great tool to catch 5-10% moves on stocks you're comfortable with.

Over the past 5 days EYEG has given 9 separate alert windows and ONLY 1 missed.
I think the math works out to...
1. +2.5%
2. +4.5%
3. +4%
4. +2.5%
5. -7.4
6 +10.6
7 +5.17
8 +10.78
9 +7.52



bE5VPrW719Rvov?width=1034&height=489&cropmode=none.png
 
Now I could use some new help. I'm trying to anchor these studies to the last price pivot point. I can get the bar number and distance between the last pivot point and the current bar but the ttm trend and other studies won't accept a variable - they require a constant. So the question becomes:

How do I trick TOS into using my bar count as the length in TTM and Accumulation studies? I can't figure it out. Here's the code (mix of Halcyonguy and Ben10 code):

Code:
declare upper;
 
#=======================================================
#               pivot points code
#=======================================================
#Inputs
input showbubble = no;
input n = 10;
input showLines = yes;
input showValues = no;
input showBarNumbers = no;
input ExtensionLengthBars = 20; # added to control length of Entension
input UpperExtensionPercentLimit = 5;
input LowerExtensionPercentLimit = 5;
input DisplayLabel = yes;    #JQ 7.8.2018 added
    addlabel (DisplayLabel, "Projection Pivots n:" + n + " " , color.WHITE);    #JQ 7.8.2018 added
 
def vHigh = high;  # creates the variable vHigh.  Use of the variable reduce data calls to tos iData server
def vLow = low;
def vOpen = open;
def vClose = close;
def vVolume = volume;
def nan = Double.NaN;
# Bar Time & Date
def bn = BarNumber();
def currentBar = HighestAll(if !IsNaN(vHigh) then bn else nan);


def PH;
def hh =
    fold i = 1 to n + 1
    with p = 1
    while p
    do vHigh > getValue(vHigh, -i);
PH =
    if (bn > n and
        vHigh == highest(vHigh, n) and
        hh)
    then
        vHigh
    else
        double.NaN;
def PHBar = if !isNaN(PH)
               then bn
               else PHBar[1];
def PHL = if !isNaN(PH)
             then PH
             else PHL[1];
def priorPHBar = if PHL != PHL[1]
                    then PHBar[1]
                    else priorPHBar[1];
def HighPivots = bn >= highestAll(priorPHBar);

plot pivotHigh = PH;
pivothigh.SetPaintingStrategy(PaintingStrategy.BOOLEAN_aRROW_DOWN);
pivothigh.SetDefaultColor(Color.orange);
pivothigh.SetLineWeight(5);

def DynamicLength = bn-phbar;
def bigpivot = highestall(priorPHBar);

#AddChartBubble(PH, close, "PH: " + PH
#                            + "\n" + "PHL: " + PHL
#                            + "\n" + "PHBar: " + PHBar 
#                            + "\n" + "hh: " + hh
#                            + "\n" + "PriorPH: " + PriorPHBar
#                            , Color.CYAN, yes);



#============================================================
#          DIVERGENCE CODE
#============================================================

def na = Double.NaN;
input lowlevel = 0.75;
input highlevel = 1.25;
input fallbelow = 1.25;
input drop_percent = 75;
input override_drop_percent = 200;

# price movement

# use a short average of ttm trend, to determine price slope


input compbars = 5;

# *************HOW DO I GET THESE STUDIES TO ACCEPT DYNAMICLENGTH?

def ttmtrendup = reference ttm_trend( compBars = compbars ).trendup;
def ttmtrenddwn = reference ttm_trend( compBars = compBars ).trenddown;

def countups = sum(ttmtrendup > 0, compBars );  # num of upsignals in last 10
def countdwn = sum(ttmtrenddwn > 0, compBars ); #num of downsignals in last 10

def trndsign = if countups >= compBars *.75 then 1 else -1; #more than half upsignals

# code from AccumulationDistribution
input accumlength1 = 10;
def  range = Highest(high, accumlength1) - Lowest(low, accumlength1);
def RangeRatio = range / range[accumlength1];

input accumlength2 = 3;
def  range2 = Highest(high, accumlength2) - Lowest(low, accumlength2);
def RangeRatio2 = range2 / range2[accumlength2];

# smooth out accu line with an avg
input accumavg2_len = 4;
input accumavg2_type = AverageType.SIMPLE;
def RangeRatioavg = MovingAverage(accumavg2_type, RangeRatio, accumavg2_len);
def RangeRatioavg2 = RangeRatioavg;

# calc bar to bar4 change
def RangeRatioavgchg = RangeRatioavg[1] - RangeRatioavg;
def accsign = Sign(RangeRatioavgchg);

# ============================
def range2true = rangeratio2 - rangeratio2[1] > 0;
# use original accum signal to test for drop

def ratiomax = highest(RangeRatio, 5);

def accdrop2 = if
                ( Ratiomax -  RangeRatio ) >  ( drop_percent / 100 )
                and range2true within 2 bars   #added 8/5/21
                then 1 else 0;

def drop_max = (Ratiomax - rangeratio) * 100;

# ===================================================
def top = if
            accdrop2
            and RangeRatioavgchg > 0
            and accsign > 0
            and trndsign < 0
           # and reference ttm_trend().trenddown
            and RangeRatio[1] > highlevel
            and rangeratio < fallbelow
            and countdwn > compbars *.75
            #and countred > compbars *.75
            then 1 else
#         if drop_max >= override_drop_percent
#            and trndsign < 0
#            and reference ttm_trend().trenddown
#            and RangeRatio[1] > highlevel
#            and rangeratio < fallbelow
#            and countdwn > compbars *.75
            #and countred > compbars *.75
#            then 1 else
            0;

plot toparrow = top;
toparrow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
toparrow.SetDefaultColor(Color.orange);
toparrow.SetLineWeight(5);

AddChartBubble(top and showbubble, close,
                            #"Enter Below " + Close
                             "BarNum: " + bn
                            + "\n" + "PHBar: " + PHBar 
                            + "\n" + "Diff: " + DynamicLength
                            #+ "\n" + "BigPiv: " + bigpivot
                            #+ "\n" + "BigDiff: " + bigpivot - bn
                            #+ "\n" + percent
                            , Color.orange, yes);


[/QUOTE]
 
I entered the code and the I get the following error message:
No such variable: ttmtrendup at 91:26
No such variable: ttmtrendup at 145:26
No such variable: ttmtrendup at 91:26
No such variable: ttmtrendup at 145:2
 
@jphilli11 Hey just curious I don't really understand how you are deciding when to get in the trade. And then is it a waiting game for it to spike up. Look at the stock HIPO 8/19 does this fall in your criteria for a stock to possibly enter. Sorry just trying to understand. Thanks!
 
Generally we’re waiting for the accumulation to drop by the [drop %] AND be below the [fall below] threshold. So a minimum drop of 20% and the accumulation to be below a 1.5. This meets the first criteria but not the second.
This one is also a little outside the norm because the accumulation began a few days prior to the share price drop (normally it’s the same day or the following) - I’m not sure what’s going on with HIPO but it’s weird.

What we’re trying to identify is a stock who’s price is falling because market makers are pushing it down (stacking the bid and ask), triggering stop losses, and scooping up the cheapies. We enter the trade when the pressure seems to be subsiding and price is likely to rebound.

As far as when to enter HIPO - I don’t think this indicator will be helpful. Something different is happening here.

does this help?
 
Generally we’re waiting for the accumulation to drop by the [drop %] AND be below the [fall below] threshold. So a minimum drop of 20% and the accumulation to be below a 1.5. This meets the first criteria but not the second.
This one is also a little outside the norm because the accumulation began a few days prior to the share price drop (normally it’s the same day or the following) - I’m not sure what’s going on with HIPO but it’s weird.

What we’re trying to identify is a stock who’s price is falling because market makers are pushing it down (stacking the bid and ask), triggering stop losses, and scooping up the cheapies. We enter the trade when the pressure seems to be subsiding and price is likely to rebound.

As far as when to enter HIPO - I don’t think this indicator will be helpful. Something different is happening here.

does this help?
Yes this helps I thought HIPO was weird too it just showed up on your scan the other day. But there is really no time frame or guidance as to when the stock might pop up? Is that correct?
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
452 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top