進行量化投資最基礎的工作,就是獲取量化的基礎數據。有了基礎數據,才能對數據進行加工處理,構建量化策略,進行量化分析,回測和回溯。
基於python進行量化投資的開發,獲取數據的方式比較豐富,主要介紹以下三種,並給出相應代碼:
1、從財經網站獲取數據。pandas提供了從財經網站獲取數據的接口,該接口目前在pandas的pandas_datareader模塊中,獨立於pandas模塊,需要單獨安裝。用pip install pandas_datareader安裝該模塊。由於從專業財經網站(萬德,東方財富)獲取數據都需要付費,這裏我們主要說明從免費財經網站獲取數據的方法。下面是從yahoo財經網站獲取002214股票,指定日期每天開盤價、收盤價、最高價、最低價數據的代碼。程序中DataReader()和get_data_yahoo()都可以獲取數據。返回數據格式爲DataFrame,可以利用DataFrame的相關操作函數進行數據處理。
import numpy as np
import pandas as pd
import pandas_datareader as pdr
import pandas_datareader.data as pdr_data
start_date = '2020/03/16'
end_date = '2020/04/08'
quotes=pdr.DataReader('002214.sz','yahoo',start_date,end_date)
#quotes=pdr.get_data_yahoo('002214.sz',start_date,end_date)
quotes.head()
print(quotes)
quotes.info()
由於國內對yahoo網站限制的原因,該接口獲取數據不太穩定,有時候無法獲取需要的數據。無法獲取數據時,程序就會被掛起不能自動退出,需要在console中手工終止程序,並重啓spyder內核。
此問題,通過安裝yfinance模塊來解決,不要再用fix-yahoo-finance模塊。安裝方式爲pip install yfinance。修改後的代碼如下:
import numpy as np
import pandas as pd
import datetime
import pandas_datareader as pdr
import pandas_datareader.data as pdr_data
import yfinance as yf
start_date = datetime.datetime(2020,4,1)
end_date = datetime.datetime(2020,4,11)
yf.pdr_override()
quotes=pdr_data.get_data_yahoo('002214.sz',start_date,end_date)
quotes.head()
print(quotes)
個人感覺這個接口還是不太好用,速度比較慢,不穩定,有時候數據根本獲取不了,在實際使用中無法滿足應用需求。
2、從tushare獲取數據。tushare是免費的金融大數據開放社區,網址https://tushare.pro/。用戶在tushare網站上註冊,並修改個人信息後,獲取120積分,從網站獲取tocken後即可免費使用網站的金融數據。tushare用戶級別按積分區分,120積分的免費用戶能訪問的權限有限,只能訪問日線級別的數據,用戶可以通過增加積分來升級訪問權限。使用tushare數據,需要安裝tushare軟件包,安裝方法pip install tushare -i https://pypi.tuna.tsinghua.edu.cn/simple。使用pip install tushar會產生超時出錯,指定國內的數據源,可以順利安裝完成。如果安裝有問題,也可以下載安裝。從tushare獲取股票002214日線數據的代碼如下,返回值爲DataFrame類型。
import numpy as np
import pandas as pd
import tushare as ts
#設置tushare網站申請的tocken
ts.set_token("your tocken here")
pro = ts.pro_api()
#利用tushare獲取股票日線行情數據
df = pro.daily(ts_code='002214.SZ', start_date='20200316', end_date='20200408')
df.info()
print(df)
3、從量化平臺獲取數據。量化平臺,是量化新手入門的有力工具,不僅可以獲取數據,也可以進行策略的編輯,回測驗證。
在此以業內應用最廣泛的聚寬量化平臺(https://www.joinquant.com/)爲例說明獲取股票數據的方法。聚寬量化平臺提供的python量化包爲JQDataSDK(在聚寬量化平臺內部使用爲JQData),在使用聚寬量化平臺的數據前,要先在聚寬量化平臺註冊申請試用JQData的賬號,試用期限爲一年。然後安裝JQDataSdk,安裝命令爲pip install --user jqdatasdk。安裝完成後,就可以用註冊的用戶名和密碼使用聚寬數據了。從聚寬量化平臺獲取002214日線數據代碼如下。
import numpy as np
import pandas as pd
from jqdatasdk import *
auth('###########','******') #身份認證
start_date = '2020-3-16'
end_date = '2020-4-8'
quotes = get_price('002214.XSHE',start_date,end_date,frequency='daily',skip_paused='true',fq='pre')
print(quotes)
4、數據展示。上面總結了常用的進行數據獲取的三種常用方法,順帶說一下獲取數據的圖形化展示,只有把數據圖形化展示出來,我們才能看到直觀的效果。對於DataFrame類型數據,可以使用print語句,直接將結果打印出來,這在上面三種數據獲取方法中已經使用過。進行圖形化展示,要使用python的matplotlib模塊,matplotlib庫中有單獨的finance模塊進行金融數據的展示,該模塊現在已經獨立出來,名稱爲mpl_finance模塊。可以在anaconda中使用pip install mpl_finance進行安裝,安裝後用import mpl_finance使用。從聚寬平臺獲取數據,並繪製日K線圖的代碼如下:
import datetime
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt ## 導入畫圖模塊
from matplotlib.pylab import date2num ## 導入日期到數值一一對應的轉換工具
from dateutil.parser import parse ## 導入轉換到指定格式日期的工具
import mpl_finance as mpf ## 導入 mpl_finance 模塊
from jqdatasdk import * ## 導入jqdata數據庫
plt.rcParams['font.family'] = 'SimHei' ## 設置字體
fig, ax = plt.subplots() ## 創建圖片和座標軸
fig.subplots_adjust(bottom=0.2) ## 調整底部距離
auth('###########','******') ##聚寬平臺進行身份認證
start_date = datetime.datetime(2020,3,16)
end_date = datetime.datetime(2020,4,11)
quotes = get_price('002214.XSHE',start_date,end_date,frequency='daily',skip_paused='true',fq='pre')
print(quotes)
#繪製K線圖
mpf.candlestick2_ochl(ax,quotes['open'],quotes['close'],quotes['high'],quotes['low'],width=1.0,colorup='r',colordown='green',alpha=1.0)
plt.show()
注意返回值得列名是大小寫敏感的,quotes['open']寫成quotes['Open']會報錯。
從tushare獲取數據後,數據是按照從最近日期到最早日期倒序排列的,所以如果要繪製K線圖,需要將數據順序顛倒後再繪製K線圖,要不然繪製出來的K線圖是反的。將數據順序顛倒過來可以採用下面的兩種方式之一:
df = pro.daily(ts_code='002214.SZ', start_date='20200316', end_date='20200409')
#將數據按照日期從前往後排列
df=df.reindex(index=df.index[::-1]) #使用reindex方法
print(df)
或者
df = pro.daily(ts_code='002214.SZ', start_date='20200316', end_date='20200409')
#將數據按照日期從前往後排列
df=df.iloc[::-1] #使用iloc方法
print(df)