Ads Top

Supertrend BOS CHoCH Divergence Oscillator

Built by Grok 
Working?


//@version=6
//indicator("Gold Sell Oscillator Advanced ML with Supertrend, BOS, CHoCH & Divergence", shorttitle="GSO ML SBCD", overlay=false)

// === Inputs ===
// Oscillator Settings
rsiPeriod = input.int(14, "RSI Period", minval=1, group="Oscillator Settings")
rsiOverbought = input.int(70, "RSI Overbought Level", minval=50, maxval=100, group="Oscillator Settings")
macdFast = input.int(12, "MACD Fast", minval=1, group="Oscillator Settings")
macdSlow = input.int(26, "MACD Slow", minval=1, group="Oscillator Settings")
macdSignal = input.int(9, "MACD Signal", minval=1, group="Oscillator Settings")
bbPeriod = input.int(20, "Bollinger Period", minval=1, group="Oscillator Settings")
bbDev = input.float(2.5, "Bollinger Deviation", minval=0.1, step=0.1, group="Oscillator Settings")
volPeriod = input.int(20, "Volume MA Period", minval=1, group="Oscillator Settings")
adxPeriod = input.int(14, "ADX Period", minval=1, group="Oscillator Settings")
smoothingPeriod = input.int(5, "Smoothing Period", minval=1, group="Oscillator Settings")

// ML Settings
lookback = input.int(100, "ML Lookback Period", minval=10, group="ML Settings")
neighbors = input.int(7, "Number of Neighbors", minval=1, maxval=15, group="ML Settings")

// Supertrend Settings
supertrend_period = input.int(10, "Supertrend Period", minval=1, group="Supertrend Settings")
supertrend_factor = input.float(3.0, "Supertrend Factor", minval=0.1, step=0.1, group="Supertrend Settings")
use_supertrend_filter = input.bool(true, "Use Supertrend Filter", group="Supertrend Settings")

// BOS & CHoCH Settings
structure_length = input.int(20, "Structure Lookback", minval=2, group="BOS & CHoCH Settings")
structure_sensitivity = input.float(1.0, "Structure Sensitivity", minval=0.1, step=0.1, group="BOS & CHoCH Settings")

// Divergence Settings
divergence_lookback = input.int(5, "Divergence Lookback", minval=1, group="Divergence Settings")
divergence_enabled = input.bool(true, "Enable Divergence", group="Divergence Settings")

// Levels & Visuals
overbought_level = input.float(70, "Overbought Level", minval=0, maxval=100, group="Levels")
oversold_level = input.float(30, "Oversold Level", minval=0, maxval=100, group="Levels")
show_signals = input.bool(true, "Show Signals", group="Visual Settings")
show_supertrend = input.bool(true, "Show Supertrend Direction", group="Visual Settings")

// === Calculations ===
// Technical Indicators
rsi = ta.rsi(close, rsiPeriod)
[macdLine, signalLine, _] = ta.macd(close, macdFast, macdSlow, macdSignal)
[bbUpper, bbMiddle, bbLower] = ta.bb(close, bbPeriod, bbDev)
volMA = ta.sma(volume, volPeriod)

// ADX Calculation
plusDM = math.max(high - high[1], 0)
minusDM = math.max(low[1] - low, 0)
tr = ta.tr(true)
plusDI = 100 * ta.rma(plusDM, adxPeriod) / ta.rma(tr, adxPeriod)
minusDI = 100 * ta.rma(minusDM, adxPeriod) / ta.rma(tr, adxPeriod)
dx = 100 * math.abs(plusDI - minusDI) / math.max(plusDI + minusDI, 0.0001)
adxValue = ta.rma(dx, adxPeriod)

// Supertrend
[supertrend_line, supertrend_dir_raw] = ta.supertrend(supertrend_factor, supertrend_period)
supertrend_dir = supertrend_dir_raw < 0 ? 1 : -1  // 1 for uptrend, -1 for downtrend

// Normalized Features
currentRsi = (rsi - 50) / 50
currentPricePos = bbUpper != bbLower ? (close - bbMiddle) / (bbUpper - bbLower) : 0.0
currentMacdDiff = close != 0 ? (macdLine - signalLine) / math.abs(close * 0.01) : 0.0
currentVolRatio = volMA != 0 ? volume / volMA : 1.0
currentAdx = (adxValue - 25) / 25

