You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

TradingView Pine Script固定运行分辨率与多标的策略实现技术咨询

Pine Script 策略配置与多标的运行解决方案

针对你提出的两个Pine Script策略问题,我整理了具体的解决方案和修改后的代码,希望能帮到你:


一、固定策略运行分辨率,不受图表时间范围影响

你之前尝试用security函数但没达到预期效果,核心问题是没有把所有策略依赖的数据(收盘价、均线、标准差)都切换到指定分辨率上,同时还要注意避免未来函数的干扰,保证回测的准确性。

正确实现方案

  1. 使用request.security()函数(Pine Script v4推荐用这个替代旧的security)获取指定分辨率的数据源,设置lookahead=barmerge.lookahead_off禁用未来数据,确保信号完全基于历史数据生成。
  2. 将所有用于计算指标和交易信号的变量,都基于这个固定分辨率的数据,而不是当前图表的分辨率。这样不管你查看1年、5年还是YTD的时间范围,策略都会严格按照你指定的分辨率(比如日线1D)运行。

关键代码修改

// 定义运行分辨率,用户可自定义输入
res = input(title='运行分辨率', type=input.resolution, defval='1D')

// 获取指定分辨率的收盘价、SMA、标准差,禁用未来数据
[closeRes, smaRes, stdRes] = request.security(syminfo.tickerid, res, [close, sma(close, smaLength), stdev(close, stdLength)], lookahead=barmerge.lookahead_off)

// 基于固定分辨率数据计算布林带
upperBand = smaRes + stdRes * ubOffset
lowerBand = smaRes - stdRes * lbOffset

二、实现多标的策略运行

TradingView和QuantConnect的多标的逻辑差异较大,这里给你两种实用的解决方案,适配不同的使用场景:

方案1:在同一策略中引入多标的数据,生成跨标的信号

通过request.security()引入其他标的的行情数据,在同一个策略中为每个标的编写独立的交易逻辑,同时设置资金分配规则,避免单标的占用过多资金。比如你可以给每个标的分配总资金的30%,这样最多同时持有3个标的,有效降低空仓时长。

方案2:使用TradingView内置的多标的策略测试功能

如果你不想修改代码,可以直接在策略测试器中添加多个标的:

  • 打开策略测试器,切换到「设置」标签页
  • 在「符号」选项中点击「添加符号」,选择你要测试的所有标的
  • 在「资金」设置中,选择「每个符号使用单独的资金」或「共享资金池」(推荐共享资金池来模拟真实账户的资金分配)
  • 运行策略即可查看多标的的整体回测结果

完整修改后的策略代码

这份代码整合了固定分辨率和多标的功能,你可以根据需要添加更多标的:

//@version=4 
strategy(title="Multi-Asset Bollinger", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=30, initial_capital=100000) 
// 策略规则:
// 1. 当价格上穿下轨时开多单
// 2. 当价格触碰上轨时平仓
// 
// 图表属性
testStartYear = input(2018, "回测起始年份")
testStartMonth = input(1, "回测起始月份")
testStartDay = input(1, "回测起始日期")
testPeriodStart = timestamp(testStartYear, testStartMonth, testStartDay, 0, 0)
testStopYear = input(2021, "回测结束年份")
testStopMonth = input(1, "回测结束月份")
testStopDay = input(1, "回测结束日期")
testPeriodStop = timestamp(testStopYear, testStopMonth, testStopDay, 0, 0)
// 控制回测时段背景色的开关
testPeriodBackground = input(title="是否显示背景色?", type=input.bool, defval=true)
testPeriodBackgroundColor = testPeriodBackground and time >= testPeriodStart and time <= testPeriodStop ? #6c6f6c : na
bgcolor(testPeriodBackgroundColor, transp=97)
// 用户输入参数
smaLength = input(title="SMA周期", type=input.integer, defval=20) // 中轨周期(移动平均线)
stdLength = input(title="标准差周期", type=input.integer, defval=20) // 计算布林带的周期
ubOffset = input(title="上轨偏移量", type=input.float, defval=2.0, step=0.5) // 均线之上的标准差倍数
lbOffset = input(title="下轨偏移量", type=input.float, defval=2.0, step=0.5) // 均线之下的标准差倍数
res = input(title='运行分辨率', type=input.resolution, defval='1D') // 分辨率
// 可选:添加更多标的,这里以第二个标的为例
ticker2 = input(title='第二个标的', type=input.symbol, defval='SPY')

testPeriod() => time >= testPeriodStart and time <= testPeriodStop ? true : false

// --------------------------
// 固定分辨率数据获取(当前标的)
// --------------------------
[closeRes, smaRes, stdRes] = request.security(syminfo.tickerid, res, [close, sma(close, smaLength), stdev(close, stdLength)], lookahead=barmerge.lookahead_off)
upperBand = smaRes + stdRes * ubOffset // 上轨
lowerBand = smaRes - stdRes * lbOffset // 下轨
// 绘制当前标的布林带
plot(series=smaRes, title="SMA", color=color.blue)
plot(series=upperBand, title="UB", color=color.green, linewidth=2)
plot(series=lowerBand, title="LB", color=color.red, linewidth=2)
// 当前标的交易信号
longCondition = crossover(closeRes, lowerBand)
closeLongCondition = closeRes >= upperBand
if (longCondition and testPeriod())
    strategy.entry(id="CALL", long=true)
strategy.close(id="CALL", when=closeLongCondition)

// --------------------------
// 第二个标的数据与交易逻辑
// --------------------------
[close2, sma2, std2] = request.security(ticker2, res, [close, sma(close, smaLength), stdev(close, stdLength)], lookahead=barmerge.lookahead_off)
upperBand2 = sma2 + std2 * ubOffset
lowerBand2 = sma2 - std2 * lbOffset
longCondition2 = crossover(close2, lowerBand2)
closeLongCondition2 = close2 >= upperBand2
// 第二个标的交易
if (longCondition2 and testPeriod())
    strategy.entry(id="CALL_2", long=true, ticker=ticker2)
strategy.close(id="CALL_2", when=closeLongCondition2, ticker=ticker2)

// 设置资金分配,每个标的最多占用30%总资金
strategy.risk.allow_entry_in(strategy.long, qty_percent=30)

内容的提问来源于stack exchange,提问作者Deemo

火山引擎 最新活动