量化投資 AI for Trading 1: 獲取市場資料

Chenyu Tsai
UXAI
Published in
7 min readNov 26, 2021

什麼是 Quant?

華爾街日報記者 Scott Patterson 在他的書 The Quants 中說「Those searching for the truth, the truth being the universal underlying hidden dynamics in the market.」

Quants 會將科學方法運用在金融上,建立可運算的模型來做為金融工具,或是在市場上運用。 Quants 在現今的金融產業相當活躍,像是量化對沖基金 (quantitative hedge fund)、一般商業銀行、自營商、資產管理公司和數據供應商等等。

不過我們的目標不一定要放在在前述的機構工作,從只是想理財、又會寫一點程式為出發點,我們可以把目標放在如何透過量化分析的方法,來做出數據驅動 (data-driven) 的投資決策。所以我們會假設大家對金融市場和程式語言 (使用 python) 有初步的了解,不會從零開始慢慢介紹金融市場的知識和如何撰寫程式碼。

另外我們是利用量化分析的方法來對我們的預期報酬、風險等有更好的事前認知,和分析我們投資組合表現如何,要進行什麼樣的調整等,買賣的行為都還是要靠自己來做,不會涉及自動化程式交易、高頻交易。

程式碼範例 (Kaggle 平台):

https://www.kaggle.com/chenyutsai/quant-invest-01

獲得市場資料

要進行量化分析,最基本的要素就是資料,在台股使用 python 來撈資料的話我們推薦兩個方式,一個是台灣在地的團隊 FinMind,以完整度來說,提供台股資料為主,且在免費範圍可取得的資料就可以做很好的分析,簡單好用;另一個是 Yahoo Finance,基本上是提供全球的股市,個人只有使用台股和美股,資料也比 FinMind 來得更全面一些,可以依照自己的喜好來選擇工具。

FinMind 的官方文件有非常詳細的使用方法了,可以直接到官方文件上去查詢對應的查詢方法。以下簡單列一下如何用 yahoo finance 查詢股價 (ipynb):

!pip install yfinanceimport yfinance as yfdef get_info_on_stock(ticker):    stock = yf.Ticker(ticker)
# 拿上市至今的收盤價
hist_all = stock.history(period="max")["Close"]
# 拿近 30 天的所有資料
hist_30 = stock.history(period='30d')
return hist_allget_info_on_stock('2330.TW')

yfinance 的其他詳細使用方式在這裡,上述兩個都是可以免費取得資料的管道,難免會遇到一些資料缺失的問題,在分析上的時候需要額外注意一下,除非使用的是來自收費的數據供應商,才會有比較詳盡且準確率較高的資料。

假設我們今天想比較兩家不同公司之間的股價,可以用稍微複雜一點的方式來處理,一樣先取得資料:

# 選定我們要比較的公司
track_list = ['2330.TW', '2303.TW']
def get_info_on_stocks(track_list):

df = pd.DataFrame()
for stock in track_list:
stock_info = yf.Ticker(stock)
# 拿近 10 天的資料
hist = stock_info.history(period="10d")
# 做一些簡單的處理後把 dataframe 接起來
hist['Stock_id'] = stock
hist['Date'] = hist.index
hist = hist[['Date', 'Stock_id', 'Open', 'High', 'Low', 'Close', 'Volume', 'Dividends', "Stock Splits"]]
df = pd.concat([df,hist])
return df.set_index([pd.Index([i for i in range(len(df))])]).round(1)df = get_info_on_stocks(track_list)

接下來我們可以做一些簡單的計算,利用 pandas 內建的函數來看兩者資訊的平均 (mean):

df.groupby('Stock_id').mean()

前面的圖可以看到我們是將同一個時間的兩個公司資訊堆疊起來,接下來我們可以試著用另一種表示方式來做比較:

open_prices = df.pivot(index='Date', columns='Stock_id', values='Open')high_prices = df.pivot(index='Date', columns='Stock_id', values='High')low_prices = df.pivot(index='Date', columns='Stock_id', values='Low')close_prices = df.pivot(index='Date', columns='Stock_id', values='Close')volume = df.pivot(index='Date', columns='Stock_id', values='Volume')
close_prices

這樣我們就可以用更簡單的方式來比較兩者的資料:

close_prices.mean()

重新採樣 (Resample)

有時候我們會需要將資料用不同週期的角度來檢視,例如每月的變化,或是每 5 天的變化。首先我們先建立一串由「日期」「Close Price」構成的資料。

dates = pd.date_range('2021/12/23', periods=10, freq='D')
close_prices = np.arange(len(dates))
close = pd.Series(close_prices, dates)
close.resample('5D').first()

output:

2021-12-23    0
2021-12-28 5
Freq: 5D, dtype: int64

除了利用 "D" 來做為日數採樣外,也能夠使用 "W" 來以週做為採樣週期,使用 “M” 來以月做為採樣週期,使用 "Q" 來以季做為採樣週期等

pd.DataFrame({
'days': close,
'5_days': close.resample('5D').mean(),
'weeks': close.resample('W').first()})

output:

了解 resample 的規則後我們就可以利用它來套用一些量化分析相關的分析方式,如 OHLC:

close.resample(‘W’).ohlc()

output:

拿來使用在我們先前抓下來的交易資料

df = get_info_on_stock('2330.TW')
df.Close.resample('W').ohlc()

output:

--

--