Indicator · Pine Script v6 · On the chart

Nasan Risk Score & Postion Size Estimator

by regalouisei· code credited to federalTacos5392b

This indicator estimates a risk score and suggested position size from capital, a user win rate, a profit ratio, and historical price range.

View on GitHub

GitHub stars2on the repository
Pine versionv6current
Lines of code445
Settings12inputs
LicenceNone statedfile: MPL-2.0
Last update8 months ago25 Feb 2026

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

445 lines of Pine Script v6 from pinescript/editors_picks/nasan-risk-score-postion-size-estimator.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

nasan-risk-score-postion-size-estimator.pine
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © federalTacos5392b
//@version=6
indicator("Nasan Risk Score & Postion Size Estimator", overlay = true)
if not timeframe.isdaily
    runtime.error("This indicator only works on the daily timeframe")

// Input parameters for user customization
capital =input.float(10000, "Capital")
winRate = input.float(50, "Win Rate (n)", step = 0.01)  // Default win rate
profit_Ratio = input.float(2.0, "Profit Ratio", step = 0.01)  // Default profit ratio
scalingType = input.string("Aggressive", "Risk Scaling", options = ["Aggressive", "Conservative"])  // Choose scaling type 
profitRatio = 1 - (1/(1+profit_Ratio))
startYear = 1990
endYear = 2050
lookbackYears = 5
Max_acceptable_dd = input.float(20.0, "Max Acceptable Draw Down")
// Inputs for customization
var int start_year_ = startYear

// Variables for tracking the current year's high and low values
var float current_high_ = na
var float current_low_ = na
var int current_year_ = year(time)
var float[] max_dd_array = array.new_float()
var int[] years_array_ = array.new_int()

// Detect new year and update arrays
if year(time) != current_year_
    if not na(current_high_) and not na(current_low_) and current_year_ >= start_year_
        // Calculate Max Drawdown as a percentage: (Year's High - Year's Low) / Year's High * 100
        float max_dd = 100 * (current_high_ - current_low_) / current_high_  
        array.push(max_dd_array, max_dd)
        array.push(years_array_, current_year_)
    
    // Reset values for the new year
    current_year_ := year(time)
    current_high_ := high
    current_low_ := low
else
    // Update yearly high and low values
    current_high_ := math.max(current_high_, high)
    current_low_ := math.min(current_low_, low)

// On the final bar, store the current year's data if valid and calculate weighted average
var float weighted_avg_dd = na
if barstate.islast
    if not na(current_high_) and not na(current_low_) and current_year_ >= start_year_
        float max_dd = 100 * (current_high_ - current_low_) / current_high_
        array.push(max_dd_array, max_dd)
        array.push(years_array_, current_year_)
    
    int available_years = array.size(years_array_)
    if available_years > 0
        int last_5_count = math.min(5, available_years)
        float sum_weighted_dd = 0.0
        float total_weight = 0.0
        for i = 0 to last_5_count - 1
            int index = available_years - last_5_count + i
            float dd_value = array.get(max_dd_array, index)
            int weight = i + 1  // Weighting: as provided, "last_5_count - i"
            sum_weighted_dd += dd_value * weight
            total_weight += weight
        weighted_avg_dd := sum_weighted_dd / total_weight

// Plot the weighted average max drawdown as a line on the chart
plot(weighted_avg_dd, title="Weighted Avg Max Drawdown", color=color.red, linewidth=2, style=plot.style_line) 

Tol = (100 - (weighted_avg_dd - Max_acceptable_dd)) /100
Tolerance_ = Tol 
// Inputs for customization
var int start_year = startYear

// Variables for tracking the current year and ATR percentage
var float current_high = na
var float current_low = na
var int current_year = year(time)
var float[] max_atr_array = array.new_float()
var float[] min_atr_array = array.new_float()
var int[] years_array = array.new_int()

// ATR Calculation
atr_percent = 100 * ta.ema(ta.tr / close, 14)

// Plot the ATR percentage on the chart
plot(atr_percent, color=color.gray, title="ATR% (14 EMA)")

