volatility-weighted price change divergence
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © wzkkzw12345

//@version=4
study(title="Direction")
res = input("15", type=input.resolution)
length = input(28, title="EMA length")

f_intrabarSqMove(_chartTf) =>
    // string _chartTf: chart TF in `timeframe.period` format. It is used to detect the first intrabar.
    var float _sq = na
    var int   _intrabars = na
    rate = log(close/open)
    if change(time(_chartTf))
        // First intrabar detected: reset data.
        _intrabars := 1
        _sq := rate*rate
    else
        _intrabars += 1
        _sq += rate*rate
    [_sq, _intrabars]

_f_intrabarSqMove(_chartTf) =>
    security(syminfo.tickerid, res, f_intrabarSqMove(_chartTf))

//mean = security(syminfo.tickerid, "1", sma(log(close/open), 1440))
[sq, n_bars] = if timeframe.period == "M"
    [a,b] = _f_intrabarSqMove("M")
else if timeframe.period == "W"
    [a,b] = _f_intrabarSqMove("W")
else if timeframe.period == "D"
    [a,b] =_f_intrabarSqMove("D")
else if timeframe.period == "1440"
    [a,b] = _f_intrabarSqMove("1440")
else if timeframe.period == "720"
    [a,b] = _f_intrabarSqMove("720")
else if timeframe.period == "360"
    [a,b] = _f_intrabarSqMove("360")
else if timeframe.period == "240"
    [a,b] = _f_intrabarSqMove("240")
else if timeframe.period == "180"
    [a,b] = _f_intrabarSqMove("180")
else if timeframe.period == "120"
    [a,b] =_f_intrabarSqMove("120")
else if timeframe.period == "60"
    [a,b] = _f_intrabarSqMove("60")
else if timeframe.period == "30"
    [a,b] = _f_intrabarSqMove("30")
else if timeframe.period == "15"
    [a,b] = _f_intrabarSqMove("15")
else if timeframe.period == "10"
    [a,b] = _f_intrabarSqMove("10")
else if timeframe.period == "5"
    [a,b] = _f_intrabarSqMove("5")
else if timeframe.period == "3"
    [a,b] = _f_intrabarSqMove("3")
else
    [float(na), int(1)]

mean_rate = log(close/open)/n_bars 
_time = timeframe.multiplier * (
      timeframe.isseconds ? 1. / 60             :
      timeframe.isminutes ? 1.                  :
      timeframe.isdaily   ? 60. * 24            :
      timeframe.isweekly  ? 60. * 24 * 7        :
      timeframe.ismonthly ? 60. * 24 * 30.4375  : na)


vol_rate = sqrt(sq/n_bars - mean_rate*mean_rate)
ema_vol_rate_sq = rma(vol_rate*vol_rate, 2*length)
action = ema(vol_rate*log(close/open),length)
//plot(action, color=action>=0.? color.green : color.red )
avg_move = ema(log(close/open),length)
//plot(avg_move)
//plot(chaotic_rate, color=chaotic_rate>0.5? color.red : chaotic_rate>0.06 ? color.blue : color.green )
//effective_action = ema_action/ema_abs_move
//plot(effective_action, color= effective_action>=0.? color.green:color.red)
hline(0.)
//_ema = ema(chaotic_rate,length)
diff = (action/sqrt(ema_vol_rate_sq)-avg_move)*100.

plot(diff,color=color.new(diff>= 0.? color.green : color.red,60),style=plot.style_area)
upper_divergence = avg_move> avg_move[1] and diff< diff[1] - abs(diff[1])*(0.03+1.5/length)
lower_divergence = avg_move< avg_move[1] and diff> diff[1] + abs(diff[1])*(0.03+1.5/length)

plot(upper_divergence or lower_divergence ?diff:na,color=color.new(lower_divergence? color.green : color.red,0),style=plot.style_linebr, linewidth=2)
//hline(0.06)
//hline(0.84)
//hline(1.16)
//hline(2.1)

