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