roll

语法

roll(X, step, [stepType='time'], [fill='none'], [closed='left'], [origin='start_day'], [exclude], [label])

详情

roll 是一个哑函数,用于在 SQL 查询中定义自定义滑动窗口。标准 CONTEXT BY 子句,或 GROUP BY 搭配分析函数时,窗口滑动步长固定为 1 行。GROUP BY 配合哑函数 interval 可以指定任意时间步长,但要求所有窗口长度相同。使用 roll 可以突破这些限制,自由定义窗口步长和长度。

roll 必须作为 SELECT 子句中第一个表达式,并且与 CONTEXT BY 搭配使用。

返回值:一个向量,其长度与窗口数量相同。通常,向量的每个元素表示对应窗口中 X 列的最后一个值。

但当 stepType = 'window' 时,每个元素表示对应窗口的标签(label),而非最后一个值。

窗口确定规则

在使用 roll 配合 SELECT 时,窗口的滑动步长和窗口长度由不同机制决定:

  • stepType='window' 时,窗口长度由自定义窗口(window 参数)确定。

  • stepType ≠ 'window':roll 只定义步长,不确定窗口长度。窗口长度则由 SELECT 子句中的函数类型确定:

    • 聚合函数(内置或自定义):窗口长度 = 步长。

    • 内置 m 系列滑动函数:

      • stepType = 'time' 时,若 window 是 DURATION 类型时,窗口长度 = window;若 window 是整数时,窗口长度是步长的 window 倍。

      • stepType = 'row' 时,window 必须是整数,窗口长度等于 window

      • stepType = 'volume' / 'cumvol' 时,window 必须是整数,窗口长度是步长的 window 倍。

    • 内置 tm 系列滑动函数(仅支持 stepType = 'time'):窗口长度 = 函数中 window 参数。

    • 表中列:窗口长度 = 步长,结果等价于对该列应用 last 函数。

参数

X 时间列或交易量的列。

  • stepType 为 'time',X 必须为 DATETIME/TIMESTAMP/NANOTIME/NANOTIMESTAMP 类型,并按升序排列。

  • stepType 为 'volume',X 必须为数值类型,表示交易量。

  • stepType 为 'cumvol',X 必须为数值类型,且按升序排列,表示累计交易量。

step 窗口滑动步长,可以为:

  • DURATION 类型标量,表示时间间隔,支持如下时间单位:M, w, d, H, m, s, ms, us, ns。

  • stepType = ‘window’ 时,step 是长度为 2 的元组,用于指定自定义窗口。第一个元素为起始时间,第二个元素为结束时间(需大于起始时间),两个元素的数据类型需与 X 相同,且升序排列。默认左闭右开,可通过 closed 参数调整。

stepType 可选参数,STRING 类型标量,指定步长类型,可选值:

  • 'time':按时间列滑动,默认值。

  • 'row':按行数滑动。

  • 'volume':按交易量滑动。

  • 'cumvol':按累计交易量滑动。

  • 'window':按自定义窗口滑动。

fill 可选参数,STRING 类型标量,指定窗口内无数据时的处理方式,可选值:

  • 'none':不输出,默认值。

  • 'null':输出空值。

  • 'prev':填充前一个非空值。

closed 可选参数,STRING 类型标量,指定自定义窗口的闭合方式。可选值:

  • 'left':左闭右开,默认值。

  • 'right':左开右闭。

origin 可选参数,STRING 类型标量,指定时间滑动的起点,仅在 stepType='time' 时生效。可选值:

  • 'start_day':起始点是时间序列的第一个值对应日期的午夜零点,默认值。

  • 'start':起始点为时间序列的第一个值。

  • 'epoch':起始点为 1970-01-01。

exclude 可选参数,元组,指定需要排除的时间段,仅在 stepType='time' 时生效。每个元素为 TIME、NANOTIME、MINUTE 和 SECOND 类型的数据对,例如 A 股午休时间 (11:30:00:13:00:00)。如果指定的时间段内存在数据,则必须通过 WHERE 子句过滤这段时间的数据。

label 可选参数,STRING 类型向量,自定义窗口名称,长度与自定义窗口数量一致。仅在 stepType='window' 时指定。

例子

例1. 按 symbol 分组,使用时间为步长 60 秒的滑动窗口,计算过去 180 秒,300 秒的平均价格。