// Historical Data Arrays
var float[] pastReturns = array.new_float(lookback)
var float[] pastRsi = array.new_float(lookback)
var float[] pastPricePos = array.new_float(lookback)
var float[] pastMacdDiff = array.new_float(lookback)
var float[] pastVolRatio = array.new_float(lookback)
var float[] pastAdx = array.new_float(lookback)

// Update Historical Data
for i = 0 to lookback - 2
    if i == 0
        prevClose = close[2]
        returnValue = prevClose != 0 ? (close[1] - prevClose) / prevClose : 0.0
        array.set(pastReturns, i, returnValue)
        array.set(pastRsi, i, (rsi[1] - 50) / 50)
        bbRange = bbUpper[1] - bbLower[1]
        array.set(pastPricePos, i, bbRange != 0 ? (close[1] - bbMiddle[1]) / bbRange : 0.0)
        array.set(pastMacdDiff, i, close[1] != 0 ? (macdLine[1] - signalLine[1]) / math.abs(close[1] * 0.01) : 0.0)
        array.set(pastVolRatio, i, volMA[1] != 0 ? volume[1] / volMA[1] : 1.0)
        array.set(pastAdx, i, (adxValue[1] - 25) / 25)
    else
        array.set(pastReturns, i, array.get(pastReturns, i-1))
        array.set(pastRsi, i, array.get(pastRsi, i-1))
        array.set(pastPricePos, i, array.get(pastPricePos, i-1))
        array.set(pastMacdDiff, i, array.get(pastMacdDiff, i-1))
        array.set(pastVolRatio, i, array.get(pastVolRatio, i-1))
        array.set(pastAdx, i, array.get(pastAdx, i-1))

// Weighted Distance Calculation
var float[] distances = array.new_float(lookback)
for i = 0 to lookback - 1
    rsiW = 0.3
    priceW = 0.25
    macdW = 0.2
    volW = 0.15
    adxW = 0.1
    rsiDiff = math.pow(currentRsi - array.get(pastRsi, i), 2) * rsiW
    priceDiff = math.pow(currentPricePos - array.get(pastPricePos, i), 2) * priceW
    macdDiff = math.pow(currentMacdDiff - array.get(pastMacdDiff, i), 2) * macdW
    volDiff = math.pow(currentVolRatio - array.get(pastVolRatio, i), 2) * volW
    adxDiff = math.pow(currentAdx - array.get(pastAdx, i), 2) * adxW
    totalDistance = math.sqrt(rsiDiff + priceDiff + macdDiff + volDiff + adxDiff)
    array.set(distances, i, totalDistance)

// k-Nearest Neighbors
sortedDistances = array.copy(distances)
array.sort(sortedDistances)
kNearestReturns = array.new_float(neighbors)
kNearestOutcomes = array.new_float(neighbors)
for i = 0 to neighbors - 1
    idx = array.indexof(distances, array.get(sortedDistances, i))
    array.set(kNearestReturns, i, array.get(pastReturns, idx))
    array.set(kNearestOutcomes, i, array.get(pastReturns, idx) < 0 ? 1.0 : 0.0)

// ML Sell Probability
mlSellProb = array.sum(kNearestOutcomes) / neighbors

// Base Technical Conditions
rsiScore = rsi >= rsiOverbought ? 1.0 : math.max(0, (rsi - 30) / (rsiOverbought - 30))
bbScore = close >= bbUpper ? 1.0 : math.max(0, (close - bbMiddle) / (bbUpper - bbMiddle))
volScore = volume > volMA * 2 ? 1.0 : math.max(0, (volume - volMA) / (volMA * 2))
macdScore = macdLine < signalLine ? 1.0 : math.max(0, (signalLine - macdLine) / math.abs(close * 0.01))

// Oscillator Calculation
oscRaw = (rsiScore * 25) + (bbScore * 25) + (volScore * 20) + (macdScore * 20) + (mlSellProb * 10)
oscillator = ta.sma(oscRaw, smoothingPeriod)

// BOS Detection
swing_high = ta.highest(high, structure_length)
swing_low = ta.lowest(low, structure_length)
prev_swing_high = ta.highest(high[1], structure_length)
prev_swing_low = ta.lowest(low[1], structure_length)
bull_bos = high > prev_swing_high and oscillator < overbought_level
bear_bos = low < prev_swing_low and oscillator > oversold_level

