2017-07-21 12 views
0

私はPostgreSQLでEnd-of-Dayの株価を正常化しようとしています。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の場合、発行済株式の数は倍増しましたが、個々の株式の価値はその時点から半分になります。株式が1株当たり100ドルの価値があった場合、今は1株当たり50ドルの価値がある。

これを生の数字でグラフ化すると、この種のことは本当に醜いです。会社の全体的な価値が大きく変化しなかったときに鋭い崖が現れ、複数の分割があると、会社の傾向を正しく反映していないグラフが表示されます。上記の例では、2:1分割があった場合、株式の終値は100,100,100,50,50,50のようになります。

この表を使用して、合理的に効率的な方法で(正規化された)価格を提供します(チャンクするレコードはかなりあります)。サンプルを続けると株価が50,50,50,50,50,50で表示されます。複数の分割があった場合、実際の市場価値の変動を無視すると、データは一貫性があり滑らかでなければなりません。

スプリット値の「実行中の製品」集合体のCTEを作成して、時間を追って戻ったら、在庫あたりの日付範囲とクローズコストに適用する修飾子値を定義することができます次に、それをeodテーブルに戻して、各テーブルの調整済のclose値を新しいテーブルに選択します。

...問題は、テンポラリテーブルとマルチステッププロセスのすべてではなく、何をするのか、私の頭の中を包み込むことができません。私はこれを簡単にする組み込みの機能も知らない。

正規化されたデータをどのように生成することができますか?

答えて

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

このように見えます。私はそれが何をするかを理解するためにより多くの時間が必要ですが、それは素敵できちんとしたものです。どうもありがとう! –