traderspost/pinescript-agents1 file

Pine Developer

Writes production-quality Pine Script v6 code following TradingView guidelines and best practices. Use when implementing indicators, strategies, or any Pine Script code. Triggers on requests to create, write, implement, or code Pine Script functionality.

Specification
Skill ID
traderspost/pinescript-agents/pine-developer
Publisher
traderspost
Repository
pinescript-agents
Installs
0
Files
1
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

traderspost/pinescript-agents/pine-developerInstalls these files
  • SKILL.md

What this skill tells the agent

Pine Script Developer

Specialized in writing production-quality Pine Script v6 code for TradingView.

⚠️ CRITICAL: Pine Script v6 2025 Updates

These updates are essential for writing correct, modern Pine Script code:

December 2025: Updated Line Wrapping Rules

Expressions in parentheses now support flexible indentation:

// ✅ NOW VALID - Any indentation inside parentheses
plot(series,
    title="My Plot",    // Can use any indentation
    color=color.blue)

// ✅ Also valid
longCondition = (ta.crossover(ema50, ema200) and
    rsi < 30 and
    volume > ta.sma(volume, 20))

// ⚠️ STILL REQUIRED outside parentheses - non-multiple-of-4 indentation
longCondition = ta.crossover(ema50, ema200) and
     rsi < 30   // Must NOT be multiple of 4 spaces

March 2025: BREAKING CHANGE - For Loop Dynamic Boundaries

for loops now evaluate to_num before every iteration, not just once.

PREFERRED: Use `for...in` loops for collections:

// ✅ BEST: Use for...in for arrays (safe, clean, preferred)
for element in myArray
    // Process element directly

// ✅ BEST: Use for...in with index when needed
for [index, element] in myArray
    // Have both index and value

// ✅ for...in works with arrays, matrices, and maps
for [key, value] in myMap
    // Iterate key-value pairs

If you must use traditional `for` loop:

// ⚠️ BREAKING: This creates infinite loop!
var arr = array.new<int>()
for i = 0 to array.size(arr)  // Re-evaluated each iteration
    array.push(arr, i)  // Array grows, loop never ends!

// ✅ FALLBACK: Cache the boundary if using traditional for
size = array.size(arr)
for i = 0 to size
    array.push(arr, i)

Note: for...in allows modifying array/matrix sizes during iteration. Maps cannot be resized during for...in - use map.keys() array instead.

February 2025: Scope Limit Removed

  • Previously limited to 550 total scopes
  • Now unlimited scopes across functions, methods, loops, conditionals, types, and enums

February 2025: Bid/Ask Variables

// Only available on 1T (tick) timeframe
bidPrice = bid  // Highest buyer price (na on other timeframes)
askPrice = ask  // Lowest seller price (na on other timeframes)

Pine Script v6 2025 New Features

July 2025: Input active Parameter

All input functions now support conditional activation:

useCustomMA = input.bool(false, "Use Custom MA")
customMALength = input.int(20, "Custom MA Length",
    active=useCustomMA,  // Grayed out when useCustomMA is false
    tooltip="Only available when 'Use Custom MA' is enabled")

July 2025: syminfo.current_contract

// For continuous futures - returns underlying contract ticker
currentContract = syminfo.current_contract  // Returns na for non-continuous

November 2025: syminfo.isin

// International Securities Identification Number (12 chars)
isinCode = syminfo.isin  // Empty string if unavailable

September 2025: Plot Line Styles

plot(series, linestyle=plot.linestyle_solid)   // Default
plot(series, linestyle=plot.linestyle_dashed)  // Dashed line
plot(series, linestyle=plot.linestyle_dotted)  // Dotted line

October 2025: Enhanced time() and time_close()

New timeframe_bars_back parameter:

// Get time from 5 bars back on the DAILY timeframe (not current chart)
dailyTimeBack = time("D", timeframe_bars_back=5)

// Positive = past bars, Negative = future (expected) timestamps
futureTime = time("D", timeframe_bars_back=-1)  // Expected next bar

August 2025: Increased String Length

  • Maximum string length: 40,960 characters (was 4,096)

June 2025: Library Constant Exports

// In library:
//@version=6
library("MyLib")
export const float PI = 3.14159265359
export const int MAX_BARS = 500
export const string VERSION = "1.0.0"

May 2025: time_close on Non-Time-Based Charts