// CHoCH Detection
bull_choch = low < prev_swing_low and oscillator > ta.lowest(oscillator, structure_length) * (1.0 + structure_sensitivity * 0.01)
bear_choch = high > prev_swing_high and oscillator < ta.highest(oscillator, structure_length) * (1.0 - structure_sensitivity * 0.01)

// Divergence Detection
price_high = ta.highest(close, divergence_lookback)
price_low = ta.lowest(close, divergence_lookback)
osc_high = ta.highest(oscillator, divergence_lookback)
osc_low = ta.lowest(oscillator, divergence_lookback)
bull_div = divergence_enabled and price_low < ta.lowest(close[divergence_lookback], divergence_lookback) and osc_low > ta.lowest(oscillator[divergence_lookback], divergence_lookback)
bear_div = divergence_enabled and price_high > ta.highest(close[divergence_lookback], divergence_lookback) and osc_high < ta.highest(oscillator[divergence_lookback], divergence_lookback)

// Signals with Supertrend Filter
bull_signal_raw = oscillator < oversold_level and rsi < 30
bear_signal_raw = oscillator > overbought_level and rsi > rsiOverbought
bull_signal = bull_signal_raw and (not use_supertrend_filter or supertrend_dir > 0)
bear_signal = bear_signal_raw and (not use_supertrend_filter or supertrend_dir < 0)

// Combined Signals
final_bull = bull_signal or bull_bos or bull_choch or bull_div
final_bear = bear_signal or bear_bos or bear_choch or bear_div

// === Visualization ===
hline(overbought_level, "Overbought", color=color.gray, linestyle=hline.style_dashed)
hline(oversold_level, "Oversold", color=color.gray, linestyle=hline.style_dashed)
bgcolor(oscillator > overbought_level ? color.new(color.red, 90) : na)
bgcolor(oscillator < oversold_level ? color.new(color.green, 90) : na)

plot(oscillator, "Oscillator", color=color.red, linewidth=2)
plot(show_supertrend ? supertrend_dir * 50 : na, "Supertrend Direction", style=plot.style_histogram, color=color.gray, linewidth=2)

// Moved plotshape to global scope
plotshape(show_signals and bull_signal ? bull_signal : na, "Buy", shape.triangleup, location.bottom, color.green, size=size.tiny)
plotshape(show_signals and bear_signal ? bear_signal : na, "Sell", shape.triangledown, location.top, color.red, size=size.tiny)
plotshape(show_signals and bull_bos ? bull_bos : na, "Bull BOS", shape.diamond, location.bottom, color.lime, size=size.tiny)
plotshape(show_signals and bear_bos ? bear_bos : na, "Bear BOS", shape.diamond, location.top, color.maroon, size=size.tiny)
plotshape(show_signals and bull_choch ? bull_choch : na, "Bull CHoCH", shape.circle, location.bottom, color.teal, size=size.tiny)
plotshape(show_signals and bear_choch ? bear_choch : na, "Bear CHoCH", shape.circle, location.top, color.purple, size=size.tiny)
plotshape(show_signals and bull_div ? bull_div : na, "Bull Div", shape.cross, location.bottom, color.yellow, size=size.tiny)
plotshape(show_signals and bear_div ? bear_div : na, "Bear Div", shape.cross, location.top, color.pink, size=size.tiny)

// === Alerts ===
alertcondition(bull_signal, "Buy Signal", "Gold Oscillator Buy Opportunity")
alertcondition(bear_signal, "Sell Signal", "Gold Oscillator Sell Opportunity")
alertcondition(bull_bos, "Bullish BOS", "Break of Structure Up")
alertcondition(bear_bos, "Bearish BOS", "Break of Structure Down")
alertcondition(bull_choch, "Bullish CHoCH", "Change of Character Up")
alertcondition(bear_choch, "Bearish CHoCH", "Change of Character Down")
alertcondition(bull_div and divergence_enabled, "Bullish Divergence", "Bullish Divergence Detected")
alertcondition(bear_div and divergence_enabled, "Bearish Divergence", "Bearish Divergence Detected")
alertcondition(supertrend_dir > 0 and supertrend_dir[1] <= 0, "Supertrend Up", "Supertrend Turned Bullish")
alertcondition(supertrend_dir < 0 and supertrend_dir[1] >= 0, "Supertrend Down", "Supertrend Turned Bearish")
alertcondition(oscillator > overbought_level, "Overbought", "Gold Sell Oscillator Overbought")

No comments:

Powered by Blogger.