mcpField
P
pinescript

pinescript

github.com/iliaal开发45212 次安装3 天前更新
代码仓库

关于 pinescript

面向 TradingView 指标和策略开发者的 Pine Script 技能,强调先核对最新文档,并关注语法、平台限制及信号和回测验证。

主要功能

  1. 01按版本核对文档
  2. 02语法与平台限制指导
  3. 03性能和调试实践
  4. 04策略验证与发布指导

适用场景

  1. 01编写 Pine Script 指标
  2. 02构建并测试交易策略
  3. 03调试信号与重绘行为

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/iliaal/ai-skills --skill pinescript

安装后在 Claude Code 中输入/pinescript确认已加载。

附带文件references/evidence/findings-log.mdSPEC.md

详细介绍

Pine Script 开发

实现前先验证:对于 Pine Script 特定版本的语法或新增内置函数,请先查阅当前官方文档,再编写代码。有条件时优先使用 Context7(query-docs)。否则,请使用可用的网页工具阅读适用于脚本版本的 TradingView Pine Script 文档。TradingView 会频繁更新 Pine Script,训练数据可能已经过时。

关键语法规则

  • 保持简单的三元表达式易于阅读;多行表达式必须使用有效的续行缩进。对于复杂的三元表达式,请使用中间变量:
    isBull = close > open
    barColor = isBull ? color.green : color.red
    
  • 括号外的续行必须缩进非 4 的倍数个空格:与起始行缩进相同会报错,缩进 4、8、12 个空格也会被解析为局部代码块并报错(通常使用 2 个空格)。括号内(函数调用、带括号的表达式)可使用任意缩进,包括 4 的倍数
  • 绝不能在局部作用域(if/for/函数)中使用 plot();请改用条件值:plot(condition ? value : na)
  • 当信号需要使用图表柱的收盘值时,请使用 barstate.isconfirmed。它不能保证请求的更高时间框架数值已确认;请单独检查 request.security() 的偏移和 lookahead。

平台限制

为脚本确定规模前,请查看当前平台限制:64 个 plot 计数(一次调用可能占用多个);line、box 或 label ID 各最多 500 个,polyline ID 最多 100 个;40 次唯一的 request.*() 调用,Ultimate 上为 64 次;100,000 个编译后的令牌。历史缓冲区、请求的盘中数据和图表历史各有限制;request.security() 没有通用的 500 根柱历史限制。

  • 使用 xloc.bar_index 定位的绘图最多只能向过去延伸 9,999 根柱,向未来延伸 500 根柱;对于更早的数据,请将绘图切换为 xloc.bar_time 并传入时间戳(未使用 xloc.bar_time 的时间值会被视为未来柱索引并报错)
  • 设置相应的 max_*_count 声明参数,并使用滚动缓冲区限制增长:推入每个对象,然后在超出预期线条数量时执行 line.delete(arr.shift())。每种绘图类型的默认显示数量约为 50 个。

性能

  • 元组 security 调用:使用一次返回 [close, high, low] 的 request.security(),而不是分 3 次调用
  • 使用 array.new<type>(size) 预分配数组,而不是边推入边调整大小
  • 在全局作用域中每根柱上计算依赖历史数据的函数,例如 ta.rsi()。使用已存储的结果对信号谓词进行短路求值;请参阅 Pine v6 惰性求值。
  • 将重复计算缓存到变量中;Pine 会在每根柱上重新计算
  • 使用 for item in myArray(或 for [i, item] in myArray)遍历集合,而不是使用 for i = 0 to array.size(...) - 1;这两种形式都会在后续迭代中使用更新后的集合大小。
  • 对于 for...in,调整数组或矩阵大小时,请考虑迭代边界的变化。添加或移除 map 条目时,请在修改原始 map 的同时遍历 map.keys() 快照或 map.copy()。避免直接用循环结果初始化 var/varip:循环会在第一次迭代后停止。请先声明变量,再用 := 赋值,或从函数返回循环结果。请参阅 Pine v6 循环规则。
  • 将相关值建模为用户定义类型,而不是使用多个平行数组:定义带有 float entry、int startBar 和 method 函数的 type Trade,并将其存储在一个 array<Trade> 中。平行数组(entries、startBars 等)只要有一次 push/remove 遗漏就会失去同步,而且每项操作都必须在每个数组中重复执行;一个类型化数组可将每个对象的字段放在一起

调试

