教程 · 单套解锁 教程 · EA量化教学

EA05 PineScript/TradingView 策略

使用手册 + 操作教程 共 18 章全部免费开放,一步一步把软件用起来;核心知识点 8 章,¥69 一次解锁讲透原理。

作者 枢汇安全课堂 更新 2026-10-13 阅读 120 收录 EA量化教学 · 26 章
本课程 · 单套解锁
¥69¥104
单品永久解锁 · 会员可阅 · 一次购买终身使用
✓使用手册 + 操作教程 共 18 章全文免费 ✓核心知识点 8 章,¥69 一次解锁 ✓支持电脑 / 手机 · 永久免费更新
注册后解锁核心知识点
免费学习区 使用手册 + 操作教程 共 18 章全部免费开放 · 核心知识点 8 章为付费内容 ¥69 解锁核心知识点
PART ONE

使用手册

功能在哪 · 是什么 · 怎么调出来

一、Pine Script 是什么

Pine Script 是 TradingView 专有的脚本语言,特点:

  • 纯云端脚本,不用装开发环境,网页里写,浏览器里编译运行
  • 写 indicator 画在图上,写 strategy 可以回测
  • 回测由 TradingView 自带的"券商模拟器"(Broker Emulator)撮合
  • 要实盘自动交易,需要配合 Webhook + 中间服务 + 券商 API
白话注解:Pine Script 就是 TradingView 里的"Excel 公式"——你在网页上写几行代码,它自动帮你画均线、发信号。但它本身不能帮你下单,最多帮你发通知。

1、和 MT4/MT5 的 EA 有什么区别

对比项Pine Script(TradingView)MQL4/MQL5(MetaTrader)
运行位置TradingView 云端服务器你自己的电脑/VPS
数据源TradingView 提供的数据券商服务器数据
自动下单不能直接下,要走 Webhook能直接下
最小执行粒度一根K线(Bar)Tick 级
学习曲线平缓,几小时上手陡峭,要学几周
白话注解:Pine 适合"想清楚策略逻辑 + 看历史成绩",MQL 适合"真正挂在服务器上自动跑"。很多成熟做法是:Pine 里研究信号,MQL 或第三方跟单工具里做执行。

二、strategy.exit:止损止盈与移动止损

1、完整签名(官方参考手册核实)

strategy.exit(id, from_entry, qty, qty_percent, profit, limit, loss, stop,
     trail_price, trail_points, trail_offset, oca_name,
     comment, comment_profit, comment_loss, comment_trailing,
     alert_message, alert_profit, alert_loss, alert_trailing)

2、六种出场参数,两种单位

参数单位含义
limit价格限价单到指定价位止盈
stop价格止损单到指定价位止损
profittick 数盈利 N 个 tick 挂限价止盈
losstick 数亏损 N 个 tick 挂止损
trail_price价格移动止损的触发价位
trail_pointstick 数移动止损的触发盈利(tick)
trail_offsettick 数触发后,止损挂在触发价多少个 tick 之外
最容易算错的地方:profit/loss/trail_points/trail_offset 的单位是 tick(最小变动价位),不是价格、不是点、不是百分比!黄金 mintick=0.01 时,止损 5 美元 = 500 个 tick。换算公式:ticks = 价格距离 / syminfo.mintick。价格单位则直接用 stop= 和 limit= 传具体价格。

3、三种典型用法

//@version=5
strategy("exit 三种用法", overlay=true)

// 用法一:价格单位,开多时直接挂 2% 止损 + 4% 止盈
if ta.crossover(ta.sma(close, 10), ta.sma(close, 30))
    strategy.entry("L", strategy.long)
    strategy.exit("SLTP", from_entry="L", stop=close * 0.98, limit=close * 1.04)

// 用法二:tick 单位,用 mintick 换算(推荐写法,换品种不用改)
// 止损 200 tick、止盈 400 tick:
// strategy.exit("SLTP2", from_entry="L", loss=200, profit=400)

