| name | pine-coder |
| description | TradingView Pine Script v6 编程专家。编写高质量的指标(indicator)、策略(strategy)和库(library)脚本。
触发条件:
- 用户要求编写 Pine Script / PineScript 代码
- 用户提到 TradingView 指标、策略或脚本开发
- 用户需要创建技术分析工具(均线、MACD、RSI 等)
- 用户要求编写回测策略或交易系统
- 用户需要帮助调试或优化 Pine Script 代码
- 用户提到 "Pine", "TV脚本", "tradingview 脚本"
|
Pine Script v6 编程专家
编写遵循最新 Pine Script v6 规范的 TradingView 脚本。
强制性工作流程
重要:在编写任何 Pine Script 代码之前,必须遵循以下流程:
1. 文档查阅(必须)
使用 Grep 工具在 docs/pine-script-docs/ 目录中搜索相关函数、类型或概念的官方定义:
Grep pattern="ta\.sma" path="docs/pine-script-docs/"
Grep pattern="strategy\.entry" path="docs/pine-script-docs/"
Grep pattern="series float" path="docs/pine-script-docs/language/"
Grep pattern="input\.int" path="docs/pine-script-docs/"
2. 验证清单
编写代码前必须确认:
3. 常见错误预防
在编写代码时主动检查以下易错点:
- 布尔值不能为
na(v6 特性)
and/or 短路求值可能跳过函数调用
- 整数除法返回浮点数(
5/2 = 2.5)
transp 参数已移除,使用 color.new()
when 参数已移除,使用 if 条件
核心命名空间参考
技术分析 ta.*
| 函数 | 签名 | 返回类型 |
|---|
ta.sma() | ta.sma(source, length) | series float |
ta.ema() | ta.ema(source, length) | series float |
ta.rsi() | ta.rsi(source, length) | series float |
ta.macd() | ta.macd(source, fastlen, slowlen, siglen) | [series float, series float, series float] |
ta.crossover() | ta.crossover(source1, source2) | series bool |
ta.crossunder() | ta.crossunder(source1, source2) | series bool |
ta.highest() | ta.highest(source, length) | series float |
ta.lowest() | ta.lowest(source, length) | series float |
ta.atr() | ta.atr(length) | series float |
ta.stoch() | ta.stoch(source, high, low, length) | series float |
ta.bb() | ta.bb(series, length, mult) | [series float, series float, series float] |
ta.supertrend() | ta.supertrend(factor, atrPeriod) | [series float, series float] |
注意: length 参数通常需要 simple int 类型,不接受 series int。
策略 strategy.*
| 函数 | 用途 | 关键参数 |
|---|
strategy.entry() | 入场订单 | id, direction, qty, limit, stop |
strategy.exit() | 出场订单 | id, from_entry, profit, loss, limit, stop, trail_points, trail_offset |
strategy.close() | 关闭指定入场 | id |
strategy.close_all() | 关闭所有持仓 | comment |
strategy.order() | 基础订单 | id, direction, qty, limit, stop |
strategy.cancel() | 取消订单 | id |
strategy.cancel_all() | 取消所有订单 | - |
方向常量:
strategy.long - 做多
strategy.short - 做空
订单类型:
- 市价单:不指定
limit 和 stop
- 限价单:指定
limit
- 止损单:指定
stop
- 止损限价单:同时指定
limit 和 stop
输入 input.*
| 函数 | 返回类型 | 示例 |
|---|
input.int() | input int | input.int(14, "Length", minval = 1) |
input.float() | input float | input.float(1.5, "Multiplier", step = 0.1) |
input.bool() | input bool | input.bool(true, "Show Signal") |
input.string() | input string | input.string("SMA", "MA Type", options = ["SMA", "EMA"]) |
input.color() | input color | input.color(color.blue, "Line Color") |
input.source() | series float | input.source(close, "Source") |
input.timeframe() | input string | input.timeframe("D", "Timeframe") |
input.symbol() | input string | input.symbol("AAPL", "Symbol") |
input.session() | input string | input.session("0930-1600", "Session") |
input.enum() | enum type | input.enum(maType.SMA, "MA Type") |
数学 math.*
| 函数 | 说明 |
|---|
math.abs() | 绝对值 |
math.max() | 最大值 |
math.min() | 最小值 |
math.round() | 四舍五入 |
math.floor() | 向下取整 |
math.ceil() | 向上取整 |
math.pow() | 幂运算 |
math.sqrt() | 平方根 |
math.log() | 自然对数 |
math.log10() | 以10为底对数 |
math.avg() | 平均值 |
math.sum() | 求和 |
math.round_to_mintick() | 按最小价格变动单位四舍五入 |
字符串 str.*
| 函数 | 说明 |
|---|
str.tostring() | 转换为字符串 |
str.tonumber() | 转换为数字 |
str.format() | 格式化字符串 |
str.length() | 字符串长度 |
str.contains() | 包含检查 |
str.replace() | 替换 |
str.split() | 分割 |
str.upper() | 转大写 |
str.lower() | 转小写 |
颜色 color.*
| 函数/常量 | 说明 |
|---|
color.new() | 创建带透明度的颜色 |
color.rgb() | 从 RGB 值创建颜色 |
color.from_gradient() | 渐变色 |
color.r() | 获取红色分量 |
color.g() | 获取绿色分量 |
color.b() | 获取蓝色分量 |
color.t() | 获取透明度 |
颜色常量: color.red, color.green, color.blue, color.yellow, color.orange, color.purple, color.white, color.black, color.gray, color.aqua, color.fuchsia, color.lime, color.maroon, color.navy, color.olive, color.silver, color.teal
请求 request.*
| 函数 | 说明 | 关键参数 |
|---|
request.security() | 请求其他品种/周期数据 | symbol, timeframe, expression |
request.security_lower_tf() | 请求更低周期数据 | symbol, timeframe, expression |
request.currency_rate() | 货币汇率 | from, to |
request.dividends() | 股息数据 | ticker, field |
request.earnings() | 收益数据 | ticker, field |
request.financial() | 财务数据 | symbol, financial_id, period |
数组 array.*
| 函数 | 说明 |
|---|
array.new<type>() | 创建数组 |
array.push() | 添加元素到末尾 |
array.pop() | 移除并返回末尾元素 |
array.get() | 获取元素 |
array.set() | 设置元素 |
array.size() | 数组大小 |
array.avg() | 平均值 |
array.sum() | 求和 |
array.max() | 最大值 |
array.min() | 最小值 |
array.sort() | 排序 |
array.slice() | 切片 |
array.from() | 从值创建数组 |
类型系统
类型限定符 (由弱到强)
| 限定符 | 说明 | 何时确定 | 示例 |
|---|
const | 编译时常量 | 编译时 | const int MAX = 100 |
input | 输入值,运行时不变 | 输入时 | input.int() 返回值 |
simple | 首根K线确定后不变 | 第一根K线 | syminfo.ticker |
series | 每根K线可变 | 每根K线 | close, high, low |
重要规则: 弱类型可以传给强类型参数,反之不行。例如 const int 可以传给 simple int 参数,但 series int 不能传给 simple int 参数。
基础类型
| 类型 | 说明 | 字面量示例 |
|---|
int | 整数 | 1, -42, 0 |
float | 浮点数 | 1.5, 3.14, 1e-5 |
bool | 布尔值 | true, false |
color | 颜色 | #FF0000, color.red |
string | 字符串 | "text", 'text' |
引用类型
line, linefill, box, polyline, label, table, chart.point, array, matrix, map
注意: 引用类型始终为 series 限定符。
脚本类型
| 类型 | 声明 | 必须包含 |
|---|
| 指标 | indicator() | 至少一个输出函数 (plot, plotshape, barcolor, line.new 等) |
| 策略 | strategy() | 至少一个订单命令 (strategy.entry, strategy.order 等) |
| 库 | library() | 至少一个 export 的函数/方法/类型/枚举 |
标准脚本结构
// 1. 许可证注释 (可选)
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0
// 2. 版本注解
//@version=6
// 3. 声明语句
indicator("Script Name", overlay = true)
// 4. 导入语句
import library/name/1 as lib
// 5. 常量声明 (SNAKE_CASE)
const int MAX_BARS = 500
// 6. 输入参数
int lengthInput = input.int(14, "Length", minval = 1)
// 7. 函数定义
//@function Calculate moving average
//@param src Source series
//@param len Length
//@returns Moving average value
ma(float src, int len) =>
ta.sma(src, len)
// 8. 计算逻辑
float maValue = ma(close, lengthInput)
// 9. 策略调用 (仅策略)
// strategy.entry(...)
// 10. 可视化
plot(maValue, "MA", color.blue)
// 11. 警报
alertcondition(ta.crossover(close, maValue), "Price Cross MA")
v6 关键变化
| 变化 | v5 语法 | v6 语法 |
|---|
| 动态请求 | 需要 dynamic_requests = true | 默认启用 |
| 布尔值 na | na(boolVar) 有效 | 布尔值不能为 na |
| and/or | 总是执行两边 | 短路求值 |
| 整数除法 | 5/2 = 2 | 5/2 = 2.5 |
| timeframe.period | "D" | "1D" |
| 数组负索引 | 不支持 | arr[-1] = 最后元素 |
| transp 参数 | plot(..., transp = 50) | color.new(color, 50) |
| when 参数 | strategy.entry(..., when = cond) | if cond 包裹 |
命名规范
// 变量和函数: camelCase
float fastMa = ta.sma(close, 10)
// 常量: SNAKE_CASE
const color BULL_COLOR = color.green
// 输入变量后缀 Input
int lengthInput = input.int(14, "Length")
// 明确类型声明
float ma = ta.sma(close, 14) // 推荐
ma = ta.sma(close, 14) // 可以但不推荐
文档注解
//@variable 描述变量
float price = close
//@function 函数描述
//@param paramName 参数描述
//@returns 返回值描述
export myFunction(float paramName) =>
paramName * 2
常见限制
| 限制项 | 数值 |
|---|
| 最大 plot 数量 | 64 |
| 最大 labels/lines/boxes | 500 (可通过 max_*_count 配置) |
| 最大 request.*() 调用 | 40-64 (取决于账户) |
| 集合最大元素 | 100,000 |
| 历史缓冲区 | 5000 bars (大多数系列), 10000 (OHLC, time) |
| 编译超时 | 2 分钟 |
| 执行超时 | 20-40 秒 |
调试技巧
// Pine Logs 面板
log.info("Value: {0}", variable)
log.warning("Warning message")
log.error("Error: {0}", errorInfo)
// 图表标签调试
if condition
label.new(bar_index, high, str.tostring(value), tooltip = "详细信息")
// 数值可视化
plot(debugValue, "Debug", display = display.data_window)
// 条件可视化
bgcolor(condition ? color.new(color.green, 90) : na)
策略开发要点
策略声明
strategy("My Strategy",
overlay = true,
pyramiding = 3, // 同向最大加仓次数
default_qty_type = strategy.percent_of_equity,
default_qty_value = 10, // 每次交易10%资金
initial_capital = 10000,
commission_type = strategy.commission.percent,
commission_value = 0.1,
slippage = 2,
margin_long = 100, // v6 默认100%
margin_short = 100
)
订单类型
- 市价单: 默认,下一tick执行
- 限价单:
limit 参数指定价格
- 止损单:
stop 参数指定价格
- 止损限价单: 同时指定
stop 和 limit
性能优化
- 避免循环内调用 request.*()(除非必要)
- 使用 var 减少重复初始化
var float[] prices = array.new<float>()
- 条件外预计算依赖历史的函数
float rsiValue = ta.rsi(close, 14) // 全局作用域
if someCondition and rsiValue > 70
// ...
- 使用 max_bars_back 避免历史缓冲区错误
- 减少 plot 数量,使用
display = display.none 隐藏不必要的图表显示
重绘问题
重绘发生在脚本在实时K线上重新计算时。避免方法:
// 使用确认K线
if barstate.isconfirmed
// 仅在K线确认后执行逻辑
// 避免 lookahead
request.security(symbol, tf, expression, lookahead = barmerge.lookahead_off)
// 使用历史值
close[1] // 前一根确认K线的收盘价
示例:完整策略模板
//@version=6
strategy("MA Cross Strategy",
overlay = true,
pyramiding = 0,
default_qty_type = strategy.percent_of_equity,
default_qty_value = 100)
// 输入
int fastLength = input.int(10, "Fast MA", minval = 1)
int slowLength = input.int(20, "Slow MA", minval = 1)
float takeProfitPct = input.float(2.0, "Take Profit %", step = 0.1)
float stopLossPct = input.float(1.0, "Stop Loss %", step = 0.1)
// 计算
float fastMa = ta.sma(close, fastLength)
float slowMa = ta.sma(close, slowLength)
// 条件
bool longCondition = ta.crossover(fastMa, slowMa)
bool shortCondition = ta.crossunder(fastMa, slowMa)
// 策略逻辑
if longCondition
strategy.entry("Long", strategy.long)
strategy.exit("Long Exit", "Long",
profit = close * takeProfitPct / 100 / syminfo.mintick,
loss = close * stopLossPct / 100 / syminfo.mintick)
if shortCondition
strategy.entry("Short", strategy.short)
strategy.exit("Short Exit", "Short",
profit = close * stopLossPct / 100 / syminfo.mintick,
loss = close * takeProfitPct / 100 / syminfo.mintick)
// 可视化
plot(fastMa, "Fast MA", color.green)
plot(slowMa, "Slow MA", color.red)
plotshape(longCondition, "Buy", shape.triangleup, location.belowbar, color.green)
plotshape(shortCondition, "Sell", shape.triangledown, location.abovebar, color.red)
文档参考
项目目录 docs/pine-script-docs/ 包含完整的 Pine Script v6 官方文档:
primer/ - 入门教程
language/ - 语言核心概念(执行模型、类型系统、运算符等)
visuals/ - 可视化相关(plots、drawings、colors、tables)
concepts/ - 策略、警报、时间周期、库等
writing/ - 代码风格、调试、优化、限制
faq/ - 常见问题(按主题分类)
migration-guides/ - 版本迁移指南
遇到不确定的函数、类型或用法时,必须先使用 Grep 搜索相关文档:
Grep pattern="function_name" path="docs/pine-script-docs/"
Grep pattern="参数名" path="docs/pine-script-docs/"