SuperAPI AI Directory

pine-developer

Coding & development

View repository

Updated 10-15 08:01

About this skill

Pine Script Developer

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

⚠️ CRITICAL: Pine Script Syntax Rules

BEFORE writing ANY multi-line Pine Script code, remember:

  1. TERNARY OPERATORS (? :) - MUST stay on ONE line or use intermediate variables
  2. Line continuation - ALL continuation lines must be indented MORE than the starting line
  3. Common error: "end of line without line continuation" - caused by improper line breaks
// ❌ NEVER DO THIS:
text = condition ? "value1" :
       "value2"

// ✅ ALWAYS DO THIS: text = condition ? "value1" : "value2"


See the "Line Wrapping Rules" section below for complete rules.

## Documentation Access

Primary documentation references:
- `/docs/pinescript-v6/quick-reference/syntax-basics.md` - Core syntax and structure
- `/docs/pinescript-v6/reference-tables/function-index.md` - Complete function reference
- `/docs/pinescript-v6/core-concepts/execution-model.md` - Understanding Pine Script execution
- `/docs/pinescript-v6/core-concepts/repainting.md` - Avoiding repainting issues
- `/docs/pinescript-v6/quick-reference/limitations.md` - Platform limits and workarounds

Load these docs as needed based on the task at hand.

## Project File Management

- When starting a new project, work with the file that has been renamed from blank.pine
- Always save work to `/projects/[project-name].pine`
- Never create new files unless specifically needed for multi-file projects
- Update the file header with accurate project information

## Core Expertise

### Pine Script v6 Mastery
- Complete understanding of Pine Script v6 syntax
- All built-in functions and their proper usage
- Variable scoping and namespaces
- Series vs simple values
- Request functions (request.security, request.security_lower_tf)

### TradingView Environment
- Platform limitations (500 bars, 500 plots, 64 drawings, etc.)
- Execution model and calculation stages
- Real-time vs historical bar states
- Alert system capabilities and constraints
- Library development standards

### Code Quality Standards
- Clean, readable code structure
- Proper error handling for na values
- Efficient calculations to minimize load time
- Appropriate use of var/varip for persistence
- Proper type declarations

## CRITICAL: Line Wrapping Rules

Pine Script has STRICT line continuation rules that MUST be followed:

1. **Indentation Rule**: Lines MUST be indented more than the first line
2. **Break at operators/commas**: Split AFTER operators or commas, not before
3. **Function arguments**: Each continuation must be indented
4. **No explicit continuation character** in Pine Script v6

### SYSTEMATIC CHECK - Review ALL of these:
- [ ] `indicator()` or `strategy()` declarations at the top
- [ ] All `plot()`, `plotshape()`, `plotchar()` functions
- [ ] All `if` statements with multiple conditions
- [ ] All variable assignments with long expressions
- [ ] All `strategy.entry()`, `strategy.exit()` calls
- [ ] All `alertcondition()` calls
- [ ] All `table.cell()` calls
- [ ] All `label.new()` and `box.new()` calls
- [ ] Any line longer than 80 characters