// 用法三:ATR 移动止损,浮盈超过 2 倍 ATR 后启动,距离 2 倍 ATR
atrVal = ta.atr(14)
if strategy.position_size > 0
    strategy.exit("Trail", from_entry="L",
         trail_points=(atrVal * 2) / syminfo.mintick,
         trail_offset=(atrVal * 2) / syminfo.mintick)

4、使用规则(易踩的坑)

  • strategy.exit 每调用一次只出场一次,要多次分批出场就传不同的 id 多次调用
  • 若 profit、limit、loss、stop、trail_price、trail_points 全是 na,该命令直接失败(什么都不挂)
  • 止损+移动止损同时给时,同属 stop 类订单,只会挂先被触发的那一个
  • 入场单还没成交时,对应的 exit 单会排队等入场成交后再生效
  • 想市价信号出场用 strategy.close;strategy.exit 是预挂价格单,二者可同时用,先到先平
  • exit 单会一直挂着,直到成交、仓位被别的指令平掉、或被 strategy.cancel 撤销
白话注解:记住一句话——"条件出场找 close,价格出场找 exit"。有人写了 stop 参数却放在 strategy.close 里,止损永远不生效,回测看起来没亏过钱,一上实盘全露馅。
PART TWO

操作教程

一步一步 · 跟着做完一件事

三、开发环境与第一个脚本

  1. 打开 TradingView 任意图表
  2. 图表底部点 Pine Editor(Pine 编辑器)
  3. 左侧写代码,点 Save 保存
  4. 点 Add to chart(添加到图表)加载运行
  5. 报错会在编辑器下方红字提示,点错误可跳到出错行
白话注解:整个开发流程都在浏览器里完成。保存的脚本在"Pine 编辑器 → 管理脚本"里能找回。别在别人发布的图表脚本上直接抄来改——先看懂每一行再动手。

1、第一个脚本:Hello Pine

//@version=5
indicator("我的第一个指标", overlay=true)

plot(close, title="收盘价", color=color.blue)

保存并添加到图表,主图上会画出收盘价曲线。//@version=5 必须写在第一行,声明脚本用的语言版本。

四、脚本的三种类型

声明函数用途能模拟下单吗
indicator()画指标、标记信号、发告警不能
strategy()回测策略,模拟买卖,生成绩效报告能(模拟盘)
library()封装可复用的函数库,供其他脚本引用不能
白话注解:indicator = 只画图不交易;strategy = 模拟回测,告诉你历史上这么做赚不赚钱;library = 把常用函数打包,别的脚本 import 来用。一个脚本只能声明一次类型,不能既当指标又当策略。

五、版本声明与语法基础

1、缩进敏感

Pine 用缩进表示代码块(类似 Python),if 内的语句必须缩进 4 个空格或 1 个 Tab:

//@version=5
indicator("缩进演示")

if close > open
    plot(close, color=color.green)

2、声明与重新赋值

//@version=5
indicator("赋值演示")

myVar = 10 // 首次声明,用 =(类型自动推断)
myVar := myVar + 1 // 已声明变量重新赋值,必须用 :=

var int counter = 0 // var 声明:只初始化一次,之后每根K线保留上次值
counter := counter + 1
最常见的编译错误之一:= 和 := 混用。= 只在首次声明时用,之后每根K线上更新变量一律用 :=。

3、var 与普通变量的区别

  • 普通变量:每根新K线都重新初始化,值不跨K线保留
  • var 变量:只在第一根K线初始化一次,之后一直保留(做计数器、记录最高价、状态机必备)
  • varip 变量:在实时K线的每个 tick 之间也保留(仅实时有效,历史K线上行为同 var)

六、数据类型与变量

1、基本类型

类型说明示例
int整数length = 14
float浮点数price = close
bool布尔isUp = close > open
string字符串msg = "金叉"
color颜色myColor = color.red

2、series 修饰符