timestamp = 2025.08.10T00:00:00 + 30 * 0..19
symbol = take(`A`B`C, 20)
price = [20.81,20.34,20.42,20.99,20.01,20.60,20.45,20.70,20.05,20.25,20.52,20.32,20.15,20.67,20.28,20.70,20.98,20.48,20.01,20.42]
vol = [1002,1091,1035,1041,1016,1038,1007,1007,1062,1030,1064,1012,1007,1007,1035,1038,1015,1041,1029,1048]
t = table(timestamp as timestamp, symbol as symbol, vol as vol, price as price)

select * from t order by symbol
// 使用 roll + mavg 计算 180 秒和 300 秒滑动平均
select
    roll(X=timestamp, step=60s, stepType='time') as period,
    mavg(price, 180s) as avg_60s,
    mavg(price, 300s) as avg_300s,
    symbol,
    price,
    vol
from t
context by symbol

部分结果展示:

period avg_60s avg_300s symbol price vol
2025.08.10 00:01:00 20.81 20.81 A 20.81 1,002
2025.08.10 00:02:00 20.9 20.9 A 20.99 1,041
2025.08.10 00:04:00 20.72 20.75 A 20.45 1,007
2025.08.10 00:05:00 20.35 20.625 A 20.25 1,030
2025.08.10 00:07:00 20.2 20.28333333333333 A 20.15 1,007
2025.08.10 00:08:00 20.424999999999997 20.3875 A 20.7 1,038
2025.08.10 00:10:00 20.355 20.286666666666665 A 20.01 1,029

例2. 按 symbol 分组,滑动步长为 2 行,分别计算过去 2 行的交易量均值,以及过去 3 行交易量总和。

select roll(X=vol, step=2, stepType='row') as window, avg(vol), msum(vol, 3), symbol, price, vol from t context by symbol
window avg_vol msum_vol symbol price vol
1,041 1,021.5 2,043 A 20.99 1,041
1,030 1,018.5 3,078 A 20.25 1,030
1,038 1,022.5 3,075 A 20.7 1,038
1,016 1,053.5 2,107 B 20.01 1,016
1,064 1,035.5 3,087 B 20.52 1,064
1,015 1,011 3,086 B 20.98 1,015
1,038 1,036.5 2,073 C 20.6 1,038
1,012 1,037 3,112 C 20.32 1,012
1,041 1,038 3,088 C 20.48 1,041

例3. 本例通过参数 exclude 排除1:30–13:00 的午休时段。在该时间区间内,系统不进行窗口划分。

select
    roll(X=timestamp, step=60s, stepType='time', exclude=(11:30:00 : 13:00:00)) as period,
    mavg(price, 180s) as avg_60s,
    mavg(price, 300s) as avg_300s,
    symbol,
    price,
    vol
from t
context by symbol
period avg_60s avg_300s symbol price vol
2025.08.10 00:01:00 20.81 20.81 A 20.81 1,002
2025.08.10 00:02:00 20.9 20.9 A 20.99 1,041
2025.08.10 00:04:00 20.72 20.75 A 20.45 1,007
2025.08.10 00:05:00 20.35 20.625 A 20.25 1,030
2025.08.10 00:07:00 20.2 20.28333333333333 A 20.15 1,007
2025.08.10 00:08:00 20.424999999999997 20.3875 A 20.7 1,038
2025.08.10 00:10:00 20.355 20.286666666666665 A 20.01 1,029
2025.08.10 00:01:00 20.34 20.34 B 20.34 1,091
2025.08.10 00:03:00 20.175 20.175 B 20.01 1,016
2025.08.10 00:04:00 20.355 20.35 B 20.7 1,007

例4. 通过stepType='window' 自定义 3 个时间窗口,计算每个股票过去 1 天,3 天和 7 天内的成交量和加权平均价格。roll 函数采用增量计算,可以大幅提升计算效率。

date = stretch(2025.08.01+ 0..8, 24)
time = take([09:30:00, 10:00:00, 10:30:00],24)
symbol = take(`A`B, 24)   
price = [22.40, 24.00, 23.50, 29.30, 24.10, 27.60, 20.10, 21.00, 23.60, 22.40,
               24.60, 23.30, 21.20, 20.60, 27.30, 29.30, 26.90, 25.20, 20.20, 20.10,
               28.30, 22.50, 28.20, 23.50]

vol = [1088, 1074, 1081, 1018, 1045, 1007, 1023, 1009, 1018, 1019,
           1013, 1017, 1039, 1057, 1045, 1062, 1046, 1033, 1022, 1007,
           1087, 1012, 1091, 1074]         
timestamp=concatDateTime(date,time)
t = table(timestamp as timestamp, symbol as symbol, price as price, vol as vol)
t = select * from t order by symbol, timestamp

startDates = [datetime(2025.08.01), datetime(2025.08.01), datetime(2025.08.01)]
endDates = [datetime(2025.08.02), datetime(2025.08.04), datetime(2025.08.07)]
labels = ["1d", "3d", "7d"]

// 计算窗口指标
select 
    roll(X=datetime(timestamp), step=(startDates, endDates), stepType='window', label=labels, fill='none') as period,
    timestamp,
    symbol,
    vol,
    price,
    sum(vol) as vol_sum,
    wavg(price, vol) as vwap
from t context by symbol
period timestamp symbol vol price vol_sum vwap
1d 2025.08.01 10:30:00 A 1,081 23.5000 2,169 22.9482
3d 2025.08.03 10:30:00 A 1,018 23.6000 5,255 22.7491
7d 2025.08.06 10:00:00 A 1,046 26.9000 9,398 23.7454
1d 2025.08.01 10:00:00 B 1,074 24.0000 1,074 24.0000
3d 2025.08.03 10:00:00 B 1,009 21.0000 4,108 25.4590
7d 2025.08.06 10:30:00 B 1,033 25.2000 9,296 24.7450