Indicator · Pine Script v6 · On the chart

Vein: Spread Context [WavesUnchained]

by casoon

This indicator plots calendar-spread context for commodity futures on the price chart.

View on GitHub

GitHub stars9on the repository
Pine versionv6current
Lines of code390
Settings12inputs
LicenceMIT
Last updateyesterday27 Oct 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

390 lines of Pine Script v6 from indicators/trend_direction/vein/vein_spread_context.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

vein_spread_context.pine
//@version=6
// ============================================================================
// Vein: Spread Context [WavesUnchained]
// Version: 0.1.4
// Author: WavesUnchained
// Build: 2026-10-12 00:00:00
// ============================================================================
// Optional commodity futures calendar spread context module.
// Auto-maps chart symbols to their front/next month futures spread.
// Provides bias, trend, momentum, divergence as context modifier.
//
// NOT a signal generator — only a context filter for other Vein modules.
//
// Supported: NatGas, WTI, Brent, Gold, Silver, Copper + manual override
// ============================================================================
indicator("Vein: Spread Context [WavesUnchained]", "Vein Spread", overlay=true, max_labels_count=10)

// ============================================================================
// INPUTS
// ============================================================================

var gSpread = "Spread Settings"
bool   useSpread    = input.bool(true, "Enable Spread Context", group=gSpread)
string spreadMode   = input.string("Auto", "Symbol Mapping", options=["Auto", "Manual"], group=gSpread, tooltip="Auto: detect commodity from chart symbol.\nManual: specify front/next symbols yourself.")
string manualFront  = input.symbol("NYMEX:NG1!", "Manual Front Month", group=gSpread)
string manualNext   = input.symbol("NYMEX:NG2!", "Manual Next Month", group=gSpread)
string spreadCalc   = input.string("Diff", "Spread Calculation", options=["Diff", "Ratio"], group=gSpread, tooltip="Diff: Front - Next (contango/backwardation).\nRatio: Front / Next.")
string spreadWeight = input.string("Normal", "Spread Weight", options=["Low", "Normal", "High"], group=gSpread, tooltip="How much the spread modifier influences other modules.")

var gTrend = "Spread Analysis"
int   spreadEmaFast = input.int(5, "Spread EMA Fast", minval=2, group=gTrend)
int   spreadEmaSlow = input.int(20, "Spread EMA Slow", minval=5, group=gTrend)
int   divLookback   = input.int(10, "Divergence Lookback", minval=3, group=gTrend)

var gDisplay = "Display"
bool   showTable    = input.bool(true, "Show Spread Table", group=gDisplay)
string displayMode  = input.string("Light", "Display Mode", options=["Light", "Debug"], group=gDisplay)

// ============================================================================
// SYMBOL MAPPING
// ============================================================================

// Detect current symbol
string currentSym = syminfo.tickerid
string currentRoot = syminfo.root