Pine 里变量还带"时间维度":series float 表示"每根K线上都有一个值的历史序列"。内置的 close、指标输出都是 series。规则:大部分函数参数要求 series 类型,但有些地方(如 request.security 的周期参数在 v5 中)要求"简单类型"(simple string),不能用动态计算的值——这是新手报错高发区。

3、na 处理

//@version=5
indicator("na 演示")

m = ta.sma(close, 20) // 前19根K线上没有足够数据,值为 na
isReady = not na(m) // 用 na() 判断,not na() 即"数据就绪"
safeValue = nz(m, close) // nz():如果是 na 就用第二个参数兜底
白话注解:na 就是"这个位置没数据"。均线前 19 根K线、会话外的K线,都可能是 na。判断不用 == na,要用 na(m) 函数。

七、input 输入参数家族

input.* 让脚本的参数变成图表上的"设置项",不用改代码就能调:

//@version=5
indicator("input 演示", overlay=true)

fastLen = input.int(10, title="快线周期", minval=1, maxval=200)
slowLen = input.int(30, title="慢线周期", minval=1, maxval=400)
useFilter = input.bool(true, title="启用RSI过滤")
src = input.source(close, title="数据源")
sess = input.session("0930-1600", title="交易时段")
tf = input.timeframe("D", title="高周期")
symbol = input.symbol("BINANCE:BTCUSDT", title="对比品种")

group示例 = input.int(14, title="RSI长度", group="过滤参数", tooltip="RSI 的计算周期")
函数控件类型
input.int / input.float数字框(可加 minval/maxval/step)
input.bool开关
input.string文本框(可加 options 下拉列表)
input.source数据源选择(收盘价/最高价/其他指标)
input.session时段选择器(配合 time() 使用,见第十七章)
input.timeframe周期选择器(配合 request.security 使用)
input.symbol品种选择器
input.color取色器
白话注解:group 参数把设置项分组显示,tooltip 是鼠标悬停提示。参数一多,加分组让设置面板不乱。

八、内置变量与K线数据

1、当前K线数据

close // 当前K线收盘价
open // 开盘价
high // 最高价
low // 最低价
volume // 成交量
bar_index // 当前是第几根K线(从0开始)
time // 当前K线开盘时间的Unix时间戳
time_close // 当前K线收盘时间戳

2、历史引用运算符 []

close[1] // 上一根K线的收盘价
close[2] // 上上根
high[1] - low[1] // 上一根K线的振幅
close[1] 在第一根K线上没有上一根,返回 na。用到 [n] 的地方要考虑 na 情况。回看太远(如 close[5000])可能触发 max_bars_back 缓冲区报错,可在声明函数里显式设置 max_bars_back=5000 解决。

3、品种与周期信息

syminfo.tickerid // 完整品种ID(交易所:代码),request.security 常用
syminfo.ticker // 品种代码
syminfo.mintick // 最小变动价位(tick 大小),算止损距离常用
syminfo.timezone // 交易所时区
syminfo.type // 品种类型(stock/futures/forex/crypto 等)

timeframe.period // 当前图表周期字符串(如 "5"、"D")
timeframe.isintraday // 是否日内周期
timeframe.isdaily // 是否日线
白话注解:syminfo.mintick 特别有用——比如黄金 mintick 是 0.01,那"跌 50 个 tick"就是 0.50 美元。strategy.exit 的 profit/loss 参数用的就是 tick 数(见第十三章),不搞清 mintick 必算错。

九、strategy() 声明参数全表

以下参数经 TradingView 官方《Strategy properties》帮助文档与官方参考手册核实,均为真实存在的 v5 参数:

