Python 時間序列實做!

之前我們介紹了很多爬蟲,可以爬每天、每月、每季的資料,今天就是要交爬完了之後要怎麼運用。這篇文章會教如何將爬下來的資料整理成 time series (時間序列)

thumbnail 2

每日爬蟲

首先,我們將之前一篇:超簡單台股每日爬蟲教學 所分享的程式碼變成以下的function,方便我們多次呼叫,才能爬每一天的股價。

每日股價爬蟲

import requests
from io import StringIO
import pandas as pd
import numpy as np

def crawl_price(date):
    r = requests.post('http://www.twse.com.tw/exchangeReport/MI_INDEX?response=csv&date=' + str(date).split(' ')[0].replace('-','') + '&type=ALL')
    ret = pd.read_csv(StringIO("\n".join([i.translate({ord(c): None for c in ' '}) 
                                        for i in r.text.split('\n') 
                                        if len(i.split('",')) == 17 and i[0] != '='])), header=0)
    ret = ret.set_index('證券代號')
    ret['成交金額'] = ret['成交金額'].str.replace(',','')
    ret['成交股數'] = ret['成交股數'].str.replace(',','')
    return ret

就跟之前是一樣的,只是被包成 function ,它的 input 是日期,output 是 dataframe,寫程式最重要的就是瞭解 input 跟 output 的型態,就會比較簡單了!

呼叫每日爬蟲,連續爬 n 天

接下來我們就來利用這個 function 幫我們爬最近9天的資料,並將數據存在 data 這個 variable 中:

一次爬 n_days 天的股價

import datetime
import time

data = {}
n_days = 9
date = datetime.datetime.now()
fail_count = 0
allow_continuous_fail_count = 5
while len(data) < n_days:

    print('parsing', date)
    # 使用 crawPrice 爬資料
    try:
        # 抓資料
        data[date.date()] = crawl_price(date)
        print('success!')
        fail_count = 0
    except:
        # 假日爬不到
        print('fail! check the date is holiday')
        fail_count += 1
        if fail_count == allow_continuous_fail_count:
            raise
            break
    
    # 減一天
    date -= datetime.timedelta(days=1)
    time.sleep(10)

想要增加天數,只要調整 n_days 這個參數就行了!
一切都順利的話,會顯示成以下這樣:

everyday

大部分的天數都是 success 代表成功讀取資料,但是每間隔5天就會顯示兩次 fail,代表那可能是假日,然而不能保證就是了,也可能是你的網路斷掉XD,或是 code 有bug,就要單獨做測試,至少在我的電腦裡,它抓的滿好的。

整理 data 轉成 收盤價 time series

接下來我們來看一下得到了什麼:

data

我們像上圖一樣,只拿取 “2019-06-05” 號的股價,會像上面這樣,變換不同的日期,可以得到不同的表。但這並不是我們想要的,我們想要有 time series,也就是看到某個欄位隨時間變動的圖表,於是我們做以下的轉換:

close = pd.DataFrame({k:d['收盤價'] for k,d in data.items()}).transpose()
close.index = pd.to_datetime(close.index)
close

在上面的程式中,現在我們只拿所有股票的 收盤價,並建構 close 這個 dataframe,這個 dataframe,假如你還不知道什麼是 dataframe,或對 dataframe 還不熟,可以參考連結學習一下。

輸入後會看到以下成品:

clean

現在整張表都只剩 收盤價 了,而且還是按照日期排列,超讚的!我也覺得很開心,竟然兩行就處理完,可見pandas真的很厲害!

時間序列還有非常多功用!接下來我們就來實做一百種指標吧!

FinLab - 韓承佑

嗨大家好,我是韓承佑,FinLab創辦人,畢業於巴黎薩克雷大學資工博士,目前擔任臺灣量化交易協會 學術顧問、台北商業大學 創新育成中心 創業技術顧問與上市科技公司 量化交易顧問。當初,我喜歡寫程式、無意間因為軟體比賽接觸Fintech,從此開始了財經跟程式的學習之路。我們成立 FinLab 量化投資部落格,用自己研發的軟體,對台灣股市做大量快速的實驗。希望可以在量化投資的路上,當大家的「武器製造商」!