Indicator · Pine Script v5 · On the chart

CryptoVision Explorer

by unemployedrabi

Projects a distribution of possible future price moves on the price chart using a Monte Carlo style simulation of drift and returns.

View on GitHub

GitHub stars1on the repository
Pine versionv5runs as is
Lines of code430
Settings34inputs
LicenceMIT
Last update4 months ago23 Jun 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

430 lines of Pine Script v5 from pinescript-strategies-web/src/cryptovision-explorer/cryptovision_explorer.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

cryptovision_explorer.pine
//@version=5
indicator("CryptoVision Explorer", max_boxes_count=500, max_lines_count=500, max_bars_back=5000, overlay=true)

prng(series float seed, series int _range=100) =>
    var float random = 1.0
    random :=   ((3.1415926 * random %   seed) * 271.828) % _range
    float new_seed = ((seed * 1.618) % _range) + random
    [random, new_seed]

method probability(series float[] self, series int idx, series float sum) => self.get(idx) / sum * 100.0

percent    (series float   end, series float   start) => (end -   start) / start
add_percent(series float value, series float percent) => (1.0 + percent) * value

log_returns    (series float   end, series float       start) => math.log(end / start)
add_log_returns(series float value, series float log_returns) => math.exp(log_returns) * value

returns    (series float   end, series float   start, simple bool style) => style ?     percent(  end,   start) :     log_returns(  end,   start)
add_returns(series float value, series float returns, series bool style) => style ? add_percent(value, returns) : add_log_returns(value, returns)

method add        (series int[] self, series int     idx, series int     value=1) => self.set(idx, self.get(idx) + value)
method add_to_dist(series int[] self, series float value, series float bin_width) => self.add(int(math.abs(value) / bin_width), 1)

method normal_value( series float[] self,
                     series int      idx,
                     simple int    scale,
                     simple bool  invert=true) =>
    float  min = self.min()
    int normal = int((self.get(idx) - min) * (scale - 1) / (self.max() - min)) + 1
    if invert
        normal := scale - normal
    normal

sinc(series float source, series float bandwidth) =>
    float omega = math.pi * source / bandwidth
    source != 0.0 ? math.sin(omega) / omega : 1.0

type move
    int[]  polarity
    int[]  up
    int[]  down
    float  bin_width
    float  extreme
    float  drift
    string drift_style
    bool   return_style
    float  vol

slope(series int length) =>
    float sumx  = 0.0
    float sumy  = 0.0
    float sumx2 = 0.0
    float sumxy = 0.0
    for int i = 0 to length - 1
        float src = close[i]
        int idx_1 = i + 1
        sumx     += idx_1
        sumy     += src
        sumx2    += math.pow(idx_1, 2)
        sumxy    +=    src * idx_1
    float slope = -((length * sumxy - sumx * sumy) / (length * sumx2 - sumx * sumx))

standard_drift(series int length) => 
    float log_return  = math.log(close / close[1])
    float log_return2 = math.pow( log_return,  2 )
    float vari = 0.0
    float mean = 0.0
    for int i = 0 to length - 1
        mean += log_return[ i]
        vari += log_return2[i]
    mean /= length
    vari /= length * 2
    float drift = mean - vari

drift(series int length, simple string style) =>
    switch style
        "Standard"          => standard_drift(length)
        "Linear Regression" =>          slope(length)
        =>                     0.0 // "None"

volatility_adjustment(series float source, simple int length, simple bool enable) =>
    float vol_adj = ta.sma(math.sqrt(math.sum(math.pow(source, 2), length) / (length - 1)), length) * 0.5
    if not enable
        vol_adj := 0.0
    vol_adj