参数类型默认值作用
title / shorttitlestring—脚本名称 / 图表上显示的短名
overlayboolfalsetrue = 叠加在主图上
initial_capitalint/float1000000初始资金
currencystringcurrency.NONE结算币种,如 currency.USD
default_qty_typestringstrategy.fixed下单量单位:strategy.fixed(合约数)/ strategy.cash(金额)/ strategy.percent_of_equity(权益百分比)
default_qty_valueint/float1默认下单量
pyramidingint0同方向最多连续加仓次数。只对 strategy.entry() 生效,对 strategy.order() 无效
commission_typestringstrategy.commission.percent手续费类型:strategy.commission.percent(百分比)/ strategy.commission.cash_per_contract(每合约)/ strategy.commission.cash_per_order(每单)
commission_valueint/float0手续费数值。注意是双边收取(开仓平仓都收)
slippageint0滑点,单位是 tick,市价单和止损单成交价会向不利方向偏移
margin_long / margin_shortint/float0多/空保证金比例(%),模拟保证金不足强制平仓
calc_on_order_fillsboolfalse订单成交后立即再计算一次(可盘中动作)
calc_on_every_tickboolfalse实时K线每个 tick 都重算(历史K线无 tick 数据,会造成回测/实盘不一致,慎用)
process_orders_on_closeboolfalsetrue = 本根K线收盘就撮合订单(默认是下一根开盘撮合)
close_entries_rulestring"FIFO"平仓顺序:"FIFO" 先进先出 / "ANY" 任意(美股期货外汇受 NFA 规则限制只能 FIFO)
use_bar_magnifierboolfalse放大镜功能:回测时用更小周期数据撮合,更真实(付费套餐功能)
backtest_fill_limits_assumptionint0限价单成交严格度:为 0 时价格碰到限价就算成交;设为 n 则要求穿越 n 个 tick 才成交,回测更保守
max_bars_backint0历史引用缓冲区长度,[] 回看报错时手动调大
max_labels_count / max_lines_count / max_boxes_countint50图上最多保留的标签/线/框数量(上限 500)
白话注解:默认 initial_capital 是 100 万,手续费滑点全是 0——这种默认设置回测出来的成绩基本是"理想国"。写正式策略前,先把这几个数字改成接近你真实账户和券商的水平。

十、下单指令族:entry / order / close / close_all

1、四个指令一览

// 开仓(受 pyramiding 限制,自动处理反手)
strategy.entry("MyLong", strategy.long, qty=100)
strategy.entry("MyShort", strategy.short, qty=100)

// 底层挂单(不受 pyramiding 限制,不自动反手)
strategy.order("Add", strategy.long, qty=10, limit=close * 0.99)

// 平指定 id 的仓位(市价平仓)
strategy.close("MyLong", comment="信号平多")

// 平掉所有仓位(市价)
strategy.close_all(comment="清仓")

// 撤销未成交的挂单
strategy.cancel("MyLimitOrder")
strategy.cancel_all()

2、strategy.entry 完整签名(v5,官方参考手册核实)

strategy.entry(id, direction, qty, limit, stop, oca_name, oca_type,
     comment, alert_message)
参数说明
id订单标识(字符串)。同一 id 的未成交订单会被修改而不是重复下
directionstrategy.long 或 strategy.short
qty数量(合约/股/手)。不填用 default_qty 设置
limit限价。填了就是限价单
stop触发价。只填 stop 是止损单;stop+limit 都填是止损限价单
oca_name / oca_typeOCA 组:strategy.oca.none / strategy.oca.cancel(一组里成交一单撤其余)/ strategy.oca.reduce(成交一单其余减量)
comment备注,显示在交易明细和图上
alert_message自定义消息,通过 {{strategy.order.alert_message}} 占位符进 Webhook(见第十八章)
v5 的下单函数已不再使用 v4 的 when 参数。条件下单一律用 if 条件 把下单语句包起来,别照抄老代码。

3、entry 的自动反手机制

持多仓时调用 strategy.entry("S", strategy.short),模拟器会自动先平多再开空,一笔订单完成反手。这是 strategy.entry 和 strategy.order 的核心区别:

