Python量化交易實戰:獲取股票數據并做分析處理
量化交易(也稱自動化交易)是一種應用數學模型幫助投資者進行判斷,并且根據計算機程序發送的指令進行交易的投資方式,它極大地減少了投資者情緒波動的影響。量化交易的主要優勢如下:
- 快速檢測
- 客觀、理性
- 自動化
量化交易的核心是篩選策略,策略也是依靠數學或物理模型來創造,把數學語言變成計算機語言。量化交易的流程是從數據的獲取到數據的分析、處理。
數據獲取
數據分析工作的第一步就是獲取數據,也就是數據采集。獲取數據的方式有很多,一般來講, 數據來源主要分為兩大類:外部來源(外部購買、網絡爬取、免費開源數據等)和內部來源 (自己企業銷售數據、財務數據等)。
因為我們不生產數據,所以只能從外部獲取數據。其獲取途徑是第三方開源庫tushare。
使用 tushare 獲取歷史股票數據
tushare 是一個免費、開源的Python 財經數據接口包。其主要實現對股票等金融數據從數據采集、清洗加工到數據存儲的過程,能夠為金融分析人員提供快速、整潔和多樣的便于分析的數據,以減輕他們在數據獲取方面的工作量。
安裝 tushare 庫,在 Jupter Notebook 下輸入以下命令:
%pip install tushare
重啟kernel,然后輸入以下命令。
import tushare
print("tushare版本號{}".format(tushare.__version__))
tushare版本號1.2.85
獲取個股歷史交易數據(包括均線數據),用戶可以通過參數設置獲取日K線、周K線、月K線,以及5分鐘、15 分鐘、30 分鐘和 60分鐘K線數據。本接口只能獲取近3年的日線數據,適合搭配均線數據進行選股和分析。Python 代碼如下:
import tushare as ts
ts.get_hist_data('000001') #一次性獲取全部日k線數據
'''
參數說明:
code:股票代碼,即6位數字代碼,或者指數代碼(sh=上證指數 sz=深圳成指 hs300=滬深300指數 sz50=上證50 zxb=中小板 cyb=創業板)
start:開始日期,格式YYYY-MM-DD
end:結束日期,格式YYYY-MM-DD
ktype:數據類型,D=日k線 W=周 M=月 5=5分鐘 15=15分鐘 30=30分鐘 60=60分鐘,默認為D
retry_count:當網絡異常后重試次數,默認為3
pause:重試時停頓秒數,默認為0
例如:
ts.get_hist_data('000001', ktype='W') #獲取周k線數據
ts.get_hist_data('000001', ktype='M') #獲取月k線數據
ts.get_hist_data('000001', ktype='5') #獲取5分鐘k線數據
ts.get_hist_data('000001', ktype='15') #獲取15分鐘k線數據
ts.get_hist_data('000001', ktype='30') #獲取30分鐘k線數據
ts.get_hist_data('000001', ktype='60') #獲取60分鐘k線數據
ts.get_hist_data('sh')#獲取上證指數k線數據
ts.get_hist_data('sz')#獲取深圳成指k線數據
ts.get_hist_data('hs300')#獲取滬深300指數k線數據
ts.get_hist_data('000001',start='2021-01-01',end='2021-03-20') #獲取”000001”從2021-01-01到2021-03-20的k線數據
'''
返回值說明如下。
- date: 日期;
- open:開盤價;
- high:最高價;
- close:收盤價;
- low:最低價;
- volume:成交量;
- price_ change:價格變動;
- pchange:漲跌幅;
- mas:5日均價;
- ma10:10 日均價;
- ma20:20日均價;
- v_mas:5日均量;
- v_ma10: 10日均量;
- v_ma20:20日均量;
turnover:換手率(注:指數無此項)。
使用 tushare 獲取所有股票即時數據
個股歷史交易數據屬于延遲數據。面對即時變動的價格數據,我們可以使用更加便捷的當日實時行情,以便在Python 量化中快速把握行情,選擇出當目符合條件的優秀股票。
下面使用第三方庫 tushare 中的 get_today_all() 兩數獲取所有股票的即時數據(如果是節假日,即為上一交易日)。代碼如下:
import tushare as ts
ts.get_today_all()
數據的獲取是數據研究的根本。一個快速、準確而穩定的 API會極大縮短個人獲取數據的時間,從而將研究者的精力更多地投入數據處理與建模中。tushare 庫也是筆者獲取數據的主要方式之它為量化工作提供了穩定而強大的數據來源,從而使數據的采集簡單地使用一行代碼就可以實現。
數據預處理
無論是量化策略還是單純的機器學習項目,數據預處理都是非常重要的一環。從量化學習的視角來看,數據預處理主要包括數據清洗、排序、缺失值或異常值處理、統計量分析、相關性分析和主成分分析(PCA)等。
因為先前本書采集的都是規整股票數據,因此本章要介紹的數據預處理就是預先剔除掉不符合條件的股票數據,然后對剩余股票進行優化篩選。本章主要使用的是 Pandas 庫,讀者應該著重理解篩選思路。
清洗掉 ST 股票
ST 股票通常表示對財務狀況或其他狀況出現異常的上市公司股票,對其交易要進行特別處理(Special Treatment)。由于“特別處理”,在簡稱前冠以 ST,因此這類股票稱為 ST 股。
哪支股票的名稱前加上 ST,就是給市場一個警示,該股票存在投資風險,起警告作用,但這種股票風險大,收益也大,如果加上*ST,就表示該股票有退市風險,要警惕的意思,具體就是在 2021年4 月左右,如果公司向證監會交的財務報表連續了年虧損,就有退市的風險。股票的交易規則也由報價日漲跌幅限制為漲幅 5%、跌幅 5%。
我們要回避這類“地雷股”(ST 股票),因而可以使用如下代碼來清洗掉 ST 股票。
import tushare as ts
csv_data=ts.get_today_all()
csv_data[~csv_data.name.str.contains('ST')]
我們對 csv_data 的 name 列進行操作,篩選出包含 ST 字母的行,并對整個 DataFrame 取反,進而篩選出不含 ST 股票的行。經過觀察,我們發現在運行結果中沒有 ST 股票,實現了數據的初步清洗。
清洗掉沒成交量的股票
首先要明確定義,什么是沒有成交量的股票。沒有成交量不是成交量為零,而是一支股票單位時間的成交量不活躍。成交量是反映股市上人氣聚散的一面鏡子。人氣旺盛、 買賣踴躍,成交量自然放大:相反人氣低迷、買賣不活躍,成交量必定萎縮。成交量是觀察莊家大戶動態的有效途徑。
下面開始清洗沒成交量的股票,在原來的基礎上增加代碼如下:
import tushare as ts
csv_data=ts.get_today_all()
csv_data=csv_data[~csv_data.name.str.contains('ST')]
csv_data[csv_data["volume"]>15000000]#15萬手
在以上代碼中,我們對 csv_data 的 volume 列進行操作。15 萬手是過濾掉不活躍、沒成交量的股票,主要以小盤股居多。
其運行結果為:
Index 出現了調行現象,即為去掉成交量小手 15 萬手的股票。
清洗掉成交額過小的股票
成交額是成交價格與成交數量的乘積,它是指當天已成交股票的金額總數。成交最的至少取決于市場的投資熱情。我們每天看大盤,一個重要的指標就是大 A 股成交量是否超過一萬億元,超過即為成交活躍。
篩選成交額超過 1 億元的股票,代碼如下:
import tushare as ts
csv_data=ts.get_today_all()
csv_data=csv_data[~csv_data.name.str.contains('ST')]
csv_data=csv_data[csv_data["volume"]>15000000]#15萬手
csv_data["amount"]=round(csv_data["amount"]/100000000,2)#一億,保留2位
csv_data[(csv_data["amount"]>1)]
篩選股票的數量沒有銳減,這是因為成交額-成交價格×成交量。有些股票價格低,成交量巨大,乘積剛剛超過 1億元;有些股票價格高,成交量相對小一些,乘積仍然超過1億元。同成交額,2元股票相對于 20 元與 200 元股票,其成交量相差10 倍到 100 倍之多。同成交量,有些股票成交額為 100 億元,相對于成交額僅有 1億元的股票,也有百倍之多。
用戶可以對 1億元這個參數進行調參,不過筆者不是特別支持。因為將成交額變大即是對大盤股產生偏重,而前面成交量的篩選也己經對大盤股的成交量進行了偏重篩選,這樣雙重篩選下來,就會全部變成大盤股,數據偏置嚴重,沒有合理性。預處理的思想也是先將數據進行簡單的篩選。筆者認為后期的策略相對于這里的調參更為重要,策略是日后交易的核心。
清洗掉換手率低的股票
換手率=某一段時期內的成交量/流通總股數×100% 。一般情況下,大多數股票每日換手率在1%~2.5%之間(不包括初上市的股票)。70%股票的換手率基本在 3%以下,3%就成為一種分界。
當一支股票的換手率在 3%~7%之間時,該股進入相對活躍狀態。當換手率在 7%~10%之間時,則為強勢股的出現,股價處于高度活躍中。
篩選換手率超過3的股票,代碼如下:
import tushare as ts
csv_data=ts.get_today_all()
csv_data=csv_data[~csv_data.name.str.contains('ST')]
csv_data=csv_data[csv_data["volume"]>15000000]#15萬手
csv_data["amount"]=round(csv_data["amount"]/100000000,2)#一億,保留2位
csv_data=csv_data[(csv_data["amount"]>1)]
csv_data["liutongliang"]=csv_data["nmc"]/csv_data["trade"]#增加流通盤的列
csv_data["turnoverratio"]=round(csv_data["turnoverratio"],2)#換手率保留2位
csv_data[csv_data["turnoverratio"]>3]
篩選股票的數量減半。換手率低于 3%當然也有不錯的股票,但是根據正態分布,我們不選取小概率事件。選擇換手率較好的股票,意味著該文股票的交投越活躍,人們購買該支股票的意愿越高,該股票屬于熱門股。
換手率商一般意味股票流通性好,進出市場比較容易,不會出現想買買不到、想賣賣不出的現象,具有我較強的變現能力。然而值得注意的是,換手率較高的股票,往往也是短線資金追逐的對象,投機性較強,股價起伏較大,風險也相對較大。
將換手率降序排列并保存數據
換手率是最重要的一個指標,所以將篩選出來的股票換手率進行降序排列并保存,以備日后取證與研究。
將序排列用 sort_values() 兩數,保存用 to_csv() 函數。這兩個函數都很常用,也比較簡單。代碼如下:
import tushare as ts
def today_data():
csv_data=ts.get_today_all()
csv_data=csv_data[~csv_data.name.str.contains('ST')]
csv_data=csv_data[csv_data["volume"]>15000000]#15萬手
csv_data["amount"]=round(csv_data["amount"]/100000000,2)#一億,保留2位
csv_data=csv_data[(csv_data["amount"]>1)]
csv_data["liutongliang"]=csv_data["nmc"]/csv_data["trade"]#增加流通盤的列
csv_data["turnoverratio"]=round(csv_data["turnoverratio"],2)#換手率保留2位
csv_data=csv_data[csv_data["turnoverratio"]>3]
csv_data=csv_data.sort_values(by="turnoverratio", ascending=False)
return csv_data
經過一系列的數據清洗與篩選,選擇出符合要求的股票數據并保存到 Jupter Notebook 中。我們將上述代碼進行函數化處理,并命名為 get_data.py。
以后,只要運行如下代碼,就會將得到的 csv_data 顯示出來:
import get_data
get_data.today_data()
模塊化后,將去掉大量重復代碼,重加專注一個功能,也會增強代碼的可讀性。
本文摘編自《Python量化交易實戰》,經出版方授權發布。(ISBN:9787522602820)