通过 log.info()、log.warning() 和 log.error() 使用 Pine Logs,并进行以下可视化检查:

  • 标签调试:使用 label.new(bar_index, high, str.tostring(myVar)) 检查数值;明确限制保留的标签数量。
  • 表格监视器:使用 table.new() 和 barstate.islast 创建实时变量仪表板
  • 调试模式开关:使用 if input.bool(false, "Debug") 编写本地调试代码;绘图调用保持在全局作用域。
  • 重绘检查:记录带时间戳的实时信号,然后在重新加载后对比相同的柱。value[1] 指的是前一根柱,无法检测更早计算结果的修订。

策略与回测

  • 使用 strategy.* 函数:strategy.wintrades、strategy.losstrades、strategy.grossprofit
  • 在更新持久化回撤状态之前先声明它:
    var float maxEquity = strategy.equity
    maxEquity := math.max(maxEquity, strategy.equity)
    dd = maxEquity > 0 ? (maxEquity - strategy.equity) / maxEquity * 100 : na
    
  • 根据超额收益的均值除以其标准差,并乘以每年周期数的平方根,估算年化 Sharpe;说明采样间隔和年化假设,并处理方差为零的情况。
  • 滚动前向验证:在第 1 个时期优化,在第 2 个时期测试;在第 2 个时期重新优化,在第 3 个时期测试。将性能退化与抽样不确定性、成本和市场状态变化进行比较;没有任何通用百分比可以判定过拟合。
  • 指标准确性测试:在柱 t,将 prediction[horizon] 与此时已实现的结果进行评分,例如 close > close[horizon],并排除预热柱。正偏移引用过去,绝不引用未来柱;参见历史引用。
  • 统计每个切片的评估次数:调优期间被评分 N 次的切片就是调优数据,无论它被如何标记;因此,在每个切片上运行多参数扫描,会让“验证”数据变成选择偏差。至少保留一个切片,并明确规定查看次数预算;等参数锁定后再使用该切片。如果想“再看一次”,就该停止。
  • 每个切片的最优参数互相冲突,表明策略不稳定:在添加市场状态分类器之前,先将稳健的固定参数与更简单的策略进行比较。使用入场前可获取的信息拟合任何分类器,并在未触及的数据上验证;仅凭最优参数冲突,并不能证明所有固定参数都无效。
  • 启用市场状态门控后,重新运行每次参数扫描:门控前的扫描结果无法直接沿用,因为被排除的亏损时段会掩盖参数的实际效果。针对一种策略失效模式校准的过滤器,不能直接套用到基于相同信号的其他策略。

可视化

  • 使用 color.from_gradient() 为趋势强度着色
  • 自适应文本大小:日内使用 size.small,日线及更长周期使用 size.normal
  • 动态表格行数:通过输入开关,根据已启用的功能调整大小
  • 当控制开关关闭时,input.*(..., active = condition) 会将输入项显示为灰色(例如,只有勾选“Use smoothing”后,才能编辑平滑长度),这比用工具提示说明“除非……否则忽略”更清晰
  • 专业配色常量:定义一次 BULL_COLOR、BEAR_COLOR、NEUTRAL_COLOR,并设置透明度

发布

  • 文档应作为注释放在 .pine 文件顶部,位于 indicator()/strategy() 之前
  • 使用 @version、@description、@param 标签
  • 多行工具提示:tooltip="Line 1" + "\n" + "Line 2"
  • 发布前,请查阅当前 TradingView 发布规则,确认脚本的可见性和类别;不要根据固定清单推断平台政策。

常见编码错误

  • 指标堆叠(RSI + Stochastics + CCI):它们测量的都是同一项内容(动量)。应改用不同类别的指标。
  • 在未触碰过的数据上评估参数稳定性;数值看起来特别具体,并不能证明存在过拟合,而使用整数也无法避免过拟合。
  • 说明信号是有意在柱线内更新,还是需要等待柱线确认;测试这一行为,包括请求的时间范围。
  • 将阈值硬编码而不使用 input(),会让脚本无法在不同交易品种上进行测试。

工作流

  1. 在 Pine Editor 中编写指标/策略
  2. 使用多个时间范围,通过柱线回放和策略测试器进行测试
  3. 在信任回测结果之前进行滚动前向验证(参见上文的策略与回测)
  4. 验证:在 3 个以上的交易品种和 2 个以上的时间范围上运行

验证

  • 指标在 TradingView 上编译无错误
  • 通过比较实时柱线与重新加载后的柱线,验证信号稳定性,并检查更高时间范围的请求;仅仅存在保护机制并不能证明其有效。
  • 在不同时间范围内,对 3 个以上的交易品种进行滚动前向测试

评论

支持 Markdown