// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © joebaus
//@version=5
// ———————————————————— Acknowledgements {
// - Fortunate, a good friend who helped me significantly start my research.
// - Telugu Traders Community, for their video on calculating cones.
// - Savva Shanaev, for his NEDL tutorial on the Laplace distribution.
// - JeylaniB, for his Pine Script V5 extension for VS Studio Code.
// - PineCoders and TradingView, for great Pine documentation and features.
// - @RicardoSantos, for example code and idea of the Select Date feature.
// - Anton Berlin, for his discussions on statistical interpretations.
// }
// ———————————————————— Indicator {
indicator(
shorttitle = "Probability Cones",
title = "Probability Cones",
max_lines_count = 500,
max_bars_back = 5000,
overlay = true)
// }
// ———————————————————— Constants {
// All tooltip constants are prefixed with "T_".
T_SRC = "The data source to use for calculating the probability cones."
T_DEV = "Select the calculation method for the cone deviations."
T_LOOKBACK = "The number of bars sampled for the probability calculations. Minimum value: 1 and Maximum value: 5000"
T_FORECAST = "The number of bars to project the probability cones forward. At 70 bars with all cones enabled, TradingView's line limitations will be hit, and the indicator will begin to remove earlier lines. Either keep this input below 70 or hide cones to get extra drawing lines."
T_FILLS = "The background color highlights between cone lines."
T_BARSBACK = "The number of bars + or - to position the probability cones."
T_CONELOCK = "Enables Anchor Type inputs. Keeps the cone origin stationary based on the Anchor Type selected. When disabled, cone origin will use a rolling window placement using the Bars Back to Place Cones input."
T_ANCHOR = "Select the method to anchor the probability cone origin."
T_DATE = "Keeps the cone origin stationary at the selected date."
T_HTF = "Sets the cone's origin to the beginning of a specified timeframe. Updates the cones automatically when a new period begins."
T_OFFSET = "The number of bars + or - to position cones after being anchored. Only effects the Higher Timeframe Anchor Type."
T_MEAN = "Select the desired mean for the cones. The Auto setting will use the default, recommended means for the current Deviation input. By default: Standard uses Average, Laplace and Absolute Deviation use Median."
T_MEANDRIFT = "Adds or removes the drift to the cones caused by the mean's increasing or decreasing value in the future. Turning \"Use Mean Drift\" off projects forward only the initial value of the mean, and shifts the values of the cone's deviation lines relative to the mean."
// All group constants are prefixed with "G_".
G_SETTINGS = "Cone Settings"
G_ANCHOR = "Anchor Settings "
G_MEAN = "Mean Settings"
G_CONE1_SETTINGS = "First Cone's Settings"
G_CONE2_SETTINGS = "Second Cone's Settings"
G_CONE3_SETTINGS = "Third Cone's Settings"
// Constants for i_deviation
DEV_STANDARD = "Standard"
DEV_LAPLACE = "Laplace Stdev"
DEV_MAD = "Absolute"
// Constants for i_anchorType
AT_BAR = "Bar"
AT_DATE = "Select Date"
AT_HTF = "Higher Timeframe"
// Constants for i_mu
MU_AUTO = "Auto"
MU_AVERAGE = "Average"
MU_MEDIAN = "Median"
// Constants for f_lineStyle()
LINE_STYLE_SOLID = "Solid"
LINE_STYLE_DASHED = "Dashed"
LINE_STYLE_DOTTED = "Dotted"
// Inline constants.
INLINE_CONE_DEV = "Cone Deviations"
INLINE_CONE_STYLE = "Cone Line Styles"
INLINE_CONE_COLOR = "Cone Line Colors"
INLINE_CONE_WIDTH = "Cone Line Widths"
INLINE_FILL_COLOR = "Fill Color"
INLINE_FILL_BOOL = "Fill Bool"
INLINE_MEAN_1 = "Mean Inline Settings 1"
INLINE_MEAN_2 = "Mean Inline Settings 2"
// }
// ———————————————————— Inputs {
// Here is how the cone in variables are written:
// Cone Order: "first", "second", or "third" cone.
// Position: Upper "Up" or lower "Dn" line of the cone.
// Attribute: "Color", "Width", etc.
// All inputs prefixed with "i_", all arrays prefixed with "a_".
// E.g. i_firstUpColor is the input for the first cone's, upper line, color.
// ———————————————————— General Settings Inputs {
i_src = input.source(
defval = close,
title = "Source",
tooltip = T_SRC,
group = G_SETTINGS)
i_deviation = input.string(
defval = DEV_STANDARD,
title = "Deviation",
options = [DEV_STANDARD,
DEV_LAPLACE,
DEV_MAD],
tooltip = T_DEV,
group = G_SETTINGS)
i_lookBack = input.int(
defval = 500,
title = "Bar Lookback",
minval = 1,
maxval = 5000,
tooltip = T_LOOKBACK,
group = G_SETTINGS)
i_forecast = input.int(
defval = 30,
title = "Bar Forecast",
minval = 1,
tooltip = T_FORECAST,
group = G_SETTINGS)
i_meanDriftBool = input.bool(
defval = true,
title = "Use Mean Drift",
tooltip = T_MEANDRIFT,
group = G_SETTINGS)
i_fillBool = input.bool(
defval = true,
title = "Show Fills",
tooltip = T_FILLS,
group = G_SETTINGS)
// }
// ———————————————————— Anchor Settings {
i_barsBack = input.int(
defval = 20,
title = "Bars Back to Place Cones",
tooltip = T_BARSBACK,
group = G_ANCHOR)
i_coneLock = input.bool(
defval = false,
title = "Lock Cones to Anchor Type",
tooltip = T_CONELOCK,
group = G_ANCHOR)
i_anchorType = input.string(
defval = AT_BAR,
title = "Anchor Type",
options = [AT_BAR,
AT_DATE,
AT_HTF],
tooltip = T_ANCHOR,
group = G_ANCHOR)
// @RicardoSantos contribution
i_anchorDate = time == input.time(
defval = timestamp("2022-01-01"),
title = "Select Date to Place Cones",
tooltip = T_DATE,
group = G_ANCHOR)
i_anchorHtf = input.timeframe(
defval = "W",
title = "Higher Timeframe Anchor",
tooltip = T_HTF,
group = G_ANCHOR)
i_anchorOffset = input.int(
defval = 1,
title = "HTF Anchor Offset",
tooltip = T_OFFSET,
group = G_ANCHOR)
// }
// ———————————————————— Mean Input Settings {
i_muBool = input.bool(
defval = true,
title = "Show Mean",
group = G_MEAN)
i_muCalc = input.string(
defval = MU_AUTO,
title = "Mean Calculation",
options = [MU_AUTO,
MU_AVERAGE,
MU_MEDIAN],
tooltip = T_MEAN,
inline = INLINE_MEAN_1,
group = G_MEAN)
i_muColor = input.color(
defval = color.new(color.orange, 0),
title = "Color",
inline = INLINE_MEAN_2,
group = G_MEAN)
i_muWidth = input.int(
defval = 2,
title = "Width",
minval = 1,
maxval = 4,
inline = INLINE_MEAN_2,
group = G_MEAN)
i_muLineStyle = input.string(
defval = LINE_STYLE_DOTTED,
title = "Line Style",
options = [LINE_STYLE_SOLID,
LINE_STYLE_DASHED,
LINE_STYLE_DOTTED],
inline = INLINE_MEAN_2,
group = G_MEAN)
// }
// ———————————————————— First Cone's Input Settings {
i_firstConeBool = input.bool(
defval = true,
title = "Show First Cone",
group = G_CONE1_SETTINGS)
i_firstUpColor = input.color(
defval = color.new(color.green, 0),
title = "Upper Cone Color",
inline = INLINE_CONE_COLOR,
group = G_CONE1_SETTINGS)
i_firstDnColor = input.color(
defval = color.new(color.green, 0),
title = "Lower Cone Color",
inline = INLINE_CONE_COLOR,
group = G_CONE1_SETTINGS)
i_firstUpDev = input.float(
defval = 1,
title = "Upper Deviation",
step = 0.01,
inline = INLINE_CONE_DEV,
group = G_CONE1_SETTINGS)
// Dn cone deviation inputs are positive, and made negative later.
i_firstDnDev = input.float(
defval = 1,
title = "Lower Deviation",
step = 0.01,
inline = INLINE_CONE_DEV,
group = G_CONE1_SETTINGS)
i_firstUpLineStyle = input.string(
defval = LINE_STYLE_DOTTED,
title = "Upper Line Style",
options = [LINE_STYLE_SOLID,
LINE_STYLE_DASHED,
LINE_STYLE_DOTTED],
inline = INLINE_CONE_STYLE,
group = G_CONE1_SETTINGS)
i_firstDnLineStyle = input.string(
defval = LINE_STYLE_DOTTED,
title = "Lower Line Style",
options = [LINE_STYLE_SOLID,
LINE_STYLE_DASHED,
LINE_STYLE_DOTTED],
inline = INLINE_CONE_STYLE,
group = G_CONE1_SETTINGS)
i_firstUpWidth = input.int(
defval = 2,
title = "Upper Cone Width",
minval = 1,
maxval = 4,
inline = INLINE_CONE_WIDTH,
group = G_CONE1_SETTINGS)
i_firstDnWidth = input.int(
defval = 2,
title = "Lower Cone Width",
minval = 1,
maxval = 4,
inline = INLINE_CONE_WIDTH,
group = G_CONE1_SETTINGS)
i_firstUpFillBool = input.bool(
defval = true,
title = "Show Upper Fill",
inline = INLINE_FILL_BOOL,
group = G_CONE1_SETTINGS)
i_firstDnFillBool = input.bool(
defval = true,
title = "Show Lower Fill",
inline = INLINE_FILL_BOOL,
group = G_CONE1_SETTINGS)
i_firstUpFill = input.color(
defval = color.new(color.green, 95),
title = "Upper Fill Color",
inline = INLINE_FILL_COLOR,
group = G_CONE1_SETTINGS)
i_firstDnFill = input.color(
defval = color.new(color.green, 95),
title = "Lower Fill Color",
inline = INLINE_FILL_COLOR,
group = G_CONE1_SETTINGS)
// }
// ———————————————————— Second Cone's Input Settings {
i_secondConeBool = input.bool(
defval = true,
title = "Show Second Cone",
group = G_CONE2_SETTINGS)
i_secondUpColor = input.color(
defval = color.new(color.blue, 0),
title = "Upper Cone Color",
inline = INLINE_CONE_COLOR,
group = G_CONE2_SETTINGS)
i_secondDnColor = input.color(
defval = color.new(color.blue, 0),
title = "Lower Cone Color",
inline = INLINE_CONE_COLOR,
group = G_CONE2_SETTINGS)
i_secondUpDev = input.float(
defval = 2,
title = "Upper Deviation",
step = 0.01,
inline = INLINE_CONE_DEV,
group = G_CONE2_SETTINGS)
// Dn cone deviation inputs are positive, and made negative later.
i_secondDnDev = input.float(
defval = 2,
title = "Lower Deviation",
step = 0.01,
inline = INLINE_CONE_DEV,
group = G_CONE2_SETTINGS)
i_secondUpLineStyle = input.string(
defval = LINE_STYLE_DOTTED,
title = "Upper Line Style",
options = [LINE_STYLE_SOLID,
LINE_STYLE_DASHED,
LINE_STYLE_DOTTED],
inline = INLINE_CONE_STYLE,
group = G_CONE2_SETTINGS)
i_secondDnLineStyle = input.string(
defval = LINE_STYLE_DOTTED,
title = "Lower Line Style",
options = [LINE_STYLE_SOLID,
LINE_STYLE_DASHED,
LINE_STYLE_DOTTED],
inline = INLINE_CONE_STYLE,
group = G_CONE2_SETTINGS)
i_secondWidthUp = input.int(
defval = 2,
title = "Upper Cone Width",
minval = 1,
maxval = 4,
inline = INLINE_CONE_WIDTH,
group = G_CONE2_SETTINGS)
i_secondDnWidth = input.int(
defval = 2,
title = "Lower Cone Width",
minval = 1,
maxval = 4,
inline = INLINE_CONE_WIDTH,
group = G_CONE2_SETTINGS)
i_secondUpFillBool = input.bool(
defval = true,
title = "Show Upper Fill",
inline = INLINE_FILL_BOOL,
group = G_CONE2_SETTINGS)
i_secondDnFillBool = input.bool(
defval = true,
title = "Show Lower Fill",
inline = INLINE_FILL_BOOL,
group = G_CONE2_SETTINGS)
i_secondUpFill = input.color(
defval = color.new(color.blue, 95),
title = "Fill Upper Color",
inline = INLINE_FILL_COLOR,
group = G_CONE2_SETTINGS)
i_secondDnFill = input.color(
defval = color.new(color.blue, 95),
title = "Fill Lower Color",
inline = INLINE_FILL_COLOR,
group = G_CONE2_SETTINGS)
// }
// ———————————————————— Third Cone's Input Settings {
i_thirdConeBool = input.bool(
defval = true,
title = "Show Third Cone",
group = G_CONE3_SETTINGS)
i_thirdUpColor = input.color(
defval = color.new(color.red, 0),
title = "Upper Cone Color",
inline = INLINE_CONE_COLOR,
group = G_CONE3_SETTINGS)
i_thirdDnColor = input.color(
defval = color.new(color.red, 0),
title = "Lower Cone Color",
inline = INLINE_CONE_COLOR,
group = G_CONE3_SETTINGS)
i_thirdUpDev = input.float(
defval = 3,
title = "Upper Deviation",
step = 0.01,
inline = INLINE_CONE_DEV,
group = G_CONE3_SETTINGS)
// Dn cone deviation inputs are positive, made negative later.
i_thirdDnDev = input.float(
defval = 3,
title = "Lower Deviation",
step = 0.01,
inline = INLINE_CONE_DEV,
group = G_CONE3_SETTINGS)
i_thirdUpLineStyle = input.string(
defval = LINE_STYLE_DOTTED,
title = "Upper Line Style",
options = [LINE_STYLE_SOLID,
LINE_STYLE_DASHED,
LINE_STYLE_DOTTED],
inline = INLINE_CONE_STYLE,
group = G_CONE3_SETTINGS)
i_thirdDnLineStyle = input.string(
defval = LINE_STYLE_DOTTED,
title = "Lower Line Style",
options = [LINE_STYLE_SOLID,
LINE_STYLE_DASHED,
LINE_STYLE_DOTTED],
inline = INLINE_CONE_STYLE,
group = G_CONE3_SETTINGS)
i_thirdUpWidth = input.int(
defval = 2,
title = "Upper Cone Width",
minval = 1,
maxval = 4,
inline = INLINE_CONE_WIDTH,
group = G_CONE3_SETTINGS)
i_thirdDnWidth = input.int(
defval = 2,
title = "Lower Cone Width",
minval = 1,
maxval = 4,
inline = INLINE_CONE_WIDTH,
group = G_CONE3_SETTINGS)
i_thirdUpFillBool = input.bool(
defval = true,
title = "Show Upper Fill",
inline = INLINE_FILL_BOOL,
group = G_CONE3_SETTINGS)
i_thirdDnFillBool = input.bool(
defval = true,
title = "Show Lower Fill",
inline = INLINE_FILL_BOOL,
group = G_CONE3_SETTINGS)
i_thirdUpFill = input.color(
defval = color.new(color.red, 95),
title = "Fill Upper Color",
inline = INLINE_FILL_COLOR,
group = G_CONE3_SETTINGS)
i_thirdDnFill = input.color(
defval = color.new(color.red, 95),
title = "Fill Lower Color",
inline = INLINE_FILL_COLOR,
group = G_CONE3_SETTINGS)
// }
// }
// ———————————————————— Calculations {
// ———————————————————— Array Index Variables {
// coneForecast adds 1 to i_forecast.
// This prevents an array from being a length making the forecast 1 bar short.
coneForecast = i_forecast + 1
// coneForecastIndex stops repetitition in "for" loops.
// While i_forecast is equivalent, this variable is explicit for indexing.
coneForecastIndex = coneForecast - 1
// }
// ———————————————————— Cone Origin Anchor Variables {
// Barlock variable
barLock = ta.valuewhen(barstate.isnew == true, bar_index, 0)
// Date Select, anchor variable
// @RicardoSantos contribution
var int dateAnchor = na
// Last time i_anchorDate was true, get bar_index and set to dateAnchor.
if i_anchorDate == true
dateAnchor := bar_index
// Get the close of the prior, historical higher timeframe.
// barmerge.lookahead_on resolves historical cone anchor repaints.
higherTimeframe = request.security(
symbol = syminfo.tickerid,
timeframe = i_anchorHtf,
expression = close[1],
lookahead = barmerge.lookahead_on)
// Find the numbers of barssince the start a new candle based on i_anchorHtf.
htfAnchor = ta.barssince(higherTimeframe[1] != higherTimeframe)
// If i_coneLock is enabled, use the respective anchorBarIndex bar_index input.
// Otherwise, default back to the i_barsBack input.
anchorBar = switch i_coneLock
true => bar_index - i_barsBack - (bar_index - barLock[1] - 1)
false => bar_index - i_barsBack
anchorDate = switch i_coneLock
true => dateAnchor
false => bar_index - i_barsBack
anchorHtf = switch i_coneLock
true => bar_index - htfAnchor - i_anchorOffset
false => bar_index - i_barsBack
// What bar index to start displaying the cones. Used for f_coneLine().
anchorBarIndex = switch i_anchorType
AT_BAR => anchorBar
AT_DATE => anchorDate
AT_HTF => anchorHtf
// If i_coneLock is enabled, use the respective i_anchorType subscript input.
// Otherwise, default back to the i_barsBack input.
anchorBarSub = switch i_coneLock
true => i_barsBack + (bar_index - barLock[1] - 1)
false => i_barsBack
anchorDateSub = switch i_coneLock
true => bar_index - dateAnchor
false => i_barsBack
anchorHtfSub = switch i_coneLock
true => htfAnchor + i_anchorOffset
false => i_barsBack
// Get the equivalent anchorBarIndex value to use as a subscript[] for variables.
// Used in "Devation and Mean Switches", and "Cone Value Array" sections.
anchorBarIndexSub = switch i_anchorType
AT_BAR => anchorBarSub
AT_DATE => anchorDateSub
AT_HTF => anchorHtfSub
// }
// ———————————————————— Log Returns Variables {
logReturns = math.log(i_src / i_src[1])
logReturnsMed = ta.median(logReturns, i_lookBack)
logReturnsAvg = ta.sma(logReturns, i_lookBack)
logReturnsDev = ta.stdev(logReturns, i_lookBack)
// }
// ———————————————————— Mean Switches {
// Based on i_deviation, select the mean.
meanAuto = switch i_deviation
DEV_STANDARD => logReturnsAvg[anchorBarIndexSub]
DEV_LAPLACE => logReturnsMed[anchorBarIndexSub]
DEV_MAD => logReturnsMed[anchorBarIndexSub]
// Based on the mean input, return autoMean or a manually selected mean.
meanSwitch = switch i_muCalc
MU_AUTO => meanAuto
MU_AVERAGE => logReturnsAvg
MU_MEDIAN => logReturnsMed
// }
// ———————————————————— Absolute Deviation Calculation {
a_absDev = array.new_float(i_lookBack, na)
for i = 0 to i_lookBack - 1
_absDev = math.abs(logReturns - meanSwitch) // Absolute Deviation Calculation
array.set(id = a_absDev, index = i, value = _absDev)
absDev = array.avg(id = a_absDev) // Absolute Deviation
// }
// ———————————————————— Laplace Standard Deviation Calculation {
laplaceVar = 2 * math.pow(absDev, 2)
laplaceStdev = math.sqrt(laplaceVar)
// }
// ———————————————————— Devation Switches {
devSelectUp = switch i_deviation
DEV_STANDARD => logReturnsDev[anchorBarIndexSub]
DEV_LAPLACE => laplaceStdev[anchorBarIndexSub]
DEV_MAD => absDev[anchorBarIndexSub]
devSelectDn = switch i_deviation
DEV_STANDARD => logReturnsDev[anchorBarIndexSub]
DEV_LAPLACE => laplaceStdev[anchorBarIndexSub]
DEV_MAD => absDev[anchorBarIndexSub]
// }
// ———————————————————— a_conePeriod and a_conePeriodSqrt {
// Holds an increasing int series: 1, 2, 3... up to coneForecast
// This counts the number of bars to forecast the cones forward.
a_conePeriod = array.new_int(size = coneForecast, initial_value = na)
// Holds square root of a_conePeriod.
// When multiplied by a deviation, generates the a cone line's curve.
a_conePeriodSqrt = array.new_float(size = coneForecast, initial_value = na)
for i = 0 to coneForecastIndex
int _conePeriod = na
_conePeriod := i + 1
array.set(id = a_conePeriod, index = i, value = _conePeriod)
_conePeriodSqrt = math.sqrt(number = _conePeriod)
array.set(id = a_conePeriodSqrt, index = i, value = _conePeriodSqrt)
// }
// ———————————————————— conePeriod and DevSqrt Arrays {
a_conePeriodAvg = array.new_float(size = coneForecast, initial_value = na)
// Arrays for the three cones.
a_firstUpDevSqrt = array.new_float(size = coneForecast, initial_value = na)
a_firstDnDevSqrt = array.new_float(size = coneForecast, initial_value = na)
a_secondUpDevSqrt = array.new_float(size = coneForecast, initial_value = na)
a_secondDnDevSqrt = array.new_float(size = coneForecast, initial_value = na)
a_thirdUpDevSqrt = array.new_float(size = coneForecast, initial_value = na)
a_thirdDnDevSqrt = array.new_float(size = coneForecast, initial_value = na)
for i = 0 to coneForecastIndex
// When i_meanDriftBool is true, multiply the mean by a_conePeriod at i
// If false, set the initial mean value, from i to coneForecastIndex, to a_conePeriodAvg
_conePeriodAvg = switch i_meanDriftBool
true => meanSwitch * array.get(id = a_conePeriod, index = i)
false => meanSwitch
array.set(id = a_conePeriodAvg, index = i, value = _conePeriodAvg)
// Multiply the stdev of log returns by the sqrt of the cone period.
_firstUpDevSqrt = i_firstUpDev * devSelectUp * array.get(id = a_conePeriodSqrt, index = i)
array.set(id = a_firstUpDevSqrt, index = i, value = _firstUpDevSqrt)
_firstDnDevSqrt = i_firstDnDev * devSelectDn * array.get(id = a_conePeriodSqrt, index = i)
array.set(id = a_firstDnDevSqrt, index = i, value = _firstDnDevSqrt)
_secondUpDevSqrt = i_secondUpDev * devSelectUp * array.get(id = a_conePeriodSqrt, index = i)
array.set(id = a_secondUpDevSqrt, index = i, value = _secondUpDevSqrt)
_secondDnDevSqrt = i_secondDnDev * devSelectDn * array.get(id = a_conePeriodSqrt, index = i)
array.set(id = a_secondDnDevSqrt, index = i, value = _secondDnDevSqrt)
_thirdUpDevSqrt = i_thirdUpDev * devSelectUp * array.get(id = a_conePeriodSqrt, index = i)
array.set(id = a_thirdUpDevSqrt, index = i, value = _thirdUpDevSqrt)
_thirdDnDevSqrt = i_thirdDnDev * devSelectDn * array.get(id = a_conePeriodSqrt, index = i)
array.set(id = a_thirdDnDevSqrt, index = i, value = _thirdDnDevSqrt)
// }
// ———————————————————— Percent Arrays {
a_firstUpPercent = array.new_float(size = coneForecast, initial_value = na)
a_firstDnPercent = array.new_float(size = coneForecast, initial_value = na)
a_secondUpPercent = array.new_float(size = coneForecast, initial_value = na)
a_secondDnPercent = array.new_float(size = coneForecast, initial_value = na)
a_thirdUpPercent = array.new_float(size = coneForecast, initial_value = na)
a_thirdDnPercent = array.new_float(size = coneForecast, initial_value = na)
for i = 0 to coneForecastIndex
// If i_meanDriftBool is true, a_conePeriodAvg equals meanSwitch for i to coneForecastIndex
_firstUpPercent = array.get(id = a_conePeriodAvg, index = i) +
array.get(id = a_firstUpDevSqrt, index = i)
array.set(id = a_firstUpPercent, index = i, value = _firstUpPercent)
_firstDnPercent = array.get(id = a_conePeriodAvg, index = i) -
array.get(id = a_firstDnDevSqrt, index = i)
array.set(id = a_firstDnPercent, index = i, value = _firstDnPercent)
_secondUpPercent = array.get(id = a_conePeriodAvg, index = i) +
array.get(id = a_secondUpDevSqrt, index = i)
array.set(id = a_secondUpPercent, index = i, value = _secondUpPercent)
_secondDnPercent = array.get(id = a_conePeriodAvg, index = i) -
array.get(id = a_secondDnDevSqrt, index = i)
array.set(id = a_secondDnPercent, index = i, value = _secondDnPercent)
_thirdUpPercent = array.get(id = a_conePeriodAvg, index = i) +
array.get(id = a_thirdUpDevSqrt, index = i)
array.set(id = a_thirdUpPercent, index = i, value = _thirdUpPercent)
_thirdDnPercent = array.get(id = a_conePeriodAvg, index = i) -
array.get(id = a_thirdDnDevSqrt, index = i)
array.set(id = a_thirdDnPercent, index = i, value = _thirdDnPercent)
// }
// ———————————————————— Cone Value Arrays {
a_meanValue = array.new_float(size = coneForecast, initial_value = na)
a_firstUpValue = array.new_float(size = coneForecast, initial_value = na)
a_firstDnValue = array.new_float(size = coneForecast, initial_value = na)
a_secondUpValue = array.new_float(size = coneForecast, initial_value = na)
a_secondDnValue = array.new_float(size = coneForecast, initial_value = na)
a_thirdUpValue = array.new_float(size = coneForecast, initial_value = na)
a_thirdDnValue = array.new_float(size = coneForecast, initial_value = na)
for i = 0 to coneForecastIndex
_a_meanValue = i_src[anchorBarIndexSub] * math.exp( array.get(id = a_conePeriodAvg, index = i) )
array.set(id = a_meanValue, index = i, value = _a_meanValue)
_firstUpConeValue = i_src[anchorBarIndexSub] * math.exp( array.get(id = a_firstUpPercent, index = i) )
array.set(id = a_firstUpValue, index = i, value = _firstUpConeValue)
_firstDnConeValue = i_src[anchorBarIndexSub] * math.exp( array.get(id = a_firstDnPercent, index = i) )
array.set(id = a_firstDnValue, index = i, value = _firstDnConeValue)
_secondUpConeValue = i_src[anchorBarIndexSub] * math.exp( array.get(id = a_secondUpPercent, index = i) )
array.set(id = a_secondUpValue, index = i, value = _secondUpConeValue)
_secondDnConeValue = i_src[anchorBarIndexSub] * math.exp( array.get(id = a_secondDnPercent, index = i) )
array.set(id = a_secondDnValue, index = i, value = _secondDnConeValue)
_thirdUpConeValue = i_src[anchorBarIndexSub] * math.exp( array.get(id = a_thirdUpPercent, index = i) )
array.set(id = a_thirdUpValue, index = i, value = _thirdUpConeValue)
_thirdDnConeValue = i_src[anchorBarIndexSub] * math.exp( array.get(id = a_thirdDnPercent, index = i) )
array.set(id = a_thirdDnValue, index = i, value = _thirdDnConeValue)
// }
// }
// ———————————————————— Lines and Fills {
// ———————————————————— Draw Functions {
// ———————————————————— Line Style Function {
f_lineStyle(_lineStyle) =>
// @param _lineStyle, user input line style variable.
_output = switch _lineStyle
LINE_STYLE_SOLID => line.style_solid
LINE_STYLE_DASHED => line.style_dashed
LINE_STYLE_DOTTED => line.style_dotted
// }
// ———————————————————— Cone Line Function {
f_coneLine(_a_coneValue, _color, _style, _width, _coneToggle) =>
// @param _a_coneValue, the array holding the cone's forecast values.
// @param _color, line color variable.
// @param _style, line style variable.
// @param _width, line width variable.
// @param _coneToggle, bool input for this line.
var _a_coneLine = array.new_line(size = coneForecast, initial_value = na)
// Offset "i" to get the next _a_coneValue to use as y2 in _coneLine.
_a_x2Period = array.new_int(size = coneForecast, initial_value = na)
// If the respective cone and line input toggles are on, display the line.
if _coneToggle == true
// For loop to generate offset "i" array in _a_x2Period
for i = 0 to coneForecastIndex - 1 // Index is one shorter than "i".
_x2Period = i + 1 // Create offset index value from "i".
array.set(id = _a_x2Period, index = i, value = _x2Period)
for i = 0 to coneForecastIndex
_coneX1 = anchorBarIndex + i
_coneX2 = anchorBarIndex + array.get(id = _a_x2Period, index = i)
line _coneLine = na
_coneLine := line.new(
x1 = _coneX1,
y1 = array.get(id = _a_coneValue, index = i ),
x2 = _coneX2,
y2 = array.get(id = _a_coneValue, index = array.get(id = _a_x2Period, index = i) ),
xloc = xloc.bar_index,
extend = extend.none,
color = _color,
style = _style,
width = _width)
array.push(id = _a_coneLine, value = _coneLine)
if array.size(id = _a_coneLine) > coneForecast
_ln = array.shift(id = _a_coneLine)
line.delete(id = _ln)
_a_coneLine
// }
// ———————————————————— Cone Fill Function {
f_coneFill(_a_line1, _a_line2, _color, _i_fillBool) =>
// @param _a_line1, is the first line's array for the fill function.
// @param _a_line2, is the second line's array for the fill function.
// @param _color, color variable.
// @param _i_fillBool, bool input for this fill.
_a_linefill = array.new_linefill()
if i_fillBool == true // i_fillBool is a global variable.
if _i_fillBool == true // _i_fillBool is a local variable.
for i = 0 to coneForecastIndex
line _line1 = na
line _line2 = na
_line1 := array.get(id = _a_line1, index = i)
_line2 := array.get(id = _a_line2, index = i)
_linefill = linefill.new(_line1, _line2, _color)
array.push(id = _a_linefill, value = _linefill)
if array.size(id = _a_linefill) > coneForecast
_ln = array.shift(id = _a_linefill)
linefill.delete(id = _ln)
// }
// }
// ———————————————————— Draw Indicator {
// ———————————————————— Draw Lines {
meanLine = f_coneLine(
a_meanValue,
i_muColor,
f_lineStyle(i_muLineStyle),
i_muWidth,
i_muBool)
firstUpLine = f_coneLine(
a_firstUpValue,
i_firstUpColor,
f_lineStyle(i_firstUpLineStyle),
i_firstUpWidth,
i_firstConeBool)
firstDnLine = f_coneLine(
a_firstDnValue,
i_firstDnColor,
f_lineStyle(i_firstDnLineStyle),
i_firstDnWidth,
i_firstConeBool)
secondUpLine = f_coneLine(
a_secondUpValue,
i_secondUpColor,
f_lineStyle(i_secondUpLineStyle),
i_secondWidthUp,
i_secondConeBool)
secondDnLine = f_coneLine(
a_secondDnValue,
i_secondDnColor,
f_lineStyle(i_secondDnLineStyle),
i_secondDnWidth,
i_secondConeBool)
thirdUpLine = f_coneLine(
a_thirdUpValue,
i_thirdUpColor,
f_lineStyle(i_thirdUpLineStyle),
i_thirdUpWidth,
i_thirdConeBool)
thirdDnLine = f_coneLine(
a_thirdDnValue,
i_thirdDnColor,
f_lineStyle(i_thirdDnLineStyle),
i_thirdDnWidth,
i_thirdConeBool)
// }
// ———————————————————— Draw Fills
f_coneFill(meanLine, firstUpLine, i_firstUpFill, i_firstUpFillBool)
f_coneFill(meanLine, firstDnLine, i_firstDnFill, i_firstDnFillBool)
f_coneFill(firstUpLine, secondUpLine, i_secondUpFill, i_secondUpFillBool)
f_coneFill(firstDnLine, secondDnLine, i_secondDnFill, i_secondDnFillBool)
f_coneFill(secondUpLine, thirdUpLine, i_thirdUpFill, i_thirdUpFillBool)
f_coneFill(secondDnLine, thirdDnLine, i_thirdDnFill, i_thirdDnFillBool)
// }
// }