TradingView脚本入门:写自己的Pine Script指标
Pine Script是TradingView的自定义指标语言,本文从语法基础到实战案例,教你编写自己的技术指标、信号提醒和策略回测脚本。
引言:为什么你需要自己的脚本
TradingView提供了上百个内置技术指标——MA、RSI、MACD、布林带等应有尽有。但这些指标是通用的——它们的参数固定、逻辑固定、显示方式固定。如果你想:
- 只在成交量放大时才显示MA交叉信号
- 同时监控5个指标并在图表上显示看板评分
- 用自己定义的条件自动发出买卖提醒
- 回测某个策略在过去一年的实际胜率
你需要Pine Script——TradingView的自定义指标编程语言。它让你编写自己的指标逻辑、自定义显示方式、设置条件提醒和运行策略回测。
本文将从Pine Script的语法基础开始,逐步教你编写实用的交易指标和策略脚本。
第一章:Pine Script语法基础
脚本的基本结构
每个Pine Script脚本都遵循这个基本结构:
//@version=5
indicator("我的指标", overlay=true)
// 变量声明
ma20 = ta.sma(close, 20)
ma50 = ta.sma(close, 50)
// 信号逻辑
bullSignal = ta.crossover(ma20, ma50)
// 绘图
plot(ma20, color=color.green, title="MA20")
plot(ma50, color=color.red, title="MA50")
// 标记信号
plotshape(bullSignal, style=shape.triangleup, location=location.belowbar, color=color.green, title="金叉买入")
关键要素:
//@version=5— 声明使用Pine Script v5(最新版本)indicator()或strategy()— 脰明脚本类型overlay=true— 指标画在主图表上(不是单独窗口)ta.sma()— 内置技术分析函数ta.crossover()— 交叉检测函数plot()— 画线plotshape()— 画标记(三角形、圆圈等)
变量与数据类型
Pine Script的变量类型:
- float:浮点数(价格、指标值)
- int:整数(周期数)
- bool:布尔值(true/false,信号触发条件)
- color:颜色值
- string:字符串
变量声明方式:
// 用 = 声明新变量
myMA = ta.sma(close, 20)
// 用 := 更新已有变量(在if/for语句中)
var counter = 0
if bullSignal
counter := counter + 1
内置数据引用
Pine Script提供了内置的价格数据:
close— 收盘价open— 开盘价high— 最高价low— 最低价volume— 成交量bar_index— 当前K线的序号
条件判断
// 简单条件
isBull = close > open
// 复合条件
strongBull = close > open and volume > ta.sma(volume, 20) * 1.5
// if-else
signal = if close > ta.sma(close, 20)
1 // 多
else if close < ta.sma(close, 20)
-1 // 空
else
0 // 中性
第二章:常用内置技术分析函数
移动平均类
ta.sma(source, length) // 简单移动平均
ta.ema(source, length) // 指数移动平均
ta.wma(source, length) // 加权移动平均
ta.vwma(source, length) // 成交量加权移动平均
ta.rma(source, length) // 相对移动平均(RSI内部使用)
动量类
ta.rsi(source, length) // RSI
ta.mom(source, length) // 动量指标
ta.roc(source, length) // 变化率
MACD
[macdLine, signalLine, histLine] = ta.macd(close, 12, 26, 9)
交叉检测
ta.crossover(a, b) // a上穿b(前一根a<b,当前a>b)
ta.crossunder(a, b) // a下穿b(前一根a>b,当前a<b)
波动类
ta.atr(length) // ATR
ta.stdev(source, length) // 标准偏差
第三章:实战脚本案例——5个实用指标
案例1:成交量确认的MA交叉指标
只在成交量放大时才发出MA交叉信号——过滤低成交量的假信号:
//@version=5
indicator("成交量确认MA交叉", overlay=true)
ma20 = ta.sma(close, 20)
ma50 = ta.sma(close, 50)
volMA = ta.sma(volume, 20)
// MA交叉
goldenCross = ta.crossover(ma20, ma50)
deathCross = ta.crossunder(ma20, ma50)
// 成交量确认:当前成交量 > 20日均量的1.5倍
volConfirm = volume > volMA * 1.5
// 只在成交量确认时发出信号
buySignal = goldenCross and volConfirm
sellSignal = deathCross and volConfirm
plot(ma20, color=color.green)
plot(ma50, color=color.red)
plotshape(buySignal, style=shape.triangleup, location=location.belowbar, color=color.green, title="金叉买入")
plotshape(sellSignal, style=shape.triangledown, location=location.abovebar, color=color.red, title="死叉卖出")
案例2:5指标看板评分脚本
在图表上显示5个指标的评分和多空判断:
//@version=5
indicator("5指标看板", overlay=false)
// 趋势指标:MA方向
trendScore = close > ta.sma(close, 50) ? 40 : (close < ta.sma(close, 50) ? -40 : 0)
// 动量指标:RSI
rsiVal = ta.rsi(close, 14)
momentumScore = rsiVal > 70 ? 15 : (rsiVal > 50 ? 10 : (rsiVal < 30 ? -15 : -10))
// 波动指标:ATR风险
atrVal = ta.atr(14)
atrMA = ta.sma(atrVal, 14)
volatilityScore = atrVal < atrMA * 0.5 ? 10 : (atrVal > atrMA * 1.5 ? -10 : 5)
// 成交量指标:VWAP方向
vwapVal = ta.vwap(close)
volumeScore = close > vwapVal ? 25 : (close < vwapVal ? -25 : 0)
// 支撑阻力:接近支撑加分
supportScore = close < ta.sma(close, 50) * 0.97 ? 10 : (close > ta.sma(close, 50) * 1.03 ? -10 : 0)
// 总分
totalScore = trendScore + momentumScore + volatilityScore + volumeScore + supportScore
// 多空判断
bias = totalScore > 50 ? "强多" : (totalScore > 20 ? "偏多" : (totalScore < -50 ? "强空" : (totalScore < -20 ? "偏空" : "中性")))
// 显示
plot(totalScore, color=totalScore > 0 ? color.green : color.red, title="看板评分")
label.new(bar_index, totalScore, bias, color=totalScore > 0 ? color.green : color.red, textcolor=color.white, style=label.style_label_center)
案例3:自动提醒脚本
设置条件满足时自动发送提醒消息:
//@version=5
indicator("买卖提醒", overlay=true)
rsi = ta.rsi(close, 14)
ma20 = ta.sma(close, 20)
ma50 = ta.sma(close, 50)
// 买入提醒:RSI<30 + MA金叉
buyAlert = rsi < 30 and ta.crossover(ma20, ma50)
// 卖出提醒:RSI>70 + MA死叉
sellAlert = rsi > 70 and ta.crossunder(ma20, ma50)
alertcondition(buyAlert, title="买入提醒", message="RSI超卖+MA金叉,买入信号!")
alertcondition(sellAlert, title="卖出提醒", message="RSI超买+MA死叉,卖出信号!")
plotshape(buyAlert, style=shape.triangleup, location=location.belowbar, color=color.green)
plotshape(sellAlert, style=shape.triangledown, location=location.abovebar, color=color.red)
案例4:策略回测脚本
用strategy()类型可以运行回测:
//@version=5
strategy("MA交叉策略回测", overlay=true)
ma20 = ta.sma(close, 20)
ma50 = ta.sma(close, 50)
// 入场条件
longCondition = ta.crossover(ma20, ma50)
shortCondition = ta.crossunder(ma20, ma50)
// 入场
if longCondition
strategy.entry("多", strategy.long)
if shortCondition
strategy.entry("空", strategy.short)
// 止损
strategy.exit("多平", "多", stop=strategy.position_avg_price * 0.97)
strategy.exit("空平", "空", stop=strategy.position_avg_price * 1.03)
plot(ma20, color=color.green)
plot(ma50, color=color.red)
案例5:自定义看板表格
在图表右上角显示指标状态表格:
//@version=5
indicator("看板表格", overlay=true)
rsi = ta.rsi(close, 14)
ma20 = ta.sma(close, 20)
ma50 = ta.sma(close, 50)
atr = ta.atr(14)
// 表格
var table dash = table.new(position.top_right, 2, 5, bgcolor=color.new(color.black, 80))
if barstate.islast
table.cell(dash, 0, 0, "指标", text_color=color.white)
table.cell(dash, 1, 0, "状态", text_color=color.white)
table.cell(dash, 0, 1, "MA方向", text_color=color.white)
table.cell(dash, 1, 1, close > ma50 ? "多" : "空", text_color=close > ma50 ? color.green : color.red)
table.cell(dash, 0, 2, "RSI", text_color=color.white)
table.cell(dash, 1, 2, str.tostring(rsi, "#.0"), text_color=rsi > 50 ? color.green : color.red)
table.cell(dash, 0, 3, "ATR", text_color=color.white)
table.cell(dash, 1, 3, str.tostring(atr, "#.0"), text_color=color.white)
第四章:脚本优化与注意事项
性能优化
- 避免在每根K线上重新计算:用
var声明只初始化一次的变量 - 减少plotshape的频率:只在关键信号时标注,不要每根K线都标注
- 避免过度嵌套if语句:Pine Script对嵌套深度有限制
常见错误
- 忘记 //@version=5:导致使用旧版本语法,很多v5功能不可用
- 用 = 代替 :=:在if语句中更新变量必须用 :=,用 = 会声明新变量
- 混淆 indicator 和 strategy:indicator只显示不能回测,strategy可以回测但不能设置提醒
- 忽略安全函数限制:Pine Script不允许请求其他品种的数据(除非用request.security)
跨品种数据引用
如果你想在BTC的图表上同时看ETH的数据:
ethClose = request.security("ETHUSDT", "60", close)
注意:跨品种引用会降低脚本性能,且不能在strategy中使用。
第五章:常见误区与陷阱
误区1:脚本信号就是交易信号
脚本告诉你某个条件满足了——但满足条件不等于应该交易。脚本只是信息工具,最终的交易决策仍然需要你结合市场环境、品种特征和风险管理来做判断。
误区2:过度复杂化脚本
脚本越复杂,运行越慢,维护越难。一个简单的5指标看板比一个20指标看板更实用——因为你能在几秒钟内理解5指标的状态,而20指标需要几分钟才能分析完。保持简洁。
误区3:不回测策略脚本
strategy脚本提供了回测功能——运行后TradingView会显示策略的胜率、盈亏比、最大回撤等统计。如果你不回测就直接用策略脚本交易,可能发现实际效果远不如预期。
误区4:忽视版本兼容性
Pine Script从v1到v5有很多语法变化——v5的函数命名和逻辑与v3完全不同。如果你在网上找到旧版本的脚本,需要手动转换到v5语法才能运行。不要直接复制v3/v4的脚本到v5环境。
误区5:只写脚本不手动验证
脚本输出的信号应该与手动计算的结果一致——如果脚本显示RSI=45,手动计算应该是45。如果不一致,说明脚本有bug。每次写新脚本后,都应该用几根已知K线的手动计算来验证脚本输出。
总结
Pine Script的核心价值在于让你自定义指标逻辑和交易信号——不再受限于TradingView的内置指标。它的最佳使用方式是:
- 从简单脚本开始——先学会画一条MA、标注一个交叉
- 逐步增加复杂度——加入成交量确认、多指标看板
- 回测验证所有策略——不回测不交易
- 设置自动提醒——条件满足时自动通知
- 保持脚本简洁——5个指标比20个指标更实用
Pine Script不需要你是程序员——它的语法简单、函数丰富、文档完整。只要学会基本的语法结构和几个核心函数,你就能写出实用的交易指标。从今天开始写第一个脚本——哪怕只是一条自定义颜色的MA线,你已经迈出了自定义交易工具的第一步。
更多实战方法见帝门交易。