Strategy · Pine Script v5 · On the chart

AI Volume Supertrend Strategy

by veo555· code credited to PresentTrading

This overlay strategy combines a Supertrend with a k-nearest-neighbors filter.

View on GitHub

GitHub stars4on the repository
Pine versionv5runs as is
Lines of code243
Settings14inputs
LicenceNone statedfile: MPL-2.0
Last update2 years ago23 Nov 2023

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

243 lines of Pine Script v5 from data/2.txt, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

2.txt
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © PresentTrading

//@version=5
strategy("AI Volume Supertrend - Strategy [presentTrading]", overlay=true, precision=3, default_qty_type=strategy.cash, 
 commission_value= 0.1, commission_type=strategy.commission.percent, slippage= 1, 
  currency=currency.USD, default_qty_type = strategy.percent_of_equity, default_qty_value = 10, initial_capital= 10000)

// ~~ ToolTips {
t1="Number of nearest neighbors in KNN algorithm (k): Increase to consider more neighbors, providing a more balanced view but possibly smoothing out local patterns. Decrease for fewer neighbors to make the algorithm more responsive to recent changes. \n\nNumber of data points to consider (n): Increase for more historical data, providing a broader context but possibly diluting recent trends. Decrease for less historical data to focus more on recent behavior."
t2="Length of weighted moving average for price (KNN_PriceLen): Higher values create a smoother price line, influencing the KNN algorithm to be more stable but less sensitive to short-term price movements. Lower values enhance responsiveness in KNN predictions to recent price changes but may lead to more noise. \n\nLength of weighted moving average for SuperTrend (KNN_STLen): Higher values lead to a smoother SuperTrend line, affecting the KNN algorithm to emphasize long-term trends. Lower values make KNN predictions more sensitive to recent SuperTrend changes but may result in more volatility."
t3="Length of the SuperTrend (len): Increase for a smoother trend line, ideal for identifying long-term trends but possibly ignoring short-term fluctuations. Decrease for more responsiveness to recent changes but risk of more false signals. \n\nMultiplier for ATR in SuperTrend calculation (factor): Increase for wider bands, capturing larger price movements but possibly missing subtle changes. Decrease for narrower bands, more sensitive to small shifts but risk of more noise."
t4="Type of moving average for SuperTrend calculation (maSrc): Choose based on desired characteristics. SMA is simple and clear, EMA emphasizes recent prices, WMA gives more weight to recent data, RMA is less sensitive to recent changes, and VWMA considers volume."
t5="Color for bullish trend (upCol): Select to visually identify upward trends. \n\nColor for bearish trend (dnCol): Select to visually identify downward trends.\n\nColor for neutral trend (neCol): Select to visually identify neutral trends."
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// Add Button for Trading Direction
tradeDirection = input.string("Both", "Select Trading Direction", options=["Long", "Short", "Both"])

// ~~ Input settings for K and N values
k  = input.int(3, title = "Neighbors", minval=1, maxval=100,inline="AI", group="AI Settings") 
n_ = input.int(10, title ="Data", minval=1, maxval=100,inline="AI", group="AI Settings", tooltip=t1) 
n  = math.max(k,n_)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}

// ~~ Input settings for prediction values
KNN_PriceLen = input.int(20, title="Price Trend", minval=2, maxval=500, step=10,inline="AITrend", group="AI Trend")
KNN_STLen    = input.int(100, title="Prediction Trend", minval=2, maxval=500, step=10, inline="AITrend", group="AI Trend", tooltip=t2)
aisignals    = input.bool(true,title="AI Trend Signals",inline="signal", group="AI Trend")
Bullish_col  = input.color(color.lime,"",inline="signal", group="AI Trend")
Bearish_col  = input.color(color.red,"",inline="signal", group="AI Trend")
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}

// ~~ Define SuperTrend parameters
len    = input.int(10, "Length", minval=1,inline="SuperTrend", group="Super Trend Settings") 
factor = input.float(3.0,step=.1,inline="SuperTrend", group="Super Trend Settings", tooltip=t3) 
maSrc  = input.string("WMA","Moving Average Source",["SMA","EMA","WMA","RMA","VWMA"],inline="", group="Super Trend Settings", tooltip=t4) 
upCol  = input.color(color.lime,"Bullish Color",inline="col", group="Super Trend Coloring") 
dnCol  = input.color(color.red,"Bearish Color",inline="col", group="Super Trend Coloring") 
neCol  = input.color(color.blue,"Neutral Color",inline="col", group="Super Trend Coloring", tooltip=t5) 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}

