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/"
1---2name: pine-coder3description: TradingView Pine Script v6 编程专家。编写高质量的指标(indicator)、策略(strategy)和库(library)脚本。 触发条件: - 用户要求编写 Pine Script / PineScript 代码 - 用户提到 TradingView 指标、策略或脚本开发 - 用户需要创建技术分析工具(均线、MACD、RSI 等) - 用户要求编写回测策略或交易系统 - 用户需要帮助调试或优化 Pine Script 代码 - 用户提到 "Pine", "TV脚本", "tradingview 脚本"4---56# Pine Script v6 编程专家78编写遵循最新 Pine Script v6 规范的 TradingView 脚本。910## 强制性工作流程1112**重要:在编写任何 Pine Script 代码之前,必须遵循以下流程:**1314### 1. 文档查阅(必须)1516使用 Grep 工具在 `docs/pine-script-docs/` 目录中搜索相关函数、类型或概念的官方定义:1718```bash19# 搜索函数签名和用法20Grep pattern="ta\.sma" path="docs/pine-script-docs/"21Grep pattern="strategy\.entry" path="docs/pine-script-docs/"2223# 搜索类型定义24Grep pattern="series float" path="docs/pine-script-docs/language/"25Grep pattern="input\.int" path="docs/pine-script-docs/"26```2728### 2. 验证清单2930编写代码前必须确认:31- [ ] 函数名称拼写正确(如 `ta.sma` 而非 `sma`)32- [ ] 参数类型匹配(如 `length` 需要 `simple int`)33- [ ] 返回类型正确(如 `ta.sma()` 返回 `series float`)34- [ ] 使用的是 v6 语法(非废弃的 v4/v5 语法)3536### 3. 常见错误预防3738在编写代码时主动检查以下易错点:39- 布尔值不能为 `na`(v6 特性)40- `and`/`or` 短路求值可能跳过函数调用41- 整数除法返回浮点数(`5/2 = 2.5`)42- `transp` 参数已移除,使用 `color.new()`43- `when` 参数已移除,使用 `if` 条件4445---4647## 核心命名空间参考4849### 技术分析 `ta.*`5051| 函数 | 签名 | 返回类型 |52|------|------|----------|53| `ta.sma()` | `ta.sma(source, length)` | series float |54| `ta.ema()` | `ta.ema(source, length)` | series float |55| `ta.rsi()` | `ta.rsi(source, length)` | series float |56| `ta.macd()` | `ta.macd(source, fastlen, slowlen, siglen)` | [series float, series float, series float] |57| `ta.crossover()` | `ta.crossover(source1, source2)` | series bool |58| `ta.crossunder()` | `ta.crossunder(source1, source2)` | series bool |59| `ta.highest()` | `ta.highest(source, length)` | series float |60| `ta.lowest()` | `ta.lowest(source, length)` | series float |61| `ta.atr()` | `ta.atr(length)` | series float |62| `ta.stoch()` | `ta.stoch(source, high, low, length)` | series float |63| `ta.bb()` | `ta.bb(series, length, mult)` | [series float, series float, series float] |64| `ta.supertrend()` | `ta.supertrend(factor, atrPeriod)` | [series float, series float] |6566**注意:** `length` 参数通常需要 `simple int` 类型,不接受 `series int`。6768### 策略 `strategy.*`6970| 函数 | 用途 | 关键参数 |71|------|------|----------|72| `strategy.entry()` | 入场订单 | `id`, `direction`, `qty`, `limit`, `stop` |73| `strategy.exit()` | 出场订单 | `id`, `from_entry`, `profit`, `loss`, `limit`, `stop`, `trail_points`, `trail_offset` |74| `strategy.close()` | 关闭指定入场 | `id` |75| `strategy.close_all()` | 关闭所有持仓 | `comment` |76| `strategy.order()` | 基础订单 | `id`, `direction`, `qty`, `limit`, `stop` |77| `strategy.cancel()` | 取消订单 | `id` |78| `strategy.cancel_all()` | 取消所有订单 | - |7980**方向常量:**81- `strategy.long` - 做多82- `strategy.short` - 做空8384**订单类型:**85- 市价单:不指定 `limit` 和 `stop`86- 限价单:指定 `limit`87- 止损单:指定 `stop`88- 止损限价单:同时指定 `limit` 和 `stop`8990### 输入 `input.*`9192| 函数 | 返回类型 | 示例 |93|------|----------|------|94| `input.int()` | input int | `input.int(14, "Length", minval = 1)` |95| `input.float()` | input float | `input.float(1.5, "Multiplier", step = 0.1)` |96| `input.bool()` | input bool | `input.bool(true, "Show Signal")` |97| `input.string()` | input string | `input.string("SMA", "MA Type", options = ["SMA", "EMA"])` |98| `input.color()` | input color | `input.color(color.blue, "Line Color")` |99| `input.source()` | series float | `input.source(close, "Source")` |100| `input.timeframe()` | input string | `input.timeframe("D", "Timeframe")` |101| `input.symbol()` | input string | `input.symbol("AAPL", "Symbol")` |102| `input.session()` | input string | `input.session("0930-1600", "Session")` |103| `input.enum()` | enum type | `input.enum(maType.SMA, "MA Type")` |104105### 数学 `math.*`106107| 函数 | 说明 |108|------|------|109| `math.abs()` | 绝对值 |110| `math.max()` | 最大值 |111| `math.min()` | 最小值 |112| `math.round()` | 四舍五入 |113| `math.floor()` | 向下取整 |114| `math.ceil()` | 向上取整 |115| `math.pow()` | 幂运算 |116| `math.sqrt()` | 平方根 |117| `math.log()` | 自然对数 |118| `math.log10()` | 以10为底对数 |119| `math.avg()` | 平均值 |120| `math.sum()` | 求和 |121| `math.round_to_mintick()` | 按最小价格变动单位四舍五入 |122123### 字符串 `str.*`124125| 函数 | 说明 |126|------|------|127| `str.tostring()` | 转换为字符串 |128| `str.tonumber()` | 转换为数字 |129| `str.format()` | 格式化字符串 |130| `str.length()` | 字符串长度 |131| `str.contains()` | 包含检查 |132| `str.replace()` | 替换 |133| `str.split()` | 分割 |134| `str.upper()` | 转大写 |135| `str.lower()` | 转小写 |136137### 颜色 `color.*`138139| 函数/常量 | 说明 |140|-----------|------|141| `color.new()` | 创建带透明度的颜色 |142| `color.rgb()` | 从 RGB 值创建颜色 |143| `color.from_gradient()` | 渐变色 |144| `color.r()` | 获取红色分量 |145| `color.g()` | 获取绿色分量 |146| `color.b()` | 获取蓝色分量 |147| `color.t()` | 获取透明度 |148149**颜色常量:** `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`150151### 请求 `request.*`152153| 函数 | 说明 | 关键参数 |154|------|------|----------|155| `request.security()` | 请求其他品种/周期数据 | `symbol`, `timeframe`, `expression` |156| `request.security_lower_tf()` | 请求更低周期数据 | `symbol`, `timeframe`, `expression` |157| `request.currency_rate()` | 货币汇率 | `from`, `to` |158| `request.dividends()` | 股息数据 | `ticker`, `field` |159| `request.earnings()` | 收益数据 | `ticker`, `field` |160| `request.financial()` | 财务数据 | `symbol`, `financial_id`, `period` |161162### 数组 `array.*`163164| 函数 | 说明 |165|------|------|166| `array.new<type>()` | 创建数组 |167| `array.push()` | 添加元素到末尾 |168| `array.pop()` | 移除并返回末尾元素 |169| `array.get()` | 获取元素 |170| `array.set()` | 设置元素 |171| `array.size()` | 数组大小 |172| `array.avg()` | 平均值 |173| `array.sum()` | 求和 |174| `array.max()` | 最大值 |175| `array.min()` | 最小值 |176| `array.sort()` | 排序 |177| `array.slice()` | 切片 |178| `array.from()` | 从值创建数组 |179180---181182## 类型系统183184### 类型限定符 (由弱到强)185186| 限定符 | 说明 | 何时确定 | 示例 |187|--------|------|----------|------|188| `const` | 编译时常量 | 编译时 | `const int MAX = 100` |189| `input` | 输入值,运行时不变 | 输入时 | `input.int()` 返回值 |190| `simple` | 首根K线确定后不变 | 第一根K线 | `syminfo.ticker` |191| `series` | 每根K线可变 | 每根K线 | `close`, `high`, `low` |192193**重要规则:** 弱类型可以传给强类型参数,反之不行。例如 `const int` 可以传给 `simple int` 参数,但 `series int` 不能传给 `simple int` 参数。194195### 基础类型196197| 类型 | 说明 | 字面量示例 |198|------|------|------------|199| `int` | 整数 | `1`, `-42`, `0` |200| `float` | 浮点数 | `1.5`, `3.14`, `1e-5` |201| `bool` | 布尔值 | `true`, `false` |202| `color` | 颜色 | `#FF0000`, `color.red` |203| `string` | 字符串 | `"text"`, `'text'` |204205### 引用类型206207`line`, `linefill`, `box`, `polyline`, `label`, `table`, `chart.point`, `array`, `matrix`, `map`208209**注意:** 引用类型始终为 `series` 限定符。210211---212213## 脚本类型214215| 类型 | 声明 | 必须包含 |216|------|------|----------|217| 指标 | `indicator()` | 至少一个输出函数 (plot, plotshape, barcolor, line.new 等) |218| 策略 | `strategy()` | 至少一个订单命令 (strategy.entry, strategy.order 等) |219| 库 | `library()` | 至少一个 `export` 的函数/方法/类型/枚举 |220221---222223## 标准脚本结构224225```pinescript226// 1. 许可证注释 (可选)227// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0228229// 2. 版本注解230//@version=6231232// 3. 声明语句233indicator("Script Name", overlay = true)234235// 4. 导入语句236import library/name/1 as lib237238// 5. 常量声明 (SNAKE_CASE)239const int MAX_BARS = 500240241// 6. 输入参数242int lengthInput = input.int(14, "Length", minval = 1)243244// 7. 函数定义245//@function Calculate moving average246//@param src Source series247//@param len Length248//@returns Moving average value249ma(float src, int len) =>250 ta.sma(src, len)251252// 8. 计算逻辑253float maValue = ma(close, lengthInput)254255// 9. 策略调用 (仅策略)256// strategy.entry(...)257258// 10. 可视化259plot(maValue, "MA", color.blue)260261// 11. 警报262alertcondition(ta.crossover(close, maValue), "Price Cross MA")263```264265---266267## v6 关键变化268269| 变化 | v5 语法 | v6 语法 |270|------|---------|---------|271| 动态请求 | 需要 `dynamic_requests = true` | 默认启用 |272| 布尔值 na | `na(boolVar)` 有效 | 布尔值不能为 na |273| and/or | 总是执行两边 | 短路求值 |274| 整数除法 | `5/2 = 2` | `5/2 = 2.5` |275| timeframe.period | `"D"` | `"1D"` |276| 数组负索引 | 不支持 | `arr[-1]` = 最后元素 |277| transp 参数 | `plot(..., transp = 50)` | `color.new(color, 50)` |278| when 参数 | `strategy.entry(..., when = cond)` | `if cond` 包裹 |279280---281282## 命名规范283284```pinescript285// 变量和函数: camelCase286float fastMa = ta.sma(close, 10)287288// 常量: SNAKE_CASE289const color BULL_COLOR = color.green290291// 输入变量后缀 Input292int lengthInput = input.int(14, "Length")293294// 明确类型声明295float ma = ta.sma(close, 14) // 推荐296ma = ta.sma(close, 14) // 可以但不推荐297```298299---300301## 文档注解302303```pinescript304//@variable 描述变量305float price = close306307//@function 函数描述308//@param paramName 参数描述309//@returns 返回值描述310export myFunction(float paramName) =>311 paramName * 2312```313314---315316## 常见限制317318| 限制项 | 数值 |319|--------|------|320| 最大 plot 数量 | 64 |321| 最大 labels/lines/boxes | 500 (可通过 max_*_count 配置) |322| 最大 request.*() 调用 | 40-64 (取决于账户) |323| 集合最大元素 | 100,000 |324| 历史缓冲区 | 5000 bars (大多数系列), 10000 (OHLC, time) |325| 编译超时 | 2 分钟 |326| 执行超时 | 20-40 秒 |327328---329330## 调试技巧331332```pinescript333// Pine Logs 面板334log.info("Value: {0}", variable)335log.warning("Warning message")336log.error("Error: {0}", errorInfo)337338// 图表标签调试339if condition340 label.new(bar_index, high, str.tostring(value), tooltip = "详细信息")341342// 数值可视化343plot(debugValue, "Debug", display = display.data_window)344345// 条件可视化346bgcolor(condition ? color.new(color.green, 90) : na)347```348349---350351## 策略开发要点352353### 策略声明354355```pinescript356strategy("My Strategy",357 overlay = true,358 pyramiding = 3, // 同向最大加仓次数359 default_qty_type = strategy.percent_of_equity,360 default_qty_value = 10, // 每次交易10%资金361 initial_capital = 10000,362 commission_type = strategy.commission.percent,363 commission_value = 0.1,364 slippage = 2,365 margin_long = 100, // v6 默认100%366 margin_short = 100367)368```369370### 订单类型371372- **市价单**: 默认,下一tick执行373- **限价单**: `limit` 参数指定价格374- **止损单**: `stop` 参数指定价格375- **止损限价单**: 同时指定 `stop` 和 `limit`376377---378379## 性能优化3803811. **避免循环内调用 request.*()**(除非必要)3822. **使用 var 减少重复初始化**383 ```pinescript384 var float[] prices = array.new<float>()385 ```3863. **条件外预计算依赖历史的函数**387 ```pinescript388 float rsiValue = ta.rsi(close, 14) // 全局作用域389 if someCondition and rsiValue > 70390 // ...391 ```3924. **使用 max_bars_back 避免历史缓冲区错误**3935. **减少 plot 数量**,使用 `display = display.none` 隐藏不必要的图表显示394395---396397## 重绘问题398399重绘发生在脚本在实时K线上重新计算时。避免方法:400401```pinescript402// 使用确认K线403if barstate.isconfirmed404 // 仅在K线确认后执行逻辑405406// 避免 lookahead407request.security(symbol, tf, expression, lookahead = barmerge.lookahead_off)408409// 使用历史值410close[1] // 前一根确认K线的收盘价411```412413---414415## 示例:完整策略模板416417```pinescript418//@version=6419strategy("MA Cross Strategy",420 overlay = true,421 pyramiding = 0,422 default_qty_type = strategy.percent_of_equity,423 default_qty_value = 100)424425// 输入426int fastLength = input.int(10, "Fast MA", minval = 1)427int slowLength = input.int(20, "Slow MA", minval = 1)428float takeProfitPct = input.float(2.0, "Take Profit %", step = 0.1)429float stopLossPct = input.float(1.0, "Stop Loss %", step = 0.1)430431// 计算432float fastMa = ta.sma(close, fastLength)433float slowMa = ta.sma(close, slowLength)434435// 条件436bool longCondition = ta.crossover(fastMa, slowMa)437bool shortCondition = ta.crossunder(fastMa, slowMa)438439// 策略逻辑440if longCondition441 strategy.entry("Long", strategy.long)442 strategy.exit("Long Exit", "Long",443 profit = close * takeProfitPct / 100 / syminfo.mintick,444 loss = close * stopLossPct / 100 / syminfo.mintick)445446if shortCondition447 strategy.entry("Short", strategy.short)448 strategy.exit("Short Exit", "Short",449 profit = close * stopLossPct / 100 / syminfo.mintick,450 loss = close * takeProfitPct / 100 / syminfo.mintick)451452// 可视化453plot(fastMa, "Fast MA", color.green)454plot(slowMa, "Slow MA", color.red)455plotshape(longCondition, "Buy", shape.triangleup, location.belowbar, color.green)456plotshape(shortCondition, "Sell", shape.triangledown, location.abovebar, color.red)457```458459---460461## 文档参考462463项目目录 `docs/pine-script-docs/` 包含完整的 Pine Script v6 官方文档:464465- `primer/` - 入门教程466- `language/` - 语言核心概念(执行模型、类型系统、运算符等)467- `visuals/` - 可视化相关(plots、drawings、colors、tables)468- `concepts/` - 策略、警报、时间周期、库等469- `writing/` - 代码风格、调试、优化、限制470- `faq/` - 常见问题(按主题分类)471- `migration-guides/` - 版本迁移指南472473**遇到不确定的函数、类型或用法时,必须先使用 Grep 搜索相关文档:**474475```bash476# 搜索示例477Grep pattern="function_name" path="docs/pine-script-docs/"478Grep pattern="参数名" path="docs/pine-script-docs/"479```