Indicator · Pine Script v5 · On the chart

Machine Learning: kNN (New Approach)

by capissimo

This indicator estimates the next bar's price with a k-nearest neighbors model built from consecutive price samples.

View on GitHub

GitHub stars114on the repository
Pine versionv5runs as is
Lines of code127
Settings10inputs
LicenceNone statedfile: MPL-2.0
Last update1 year ago7 Nov 2024

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 indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

127 lines of Pine Script v5 from scripts/126-2-Machine-Learning-kNN-(New-Approach)-[5].pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

126-2-Machine-Learning-kNN-(New-Approach)-[5].pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © capissimo

//@version=5
indicator("Machine Learning: kNN (New Approach) [5]", '', true, format=format.price, precision=2, timeframe="", timeframe_gaps=true)

// kNN is a very robust and simple method for data classification and prediction. It is very 
// effective if the training data is large. However, it is distinguished by difficulty at 
// determining its main parameter, K (a number of nearest neighbors), beforehand. The 
// computation cost is also quite high because we need to compute distance of each instance 
// to all training samples. Nevertheless, in algorithmic trading KNN is reported to perform 
// on a par with such techniques as SVM and Random Forest. It is also widely used in the area 
// of data science.

// The input data is just a long series of prices over time without any particular features. 
// The value to be predicted is just the next bar's price. The way that this problem is 
// solved for both nearest neighbor techniques and for some other types of prediction 
// algorithms is to create training records by taking, for instance, 10 consecutive prices 
// and using the first 9 as predictor values and the 10th as the prediction value. 
// Doing this way, given 100 data points in your time series you could create 10 different 
// training records. It's possible to create even more training records than 10 by creating 
// a new record starting at every data point. For instance, you could take the first 10 data 
// points and create a record. Then you could take the 10 consecutive data points starting at 
// the second data point, the 10 consecutive data points starting at the third data point, etc.

// By default, shown are only 10 initial data points as predictor values and the 6th as the 
// prediction value. 

// Here is a step-by-step workthrough on how to compute K nearest neighbors (KNN) algorithm for 
// quantitative data:

// 1. Determine parameter K = number of nearest neighbors. 
// 2. Calculate the distance between the instance and all the training samples. As we are 
// dealing with one-dimensional distance, we simply take absolute value from the instance to  
// value of x (| x – v |). 
// 3. Rank the distance and determine nearest neighbors based on the K'th minimum distance.
// 4. Gather the values of the nearest neighbors.
// 5. Use average of nearest neighbors as the prediction value of the instance.

// The original logic of the algorithm was slightly modified, and as a result at approx. N=17 
// the resulting curve nicely approximates that of the sma(20). See the description below.
// Beside the sma-like MA this algorithm also gives you a hint on the direction of the next bar 
// move.

//-- Inputs

TF    = input.timeframe('5',       'Resolution',                         ['1','3','5','10','15','30','45','60','120','180','240','480','D','W','M'])
N     = input.int      (10,        '# of Data Points [2:n]',             2)
K     = input.int      (100,       '# of Nearest Neighbors (K) [1:252]', 1, 252)
ADJ   = input.bool     (true,      'Adjust Prediction',                  inline='b')
SIG   = input.bool     (false,     'Signals',                            inline='b')
ADDON = input.string   ('Z-Score', 'Add-On',                             ['None','Pivot Point','Z-Score'])
LAGP  = input.int      (5,         'Pivot Point Lag [2:n] if selected',  2)
LAGZ  = input.int      (20,        'Z-Score Lag [2:n] if selected',      2)
DISP  = input.string   ('Both',    'Show Outcomes',                      ['Curve','Predict','Both'])
ODS   = input.source   (hlcc4,     'Projection Base')

//-- Series

var int signal = 0

//-- Functions

knn(data) =>  //-- calculate nearest neighbors (if any)
    float[] nearest_neighbors = array.new_float(0)
    float[] distances         = array.new_float(0)
    
    for i = 0 to N-1
        float d = math.abs(data[i] - data[i+1])
        //-- euclidean will do just as well
        // float d = math.sqrt(math.pow(data[i] - data[i+1], 2))
        array.push(distances, d)
        int size = array.size(distances)
        
        //-- The original logic was too funky, imho :-)
        // float new_neighbor = d<array.min(distances, size>K?K:0)?data[i+1]:0
        // if new_neighbor > 0
        //    array.push(nearest_neighbors, new_neighbor)
        //-- The following logic reasonably smooths the outcome!
        float new_neighbor = d<array.min(distances, size>K?K:0)?data[i+1]:data[i]
        array.push(nearest_neighbors, new_neighbor)

    nearest_neighbors  

predict(neighbors, data) =>  //-- predict the expected price and calculate next bar's direction
    float prediction = array.avg(neighbors)
    int   direction  = prediction < data[ADJ?0:1] ? 1 : prediction > data[ADJ?0:1] ? -1 : 0
    [prediction, direction] 

pivot_color(h,l, p, dir) =>
    float ph = ta.highestbars(h, LAGP)==0 ? h : na
    float pl = ta.lowestbars(l, LAGP)==0   ? l  : na
    ph and dir==1 ? 1 : pl and dir==-1 ? -1 : 0

