iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 26
0
Elastic Stack on Cloud

Elastic 戰台股系列 第 26

[Day26] 用 Aggregation 統計月/週 K線

今天來玩複雜一點的 Aggregation。

分析問題

月/週 K 線是把同月份/週數的收盤資料做統計的動作,每根 K 棒代表當月/週的開盤、最高價、最低價、收盤價以及總成交量。要利用 Aggregation 來進行運算,我的第一步是來拆解 "Buckets"。用一個圖來分析:
https://ithelp.ithome.com.tw/upload/images/20201010/20129624lhzcne8tWL.png

  1. 用 stock_id (股票代號)對所有的收盤資料進行 Agrregation
  2. 在每個 stock_id bucket 中再根據不同的月份進行一次 Aggregation
  3. 在 month_k bucket 中找出當月份的開/高/低/收/量。
    在這個問題中,我們會用到很多不同的 Aggregation,就一步步來實現吧!

terms aggregation

第一步,拆出 stock_id buckets:

GET /stock-history-prices-daily/_search
{
  "size":0,
  "aggs" : {
      "stock_id" : {
        "terms": {
          "field": "stock_id"
        }
      }
  }
}

https://ithelp.ithome.com.tw/upload/images/20201010/20129624BklDoAQWA8.png

nested aggregation

Aggregation 是可以 Nested 的!第二步,我要把每個 stock_id bucket 中的相同月份,再進行一次 aggregation。

GET /stock-history-prices-daily/_search
{
  "size":0,
  "aggs" : {
      "stock_id" : {
        "terms": {
          "field": "stock_id"
        },
        "aggs" : {
          "month_k": {
            "date_histogram": {
              "field": "date",
              "calendar_interval": "month"
            }
          }
        }
      }
  }
}

上面我使用了一個 date_histogram,參數設定只要指定以 month 為單位就可以,結果如下:
https://ithelp.ithome.com.tw/upload/images/20201010/20129624s9hO26GzYb.png

max, min aggregation

這就簡單了,再接一層 Aggregation,分別對 high/low 做 max,min aggs:

GET /stock-history-prices-daily/_search
{
  "size":0,
  "aggs" : {
      "stock_id" : {
        "terms": {
          ...
        },
        "aggs" : {
          "month_k": {
            ...
            },
            "aggs": {
              "high": {
                "max": {
                  "field": "high"
                }
              },
              "low": {
                "min": {
                  "field": "low"
                }
              }
            }
          }
        }
      }
  }
}

結果如下:
https://ithelp.ithome.com.tw/upload/images/20201010/20129624vs9iryT8tj.png

top_hits aggregation

要找出當月份的 open (開盤)/close (收盤)價,我利用了 top_hit aggregation,並且進行了 sort,稍微麻煩一點:

GET /stock-history-prices-daily/_search
{
  "size":0,
  "aggs" : {
      "stock_id" : {
        ...
        },
        "aggs" : {
          "month_k": {
            ...
            },
            "aggs": {
              "high": {
                ...
              },
              "low": {
                ...
              },
              "open": {
                "top_hits": {
                  "size": 1,
                  "sort": [
                    {
                      "date": {
                         "order": "asc"
                      }
                    }
                  ]
                }
              },
              "close": {
                "top_hits": {
                  "size": 1,
                  "sort": 
                  {
                      "date": {
                         "order": "desc"
                      }
                  }
                }
              }
...
}

結果如下:
https://ithelp.ithome.com.tw/upload/images/20201010/201296245EDtyEldaU.png

今天一口氣玩了好幾種 Aggregation,但在研究怎麼進行 Transform 成新的 Index 時卡關了。趕稿階段,沒太多探索時間,只好先放放… 最差不過就用 Python 解決嘛。 明天見啦~


上一篇
[Day25] 資料統計 & 運算 - Aggregation
下一篇
[Day27] 監視股價 - Watcher
系列文
Elastic 戰台股30

尚未有邦友留言

立即登入留言