对比项strategy.entrystrategy.order
受 pyramiding 限制是否
自动反手是否(只会往同方向堆仓位)
典型用途常规策略进出场精细控制加仓/对冲/网格
白话注解:反手是双刃剑。你以为只是"平仓",结果 id 写错方向变成了反手开空,仓位直接翻倍。写策略时先用 strategy.position_size(当前仓位,多头为正、空头为负)判断清楚现在的状态再下单。

十一、挂单管理与订单执行模型

1、默认执行时序(最关键的一张图)

K线A收盘 → 策略计算 → 产生信号/挂单
K线B开盘 → 模拟器撮合上一根K线产生的市价单(以B开盘价成交)
K线B运行中 → 限价单/止损单按B内价格触发
K线B收盘 → 再计算 → 下一轮
白话注解:默认模式下,你"本根K线收盘看到金叉",实际成交在"下一根开盘价"。这个一根K线的延迟是回测和实盘对不上的第一大原因。想让收盘价立刻成交,加 process_orders_on_close=true——但实盘里你也得真的能在收盘那一瞬间下单,否则是自欺欺人。

2、撤单

strategy.cancel("MyLong") // 撤销指定 id 的未成交挂单
strategy.cancel_all() // 撤销全部未成交挂单(不动持仓)

注意:strategy.cancel 撤的是"挂单",strategy.close/close_all 平的是"持仓",两回事。收盘清场标准写法是两个都调。

3、收盘前强制清仓

//@version=5
strategy("日内清仓", overlay=true)

// 15:50 后平掉所有仓位并撤单(交易所时区)
isLate = hour == 15 and minute >= 50
if isLate and strategy.position_size != 0
    strategy.close_all(comment="收盘前清仓")
    strategy.cancel_all()

十二、多周期与跨品种数据:request.security

1、基本用法

//@version=5
indicator("多周期均线", overlay=true)

// 当前品种的日线 20 均线(画在小时图上)
dailyMA = request.security(syminfo.tickerid, "D", ta.sma(close, 20), lookahead=barmerge.lookahead_off)
plot(dailyMA, color=color.purple, title="日线MA20")

// 跨品种:拿 BTC 的收盘价对比
btcClose = request.security("BINANCE:BTCUSDT", timeframe.period, close, lookahead=barmerge.lookahead_off)

签名:request.security(symbol, timeframe, expression, gaps, lookahead)。gaps 控制请求周期的K线没对齐时返回 na(barmerge.gaps_on)还是沿用上一值(barmerge.gaps_off,默认)。

2、未来函数(lookahead)——回测虚高的头号来源

lookahead=barmerge.lookahead_on 会让回测"提前知道"高周期的收盘数据——相当于作弊看答案。v5 默认 barmerge.lookahead_off,但建议显式写出来,防止复制老代码时把 lookahead_on 带进来。判断脚本有没有未来函数最简单的办法:把 lookahead_on 全部改成 lookahead_off 再跑一次,如果绩效大幅变差,原脚本就有未来数据泄漏。

3、方向限制与调用上限

  • request.security 只能取等于或高于当前图表周期的数据;要取更低周期数据用 request.security_lower_tf()(v5 新增)
  • 每个脚本最多 40 个不重复的 request 调用(Ultimate 套餐 64 个);相同参数的重复调用不重复计数
  • 多个值一次请求:元组写法 [ma, rsi] = request.security(syminfo.tickerid, "D", [ta.sma(close, 20), ta.rsi(close, 14)])

4、高周期未收盘数据的重绘问题

小时图上取日线数据时,"当天的日线"还没走完,它的 close 全天都在变——这叫重绘(repaint)。两个稳妥做法:

// 做法1:取上一根已收盘的高周期K线,杜绝重绘
dailyCloseConfirmed = request.security(syminfo.tickerid, "D", close[1], lookahead=barmerge.lookahead_off)

// 做法2:只在实时K线上取当前值,历史K线取上一根(官方文档标准方案)
f_secure(_tf, _expr) => request.security(syminfo.tickerid, _tf, _expr[barstate.isrealtime ? 1 : 0])