zscore_color(data, p, dir) =>
    float zs = (data - ta.sma(data, p)) / ta.stdev(data, p)  // standardize
    zs/(p/5)>0 and dir==1 ? 1 : zs/(p/5)<0 and dir==-1 ? -1 : 0

//-- Logic

int rt     = barstate.isrealtime?1:0
[O,H,L,C]  = request.security('', TF, [open,high[rt],low[rt],close[rt]])
float[] nn = knn(C)
[pred,dir] = predict(nn, C)
signal    := ADDON=='Z-Score' ? zscore_color(C, LAGZ, dir) : ADDON=='Pivot Point' ? pivot_color(H,L,LAGP, dir) : dir
color clr  = signal==1 ? color.green : signal==-1 ? color.red : na

bool changed         = bool(ta.change(signal))
bool long_condition  = changed and signal==1
bool short_condition = changed and signal==-1
bool clear_condition = changed and signal==0

//-- Visuals

//plot(ta.sma(close,20))
plot(DISP=='Curve'   or DISP=='Both' ? pred : na, 'kNN Curve',  clr, 3)
plot(DISP=='Predict' or DISP=='Both' ? ODS  : na, 'Prediction', clr, 5, plot.style_circles, offset=2, show_last=1)
plotshape(SIG and long_condition,  '', shape.labelup,   location.belowbar, color.green, 0, '', color.white, size=size.tiny)
plotshape(SIG and short_condition, '', shape.labeldown, location.abovebar, color.red,   0, '', color.white, size=size.tiny)
plotshape(SIG and clear_condition and signal[1]==1,  '', shape.xcross, location.abovebar, color.orange, 0, '', color.white, size=size.tiny)
plotshape(SIG and clear_condition and signal[1]==-1, '', shape.xcross, location.belowbar, color.orange, 0, '', color.white, size=size.tiny)

//-- Notification

alertcondition(long_condition,  'Go long',  'Upturn!')
alertcondition(short_condition, 'Go short', 'Downturn!')
alertcondition(long_condition or short_condition, 'Reversal', 'Time to ACT!')

Overview

Machine Learning: kNN (New Approach) ranks one-dimensional distances, averages the nearest neighbors, and can adjust that projection. Optional signals hint at the next bar's direction, and an add-on can overlay a pivot point or a z-score. Users set the resolution, sample length, neighbor count, display mode, and projection source. It draws on the price chart and has no entry, exit, or stop rules.

Details

Published by

capissimo on GitHub

Type

Indicator, Pine Script v5

Draws

On the price chart

Category

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
Resolutiontimeframe5TF
# of Data Points [2:n]int10N
# of Nearest Neighbors (K) [1:252]int100K
Adjust PredictionbooltrueADJ
SignalsboolfalseSIG
Add-OnstringZ-ScoreADDON
Pivot Point Lag [2:n] if selectedint5LAGP
Z-Score Lag [2:n] if selectedint20LAGZ
Show OutcomesstringBothDISP
Projection Basesourcehlcc4ODS
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

Function K-Means Clustering

by ricardosantos79
261 stars

This indicator implements a K-means clustering algorithm in Pine Script to partition two-dimensional data points into user-defined clusters. It features an internal pseudo-random number generator for centroid initialization and computes Euclidean distances acr

Indicator v4 AI / machine learning
Updated 4 years ago · None stated GitHub repository of Function K-Means Clustering
257 stars

This indicator uses a Lorentzian distance k-nearest neighbors classification algorithm to predict market direction based on up to five technical features, such as RSI, WaveTrend, CCI, and ADX. It compares current feature values against historical bar patterns

Indicator v5 AI / machine learningOscillators & momentum
Updated 6 weeks ago · None stated GitHub repository of Donald - Machine Learning Options

AI Trend Navigator

by hasnocool
106 stars

This indicator calculates a trend direction and smoothed moving average using a k-nearest neighbours (k-NN) classification algorithm directly on the main price chart. Users can select input price types, target values, neighborhood size, and smoothing periods.

Indicator v5 AI / machine learningTrend
Updated 2 years ago · GPL-3.0 GitHub repository of AI Trend Navigator

Machine Learning: Lorentzian Classification

by artificial-intelligence-edge
75 stars

This indicator classifies the current bar by comparing its feature vector with historical bars using Lorentzian distance and a k-nearest-neighbors vote. Configurable features include RSI, WaveTrend, CCI, and ADX. Optional volatility, regime, ADX, and EMA filte

Indicator v5 AI / machine learningOscillators & momentum
Updated 2 days ago · MIT GitHub repository of Machine Learning: Lorentzian Classification
47 stars

Calculates and plots a forward price prediction directly on the main chart using an on-chart multilayer perceptron neural network. The model processes technical input features including moving average ratios, RSI, normalized ATR, and Bollinger bandwidth throug

Indicator v6 AI / machine learning
Updated 8 months ago · MIT GitHub repository of Multilayer Perceptron Predictor
46 stars

This indicator uses a Hidden Markov Model (HMM) framework combined with an adaptive dual moving average engine and Directional Movement Index (DMI) features to identify market regimes (bullish, bearish, or ranging/chop). It calculates regime probabilities on e

Indicator v5 AI / machine learningTrend
Updated 7 weeks ago · None stated GitHub repository of HMM Enhanced: Regime Probability

More indicators

Trade Your Charts With a Regulated Broker

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

Compare brokers