pinescript ยท diff
git:20260601.e2aad93 to git:20260829.a566ff1
8 added, 2 removed. Audit A to A.
---
name: pinescript
class: language
description: >-
Pine Script v6: syntax, performance, error diagnosis, backtesting,
visualization. Use when writing or debugging `.pine` files or TradingView
Pine indicators/strategies.
paths: "**/*.pine"
---
# Pine Script Development
**Verify before implementing**: For Pine Script version-specific syntax or new built-in functions, look up current docs via Context7 (`query-docs`) before writing code. TradingView updates Pine Script frequently and training data may be stale.
## Critical Syntax Rules
- **Ternary operators MUST stay on one line** -- splitting across lines causes "end of line without line continuation" error. For complex ternaries, use intermediate variables:
```
isBull = close > open
barColor = isBull ? color.green : color.red
```
- - **Continuation lines MUST be indented MORE than the starting line** -- same indentation = error
+ - **Continuation lines outside parentheses MUST be indented by a non-multiple of 4** -- same indentation as the start errors, and 4/8/12 spaces parse as a local block and error too (2 spaces is the conventional choice). Inside parentheses (function calls, parenthesized expressions) any indentation works, including multiples of 4
- **NEVER use plot() inside local scopes** (if/for/functions) -- use conditional value instead: `plot(condition ? value : na)`
- **barstate.isconfirmed** -- use to prevent repainting on real-time bars
## Platform Limits
500 bars history for `request.security()` | 500 plot calls | 64 drawing objects | 40 `request.security()` calls | 100KB compiled size
+ - Drawings positioned with `xloc.bar_index` reach at most 9,999 bars into the past and 500 into the future; for anything older, switch the drawing to `xloc.bar_time` and pass a timestamp (a time value without `xloc.bar_time` is treated as a future bar index and errors)
+ - Cap drawing growth with a rolling buffer: push each new object into an array, then `line.delete(arr.shift())` once `arr.size()` exceeds the intended count -- otherwise the oldest drawings silently vanish at the 64-object limit
+
## Performance
- **Tuple security calls** -- one `request.security()` returning `[close, high, low]` instead of 3 separate calls
- Pre-allocate arrays with `array.new<type>(size)` instead of push-and-resize
- Short-circuit signals: build conditions incrementally, exit early when first condition fails
- Cache repeated calculations in variables -- Pine recalculates every bar
+ - Iterate collections with `for item in myArray` (or `for [i, item] in myArray`) instead of `for i = 0 to array.size(...) - 1` -- the indexed form re-evaluates the bound each pass and breaks when the loop mutates the array's size
+ - Model related values as a user-defined type, not parallel arrays: `type Trade` with `float entry`, `int startBar`, plus `method` functions, stored in one `array<Trade>`. Parallel arrays (`entries`, `startBars`, ...) desync on any missed push/remove and every operation must be repeated per array; one typed array keeps each object's fields together
## Debugging
TradingView has no console or debugger. Use these patterns:
- - **Label debugging**: `label.new(bar_index, high, str.tostring(myVar))` to inspect values
+ - **Label debugging**: `label.new(bar_index, high, str.tostring(myVar))` to inspect values -- cap with the rolling-buffer pattern from Platform Limits, or older labels silently vanish at the 64-object limit
- **Table monitor**: `table.new()` with `barstate.islast` for real-time variable dashboard
- **Debug mode toggle**: wrap all debug code in `if input.bool("Debug", false)` -- remove before publishing
- **Repainting detector**: track `previousValue = value[1]`, flag when historical values change
## Strategy & Backtesting
- Use `strategy.*` functions: `strategy.wintrades`, `strategy.losstrades`, `strategy.grossprofit`
- Drawdown tracking: `maxEquity = math.max(strategy.equity, nz(maxEquity[1]))`, then `dd = (maxEquity - strategy.equity) / maxEquity * 100`
- Sharpe: `dailyReturn * 252 / (stdDev * math.sqrt(252))`
- **Walk-forward validation** -- optimize on period 1, test on period 2, re-optimize on period 2, test on period 3. If metrics degrade > 30%, parameters are overfit.
- **Indicator accuracy testing** -- use forward-looking `close[lookforward]` to measure prediction accuracy, track true/false positive rates
## Visualization
- `color.from_gradient()` for trend strength coloring
- Adaptive text sizing: `size.small` for intraday, `size.normal` for daily+
- Dynamic table rows -- resize based on enabled features via input toggles
+ - `input.*(..., active = condition)` greys out an input when its controlling toggle is off (e.g. a smoothing length only editable while "Use smoothing" is checked) -- clearer than a tooltip saying "ignored unless..."
- Professional color constants: define BULL_COLOR, BEAR_COLOR, NEUTRAL_COLOR once with transparency
## Publishing
- Documentation goes at TOP of .pine file as comments before `indicator()`/`strategy()`
- Use `@version`, `@description`, `@param` tags
- Multi-line tooltips: `tooltip="Line 1" + "\n" + "Line 2"`
- **TradingView House Rules**: no financial advice, no performance guarantees, no external links, no obfuscated code, no donation requests
## Common Coding Mistakes
- Indicator stacking (RSI + Stochastics + CCI) -- all measure the same thing (momentum). Use indicators from different categories instead.
- Overfitting parameters: if optimal values are oddly specific (RSI 23 instead of 20), the backtest is curve-fitted. Use round numbers and `input()` with sensible defaults.
- Missing `barstate.isconfirmed` guard -- calculations on unconfirmed bars cause repainting. Always guard entry signals.
- Hardcoded thresholds without `input()` -- makes the script untestable across instruments.
## Workflow
1. Write indicator/strategy in Pine Editor
2. Test with bar replay and strategy tester on multiple timeframes
3. Walk-forward validate before trusting backtest results (see Strategy & Backtesting above)
4. Verify: run on 3+ symbols and 2+ timeframes
## Verify
- Indicator compiles without errors on TradingView
- No repainting: `barstate.isconfirmed` guard present where needed
- Walk-forward tested on 3+ symbols across different timeframes