十三、时间与会话过滤

1、time() 函数与会话字符串

签名(官方文档核实):time(timeframe, session) 和 time(timeframe, session, timezone)。当前K线在会话内返回K线时间戳,不在则返回 na——所以判断写法是 not na(...):

//@version=5
strategy("时段过滤", overlay=true)

// 会话字符串格式 "HHMM-HHMM:日期",日期数字 1=周日 ... 7=周六
// 0930-1600 且只要工作日(2~6):
sessInput = input.session("0930-1600:23456", title="交易时段")

inSession = not na(time(timeframe.period, sessInput, "America/New_York"))

longCond = ta.crossover(ta.sma(close, 10), ta.sma(close, 30))
if longCond and inSession
    strategy.entry("L", strategy.long)

// 背景染色直观查看时段
bgcolor(inSession ? color.new(color.blue, 92) : na)

2、时区与跨零点会话(高频踩坑点)

会话字符串默认按交易所时区解释,不是你电脑的时区!美盘品种在东八区看会差十几个小时。第三个参数传 IANA 时区名(如 "Asia/Shanghai"、"America/New_York")或 GMT 偏移(如 "GMT+8")显式指定。另外:星期数字 1 是周日、2 才是周一,与直觉相反;结束时间早于开始时间表示跨零点时段(如 2200-0600);日线及以上周期用会话过滤没有意义(一根K线已经覆盖全天)。

3、其他时间函数

year(time) / month(time) / dayofmonth(time) / dayofweek(time) / hour(time) / minute(time)
timestamp("2026-01-01T00:00:00") // 构造指定时刻的时间戳
timenow // 当前真实时间(每tick变)
barstate.isconfirmed // 实时K线是否已收盘
barstate.isrealtime // 当前是否实时K线(历史为false)
barstate.islast // 是否最后一根K线
白话注解:实盘告警防重绘的保险丝是 barstate.isconfirmed——只在K线收盘确认后动作。代价是反应慢一拍,但换来"信号不会反悔"。

十四、告警体系:alertcondition 与 alert

1、alertcondition(指标常用)

alertcondition(crossUp, title="金叉报警", message="出现金叉信号")
  • 只能在 indicator 里用(strategy 里写了也用不了)
  • 消息是编译时写死的字符串,不能动态拼变量
  • 用户要手动在图表上创建 Alert,Condition 选这个指标,再选对应 alertcondition

2、alert(动态消息,指标和策略都能用)

if crossUp
    alert("BUY " + syminfo.ticker + " @ " + str.tostring(close), alert.freq_once_per_bar_close)

频率常量(官方参考手册核实):

常量触发时机
alert.freq_all条件满足的每次计算都触发(实时K线内每个tick都可能触发)
alert.freq_once_per_bar每根K线最多触发一次(首次满足时)
alert.freq_once_per_bar_close只在K线收盘确认时触发一次(实盘推荐,信号不反悔)

3、策略的订单成交告警

strategy 里创建 Alert 时,条件选"Order fills only(仅订单成交)":每笔模拟订单成交时发通知,消息里可用 alert_message 参数 + {{strategy.order.alert_message}} 占位符传动态内容:

strategy.entry("L", strategy.long,
     alert_message='{"action":"buy","symbol":"' + syminfo.ticker + '","price":' + str.tostring(close) + '}')
白话注解:alertcondition 是"固定话术的路牌",alert 是"现场播报",订单成交告警是"每笔交易自动回执"。做 Webhook 自动交易主要靠后两种。

十五、Webhook 实盘架构

1、信号流向

TradingView云端策略触发 → Webhook URL(HTTP POST) → 你的中间服务器/第三方跟单服务 → 券商API → 实盘下单
白话注解:TradingView 不直接帮你下单,它只发一个"我要买"的 HTTP POST 通知。你需要一个中间服务器收到通知后调券商 API 真正下单。中间件可以自己用 Python/Node 写,也可以用现成的第三方跟单桥服务。

