2017-07-21 34 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

看起來像這樣。我需要更多的時間來了解它的功能,但它很好,很整潔。非常感謝! –