I am trying to calculate stochastic oscillator values on a table of stock prices for stocks at a particular date.
The table I am working on is:
CREATE TABLE [dbo].[equityprice](
[SecurityId] [int] NOT NULL,
[Date] [date] NOT NULL,
[Open] [numeric](19, 6) NULL,
[High] [numeric](19, 6) NULL,
[Low] [numeric](19, 6) NULL,
[Close] [numeric](19, 6) NULL,
[Volume] [bigint] NULL
CONSTRAINT [PK_equityprice] PRIMARY KEY CLUSTERED
(
[SecurityId] ASC,
[Date] ASC,
[DateAdded] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
The calculation is as follows:
Work out the lowest low for the last 14 periods (including the current one)
Calculate the raw value by: 100 * (CurrentClose-LowestLow) / (CurrentHigh-LowestLow)
Return field k as the average of the raw value for the last 3 periods (including the current one)
Return field d as the average of field k for the last 3 periods (including the current one)
There are potentially going to be 100 million plus price records over 50,000 SecurityIds.
I've come up with this as an initial try. It works, but it doesn't scale very well and I suspect there is a better way of doing it:
declare @dt date = '2010-11-12';
select * from
(select
SecurityId, [Date], [High], lowestLow, [Close], rawk, k,
avg(k) OVER(PARTITION BY SecurityId ORDER BY [Date] ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) as d
from
(select
SecurityId, [Date], [Close], [High], [lowestLow], rawk,
avg(rawK) OVER(PARTITION BY SecurityId ORDER BY [Date] ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) as k
from
(select
SecurityId, [Date], [Close], [High], [lowestLow],
iif(lowestLow is null, 0, iif([High]-lowestLow=0, 0, 100*([Close]-lowestLow)/([High]-lowestLow))) as rawK
from
(select
SecurityId, [Date], [Close], [High],
Min([Low]) OVER(PARTITION BY SecurityId ORDER BY [Date] ROWS BETWEEN 13 PRECEDING AND CURRENT ROW) as lowestLow
from
equityprice
where
[Date]<=@dt) as base)
as raw)
as k)
as d
where
[Date]=@dt
Any ideas?
Test data as follows:
High Lowest Close rawK K D
7.39 7.251 7.33 56.83453237
7.38 7.251 7.282 24.03100775
7.432 7.251 7.3 27.0718232 35.97912111
7.38 7.203 7.38 100 50.36761032
7.35 7.203 7.214 7.482993197 44.85160547 43.73277897
7.349 7.203 7.349 100 69.16099773 54.79340451
7.399 7.203 7.3 49.48979592 52.32426304 55.44562208
7.501 7.203 7.501 100 83.16326531 68.21617536
7.549 7.203 7.49 82.94797688 77.4792576 70.98892865
7.649 7.203 7.649 100 94.31599229 84.98617173
7.609 7.203 7.609 100 94.31599229 88.70374739
7.504 7.203 7.473 89.70099668 96.56699889 95.06632783
7.688 7.203 7.483 57.73195876 82.47765181 91.12021433
7.558 7.203 7.558 100 82.47765181 87.17410084