// ~~ Calculate the SuperTrend based on the user's choice
vwma = switch maSrc
    "SMA"  => ta.sma(close*volume, len) / ta.sma(volume, len)
    "EMA"  => ta.ema(close*volume, len) / ta.ema(volume, len)
    "WMA"  => ta.wma(close*volume, len) / ta.wma(volume, len)
    "RMA"  => ta.rma(close*volume, len) / ta.rma(volume, len)
    "VWMA" => ta.vwma(close*volume, len) / ta.vwma(volume, len)

atr = ta.atr(len)
upperBand = vwma + factor * atr
lowerBand = vwma - factor * atr
prevLowerBand = nz(lowerBand[1])
prevUpperBand = nz(upperBand[1])

lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
int direction = na
float superTrend = na
prevSuperTrend = superTrend[1]
if na(atr[1])
    direction := 1
else if prevSuperTrend == prevUpperBand
    direction := close > upperBand ? -1 : 1
else
    direction := close < lowerBand ? 1 : -1
superTrend := direction == -1 ? lowerBand : upperBand
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
// ~~ Collect data points and their corresponding labels
price  = ta.wma(close,KNN_PriceLen)
sT     = ta.wma(superTrend,KNN_STLen)
data   = array.new_float(n) 
labels = array.new_int(n) 
for i = 0 to n - 1
    data.set(i, superTrend[i]) 
    label_i = price[i] > sT[i] ? 1 : 0 
    labels.set(i, label_i) 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}

// ~~ Define a function to compute distance between two data points
distance(x1, x2) => 
    math.abs(x1 - x2)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}

// ~~ Define the weighted k-nearest neighbors (KNN) function
knn_weighted(data, labels, k, x) =>
    n1 = data.size() 
    distances = array.new_float(n1) 
    indices   = array.new_int(n1) 
    // Compute distances from the current point to all other points
    for i = 0 to n1 - 1 
        x_i = data.get(i)
        dist = distance(x, x_i) 
        distances.set(i, dist)
        indices.set(i, i)
    // Sort distances and corresponding indices in ascending order
    // Bubble sort method
    for i = 0 to n1 - 2
        for j = 0 to n1 - i - 2
            if distances.get(j) > distances.get(j + 1)
                tempDist = distances.get(j) 
                distances.set(j, distances.get(j + 1))
                distances.set(j + 1, tempDist)
                tempIndex = indices.get(j)
                indices.set(j, indices.get(j + 1))
                indices.set(j + 1, tempIndex)
    // Compute weighted sum of labels of the k nearest neighbors
    weighted_sum = 0.
    total_weight = 0.
    for i = 0 to k - 1
        index = indices.get(i)
        label_i = labels.get(index)
        weight_i = 1 / (distances.get(i) + 1e-6) 
        weighted_sum += weight_i * label_i
        total_weight += weight_i
    weighted_sum / total_weight 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}

// ~~ Classify the current data point
current_superTrend = superTrend
label_             = knn_weighted(data, labels, k, current_superTrend)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~} 
// ~~ Plot
col = label_ == 1?upCol:label_ == 0?dnCol:neCol
plot(current_superTrend, color=col, title="Volume Super Trend AI")

upTrend   = plot(superTrend==lowerBand?current_superTrend:na, title="Up Volume Super Trend AI", color=col, style=plot.style_linebr)
Middle    = plot((open + close) / 2, display=display.none, editable=false)
downTrend = plot(superTrend==upperBand?current_superTrend:na, title="Down Volume Super Trend AI", color=col, style=plot.style_linebr)
fill_col  = color.new(col,90)
fill(Middle, upTrend, fill_col, fillgaps=false,title="Up Volume Super Trend AI")
fill(Middle, downTrend, fill_col, fillgaps=false, title="Down Volume Super Trend AI")
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}

// ~~ Ai Super Trend Signals
Start_TrendUp = col==upCol and (col[1]!=upCol or col[1]==neCol) and aisignals
Start_TrendDn = col==dnCol and (col[1]!=dnCol or col[1]==neCol) and aisignals
TrendUp       = direction == -1 and direction[1] == 1  and label_ == 1 and aisignals
TrendDn       = direction == 1  and direction[1] ==-1  and label_ == 0 and aisignals