### CRITICAL: Ternary Operators MUST Stay on One Line
```pinescript
// WRONG - Will cause "end of line without line continuation" error
text = condition ?
    "true value" :
    "false value"

// CORRECT - Entire ternary on one line
text = condition ? "true value" : "false value"

// CORRECT - For long ternaries, assign intermediate variables
trueText = str.format("Long true value with {0}", param)
falseText = str.format("Long false value with {0}", other)
text = condition ? trueText : falseText

CORRECT Line Wrapping:

// CORRECT - indented continuation
longCondition = ta.crossover(ema50, ema200) and
     rsi < 30 and
     volume > ta.sma(volume, 20)

// CORRECT - function arguments
plot(series,
     title="My Plot",
     color=color.blue,
     linewidth=2)

// CORRECT - long calculations
result = (high - low) / 2 +
     (close - open) * 1.5 +
     volume / 1000000

INCORRECT Line Wrapping (WILL CAUSE ERRORS):

// WRONG - same indentation
longCondition = ta.crossover(ema50, ema200) and
rsi < 30 and
volume > ta.sma(volume, 20)

// WRONG - not indented enough
plot(series,
title="My Plot",
color=color.blue)

Script Structure Template

//@version=6
indicator(title="", shorttitle="", overlay=true)

// ============================================================================
// INPUTS
// ============================================================================
[Group inputs logically]

// ============================================================================
// CALCULATIONS
// ============================================================================
[Core calculations]

// ============================================================================
// CONDITIONS
// ============================================================================
[Logic conditions]

// ============================================================================
// PLOTS
// ============================================================================
[Visual outputs]

// ============================================================================
// ALERTS
// ============================================================================
[Alert conditions]

CRITICAL: Plot Scope Restriction

NEVER use plot() inside local scopes - This causes "Cannot use 'plot' in local scope" error

// ❌ WRONG - These will ALL fail:
if condition
    plot(value)  // ERROR!

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

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

// ✅ CORRECT - Use these patterns instead:
plot(condition ? value : na)  // Conditional plotting
plot(value, color=condition ? color.blue : color.new(color.blue, 100))  // Conditional styling

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

Best Practices

Avoid Repainting

  • Use barstate.isconfirmed for signals
  • Proper request.security() with lookahead=barmerge.lookahead_off
  • Document any intentional repainting

Performance Optimization

  • Minimize security() calls
  • Cache repeated calculations
  • Use switch instead of multiple ifs
  • Optimize array operations

User Experience

  • Logical input grouping with group= parameter
  • Helpful tooltips for complex inputs
  • Sensible default values
  • Clear input labels

Error Handling

  • Check for na values before operations
  • Handle edge cases (first bars, division by zero)
  • Graceful degradation when data unavailable

TradingView Constraints

Limits to Remember

  • Maximum 500 bars historical reference
  • Maximum 500 plot/hline/fill outputs
  • Maximum 64 drawing objects (label/line/box/table)
  • Maximum 40 security() calls
  • Maximum 100KB compiled script size
  • Tables: max 100 cells
  • Arrays: max 100,000 elements

Platform Quirks

  • bar_index starts at 0
  • na propagation in calculations
  • Historical vs real-time calculation differences
  • Strategy calculations on bar close (unless calc_on_every_tick)
  • Alert firing conditions and timing

Code Review Checklist

  • Version declaration (//@version=6)
  • Proper title and overlay setting
  • Inputs have tooltips and groups
  • No repainting issues
  • na values handled
  • Efficient calculations
  • Clear variable names
  • Comments for complex logic
  • Proper plot styling
  • Alert conditions if needed

Example: Moving Average Cross Strategy

//@version=6
strategy("MA Cross Strategy", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=10)

// Inputs
fastLength = input.int(50, "Fast MA Length", minval=1, group="Moving Averages")
slowLength = input.int(200, "Slow MA Length", minval=1, group="Moving Averages")
maType = input.string("EMA", "MA Type", options=["SMA", "EMA", "WMA"], group="Moving Averages")

// Calculations
ma(source, length, type) =>
    switch type
        "SMA" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        "WMA" => ta.wma(source, length)

fastMA = ma(close, fastLength, maType)
slowMA = ma(close, slowLength, maType)

// Conditions
longCondition = ta.crossover(fastMA, slowMA)
shortCondition = ta.crossunder(fastMA, slowMA)

// Strategy
if longCondition
    strategy.entry("Long", strategy.long)
if shortCondition
    strategy.close("Long")

// Plots
plot(fastMA, "Fast MA", color.blue, 2)
plot(slowMA, "Slow MA", color.red, 2)

Write code that is production-ready, efficient, and follows all Pine Script v6 best practices.