代码之家  ›  专栏  ›  技术社区  ›  Ramy

在SQL中计算“Max Draw Down”

  •  11
  • Ramy  · 技术社区  · 14 年前

    编辑:我正在使用SQLServer 2005

    与此类似的内容以前也曾发布过,但我不认为海报提供了足够的信息来真正解释max draw down是什么。我对max draw down的所有定义都来自(前两页)本文: http://www.stat.columbia.edu/~vecer/maxdrawdown3.pdf

    运行最大值,M

    =最大值 u in[0,t] (第 u型
    在哪里 t型 是股票的价格,S,在时间t。

    t型

    t型 t型 -S公司

    最大下降,MDD

    MDD公司 t型 u in[0,t] (四) )

    因此,需要确定的是给定股票在一段时间内的一组高、低价格的局部极大值和极小值。

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

    因此,对于给定的日期范围,您每天都会看到相同的stockid。


    高和低是一天中的高和低。

    一旦确定了局部最大值和最小值,就可以将每个最大值与之后的每个最小值配对,并计算出差值。从这个集合中,最大的差别是“最大下降”。

    编辑:请注意: 最大支取定义为假设损失的价值,如果股票在最高买入点买入,在最低卖出点卖出。股票不能以低于maxval的价格出售。因此,如果全局minval在全局maxval之前,那么这两个值不能提供足够的信息来确定最大提取。

    6 回复  |  直到 14 年前
        1
  •  1
  •   akaphenom    14 年前

    在问题领域我们需要考虑的一些事情:

    1. 股票每天都有一系列的价格,经常在烛台图上看到
    2. 让我们把一天中的最低价称为
    3. 这个问题受到时间的限制,即使时间限制是IPO日期和退市日期
    4. 假设一个长策略:逻辑上,如果我们能够确定所有局部最大值(maxes)和所有局部最小值(mins),我们可以定义一个集合,在其中我们将每个最大值与随后的每个最小值配对,并计算差异
    5. 有时差异会导致负数,但这并不是减少

    问题在于定义最大值和最小值,利用曲线的函数我们可以应用微积分,但是我们不能

    1. maxes需要来自HI和

    解决这个问题的一个方法是定义一个游标并强制它。函数式语言也有很好的工具集来解决这个问题。

        2
  •  3
  •   van    14 年前

    效率极低,但使用视图的非常简单的版本如下:

    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

        3
  •  1
  •   JNK    14 年前

    对于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'
    
        4
  •  1
  •   will    13 年前

    我最近遇到这个问题,我的解决办法是这样的: 把和一个一个地相加,如果和大于0,设为0,否则求和,结果如下 0,0,0,0,-1,0,-8,-11,-11,-1

        5
  •  0
  •   Craig    14 年前

    这就是你要找的吗?

    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的暴力方法。它比较了同一个股票在今天的高价之后的每一个低价,发现这两个价格之间的最大差异。这将是最大的下降。

    因为我们在表格中没有足够的信息来确定高价格是否发生在当天的低价格之前,所以不能比较同一天的最高提款额。

        6
  •  0
  •   RBarryYoung    14 年前

    下面是一个SQL Server 2005用户定义函数,它应该非常有效地返回单个stockid的正确答案

    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
    

    但是,这对于同时处理多个stockid来说不是很有效。如果您需要同时执行许多/所有stockid,那么有一种类似但实际上更困难的方法可以非常有效地执行此操作。

    推荐文章