OPEN-SOURCE SCRIPT
Log Regression Oscillator (caN)

fi(ki)=>'ra'
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org/MPL/2.0/
// © fikira
//version=6
indicator('Log Regression Oscillator', max_bars_back=5000, max_labels_count=500, max_lines_count=500, overlay=false)
________________________________________________________________________________________________________________________ ='
⎞ Settings ⎛
(__--------__) '
cGREEN = #089981, cRED = #F23645, cGRAY = #757a79
threshold = input.int (300 , minval=150)
proactive = input.bool (false )
GRE = input.color(cGREEN , 'Bull' , group='Style' )
RED = input.color(cRED , 'Bear' , group='Style' )
GRY = input.color(cGRAY , 'Unconfirmed Bull/Bear' , group='Style' )
showDsh = input.bool ( true , 'Show Dashboard' , group='Dashboard' )
dshLoc = str.replace(str.lower(input.string('Top Right', 'Location', group='Dashboard', options=['Top Right', 'Bottom Right', 'Bottom Left'])), ' ', '_')
txtSize = str.lower(input.string('Normal' , 'Size' , group='Dashboard', options=['Tiny', 'Small', 'Normal', 'Large', 'Huge']) )
________________________________________________________________________________________________________________________ :='
⎞ Constants and general variables ⎛
(__-------------------------------__) '
INV = color(na)
n = bar_index
________________________________________________________________________________________________________________________ :='
⎞ Functions ⎛
(__---------__) '
dot(x, y)=>
if x.size() > 1 and y.size() > 1
m1 = matrix.new<float>()
m2 = matrix.new<float>()
m1.add_col(m1.columns(), y)
m2.add_row(m2.rows (), x)
m1.mult (m2)
.eigenvalues()
.sum()
//Closed form solution to best fit log function
log_reg(log_x, log_x2, log_y) =>
sum_log_x = log_x . sum()
sum_y = log_y . sum()
sum_log_x_y = dot(log_x ,log_y)
sum_log_x_sq = log_x2 . sum()
n_ = log_x .size()
//Closed-form solutions for a and b
a = (n_ * sum_log_x_y - sum_log_x * sum_y)
/ (n_ * sum_log_x_sq - math.pow(sum_log_x , 2))
b = ( sum_y - a * sum_log_x ) / n_
[a, b]
//Variables declared for draw()
var array<float>arr = array.new<float>(4, na)
proActH = false, proActL = false
var lastHi = 0., var lastLi = 0.
draw(aTop_x, aTop_x2, aTop_y, aBot_x, aBot_x2, aBot_y, top_points, prc_points, btm_points, refit) =>
var label labH = na, var label labL = na
vTop = 0.
vBtm = 0.
if refit
top_points.clear(), prc_points.clear(), btm_points.clear()
[a_top, b_top] = log_reg(aTop_x, aTop_x2, aTop_y), arr.set(0, a_top), arr.set(1, b_top)
[a_btm, b_btm] = log_reg(aBot_x, aBot_x2, aBot_y), arr.set(2, a_btm), arr.set(3, b_btm)
for i = 0 to n
top = math.exp(a_top * math.log(i) + b_top)
btm = math.exp(a_btm * math.log(i) + b_btm)
avg = math.avg(top, btm)
if i == n
vTop := top
vBtm := btm
ix = n - i
if ix < 4999
hi = high [ix]
lo = low [ix]
cl = close[ix]
getC = hi > avg ? hi : lo < avg ? lo : cl
prc_points.push(chart.point.from_index(i, 100 * math.max(-1.5, math.min(1.5, (getC - btm) / (top - btm)))))
for lab in label.all
lab.delete()
firstH = proactive ? true : false
firstL = proactive ? true : false
color colH = na, color colL = na
sz = prc_points.size()
if aTop_x.size() > 0
for i = aTop_x.size() -1 to 0
idx = int(math.exp(aTop_x.get(i)))
if idx < sz and idx > n - 5000 and idx >= 0
if firstH
if aTop_x.last() != lastHi
colH := GRY
firstH := false
else
colH := RED
else
colH := RED
top = math.exp(a_top * math.log(idx) + b_top)
btm = math.exp(a_btm * math.log(idx) + b_btm)
label.new(idx , 100 *
math.max(-1.5, math.min(1.5, (high[n-idx] - btm)
/ (top - btm)
) ), '●', textcolor = colH, color=INV, size=8)
if aBot_x.size() > 0
for i = aBot_x.size() -1 to 0
idx = int(math.exp(aBot_x.get(i)))
if idx < sz and idx > n - 5000 and idx >= 0
if firstL
if aBot_x.last() != lastLi
colL := GRY
firstL := false
else
colL := GRE
else
colL := GRE
top = math.exp(a_top * math.log(idx) + b_top)
btm = math.exp(a_btm * math.log(idx) + b_btm)
label.new(idx , 100 *
math.max(-1.5, math.min(1.5, (low [n-idx] - btm)
/ (top - btm)
) ), '●', textcolor = colL, color=INV, size=8
, style = label.style_label_up)
else
top = math.exp(arr.get(0) * math.log(n) + arr.get(1))
btm = math.exp(arr.get(2) * math.log(n) + arr.get(3))
avg = math.avg(top, btm)
vTop := top
vBtm := btm
hi = high, lo = low, cl = close
getC = hi > avg ? hi : lo < avg ? lo : cl
prc_points.push(chart.point.from_index(n, 100 * math.max(-1.5, math.min(1.5, (getC - btm) / (top - btm)))))
for poly in polyline.all
poly.delete()
if barstate.islast
labH.delete(), labH := label.new(n, 100, str.tostring(vTop, format.mintick), color=color.new(chart.fg_color, 85), textcolor=RED, style=label.style_label_lower_left, size=12)
labL.delete(), labL := label.new(n, 0, str.tostring(vBtm, format.mintick), color=color.new(chart.fg_color, 85), textcolor=GRE, style=label.style_label_upper_left, size=12)
polyline.new(prc_points.size() >= 5000 ? prc_points.slice(prc_points.size()-4999, prc_points.size()-1) : prc_points, line_color=chart.fg_color)
________________________________________________________________________________________________________________________ :='
⎞ Variables ⎛
(__---------__) '
//bool trigerring fit
refit = false
var top_points = array.new<chart.point>(0)
var prc_points = array.new<chart.point>(0)
var btm_points = array.new<chart.point>(0)
//Variables arrays
var peaks_y = array.new<float>(0)
var peaks_x = array.new<float>(0)
var peaks_x2 = array.new<float>(0)
var btms_y = array.new<float>(0)
var btms_x = array.new<float>(0)
var btms_x2 = array.new<float>(0)
var tb = table.new(dshLoc, 4, 8
, bgcolor = #1e222d
, border_color = #373a46
, border_width = 1
, frame_color = #373a46
, frame_width = 1)
________________________________________________________________________________________________________________________ :='
⎞ Exec ⎛
(__----__) '
//Top Bottom detection
max = ta.max(high)
var min = low
min := max == high ? low
: math.min(low , min)
barsmax = ta.barssince(high == max)
barsmin = ta.barssince(low == min)
if barsmax == threshold
nmax = n-barsmax
if peaks_x .size() > 0 and peaks_x.last() != lastHi
peaks_y .set(-1, math.log( max) )
peaks_x .set(-1, math.log(nmax) )
peaks_x2.set(-1, math.pow(math.log(nmax), 2))
else
peaks_y .push( math.log(max) )
peaks_x .push( math.log(nmax) )
peaks_x2.push( math.pow(math.log(nmax), 2))
lastHi := math.log(nmax)
refit := true
else
min := math.min(low , min)
if barsmin == threshold
nmin = n-barsmin
if btms_x .size() > 0 and btms_x.last() != lastLi
btms_y .set(-1, math.log(min) )
btms_x .set(-1, math.log(nmin) )
btms_x2 .set(-1, math.pow(math.log(nmin), 2))
else
btms_y .push( math.log( min) )
btms_x .push( math.log(nmin) )
btms_x2.push( math.pow(math.log(nmin), 2))
lastLi := math.log(nmin)
refit := true
chMax = ta.change(max) , chMin = ta.change(min)
if (chMax != 0 or chMin != 0) and proactive and not refit and n > threshold
[a_top, b_top] = log_reg(peaks_x, peaks_x2, peaks_y)
[a_btm, b_btm] = log_reg( btms_x, btms_x2, btms_y)
top = math.exp(a_top * math.log(n) + b_top)
btm = math.exp(a_btm * math.log(n) + b_btm)
if 100 * ((high - btm) / (top - btm)) > 90
if peaks_x.last() == lastHi
peaks_y .push(math.log(max))
peaks_x .push(math.log(n))
peaks_x2.push(math.log(n)
*math.log(n))
else
peaks_y .set(-1, math.log(max))
peaks_x .set(-1, math.log(n))
peaks_x2.set(-1, math.log(n)
* math.log(n))
arr.set(0, a_top), arr.set(1, b_top)
arr.set(2, a_btm), arr.set(3, b_btm)
refit := true
proActH := true
if 100 * ((low - btm) / (top - btm)) < 10
if btms_x.last() == lastLi
btms_y .push(math.log(min))
btms_x .push(math.log(n))
btms_x2.push(math.log(n)
*math.log(n))
else
btms_y .set(-1, math.log(min))
btms_x .set(-1, math.log(n))
btms_x2.set(-1, math.log(n)
* math.log(n))
arr.set(0, a_top), arr.set(1, b_top)
arr.set(2, a_btm), arr.set(3, b_btm)
refit := true
proActL := true
enough = peaks_x.size() > 1 and btms_x.size() > 1
if enough
draw(peaks_x, peaks_x2, peaks_y, btms_x, btms_x2, btms_y, top_points, prc_points, btm_points, refit)
else
if barstate.islast
txt = ''
if peaks_x.size() < 2
txt += str.format('{0} Top Swing', peaks_x.size())
if btms_x .size() < 2
if txt != ''
txt += ', '
txt += str.format('{0} Bottom Swing', btms_x .size())
txt += '\nChange "Threshold" or timeframe\nfor more Swings'
tb.cell(0, 0, txt, text_color=chart.fg_color, text_size=txtSize)
________________________________________________________________________________________________________________________ :='
⎞ Plot ⎛
(__----__) '
plot(n%2==0? 30 : na,'30' , color=color.new(chart.fg_color, 50), style=plot.style_linebr, display=display.pane)
plot(n%2==0? 70 : na,'70' , color=color.new(chart.fg_color, 50), style=plot.style_linebr, display=display.pane)
_100 = plot(100, 'na(100)', display=display.none)
_70 = plot( 70, 'na(70)' , display=display.none)
_60 = plot( 60, 'na(60)' , display=display.none)
_50 = plot( 50, 'na(50)' , display=display.none)
_40 = plot( 40, 'na(40)' , display=display.none)
_30 = plot( 30, 'na(30)' , display=display.none)
_00 = plot( 0, 'na(0)' , display=display.none)
fill(_100, _70, 100, 70, color.new(RED, 50), INV)
fill( _60, _50, 60, 50, INV, color.new(chart.fg_color, 85))
fill( _50, _40, 50, 40, color.new(chart.fg_color, 85), INV)
fill( _30, _00, 30, 0, INV, color.new(GRE, 75))
________________________________________________________________________________________________________________________ :='
⎞ End ⎛
(__---__) '
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org/MPL/2.0/
// © fikira
//version=6
indicator('Log Regression Oscillator', max_bars_back=5000, max_labels_count=500, max_lines_count=500, overlay=false)
________________________________________________________________________________________________________________________ ='
⎞ Settings ⎛
(__--------__) '
cGREEN = #089981, cRED = #F23645, cGRAY = #757a79
threshold = input.int (300 , minval=150)
proactive = input.bool (false )
GRE = input.color(cGREEN , 'Bull' , group='Style' )
RED = input.color(cRED , 'Bear' , group='Style' )
GRY = input.color(cGRAY , 'Unconfirmed Bull/Bear' , group='Style' )
showDsh = input.bool ( true , 'Show Dashboard' , group='Dashboard' )
dshLoc = str.replace(str.lower(input.string('Top Right', 'Location', group='Dashboard', options=['Top Right', 'Bottom Right', 'Bottom Left'])), ' ', '_')
txtSize = str.lower(input.string('Normal' , 'Size' , group='Dashboard', options=['Tiny', 'Small', 'Normal', 'Large', 'Huge']) )
________________________________________________________________________________________________________________________ :='
⎞ Constants and general variables ⎛
(__-------------------------------__) '
INV = color(na)
n = bar_index
________________________________________________________________________________________________________________________ :='
⎞ Functions ⎛
(__---------__) '
dot(x, y)=>
if x.size() > 1 and y.size() > 1
m1 = matrix.new<float>()
m2 = matrix.new<float>()
m1.add_col(m1.columns(), y)
m2.add_row(m2.rows (), x)
m1.mult (m2)
.eigenvalues()
.sum()
//Closed form solution to best fit log function
log_reg(log_x, log_x2, log_y) =>
sum_log_x = log_x . sum()
sum_y = log_y . sum()
sum_log_x_y = dot(log_x ,log_y)
sum_log_x_sq = log_x2 . sum()
n_ = log_x .size()
//Closed-form solutions for a and b
a = (n_ * sum_log_x_y - sum_log_x * sum_y)
/ (n_ * sum_log_x_sq - math.pow(sum_log_x , 2))
b = ( sum_y - a * sum_log_x ) / n_
[a, b]
//Variables declared for draw()
var array<float>arr = array.new<float>(4, na)
proActH = false, proActL = false
var lastHi = 0., var lastLi = 0.
draw(aTop_x, aTop_x2, aTop_y, aBot_x, aBot_x2, aBot_y, top_points, prc_points, btm_points, refit) =>
var label labH = na, var label labL = na
vTop = 0.
vBtm = 0.
if refit
top_points.clear(), prc_points.clear(), btm_points.clear()
[a_top, b_top] = log_reg(aTop_x, aTop_x2, aTop_y), arr.set(0, a_top), arr.set(1, b_top)
[a_btm, b_btm] = log_reg(aBot_x, aBot_x2, aBot_y), arr.set(2, a_btm), arr.set(3, b_btm)
for i = 0 to n
top = math.exp(a_top * math.log(i) + b_top)
btm = math.exp(a_btm * math.log(i) + b_btm)
avg = math.avg(top, btm)
if i == n
vTop := top
vBtm := btm
ix = n - i
if ix < 4999
hi = high [ix]
lo = low [ix]
cl = close[ix]
getC = hi > avg ? hi : lo < avg ? lo : cl
prc_points.push(chart.point.from_index(i, 100 * math.max(-1.5, math.min(1.5, (getC - btm) / (top - btm)))))
for lab in label.all
lab.delete()
firstH = proactive ? true : false
firstL = proactive ? true : false
color colH = na, color colL = na
sz = prc_points.size()
if aTop_x.size() > 0
for i = aTop_x.size() -1 to 0
idx = int(math.exp(aTop_x.get(i)))
if idx < sz and idx > n - 5000 and idx >= 0
if firstH
if aTop_x.last() != lastHi
colH := GRY
firstH := false
else
colH := RED
else
colH := RED
top = math.exp(a_top * math.log(idx) + b_top)
btm = math.exp(a_btm * math.log(idx) + b_btm)
label.new(idx , 100 *
math.max(-1.5, math.min(1.5, (high[n-idx] - btm)
/ (top - btm)
) ), '●', textcolor = colH, color=INV, size=8)
if aBot_x.size() > 0
for i = aBot_x.size() -1 to 0
idx = int(math.exp(aBot_x.get(i)))
if idx < sz and idx > n - 5000 and idx >= 0
if firstL
if aBot_x.last() != lastLi
colL := GRY
firstL := false
else
colL := GRE
else
colL := GRE
top = math.exp(a_top * math.log(idx) + b_top)
btm = math.exp(a_btm * math.log(idx) + b_btm)
label.new(idx , 100 *
math.max(-1.5, math.min(1.5, (low [n-idx] - btm)
/ (top - btm)
) ), '●', textcolor = colL, color=INV, size=8
, style = label.style_label_up)
else
top = math.exp(arr.get(0) * math.log(n) + arr.get(1))
btm = math.exp(arr.get(2) * math.log(n) + arr.get(3))
avg = math.avg(top, btm)
vTop := top
vBtm := btm
hi = high, lo = low, cl = close
getC = hi > avg ? hi : lo < avg ? lo : cl
prc_points.push(chart.point.from_index(n, 100 * math.max(-1.5, math.min(1.5, (getC - btm) / (top - btm)))))
for poly in polyline.all
poly.delete()
if barstate.islast
labH.delete(), labH := label.new(n, 100, str.tostring(vTop, format.mintick), color=color.new(chart.fg_color, 85), textcolor=RED, style=label.style_label_lower_left, size=12)
labL.delete(), labL := label.new(n, 0, str.tostring(vBtm, format.mintick), color=color.new(chart.fg_color, 85), textcolor=GRE, style=label.style_label_upper_left, size=12)
polyline.new(prc_points.size() >= 5000 ? prc_points.slice(prc_points.size()-4999, prc_points.size()-1) : prc_points, line_color=chart.fg_color)
________________________________________________________________________________________________________________________ :='
⎞ Variables ⎛
(__---------__) '
//bool trigerring fit
refit = false
var top_points = array.new<chart.point>(0)
var prc_points = array.new<chart.point>(0)
var btm_points = array.new<chart.point>(0)
//Variables arrays
var peaks_y = array.new<float>(0)
var peaks_x = array.new<float>(0)
var peaks_x2 = array.new<float>(0)
var btms_y = array.new<float>(0)
var btms_x = array.new<float>(0)
var btms_x2 = array.new<float>(0)
var tb = table.new(dshLoc, 4, 8
, bgcolor = #1e222d
, border_color = #373a46
, border_width = 1
, frame_color = #373a46
, frame_width = 1)
________________________________________________________________________________________________________________________ :='
⎞ Exec ⎛
(__----__) '
//Top Bottom detection
max = ta.max(high)
var min = low
min := max == high ? low
: math.min(low , min)
barsmax = ta.barssince(high == max)
barsmin = ta.barssince(low == min)
if barsmax == threshold
nmax = n-barsmax
if peaks_x .size() > 0 and peaks_x.last() != lastHi
peaks_y .set(-1, math.log( max) )
peaks_x .set(-1, math.log(nmax) )
peaks_x2.set(-1, math.pow(math.log(nmax), 2))
else
peaks_y .push( math.log(max) )
peaks_x .push( math.log(nmax) )
peaks_x2.push( math.pow(math.log(nmax), 2))
lastHi := math.log(nmax)
refit := true
else
min := math.min(low , min)
if barsmin == threshold
nmin = n-barsmin
if btms_x .size() > 0 and btms_x.last() != lastLi
btms_y .set(-1, math.log(min) )
btms_x .set(-1, math.log(nmin) )
btms_x2 .set(-1, math.pow(math.log(nmin), 2))
else
btms_y .push( math.log( min) )
btms_x .push( math.log(nmin) )
btms_x2.push( math.pow(math.log(nmin), 2))
lastLi := math.log(nmin)
refit := true
chMax = ta.change(max) , chMin = ta.change(min)
if (chMax != 0 or chMin != 0) and proactive and not refit and n > threshold
[a_top, b_top] = log_reg(peaks_x, peaks_x2, peaks_y)
[a_btm, b_btm] = log_reg( btms_x, btms_x2, btms_y)
top = math.exp(a_top * math.log(n) + b_top)
btm = math.exp(a_btm * math.log(n) + b_btm)
if 100 * ((high - btm) / (top - btm)) > 90
if peaks_x.last() == lastHi
peaks_y .push(math.log(max))
peaks_x .push(math.log(n))
peaks_x2.push(math.log(n)
*math.log(n))
else
peaks_y .set(-1, math.log(max))
peaks_x .set(-1, math.log(n))
peaks_x2.set(-1, math.log(n)
* math.log(n))
arr.set(0, a_top), arr.set(1, b_top)
arr.set(2, a_btm), arr.set(3, b_btm)
refit := true
proActH := true
if 100 * ((low - btm) / (top - btm)) < 10
if btms_x.last() == lastLi
btms_y .push(math.log(min))
btms_x .push(math.log(n))
btms_x2.push(math.log(n)
*math.log(n))
else
btms_y .set(-1, math.log(min))
btms_x .set(-1, math.log(n))
btms_x2.set(-1, math.log(n)
* math.log(n))
arr.set(0, a_top), arr.set(1, b_top)
arr.set(2, a_btm), arr.set(3, b_btm)
refit := true
proActL := true
enough = peaks_x.size() > 1 and btms_x.size() > 1
if enough
draw(peaks_x, peaks_x2, peaks_y, btms_x, btms_x2, btms_y, top_points, prc_points, btm_points, refit)
else
if barstate.islast
txt = ''
if peaks_x.size() < 2
txt += str.format('{0} Top Swing', peaks_x.size())
if btms_x .size() < 2
if txt != ''
txt += ', '
txt += str.format('{0} Bottom Swing', btms_x .size())
txt += '\nChange "Threshold" or timeframe\nfor more Swings'
tb.cell(0, 0, txt, text_color=chart.fg_color, text_size=txtSize)
________________________________________________________________________________________________________________________ :='
⎞ Plot ⎛
(__----__) '
plot(n%2==0? 30 : na,'30' , color=color.new(chart.fg_color, 50), style=plot.style_linebr, display=display.pane)
plot(n%2==0? 70 : na,'70' , color=color.new(chart.fg_color, 50), style=plot.style_linebr, display=display.pane)
_100 = plot(100, 'na(100)', display=display.none)
_70 = plot( 70, 'na(70)' , display=display.none)
_60 = plot( 60, 'na(60)' , display=display.none)
_50 = plot( 50, 'na(50)' , display=display.none)
_40 = plot( 40, 'na(40)' , display=display.none)
_30 = plot( 30, 'na(30)' , display=display.none)
_00 = plot( 0, 'na(0)' , display=display.none)
fill(_100, _70, 100, 70, color.new(RED, 50), INV)
fill( _60, _50, 60, 50, INV, color.new(chart.fg_color, 85))
fill( _50, _40, 50, 40, color.new(chart.fg_color, 85), INV)
fill( _30, _00, 30, 0, INV, color.new(GRE, 75))
________________________________________________________________________________________________________________________ :='
⎞ End ⎛
(__---__) '
Script open-source
In pieno spirito TradingView, il creatore di questo script lo ha reso open-source, in modo che i trader possano esaminarlo e verificarne la funzionalità. Complimenti all'autore! Sebbene sia possibile utilizzarlo gratuitamente, ricorda che la ripubblicazione del codice è soggetta al nostro Regolamento.
Declinazione di responsabilità
Le informazioni ed i contenuti pubblicati non costituiscono in alcun modo una sollecitazione ad investire o ad operare nei mercati finanziari. Non sono inoltre fornite o supportate da TradingView. Maggiori dettagli nelle Condizioni d'uso.
Script open-source
In pieno spirito TradingView, il creatore di questo script lo ha reso open-source, in modo che i trader possano esaminarlo e verificarne la funzionalità. Complimenti all'autore! Sebbene sia possibile utilizzarlo gratuitamente, ricorda che la ripubblicazione del codice è soggetta al nostro Regolamento.
Declinazione di responsabilità
Le informazioni ed i contenuti pubblicati non costituiscono in alcun modo una sollecitazione ad investire o ad operare nei mercati finanziari. Non sono inoltre fornite o supportate da TradingView. Maggiori dettagli nelle Condizioni d'uso.