AI SuperTrend Clustering Oscillator [LuxAlgo]

LuxAlgo · study · 152 行 · 点赞 3,137 · TradingView 原页

本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。

Pine Script

// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © LuxAlgo
 
//@version=5
indicator("AI SuperTrend Clustering Oscillator [LuxAlgo]", "LuxAlgo - AI SuperTrend Clustering Oscillator")
//------------------------------------------------------------------------------
//Settings
//-----------------------------------------------------------------------------{
length = input(10, 'ATR Length')
 
minMult = input.int(1, 'Factor Range', minval = 0, inline = 'factor')
maxMult = input.int(5, '', minval = 0, inline = 'factor')
step    = input.float(.5, 'Step', minval = 0, step = 0.1)
smooth = input.float(1, minval = 1)
 
//Trigger error
if minMult > maxMult
    runtime.error('Minimum factor is greater than maximum factor in the range')
 
//Optimization
maxIter = input.int(1000, 'Maximum Iteration Steps', minval = 0, group = 'Optimization')
maxData = input.int(10000, 'Historical Bars Calculation', minval = 0, group = 'Optimization')
 
//Style
bullCss = input(color.new(#5b9cf6, 50), 'Bullish', inline = 'bull', group = 'Style')
strongBullCss = input(color.new(#5b9cf6, 28), 'Strong', inline = 'bull', group = 'Style')
 
neutCss = input(#9598a1, 'Neutral', inline = 'neut', group = 'Style')
 
bearCss = input(color.new(#f77c80, 50), 'Bearish', inline = 'bear', group = 'Style')
strongBearCss = input(color.new(#f77c80, 28), 'Strong', inline = 'bear', group = 'Style')
 
//-----------------------------------------------------------------------------}
//UDT's
//-----------------------------------------------------------------------------{
type supertrend
    float upper = hl2
    float lower = hl2
    float output
    int trend
 
type vector
    array<float> out
 
//-----------------------------------------------------------------------------}
//Supertrend
//-----------------------------------------------------------------------------{
var holder = array.new<supertrend>(0)
var factors = array.new<float>(0)
 
//Populate supertrend type array
if barstate.isfirst
    for i = 0 to int((maxMult - minMult) / step)
        factors.push(minMult + i * step)
        holder.push(supertrend.new())
 
atr = ta.atr(length)
 
//Compute Supertrend for multiple factors
k = 0
for factor in factors
    get_spt = holder.get(k)
 
    up = hl2 + atr * factor
    dn = hl2 - atr * factor
    
    get_spt.upper := close[1] < get_spt.upper ? math.min(up, get_spt.upper) : up
    get_spt.lower := close[1] > get_spt.lower ? math.max(dn, get_spt.lower) : dn
    get_spt.trend := close > get_spt.upper ? 1 : close < get_spt.lower ? 0 : get_spt.trend
    get_spt.output := get_spt.trend == 1 ? get_spt.lower : get_spt.upper
    k += 1
 
//-----------------------------------------------------------------------------}
//K-means clustering
//-----------------------------------------------------------------------------{
data = array.new<float>(0)
 
//Populate data arrays
if last_bar_index - bar_index <= maxData
    for element in holder
        data.push(close - element.output)
 
//Intitalize centroids using quartiles
centroids = array.new<float>(0)
centroids.push(data.percentile_linear_interpolation(25))
centroids.push(data.percentile_linear_interpolation(50))
centroids.push(data.percentile_linear_interpolation(75))
 
//Intialize clusters
var array<vector> clusters = na
 
if last_bar_index - bar_index <= maxData
    for _ = 0 to maxIter
        clusters := array.from(vector.new(array.new<float>(0)), vector.new(array.new<float>(0)), vector.new(array.new<float>(0)))
        
        //Assign value to cluster
        for value in data
            dist = array.new<float>(0)
            for centroid in centroids
                dist.push(math.abs(value - centroid))
 
            idx = dist.indexof(dist.min())
            if idx != -1
                clusters.get(idx).out.push(value)
            
        //Update centroids
        new_centroids = array.new<float>(0)
        for cluster_ in clusters
            new_centroids.push(cluster_.out.avg())
 
        //Test if centroid changed
        if new_centroids.get(0) == centroids.get(0) and new_centroids.get(1) == centroids.get(1) and new_centroids.get(2) == centroids.get(2)
            break
 
        centroids := new_centroids
 
//-----------------------------------------------------------------------------}
//Get centroids
//-----------------------------------------------------------------------------{
//Get associated supertrend
var float bull = 0
var float neut = 0
var float bear = 0
var den = 0
 
if not na(clusters)
    bull += 2/(smooth+1) * nz(centroids.get(2) - bull)
    neut += 2/(smooth+1) * nz(centroids.get(1) - neut)
    bear += 2/(smooth+1) * nz(centroids.get(0) - bear)
    den += 1
 
//-----------------------------------------------------------------------------}
//Plots
//-----------------------------------------------------------------------------{
plot_bull = plot(math.max(bull, 0), color = na, editable = false)
plot_bull_ext = plot(math.max(bear, 0), 'Strong Bullish'
  , bear > 0 ? strongBullCss : na
  , style = plot.style_circles)
 
plot_bear = plot(math.min(bear, 0), color = na, editable = false)
plot_bear_ext = plot(math.min(bull, 0), 'Strong Bearish'
  , bull < 0 ? strongBearCss : na
  , style = plot.style_circles)
 
plot(neut, 'Consensus', neutCss)
 
fill(plot_bull, plot_bull_ext, bull, math.max(bear, 0), bullCss, color.new(chart.bg_color, 100))
fill(plot_bear_ext, plot_bear, math.min(bull, 0), bear, color.new(chart.bg_color, 100), bearCss)
 
hline(0, linestyle = hline.style_solid)
 
//-----------------------------------------------------------------------------}

← 返回列表