// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.
0
at [Link]
// BullVisionCapital
//
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@
//
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@
//
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
%#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%
+=#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*==+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@
//
@@@@@@@@@@@@@@@@@@@@@@@@@@@@*===+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#+#@@@@@@@@@@@
@@@@@@@@@@@@@@@@@
//
@@@@@@@@@@@@@@@@@@@@@@@@@@@#====+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@==#@@@@@@@@@@@
@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@#=====+
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*===#@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@#========*#%%%@@%%%%%%%%%%%@@@@@@@@@
%#+====+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@#==============*+===========*
%@#+========+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
%*=============+=============#@*======+#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%#+========================#@%==+#
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%##+==================+
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+===============================@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
%==================*@@@*=======@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%@@@%#*=============++*%#=====
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#==========================+=====*@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*==================================+
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@*==========+
+=========================*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@#==========+@%
+====================#+====#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@%+=========+@@@@#===================#@%+==
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@#=========+@@@@@@@@@%%%%%%
%*==============@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//
@@@@@@@@@@@@@@@@@@@@@@@@@@@#========+@@@@@@@@@@@@@@@@@@@@@#========+@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@%+=======%@@@@@@@@@@@@+@@@@@@@@@@@
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@%+=====*@@@@@@@%@@@%+==#@@@@@@#
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+====#@@@@@@@=@@@%
+==#@@@@@===#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#===#@@@@@%*=*%@%
+==#@@@@@==*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%*=#@@@@@#+==%@%
+==#@@@@+=#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%@@@@@@#+==%@%+==#@@@+=
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#+==
%@@@=@@@@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#+==%@@@#@@@#
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%=
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@
//
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@
//
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@
//@version=6
indicator('Husain', overlay = false)
// ╔══════════════════════════════════════════════════════════════════════════════╗
// ║ ║
// ║ RSI with K-Nearest Neighbors (KNN) Machine Learning ║
// ║ ║
// ║ This indicator enhances the traditional RSI using machine learning. ║
// ║ ║
// ║ The KNN algorithm identifies historical situations most similar to current ║
// ║ market conditions by analyzing multiple features: ║
// ║ - RSI value itself ║
// ║ - Momentum (rate of change) ║
// ║ - Volatility (standard deviation) ║
// ║ - Slope (linear regression) ║
// ║ - Price momentum ║
// ║ ║
// ║ Once these similar historical situations are found, their outcomes are ║
// ║ weighted by similarity to predict how the RSI might behave in the current ║
// ║ situation, creating a more responsive and accurate indicator. ║
// ║ ║
// ╚══════════════════════════════════════════════════════════════════════════════╝
// ===== Import Required Libraries =====
import TradingView/ta/7
// ===== Input Parameters =====
//
===================================================================================
==
// 📊 RSI Base Settings
//
===================================================================================
==
group_rsi = '📊 ================ RSI Base Settings ================'
rsiLength = [Link](14, 'RSI Length', minval = 1, group = group_rsi)
useSmoothing = [Link](true, 'Apply Moving Average', group = group_rsi)
smoothingLength = [Link](3, 'MA Length', minval = 1, group = group_rsi)
maType = [Link]('ALMA', 'Moving Average Type', options = ['SMA', 'EMA',
'DEMA', 'TEMA', 'WMA', 'VWMA', 'SMMA', 'HMA', 'LSMA', 'ALMA'], group = group_rsi)
almaSigma = [Link](4, 'ALMA Sigma', minval = 1, group = group_rsi)
//
===================================================================================
==
// 📏 Threshold Settings
//
===================================================================================
==
group_threshold = '📏 ================ Threshold Settings ================'
//useAdaptiveThresholds = [Link](true, "Use Adaptive Thresholds",
tooltip="Automatically adjust overbought/oversold levels based on market
conditions", group=group_threshold)
rsiOverbought = [Link](70, ' Overbought Level', minval = 50, maxval = 100, group
= group_threshold)
rsiOversold = [Link](30, ' Oversold Level', minval = 0, maxval = 50, group =
group_threshold)
//
===================================================================================
==
// 🧠 KNN Machine Learning Parameters
//
===================================================================================
==
group_knn = '🧠 ================ KNN Machine Learning ================'
useKnn = [Link](true, 'Enable KNN Machine Learning', group = group_knn)
knnNeighbors = [Link](5, 'K - Number of Neighbors', minval = 1, maxval = 50,
group = group_knn)
knnLookback = [Link](100, 'Historical Period for KNN', minval = 20, maxval =
500, group = group_knn)
knnWeight = [Link](0.4, 'ML Weight vs Standard RSI', minval = 0.0, maxval =
1.0, step = 0.1, group = group_knn)
featureCount = [Link](3, 'Number of Features', minval = 1, maxval = 5, tooltip =
'Number of characteristics for finding similar market conditions', group =
group_knn)
//
===================================================================================
==
// 🔍 Advanced Filtering
//
===================================================================================
==
group_filter = '🔍 ================ Advanced Filtering ================'
useFilter = [Link](true, 'Apply Additional Smoothing', group = group_filter)
filterMethod = [Link]('Kalman', 'Smoothing Method', options = ['None',
'Kalman', 'DoubleEMA', 'ALMA'], group = group_filter)
filterStrength = [Link](0.3, 'Smoothing Parameter', minval = 0.01, maxval =
1.0, step = 0.01, group = group_filter)
//
===================================================================================
==
// 🎨 Visual Settings
//
===================================================================================
==
group_visual = '🎨 ================ Visual Settings ================'
neonEffect = [Link](true, 'Neon Effect', tooltip = 'Enable vibrant neon-like
colors', group = group_visual)
colorScheme = [Link]('Classic', 'Color Palette', ['Classic', 'Deuteranopia',
'Protanopia', 'Tritanopia', 'Monochrome'], group = group_visual)
colorMode = [Link]('Trend Following', 'Coloring Mode', ['None', 'Trend
Following', 'Impulse'], group = group_visual)
//
===================================================================================
==
// COLOR DEFINITION
//
===================================================================================
==
// Colors adapted for different types of color blindness
[bullColor, bearColor] = switch colorScheme
'Classic' => [neonEffect ? [Link](0, 255, 187) : [Link](0, 183, 18),
neonEffect ? [Link](255, 17, 0) : [Link](195, 0, 16)]
'Deuteranopia' => [[Link](0, 170, 255), [Link](255, 204, 0)] //
Blue/Yellow for red-green color blindness
'Protanopia' => [[Link](0, 170, 230), [Link](230, 175, 0)] // Blue/Yellow
variant
'Tritanopia' => [[Link](255, 112, 0), [Link](0, 33, 171)] // Red/Blue for
blue-yellow color blindness
'Monochrome' => [[Link](222, 226, 230), [Link](73, 80, 87)] // High
contrast grayscale
//
===================================================================================
==
// RSI Calculation Functions
//
===================================================================================
==
// Moving Average wrapper function
// Moving Average wrapper function
calcMovingAverage(type, src, length, sigma) =>
float result = na
if type == 'SMA'
result := [Link](src, length)
result
else if type == 'EMA'
result := [Link](src, length)
result
else if type == 'DEMA'
// Double EMA implementation
e1 = [Link](src, length)
e2 = [Link](e1, length)
result := 2 * e1 - e2
result
else if type == 'TEMA'
// Triple EMA implementation
e1 = [Link](src, length)
e2 = [Link](e1, length)
e3 = [Link](e2, length)
result := 3 * (e1 - e2) + e3
result
else if type == 'WMA'
// Weighted Moving Average implementation
norm = 0.0
sum = 0.0
for i = 0 to length - 1 by 1
weight = length - i
norm := norm + weight
sum := sum + src[i] * weight
sum
result := sum / norm
result
else if type == 'VWMA'
result := [Link](src, length)
result
else if type == 'SMMA'
// Smoothed Moving Average implementation (also known as RMA)
result := [Link](src, length)
result
else if type == 'HMA'
result := [Link](src, length)
result
else if type == 'LSMA'
// Least Squares Moving Average (Linear Regression)
result := [Link](src, length, 0)
result
else if type == 'ALMA'
result := [Link](src, length, 0.85, sigma)
result
result
//
===================================================================================
==
// Calculate base RSI
//
===================================================================================
==
baseRsi = [Link](close, rsiLength)
smoothedRsi = calcMovingAverage(maType, baseRsi, smoothingLength, almaSigma)
standardRsi = useSmoothing ? smoothedRsi : baseRsi
//
===================================================================================
==
// FEATURE EXTRACTION FUNCTIONS
//
===================================================================================
==
// Calculate momentum (rate of change)
getMomentum(source, length) =>
source - source[length]
// Calculate volatility (standard deviation)
getVolatility(source, length) =>
[Link](source, length)
// Calculate slope (linear regression difference)
getSlope(source, length) =>
[Link](source, length, 0) - [Link](source, length, 1)
// Min-max normalization function
normalize(source, length) =>
maxVal = [Link](source, length)
minVal = [Link](source, length)
valueRange = maxVal - minVal
valueRange != 0 ? (source - minVal) / valueRange : 0.5
// Euclidean distance calculation
euclideanDistance(v1, v2) =>
float sum = 0.0
for i = 0 to [Link](v1) - 1 by 1
sum := sum + [Link]([Link](v1, i) - [Link](v2, i), 2)
sum
[Link](sum)
//
===================================================================================
==
// ADAPTIVE THRESHOLDS
//
===================================================================================
==
// Calculates dynamic overbought/oversold levels based on historical RSI
distribution
calculateAdaptiveThresholds(src, period, percentile) =>
var rsiValues = array.new_float(0)
// Reset array when period changes
if [Link] or [Link](rsiValues) > period
[Link](rsiValues)
[Link](rsiValues, src)
// Keep array size equal to period
if [Link](rsiValues) > period
[Link](rsiValues)
// Sort values for percentile calculation
sortedValues = [Link](rsiValues)
[Link](sortedValues)
// Find percentile indices
int lowIndex = [Link]([Link](sortedValues) * percentile / 100)
int highIndex = [Link]([Link](sortedValues) * (100 - percentile) / 100)
// Get threshold values (with safety checks)
lowVal = [Link](sortedValues) > 0 and lowIndex < [Link](sortedValues) ?
[Link](sortedValues, lowIndex) : 30
highVal = [Link](sortedValues) > 0 and highIndex < [Link](sortedValues)
? [Link](sortedValues, highIndex) : 70
[lowVal, highVal]
//
===================================================================================
==
// KNN MACHINE LEARNING
//
===================================================================================
==
knnEnhancedRsi() =>
float enhancedRsi = standardRsi
float knnDivergence = 0.0
int effectiveK = 0
// Arrays to collect ML extreme candidates
var overBoughtCandidates = array.new_float(0)
var overSoldCandidates = array.new_float(0)
[Link](overBoughtCandidates)
[Link](overSoldCandidates)
// Current point features
var currentPoint = array.new_float(0)
[Link](currentPoint)
[Link](currentPoint, normalize(standardRsi, knnLookback))
if featureCount >= 2
[Link](currentPoint, normalize(getMomentum(standardRsi, 3),
knnLookback))
if featureCount >= 3
[Link](currentPoint, normalize(getVolatility(standardRsi, 10),
knnLookback))
if featureCount >= 4
[Link](currentPoint, normalize(getSlope(standardRsi, 5), knnLookback))
if featureCount >= 5
[Link](currentPoint, normalize(getMomentum(close, 5), knnLookback))
var distances = array.new_float(0)
var indices = array.new_int(0)
[Link](distances)
[Link](indices)
// Calculate distances to historical points
for i = 1 to knnLookback by 1
if i < bar_index
var historicalPoint = array.new_float(0)
[Link](historicalPoint)
[Link](historicalPoint, normalize(standardRsi[i], knnLookback))
if featureCount >= 2
[Link](historicalPoint, normalize(getMomentum(standardRsi[i],
3), knnLookback))
if featureCount >= 3
[Link](historicalPoint, normalize(getVolatility(standardRsi[i],
10), knnLookback))
if featureCount >= 4
[Link](historicalPoint, normalize(getSlope(standardRsi[i], 5),
knnLookback))
if featureCount >= 5
[Link](historicalPoint, normalize(getMomentum(close[i], 5),
knnLookback))
if [Link](currentPoint) == [Link](historicalPoint)
dist = euclideanDistance(currentPoint, historicalPoint)
[Link](distances, dist)
[Link](indices, i)
[Link](historicalPoint)
if [Link](distances) > 1
for i = 0 to [Link](distances) - 2 by 1
for j = 0 to [Link](distances) - 2 - i by 1
if [Link](distances, j) > [Link](distances, j + 1)
tempDist = [Link](distances, j)
[Link](distances, j, [Link](distances, j + 1))
[Link](distances, j + 1, tempDist)
tempIdx = [Link](indices, j)
[Link](indices, j, [Link](indices, j + 1))
[Link](indices, j + 1, tempIdx)
float weightedSum = 0.0
float weightSum = 0.0
effectiveK := [Link](knnNeighbors, [Link](distances))
if effectiveK > 0
for i = 0 to effectiveK - 1 by 1
if i < [Link](distances)
idx = [Link](indices, i)
dist = [Link](distances, i)
weight = dist < 0.0001 ? 1.0 : 1.0 / dist
float neighborRsi = na
if idx < bar_index
neighborRsi := standardRsi[idx - 1]
// Sécurité sur futureReturn
float futureReturn = na
if idx + 5 < bar_index + 1 and not na(close[idx + 5]) and
not na(close[idx])
futureReturn := close[idx + 5] - close[idx]
futureReturn
// Identification des zones extrêmes
if not na(futureReturn)
if futureReturn > close[idx] * 0.02
[Link](overBoughtCandidates, standardRsi[idx])
if futureReturn < close[idx] * -0.02
[Link](overSoldCandidates, standardRsi[idx])
if not na(neighborRsi)
weightedSum := weightedSum + neighborRsi * weight
weightSum := weightSum + weight
weightSum
if weightSum > 0.0
knnRsi = weightedSum / weightSum
enhancedRsi := (1.0 - knnWeight) * standardRsi + knnWeight * knnRsi
enhancedRsi := [Link](0.0, [Link](100.0, enhancedRsi))
float diffSum = 0.0
int count = 0
for i = 0 to effectiveK - 1 by 1
if i < [Link](distances)
idx = [Link](indices, i)
if idx < bar_index
diffSum := diffSum + [Link](standardRsi -
standardRsi[idx])
count := count + 1
count
knnDivergence := count > 0 ? diffSum / count : 0.0
knnDivergence
adaptiveOverboughtML = [Link](overBoughtCandidates) > 0 ?
[Link](overBoughtCandidates) : 70
adaptiveOversoldML = [Link](overSoldCandidates) > 0 ?
[Link](overSoldCandidates) : 30
[enhancedRsi, knnDivergence, effectiveK, adaptiveOversoldML,
adaptiveOverboughtML]
//
===================================================================================
==
// APPLY ALGORITHMS
//
===================================================================================
==
// Get enhanced RSI from KNN
[knnRsi, knnDivergence, kEffective, adaptiveOversoldML, adaptiveOverboughtML] =
knnEnhancedRsi()
actualOversold = rsiOversold
actualOverbought = rsiOverbought
// Use either standard or KNN-enhanced RSI
mlRsi = useKnn ? knnRsi : standardRsi
// Apply advanced filtering if enabled
filteredRsi = switch filterMethod
'None' => mlRsi
'Kalman' =>
var float kfRsi = na
kfRsi := na(kfRsi) ? mlRsi : kfRsi + filterStrength * (mlRsi - kfRsi)
kfRsi
'DoubleEMA' =>
var float ema1 = na
var float ema2 = na
ema1 := [Link](mlRsi, [Link](filterStrength * 10))
ema2 := [Link](ema1, [Link](filterStrength * 5))
ema2
'ALMA' => [Link](mlRsi, [Link](filterStrength * 20), 0, 6)
=> mlRsi
// Final RSI value after all processing
finalRsi = useFilter ? filteredRsi : mlRsi
// ===== Color Determination =====
color indicatorColor = switch colorMode
'None' => na
'Trend Following' => finalRsi > 50 ? bullColor : bearColor
'Impulse' => finalRsi > actualOverbought ? bullColor : finalRsi <
actualOversold ? bearColor : finalRsi < 55 and finalRsi > 45 ? [Link] :
[Link]
//
===================================================================================
==
// VIUSALS AND PLOTS
//
===================================================================================
==
// Variables for transparency
t_ = 20 // Secondary transparency for bar coloring
color_ = finalRsi > 50 ? indicatorColor : indicatorColor
// Main RSI line
rsiLine = plot(finalRsi, 'RSI KNN', color_, 3, plot.style_columns)
// Median line (level 50)
// midLine = plot(50, "50 Level", [Link]([Link], 70), 1)
// Fill between RSI and median line with gradient
// fill(rsiLine, midLine, finalRsi > 50 ? finalRsi : 50, finalRsi > 50 ? 50 :
finalRsi,
// neonEffect ? (finalRsi > 50 ? indicatorColor : #00000000) : #00000000,
// neonEffect ? (finalRsi > 50 ? #00000000 : indicatorColor) : #00000000)
// Overbought/oversold zones with gradient
// Overbought zone
// obUpper = plot(100, "", [Link](bearColor, 0), display=[Link])
// obLower = plot(actualOverbought, "", [Link](bearColor, 0), 1)
// obMid = plot((100 + actualOverbought) / 2, "", display=[Link])
// // Oversold zone
// osUpper = plot(actualOversold, "", [Link](bullColor, 0), 1)
// osLower = plot(0, "", [Link](bullColor, 0), display=[Link])
// osMid = plot(actualOversold / 2, "", display=[Link])
// Chart bar coloring
barcolor(finalRsi > 50 ? [Link](bullColor, t_) : [Link](bearColor, t_))
//
===================================================================================
==
// TABLE
//
===================================================================================
==
//
===================================================================================
==
// TABLE DISPLAY
//
===================================================================================
==
string modeUsed = colorMode
string context = switch colorMode
'Trend Following' => finalRsi > 50 ? 'Bullish Trend' : 'Bearish Trend'
'Impulse' => finalRsi > actualOverbought ? 'Bullish Impulse' : finalRsi <
actualOversold ? 'Bearish Impulse' : 'None'
=> 'None'
string mlStatus = useKnn ? 'YES' : 'NO'
tableColor = #160d0db3
var table myTable = [Link](position = position.top_right, columns = 4, rows = 6,
bgcolor = #160d0db3, border_color = #160d0db3, border_width = 1, frame_color =
#ffffff, frame_width = 1, force_overlay = true)
if bar_index % 10 == 0 // Met à jour toutes les 10 bougies pour optimiser les perfs
[Link](myTable, 0, 0, 'Mode', text_color = [Link], bgcolor =
tableColor)
[Link](myTable, 1, 0, modeUsed, text_color = [Link], bgcolor =
tableColor)
[Link](myTable, 0, 1, 'Detected', text_color = [Link], bgcolor =
tableColor)
[Link](myTable, 1, 1, context, text_color = [Link], bgcolor =
tableColor)
[Link](myTable, 0, 2, 'Machine Learning', text_color = [Link], bgcolor
= tableColor)
[Link](myTable, 1, 2, mlStatus, text_color = [Link], bgcolor =
tableColor)
[Link](myTable, 0, 3, 'OB/OS Thresholds', text_color = [Link], bgcolor
= tableColor)
[Link](myTable, 1, 3, [Link](actualOverbought) + ' / ' +
[Link](actualOversold), text_color = [Link], bgcolor =
[Link]([Link], 70))
///////////////////////////////////////////////
ema_trend = [Link] ( true , title = "==========================================
EMA TREND ===")
ema21 = [Link](close, 21)
ema62 = [Link](close, 62)
ema200 = [Link](close, 200)
// Trend conditions
scalping_bull = close > ema21
intraday_bull = close > ema62
positional_bull = close > ema200
// Input for table position
table_position_str = [Link]('Bottom Left', title = 'Table Position', options
= ['Top Left', 'Top Center', 'Top Right', 'Middle Left', 'Middle Center', 'Middle
Right', 'Bottom Left', 'Bottom Center', 'Bottom Right'])
// Convert string to position
pos = switch table_position_str
'Top Left' => position.top_left
'Top Center' => position.top_center
'Top Right' => position.top_right
'Middle Left' => position.middle_left
'Middle Center' => position.middle_center
'Middle Right' => position.middle_right
'Bottom Left' => position.bottom_left
'Bottom Center' => position.bottom_center
'Bottom Right' => position.bottom_right
=> position.top_right // default
// Create table
var table trend_table = [Link](pos, 2, 4, bgcolor = [Link], border_width =
1, force_overlay = true)
// Headers
if [Link] and ema_trend
[Link](trend_table, 0, 0, 'Trend Type', text_color = [Link], bgcolor =
[Link])
[Link](trend_table, 1, 0, 'Status', text_color = [Link], bgcolor =
[Link])
// Scalping
[Link](trend_table, 0, 1, 'Scalping (EMA 21)', text_color = [Link])
[Link](trend_table, 1, 1, scalping_bull ? 'Bullish' : 'Bearish', text_color
= scalping_bull ? [Link] : [Link])
// Intraday
[Link](trend_table, 0, 2, 'Intraday (EMA 62)', text_color = [Link])
[Link](trend_table, 1, 2, intraday_bull ? 'Bullish' : 'Bearish', text_color
= intraday_bull ? [Link] : [Link])
// Positional
[Link](trend_table, 0, 3, 'Positional (EMA 200)', text_color = [Link])
[Link](trend_table, 1, 3, positional_bull ? 'Bullish' : 'Bearish',
text_color = positional_bull ? [Link] : [Link])
// ===== INPUTS =====
tw_trend = [Link] ( true , title = "=== TW TREND ===")
lenDI = [Link](10, minval=1, title="DI Length")
lenADX = [Link](10, minval=1, title="ADX Smoothing")
adxThresh = [Link](20, title="ADX Strong Trend Threshold")
// ===== TIMEFRAMES =====
tf1 = "1"
tf2 = "3"
tf3 = "5"
tf10 = "10"
tf4 = "15"
tf5 = "60"
tf6 = "240"
// ===== TABLE OPTIONS =====
showTable = tw_trend //[Link](true, "Show Table")
useBg = tw_trend //[Link](true, "Change Chart Background?")
// ==== FONT SIZE OPTION ====
tableSizeOpt = [Link]("Small", "Table Font Size", options=["Normal", "Small",
"Tiny"])
var textSize = [Link]
if tableSizeOpt == "Normal"
textSize := [Link]
else if tableSizeOpt == "Small"
textSize := [Link]
else
textSize := [Link]
// ===== COLOR OPTIONS =====
colTableBg = [Link]([Link], "Table Background")
colBorder = [Link]([Link], "Table Border")
colHeader = [Link]([Link], "Header Background")
colTextHeader = [Link]([Link], "Header Text")
colBull = [Link]([Link], "Bullish Color")
colBear = [Link]([Link], "Bearish Color")
colNeutral = [Link]([Link], "Neutral Color")
colStrong = [Link]([Link], "Strong Trend Color")
colWeak = [Link]([Link], "Weak Trend Color")
colTFbg = [Link]([Link], "TF Column Background")
colTFtext = [Link]([Link], "TF Text Color")
// ===== FUNCTION TO CALCULATE DMI TREND =====
f_dmi_trend(_plus, _minus, _adx) =>
trendDir = _plus > _minus ? "Bull" : _plus < _minus ? "Bear" : "Neutral"
trendColor = _plus > _minus ? colBull : _plus < _minus ? colBear : colNeutral
trendStrength = _adx > adxThresh ? "Strong" : "Weak"
[trendDir, trendColor, trendStrength]
// ===== CALCULATE DMI =====
calc_dmi() =>
up = [Link](high)
down = -[Link](low)
plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
trur = [Link]([Link], lenDI)
plus = fixnan(100 * [Link](plusDM, lenDI) / trur)
minus = fixnan(100 * [Link](minusDM, lenDI) / trur)
sumDI = plus + minus
adx = fixnan(100 * [Link]([Link](plus - minus) / (sumDI == 0 ? 1 : sumDI),
lenADX))
[plus, minus, adx]
// ===== REQUEST SECURITY =====
[plus1, minus1, adx1] = [Link]([Link], tf1, calc_dmi())
[plus2, minus2, adx2] = [Link]([Link], tf2, calc_dmi())
[plus3, minus3, adx3] = [Link]([Link], tf3, calc_dmi())
[plus10, minus10, adx10]= [Link]([Link], tf10, calc_dmi())
[plus4, minus4, adx4] = [Link]([Link], tf4, calc_dmi())
[plus5, minus5, adx5] = [Link]([Link], tf5, calc_dmi())
[plus6, minus6, adx6] = [Link]([Link], tf6, calc_dmi())
// ===== GET TREND =====
[dir1, col1, strg1] = f_dmi_trend(plus1, minus1, adx1)
[dir2, col2, strg2] = f_dmi_trend(plus2, minus2, adx2)
[dir3, col3, strg3] = f_dmi_trend(plus3, minus3, adx3)
[dir10, col10, strg10]= f_dmi_trend(plus10, minus10, adx10)
[dir4, col4, strg4] = f_dmi_trend(plus4, minus4, adx4)
[dir5, col5, strg5] = f_dmi_trend(plus5, minus5, adx5)
[dir6, col6, strg6] = f_dmi_trend(plus6, minus6, adx6)
// ===== CREATE TABLE =====
var table trendTable = [Link](position.bottom_right, 3, 8,
frame_color=colBorder, border_width=1,force_overlay = true)
// ===== HELPER FUNCTION =====
fillRow(_row, _tf, _dir, _col, _strg) =>
[Link](trendTable, 0, _row, _tf, text_color=colTFtext, bgcolor=colTFbg,
text_size=textSize)
[Link](trendTable, 1, _row, _dir, text_color=[Link], bgcolor=_col,
text_size=textSize)
[Link](trendTable, 2, _row, _strg, text_color=[Link], bgcolor=_strg ==
"Strong" ? colStrong : colWeak, text_size=textSize)
// ===== DRAW TABLE =====
if showTable
for r = 0 to 7
for c = 0 to 2
[Link](trendTable, c, r, "", bgcolor=colTableBg,
text_size=textSize)
[Link](trendTable, 0, 0, "TF", text_color=colTextHeader,
bgcolor=colHeader, text_size=textSize)
[Link](trendTable, 1, 0, "Trend", text_color=colTextHeader,
bgcolor=colHeader, text_size=textSize)
[Link](trendTable, 2, 0, "Strength", text_color=colTextHeader,
bgcolor=colHeader, text_size=textSize)
fillRow(1, tf1, dir1, col1, strg1)
fillRow(2, tf2, dir2, col2, strg2)
fillRow(3, tf3, dir3, col3, strg3)
fillRow(4, tf10, dir10, col10, strg10)
fillRow(5, tf4, dir4, col4, strg4)
fillRow(6, tf5, dir5, col5, strg5)
fillRow(7, tf6, dir6, col6, strg6)
// ===== CHART BACKGROUND =====
bgTransp = [Link](85, title="Background transparency (0 = opaque, 100 = fully
transparent)", minval=0, maxval=100)
var color bgColor = na
if useBg
bgColor :=
[Link] == tf1 ? (dir1 == "Bull" ? colBull : dir1 == "Bear" ?
colBear : colNeutral) :
[Link] == tf2 ? (dir2 == "Bull" ? colBull : dir2 == "Bear" ?
colBear : colNeutral) :
[Link] == tf3 ? (dir3 == "Bull" ? colBull : dir3 == "Bear" ?
colBear : colNeutral) :
[Link] == tf10 ? (dir10 == "Bull" ? colBull : dir10 == "Bear" ?
colBear : colNeutral) :
[Link] == tf4 ? (dir4 == "Bull" ? colBull : dir4 == "Bear" ?
colBear : colNeutral) :
[Link] == tf5 ? (dir5 == "Bull" ? colBull : dir5 == "Bear" ?
colBear : colNeutral) :
[Link] == tf6 ? (dir6 == "Bull" ? colBull : dir6 == "Bear" ?
colBear : colNeutral) :
na
bgcolor(useBg and not na(bgColor) ? [Link](bgColor, bgTransp) : na,force_overlay
= true)
slingshot = [Link](true,'=== slingshot ===')
sae = input(true, title='Show Aggressive Entry?, Or Use as Alert To Potential
Conservative Entry?')
sce = input(true, title='Show Conservative Entry?')
st = input(true, title='Show Trend Arrows at Top and Bottom of Screen?')
def = input(false, title='Only Choose 1 - Either Conservative Entry Arrows
or \'B\'-\'S\' Letters')
pa = input(true, title='Show Conservative Entry Arrows?')
sl = input(false, title='Show \'B\'-\'S\' Letters?')
//EMA Definitions
emaSlow = [Link](close, 62)
emaFast = [Link](close, 38)
//Aggressive Entry or Alert To Potential Trade
pullbackUpT() =>
emaFast > emaSlow and close < emaFast
pullbackDnT() =>
emaFast < emaSlow and close > emaFast
//Conservative Entry Code For Highlight Bars
entryUpT() =>
emaFast > emaSlow and close[1] < emaFast and close > emaFast
entryDnT() =>
emaFast < emaSlow and close[1] > emaFast and close < emaFast
//Conservative Entry True/False Condition
entryUpTrend = emaFast > emaSlow and close[1] < emaFast and close > emaFast ? 1 : 0
entryDnTrend = emaFast < emaSlow and close[1] > emaFast and close < emaFast ? 1 : 0
//Define Up and Down Trend for Trend Arrows at Top and Bottom of Screen
upTrend = emaFast >= emaSlow
downTrend = emaFast < emaSlow
//Definition for Conseervative Entry Up and Down PlotArrows
codiff = entryUpTrend == 1 ? entryUpTrend : 0
codiff2 = entryDnTrend == 1 ? entryDnTrend : 0
//Color definition for Moving Averages
col = emaFast > emaSlow ? [Link] : emaFast < emaSlow ? [Link] : [Link]
// Moving Average Plots and Fill
p1 = plot(slingshot?emaSlow:na, title='Slow MA', style=plot.style_linebr,
linewidth=4, color=col,force_overlay = true)
p2 = plot(slingshot?emaFast:na, title='Slow MA', style=plot.style_linebr,
linewidth=2, color=col,force_overlay = true)
fill(p1, p2, color=[Link]([Link], 50))
//Aggressive Entry, Conservative Entry Highlight Bars
pullbackDnT_1 = pullbackDnT()
barcolor(sae and pullbackUpT() ? [Link] : sae and pullbackDnT_1 ?
[Link] : na)
entryDnT_1 = entryDnT()
barcolor(sce and entryUpT() ? [Link] : sce and entryDnT_1 ? [Link] : na)
// Trend Triangles at Top and Bottom of Screen
plotshape(st and upTrend , title='Conservative Buy Entry Triangle',
style=[Link], location=[Link], color=[Link]([Link], 0),
offset=0,force_overlay = true)
plotshape(st and downTrend , title='Conservative Short Entry Triangle',
style=[Link], location=[Link], color=[Link]([Link], 0),
offset=0,force_overlay = true)
//Plot Arrows OR Letters B and S for Buy Sell Signals
// plotarrow(pa and entryUpTrend == 1 ? entryUpTrend : na, title='Up Entry Arrow',
colorup=[Link]([Link], 0), maxheight=30, minheight=30,force_overlay = true)
// plotarrow(pa and (entryDnTrend == 1) ? codiff2 * -1 : na, title='Down Entry
Arrow', colordown=[Link]([Link], 0), maxheight=30, minheight=30,force_overlay
= true)
plotchar(sl and entryUpTrend == 1 ? low - [Link] : na, title='Buy Entry', offset=0,
char='B', location=[Link], color=[Link]([Link], 0),force_overlay
= true)
plotchar(sl and (entryDnTrend == 1) ? high + [Link] : na, title='Short Entry',
offset=0, char='S', location=[Link], color=[Link]([Link],
0),force_overlay = true)
plotchar(emaFast > emaSlow and
slingshot ,'','',[Link],[Link] ,0,"███",force_overlay = true)
plotchar(emaFast < emaSlow and
slingshot ,'','',[Link],[Link] ,0,"███",force_overlay = true)
plotshape(pa and entryUpTrend ==
1,'buy',[Link],[Link],[Link],0,'B',[Link],force_overlay
= true)
plotshape(pa and entryDnTrend ==
1,'sell',[Link],[Link],[Link] ,0,'S',[Link],force_overl
ay = true)
twtrend = bgColor==colBull?1 :bgColor==colBear?-1:0
plotshape(pa and entryUpTrend == 1 and
twtrend==1,'buy',[Link],[Link],[Link],0,'Buy',[Link],for
ce_overlay = true)
plotshape(pa and entryDnTrend == 1 and twtrend==-
1,'sell',[Link],[Link],[Link] ,0,'Sell',[Link],force_ov
erlay = true)