iir
首发版本:2.00.19/3.00.6
语法
iir(X, b, a)
详情
对输入数据 X 应用 IIR(无限脉冲响应)滤波器,返回滤波后的结果。IIR 滤波器利用了过去的输出值作为反馈,因此可以用比 FIR 低得多的阶数实现陡峭的过渡带。
其数学表达式为:a[0]·y[n] = (b[0]·x[n] + b[1]·x[n-1] + … + b[M]·x[n-M]) - (a[1]·y[n-1] + … + a[N]·y[n-N]),其中 b 为分子系数,a 为分母系数。
-
输入数据中的前导空值不参与计算,对应位置的输出也为空值。除前导空值外,后续出现的空值按 0 处理。
-
该函数与 Python
scipy.signal.lfilter(b, a, X)功能相同,但两者对缺失值的处理方式不同。scipy.signal.lfilter不会对 NaN 进行特殊处理,因此 NaN 会参与滤波运算并传播到后续结果中。
参数
X 数值类型的常规向量,表示待滤波的数据。
b 非空数值类型的常规向量,表示 IIR 滤波器的分子系数。
a 非空数值类型的常规向量,表示 IIR 滤波器的分母系数。
返回值
返回与输入 X 相同形式且长度一致的结果。
例子
例1. 对向量应用 IIR 滤波。
x = 1 2 3 4 5
b = 0.2 0.2
a = 1 -0.5
iir(x, b, a)
// output: [0.2,0.7,1.35,2.075,2.8375]
x = [1, 2, NULL, 4] // 等价于 [1, 2, 0, 4]
b = 0.2 0.2
a = 1 -0.5
iir(x, b, a)
// output: [0.2,0.7,0.75,1.175]
例2. 在量化策略回测中,双均线交叉是最经典的趋势跟踪策略之一:用一条快速 EMA 和一条慢速 EMA,当快线上穿慢线时产生买入信号,下穿时产生卖出信号。EMA
本质上就是一个一阶 IIR 滤波器—— iir(X, [α], [1, -(1-α)]),其中 α =
2/(N+1)。相比用 FIR 实现同等平滑度,IIR 只需 2 个系数,在对数百只股票做全市场回测时,计算效率优势显著。
下面的示例模拟了某只股票一个交易日的 1 分钟 K 线数据,分别用 alphaFast(对应 10 周期 EMA)和 alphaSlow(对应 30 周期 EMA)两个一阶 IIR 滤波器提取快慢趋势线,并生成交叉信号。
// 1. 建 catalog、库、表
if(!existsCatalog("FinanceData")){
createCatalog("FinanceData")
}
go
use catalog FinanceData
if(!existsDatabase("FinanceData.kline")){
create database kline
partitioned by VALUE(2026.06.01..2026.06.30),
engine='TSDB'
}
go
if(!existsTable("FinanceData.kline", "min1")){
create table kline.min1 (
SecurityID SYMBOL,
TradeDate DATE,
BarTime TIMESTAMP,
Open DOUBLE,
High DOUBLE,
Low DOUBLE,
Close DOUBLE,
Volume LONG
)
partitioned by TradeDate,
sortColumns = [`SecurityID, `BarTime],
keepDuplicates = ALL
}
// 2. 造数据:模拟 600519.SH 当日 240 根 1 分钟 K 线
n = 240
idx = 0..(n - 1)
baseTime = 2026.06.02T09:30:00.000
barTime = baseTime + idx * 60000
trendComponent = 1800.0 + 10.0 * sin(2.0 * pi * idx / n * 2.0) + cumsum(rand(0.2, n) - 0.1)
noise = norm(0.0, 1.0, n)
closePrice = round(trendComponent + noise, 2)
openPrice = round(closePrice + norm(0.0, 0.5, n), 2)
highBase = iif(openPrice > closePrice, openPrice, closePrice)
lowBase = iif(openPrice < closePrice, openPrice, closePrice)
highPrice = round(highBase + abs(norm(0.0, 0.3, n)), 2)
lowPrice = round(lowBase - abs(norm(0.0, 0.3, n)), 2)
volume = long(rand(10000, n) + 100)
t = table(
symbol(take("600519.SH", n)) as SecurityID,
take(2026.06.02, n) as TradeDate,
barTime as BarTime,
openPrice as Open,
highPrice as High,
lowPrice as Low,
closePrice as Close,
volume as Volume
)
// 3. 插入数据
kline.min1.append!(t)
// 4. 读取原始 K 线数据
raw = select BarTime, Close
from kline.min1
where SecurityID = `600519.SH
and TradeDate = 2026.06.02
order by BarTime
// 5. IIR 计算 EMA 快慢线
alphaFast = 2.0 / (10 + 1)
alphaSlow = 2.0 / (30 + 1)
emaResult = select
BarTime,
Close,
iir(Close, [alphaFast], [1.0, -(1.0 - alphaFast)]) as emaFast,
iir(Close, [alphaSlow], [1.0, -(1.0 - alphaSlow)]) as emaSlow
from raw
// 6. 生成交叉信号
signals = select
BarTime,
Close,
emaFast,
emaSlow,
iif(
emaFast > emaSlow and prev(emaFast) <= prev(emaSlow),
"BUY",
iif(
emaFast < emaSlow and prev(emaFast) >= prev(emaSlow),
"SELL",
"HOLD"
)
) as signal
from emaResult
order by BarTime
// 7. 查看所有买卖信号
select *
from signals
where signal != "HOLD"
order by BarTime
相关函数:fir