// Map to front/next futures. The futures root is compared exactly — a substring
// match on two letters mapped unrelated roots (e.g. "PLTR" → Platinum, "HOOD" → Heating Oil).
// Returns [frontSymbol, nextSymbol, commodityName, isSupported]
f_mapSymbol() =>
    string front = ""
    string next  = ""
    string name  = ""
    bool   found = false

    // ── NatGas ──
    if str.contains(currentSym, "NATURALGAS") or str.contains(currentSym, "NATGAS") or currentRoot == "NG" or str.contains(currentSym, "NG1!") or str.contains(currentSym, "NG2!")
        front := "NYMEX:NG1!"
        next  := "NYMEX:NG2!"
        name  := "NatGas"
        found := true

    // ── WTI Crude ──
    else if str.contains(currentSym, "OIL_CRUDE") or str.contains(currentSym, "USOIL") or str.contains(currentSym, "WTI") or currentRoot == "CL" or str.contains(currentSym, "CL1!")
        front := "NYMEX:CL1!"
        next  := "NYMEX:CL2!"
        name  := "WTI"
        found := true

    // ── Brent ──
    else if str.contains(currentSym, "OIL_BRENT") or str.contains(currentSym, "UKOIL") or str.contains(currentSym, "BRENT") or currentRoot == "BZ" or str.contains(currentSym, "BZ1!")
        front := "NYMEX:BZ1!"
        next  := "NYMEX:BZ2!"
        name  := "Brent"
        found := true

    // ── Gold ──
    else if str.contains(currentSym, "GOLD") or str.contains(currentSym, "XAUUSD") or currentRoot == "GC" or str.contains(currentSym, "GC1!")
        front := "COMEX:GC1!"
        next  := "COMEX:GC2!"
        name  := "Gold"
        found := true

    // ── Silver ──
    else if str.contains(currentSym, "SILVER") or str.contains(currentSym, "XAGUSD") or currentRoot == "SI" or str.contains(currentSym, "SI1!")
        front := "COMEX:SI1!"
        next  := "COMEX:SI2!"
        name  := "Silver"
        found := true

    // ── Copper ──
    else if str.contains(currentSym, "COPPER") or currentRoot == "HG" or str.contains(currentSym, "HG1!")
        front := "COMEX:HG1!"
        next  := "COMEX:HG2!"
        name  := "Copper"
        found := true

    // ── Heating Oil ──
    else if currentRoot == "HO" or str.contains(currentSym, "HO1!")
        front := "NYMEX:HO1!"
        next  := "NYMEX:HO2!"
        name  := "Heating Oil"
        found := true

    // ── RBOB Gasoline ──
    else if currentRoot == "RB" or str.contains(currentSym, "RB1!")
        front := "NYMEX:RB1!"
        next  := "NYMEX:RB2!"
        name  := "RBOB"
        found := true

    // ── Corn ──
    else if str.contains(currentSym, "CORN") or currentRoot == "ZC" or str.contains(currentSym, "ZC1!")
        front := "CBOT:ZC1!"
        next  := "CBOT:ZC2!"
        name  := "Corn"
        found := true

    // ── Wheat ──
    else if str.contains(currentSym, "WHEAT") or currentRoot == "ZW" or str.contains(currentSym, "ZW1!")
        front := "CBOT:ZW1!"
        next  := "CBOT:ZW2!"
        name  := "Wheat"
        found := true

    // ── Soybeans ──
    else if str.contains(currentSym, "SOYBEAN") or currentRoot == "ZS" or str.contains(currentSym, "ZS1!")
        front := "CBOT:ZS1!"
        next  := "CBOT:ZS2!"
        name  := "Soybeans"
        found := true

    // ── Coffee ──
    else if str.contains(currentSym, "COFFEE") or currentRoot == "KC" or str.contains(currentSym, "KC1!")
        front := "ICEUS:KC1!"
        next  := "ICEUS:KC2!"
        name  := "Coffee"
        found := true

    // ── Sugar ──
    else if str.contains(currentSym, "SUGAR") or currentRoot == "SB" or str.contains(currentSym, "SB1!")
        front := "ICEUS:SB1!"
        next  := "ICEUS:SB2!"
        name  := "Sugar"
        found := true

    // ── Cotton ──
    else if str.contains(currentSym, "COTTON") or currentRoot == "CT" or str.contains(currentSym, "CT1!")
        front := "ICEUS:CT1!"
        next  := "ICEUS:CT2!"
        name  := "Cotton"
        found := true

    // ── Cocoa ──
    else if str.contains(currentSym, "COCOA") or currentRoot == "CC" or str.contains(currentSym, "CC1!")
        front := "ICEUS:CC1!"
        next  := "ICEUS:CC2!"
        name  := "Cocoa"
        found := true

    // ── Platinum ──
    else if str.contains(currentSym, "PLATINUM") or currentRoot == "PL" or str.contains(currentSym, "PL1!")
        front := "NYMEX:PL1!"
        next  := "NYMEX:PL2!"
        name  := "Platinum"
        found := true

    // ── Palladium ──
    else if str.contains(currentSym, "PALLADIUM") or currentRoot == "PA" or str.contains(currentSym, "PA1!")
        front := "NYMEX:PA1!"
        next  := "NYMEX:PA2!"
        name  := "Palladium"
        found := true

    [front, next, name, found]

// Resolve mapping
[autoFront, autoNext, commodityName, isAutoMapped] = f_mapSymbol()

