Pine Script v6:无NA校验加载高时间周期数据至数组并索引访问问题
问题:Pine Script v6中预加载高时间周期K线数组后无法访问指定索引
我需要创建一个基于M15数据的指标,目标是将指定高时间周期的最近2000根K线加载到数组中,通过索引直接访问进行计算。以下是我的Pine Script v6实现:
//@version=6 indicator("HTF Array Example", overlay=false) TimeFrame = input.timeframe("15", "HTF Timeframe") CandlesToCalculate = input.int(2000, "Number of HTF Candles") type ChartData array<float> Open array<float> High array<float> Low array<float> Close array<int> Time var ChartData MyChartData = ChartData.new( array.new_float(), array.new_float(), array.new_float(), array.new_float(), array.new_int() ) method ChartData_Load(ChartData cd)=> // Request higher timeframe series htfOpen = request.security(syminfo.tickerid, TimeFrame, open) htfHigh = request.security(syminfo.tickerid, TimeFrame, high) htfLow = request.security(syminfo.tickerid, TimeFrame, low) htfClose = request.security(syminfo.tickerid, TimeFrame, close) htfTime = request.security(syminfo.tickerid, TimeFrame, time) // --- 1️⃣ Load initial batch once if barstate.isfirst for idx = CandlesToCalculate + 100 to 0 if not na(htfTime[idx]) array.push(cd.Open, htfOpen[idx]) array.push(cd.High, htfHigh[idx]) array.push(cd.Low, htfLow[idx]) array.push(cd.Close, htfClose[idx]) array.push(cd.Time, htfTime[idx]) // --- 2️⃣ Append new HTF bars newHTFBar = ta.change(htfTime) != 0 if newHTFBar and not na(htfTime) array.push(cd.Open, htfOpen) array.push(cd.High, htfHigh) array.push(cd.Low, htfLow) array.push(cd.Close, htfClose) array.push(cd.Time, htfTime) // --- 3️⃣ Trim arrays to maximum size if array.size(cd.Open) > CandlesToCalculate + 100 array.shift(cd.Open) array.shift(cd.High) array.shift(cd.Low) array.shift(cd.Close) array.shift(cd.Time) MyChartData.ChartData_Load() // Test array.size(MyChartData.Open) // returns 2000 array.get(MyChartData.Open, 1000) // ERROR: Index 1000 out of bounds
运行后,array.size(MyChartData.Open)返回2000,但访问数组中间值array.get(MyChartData.Open, 1000)时出现以下错误:
Error on bar 0: In 'array.get()' function. Index 1000 is out of bounds, array size is 1.
我希望无需每次用if not na校验,就能直接访问数组值进行计算。请问如何正确预加载高时间周期序列到数组,实现任意索引的自由访问?
解决方案
问题根源
barstate.isfirst执行限制:脚本初始化阶段(bar 0),request.security返回的历史序列数据并未完全加载,此时循环访问htfTime[idx]只能获取少量有效值,导致数组实际初始填充元素远不足预期数量。- 索引访问时机错误:即使后续数组被填充到指定大小,初始化阶段直接访问索引1000时,数组还未完成填充,触发越界错误。
修正实现方案
通过逐Bar累积历史数据的方式填充数组,确保数组在脚本运行过程中逐步完成初始化,同时维护固定大小,保证索引访问的有效性:
//@version=6 indicator("HTF Array Fixed", overlay=false) TimeFrame = input.timeframe("15", "HTF Timeframe") CandlesToCalculate = input.int(2000, "Number of HTF Candles") // 定义K线数据结构 type ChartData array<float> Open array<float> High array<float> Low array<float> Close array<int> Time // 预分配固定大小的数组,避免动态扩容的不确定性 var ChartData MyChartData = ChartData.new( array.new_float(CandlesToCalculate), array.new_float(CandlesToCalculate), array.new_float(CandlesToCalculate), array.new_float(CandlesToCalculate), array.new_int(CandlesToCalculate) ) method ChartData_Load(ChartData cd)=> // 请求高时间周期数据,关闭未来数据避免异常 htfOpen = request.security(syminfo.tickerid, TimeFrame, open, lookahead=barmerge.lookahead_off) htfHigh = request.security(syminfo.tickerid, TimeFrame, high, lookahead=barmerge.lookahead_off) htfLow = request.security(syminfo.tickerid, TimeFrame, low, lookahead=barmerge.lookahead_off) htfClose = request.security(syminfo.tickerid, TimeFrame, close, lookahead=barmerge.lookahead_off) htfTime = request.security(syminfo.tickerid, TimeFrame, time, lookahead=barmerge.lookahead_off) // 检测新的高时间周期Bar var int lastHtfTime = na newHTFBar = htfTime != lastHtfTime and not na(htfTime) if newHTFBar // 左移数组元素,腾出最后位置给新Bar array.shift(cd.Open) array.shift(cd.High) array.shift(cd.Low) array.shift(cd.Close) array.shift(cd.Time) // 添加新Bar数据到数组末尾 array.push(cd.Open, htfOpen) array.push(cd.High, htfHigh) array.push(cd.Low, htfLow) array.push(cd.Close, htfClose) array.push(cd.Time, htfTime) // 更新最后记录的HTF时间 lastHtfTime := htfTime // 调用加载方法 MyChartData.ChartData_Load() // 测试:数组填充完成后再访问索引 if array.size(MyChartData.Open) == CandlesToCalculate // 访问第1000个元素(索引0对应最早的HTF K线,索引1999对应最新的HTF K线) testValue = array.get(MyChartData.Open, 1000) label.new(bar_index, high, str.tostring(testValue), color=color.green)
关键改进点
- 预分配固定大小数组:初始化时直接创建指定大小的数组,避免动态扩容带来的不确定性。
- 逐Bar更新数组:通过检测新HTF Bar,用
array.shift左移元素并array.push添加新数据,确保数组始终保持目标大小。 - 关闭未来数据:在
request.security中添加lookahead=barmerge.lookahead_off,避免获取未闭合的Bar数据,保证计算准确性。 - 安全访问索引:添加数组大小校验,仅当数组完全填充后才访问指定索引,避免初始化阶段的越界错误。
索引说明
数组索引0对应最早的HTF K线,索引CandlesToCalculate-1对应最新的HTF K线。若需访问最近的第N根K线,可使用array.get(cd.Open, CandlesToCalculate - N)。
内容的提问来源于stack exchange,提问作者Hossein Tavakoli
相关产品推荐
相关产品推荐

