Как рассчитать скользящую максимальную просадку по диапазону инструментов в SQL? - PullRequest
1 голос
/ 18 апреля 2020

Доброе утро,

Я пытаюсь создать хранимую процедуру для вычисления скользящего максимального уровня рисования для каждой даты в диапазоне от 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

Любая помощь или предложение будет принята с благодарностью.

Николас

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...