plotshape(Start_TrendUp?superTrend:na, location=location.absolute, style= shape.circle, size=size.tiny, color=Bullish_col, title="AI Bullish Trend Start")
plotshape(Start_TrendDn?superTrend:na, location=location.absolute, style= shape.circle,size=size.tiny, color=Bearish_col, title="AI Bearish Trend Start")
plotshape(TrendUp?superTrend:na, location=location.absolute, style= shape.triangleup, size=size.small, color=Bullish_col, title="AI Bullish Trend Signal")
plotshape(TrendDn?superTrend:na, location=location.absolute, style= shape.triangledown,size=size.small, color=Bearish_col, title="AI Bearish Trend Signal")
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}

// Trading Logic
longCondition = Start_TrendUp or TrendUp
shortCondition = Start_TrendDn or TrendDn
longExitCondition = false // Initialize
shortExitCondition = false // Initialize

// Trend Continuation Signals
// Note: You can refine these conditions based on your understanding of trend continuation signals.
if (direction == -1 and label_ == 1) // Bullish trend continues
    longExitCondition := false
else if (direction == 1 and label_ == 0) // Bearish trend continues
    shortExitCondition := false
else // Trend does not continue
    longExitCondition := true
    shortExitCondition := true

// Dynamic Trailing Stop Loss
longTrailingStop = superTrend - atr * factor
shortTrailingStop = superTrend + atr * factor

// Adjust Enter and Exit Conditions based on Trading Direction
if (tradeDirection == "Long" or tradeDirection == "Both")
    strategy.entry("Long", strategy.long, when=longCondition)
    strategy.exit("Exit Long", "Long", stop=longTrailingStop, when=longExitCondition)

if (tradeDirection == "Short" or tradeDirection == "Both")
    strategy.entry("Short", strategy.short, when=shortCondition)
    strategy.exit("Exit Short", "Short", stop=shortTrailingStop, when=shortExitCondition)

█ Introduction and How it is Different

The AI Supertrend Strategy is a unique hybrid approach that employs both traditional technical indicators and machine learning techniques. Unlike standard strategies that rely solely on traditional indicators or mathematical models, this strategy integrates the power of k-Nearest Neighbors (KNN), a machine learning algorithm, with the tried-and-true SuperTrend indicator. This blend aims to provide traders with more accurate, responsive, and context-aware trading signals.
*The KNN part is mainly referred from @Zeiierman.

BTCUSD 8hr performance
snapshot

ETHUSD 8hr performance
snapshot

█ Strategy, How it Works: Detailed Explanation

SuperTrend Calculation

Volume-Weighted Moving Average (VWMA): A VWMA of the close price is calculated based on the user-defined length (len). This serves as the central line around which the upper and lower bands are calculated.
Average True Range (ATR): ATR is calculated over a period defined by len. It measures the market's volatility.
Upper and Lower Bands: The upper band is calculated as VWMA + (factor * ATR) and the lower band as VWMA - (factor * ATR). The factor is a user-defined multiplier that decides how wide the bands should be.


KNN Algorithm

Data Collection: An array (data) is populated with recent n SuperTrend values. Corresponding labels (labels) are determined by whether the weighted moving average price (price) is greater than the weighted moving average of the SuperTrend (sT).
Distance Calculation: The absolute distance between each data point and the current SuperTrend value is calculated.
Sorting & Weighting: The distances are sorted in ascending order, and the closest k points are selected. Each point is weighted by the inverse of its distance to the current point.
Classification: A weighted sum of the labels of the k closest points is calculated. If the sum is closer to 1, the trend is predicted as bullish; if closer to 0, bearish.


Signal Generation

Start of Trend: A new bullish trend (Start_TrendUp) is considered to have started if the current trend color is bullish and the previous was not bullish. Similarly for bearish trends (Start_TrendDn).
Trend Continuation: A bullish trend (TrendUp) is considered to be continuing if the direction is negative and the KNN prediction is 1. Similarly for bearish trends (TrendDn).


Trading Logic

Long Condition: If Start_TrendUp or TrendUp is true, a long position is entered.
Short Condition: If Start_TrendDn or TrendDn is true, a short position is entered.
Exit Condition: Dynamic trailing stops are used for exits. If the trend does not continue as indicated by the KNN prediction and SuperTrend direction, an exit signal is generated.

