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 ⎛
(__---__) '
Skrip sumber terbuka
Dalam semangat sebenar TradingView, pencipta skrip ini telah menjadikannya sumber terbuka supaya pedagang dapat menilai dan mengesahkan kefungsiannya. Terima kasih kepada penulis! Walaupun anda boleh menggunakannya secara percuma, ingat bahawa menerbitkan semula kod ini adalah tertakluk kepada Peraturan Dalaman kami.
Penafian
Maklumat dan penerbitan adalah tidak dimaksudkan untuk menjadi, dan tidak membentuk, nasihat untuk kewangan, pelaburan, perdagangan dan jenis-jenis lain atau cadangan yang dibekalkan atau disahkan oleh TradingView. Baca dengan lebih lanjut di Terma Penggunaan.
Skrip sumber terbuka
Dalam semangat sebenar TradingView, pencipta skrip ini telah menjadikannya sumber terbuka supaya pedagang dapat menilai dan mengesahkan kefungsiannya. Terima kasih kepada penulis! Walaupun anda boleh menggunakannya secara percuma, ingat bahawa menerbitkan semula kod ini adalah tertakluk kepada Peraturan Dalaman kami.
Penafian
Maklumat dan penerbitan adalah tidak dimaksudkan untuk menjadi, dan tidak membentuk, nasihat untuk kewangan, pelaburan, perdagangan dan jenis-jenis lain atau cadangan yang dibekalkan atau disahkan oleh TradingView. Baca dengan lebih lanjut di Terma Penggunaan.