如何使用 Pine Script 创建自定义指标和交易策略?
Pine Script 是 TradingView 平台专有的脚本语言,用于创建自定义技术指标、绘图工具和交易策略。无论是想自定义一个均线变色显示,还是构建一套完整的量化交易系统,Pine Script 都能实现。
Pine Script 的基本语法结构
Pine Script 的语法融合了 Python 和 JavaScript 的特点,上手门槛不高,但要写出健壮的策略代码需要理解其核心机制。
一个最简单的指标脚本如下:
pine//@version=5 indicator("My First Indicator", overlay=true) length = input.int(20, "MA Length") ma = ta.sma(close, length) plot(ma, color=color.blue, linewidth=2)
第一行 //@version=5 声明脚本版本,indicator() 函数定义指标名称和属性,overlay=true 表示指标叠加在K线图上。input.int() 创建用户可配置的参数,ta.sma() 计算简单移动平均,plot() 将结果绘制到图表上。
版本选择:v4、v5 还是 v6?
目前 Pine Script 有三个主要版本在使用:
- v4:老旧版本,TradingView 已不再推荐,仅用于维护旧脚本
- v5:当前最稳定、社区资源最丰富的版本,绝大多数教程和开源代码基于 v5
- v6:2026 年最新版本,新增枚举类型、动态请求、多段线绘制等功能,但社区生态仍在建设中
新项目建议从 v5 起步,掌握后再迁移到 v6。v5 到 v6 的迁移主要涉及整数除法行为变化(v5 中 1/2=0,v6 中 1/2=0.5)、更严格的类型检查等,TradingView 提供了自动迁移工具。
核心概念详解
输入参数:让指标可配置
input() 系列函数允许用户在指标设置面板中调整参数,无需修改代码:
pine//@version=5 indicator("Configurable RSI") length = input.int(14, "RSI Length", minval=1) src = input.source(close, "Source") ovb = input.int(70, "Overbought Level") oss = input.int(30, "Oversold Level") rsi = ta.rsi(src, length) plot(rsi, "RSI", color=color.purple) hline ovb, "Overbought", color=color.red hline oss, "Oversold", color=color.green
input.int() 定义整数参数,input.source() 定义数据源(如 close、open、high),input.float() 定义浮点参数,input.string() 定义字符串选项。这些函数都支持 minval、maxval、step 等约束。
变量声明:理解 var 和 varip
Pine Script 按照每根K线逐根执行脚本,变量的生命周期是理解其运行模型的关键:
- 普通赋值:每根K线重新计算,如
count = count + 1在每根K线上初始值都是na - var 声明:只在第一根K线上初始化,之后保持值跨K线持久化,如
var count = 0然后count := count + 1会持续累加 - varip 声明:与 var 类似,但在实时K线的每次价格变动时更新,适用于需要跟踪盘口变化的场景
pine//@version=5 indicator("var vs varip Demo") var int barCount = 0 barCount := barCount + 1 varip int tickCount = 0 tickCount := tickCount + 1 plot(barCount, "Bars", color=color.blue) plot(tickCount, "Ticks", color=color.red)
自定义函数
Pine Script 支持自定义函数,且可以返回多个值(用元组实现):
pine//@version=5 indicator("Custom Function Demo") calcMA(float src, int len, string method) => switch method "SMA" => ta.sma(src, len) "EMA" => ta.ema(src, len) "WMA" => ta.wma(src, len) => ta.sma(src, len) maType = input.string("SMA", "MA Type", options=["SMA", "EMA", "WMA"]) maLen = input.int(20, "Length") result = calcMA(close, maLen, maType) plot(result, "Custom MA", color=color.orange, linewidth=2)
v5 引入的 switch 语句使多条件逻辑比 if-else 更简洁,v6 进一步支持枚举类型来替代字符串选项。
创建自定义指标:从思路到实现
以创建一个带买卖信号的均线交叉指标为例,完整演示开发流程:
pine//@version=5 indicator("MA Crossover Signal", overlay=true) // 1. 定义输入参数 fastLen = input.int(10, "Fast MA Length", minval=1) slowLen = input.int(30, "Slow MA Length", minval=1) maType = input.string("EMA", "MA Type", options=["SMA", "EMA"]) // 2. 计算指标 fastMA = maType == "SMA" ? ta.sma(close, fastLen) : ta.ema(close, fastLen) slowMA = maType == "SMA" ? ta.sma(close, slowLen) : ta.ema(close, slowLen) // 3. 判断交叉 bullCross = ta.crossover(fastMA, slowMA) bearCross = ta.crossunder(fastMA, slowMA) // 4. 绘制 plot(fastMA, "Fast MA", color=color.blue, linewidth=2) plot(slowMA, "Slow MA", color=color.red, linewidth=2) plotshape(bullCross, "Buy Signal", shape.triangleup, location.belowbar, color.green, size=size.small) plotshape(bearCross, "Sell Signal", shape.triangledown, location.abovebar, color.red, size=size.small) // 5. 设置警报 alertcondition(bullCross, "Golden Cross", "Fast MA crossed above Slow MA") alertcondition(bearCross, "Death Cross", "Fast MA crossed below Slow MA")
这个指标实现了:可配置的快慢均线参数、SMA/EMA 切换、交叉信号标记、以及警报触发条件。在 TradingView 的 Pine Script 编辑器中粘贴代码,点击"添加到图表"即可看到效果。
构建交易策略与回测
将 indicator() 替换为 strategy() 就能启用回测功能,自动生成交易报告:
pine//@version=5 strategy("MA Crossover Strategy", overlay=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1) fastLen = input.int(10, "Fast MA") slowLen = input.int(30, "Slow MA") fastMA = ta.ema(close, fastLen) slowMA = ta.ema(close, slowLen) bullCross = ta.crossover(fastMA, slowMA) bearCross = ta.crossunder(fastMA, slowMA) if bullCross strategy.entry("Long", strategy.long) if bearCross strategy.close("Long") plot(fastMA, "Fast", color=color.blue) plot(slowMA, "Slow", color=color.red)
strategy() 函数的关键参数:
initial_capital:回测初始资金default_qty_type和default_qty_value:每次交易的仓位大小commission_type和commission_value:手续费设置slippage:滑点模拟
strategy.entry() 开仓,strategy.close() 平仓,strategy.exit() 可以设置止损止盈。回测结果面板显示净利润、胜率、最大回撤、夏普比率等关键指标。
多时间框架分析
request.security() 函数可以在当前图表的时间框架下访问其他时间框架的数据,这是构建多周期策略的基础:
pine//@version=5 indicator("Multi-Timeframe MA", overlay=true) currentMA = ta.ema(close, 20) dailyMA = request.security(syminfo.tickerid, "D", ta.ema(close, 20)) weeklyMA = request.security(syminfo.tickerid, "W", ta.ema(close, 20)) plot(currentMA, "Chart MA", color=color.blue) plot(dailyMA, "Daily MA", color=color.orange) plot(weeklyMA, "Weekly MA", color=color.purple)
使用 request.security() 时要注意:避免在当前时间框架比请求时间框架更小时产生重绘问题,推荐在历史数据回测中使用 barmerge.lookahead_on 配合 barmerge.gaps_off 来确保数据对齐。
常用内置函数速查
| 类别 | 函数 | 说明 |
|---|---|---|
| 趋势指标 | ta.sma() / ta.ema() / ta.wma() | 简单/指数/加权移动平均 |
| 趋势指标 | ta.macd() | MACD 指标,返回元组 |
| 动量指标 | ta.rsi() | 相对强弱指标 |
| 动量指标 | ta.stoch() | 随机指标 |
| 波动指标 | ta.atr() | 平均真实波幅 |
| 波动指标 | ta.bb() | 布林带,返回元组 |
| 成交量 | ta.obv() | 能量潮指标 |
| 交叉判断 | ta.crossover() / ta.crossunder() | 交叉信号检测 |
| 绘图 | plot() / plotshape() / plotchar() | 线条/形状/字符绘制 |
| 警报 | alertcondition() | 自定义警报条件 |
| 策略 | strategy.entry() / strategy.close() / strategy.exit() | 开仓/平仓/带止损止盈平仓 |
实际开发中的注意事项
性能优化: Pine Script 在每根K线上逐根执行,避免在循环中进行复杂计算。for 循环的迭代次数有上限(默认 100 次),超出会报错。将能用内置函数实现的逻辑优先使用 ta.* 系列,它们经过了底层优化。
重绘问题: 某些写法会导致历史信号随新数据变化,这会严重干扰回测结果的可靠性。使用 barstate.isrealtime 区分实时和历史数据,在策略中避免使用 request.security() 获取未来数据。
代码组织: 随着指标复杂度增加,建议将逻辑拆分为独立函数,使用有意义的变量名,添加注释说明关键逻辑。Pine Script 支持用 import 引入库(library),将通用功能封装为可复用模块。
调试技巧: 使用 label.new() 在图表上打印变量值,比反复修改 plot() 更灵活。str.tostring() 将数值转为字符串用于标签显示。在开发阶段,可以临时用 plot() 输出中间变量来排查逻辑错误。
从想法到发布的完整流程
- 在 TradingView 图表底部打开 Pine Script 编辑器
- 选择"新建/指标"或"新建/策略"模板
- 编写代码,点击"添加到图表"预览效果
- 切换不同品种和时间框架验证指标的适用性
- 确认无误后点击"发布",可设为公开或私有
- 在指标设置中调整参数,观察不同配置下的表现
- 对策略类脚本,使用策略测试器面板查看回测报告
Pine Script 的学习曲线平缓,从几行代码的简单指标到复杂的量化策略,都可以在 TradingView 平台内完成开发、测试和发布。掌握输入参数、变量声明、内置技术分析函数和策略框架这几个核心模块后,就能应对大部分自定义指标和策略的开发需求。