Доброе утро,
Я пытаюсь создать хранимую процедуру для вычисления скользящего максимального уровня рисования для каждой даты в диапазоне от 3 лет на большом количестве инструментов, используя скользящий windows из 30 календарных дней.
Для этой цели я использую следующие переменные в качестве записей:
@DateDebut datetime,
@DateFin datetime,
@ReturnPeriod int
Моя исходная таблица цен представлена ниже
create table #tmpPrix
(
InstrumentID int not null,
DatePrix datetime,
Prix float
)
У меня тогда есть следующая структура, чтобы помочь мне сохранить мои вычисления и визуализировать мои результаты
create table #tmpCalculDD
(
InstrumentID int not null,
BoPDate datetime,
BoPPrice float,
EoPDate datetime,
EoPPrice float,
CurrentMinEoPPrice float,
CurrentMaxEoPPrice float,
CurrentSubsequentMinEoPPrice float,
CurrentDD float,
CurrentMaxDD float,
IsNewPeak bit,
IsNewValley bit,
tmpDatePeak datetime,
tmpDateValley datetime
)
Оттуда я перешел к вставке данных для цен, идентификаторов продуктов и дат:
insert into #tmpCalculDD (InstrumentID, EoPDate, EoPPrice)
select InstrumentID, DatePrix, Prix from #tmpPrix
update #tmpCalculDD set
BoPDate = c.MinDate
from #tmpCalculDD
inner join (
select a.InstrumentID, max(a.DatePrix) as MinDate, b.DatePrix
from #tmpPrix as a
inner join #tmpPrix as b on (a.InstrumentID = b.InstrumentID and a.DatePrix <= DATEADD(day, @ReturnPeriod, b.DatePrix))
group by a.InstrumentID,b.DatePrix) as c on (#tmpCalculDD.InstrumentID = c.InstrumentID and #tmpCalculDD.EoPDate = c.DatePrix)
update #tmpCalculDD set
BoPPrice = b.Prix
from #tmpCalculDD
inner join #tmpPrix as b on (#tmpCalculDD.InstrumentID = b.InstrumentID and #tmpCalculDD.BoPDate = b.DatePrix)
Следующим шагом является рассчитать текущие минимальные и максимальные цены скольжения:
update #tmpCalculDD set
CurrentMaxEoPPrice = a.CurrentMaxPrice,
CurrentMinEoPPrice = a.CurrentMinPrice
from #tmpCalculDD inner join (
select InstrumentID, EoPDate,
MAX(EoPPrice) OVER (PARTITION BY InstrumentID ORDER BY EoPDate ROWS UNBOUNDED PRECEDING) as CurrentMaxPrice,
MIN(EoPPrice) OVER (PARTITION BY InstrumentID ORDER BY EoPDate ROWS UNBOUNDED PRECEDING) as CurrentMinPrice
from #tmpCalculDD) as a on (#tmpCalculDD.InstrumentID = a.InstrumentID and #tmpCalculDD.EoPDate = a.EoPDate)
Затем я решил определить новые пики и новые долины - поскольку просадка рассчитывается как максимальный пик для последующей долины за каждый день вычислений
update #tmpCalculDD set
IsNewValley = a.NewValley,
IsNewPeak = a.NewPeak
from #tmpCalculDD inner join (
select InstrumentID, EoPDate,
CASE WHEN CurrentMinEoPPrice < LAG(CurrentMinEoPPrice, 1, 0) OVER (PARTITION By InstrumentID ORDER BY EoPDate) THEN 1 ELSE 0 END As NewValley,
CASE WHEN CurrentMaxEoPPrice > LAG(CurrentMaxEoPPrice, 1, 0) OVER (PARTITION BY InstrumentID ORDER BY EoPDate) THEN 1 ELSE 0 END As NewPeak
from #tmpCalculDD) as a on (#tmpCalculDD.InstrumentID = a.InstrumentID and #tmpCalculDD.EoPDate = a.EoPDate)
Я перешел к вычислениям временного пика и дат долины
update #tmpCalculDD set
tmpDatePeak = b.MinDate
from #tmpCalculDD
inner join (
select a.InstrumentID, a.EopPrice, min(a.EoPDate) as MinDate from #tmpCalculDD a group by a.InstrumentID, a.EoPPrice) as b
on (#tmpCalculDD.InstrumentID = b.InstrumentID and #tmpCalculDD.CurrentMaxEoPPrice = b.EoPPrice)
update #tmpCalculDD set
tmpDateValley = b.MinDate
from #tmpCalculDD
inner join (
select a.InstrumentID, a.EopPrice, min(a.EoPDate) as MinDate from #tmpCalculDD a group by a.InstrumentID, a.EoPPrice) as b
on (#tmpCalculDD.InstrumentID = b.InstrumentID and #tmpCalculDD.CurrentMinEoPPrice = b.EoPPrice)
И в настоящее время я застрял, так как не могу найти правильный способ упорядочить свои данные в хронологическом порядке. порядок, такой как моя MinEopPrice, должен отражать только максимальные последующие новые минимумы только после того, как произошел пик, и как только установился новый пик, я застрял при вычислении отношения долины к пику.
Ниже приведены некоторые образцы данных для вашего удобства.
data
Любая помощь или предложение будет принята с благодарностью.
Николас