bool   isManual     = spreadMode == "Manual"
string frontSymbol  = isManual ? manualFront : autoFront
string nextSymbol   = isManual ? manualNext : autoNext
string commodity    = isManual ? "Manual" : commodityName
bool   isSupported  = isManual or isAutoMapped

// ============================================================================
// DATA FETCH
// ============================================================================

float frontClose = isSupported and useSpread ? request.security(frontSymbol, timeframe.period, close, barmerge.gaps_off, barmerge.lookahead_off) : na
float nextClose  = isSupported and useSpread ? request.security(nextSymbol, timeframe.period, close, barmerge.gaps_off, barmerge.lookahead_off) : na

bool hasData = not na(frontClose) and not na(nextClose)

// ============================================================================
// SPREAD CALCULATION
// ============================================================================

float spreadValue = na
if hasData
    if spreadCalc == "Diff"
        spreadValue := frontClose - nextClose
    else
        spreadValue := nextClose != 0 ? frontClose / nextClose : na

// ============================================================================
// SPREAD ANALYSIS
// ============================================================================

float spreadEmaF = ta.ema(spreadValue, spreadEmaFast)
float spreadEmaS = ta.ema(spreadValue, spreadEmaSlow)
float spreadSlope = not na(spreadEmaF) ? spreadEmaF - nz(spreadEmaF[1]) : 0.0
float spreadROC  = not na(spreadValue) and nz(spreadValue[divLookback]) != 0 ? (spreadValue - spreadValue[divLookback]) / math.abs(spreadValue[divLookback]) * 100 : 0.0

// ── Spread Trend ──
string spreadTrend = "flat"
if not na(spreadEmaF) and not na(spreadEmaS)
    if spreadEmaF > spreadEmaS and spreadSlope > 0
        spreadTrend := "rising"
    else if spreadEmaF < spreadEmaS and spreadSlope < 0
        spreadTrend := "falling"

// ── Spread Momentum ──
string spreadMomentum = "steady"
float absROC = math.abs(spreadROC)
if absROC > 10
    spreadMomentum := spreadROC > 0 ? "accelerating_up" : "accelerating_down"
else if absROC > 3
    spreadMomentum := spreadROC > 0 ? "rising" : "falling"

// ── Contango / Backwardation ──
string termStructure = "unknown"
if hasData and spreadCalc == "Diff"
    if spreadValue > 0
        termStructure := "backwardation"
    else if spreadValue < 0
        termStructure := "contango"
    else
        termStructure := "flat"
else if hasData and spreadCalc == "Ratio"
    if spreadValue > 1.001
        termStructure := "backwardation"
    else if spreadValue < 0.999
        termStructure := "contango"
    else
        termStructure := "flat"

// ── Price-Spread Divergence ──
float priceChange  = close - close[divLookback]
float spreadChange = not na(spreadValue) ? spreadValue - nz(spreadValue[divLookback]) : 0.0

string spreadDivergence = "none"
if hasData
    if priceChange < 0 and spreadChange > 0
        spreadDivergence := "bullish"
    else if priceChange > 0 and spreadChange < 0
        spreadDivergence := "bearish"

// ── Spread Bias ──
string spreadBias = "neutral"
if hasData
    int bullPoints = 0
    int bearPoints = 0

    // Term structure
    if termStructure == "backwardation"
        bullPoints += 1
    else if termStructure == "contango"
        bearPoints += 1

    // Trend
    if spreadTrend == "rising"
        bullPoints += 1
    else if spreadTrend == "falling"
        bearPoints += 1

    // Divergence
    if spreadDivergence == "bullish"
        bullPoints += 1
    else if spreadDivergence == "bearish"
        bearPoints += 1

    if bullPoints >= 2
        spreadBias := "bullish"
    else if bearPoints >= 2
        spreadBias := "bearish"

// ── Spread Strength ──
string spreadStrength = "weak"
if hasData
    int factors = 0
    if termStructure == "backwardation" or termStructure == "contango"
        factors += 1
    if spreadTrend != "flat"
        factors += 1
    if spreadDivergence != "none"
        factors += 1
    if str.contains(spreadMomentum, "accelerating")
        factors += 1
    spreadStrength := factors >= 3 ? "strong" : factors >= 2 ? "moderate" : "weak"

