2017-07-21 35 views
0

我正在尝试使PostgreSql中的每日结束价格正常化。PostgreSql中的“Running Product”聚合/窗口函数?

比方说,我有被定义为这样的股票表:

create table eod (
    date date not null, 
    stock_id int not null, 
    split decimal(16,8) not null, 
    close decimal(12,6) not null, 
    constraint pk_eod primary key (date, stock_id) 
); 

本表数据可能是这样的:

"date","stock_id","eod_split","close" 
"2014-06-13",14010920,"1.00000000","182.560000" 
"2014-06-13",14010911,"1.00000000","91.280000" 
"2014-06-13",14010923,"1.00000000","41.230000" 
"2014-06-12",14010911,"1.00000000","92.290000" 
"2014-06-12",14010920,"1.00000000","181.220000" 
"2014-06-12",14010923,"1.00000000","40.580000" 
"2014-06-11",14010920,"1.00000000","182.250000" 
"2014-06-11",14010911,"1.00000000","93.860000" 
"2014-06-11",14010923,"1.00000000","40.860000" 
"2014-06-10",14010911,"1.00000000","94.250000" 
"2014-06-10",14010923,"1.00000000","41.110000" 
"2014-06-10",14010920,"1.00000000","184.290000" 
"2014-06-09",14010920,"1.00000000","186.220000" 
"2014-06-09",14010911,"7.00000000","93.700000" 
"2014-06-09",14010923,"1.00000000","41.270000" 
"2014-06-06",14010923,"1.00000000","41.480000" 
"2014-06-06",14010911,"1.00000000","645.570000" 
"2014-06-06",14010920,"1.00000000","186.370000" 
"2014-06-05",14010920,"1.00000000","185.980000" 
"2014-06-05",14010911,"1.00000000","647.350000" 
"2014-06-05",14010923,"1.00000000","41.210000" 
... 
"2005-03-04",14010920,"1.00000000","92.370000" 
"2005-03-04",14010911,"1.00000000","42.810000" 
"2005-03-04",14010923,"1.00000000","25.170000" 
"2005-03-03",14010923,"1.00000000","25.170000" 
"2005-03-03",14010911,"1.00000000","41.790000" 
"2005-03-03",14010920,"1.00000000","92.410000" 
"2005-03-02",14010920,"1.00000000","92.920000" 
"2005-03-02",14010923,"1.00000000","25.260000" 
"2005-03-02",14010911,"1.00000000","44.121000" 
"2005-03-01",14010920,"1.00000000","93.300000" 
"2005-03-01",14010923,"1.00000000","25.280000" 
"2005-03-01",14010911,"1.00000000","44.500000" 
"2005-02-28",14010923,"1.00000000","25.160000" 
"2005-02-28",14010911,"2.00000000","44.860000" 
"2005-02-28",14010920,"1.00000000","92.580000" 
"2005-02-25",14010923,"1.00000000","25.250000" 
"2005-02-25",14010920,"1.00000000","92.800000" 
"2005-02-25",14010911,"1.00000000","88.990000" 
"2005-02-24",14010923,"1.00000000","25.370000" 
"2005-02-24",14010920,"1.00000000","92.640000" 
"2005-02-24",14010911,"1.00000000","88.930000" 
"2005-02-23",14010923,"1.00000000","25.200000" 
"2005-02-23",14010911,"1.00000000","88.230000" 
"2005-02-23",14010920,"1.00000000","92.100000" 
... 
"2003-02-24",14010920,"1.00000000","78.560000" 
"2003-02-24",14010911,"1.00000000","14.740000" 
"2003-02-24",14010923,"1.00000000","24.070000" 
"2003-02-21",14010920,"1.00000000","79.950000" 
"2003-02-21",14010923,"1.00000000","24.630000" 
"2003-02-21",14010911,"1.00000000","15.000000" 
"2003-02-20",14010911,"1.00000000","14.770000" 
"2003-02-20",14010920,"1.00000000","79.150000" 
"2003-02-20",14010923,"1.00000000","24.140000" 
"2003-02-19",14010920,"1.00000000","79.510000" 
"2003-02-19",14010911,"1.00000000","14.850000" 
"2003-02-19",14010923,"1.00000000","24.530000" 
"2003-02-18",14010923,"2.00000000","24.960000" 
"2003-02-18",14010911,"1.00000000","15.270000" 
"2003-02-18",14010920,"1.00000000","79.330000" 
"2003-02-14",14010911,"1.00000000","14.670000" 
"2003-02-14",14010920,"1.00000000","77.450000" 
"2003-02-14",14010923,"1.00000000","48.300000" 
"2003-02-13",14010920,"1.00000000","75.860000" 
"2003-02-13",14010911,"1.00000000","14.540000" 
"2003-02-13",14010923,"1.00000000","46.990000" 

注“分割”一栏。当记录除1之外的拆分值时,基本上意味着股票按照该因子分摊。在IOW中,当拆分为2.0时,流通股的数量增加了一倍,但是从那时起,每个股份的价值减半。如果股票价值每股100美元,现在它的价值是每股50美元。

如果你用原始数字来表示这种事情,这种事情真的很丑。当公司的整体价值没有显着变化时......当你有多次拆分时,你会得到一张无法正确反映公司趋势的图表,这通常是一个很大的差距。在上面的例子中,当存在2:1的分割时,您的股票收盘价看起来应该是100,100,100,50,50,50。

我想使用此表创建一个“规范化“的价格,以合理有效的方式(有相当多的记录要通过)。继续样本,这将显示50,50,50,50,50,50,50的股票价格。如果存在多个拆分,那么如果我们忽略实际的市场价值变化,则数据应该保持一致和平滑。

我的想法是,如果我可以创建一个拆分值的“正在运行的产品”聚合的CTE,则可以及时回溯,我可以定义每个库存的日期范围以及应用于结束成本的修饰符值应该是多少然后将其加入到eod表中,并为每个股票选择调整后的收盘价值。

......问题是,我无法将自己的头围绕如何在除了大量临时表和多步骤过程之外的任何事情上进行包装。我不知道任何内置的功能,以使这更容易,无论是。

有人可以告诉我如何生成标准化的数据吗?

回答

1

你不需要CTE。你只需要一个累积产品。 Postgres没有内置。但是,算术救援!

select eod.*, 
     exp(sum(ln(eod_split)) over (partition by stock_id order by date)) as cume_split, 
     (close * 
     exp(sum(ln(eod_split)) over (partition by stock_id order by date)) 
     ) as normalized_price 
from eod; 
+0

这不算算。这是火箭科学。我甚至都不知道这里发生了什么,但我会尝试一下,看看我能否理解它。 –

+0

看起来像这样。我需要更多的时间来了解它的功能,但它很好,很整洁。非常感谢! –