如何计算年累积回报

时间:2015-03-01 04:44:26

标签: sql oracle oracle11g

我的表格如下:

Date        stock   price
19980102     xxx    1.2
19980103     xxx    1.3
...
19980102     yyy    1.2
19980103     yyy    3.3

由于某种原因,日期存储在int中并且每天更新。我想挑选每年累计回报率+ 5%的股票代码,这种模式在过去的19年中持续存在。该怎么做?

例如:if for xxx

(price(19981231)-price(19980101))/price(19980101) > 5%
那么1998年就是那一年,那么如果每年19年就是这样的话,我会选择XXX。

棘手的部分是:股票仅在工作日交易,因此19980101可能没有数据..

2 个答案:

答案 0 :(得分:4)

过去19年的累计回报率为5%,为1.05 ^ 19 = 2.53。

所以,你可以得到期间最新的结果和最新的结果,看看比率是否至少那么大:

select stock
from (select t.*, row_number() over (partition by stock order by date) as seqnum,
             count(*) over (order by date) as cnt
      from table t
      where date >= 19980101
     ) t
group by stock
having (sum(case when seqnum = cnt then price end) /
        sum(case when seqnum = 1 then price end)
       ) >= 2.53;

答案 1 :(得分:2)

好吧,这可能有点奇怪,但请耐心等待。我不得不说,我并不真正理解你的意思,每年的累积回报&#34 ;;你似乎只是在一年中的第一天和最后一天检查价格并进行比较 - 没有什么可以累积的。首先,让我们按一年的最低和最高日期获取价格:

SELECT stock, TRUNC(date/10000) AS the_year
     , MIN(price) KEEP (DENSE_RANK FIRST ORDER BY date) AS start_price
     , MAX(price) KEEP (DENSE_RANK LAST ORDER BY date) AS end_price
  FROM mytable
 GROUP BY stock, TRUNC(date/10000)

这将获得起始价格(截至一年的第一个工作日,或至少为date的最低值)和最终价格(最大值为date)。

现在我们需要做的就是找出最终价格是起始价格的105%的年份:

SELECT stock, the_year, start_price, end_price
     , ( end_price - start_price ) / start_price AS yield
     , COUNT(*) OVER ( PARTITION BY stock ) AS year_cnt
  FROM (
    SELECT stock, TRUNC(date/10000) AS the_year
         , MIN(price) KEEP (DENSE_RANK FIRST ORDER BY date) AS start_price
         , MAX(price) KEEP (DENSE_RANK LAST ORDER BY date) AS end_price
      FROM mytable
     GROUP BY stock, TRUNC(date/10000)
) WHERE end_price >= start_price * 1.05

然后获得year_cnt为19:

的股票
SELECT * FROM (
    SELECT stock, the_year, start_price, end_price
         , ( end_price - start_price ) / start_price AS yield
         , COUNT(*) OVER ( PARTITION BY stock ) AS year_cnt
      FROM (
        SELECT stock, TRUNC(date/10000) AS the_year
             , MIN(price) KEEP (DENSE_RANK FIRST ORDER BY date) AS start_price
             , MAX(price) KEEP (DENSE_RANK LAST ORDER BY date) AS end_price
          FROM mytable
         GROUP BY stock, TRUNC(date/10000)
    ) WHERE end_price >= start_price * 1.05
) WHERE year_cnt = 19;