// ── Spread Modifier ──
float weightMult = spreadWeight == "Low" ? 0.5 : spreadWeight == "High" ? 1.5 : 1.0

float spreadModifier = 0.0
if hasData and useSpread
    if spreadBias == "bullish"
        spreadModifier := (spreadStrength == "strong" ? 1.5 : spreadStrength == "moderate" ? 1.0 : 0.5) * weightMult
    else if spreadBias == "bearish"
        spreadModifier := -(spreadStrength == "strong" ? 1.5 : spreadStrength == "moderate" ? 1.0 : 0.5) * weightMult

// ============================================================================
// VISUALIZATION — Status Table
// ============================================================================

bool isDebug = displayMode == "Debug"

var table spreadTbl = na
if showTable and barstate.islast
    int rows = isDebug ? 7 : 4
    if na(spreadTbl)
        spreadTbl := table.new(position.bottom_left, 2, rows, bgcolor=color.new(color.white, 100), border_color=color.new(color.gray, 80), border_width=0, frame_color=color.new(color.gray, 80), frame_width=0)

    // Colors
    color biasCol = spreadBias == "bullish" ? #00e676 : spreadBias == "bearish" ? #ff1744 : color.new(chart.fg_color, 40)
    color divCol  = spreadDivergence == "bullish" ? #00e676 : spreadDivergence == "bearish" ? #ff1744 : color.new(chart.fg_color, 60)
    color trendCol = spreadTrend == "rising" ? #00e676 : spreadTrend == "falling" ? #ff1744 : color.new(chart.fg_color, 40)

    // Row 0: Header
    string headerText = isSupported ? ("Vein Spread: " + commodity) : "Vein Spread: unsupported"
    color  headerCol  = isSupported and hasData ? chart.fg_color : color.new(chart.fg_color, 60)
    table.cell(spreadTbl, 0, 0, headerText, text_color=headerCol, text_size=size.normal, tooltip="Spread Context Module\n────────────────\nCommodity: " + commodity + "\nFront: " + frontSymbol + "\nNext: " + nextSymbol + "\nMapping: " + (isManual ? "Manual" : "Auto") + "\nData: " + (hasData ? "OK" : "missing") + "\n\nProvides futures term structure context.\nNot a signal — a modifier for other Vein modules.")
    string biasText = not isSupported ? "—" : not hasData ? "no data" : spreadBias
    table.cell(spreadTbl, 1, 0, str.upper(biasText), text_color=biasCol, text_size=size.normal, text_halign=text.align_right, tooltip="Spread Bias\n────────────────\nCombines: term structure + trend + divergence\n\nBullish: ≥2 bull factors (backwardation, rising, bull divergence)\nBearish: ≥2 bear factors (contango, falling, bear divergence)\nNeutral: mixed or insufficient")

    if isSupported and hasData
        // Row 1: Term structure + Trend
        color termCol = termStructure == "backwardation" ? #00e676 : termStructure == "contango" ? #ff1744 : color.new(chart.fg_color, 40)
        table.cell(spreadTbl, 0, 1, termStructure, text_color=termCol, text_size=size.normal, tooltip="Term Structure\n────────────────\nBackwardation: front > next → demand exceeds supply → bullish\nContango: front < next → supply exceeds demand → bearish\nFlat: near-equal")
        table.cell(spreadTbl, 1, 1, spreadTrend + " " + (spreadModifier > 0 ? "+" : "") + str.tostring(spreadModifier, "#.1"), text_color=trendCol, text_size=size.normal, text_halign=text.align_right, tooltip="Spread Trend + Modifier\n────────────────\nTrend: " + spreadTrend + "\nMomentum: " + spreadMomentum + "\nModifier: " + str.tostring(spreadModifier, "#.1") + "\n\nModifier is applied to other Vein modules:\n+1.5 = strong bullish context\n-1.5 = strong bearish context\n0 = neutral")

        // Row 2: Divergence + Strength
        table.cell(spreadTbl, 0, 2, spreadDivergence != "none" ? "DIV " + spreadDivergence : "no divergence", text_color=divCol, text_size=size.normal, tooltip="Price-Spread Divergence\n────────────────\nCompares price direction vs spread direction over " + str.tostring(divLookback) + " bars.\n\nBullish: price falls but spread rises → hidden demand\nBearish: price rises but spread falls → hidden weakness\nNone: aligned")
        table.cell(spreadTbl, 1, 2, spreadStrength, text_color=biasCol, text_size=size.normal, text_halign=text.align_right, tooltip="Signal Strength\n────────────────\nStrong: 3-4 aligned factors\nModerate: 2 factors\nWeak: 0-1 factors")

        // Row 3: Spread value
        string spreadStr = spreadCalc == "Diff" ? str.tostring(spreadValue, format.mintick) : str.tostring(spreadValue, "#.4")
        table.cell(spreadTbl, 0, 3, "Spread: " + spreadStr, text_color=color.new(chart.fg_color, 30), text_size=size.normal, tooltip="Raw Spread Value\n────────────────\nFront (" + frontSymbol + "): " + str.tostring(frontClose, format.mintick) + "\nNext (" + nextSymbol + "): " + str.tostring(nextClose, format.mintick) + "\nSpread: " + spreadStr + "\nMode: " + spreadCalc)
        table.cell(spreadTbl, 1, 3, "", text_size=size.normal)

        // Debug rows
        if isDebug
            table.cell(spreadTbl, 0, 4, "EMA " + str.tostring(spreadEmaF, format.mintick) + " / " + str.tostring(spreadEmaS, format.mintick), text_color=color.new(chart.fg_color, 50), text_size=size.normal)
            table.cell(spreadTbl, 1, 4, "Slope " + str.tostring(spreadSlope, format.mintick), text_color=color.new(chart.fg_color, 50), text_size=size.normal, text_halign=text.align_right)

            table.cell(spreadTbl, 0, 5, "ROC " + str.tostring(spreadROC, "#.1") + "%", text_color=color.new(chart.fg_color, 50), text_size=size.normal)
            table.cell(spreadTbl, 1, 5, "Mom: " + spreadMomentum, text_color=color.new(chart.fg_color, 50), text_size=size.normal, text_halign=text.align_right)

            table.cell(spreadTbl, 0, 6, "Weight: " + spreadWeight, text_color=color.new(chart.fg_color, 50), text_size=size.normal)
            table.cell(spreadTbl, 1, 6, currentSym, text_color=color.new(chart.fg_color, 50), text_size=size.normal, text_halign=text.align_right)
    else
        // No data — show status
        table.cell(spreadTbl, 0, 1, not isSupported ? "Symbol not mapped" : "Waiting for data", text_color=color.new(chart.fg_color, 50), text_size=size.normal)
        table.cell(spreadTbl, 1, 1, "", text_size=size.normal)
        table.cell(spreadTbl, 0, 2, not isSupported ? "Use Manual mode or switch to supported symbol" : "", text_color=color.new(chart.fg_color, 60), text_size=size.normal)
        table.cell(spreadTbl, 1, 2, "", text_size=size.normal)
        table.cell(spreadTbl, 0, 3, "", text_size=size.normal)
        table.cell(spreadTbl, 1, 3, "", text_size=size.normal)

