如何在SQL Server 2012中为多日期及多股票代码计算RSI
批量计算多股票多日期的RSI(SQL Server 2012)
针对你已经实现单日期单股票RSI计算的基础上,要扩展到多股票和多日期的需求,我们可以利用SQL Server 2012支持的窗口函数来实现高效的批量计算,无需逐个变量赋值。
思路说明
你的现有逻辑是基于每日px_close - px_open的正负变动来计算平均增益(AG)和平均损失(AL),再推导RS和RSI。批量计算的核心是为每个股票、每个日期构建滚动N天窗口(这里N=14),分别计算窗口内的正变动总和和负变动绝对值总和,再完成后续计算。
完整实现代码
-- 定义参数:可以根据需求调整日期范围和RSI周期 DECLARE @StartingDate smalldatetime = '20180301' DECLARE @EndingDate smalldatetime = '20180403' DECLARE @DAYS INT = 14 WITH DailyDelta AS ( -- 第一步:计算每日价格变动,区分正增益和负损失 SELECT Ticker, Date, px_close - px_open AS Delta, -- 提取正变动(增益),负变动则记为0 CASE WHEN px_close - px_open > 0 THEN px_close - px_open ELSE 0 END AS Gain, -- 提取负变动的绝对值(损失),正变动则记为0 CASE WHEN px_close - px_open < 0 THEN ABS(px_close - px_open) ELSE 0 END AS Loss FROM [dbo].[daily_data] WHERE Date BETWEEN @StartingDate AND @EndingDate ), RollingAgg AS ( -- 第二步:为每个股票计算滚动N天的累计增益和累计损失 SELECT Ticker, Date, -- 滚动窗口:当前日期往前推@DAYS-1天(共@DAYS天) SUM(Gain) OVER ( PARTITION BY Ticker ORDER BY Date ROWS BETWEEN (@DAYS - 1) PRECEDING AND CURRENT ROW ) AS TotalGain, SUM(Loss) OVER ( PARTITION BY Ticker ORDER BY Date ROWS BETWEEN (@DAYS - 1) PRECEDING AND CURRENT ROW ) AS TotalLoss FROM DailyDelta ) -- 第三步:计算AG、AL、RS和RSI,处理除数为0的边界情况 SELECT Ticker, Date, TotalGain / @DAYS AS AG, TotalLoss / @DAYS AS AL, -- 当AL为0时,RS设为极大值(避免除以0) CASE WHEN TotalLoss = 0 THEN 999999.99 ELSE (TotalGain / @DAYS) / (TotalLoss / @DAYS) END AS RS, -- 对应RSI计算,AL为0时RSI=100(无损失) CASE WHEN TotalLoss = 0 THEN 100.0 WHEN TotalGain = 0 THEN 0.0 ELSE 100 - (100 / (1 + (TotalGain / @DAYS) / (TotalLoss / @DAYS))) END AS RSI FROM RollingAgg -- 过滤出窗口数据足够的记录(前@DAYS-1天的窗口不完整,可根据需求保留或过滤) WHERE Date >= DATEADD(DAY, @DAYS - 1, @StartingDate) ORDER BY Ticker, Date;
关键细节解释
- PARTITION BY Ticker:确保每个股票的计算独立进行,不会跨股票混合数据。
- ORDER BY Date:保证窗口内的日期按顺序排列,滚动窗口是时间上的连续区间。
- ROWS BETWEEN ...:定义滚动窗口的范围,
(@DAYS - 1) PRECEDING AND CURRENT ROW表示包含当前行在内的最近@DAYS条记录。 - 边界处理:当
TotalLoss=0时(连续@DAYS天都是正变动),RSI直接设为100;当TotalGain=0时,RSI设为0,避免除以0的错误。
扩展提示
如果你的RSI计算逻辑是基于收盘价的日变动(标准RSI公式),只需要修改DailyDeltaCTE中的Delta计算为px_close - LAG(px_close) OVER (PARTITION BY Ticker ORDER BY Date),其余逻辑保持一致即可。
内容的提问来源于stack exchange,提问作者Coding_Newbie
相关产品推荐
相关产品推荐

