2018年2月3日 星期六

以股票5日均線(MA5)為例-說明分析函數基本概念

在此將以台灣500050)及台積電(2330)之股票五日均線(MA5: Moving Average)計算為例,說明分析函數之基本概念,SQL2012ORACLE 8i/9i起已陸續提供許多相關析函數。
5日均線即逐日計算出最近5(4天及當天)收盤價之平均價格,再將每日數值連成一條曲線,以下圖0050為例,01/08MA501/02030405及當日等5日收盤價平均值(82.6083.3583.5083.7584.105日收盤價平均值為83.46),如下圖。
一般常用計算5日均線之SQL,如下所示:
WITH Stk AS
(
SELECT *
     , ROW_NUMBER() OVER(PARTITION BY StkId ORDER BY Dt) SEQ
FROM #STK
)
SELECT C.StkId, C.Dt, C.Pri, C.SEQ
      , (
           SELECT COUNT(*) 
           FROM Stk P
           WHERE 1=1
                   AND C.StkId = P.StkId
                   AND P.SEQ BETWEEN C.SEQ-4 --PRECEDING
                                AND C.SEQ   --CURRENT ROW
           ) RowCnt
      , (--彙總運算(子查詢): 5(4筆及目前)計算出平均值
           SELECT SUM(P.Pri) / COUNT(*)  --3.計算平均值可換為AVG(P.Pri)
           FROM Stk P
           WHERE 1=1
                   AND C.StkId = P.StkId      --1.股票限制:限同檔股票資料
                   AND P.SEQ BETWEEN C.SEQ-4 --2.日期區間:()4日收盤價PRECEDING
                                AND C.SEQ    --2.日期區間:()當日收盤價CURRENT ROW
           ) MA5
FROM Stk C--原始資料(主查詢)005023306
WHERE StkId IN ('0050', '2330') --0.查詢限制: 00502330兩檔

將區分主查詢(2018年初兩檔股票收盤價)及子查詢(計算5日均線)進行說明:
1.  主查詢(2018年初兩檔股票收盤價)
主查詢為2018年初兩檔股票收盤價原始資料,並未包含無任何彙總運算。但為提供子查詢計算5日均線(4天及當天)相對位置之參考依據,需使用ROW_NUMBER()次序函數根據每檔股票收盤價日期分別產生流水序號。
WITH Stk AS
(
SELECT *
, ROW_NUMBER() OVER(PARTITION BY StkId --1.股票限制: 限同檔股票資料
                      ORDER BY Dt      --2’.推導出日期前後次序關係,子查詢將參考使用
                     ) SEQ
FROM #STK
)
SELECT C.StkId, C.Dt, C.Pri, C.SEQ
, MA5
FROM Stk C--原始資料(主查詢)
WHERE C.StkId IN ('0050', '2330') --0.查詢限制: 00502330兩檔
2.  子查詢(計算5日均線)
子查詢與主查詢以股票代碼進行內部連結(INNER JOIN),限制子查詢與主查詢處理同一檔股票,再以流水序號限制此股票前4日及當日之資料,最後計算此5筆收盤價之平均值(MA5),如SQL中所列3個步驟。
(--彙總運算(子查詢): 5(4筆及目前)計算出平均值
 SELECT SUM(P.Pri) / COUNT(*)  --3.計算平均值可換為AVG(P.Pri)
 FROM Stk P
 WHERE 1=1
         AND C.StkId = P.StkId      --1.股票限制: :限同檔股票資料
         AND P.SEQ BETWEEN C.SEQ---2.日期區間: ()4日收盤價PRECEDING
                        AND C.SEQ    --2.日期區間: ()當日收盤價CURRENT ROW
  ) MA5
由前述查詢 (尤其為子查詢)之設計想法,即可導出分析函數基本概念。改以AVG()分析函數重新撰寫,SQL及說明如下:
SELECT C.StkId, C.Dt, C.Pri--, C.SEQ
     , AVG(Pri) --3.計算平均值