// ============================================================================
// DATA WINDOW
// ============================================================================

plot(spreadValue, "Spread Value [dw]", display=display.data_window, color=color.new(color.gray, 100))
plot(spreadEmaF, "Spread EMA Fast [dw]", display=display.data_window, color=color.new(color.gray, 100))
plot(spreadEmaS, "Spread EMA Slow [dw]", display=display.data_window, color=color.new(color.gray, 100))
plot(spreadModifier, "Spread Modifier [dw]", display=display.data_window, color=color.new(color.gray, 100))
plot(spreadDivergence == "bullish" ? 1 : spreadDivergence == "bearish" ? -1 : 0, "Spread Div [dw]", display=display.data_window, color=color.new(color.gray, 100))

// ============================================================================
// ALERTS
// ============================================================================

bool alertsOnBarClose = input.bool(true, "Alerts only on bar close (confirmed)", group="Alerts")
bool alertOk = not alertsOnBarClose or barstate.isconfirmed

alertcondition(alertOk and (spreadBias == "bullish" and spreadBias[1] != "bullish"), "Spread Turns Bullish", "VEIN-SPC · SPREAD BULLISH · {{ticker}} {{interval}}")
alertcondition(alertOk and (spreadBias == "bearish" and spreadBias[1] != "bearish"), "Spread Turns Bearish", "VEIN-SPC · SPREAD BEARISH · {{ticker}} {{interval}}")
alertcondition(alertOk and (spreadDivergence == "bullish" and spreadDivergence[1] != "bullish"), "Spread Bull Divergence", "VEIN-SPC · SPREAD BULL DIVERGENCE · {{ticker}} {{interval}}")
alertcondition(alertOk and (spreadDivergence == "bearish" and spreadDivergence[1] != "bearish"), "Spread Bear Divergence", "VEIN-SPC · SPREAD BEAR DIVERGENCE · {{ticker}} {{interval}}")

