You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pine Script会话蜡烛指标跨周期不一致及会话重置异常求助

解决Pine Script会话蜡烛跨周期不一致及会话切换异常问题

需求与当前问题

我正在开发一款Pine Script指标,需求是根据用户自定义的起止时间绘制单根会话蜡烛,要求:

  • 所有时间周期(如1m、5m、15m)下显示的会话蜡烛形态完全一致
  • 新会话启动时立即终止前一会话,前会话蜡烛不再更新

但目前遇到两个核心问题:

  1. 不同周期下会话蜡烛形态差异明显(比如1分钟图和15分钟图的同一会话蜡烛OHLC不一致)
  2. 新会话启动后,前一会话蜡烛仍会持续更新,导致蜡烛重叠、数据错误

原代码如下:

//@version=5
indicator("Session Candles", overlay=true)

sessionStart = input.time(defval=timestamp("2025-01-01T09:00:00"), title="Session Start")
sessionEnd   = input.time(defval=timestamp("2025-01-01T18:00:00"), title="Session End")

var float sessionOpen  = na
var float sessionHigh  = na
var float sessionLow   = na
var float sessionClose = na

inSession = time >= sessionStart and time < sessionEnd

if inSession and na(sessionOpen)
    sessionOpen := open
    sessionHigh := high
    sessionLow  := low
    sessionClose := close
else if inSession
    sessionHigh := math.max(sessionHigh, high)
    sessionLow  := math.min(sessionLow, low)
    sessionClose := close
else if not inSession
    sessionOpen  := na
    sessionHigh  := na
    sessionLow   := na
    sessionClose := na

plotcandle(sessionOpen, sessionHigh, sessionLow, sessionClose, color=color.blue)

问题根源分析

  1. 跨周期数据不一致:原代码直接使用当前图表周期的open/high/low/close计算会话OHLC,不同周期的K线数据粒度不同(比如15m K线的开盘价是15分钟内的第一个1m开盘价,而1m K线是逐分钟数据),导致同一时间段的会话蜡烛计算结果差异巨大。
  2. 会话边界处理错误:原代码仅通过当前周期的time判断是否在会话内,当新会话启动时,直接重置会话变量,导致前一会话的蜡烛数据被清除或持续更新(因为当前周期K线可能覆盖会话切换点),无法冻结历史会话的蜡烛。

解决方案代码

//@version=5
indicator("Session Candles (Fixed)", overlay=true)

// 用户自定义会话起止时间(仅提取时分秒部分,用于每日重复)
sessionStartInput = input.time(defval=timestamp("2025-01-01T09:00:00"), title="Session Start Time")
sessionEndInput = input.time(defval=timestamp("2025-01-01T18:00:00"), title="Session End Time")

// 提取时分秒,转换为当日时间戳偏移量
startTime = time("D") + (sessionStartInput - timestamp("2025-01-01T00:00:00"))
endTime = time("D") + (sessionEndInput - timestamp("2025-01-01T00:00:00"))

// 定义存储历史会话OHLC的数组
var float[] sessionOpens = array.new_float()
var float[] sessionHighs = array.new_float()
var float[] sessionLows = array.new_float()
var float[] sessionCloses = array.new_float()
var int[] sessionEndTimes = array.new_int()

// 获取1分钟周期的数据源(确保所有周期基于同一粒度计算)
[secOpen, secHigh, secLow, secClose, secTime] = request.security(syminfo.tickerid, "1", [open, high, low, close, time])

// 当前1分钟K线是否在会话内
inSession = secTime >= startTime and secTime < endTime
// 检测新会话启动(当前K线在会话内,上一根K线不在)
newSession = inSession and not na(secTime[1]) and secTime[1] < startTime
// 检测会话结束(当前K线不在会话内,上一根K线在)
sessionClosed = not inSession and not na(secTime[1]) and secTime[1] >= startTime and secTime[1] < endTime

// 会话变量:存储当前会话的OHLC
var float currentOpen = na
var float currentHigh = na
var float currentLow = na
var float currentClose = na

// 更新当前会话数据
if inSession
    if newSession
        // 新会话启动,初始化当前会话数据
        currentOpen := secOpen
        currentHigh := secHigh
        currentLow := secLow
        currentClose := secClose
    else
        // 会话进行中,更新高低点和收盘价
        currentHigh := math.max(currentHigh, secHigh)
        currentLow := math.min(currentLow, secLow)
        currentClose := secClose
elif sessionClosed
    // 会话结束,将当前会话数据存入历史数组
    array.push(sessionOpens, currentOpen)
    array.push(sessionHighs, currentHigh)
    array.push(sessionLows, currentLow)
    array.push(sessionCloses, currentClose)
    array.push(sessionEndTimes, secTime[1])
    // 重置当前会话变量
    currentOpen := na
    currentHigh := na
    currentLow := na
    currentClose := na

// 绘制历史会话蜡烛
for i = 0 to array.size(sessionOpens) - 1
    plotcandle(array.get(sessionOpens, i), array.get(sessionHighs, i), array.get(sessionLows, i), array.get(sessionCloses, i), 
               color=color.new(color.blue, 0), title="Historical Session Candle", display=display.data_window)

// 绘制当前会话蜡烛
plotcandle(currentOpen, currentHigh, currentLow, currentClose, color=color.new(color.blue, 0), title="Current Session Candle")

关键改动说明

  1. 统一数据源:使用request.security获取1分钟周期的行情数据,所有图表周期都基于最细粒度的1分钟数据计算会话OHLC,确保跨周期一致性。
  2. 会话边界精准检测:基于1分钟K线的time检测会话的启动和结束,避免当前周期K线覆盖会话切换点导致的判断错误。
  3. 历史会话存储:用数组保存已结束会话的OHLC数据,新会话启动时不会覆盖旧数据,确保历史蜡烛持续显示且不再更新。
  4. 每日重复会话:提取用户输入时间的时分秒部分,结合当日日期生成每日的会话起止时间,实现会话每日重复运行。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 07:54:52