moves(simple int       precision,
      simple int            bins,
      simple int        lookback,
      simple string  drift_style,
      simple int    drift_length,
      simple string       source,
      simple bool   return_style,
      simple int           steps,
      simple bool volatility_adj) =>
    array<int> polarity        = array.new<int>(       2, 0)
    array<int> delta_up_dist   = array.new<int>(bins + 1, 0)
    array<int> delta_down_dist = array.new<int>(bins + 1, 0)
    float      last = source=="Move" ? close[1] : open
    float       ret = returns(close, last, return_style)
    int    rounding = precision + (return_style ? 6 : 2)
    float     delta = math.round(ret, rounding)
    float   volatil = volatility_adjustment(ret, steps, volatility_adj)
    float   extreme = math.max(math.abs(ta.highest(delta[1], lookback)),
                               math.abs(ta.lowest (delta[1], lookback)))
    float     drift = drift(drift_length == 0 ? lookback : drift_length, drift_style)
    float bin_width = extreme / bins
    if barstate.islast
        for int i = 1 to lookback
            if close[i] <= last[i]
                polarity.add(1)
                add_to_dist(delta_down_dist, delta[i], bin_width)
            else
                polarity.add(0)
                add_to_dist(delta_up_dist, delta[i], bin_width)
    move.new(polarity, delta_up_dist, delta_down_dist, bin_width, extreme, drift, drift_style, return_style, volatil)

method idx_to_percent(series move     self,
                      series int     index,
                      series float volatil,
                      simple bool polarity) =>
    (polarity ? 1 : -1) * (index * self.bin_width + volatil)
                                    

monte_carlo(series move moves, series float seed, simple int steps) =>
    array<float> monte = array.new<float>(steps)
    float    over_seed = seed
    int   polarity_sum = moves.polarity.sum()
    int   moves_up_sum = moves.up.sum()
    int   moves_dn_sum = moves.down.sum()
    if moves.up.max() > 0 and moves.down.max() > 0
        for int i = 0 to steps - 1
            [polarity_random, polarity_seed] = prng(over_seed)
            over_seed := polarity_seed
            if moves.polarity.probability(0, polarity_sum) >= polarity_random 
                int moves_up_size_1 = moves.up.size() - 1
                [move_random, move_random_seed] = prng(over_seed, moves_up_size_1)
                over_seed      := move_random_seed
                int  up_index   = int(move_random)
                bool move_found = false
                while not move_found
                    if  up_index > moves_up_size_1
                        up_index := 0
                    if moves.up.get(up_index) == 0
                        up_index += 1
                        continue
                    [move_find_random, move_find_seed] = prng(over_seed)
                    over_seed := move_find_seed
                    if moves.up.probability(up_index, moves_up_sum) >= move_find_random 
                        monte.set(i, moves.idx_to_percent(up_index, moves.vol, true))
                        move_found := true
                        break
                    else
                        up_index += 1
                continue
            else
                int moves_down_size_1 = moves.down.size() - 1
                [move_random, move_random_seed] = prng(over_seed, moves_down_size_1)
                over_seed      := move_random_seed
                int  down_index = int(move_random)
                bool move_found = false
                while not move_found
                    if  down_index > moves_down_size_1
                        down_index := 0
                    if moves.down.get(down_index) == 0
                        down_index += 1
                        continue 
                    [move_find_random, move_find_seed] = prng(over_seed)
                    over_seed := move_find_seed
                    if moves.down.probability(down_index, moves_dn_sum) >= move_find_random 
                        monte.set(i, moves.idx_to_percent(down_index, moves.vol, false))
                        move_found := true
                        break
                    else
                        down_index += 1
                continue
    [monte, over_seed]

add_drift(series float value, series float drift, series string style) =>
    switch style
        "Standard"          => add_log_returns(value, drift)
        "Linear Regression" => value + drift
        =>                     value // "None"

sim(series move moves, series float seed, simple int steps) =>
    float simulation = open
    [movements, _seed] = monte_carlo(moves, seed, steps)
    for int i = 0 to steps - 1
        simulation := add_drift(add_returns(simulation, movements.get(i), moves.return_style), moves.drift, moves.drift_style)
    [simulation, _seed]

sinc_filter(series array<float> source, simple float length) =>
    var float length_1 = length + 1.0
    if length > 0.0 and source.size() > 0
        int source_size   = array.size(source)
        int source_size_1 = source_size - 1
        array<float> est  = array.new<float>(source_size)
        for int i = 0 to source_size_1
            float sum  = 0.0
            float sumw = 0.0
            for int j = 0 to source_size_1
                float weight =  sinc(i - j, length_1)
                sum  += weight * array.get(source, j)
                sumw += weight
            float current_price = sum / sumw
            array.set(est, i, current_price >= 0.0 ? current_price : 0.0)
        est
    else
        source