Overview

Vein: Spread Context [WavesUnchained] maps the chart symbol to front and next month contracts automatically, or uses manual symbols, then calculates the spread as a difference or ratio. Fast and slow EMAs, a weight setting, and a lookback describe trend, momentum, and divergence as modifiers for other Vein modules. It is not a signal generator and has no entry or exit rules. A table and light or debug display modes show the context.

Details

Published by

casoon on GitHub

Type

Indicator, Pine Script v6

Draws

On the price chart

Category

Trend, Oscillators & momentum, Divergence, Screeners & dashboards

Markets

Oil & commodities, Gold

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.

Topics

pine-scriptpinescripttechnical-analysistrading-indicatorstrading-strategiestradingview

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Enable Spread ContextbooltrueuseSpread
Symbol MappingstringAutospreadMode
Manual Front MonthsymbolNYMEX:NG1!manualFront
Manual Next MonthsymbolNYMEX:NG2!manualNext
Spread CalculationstringDiffspreadCalc
Spread WeightstringNormalspreadWeight
Spread EMA Fastint5spreadEmaFast
Spread EMA Slowint20spreadEmaSlow
Divergence Lookbackint10divLookback
Show Spread TablebooltrueshowTable
Display ModestringLightdisplayMode
Alerts only on bar close (confirmed)booltruealertsOnBarClose
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

218 stars

TradersPost Trading Checklist is an overlay indicator that evaluates a suite of popular technical conditions for long and short trade setups. It checks session-anchored VWAP, fast and slow EMA alignments and crosses, 200 SMA, RSI overbought or oversold conditi

Indicator v6 Screeners & dashboardsTrend
Updated 3 months ago · None stated GitHub repository of TradersPost Trading Checklist
53 stars

This indicator analyzes historical candle direction and price range over a configurable lookback window to gauge market trend. It categorizes trend direction using candle count, price range sum, or both. Signals are filtered using a Simple Moving Average to en

Indicator v6 TrendOscillators & momentum
Updated 2 months ago · MPL-2.0 GitHub repository of Candle Counter + MA + RSI + Mode

Pocket Scout - SPY/QQQ

by chris-c-thomas
14 stars

Pocket Scout - SPY/QQQ is a mobile-optimized intraday bias indicator designed for major US equity ETFs and indices. It overlays a 9/21/50 EMA ribbon, session VWAP, prior day high/low/close levels, and intraday high/low lines directly on the main price chart. T

Indicator v6 TrendOscillators & momentum Repaints
Updated 6 months ago · MIT GitHub repository of Pocket Scout - SPY/QQQ

This indicator implements a full Chanlun pipeline on the price chart. It merges contained bars, marks top and bottom fractals, and connects alternating fractals into strokes. Overlapping strokes form pivot boxes, and MACD area ratios flag trend or consolidatio

Indicator v6 Support & resistanceDivergence
Updated 2 months ago · GPL-3.0 GitHub repository of 缠论 - 分型与笔 [Chanlun Core]

Portfolio Backtester

by f-cksociety
11 stars

The script is a Pine Script v5 indicator that emulates strategy backtesting directly on the price chart. It evaluates modular entry strategies, trade directions, entry stop-loss types such as ATR multiples or fixed percentages, and a wide variety of trade filt

Indicator v5 TrendOscillators & momentum
Updated 4 years ago · MPL-2.0 GitHub repository of Portfolio Backtester

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