// Detect new year and update arrays
if year(time) != current_year
    if not na(current_high) and not na(current_low) and current_year >= start_year
        array.push(max_atr_array, current_high)  // Store max ATR% for the year
        array.push(min_atr_array, current_low)   // Store min ATR% for the year
        array.push(years_array, current_year)    // Store the year

    // Reset values for the new year
    current_year := year(time)
    current_high := atr_percent
    current_low := atr_percent
else
    // Update yearly high and low ATR% values
    current_high := math.max(current_high, atr_percent)
    current_low := math.min(current_low, atr_percent)

// Ensure the table is created at the beginning
var table atr_table = table.new(position.top_center, 3, 7, bgcolor=color.white)

// Store the final year's data on the last bar
var float weighted_avg_high = na
var float weighted_avg_low = na

if barstate.islast
    if not na(current_high) and not na(current_low) and current_year >= start_year
        array.push(max_atr_array, current_high)
        array.push(min_atr_array, current_low)
        array.push(years_array, current_year)

    // Ensure there's enough data for the last five years
    int available_years = array.size(years_array)

    if available_years > 0
        var int[] last_years = array.new_int()
        var float[] last_highs = array.new_float()
        var float[] last_lows = array.new_float()

        int last_5_count = math.min(5, available_years)

        float sum_weighted_high = 0
        float sum_weighted_low = 0
        float total_weight = 0

        for i = 0 to last_5_count - 1
            int index = available_years - last_5_count + i
            float max_value = array.get(max_atr_array, index)
            float min_value = array.get(min_atr_array, index)

            int weight = i + 1  // Recent years have higher weight

            // Weighted Sum Calculation
            sum_weighted_high += max_value * weight
            sum_weighted_low += min_value * weight
            total_weight += weight

            array.push(last_years, array.get(years_array, index))
            array.push(last_highs, max_value)
            array.push(last_lows, min_value)

        // Compute Weighted Averages
        weighted_avg_high := sum_weighted_high / total_weight
        weighted_avg_low := sum_weighted_low / total_weight


// Plot the Weighted Max and Min ATR% outside the table
plot(weighted_avg_high, color=color.red, title="Weighted Max ATR%", linewidth=2, style=plot.style_line)
plot(weighted_avg_low, color=color.green, title="Weighted Min ATR%", linewidth=2, style=plot.style_line)
// Function to calculate annual returns

//------------------------------------------------------
// Annual returns + current-year YTD + weighted averages
//------------------------------------------------------

// Function to calculate annual returns (~12M, completed years)
calculate_annual_returns() =>
    var float[] returns = array.new_float()
    var int[]   years   = array.new_int()

    int yr = year(time)

    if yr >= startYear and yr <= endYear
        float annualReturn = (close - close[1]) / close[1] * 100
        if not na(annualReturn)
            array.push(returns, math.round(annualReturn, 2))
            array.push(years, yr)

    [returns, years]

//------------------------------------------------------
// Get annual returns (12M bars)
//------------------------------------------------------
[returnsArray, yearsArray] = request.security(syminfo.tickerid, "12M", calculate_annual_returns())

benchmarkTicker = input.symbol("SP:SPX", "Benchmark (SPX)")

[benchmarkReturnsArray, benchmarkYearsArray] = request.security(benchmarkTicker, "12M", calculate_annual_returns())

//------------------------------------------------------
// Detect first close of CURRENT calendar year (YTD only)
//------------------------------------------------------
int evalYear = year(time)

var float firstCloseOfYear          = na
var float benchmarkFirstCloseOfYear = na

if year(time) != year(time[1])
    if year(time) == evalYear
        firstCloseOfYear          := close
        benchmarkFirstCloseOfYear := request.security(benchmarkTicker, "D", close)

// YTD return (current year only)
float ytdReturn = not na(firstCloseOfYear) ? (close - firstCloseOfYear) / firstCloseOfYear * 100 : na

float benchmarkYTDReturn = not na(benchmarkFirstCloseOfYear) ? (request.security(benchmarkTicker, "D", close) - benchmarkFirstCloseOfYear)/ benchmarkFirstCloseOfYear * 100 : na