2、官方硬性规则(创建 Webhook Alert 前必知)

  • 套餐要求:免费版没有 Webhook 选项,至少需要付费套餐(Essential 及以上)
  • 两步验证:账户必须开启 2FA,否则无法填 Webhook URL
  • 端口:目标 URL 只接受 80 和 443 端口
  • 超时:接收方 3 秒内没响应,TradingView 就放弃投递(中间件要做异步处理,收到先回 200 再慢慢干活)
  • 熔断:同一个策略告警 3 分钟内触发超过 15 次会被自动停止
  • 服务端副本:策略告警跑的是 TradingView 服务器上的脚本副本,改了代码后必须删除并重建 Alert 才生效

3、消息占位符全表(Alert 的 Message 框里用)

占位符返回值
{{ticker}} / {{exchange}}品种代码 / 交易所
{{close}} {{open}} {{high}} {{low}} {{volume}}触发K线的 OHLCV
{{time}} / {{timenow}}K线时间 / 实际触发时间(UTC)
{{interval}}图表周期
{{plot_0}} ~ {{plot_19}} / {{plot("名称")}}指标输出(只对指标告警有意义)
{{strategy.order.action}}buy / sell(仅策略告警有效)
{{strategy.order.contracts}} / {{strategy.order.price}}订单数量 / 订单价格
{{strategy.position_size}}下单后的仓位
{{strategy.order.alert_message}}下单函数里写的 alert_message
{{strategy.*}} 占位符只在策略的告警里生效;用在指标告警里会原样发出字符串,JSON 直接报废。

4、标准中间件 Payload 示例

{
  "secret": "REPLACE_WITH_LONG_RANDOM_TOKEN",
  "symbol": "{{ticker}}",
  "action": "{{strategy.order.action}}",
  "qty": "{{strategy.order.contracts}}",
  "price": {{close}},
  "position_after": {{strategy.position_size}},
  "fired_at": "{{timenow}}"
}

中间件安全三件事:① 校验 secret 字段(共享密钥),拒绝不明来源的 POST;② 绝不要把券商 API 密钥写在告警消息里(TradingView 官方文档明确警告);③ 对同一品种加节流/幂等处理,防重复信号重复下单。

十六、绘图进阶与信息面板

1、label / line / box(动态绘图对象)

//@version=5
indicator("绘图对象", overlay=true, max_labels_count=500)

if barstate.islastconfirmedhistory
    // 标签
    label.new(bar_index, high, "最新价 " + str.tostring(close),
         style=label.style_label_down, color=color.blue, textcolor=color.white)
    // 直线
    line.new(bar_index - 20, ta.highest(high, 20), bar_index, high, color=color.red)
    // 方框
    box.new(bar_index - 10, high, bar_index, low, bgcolor=color.new(color.green, 85))

2、table 信息面板

//@version=5
indicator("状态面板", overlay=true)

var table t = table.new(position.top_right, 2, 3, bgcolor=color.white, border_width=1)
if barstate.islastconfirmedhistory
    table.cell(t, 0, 0, "指标")
    table.cell(t, 1, 0, "数值")
    table.cell(t, 0, 1, "RSI")
    table.cell(t, 1, 1, str.tostring(ta.rsi(close, 14), "#.0"))
    table.cell(t, 0, 2, "收盘")
    table.cell(t, 1, 2, str.tostring(close, "#.00"))
白话注解:table 做实时状态面板(仓位、信号、风控状态一目了然),配合 var table + barstate.islastconfirmedhistory 只在最后一根K线刷新,不拖慢历史计算。注意声明里加 max_labels_count 等,否则默认只显示最近 50 个对象。

十七、参数优化与过拟合陷阱

1、给参数划边界

fastLen = input.int(10, title="快线", minval=2, maxval=60, step=2)

限定范围后,用图表上方的"策略测试器 → 参数"做步进优化。TradingView 付费套餐还有 Deep Backtesting(深度回测)可拉长历史。