OVER(PARTITION BY StkId        --1.股票限制: 限同檔股票資料
                    ORDER BY Dt               --2’.推導出日期前後次序關係,子查詢將參考使用
                    ----------(以上與ROW_NUMBER概念相同)----------------
                    ROWS BETWEEN 4 PRECEDING   --2.日期區間: ()4
AND CURRENT ROW  --2.日期區間: ()當日
) MA5                       
     --, MA5
FROM #Stk C --原始資料(主查詢)
WHERE StkId IN ('0050', '2330') --0.查詢限制: 00502330兩檔
以分析函數計算5日均線應用中,股票限制(PARTITION BY: 資料分割)及導出日期前後次序關係(ORDER BY)所應用觀念與常用ROW_NUMBER次序函數雷同;但為取得或限制最近5(4日及當日)收盤價資料,需針對此檔股票收盤價日期再次限縮,如同子查詢SQL概念,資料計算日期區間天數為固定值(MA5:固定為5日),但實際範圍將依位置而上下滑動,即由相對位置動態決定上下邊界(前4天及當天),即日期區間(如圖中之方框,定義為WINDOW: 視窗框架)
將子查詢及分析函數之視窗框架WINDOW條件式兩者對照整理如下,由此可得知分析函數重要概念『視窗框架WINDOW)』。
日期區間(WINDOW
子查詢-查詢條件式
分析函數-窗口條件式
2.日期區間: ()4日收盤價
2.日期區間: ()當日收盤價
P.SEQ BETWEEN C.SEQ-4 --上界
AND C.SEQ   --下界
ROWS BETWEEN 4 PRECEDING--上界
          AND CURRENT ROW--下界

WINDOW子句可指定資料區間之起始點和結束點,用再次限縮 計算資料集語法如下:
[ROWS|RANGE] BETWEEN <Start Expr> AND <End Expr>
ROWS:  指定目前資料列(Row)前或後之固定資料筆數。
RANGE: 以邏輯方式指定與目前資料列的值相關的值範圍
{ ROWS | RANGE }
{ BETWEEN
  { UNBOUNDED PRECEDING
  | CURRENT ROW
  | value_expr { PRECEDING | FOLLOWING }
  }
  AND
  { UNBOUNDED FOLLOWING
  | CURRENT ROW
  | value_expr { PRECEDING | FOLLOWING }
  }
| { UNBOUNDED PRECEDING
  | CURRENT ROW
  | value_expr PRECEDING
  }
}

另外,為符合計算5日均線所需,查詢條件之起始條件(上界)為前4天(4 PRECEDING),結束條件(下界)為當天(CURRENT ROW),請注意天數之計算基準是以營業日而非日曆日,因此將使用ROWS關鍵字指定前後資料列,如同子查詢範例,ROW_NUMBER()次序函數於ORDER BY子句中指定收盤日為排序依據並產生前後對應次序關係,即是以動態/滑動相對座標之概念。
ROWS BETWEEN 4 PRECEDING--上界
          AND CURRENT ROW--下界

如本文計算MA為例,欲同時呈現股票每日之收盤價(主查詢,原始資料)及5日均價(子查詢,彙總運算結果),使用分析函數可簡化(取代)過去許多需使用多組自我連結複雜查詢語法(通常為子查詢),如圖示中需一併計算MA1010日均價),也可直指定上界為前9天(9 PRECEDING)即可,在此嘗試以對照說明方式分析函數導入之概念,使用細節、參數未多做著墨,應用時建議參考原廠文件、其他技術文章等。範例所用AVG()函數為分析函數與並非為彙總函數,兩者差別比較整理如下,以供應用參考。

彙總函數(Aggegate)
分析函數(Analytic)
語法
常搭配GROUP BY子句
OVER關鍵字
輸出
將多筆彙總成一筆
仍為原資料集



沒有留言:

張貼留言