monte_carlo_distribution(series move moves,
                         series float seed,
                         simple int   bins,
                         simple int  steps,
                         simple int   sims) =>
    array< int > distribution = array.new< int >(bins + 1, 0)
    array<float> sim_outcomes = array.new<float>()
    var int sims_1  = sims - 1
    float sum_stdev = 0.0
    float    reseed = seed
    for int i = 0 to sims_1
        [simulation, seed_sim] = sim(moves, reseed, steps)
        reseed    := seed_sim
        sum_stdev += math.pow(simulation - open, 2)
        sim_outcomes.push(simulation)
    float sim_lowest  = sim_outcomes.min()
    float sim_highest = sim_outcomes.max()
    float bin_width   = (sim_highest - sim_lowest) / bins
    float avg_idx_up  = 0.0
    float sum_idx_up  = 0.0
    float avg_idx_dn  = 0.0
    float sum_idx_dn  = 0.0
    for int i = 0 to sim_outcomes.size() - 1
        float outcome = sim_outcomes.get(i)
        int idx = int((outcome - sim_lowest) / bin_width)
        if outcome > open
            avg_idx_up += idx
            sum_idx_up += 1
        else
            avg_idx_dn += idx
            sum_idx_dn += 1
        distribution.add(idx)
    float avg_up   = avg_idx_up   / sum_idx_up
    float avg_dn = avg_idx_dn / sum_idx_dn
    float stdev    = math.sqrt(sum_stdev / sims)
    [distribution, bin_width, sim_lowest, sim_highest, avg_up, avg_dn, stdev, reseed]