//------------------------------------------------------
// Weighted average: completed years + current YTD once
//------------------------------------------------------
calculate_weighted_average_with_ytd(returns, years, float ytdReturn, int lookback) =>
    int sz = array.size(returns)
    int sy = array.size(years)

    // No data yet (early history)
    if sz == 0 or sy == 0
        na
    else
        float totalWeightedReturns = 0.0
        float totalWeights         = 0.0
        int   evalYearLocal        = year(time)

        int limit = math.min(sz, sy)

        // Completed years only
        for i = 0 to limit - 1
            int yr  = array.get(years, i)
            int age = evalYearLocal - yr

            if age > 0 and age <= lookback
                float weight = lookback - age
                totalWeightedReturns += array.get(returns, i) * weight
                totalWeights         += weight

        // Add CURRENT YEAR YTD once (highest weight)
        bool lastIsCurrentYear = false
        if sy > 0
            lastIsCurrentYear := array.get(years, sy - 1) == evalYearLocal

        if not na(ytdReturn) and not lastIsCurrentYear
            totalWeightedReturns += ytdReturn * lookback
            totalWeights         += lookback

        totalWeights != 0 ? totalWeightedReturns / totalWeights : na

//------------------------------------------------------
// Final weighted averages (compute ONLY on last bar)
//------------------------------------------------------
float weightedAverageMain      = na
float weightedAverageBenchmark = na

if barstate.islast
    weightedAverageMain := calculate_weighted_average_with_ytd(returnsArray, yearsArray, ytdReturn, 5)

    weightedAverageBenchmark := calculate_weighted_average_with_ytd(benchmarkReturnsArray, benchmarkYearsArray, benchmarkYTDReturn, 5)

// Plot results
plot(weightedAverageMain, title="Weighted Average Main", color=color.blue)
plot(weightedAverageBenchmark, title="Weighted Average Benchmark", color=color.red)


// Function to calculate Min Risk with 1% cap when stock return is negative
calculate_min_risk(stockReturn, benchmarkReturn, maxATR) =>
    risk =  (stockReturn - benchmarkReturn) / maxATR > 1 ? (stockReturn - benchmarkReturn)/maxATR: 1
    
// Function to calculate Max Risk with 1% cap when stock return is negative
calculate_max_risk(stockReturn, benchmarkReturn, minATR) =>
    risk = (stockReturn - benchmarkReturn) / minATR > 1 ? (stockReturn - benchmarkReturn) / minATR : 2
    
// Function to calculate Nasan Risk Score (Aggressive Scaling)
calculate_aggressive_risk(minRisk, maxRisk, n, m) =>
    a = math.max(m, n)
    b = math.min(m, n)
    math.pow(minRisk,a )+ b * (math.pow(maxRisk,a) - math.pow(minRisk,a))

// Function to calculate Nasan Risk Score (Conservative Scaling)
calculate_conservative_risk(minRisk, maxRisk, n, m) =>
    a = math.max(m, n)
    b = math.min(m, n)
    math.pow(minRisk,b )+  a * (math.pow(maxRisk,b) - math.pow(minRisk,b))

// Calculate Min Risk and Max Risk using the placeholders
minRisk = calculate_min_risk(weightedAverageMain, weightedAverageBenchmark, weighted_avg_high)
maxRisk = calculate_max_risk(weightedAverageMain, weightedAverageBenchmark, weighted_avg_low)
plot(weightedAverageMain, "Weighted Anuual Stock Return")
plot(weightedAverageBenchmark ,"Weighted Anuual Benchmark Return", color=color.white)

// Declare the risk score as float
var float nasanRiskScore = na


// Calculate Nasan Risk Score using the appropriate scaling
if scalingType == "Aggressive"
    nasanRiskScore := calculate_aggressive_risk(minRisk, maxRisk, (winRate / 100), profitRatio)
else
    nasanRiskScore := calculate_conservative_risk(minRisk, maxRisk, (winRate / 100), profitRatio)

// Round the Nasan Risk Score to one decimal place
nasanRiskScoreRounded = math.round(nasanRiskScore*Tolerance_, 2)

// Calculate Nsasn Ultimate Helth Index 
Nor_len = input(252, "Normalization Length")
n = input(21, "Technical Length")

benchmark_ticker = benchmarkTicker
// Stock Raw Score
ema = ta.ema(hlc3, n)
// Volume Ratio Calculation
volume_ratio = ta.sma(volume, n) / ta.sma(volume, 252)

