2017-07-28 6 views
0

私は毎月の株式データの五分位ポートフォリオを形成することができるSQLコードを持っています。五分位ポートフォリオの形成は、比率(私のスプレッドシートのB/Mと呼ばれます)によって決まります。株式/企業が前月と比較してある月間に追加されたり取り下げされたりするため、このコードは毎月異なる5つのポートフォリオを自動的に生成したいと思います。比率はまた、翌月にある株式が別の五分位でランク付けされるように変更することもできます。SQLで五分ストックポートフォリオを作成

私はエクセルシートの構成を簡単に示すためにプリントスクリーンを追加しました。 基本的には、1か月にソートされます。 enter image description here

+0

画像が表示されません。比率を計算するために現在どの式を使用していますか?ウィンドウ関数(https://docs.microsoft.com/en-us/sql/t-sql/functions/ranking-functions-transact-sql)を使用して五分木を計算することができます。どのような味とバージョンのSQLを使用していますか? – Shawn

+0

また、https://stackoverflow.com/help/mcve <<<非常に役立ちます。 – Shawn

答えて

0

注:これはMS SQL 2008+に適用されます。

私はあなたのデータ構造がどのようなものか知らないが、多分

/* Test Data */ 
WITH stocks AS (
    /* Jan = 10 = 2 per quint */ 
    SELECT 'abc' AS StockName, 100.00 AS StockPrice, '20170101' AS PriceDate UNION ALL 
    SELECT 'def' AS StockName, 99.00 AS StockPrice, '20170101' AS PriceDate UNION ALL 
    SELECT 'ghi' AS StockName, 50.00 AS StockPrice, '20170101' AS PriceDate UNION ALL 
    SELECT 'jkl' AS StockName, 50.00 AS StockPrice, '20170101' AS PriceDate UNION ALL 
    SELECT 'mno' AS StockName, 75.00 AS StockPrice, '20170101' AS PriceDate UNION ALL 
    SELECT 'pqr' AS StockName, 77.00 AS StockPrice, '20170101' AS PriceDate UNION ALL 
    SELECT 'stu' AS StockName, 20.00 AS StockPrice, '20170101' AS PriceDate UNION ALL 
    SELECT 'vwx' AS StockName, 10.00 AS StockPrice, '20170101' AS PriceDate UNION ALL 
    SELECT 'yz1' AS StockName, 2.00 AS StockPrice, '20170101' AS PriceDate UNION ALL 
    SELECT '234' AS StockName, 1.00 AS StockPrice, '20170101' AS PriceDate UNION ALL 

    /* Feb = 7 = uneven quints */ 
    SELECT 'abc' AS StockName, 1.00 AS StockPrice, '20170201' AS PriceDate UNION ALL 
    SELECT 'def' AS StockName, 2.00 AS StockPrice, '20170201' AS PriceDate UNION ALL 
    SELECT 'ghi' AS StockName, 20.00 AS StockPrice, '20170201' AS PriceDate UNION ALL 
    SELECT 'jkl' AS StockName, 55.00 AS StockPrice, '20170201' AS PriceDate UNION ALL 
    SELECT 'mno' AS StockName, 50.00 AS StockPrice, '20170201' AS PriceDate UNION ALL 
    SELECT 'pqr' AS StockName, 100.00 AS StockPrice, '20170201' AS PriceDate UNION ALL 
    SELECT 'stu' AS StockName, 90.00 AS StockPrice, '20170201' AS PriceDate UNION ALL 

    /* Mar = 3 = not enough for 5 quints. */ 
    SELECT 'abc' AS StockName, 42.00 AS StockPrice, '20170301' AS PriceDate UNION ALL 
    SELECT 'jkl' AS StockName, 42.00 AS StockPrice, '20170301' AS PriceDate UNION ALL 
    SELECT 'vwx' AS StockName, 42.00 AS StockPrice, '20170301' AS PriceDate 
) 

/* Query */  
SELECT y.StockName, y.StockPrice, y.PriceMonth, y.quintile 
FROM (
    SELECT x.StockName, x.StockPrice, month(x.PriceDate) AS PriceMonth 
     , NTILE(5) OVER (PARTITION BY month(x.PriceDate) ORDER BY x.StockPrice DESC) AS quintile 
    FROM stocks x 
    GROUP BY x.StockName, x.StockPrice, month(x.PriceDate) 
) y 
ORDER BY y.PriceMonth, y.quintile ASC 

の線に沿って何かは、あなたがそれを表示する場合次に、あなただけのことができ

StockName StockPrice PriceMonth quintile 
abc  100.00  1   1 
def   99.00  1   1 
pqr   77.00  1   2 
mno   75.00  1   2 
ghi   50.00  1   3 
jkl   50.00  1   3 
stu   20.00  1   4 
vwx   10.00  1   4 
yz1   2.00  1   5 
234   1.00  1   5 
pqr  100.00  2   1 
stu   90.00  2   1 
jkl   55.00  2   2 
mno   50.00  2   2 
ghi   20.00  2   3 
def   2.00  2   4 
abc   1.00  2   5 
abc   42.00  3   1 
jkl   42.00  3   2 
vwx   42.00  3   3 

あなた

を与えます五分音符でソート/グループ化します。

また、上記の例は、NTILE()があなたの探しているものを提供するとは限りません。計算してから自分で五分木を作成する必要があるかもしれません。 March group >> allは42ドルですが、3つの異なるクインタイルに入れられています。他のQuintile 3価格の下にもあります。だからそれがあなたが望むものであることを確認してください。

最後に、日付部分を事前計算する日付ディメンションテーブルを追加してから、メインサブクエリにJOINを追加する方が良いでしょうが、それは全く異なる議論です。

0

比率を計算し、それらを使って何かがあると判断された場合は、が簡単になります。 NTILE()を使用する必要はありません。各五分位に入る最小と最大の比率を指定するCTEを設定することができます。

/* Test Data */ 
IF OBJECT_ID(N'tempdb..#stocks') IS NOT NULL 
    DROP TABLE #stocks 
; 

CREATE TABLE #stocks (StockName varchar(10), BMratio int, StockMonth datetime) ; 
INSERT INTO #stocks (StockName, BMratio, StockMonth) 
    /* Jan = 10 = 2 per quint */ 
    SELECT 'abc' AS StockName, 10 AS BMratio, '20170101' AS StockMonth UNION ALL 
    SELECT 'def' AS StockName, 9 AS BMratio, '20170101' AS StockMonth UNION ALL 
    SELECT 'ghi' AS StockName, 8 AS BMratio, '20170101' AS StockMonth UNION ALL 
    SELECT 'jkl' AS StockName, 7 AS BMratio, '20170101' AS StockMonth UNION ALL 
    SELECT 'mno' AS StockName, 6 AS BMratio, '20170101' AS StockMonth UNION ALL 
    SELECT 'pqr' AS StockName, 5 AS BMratio, '20170101' AS StockMonth UNION ALL 
    SELECT 'stu' AS StockName, 4 AS BMratio, '20170101' AS StockMonth UNION ALL 
    SELECT 'vwx' AS StockName, 3 AS BMratio, '20170101' AS StockMonth UNION ALL 
    SELECT 'yz1' AS StockName, 2 AS BMratio, '20170101' AS StockMonth UNION ALL 
    SELECT '234' AS StockName, 1 AS BMratio, '20170101' AS StockMonth UNION ALL 

    /* Feb = 7 = uneven quints */ 
    SELECT 'abc' AS StockName, 1 AS BMratio, '20170201' AS StockMonth UNION ALL 
    SELECT 'def' AS StockName, 2 AS BMratio, '20170201' AS StockMonth UNION ALL 
    SELECT 'ghi' AS StockName, 4 AS BMratio, '20170201' AS StockMonth UNION ALL 
    SELECT 'jkl' AS StockName, 5 AS BMratio, '20170201' AS StockMonth UNION ALL 
    SELECT 'mno' AS StockName, 7 AS BMratio, '20170201' AS StockMonth UNION ALL 
    SELECT 'pqr' AS StockName, 10 AS BMratio, '20170201' AS StockMonth UNION ALL 
    SELECT 'stu' AS StockName, 9 AS BMratio, '20170201' AS StockMonth UNION ALL 

    /* Mar = 3 = not enough for 5 quints. */ 
    SELECT 'abc' AS StockName, 5 AS BMratio, '20170301' AS StockMonth UNION ALL 
    SELECT 'jkl' AS StockName, 5 AS BMratio, '20170301' AS StockMonth UNION ALL 
    SELECT 'vwx' AS StockName, 5 AS BMratio, '20170301' AS StockMonth 
; 

/* Create CTE query */ 
; WITH Quint_CTE AS (
    SELECT 1 AS quintNum, 9 AS quintMin, 10 AS quintMax UNION ALL 
    SELECT 2 AS quintNum, 7 AS quintMin, 8 AS quintMax UNION ALL 
    SELECT 3 AS quintNum, 5 AS quintMin, 6 AS quintMax UNION ALL 
    SELECT 4 AS quintNum, 3 AS quintMin, 4 AS quintMax UNION ALL 
    SELECT 5 AS quintNum, 0 AS quintMin, 2 AS quintMax 
) 
SELECT x.StockName, month(x.StockMonth) AS StockMonth, q.quintNum AS quintile 
FROM #stocks x 
INNER JOIN Quint_CTE q ON x.BMratio BETWEEN q.quintMin AND q.quintMax 
ORDER BY StockMonth, q.quintNum ASC