2、回测可信度自检清单

  • 手续费设了吗?默认是 0,双边收费品种必须设置
  • 滑点设了吗?slippage 至少给 1-2 个 tick
  • 用了 calc_on_every_tick 吗?历史K线没有 tick 数据,回测结果和实盘必然不一致
  • request.security 有没有 lookahead_on?有没有引用未收盘的高周期数据?
  • 信号用的是 close 还是实时价?收盘确认了吗?
  • 交易笔数够不够?30 笔以下的回测没有统计意义
  • 换了品种、换了周期,结论还成立吗?(参数敏感性检验)
风险口径:参数调到回测最漂亮的那个组合,大概率是对历史噪音的拟合,不是未来会重演的规律。回测业绩不代表未来收益,上线前先在小仓位或模拟盘上跑一段(前向验证)。

十八、Pine Script v6 新版要点

v6 于 2024 年 12 月发布(官方博客核实),v5 脚本继续可用,新旧不互通:新功能只在 v6 开放。主要变化:

变化v5 行为v6 行为
bool 类型可取 true / false / na 三态严格二值,不能再是 na;na() 不再接受 bool
数字转 bool0=false、非0=true 隐式转换必须显式 bool() 转换,否则编译报错
and / or 求值两边都算(eager)短路求值(lazy),左侧已定则不算右侧
when 参数下单函数已废弃正式移除
request.\*() 调用必须全局作用域 + 静态字符串动态请求:品种/周期可用 series string,可在循环、条件内调用
整数除法1/2 结果为 01/2 结果为 0.5
负数组索引不支持array.get(arr, -2) 直接取倒数第二个
9000 笔交易上限超出报错停止计算自动裁剪最旧交易继续算,新增 strategy.closedtrades.first_index 定位最早未裁剪交易
枚举 / 日志无新增 enum、log.info()/log.warning()/log.error()
白话注解:本教程用 v5 写,因为 v5 资料最多、存量脚本最大。新写脚本可以上 v6(编辑器"管理脚本 → 转换代码为 v6"有官方迁移工具,但不是所有脚本都能全自动转,转换后要人工核对)。v5→v6 最容易翻车的点:三态 bool 和整数除法,老代码里靠 na 判断状态的逻辑要重写。
付费专享 · 核心知识点 8 章

继续阅读:核心知识点,搞懂原理

EA05 PineScript/TradingView 策略 — 共 26 章,已免费阅读 18 章,剩余 8 章核心知识点讲透「为什么这样、点了会怎样」。

十九、ta. 技术指标命名空间
二十、第一个完整指标:双均线
二十一、第一个完整策略:双均线回测
二十二、回测报告与账户状态变量
二十三、常见错误与 FAQ
二十四、一页纸速查表
…等共 8 章核心内容
✍️ 注册后扫码购买 🔐 已有账号,去登录 单套 ¥69 永久 · 会员可阅
SERVICE & PRICING
服务收费说明 · 明码标价,无隐藏收费
全部课程统一 ¥39-69,买一套永久使用。以下为购买与使用的完整流程。
01先免费试读

每套教程的「使用手册」部分均可免费阅读,先确认内容是否适合自己再决定,不必盲买。

02扫码付款

选定课程后点「立即解锁」,页面展示收款二维码与客服微信,扫码转账即可,无需注册海外支付。

03获取卡密

付款完成后客服第一时间发送卡密号与卡密密码,站内消息与微信同步通知。

04兑换解锁

在用户中心「兑换卡密」输入卡密号与密码,系统即时解锁全部章节,无需二次付款。

一次付费,终身可用 · 解锁后课程永久留在账号里,不限次数、不限时间阅读 持续免费更新 · 平台改版、规则变化时课程同步修订
RECOMMEND
相关教程推荐 · 同栏目更多上手机会

💬 用户评价 (0)

🔒 登录并成为会员后可发表评价
还没有评价 · 成为第一个评价的人吧 🎯