green_volume = math.sum(volume * (close > open ? 1 : 0), n)
red_volume = math.sum(volume * (close < open ? 1 : 0), n)
total_volume = math.sum(volume, n)

green_weight = green_volume / total_volume
red_weight = red_volume / total_volume

temp_weight = ema - ema[n] > 0 ? green_weight : red_weight

// Adjusted Volume Ratio
adjusted_volume_ratio = volume_ratio * temp_weight

// Stock Raw Score
raw_score = ((ema - ema[n]) * adjusted_volume_ratio) / ta.atr(n)

// Benchmark Raw Score 
BenchmarkRawScore() =>  
    benchmark_hlc3 = hlc3  
    benchmark_close = close  
    benchmark_open = open  
    benchmark_volume = volume  
    benchmark_green_vol = math.sum(benchmark_volume * (benchmark_close > benchmark_open ? 1 : 0), n) 
    benchmark_red_vol = math.sum(benchmark_volume * (benchmark_close < benchmark_open ? 1 : 0), n) 
    benchmark_total_vol = math.sum(benchmark_volume, n) 
    benchmark_green_weight = benchmark_green_vol / benchmark_total_vol 
    benchmark_red_weight = benchmark_red_vol / benchmark_total_vol 
    benchmark_ema = ta.ema(hlc3, n)  
    benchmark_temp_weight = benchmark_ema - benchmark_ema[n] > 0 ? benchmark_green_weight : benchmark_red_weight 
    benchmark_volume_ratio = ta.sma(benchmark_volume, n) / ta.sma(benchmark_volume, 252) 
    benchmark_adjusted_volume_ratio = benchmark_volume_ratio * benchmark_temp_weight 
    benchmark_atr = ta.atr(n) 
    benchmark_raw_score = ((benchmark_ema - benchmark_ema[n]) * benchmark_adjusted_volume_ratio) / benchmark_atr  
 
    [benchmark_hlc3, benchmark_close, benchmark_open, benchmark_volume, benchmark_green_vol, benchmark_red_vol,  
     benchmark_total_vol, benchmark_green_weight, benchmark_red_weight, benchmark_ema, benchmark_temp_weight,  
     benchmark_volume_ratio, benchmark_adjusted_volume_ratio, benchmark_atr, benchmark_raw_score] 
 
[benchmark_hlc3, benchmark_close, benchmark_open, benchmark_volume, benchmark_green_vol, benchmark_red_vol,  
 benchmark_total_vol, benchmark_green_weight, benchmark_red_weight, benchmark_ema, benchmark_temp_weight,  
 benchmark_volume_ratio, benchmark_adjusted_volume_ratio, benchmark_atr, benchmark_raw_score] = request.security(benchmark_ticker, timeframe.period, BenchmarkRawScore())

// Min-Max Normalization for Stock
min_x = ta.lowest(raw_score, Nor_len)
max_x = ta.highest(raw_score, Nor_len)
normalized_stock = (raw_score - min_x) / (max_x - min_x)

// Min-Max Normalization for Benchmark
min_y = ta.lowest(benchmark_raw_score, Nor_len)
max_y = ta.highest(benchmark_raw_score, Nor_len)
normalized_benchmark = (benchmark_raw_score - min_y) / (max_y - min_y)

// Compute ATR multiplier to scale ATR in postion size calulationw e nh
Baseline = input.float(3, "ATR Baseline Multiple")
NUHI = math.log((1 + normalized_stock) / (1 + normalized_benchmark))
tr_var = ta.stdev(ta.tr,21) 
tr_var_stoch =(ta.stoch(tr_var,tr_var,tr_var,252))/100
Q = Baseline + tr_var_stoch
mul= Q - math.exp(ta.ema(NUHI,21))
plot(mul, color=color.purple)

// Calulate  Position Size
PositionSize = int((capital * (nasanRiskScoreRounded / 100)) / (mul*ta.atr(21)))

// User-defined input to control the display of risk metrics
showRiskMetrics = input.bool(false, title="Show Postion Size  even if Stock Return < Benchmark Return")

// Determine if risk metrics should be shown
showMetrics = showRiskMetrics or (weightedAverageMain >= weightedAverageBenchmark)