The synergy between SuperTrend and KNN aims to filter out noise and produce more reliable trading signals. While SuperTrend provides a broad sense of the market direction, KNN refines this by predicting short-term price movements, leading to a more nuanced trading strategy.

Local picture
snapshot

█ Trade Direction

The strategy allows traders to choose between taking only long positions, only short positions, or both. This is particularly useful for adapting to different market conditions.

█ Usage

ToolTips: Explains what each parameter does and how to adjust them.
Inputs: Customize values like the number of neighbors in KNN, ATR multiplier, and moving average type.
Plotting: Visual cues on the chart to indicate bullish or bearish trends.
Order Execution: Based on the generated signals, the strategy will execute buy/sell orders.

█ Default Settings

The default settings are selected to provide a balanced approach, but they can be modified for different trading styles and asset classes.

Initial Capital: $10,000
Default Quantity Type: 10% of equity
Commission: 0.1%
Slippage: 1
Currency: USD


By combining both machine learning and traditional technical analysis, this strategy offers a sophisticated and adaptive trading solution.

Overview

AI Volume Supertrend Strategy smooths price and the Supertrend with weighted moving averages, then uses neighbor count and lookback length to form an AI trend signal. Traders can allow long, short, or both directions and toggle those signals. Supertrend length, ATR factor, and moving-average type change trend sensitivity; colors mark bullish, bearish, and neutral states on the price chart. Position size defaults to a percentage of equity. The provided excerpt ends before entry, exit, and stop rules.

Details

Published by

veo555 on GitHub

Code credit

PresentTrading, as written in the script's header

Type

Strategy, Pine Script v5

Draws

On the price chart

Category

Trend, Volatility & bands, AI / machine learning

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Select Trading DirectionstringBothtradeDirection
Neighborsint3k
Dataint10n_
Price Trendint20KNN_PriceLen
Prediction Trendint100KNN_STLen
AI Trend Signalsbooltrueaisignals
Bullish_colcolorcolor.limeBullish_col
Bearish_colcolorcolor.redBearish_col
Lengthint10len
factorfloat3.0factor
Moving Average SourcestringWMAmaSrc
Bullish Colorcolorcolor.limeupCol
Show all 14 settings
SettingTypeDefaultVariable
Bearish Colorcolorcolor.reddnCol
Neutral Colorcolorcolor.blueneCol
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

This strategy implements a single-layer perceptron machine learning model built from scratch to generate trading signals directly on the price chart. It calculates predictions based on sample size, threshold settings, and optional volatility or volume filters.

Strategy v5 AI / machine learningTrend
Updated 1 year ago · None stated GitHub repository of Machine Learning: Perceptron-Based Strategy [5] (v.3)

This strategy plots an ATR Chandelier trailing stop on the price chart and tracks a directional trend state. It marks confirmed flips, weak body-rejected flips, and wick traps, and colors bars as price nears warning or danger zones around the flip trigger. Ada

Strategy v6 TrendVolatility & bands
Updated yesterday · MIT GitHub repository of Chandelier Flip Radar [WavesUnchained]
1 stars

JAT+BSM Pro v13 Extended is a multi-timeframe trading strategy overlay that combines kinematic regression models, Bayesian inference, and consolidation zone analysis. It processes multi-layer volatility bands, volume profile buckets, and pattern structure targ

Strategy v5 TrendVolatility & bands
Updated today · None stated GitHub repository of JAT+BSM Pro v13 Extended
1 stars

TN Sovereign Lorentzian v6 is a quantitative strategy that classifies price action regimes using multi-dimensional indicators and causal volume auditing. It generates entry signals based on RSI center-line crossovers, 10-period momentum, and price alignment re

Strategy v6 AI / machine learningTrend
Updated 2 months ago · None stated GitHub repository of TN Sovereign Lorentzian v6
330 stars

This strategy calculates Bollinger Bands and Aroon oscillator values to identify mean-reversion opportunities. It enters a long position using full equity when the closing price crosses below the lower Bollinger Band while Aroon Up remains above a user-specifi

Strategy v5 Mean reversionVolatility & bands
Updated 2 months ago · None stated GitHub repository of Bollinger bands + Aroon [Alorse]

More strategys

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers