вычисление "Max Draw Down" в SQL - PullRequest
       0

вычисление "Max Draw Down" в SQL

11 голосов
/ 28 октября 2010

edit: стоит просмотреть раздел комментариев первого ответа, чтобы получить более четкое представление о проблеме.

изменить: я использую SQLServer 2005

что-то похожее на это было опубликовано ранее, но я не думаю, что автор предоставил достаточно информации, чтобы действительно объяснить, что такое максимальная просадка. Все мои определения максимального использования взяты из (первых двух страниц) этой статьи: http://www.stat.columbia.edu/~vecer/maxdrawdown3.pdf

эффективно, у вас есть несколько терминов, определенных математически:

Максимум хода, М т

M t = max u in [0, t] (S u )
где S t - цена акции, S, в момент времени, т.

Просадка, D t

D т = М т - S т

Макс. Просадка, MDD t

MDD t = max u in [0, t] (D u )

Таким образом, для эффективного определения необходимо определить локальные максимумы и минимумы из набора высоких и низких цен для данного запаса за определенный период времени. У меня есть таблица исторических котировок со следующими (соответствующими) столбцами:

stockid int  
day date  
hi  int --this is in pennies  
low int --also in pennies  

поэтому для данного диапазона дат вы будете видеть один и тот же запас каждый день для этого диапазона дат.

EDIT:
Привет и низкий являются высокими для дня и низким для каждого дня.

как только определены локальные максимумы и минимумы, вы можете соединить каждый максимум с каждым последующим минимумом и рассчитать разницу. Исходя из этого набора, максимальной разницей будет «Максимальная ничья».

Но самое сложное - найти эти максимумы и минимумы.

редактировать: следует отметить: Максимальная просадка определяется как значение гипотетического убытка, если акция покупается в самой высокой точке покупки и продается в самой низкой точке продажи. Акция не может быть продана на минвале, который предшествовал максимальному. поэтому, если глобальный минваль предшествует глобальному максимальному, эти два значения не предоставляют достаточно информации для определения максимальной просадки.

Ответы [ 6 ]

3 голосов
/ 29 октября 2010

Жестоко неэффективная, но очень простая версия с использованием вида ниже:

WITH DDView
AS (SELECT      pd_curr.StockID,
                pd_curr.Date,
                pd_curr.Low_Price  AS CurrPrice,
                pd_prev.High_Price AS PrevPrice,
                pd_curr.Low_Price / pd_prev.High_Price - 1.0 AS DD

    FROM        PriceData pd_curr
    INNER JOIN  PriceData pd_prev
            ON  pd_curr.StockID = pd_prev.StockID
            AND pd_curr.Date >= pd_prev.Date
            AND pd_curr.Low_Price <= pd_prev.High_Price
            AND pd_prev.Date >= '2001-12-31' -- @param: min_date of analyzed period
    WHERE       pd_curr.Date <= '2010-09-31' -- @param: max_date of analyzed period
)
SELECT      dd.StockID,
            MIN(COALESCE(dd.DD, 0)) AS MaxDrawDown
FROM        DDView dd
GROUP BY    dd.StockID

Как обычно вы выполняете анализ за определенный период времени, имеет смысл заключить запрос в хранимую процедуру с параметрами @StartDate, @EndDate и, возможно, @StockID. Опять же, это довольно неэффективно по замыслу - O (N ^ 2), но если у вас хорошие показатели и не огромное количество данных, SQL Server справится с этим довольно хорошо.

1 голос
/ 14 марта 2012

Я недавно столкнулся с этой проблемой, Мое решение таково: пусть data: 3,5,7,3, -1,3, -8, -3,0,10 добавьте сумму по одномусумма больше 0, установите 0, иначе получите сумму, результат будет примерно таким: 0,0,0,0, -1,0, -8, -11, -11, -1 Максимальная просадкасамое низкое значение в данных, -11.

1 голос
/ 29 октября 2010

Некоторые вещи, которые мы должны рассмотреть в проблемной области:

  1. Акции имеют диапазон цен каждый день, часто просматриваемый на графиках свечей
  2. Позвоним по самой высокой цене дня HI
  3. давайте назовем самую низкую цену дня LOW
  4. проблема ограничена временем, даже если временными ограничениями являются дата IPO и даты исключения из списка
  5. максимальная просадка - это максимальная сумма, которую вы можете потерять на акции за этот период
  6. при условии ДЛИТЕЛЬНОЙ стратегии: логически, если мы сможем определить все локальные максимумы (MAXES) и все локальные минимумы (MINS), мы могли бы определить набор, в котором мы соединяем каждый MAX с каждым последующим MIN и вычисляем разницу DIFFS
  7. Иногда разница приводит к отрицательному числу, однако это не просадка
  8. , следовательно, нам нужно выбрать добавление 0 в наборе разностей и выбрать максимум

Проблема заключается в определении МАКС и МИНУТ, с помощью функции кривой, которую мы могли бы применять исчисление, облом мы не можем. Очевидно,

  1. максимумы должны исходить от HI и
  2. МИНУТЫ должны прийти из НИЗКИХ

Один из способов решить эту проблему - определить курсор и перебрать его. Функциональные языки также имеют хорошие инструменты для решения этой проблемы.

1 голос
/ 28 октября 2010

Для SQL Server и для одной акции за раз, попробуйте это:

Create Procedure 'MDDCalc'(
    @StartDate date,
    @EndDate date,
    @Stock int)

AS

DECLARE @MinVal Int
DECLARE @MaxVal Int
DECLARE @MaxDate date

SET @MaxVal = (
    SELECT MAX(hi)
    FROM Table
    WHERE Stockid = @Stock 
    AND Day BETWEEN (@Startdate-1) AND (@EndDate+1))

SET @MaxDate=(
    SELECT Min(Date)
    FROM Table
    WHERE Stockid = @Stock
    AND hi = @MaxVal)

SET @MinVal = (
    SELECT MIN(low)
    FROM Table
    WHERE Stockid = @Stock 
    AND Day BETWEEN (@MaxDate-1) AND (@EndDate+1))

SELECT  (@MaxVal-@MinVal) AS 'MDD'
0 голосов
/ 30 октября 2010

Вот пользовательская функция SQL Server 2005, которая должна очень эффективно возвращать правильный ответ для одного запаса

CREATE FUNCTION dbo.StockMaxDD(@StockID int, @day datetime) RETURNS int  AS
 BEGIN
    Declare @MaxVal int;    Set @MaxVal = 0;
    Declare @MaxDD int;     Set @MaxDD = 0;

    SELECT TOP(99999)
        @MaxDD  = CASE WHEN @MaxDD < (@MaxVal-low) THEN (@MaxVal-low)  ELSE @MaxDD END,
        @MaxVal = CASE WHEN hi  > @MaxVal THEN hi   ELSE @MaxVal END
    FROM    StockHiLo
    WHERE   stockid = @Stockid
      AND   [day]  <= @day
    ORDER BY [day] ASC

    RETURN @MaxDD;
 END

Это, однако, не очень эффективно для выполнения ряда заготовок прив то же время.Если вам нужно сделать много / все запасы одновременно, то есть аналогичный, но существенно более сложный подход, который может сделать это очень эффективно.

0 голосов
/ 29 октября 2010

Это то, что вы ищете?

select StockID,max(drawdown) maxdrawdown
from (
select h.StockID,h.day highdate,l.day lowdate,h.hi - l.lo drawdown
from mdd h
  inner join mdd l on h.StockID = l.StockID
    and h.day<l.day) x
group by StockID;

Это подход грубой силы на основе SQL. Он сравнивает каждую низкую цену после сегодняшней высокой цены в пределах одной и той же акции и находит наибольшую разницу между этими двумя ценами. Это будет максимальная просадка.

Он не сравнивает тот же день, который возможен для максимальной просадки, поскольку у нас недостаточно информации в таблице, чтобы определить, произошла ли цена Hi до цены Lo в день.

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