draw_distribution(series move           moves,
                  series float           seed,
                  series bool     orientation,
                  simple int             bins,
                  simple int            steps,
                  simple int      simulations,
                  simple int            scale,
                  simple bool        avg_move,
                  simple float      deviation,
                  simple bool    enable_stdev,
                  simple bool     enable_bias,
                  simple bool      background,
                  simple color max_bear_color,
                  simple color min_bear_color,
                  simple color max_bull_color,
                  simple color min_bull_color,
                  simple color dev_high_color,
                  simple color  dev_low_color,
                  simple color     text_color,
                  simple bool    extend_lines,
                  simple bool     outcomes_on,
                  simple bool    text_on_dist,
                  simple string  move_help_on,
                  simple bool    max_expected,
                  simple float      smoothing,
                  simple bool      start_line,
                  simple color    start_color) =>
    var array< box>     dist = array.new< box>()
    var array<line> avg_line = array.new<line>()
    var string    xtend_line = extend_lines ? extend.left : extend.none
    const color    invisible = #00000000
    int offset    = steps
    int direction = orientation ? 1 : -1
    int position  = orientation ? 0 : offset
    int width     = (scale + offset) * direction
    [_monte, bin_width, lowest_sim, highest_sim, avg_idx_up, avg_idx_down, stdev, _seed] = monte_carlo_distribution(moves, seed, bins, steps, simulations)
    array<float> monte = sinc_filter(_monte, smoothing)
    float max_freq  = monte.max()
    float half_bin  = bin_width * 0.5
    float variation = stdev * deviation
    float dev_up    =               open + variation
    float dev_down  = math.max(0.0, open - variation)
    float avg_up    = avg_idx_up   * bin_width + lowest_sim
    float avg_down  = avg_idx_down * bin_width + lowest_sim
    if avg_line.size() > 0
        for int i = avg_line.size() - 1 to 0
            avg_line.get(i).delete()
            avg_line.remove(i)
    if dist.size() > 0 
        for int i = dist.size() - 1 to 0
            dist.get(i).delete()
            dist.remove(i)
    int x2 = outcomes_on ?  width + bar_index :
             orientation ? offset + bar_index :
                               -1 + bar_index
    if max_expected
        float expected       = monte.indexof(max_freq) * bin_width + lowest_sim
        color expected_color = expected > open ? min_bull_color : min_bear_color
        avg_line.push(line.new(bar_index + position, expected, x2, expected, color=expected_color, style=line.style_solid,  extend=xtend_line, width=2))

    if enable_stdev
        avg_line.push(line.new(bar_index + position, dev_up,   x2, dev_up,   color=dev_high_color, style=line.style_dotted, extend=xtend_line, width=2))
        avg_line.push(line.new(bar_index + position, dev_down, x2, dev_down, color=dev_low_color,  style=line.style_dotted, extend=xtend_line, width=2))
        if   move_help_on == "Deviation Range"
          or move_help_on == "Both"
            avg_line.push(line.new(bar_index, open, bar_index + offset, dev_up,   color=dev_high_color, style=line.style_arrow_right))
            avg_line.push(line.new(bar_index, open, bar_index + offset, dev_down, color=dev_low_color,  style=line.style_arrow_right))
    if avg_move
        avg_line.push(line.new(bar_index + position, avg_up,   x2, avg_up,   color=min_bull_color, style=line.style_dashed, extend=xtend_line, width=2))
        avg_line.push(line.new(bar_index + position, avg_down, x2, avg_down, color=min_bear_color, style=line.style_dashed, extend=xtend_line, width=2))
        if   move_help_on == "Expected"
          or move_help_on == "Both"
            avg_line.push(line.new(bar_index, open, bar_index + offset, avg_up,   color=min_bull_color, style=line.style_arrow_right))
            avg_line.push(line.new(bar_index, open, bar_index + offset, avg_down, color=min_bear_color, style=line.style_arrow_right))
    if start_line
        avg_line.push(line.new(bar_index + position, open, x2, open, color=start_color, extend=xtend_line))
    float polarity = 0.0
    float monte_sum = monte.sum()
    for int i = 0 to monte.size() - 1
        float top    = (1 + i) * bin_width + lowest_sim - half_bin
        float bottom =      i  * bin_width + lowest_sim - half_bin
        float center = math.avg(top, bottom)
        int   value  = monte.normal_value(i, scale)
        float prob   = monte.probability(i, monte_sum) 
        if center < open
            polarity += prob
        color grad_color = if center >= open
            float upper = highest_sim - half_bin
            color.from_gradient(center, open, upper, min_bull_color, max_bull_color)
        else
            float lower = lowest_sim + bin_width * 0.5
            color.from_gradient(center, lower, open, max_bear_color, min_bear_color)
        if prob > 0.0 and outcomes_on
            int left   = bar_index + (value + offset) * direction
            string txt = text_on_dist ? str.tostring(math.round(prob, 2)) + "%" : ""
            dist.push(box.new(left, top, bar_index + width, bottom, text=txt, border_color=invisible, bgcolor=grad_color, text_color=text_color))
        if background
            int left  = bar_index + position
            int right = outcomes_on ? (value + offset) * direction + bar_index :
                                              orientation ? offset + bar_index :
                                                               -1  + bar_index
            var string ext = extend_lines ? (orientation ? extend.left : extend.right) : extend.none
            color bg_color = color.from_gradient(monte.get(i), 0.0, max_freq, color.new(grad_color, 99), color.new(grad_color, 75))
            dist.push(box.new(left, top, right, bottom, invisible, bgcolor=bg_color, extend=ext))
    if enable_bias
        int left     = outcomes_on ?  width + bar_index :
                       orientation ? offset + bar_index :
                                         -1 + bar_index
        int right    = left + 2 * direction
        float bottom = lowest_sim - half_bin
        float div    = (highest_sim + half_bin - (lowest_sim - half_bin)) * (polarity / 100.0)
        dist.push(box.new(left, highest_sim + half_bin, right, div + bottom, border_color=invisible, bgcolor=min_bull_color, text="🢁\n\n" + str.tostring(math.round(100.0 - polarity, 2)) + "%", text_color=text_color))
        dist.push(box.new(left,      bottom + div,      right,       bottom, border_color=invisible, bgcolor=min_bear_color, text=str.tostring(math.round(        polarity, 2)) + "%" + "\n\n🢃", text_color=text_color))
    _seed



string source = input.string("Candle", "Derivative Source", options=["Candle", "Move"], tooltip="Candle uses the difference between Close and Open. Move uses the difference between the current close and the previous close.")

