loxxdynamiczone
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © loxx

//@version=5

// @description Dynamic Zones
//  Derives Leo Zamansky and David Stendahl's Dynamic Zone, 
//  see "Stocks & Commodities V15:7 (306-310): Dynamic Zones by Leo Zamansky, Ph .D., and David Stendahl"
library("loxxdynamiczone", overlay = true)

// @function method for retrieving the dynamic zone levels from input source.
// @param type string, value of either 'buy' or 'sell'.
// @param src float, source, either regular source type or some other caculated value.
// @param pval float, probability defined by extension over/under source, a number <= 1.0.
// @param per int, period lookback.
// @returns float dynamic zone level.
// usage:
//      dZone("buy", close, 0.2, 70)
export dZone(string type, float src, float pval, int per)=>
    float left = -ta.highest(high, per * 3) /syminfo.mintick
    float right = ta.highest(high, per * 3) /syminfo.mintick
    float eps = math.min(syminfo.mintick, 0.001)
    int maxSteps = 0
    float yval = (left + right) / 2.0
    yval := na(yval) ? close : yval
    float delta = yval - left
	while (delta > eps * 5 and maxSteps < per * 2)
        maxSteps += 1
        int count = 0
        if type == "buy"
            for k = 0 to per - 1 by 1
                if src[k] < yval
                    count += 1
            float prob = count/per
            if prob > (pval + eps)
                right := yval
                yval := (yval + left) / 2.
            if prob < (pval - eps)
                left := yval
                yval := (yval + right) / 2.
            if prob < pval + eps and prob > (pval - eps)
                right := yval
                yval := (yval + left) / 2.
            delta := yval - left
            delta
        else 
            for k = 0 to per - 1 by 1
                if src[k] > yval
                    count += 1
            float prob = count/per
            if prob > (pval + eps)
                left := yval
                yval := (yval + right) / 2.
            if prob < (pval - eps)
                right := yval
                yval := (yval + left) / 2.
            if prob < pval + eps and prob > (pval - eps)
                left := yval
                yval := (yval + right) / 2.
            delta := yval - left
    yval
    
//example usage

inter = ta.sma(close, 20)
buylevel = dZone("buy", inter, 0.2, 70)
selllevel = dZone("sell", inter, 0.2, 70)

plot(buylevel, color = color.blue)
plot(selllevel, color = color.white)







