编辑:值得回顾第一个答案的评论部分,以便更清楚地了解问题。
编辑:我正在使用SQLServer 2005
之前发布了类似于此的内容,但我认为海报没有提供足够的信息来真实地解释最大抽奖是什么。我对max draw-down的所有定义都来自本文的(前两页): http://www.stat.columbia.edu/~vecer/maxdrawdown3.pdf有效地,您可以用数学方式定义一些术语:
运行最大值,M t
M t = [0,t] 中的max u(S u )
其中S t 是股票的价格,S,时间,t。
缩编,D t
D t = M t - S t
Max Draw Down,MDD t
MDD t = [0,t] 中的max u(D u )
因此,有效的需要确定的是一段时间内给定股票的一组高价和低价的当地最大值和最小值。 我有一个历史报价表,其中包含以下(相关)列:
stockid int day date hi int --this is in pennies low int --also in pennies
因此,对于给定的日期范围,您将在该日期范围内每天看到相同的stockid。
修改
白天和白天都很高,每天都很低。
一旦确定了局部最大值和最小值,就可以将每个最大值与其后的每个最小值配对并计算差值。从该组中,最大差异将是“Max Draw Down”。
虽然困难的部分是找到那些最大和最小的。
编辑:应该注意: 最大亏损定义为假设损失的价值,如果股票在其最高买入点买入并以低卖点卖出。股票不能以maxval之前的最小值出售。所以,如果全局最小值在全局最大值之前,则这两个值不能提供足够的信息来确定最大值。
答案 0 :(得分:3)
使用视图的残酷低效但非常简单的版本如下:
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 :(得分:1)
对于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'
答案 2 :(得分:1)
我们需要在问题域中考虑一些事项:
问题在于定义MAXES和MINS,我们可以应用微积分的曲线函数,但我们不能。显然
解决此问题的一种方法是定义光标并强制它。功能语言也有很好的工具集来解决这个问题。
答案 3 :(得分:1)
我最近遇到过这个问题,我的解决方案是这样的: 让数据:3,5,7,3,-1,3,-8,-3,0,10 一个一个地加上和,如果总和大于0,设置为0,否则得到总和,结果就像这样 0,0,0,0,-1,0,-8,-11,-11,-1 最大下拉量是数据中的最低值,-11。
答案 4 :(得分:0)
这就是你要追求的吗?
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价格之前,因此我们没有比较考虑当天的最大提款量。
答案 5 :(得分:0)
这是一个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
然而,这对于同时进行多个库存来说不是非常有效。如果你需要同时做多个/所有的股票,那么有一个类似的,但实质上更难的方法可以非常有效地做到这一点。