string controls = "Primary Controls"
int simulations = input.int  ( 500, "Number of Simulations", group=controls, minval= 50, step=  50, tooltip="This adjusts the number of simulations the indicator will preform. A larger number is alway preferable but isn't always feasible. The larger the number the more accurate the indicator will be.")
int    lookback = input.int  ( 500,              "Lookback", group=controls, minval= 50, step=  50, tooltip="This determines the number of historical candles to take into account. A larger number will allow for more detail in the simulation but will also make it less relevant.")
int       steps = input.int  (  10,     "Steps Into Future", group=controls, minval=  2, step=   1, tooltip="This determines the number of steps into the future to predict. The further into the future you go, the more resources it will utilize. potentially resulting in the indicator not loading.")
int        bins = input.int  (  50,   "Outcome Granularity", group=controls, minval= 10, step=   5, tooltip="This is the number of rows in the final distribution of simulations. This determines the granularity of the final result.")
float smoothing = input.float(1.75,     "Outcome Smoothing", group=controls, minval=0.0, step=0.25, tooltip="Smooth the distribution of the outcomes. When its set to 0 it will not apply smoothing.")
int granularity = input.int  (  25,   "Returns Granularity", group=controls, minval=  5, step=   5, tooltip="This adjusts the granularity of the distribution of price movements. A larger number can be more accurate but it will sacrifice loading time.")

string  adjustments = "Additional Adjustments"
int    drift_length = input.int   (           34,             "Drift", group=adjustments, inline="drift", minval=0)
string  drift_style = input.string(   "Standard",            "Style:", group=adjustments, inline="drift", options=["Linear Regression", "Standard", "None"], tooltip="Drift adds trend to the simulation. Without drift, the simulation will assume a trendless market. Linear Regression uses linear regression to determine trend while Standard Drift uses a volatility degraded average return.\n\nBoth are excellent options and are generally very similar. Set this to 0 to use the same window size as the lookback. A shorter period will use the short term trend while a longer period will use a longer term trend.")
bool volatility_adj = input.bool  (         true, "Volatility Adjust", group=adjustments,            tooltip="Adjust the simulation to include the current volatility of returns. This will prevent the simulation from underestimating the variance in movements.")
bool   return_style = input.string("Log Returns",     "Returns Style", group=adjustments, options=["Percent", "Log Returns"], tooltip="Percent uses % change for the calculations while Log Returns uses log returns for the calculations.") == "Percent"
int       precision = input.int   (            4,         "Precision", group=adjustments,  minval=1, tooltip="Precision lets you adjust the level of rounding for the price movements. A smaller number will be faster but it will sacrifice accuracy.")
bool wait_for_steps = input.bool  (        false,  "Update Every Bar", group=adjustments,            tooltip="Enable this to update the prediction on every bar.")

string      visuals = "Visual Preferences"
bool    orientation = input.string("Right",         "Side of Chart", group=visuals, options=["Right", "Left"], tooltip="Choose which side of the chart you want the indicator on.") == "Right"
string move_help_on = input.string( "Both",    "Move Visualization", group=visuals, options=["Expected", "Deviation Range", "Both", "None"])
bool       avg_move = input.bool  (   true,      "Most Likely Move", group=visuals, tooltip="This plots the most likely up and down move for the current estimation period. These may be used as targets for your trade.")
bool   enable_stdev = input.bool  (   true,    "Standard Deviation", group=visuals,  inline="stdev")
float     deviation = input.float (    1.0,                      "", group=visuals,  inline="stdev", minval=0.0, step=0.5, tooltip="This is the range in which most of the simulations fall between. It acts as a prediction level for a  volatile move.")
bool    enable_bias = input.bool  (   true, "Most Likely Direction", group=visuals, tooltip="This shows you the sum of up and down probabilities. It allows you to quickly see what the likelihood of a move in either direction is.")
bool   max_expected = input.bool  (   true,  "Max Probability Zone", group=visuals, tooltip="This highlights the area with the largest outcome probability.")
bool    outcomes_on = input.bool  (   true,  "Outcome Distribution", group=visuals,  inline="dist")
int           scale = input.int   (     30,                      "", group=visuals,  inline="dist", minval=10, tooltip="Enable to display the distribution of outcomes. Adjust this changes the horizontal length of the distribution.")
bool   text_on_dist = input.bool  (   true,     "Distribution Text", group=visuals, tooltip="Enable outcome probabilities to be show in the distribution.")
bool     background = input.bool  (   true,            "Background", group=visuals, tooltip="Display a background of the distribution for the duration of the prediction interval.")
bool     start_line = input.bool  (   true,         "Starting Line", group=visuals, tooltip="Show the starting point of the simulation.")
bool   extend_lines = input.bool  (   true,          "Extend Lines", group=visuals, tooltip="Extend the lines and background.")