For Renko, Line Break, Kagi, Point & Figure, Range charts:

  • time_close of open realtime bar now returns na
  • time_close[1] now works immediately after bar closes

April 2025: Percentage-Based Ticker Styles

// New "PercentageLTP" style for percentage box sizing
renkoTicker = ticker.renko(syminfo.tickerid, "PercentageLTP", 1.0)
kagiTicker = ticker.kagi(syminfo.tickerid, "PercentageLTP", 0.5)
pnfTicker = ticker.pointfigure(syminfo.tickerid, "PercentageLTP", 1.0)

March 2025: box.set_xloc()

// Modify box x-coordinates after creation
box.set_xloc(myBox, left, right, xloc.bar_index)
box.set_xloc(myBox, leftTime, rightTime, xloc.bar_time)

CRITICAL: Line Wrapping Rules (Updated December 2025)

Inside Parentheses (FLEXIBLE)

// ✅ Any indentation works inside ()
plot(series,
    title="Plot",
        color=color.blue,  // Different indentation OK
    linewidth=2)

indicator("Title",
    overlay=true,
    max_bars_back=500)

Outside Parentheses (STRICT)

// ✅ CORRECT - Non-multiple-of-4 indentation
longCondition = ta.crossover(ema50, ema200) and
     rsi < 30 and
     volume > ta.sma(volume, 20)

// ❌ WRONG - Multiple of 4 (or same level)
longCondition = ta.crossover(ema50, ema200) and
    rsi < 30  // Error: 4 spaces

longCondition = ta.crossover(ema50, ema200) and
rsi < 30  // Error: same indentation

CRITICAL: Ternary Operators - Keep on ONE Line

// ❌ NEVER split ternary across lines
text = condition ?
    "value1" :
    "value2"  // ERROR!

// ✅ ALWAYS keep on one line
text = condition ? "value1" : "value2"

// ✅ For long ternaries, use intermediate variables
trueText = str.format("Long value {0}", param1)
falseText = str.format("Other value {0}", param2)
result = condition ? trueText : falseText

CRITICAL: Plot Scope Restriction

NEVER use plot() inside local scopes:

// ❌ WRONG - All of these fail:
if condition
    plot(value)  // ERROR: Cannot use 'plot' in local scope

for i = 0 to 10
    plot(close[i])  // ERROR!

myFunc() =>
    plot(close)  // ERROR!

// ✅ CORRECT patterns:
plot(condition ? value : na)  // Conditional plotting
plot(value, color=condition ? color.blue : na)  // Conditional color

// For dynamic drawing in local scopes, use:
if condition
    line.new(...)   // OK
    label.new(...)  // OK
    box.new(...)    // OK

⚠️ CRITICAL: UDT-First Architecture

For any complex data structure, ALWAYS define User Defined Types (UDTs) FIRST before writing any other code.

Why UDT-First?

  1. Encapsulation: Bundle related data and drawing objects together
  2. Methods: Add behavior directly to types with method syntax
  3. Unlimited Lookback: Use xloc.bar_time instead of xloc.bar_index (5000 bar limit!)
  4. Clean Arrays: One array<MyType> instead of 6+ parallel arrays
  5. Self-Managing Drawings: Types can create/delete their own visual objects

UDT Definition Pattern

// ALWAYS define UDTs early in script (after inputs, before calculations)
type Regression
    // Time coordinates (for xloc.bar_time - NO lookback limit!)
    int startTime
    int endTime

    // Bar indices (for Y calculations: y = slope * barIndex + intercept)
    int startBarIndex
    int endBarIndex

    // Data parameters
    float slope
    float intercept
    float stdDev
    float pearsonR

    // State flags
    bool isLive = false
    bool isOriginal = false

    // Drawing objects (managed internally)
    line centerLine = na
    line upperLine = na
    line lowerLine = na
    linefill fill = na

UDT Methods Pattern

// Delete method - clean up drawing objects
method delete(Regression this) =>
    if not na(this.centerLine)
        line.delete(this.centerLine)
    if not na(this.upperLine)
        line.delete(this.upperLine)
    if not na(this.lowerLine)
        line.delete(this.lowerLine)
    if not na(this.fill)
        linefill.delete(this.fill)

Use this skill in a project

Open any RiverX project, search the Skills panel for traderspost/pinescript-agents/pine-developer, and install it in one click.

Use this skill