// Determine the table cell color based on the Nasan Risk Score
cellColor = nasanRiskScoreRounded > 2.0 ? color.red : nasanRiskScoreRounded < 2.0 ? color.green : color.white
// === Apply color rule ===

// User input
cpf = input.float(5.0, "Capital Prudence Factor", tooltip = "If you can't afford 2X–5X position size, don't buy it. Recommended range: 2–5")
// Final CPF selection
total_exposure = PositionSize * close * cpf
bool isValid = total_exposure < capital
color posColor = isValid ? color.green : color.red
adj= isValid? math.round(PositionSize - math.sqrt(PositionSize)) : math.round(PositionSize*capital/total_exposure)
// Function to get the cell color based on specific conditions
getMetricColor(value, threshold, aboveColor, belowColor) =>
    value > threshold ? aboveColor : belowColor

// Create a single table to display all risk-related metrics
var table risk_table = table.new(position.top_right, 2, 10, border_width=1, border_color=color.blue, bgcolor=color.white)

if barstate.islast
    // Header Row
    table.cell(risk_table, 0, 0, "Metric", text_color=color.black, bgcolor=color.gray)
    table.cell(risk_table, 1, 0, "Value", text_color=color.black, bgcolor=color.gray)

    // Nasan Risk Score
    if showMetrics and not na(nasanRiskScoreRounded)
        table.cell(risk_table, 0, 1, "Nasan Risk Score", text_color=color.black)
        table.cell(risk_table, 1, 1, str.tostring(nasanRiskScoreRounded), text_color=color.white, bgcolor=cellColor)

    // Position Size
    if showMetrics
        table.cell(risk_table, 0, 2, "Position Size/Adj size", text_color=color.black)
        table.cell(risk_table, 1, 2, str.tostring(PositionSize) + "/" + str.tostring(adj), text_color=posColor, bgcolor=color.white)

    // Weighted Avg Max Drawdown
    maxDrawdownColor = getMetricColor(weighted_avg_dd, 30, color.red, color.green)
    table.cell(risk_table, 0, 3, "5 Year Weighted Avg Annual Max Drawdown", text_color=color.black)
    table.cell(risk_table, 1, 3, str.tostring(weighted_avg_dd, "#.##"), text_color=color.white, bgcolor=maxDrawdownColor)

    // Weighted Max ATR%
    maxATRColor = getMetricColor(weighted_avg_high, 5, color.red, color.green)
    table.cell(risk_table, 0, 4, "5 Year Weighted Avg Annual Max ATR%", text_color=color.black)
    table.cell(risk_table, 1, 4, str.tostring(weighted_avg_high, "#.##"), text_color=color.white, bgcolor=maxATRColor)

    // Weighted Min ATR%
    minATRColor = getMetricColor(weighted_avg_low, 2, color.red, color.green)
    table.cell(risk_table, 0, 5, "5 Year Weighted Avg Annual Min ATR%", text_color=color.black)
    table.cell(risk_table, 1, 5, str.tostring(weighted_avg_low, "#.##"), text_color=color.white, bgcolor=minATRColor)

    // Weighted Avg Stock Return vs Benchmark Return
    stockVsBenchmarkColor = weightedAverageMain > weightedAverageBenchmark ? color.green : color.red
    table.cell(risk_table, 0, 6, "5 Year Weighted Avg Annual Stock Return", text_color=color.black)
    table.cell(risk_table, 1, 6, str.tostring(weightedAverageMain, "#.##"), text_color=color.white, bgcolor=stockVsBenchmarkColor)

    // Weighted Avg Benchmark Return
    benchmarkReturnColor = weightedAverageBenchmark < 10 ? color.red : color.green
    table.cell(risk_table, 0, 7, "5 Year Weighted Avg Annual Benchmark Return", text_color=color.black)
    table.cell(risk_table, 1, 7, str.tostring(weightedAverageBenchmark, "#.##"), text_color=color.white, bgcolor=benchmarkReturnColor)

    // ATR Multiple Used
    table.cell(risk_table, 0, 8, "ATR Multiple Used", text_color=color.black)
    table.cell(risk_table, 1, 8, str.tostring(mul, "#.##"), text_color=color.purple) 
