如何在日内时间框架获取前n个交易日的高低点与日期?
Pine Script日内图获取前N个交易日高低点的实现方案
你遇到的核心问题是Pine Script不允许将循环变量或可变变量作为request.security的索引参数,因为该函数需要编译时确定的常量值。下面提供两种可行的实现思路,帮你在日内图上标记前N个交易日的高低点和日期。
方法一:在日线级别封装数据后传递到日内图
这种方法将高低点的计算逻辑放到日线上下文里执行,避免在日内图中用循环变量调用request.security,代码结构更清晰高效:
//@version=5 indicator("前N交易日高低点标记", overlay=true) // 用户输入参数 lookbackDays = input.int(3, "回溯交易日数量", minval=1) dailyTF = input.timeframe("D", "日线时间框架") // 定义存储单交易日高低点和日期的结构体 type DailyLevel float high float low int time // 在日线级别计算最近N个交易日的高低点数据 getDailyLevels() => var DailyLevel[] levelsArray = array.new<DailyLevel>() if barstate.islast // 从上个交易日开始,循环获取lookbackDays天的数据 for i = 1 to lookbackDays by 1 dailyHigh = high[i] dailyLow = low[i] dailyTime = time[i] array.push(levelsArray, DailyLevel.new(dailyHigh, dailyLow, dailyTime)) levelsArray // 通过request.security获取日线级别计算好的高低点数组 dailyLevels = request.security(syminfo.tickerid, dailyTF, getDailyLevels()) // 在日内图最后一根K线绘制标记 if barstate.islast for level in dailyLevels // 绘制高低点水平线 hline(level.high, str.tostring(time.new(level.time, "DD/MM/YYYY")) + " 高点", color=color.red, linestyle=hline.style_dashed) hline(level.low, str.tostring(time.new(level.time, "DD/MM/YYYY")) + " 低点", color=color.green, linestyle=hline.style_dashed) // 绘制带日期和价格的标签 label.new(bar_index, level.high, str.tostring(time.new(level.time, "DD/MM/YYYY")) + "\n" + str.tostring(level.high), color=color.red, textcolor=color.white, style=label.style_label_down) label.new(bar_index, level.low, str.tostring(time.new(level.time, "DD/MM/YYYY")) + "\n" + str.tostring(level.low), color=color.green, textcolor=color.white, style=label.style_label_up)
关键逻辑说明
- 把数据计算逻辑封装在
getDailyLevels()函数中,通过request.security让这个函数在日线级别执行,此时循环索引i是合法的。 - 日线级别计算完成后,将存储高低点的数组传递回日内图,最后遍历数组完成标记。
方法二:直接在日内图用序列函数提取数据
这种方法通过获取日线序列数据,结合ta.valuewhen函数提取指定回溯天数的值,逻辑更直观:
//@version=5 indicator("前N交易日高低点标记", overlay=true) // 用户输入参数 lookbackDays = input.int(3, "回溯交易日数量", minval=1) dailyTF = input.timeframe("D", "日线时间框架") // 获取日线级别的高低点和时间序列 dailyHigh = request.security(syminfo.tickerid, dailyTF, high) dailyLow = request.security(syminfo.tickerid, dailyTF, low) dailyTime = request.security(syminfo.tickerid, dailyTF, time) // 判断是否是新的日线K线(作为提取数据的触发条件) isNewDailyBar = ta.change(time("D")) != 0 // 在最后一根日内K线绘制标记 if barstate.islast for i = 1 to lookbackDays by 1 // 提取第i个上一交易日的高低点和日期 targetHigh = ta.valuewhen(isNewDailyBar, dailyHigh, i) targetLow = ta.valuewhen(isNewDailyBar, dailyLow, i) targetTime = ta.valuewhen(isNewDailyBar, dailyTime, i) // 绘制水平线和标签 hline(targetHigh, str.tostring(time.new(targetTime, "DD/MM/YYYY")) + " 高点", color=color.red, linestyle=hline.style_dashed) hline(targetLow, str.tostring(time.new(targetTime, "DD/MM/YYYY")) + " 低点", color=color.green, linestyle=hline.style_dashed) label.new(bar_index, targetHigh, str.tostring(time.new(targetTime, "DD/MM/YYYY")) + "\n" + str.tostring(targetHigh), color=color.red, textcolor=color.white, style=label.style_label_down) label.new(bar_index, targetLow, str.tostring(time.new(targetTime, "DD/MM/YYYY")) + "\n" + str.tostring(targetLow), color=color.green, textcolor=color.white, style=label.style_label_up)
关键逻辑说明
- 先通过
request.security将日线的high、low、time序列同步到日内图。 - 用
ta.change(time("D"))识别新日线K线的出现,再通过ta.valuewhen函数提取第i个上一交易日的数据,这里的i是循环变量,但并未直接传入request.security,因此合法。
内容的提问来源于stack exchange,提问作者GazleyGeester
相关产品推荐
相关产品推荐