string      coloring = "Color Preferences"
color max_bear_color = input.color(#FFA0CC,     "Bearish Colors     ", group=coloring, inline="bear")
color min_bear_color = input.color(#FF22CC,                        "", group=coloring, inline="bear")
color max_bull_color = input.color(#00FFFF,    "Bullish Colors      ", group=coloring, inline="bull")
color min_bull_color = input.color(#0066FF,                        "", group=coloring, inline="bull")
color dev_high_color = input.color(#FFB617, "Deviation Color - High:", group=coloring, inline="dev" )
color dev_low_color  = input.color(#2672ff,                    "Low:", group=coloring, inline="dev" )
color start_color    = input.color(#7E7E7E,        "Start Line Color", group=coloring)
color text_color     = input.color(#FFFFFF,              "Text Color", group=coloring)



move rand_moves = moves(precision, granularity, lookback, drift_style, drift_length, source, return_style, steps, volatility_adj)
var float seed = 1
[_, re_seed] = prng(seed)
seed := re_seed

if barstate.islast 
    var int counter = -1
    if counter == -1
        int bar_index_1 = bar_index + 1
        if bar_index_1 < lookback
            runtime.error('Please use a "Lookback" input setting that is less than: ' + str.tostring(bar_index))
        if bar_index_1 < drift_length
            runtime.error('Please use a "Drift" input setting that is less than: '    + str.tostring(bar_index))
    counter += 1
    bool once = counter == 0 ? true : barstate.isconfirmed
    bool wait = not wait_for_steps ? 0 == counter % steps and once :
                                     0 == counter or barstate.isconfirmed
    if wait
        seed :=  draw_distribution(rand_moves, seed, orientation, bins, steps, simulations, scale, avg_move, deviation, enable_stdev, enable_bias,
                                   background, max_bear_color, min_bear_color, max_bull_color, min_bull_color, dev_high_color, dev_low_color, text_color,
                                   extend_lines, outcomes_on, text_on_dist, move_help_on, max_expected, smoothing, start_line, start_color)

Overview

Settings control the number of simulations, lookback, steps into the future, outcome bins, smoothing, drift method (standard or linear regression), log or percentage returns and an optional volatility adjustment. It can display the most likely move, a standard deviation range, a bias marker and a probability distribution. The output is a statistical estimate, not a forecast.

Details

Published by

unemployedrabi on GitHub

Type

Indicator, Pine Script v5

Draws

On the price chart

Category

Volatility & bands

Markets

Crypto

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
Derivative SourcestringCandlesource
Number of Simulationsint500simulations
Lookbackint500lookback
Steps Into Futureint10steps
Outcome Granularityint50bins
Outcome Smoothingfloat1.75smoothing
Returns Granularityint25granularity
Driftint34drift_length
Style:stringStandarddrift_style
Volatility Adjustbooltruevolatility_adj
Returns StylestringLog Returnsreturn_style
Precisionint4precision
Show all 34 settings
SettingTypeDefaultVariable
Update Every Barboolfalsewait_for_steps
Side of ChartstringRightorientation
Move VisualizationstringBothmove_help_on
Most Likely Movebooltrueavg_move
Standard Deviationbooltrueenable_stdev
deviationfloat1.0deviation
Most Likely Directionbooltrueenable_bias
Max Probability Zonebooltruemax_expected
Outcome Distributionbooltrueoutcomes_on
scaleint30scale
Distribution Textbooltruetext_on_dist
Backgroundbooltruebackground
Starting Linebooltruestart_line
Extend Linesbooltrueextend_lines
Bearish Colors     color#FFA0CCmax_bear_color
min_bear_colorcolor#FF22CCmin_bear_color
Bullish Colors      color#00FFFFmax_bull_color
min_bull_colorcolor#0066FFmin_bull_color
Deviation Color - High:color#FFB617dev_high_color
Low:color#2672ffdev_low_color
Start Line Colorcolor#7E7E7Estart_color
Text Colorcolor#FFFFFFtext_color
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 11 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 2 days ago · 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