// --- Seasonality Factor Calculation ---
seasonalityFactor = input.float(1.0, "sesonality factor")  // Default neutral
// --- Seasonality-adjusted Position Size ---
seasonalityPositionSize = int(PositionSize * seasonalityFactor)
seasonalityAdj = int(adj * seasonalityFactor)
plot(adj, "PS")
// --- Add new row in risk_table ---
if barstate.islast
    table.cell(risk_table, 0, 9, "Seasonality Adj Position Size", text_color=color.black)
    table.cell(risk_table, 1, 9, str.tostring(seasonalityPositionSize) + "/" + str.tostring(seasonalityAdj), text_color=color.blue)

Overview

Nasan Risk Score & Postion Size Estimator tracks each year's high and low, converts that range into a drawdown percentage, and plots a weighted average of the most recent five years on the price chart. Users set a maximum acceptable drawdown, aggressive or conservative scaling, an ATR baseline, and a prudence factor. It can compare the symbol with an SPX benchmark and runs only on the daily timeframe. It does not place trades or define exits.

Details

Published by

regalouisei on GitHub

Code credit

federalTacos5392b, as written in the script's header

Type

Indicator, Pine Script v6

Draws

On the price chart

Category

Volatility & bands

Markets

Stocks, Indices

Timeframes

H4 and above

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
Capitalfloat10000capital
Win Rate (n)float50winRate
Profit Ratiofloat2.0profit_Ratio
Risk ScalingstringAggressivescalingType
Max Acceptable Draw Downfloat20.0Max_acceptable_dd
Benchmark (SPX)symbolSP:SPXbenchmarkTicker
Normalization Lengthint252Nor_len
Technical Lengthint21n
ATR Baseline Multiplefloat3Baseline
Show Postion Size even if Stock Return < Benchmark ReturnboolfalseshowRiskMetrics
Capital Prudence Factorfloat5.0cpf
sesonality factorfloat1.0seasonalityFactor
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

Chandelier Exit

by everget
948 stars

This indicator plots an ATR-based Chandelier Exit trailing stop on the price chart. It tracks a long stop under recent highs and a short stop above recent lows, then switches direction when price crosses the opposite stop. Buy and sell labels mark those flips.

Indicator v6 Volatility & bandsTrend Repaints
Updated 10 days ago · GPL-3.0 GitHub repository of Chandelier Exit

ICT Liquidity Void Fill

by ArunKBhaskar
575 stars

This overlay indicator marks ICT liquidity void fills on the price chart and can show long and short signals. It places a Fibonacci level inside a displacement candle, defaulting to the midpoint, and draws lines in a chosen style. Optional filters limit the fi

Indicator v6 SMC / ICT / price actionSupport & resistance
Updated 1 year ago · MPL-2.0 GitHub repository of ICT Liquidity Void Fill

This indicator plots trade entry and exit signals on the price chart by combining Bollinger Bands with optional filter conditions. It calculates standard Bollinger Bands along with RSI, Aroon, and moving average filters. Reversal signals trigger when price bre

Indicator v4 Volatility & bandsOscillators & momentum
Updated 2 months ago · None stated GitHub repository of Bollinger Bands Winner IND [Alorse]
318 stars

This indicator calculates an ATR trailing stop line derived from the highest high minus an average true range multiple over a specified lookback period. It plots the trailing stop line directly on the price chart and colors price bars based on whether the clos

Indicator v5 TrendVolatility & bands
Updated 2 months ago · MIT GitHub repository of ATR Trailing Stoploss

NVDA Trend Ribbon

by longsurf-ai
277 stars

This indicator plots three exponential moving averages and ATR volatility envelopes on the price chart. It compares the fast and slow EMAs to shade a trend ribbon and marks confirmed upward and downward crossovers with triangle labels. Settings change the thre

Indicator v6 TrendMoving averages
Updated yesterday · MIT GitHub repository of NVDA Trend Ribbon

Algo AVT

by ricardosantos79
261 stars

This indicator calculates an outlier-filtered moving average based on statistical filtering concepts. It stores close prices in a rolling array over a user-defined length, calculates the mean and standard deviation, and excludes values falling within a specifi

Indicator v4 Moving averagesVolatility & bands
Updated 4 years ago · None stated GitHub repository of Algo AVT

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