- 量化投資:交易模型開(kāi)發(fā)與數(shù)據(jù)挖掘
- 韓燾
- 1204字
- 2020-04-03 12:57:02
3.1 選擇回測(cè)平臺(tái)的技巧
近年來(lái)Python在我國(guó)量化領(lǐng)域非常流行,同時(shí)也涌現(xiàn)出了很多做量化平臺(tái)的公司,他們所提供的量化平臺(tái)基本都包含回測(cè)功能。不過(guò)從一個(gè)量化分析的過(guò)程來(lái)講,只有回測(cè)功能是不夠的,還需要有底層數(shù)據(jù)、量化因子、因子生產(chǎn)平臺(tái)、績(jī)效評(píng)價(jià)功能、策略優(yōu)化器等。對(duì)于自建平臺(tái)的機(jī)構(gòu)或個(gè)人愛(ài)好者,只需要接入外部數(shù)據(jù)即可;而對(duì)于需要使用專業(yè)而全面的量化分析工具的人們,就要對(duì)各類平臺(tái)認(rèn)真考慮,從而選擇適合自己的量化平臺(tái)。
在此列舉一些量化平臺(tái),也是筆者這幾年在量化分析中了解到的一些平臺(tái)名稱,如優(yōu)礦(通聯(lián)數(shù)據(jù))、聚寬、米筐、問(wèn)財(cái)、果仁和國(guó)信TradeStation。
另外對(duì)于自建平臺(tái)的數(shù)據(jù)使用,在此也列舉了一些數(shù)據(jù)庫(kù)廠商,僅供參考,如表3-1所示。
表3-1

3.1.1 根據(jù)個(gè)人特點(diǎn)選擇回測(cè)平臺(tái)
投資者除了選擇回測(cè)平臺(tái),還需要知道量化投資策略只有建立在有一定數(shù)量的金融數(shù)據(jù)基礎(chǔ)上才能很好地運(yùn)行。由于每位交易者的側(cè)重點(diǎn)不同,所以其需求也各不相同。
常見(jiàn)的原始數(shù)據(jù)需求,如日期、開(kāi)/收盤價(jià)、最高/最低價(jià)、交易量、交易金額、財(cái)務(wù)報(bào)表、業(yè)績(jī)預(yù)告、業(yè)績(jī)快報(bào)、IPO、配股、分紅、拆股和股改等信息屬于傳統(tǒng)的結(jié)構(gòu)化投資數(shù)據(jù)。
一些個(gè)人需要的非原始數(shù)據(jù),如社交媒體數(shù)據(jù)、新聞媒體數(shù)據(jù)、渠道公告數(shù)據(jù)、電商數(shù)據(jù)等屬于非傳統(tǒng)的結(jié)構(gòu)化數(shù)據(jù)。
無(wú)論哪種結(jié)構(gòu)化數(shù)據(jù),只有經(jīng)過(guò)不斷挖掘、優(yōu)化、組合、創(chuàng)新并不斷回測(cè),才有可能在實(shí)盤量化投資交易中盈利。
通聯(lián)數(shù)據(jù)所提供的優(yōu)礦量化平臺(tái),作為國(guó)內(nèi)最早推出的量化分析工具,已經(jīng)得到了各種金融機(jī)構(gòu)的認(rèn)可,如券商、公募基金及個(gè)人愛(ài)好者等。優(yōu)礦支持調(diào)用全量底層數(shù)據(jù)、400+量化因子、風(fēng)險(xiǎn)模型等。本章主要介紹數(shù)據(jù)的提取及回測(cè)方法。
3.1.2 回測(cè)平臺(tái)的使用方法與技巧
用戶需要在回測(cè)平臺(tái)進(jìn)行注冊(cè)才能使用,步驟如下。
首先,登錄優(yōu)礦官網(wǎng)免費(fèi)注冊(cè)一個(gè)賬號(hào),如圖3-1所示。

圖3-1
其次,輸入手機(jī)號(hào)、驗(yàn)證碼、密碼后,單擊“注冊(cè)優(yōu)礦”按鈕,如圖3-2所示。

圖3-2
注冊(cè)成功后,即可進(jìn)入主界面,單擊“研究數(shù)據(jù)”模塊,我們可以看到很多常用的金融數(shù)據(jù),而且這些金融數(shù)據(jù)絕大部分是可以免費(fèi)查看的。這些經(jīng)濟(jì)數(shù)據(jù)對(duì)學(xué)習(xí)量化投資策略能起到非常重要的作用,如圖3-3所示。

圖3-3
3.2 調(diào)用金融數(shù)據(jù)庫(kù)中的數(shù)據(jù)
下面開(kāi)始講解如何調(diào)用一些常用的金融數(shù)據(jù)。單擊“開(kāi)始研究”模塊,在左側(cè)單擊“新建”下拉按鈕,選擇“新建Notebook”選項(xiàng),即可新建一個(gè)Notebook,如圖3-4所示。

圖3-4
單擊對(duì)應(yīng)的Notebook,即可進(jìn)入Python代碼的編輯界面(見(jiàn)圖3-5)。當(dāng)打開(kāi)優(yōu)礦的Notebook時(shí),我們會(huì)發(fā)現(xiàn),它和IPython Notebook或Jupyter Notebook的翻譯環(huán)境基本都是相同的,那是因?yàn)閮?yōu)礦中的Notebook是基于IPython Notebook開(kāi)發(fā)的,所以操作基本一致,從而可以方便用戶進(jìn)行操作。

圖3-5
單擊NoteBook左上角的“代碼”下拉按鈕,將模式設(shè)置為代碼模式,即可開(kāi)始調(diào)用數(shù)據(jù),如圖3-6所示。

圖3-6
3.2.1 歷史數(shù)據(jù)庫(kù)的調(diào)取
打開(kāi)回測(cè)平臺(tái)的主界面并單擊“研究數(shù)據(jù)”模塊,尋找我們需要的數(shù)據(jù)。例如,查看滬深股票日行情數(shù)據(jù):?jiǎn)螕簟皽罟善薄薄靶星椤薄叭招星椤保缓髥螕簟皽罟善比招星椤庇覀?cè)的“展開(kāi)詳情”,如圖3-7所示。

圖3-7
我們既可以通過(guò)單擊左側(cè)的下拉按鈕來(lái)尋找數(shù)據(jù),也可以直接在上方的搜索框中輸入關(guān)鍵字進(jìn)行搜索,如圖3-8所示。

圖3-8
在“展開(kāi)詳情”中展示了參數(shù)的名稱、類型及描述信息,如圖3-9所示。例如,我們想要調(diào)取某只股票的某個(gè)時(shí)間段的行情,只要規(guī)范寫入代碼就可以了。

圖3-9
在返回值中,我們可選的行情不僅包括基本的最高價(jià)、最低價(jià)、開(kāi)盤價(jià)、收盤價(jià)、成交量、漲跌幅,還包括動(dòng)態(tài)市盈率、市凈率、VWAP等數(shù)據(jù),主要內(nèi)容如表3-2所示。
表3-2

應(yīng)將所有選擇返回的項(xiàng)傳給field參數(shù)。單擊“復(fù)制代碼”按鈕,如圖3-10所示。

圖3-10
單擊“開(kāi)始研究”模塊并新建“Notebook”,將代碼粘貼到文本框中,注意在“Notebook”內(nèi)填寫代碼,如圖3-11所示。

圖3-11
例如,調(diào)取601006大秦鐵路與000727華東科技在2019年3月1日的收盤價(jià)與總市值,返回的是一個(gè)DataFrame。在輸入股票代碼時(shí)需要注意,由于是通聯(lián)內(nèi)部自由編碼的,所以要在原股票代碼的基礎(chǔ)上加上后綴,例如,對(duì)深市股票000727華東科技加上后綴為000727.XSHE,對(duì)滬市股票601006大秦鐵路加上后綴為601006.XSHG,如圖3-12所示。

圖3-12
當(dāng)然還可以直接輸入原始股票代碼傳入ticker參數(shù),如圖3-13所示。

圖3-13
可以通過(guò)beginDate與endDate參數(shù)獲取DataAPI中某一個(gè)時(shí)間段的數(shù)據(jù),如圖3-14所示。

圖3-14
例如,調(diào)取000727華東科技與601006大秦鐵路從2019年2月26日至2019年3月1日的收盤價(jià)與總市值數(shù)據(jù)。在輸入日期時(shí)需要注意書(shū)寫格式,如圖3-15所示。

圖3-15
3.2.2 數(shù)據(jù)庫(kù)的分析方法與技巧
DataAPI支持提取多只股票在某一時(shí)間段的數(shù)據(jù),單擊“研究數(shù)據(jù)”模塊,在搜索框中輸入“因子”進(jìn)行搜索,如圖3-16所示。

圖3-16
在搜索因子后,通聯(lián)數(shù)據(jù)顯示欄顯示的“獲取多只股票歷史上某一天的因子數(shù)據(jù)”和“獲取一只股票歷史上某一時(shí)間段的因子數(shù)據(jù)”就是我們需要的DataAPI。由于數(shù)據(jù)量過(guò)大導(dǎo)致沒(méi)有因子DataAPI可以直接調(diào)用多只股票歷史上某一時(shí)間段的因子數(shù)據(jù),所以我們?cè)谑褂脙?yōu)礦的因子DataAPI時(shí),首先應(yīng)該考慮我們的需求更適合使用哪個(gè)DataAPI。
例如,“獲取一只股票歷史上某一時(shí)間段的因子數(shù)據(jù)”應(yīng)該使用如圖3-17所示的DataAPI。

圖3-17
例如,“獲取多只股票歷史上某一天的因子數(shù)據(jù)”應(yīng)該使用如圖3-18所示的DataAPI。

圖3-18
例如,“獲取多只股票歷史上某一段時(shí)間段的因子數(shù)據(jù)”則可以編寫循環(huán)語(yǔ)句來(lái)多次調(diào)用,而且應(yīng)該使用如圖3-19所示的DataAPI。

圖3-19
3.3 回測(cè)與實(shí)際業(yè)績(jī)預(yù)期偏差的調(diào)試方法
股票回測(cè)是股票模型創(chuàng)建中必不可少的一步,其過(guò)程為根據(jù)個(gè)人設(shè)定的基礎(chǔ)指標(biāo)經(jīng)過(guò)篩選、組合建立好策略模型之后,利用某一時(shí)間段的歷史行情數(shù)據(jù),嚴(yán)格按照設(shè)定的組合進(jìn)行選股,并模擬真實(shí)市場(chǎng)行情交易的規(guī)則進(jìn)行模型買入、模型賣出,得出該時(shí)間段的盈利率、最大回撤率等數(shù)據(jù)。
實(shí)際業(yè)績(jī)預(yù)期偏差是指在回測(cè)中表現(xiàn)十分優(yōu)秀的策略,一旦到實(shí)盤測(cè)試時(shí)就虧損累累。其原因在于回測(cè)中包含一定的偏差,我們要做的就是盡量篩選并將它們剔除。
交易策略一旦確定那么就需要獲取歷史數(shù)據(jù),然后根據(jù)歷史數(shù)據(jù)進(jìn)行測(cè)試。目前獲得歷史數(shù)據(jù)的方法有很多,但是根據(jù)渠道不同,歷史數(shù)據(jù)的質(zhì)量、時(shí)間間隔及深度等都不相同。交易者在選擇數(shù)據(jù)時(shí)需要關(guān)注的是歷史數(shù)據(jù)中幸存者偏差、精確度、清潔度、可用性及交易成本等方面。
在歷史數(shù)據(jù)中有些錯(cuò)誤是不容易被辨別出來(lái)的,所以需要利用數(shù)據(jù)供應(yīng)商提供的數(shù)據(jù)來(lái)進(jìn)行對(duì)比和檢查。我們需要利用一個(gè)軟件平臺(tái)來(lái)進(jìn)行回測(cè)。
例如,以優(yōu)礦來(lái)實(shí)現(xiàn),如圖3-20所示。

圖3-20
3.4 設(shè)置回測(cè)參數(shù)
3.4.1 start和end回測(cè)起止時(shí)間
策略回測(cè)的起止時(shí)間是策略的全局變量。start表示回測(cè)起始日期,end表示回測(cè)終止日期。
quartz會(huì)自動(dòng)截取start之后的第一個(gè)交易日和end之前的最后一個(gè)交易日進(jìn)行回測(cè)。
日線數(shù)據(jù)只能回測(cè)到2007年1月1日,分鐘線數(shù)據(jù)只能回測(cè)到2009年1月1日,在此之前的數(shù)據(jù)只能自行獲取。需要注意的是,在設(shè)置start和end時(shí)需要考慮max_history_window引入的提前量,例如當(dāng)max_history_window = 30時(shí),start最早僅可為2007-02-15。
時(shí)間類型包括str或datetime,注意str只支持“YYYY-MM-DD”和“YYYYMMDD”兩種格式。
不同資產(chǎn)類型支持的回測(cè)區(qū)間范圍如表3-3所示。
表3-3

示例代碼如下:
start = '2019-03-01' # 在2019年3月1日開(kāi)始回測(cè) end = '2019-03-08' # 在2019年3月8日結(jié)束回測(cè)
3.4.2 universe證券池
策略回測(cè)的證券池,即策略邏輯作用的域,下單與歷史數(shù)據(jù)獲取都只限于universe中的證券。它支持全部A股、全部可在二級(jí)市場(chǎng)交易的ETF與LOF。
有兩種獲取證券池的方式:固定的資產(chǎn)列表(靜態(tài)證券池)、DynamicUniverse(動(dòng)態(tài)證券池)。
示例代碼如下:
universe = ['000001.XSHE', '600000.XSHG'] # 靜態(tài)證券池 universe = DynamicUniverse('HS300') # 動(dòng)態(tài)證券池
1.固定的資產(chǎn)列表
靜態(tài)證券池可以指定固定的個(gè)別資產(chǎn)或資產(chǎn)列表,示例代碼如下:
universe = ['000001.XSHE', 'IFM0'] # 指定平安銀行和股指期貨為策略證券池
2.DynamicUniverse
獲取動(dòng)態(tài)證券池的示例代碼如下:
DynamicUniverse(<板塊代碼、行業(yè)或指數(shù)實(shí)例>)
在使用板塊成分股、行業(yè)成分股或指數(shù)成分股作為策略的交易對(duì)象時(shí),策略框架會(huì)根據(jù)實(shí)際情況,調(diào)整當(dāng)天股票池的內(nèi)容。
參數(shù):<板塊代碼、行業(yè)、指數(shù)實(shí)例>,即預(yù)設(shè)的板塊代碼、行業(yè)和指數(shù)實(shí)例名稱。
參數(shù)類型:str或預(yù)設(shè)的行業(yè)與指數(shù)實(shí)例。
參數(shù)用法如下。
· 預(yù)設(shè)板塊成分股:支持7個(gè)預(yù)設(shè)的指數(shù)板塊,包括’SH50’上證50、'SH180’上證180、'HS300’滬深300、'ZZ500’中證500、'CYB’創(chuàng)業(yè)板、'ZXB’中小板、'A’全A股,也支持通過(guò)DataAPI.IdxGet()函數(shù)獲取指數(shù)的secID值。滬深300指數(shù)板塊示例代碼如下:
DynamicUniverse('HS300') # 表示滬深300的字符串
· 預(yù)設(shè)行業(yè)和指數(shù)實(shí)例。在Notebook中輸入開(kāi)頭字符后會(huì)有自動(dòng)代碼提示功能,可以幫助查找具體的行業(yè)(以IndSW.開(kāi)頭)和指數(shù)(以IdxCN.開(kāi)頭)名稱。當(dāng)前使用成分股作為股票池的完整行業(yè)列表和指數(shù)列表,詳細(xì)信息請(qǐng)讀者閱讀動(dòng)態(tài)股票池支持的行業(yè)列表和動(dòng)態(tài)股票池支持的指數(shù)列表。
行業(yè)實(shí)例代碼如下:
# 行業(yè)實(shí)例,IndSW表示申萬(wàn)行業(yè),YinHangL2表示銀行二級(jí)行業(yè)分類 DynamicUniverse(IndSW.YinHangL2)
指數(shù)實(shí)例代碼如下:
# 指數(shù)實(shí)例,IdxShangZhengZongZhi表示上證綜指 DynamicUniverse(IdxCN.IdxShangZhengZongZhi)
· 也可以混合使用,示例代碼如下:
# 混合使用 DynamicUniverse('HS300', IndSW.YinHangL2, IdxCN.IdxShangZhengZongZhi)
返回動(dòng)態(tài)證券池類型的示例代碼如下:
universe = DynamicUniverse('HS300') # 使用滬深300成分股動(dòng)態(tài)證券池
支持動(dòng)態(tài)證券池和普通列表取并集,示例代碼如下:
# 包含滬深300成分股動(dòng)態(tài)證券池和平安銀行 universe = DynamicUniverse('HS300') + ['000001.XSHE']
3.apply_filter
將篩選條件作用于每個(gè)交易日的動(dòng)態(tài)證券池上,從而進(jìn)一步縮小策略標(biāo)的范圍,當(dāng)前支持使用優(yōu)礦因子庫(kù)中的所有因子對(duì)證券池進(jìn)行篩選,代碼如下。
DynamicUniverse(<板塊代碼或行業(yè)、指數(shù)實(shí)例>).apply_filter(<因子篩選條件表達(dá)式>)
參數(shù):<因子篩選條件表達(dá)式>。表達(dá)式寫法:Factor.<factor_name>.<篩選方法>。
用法:factor_name是因子名,可以通過(guò)優(yōu)礦因子庫(kù)查看所有支持篩選的因子。
優(yōu)礦因子庫(kù)目前提供了5種篩選方法,如表3-4所示。
表3-4

表達(dá)式既支持單個(gè)篩選條件,也支持多個(gè)篩選條件,最多可支持5個(gè)篩選條件。
在表達(dá)式中可以使用兩種二元運(yùn)算:交(&)表示同時(shí)滿足兩個(gè)篩選條件,并(|)表示滿足任意一個(gè)篩選條件。運(yùn)算方向?yàn)閺淖蟮接摇?/p>
當(dāng)篩選條件多于兩個(gè)時(shí),可以通過(guò)括號(hào)嵌套的方式來(lái)確定運(yùn)算順序。例如,篩選出PE值最大的100只或PB值排名為95%~100%的股票,并且RSI值大小為70~100的股票池,可使用如下表達(dá)方式:
(Factor.PE.nlarge(100) | Factor.PB.pct_range(0.95, 1)) & Factor.RSI.value _range(70, 100)
返回動(dòng)態(tài)證券池類型的示例代碼如下:
# 獲得滬深300成分股中PE值最小的100只股票列表 universe = DynamicUniverse('HS300').apply_filter(Factor.PE.nsmall(100))
3.4.3 benchmark參考基準(zhǔn)
策略參考基準(zhǔn),即量化投資策略回測(cè)結(jié)果的比較標(biāo)準(zhǔn),通過(guò)比較可以大致看出策略的好壞。策略的一些風(fēng)險(xiǎn)指標(biāo)如Alpha、beta等也要通過(guò)benchmark計(jì)算得出。
策略參考基準(zhǔn)支持如下3種賦值方式。
· 將預(yù)設(shè)板塊作為基準(zhǔn):支持5個(gè)常用指數(shù)板塊,包括’SHCI’上證綜指、'SH50’上證50、'SH180’上證180、'HS300’滬深300、'ZZ500’中證500。示例代碼如下:
benchmark = 'HS300' # 策略參考基準(zhǔn)為滬深300
· 將指數(shù)作為基準(zhǔn):當(dāng)前支持的完整的指數(shù)列表。示例代碼如下:
benchmark = '399006.ZICN' # 策略參考基準(zhǔn)為創(chuàng)業(yè)板指
· 將個(gè)股作為基準(zhǔn):當(dāng)前支持所有A股股票。示例代碼如下:
benchmark = '000001.XSHE' # 策略參考基準(zhǔn)為平安銀行
3.4.4 freq和refresh_rate策略運(yùn)行頻率
策略回測(cè),本質(zhì)上是指使用歷史行情和其他依賴數(shù)據(jù)對(duì)策略的邏輯進(jìn)行歷史回放。freq和refresh_rate共同決定了回測(cè)使用的數(shù)據(jù)和調(diào)倉(cāng)頻率。
優(yōu)礦支持日線策略和分鐘線策略兩種模式。
日線策略:每天會(huì)執(zhí)行一次handle_data。執(zhí)行時(shí)間為開(kāi)盤前,此時(shí)僅可獲得當(dāng)天的盤前信息,以及截止到前一天的行情、因子等數(shù)據(jù),不會(huì)獲得當(dāng)天的盤中行情等數(shù)據(jù)。
分鐘線策略:首先在開(kāi)盤前會(huì)執(zhí)行一次handle_data,然后在盤中的調(diào)倉(cāng)對(duì)應(yīng)時(shí)間的分鐘結(jié)束后執(zhí)行一次handle_data(不包含收盤時(shí)間)。
freq表示使用的數(shù)據(jù)為日線行情數(shù)據(jù)或分鐘線行情數(shù)據(jù)。refresh_rate表示調(diào)倉(cāng)間隔的時(shí)間,即每次觸發(fā)handle_data的間隔時(shí)間。它們的類型如下。
· freq:str。
· refresh_rate :int或(a, b)結(jié)構(gòu)。
freq和refresh_rate的用法如下。
1.日線策略
freq,取值為d,其中d表示策略中使用的數(shù)據(jù)為日線級(jí)別的數(shù)據(jù),只能進(jìn)行日線級(jí)別的調(diào)倉(cāng)。
refresh_rate有以下3種取值方式。
· 使用整數(shù)1,表示每個(gè)交易日進(jìn)行調(diào)倉(cāng)的策略,示例代碼如下:
start = '2019-01-01' # 在2019年1月1日開(kāi)始回測(cè) end = '2019-02-01' # 在2019年2月1日結(jié)束回測(cè) universe = DynamicUniverse('HS300') # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) freq = 'd' refresh_rate = 1 accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') print context.current_date
每個(gè)交易日都有調(diào)倉(cāng),下面展示了部分調(diào)倉(cāng)日期:
2019-01-03 00:00:00 2019-01-09 00:00:00 2019-01-16 00:00:00 2019-01-23 00:00:00
· 使用Weekly(1),表示每周第一個(gè)交易日進(jìn)行調(diào)倉(cāng),示例代碼如下:
start = '2019-01-01' # 在2019年1月1日開(kāi)始回測(cè) end = '2019-02-01' # 在2019年2月1日結(jié)束回測(cè) universe = DynamicUniverse('HS300') # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) freq = 'd' refresh_rate = Weekly(1) accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') print context.current_date
下面展示了每周第一個(gè)交易日的調(diào)倉(cāng)日期:
2019-01-03 00:00:00 2019-01-09 00:00:00 2019-01-16 00:00:00 2019-01-23 00:00:00
· 使用Monthly(1, -1),表示每個(gè)月第一個(gè)和最后一個(gè)交易日進(jìn)行調(diào)倉(cāng),示例代碼如下:
start = '2019-01-01' # 在2019年1月1日開(kāi)始回測(cè) end = '2019-03-01' # 在2019年3月1日結(jié)束回測(cè) universe = DynamicUniverse('HS300') # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) freq = 'd' refresh_rate = Monthly(1, -1) accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') print context.current_date
下面展示了每個(gè)月第一個(gè)和最后一個(gè)交易日調(diào)倉(cāng)的日期:
2019-01-02 00:00:00 2019-01-31 00:00:00 2019-02-01 00:00:00 2019-02-28 00:00:00 2019-03-01 00:00:00
2.分鐘線策略
freq,取值為m,其中m表示策略中使用的數(shù)據(jù)為分鐘線數(shù)據(jù),可以進(jìn)行分鐘線級(jí)別的調(diào)倉(cāng)。
refresh_rate有以下4種取值方式。
· 使用(1, 2),表示每個(gè)交易日每間隔2分鐘進(jìn)行調(diào)倉(cāng)的策略,示例代碼如下:
start = '2019-01-04' # 在2019年1月4日開(kāi)始回測(cè) end = '2019-01-04' # 在2019年1月4日結(jié)束回測(cè) universe = DynamicUniverse('HS300') # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) freq = 'm' refresh_rate = (1, 2) accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') print context.now
每個(gè)交易日的每2分鐘都有調(diào)倉(cāng),下面展示了部分調(diào)倉(cāng)時(shí)間:
2019-01-04 09:30:00 2019-01-04 09:32:00 2019-01-04 09:34:00 ... 2019-01-04 14:56:00 2019-01-04 14:58:00
· 使用(2, ['10:30', '14:30']),表示每2個(gè)交易日指定特定時(shí)間,使用分鐘線數(shù)據(jù)進(jìn)行調(diào)倉(cāng)的策略,示例代碼如下:
start = '2019-01-04' # 在2019年1月4日開(kāi)始回測(cè) end = '2019-01-10' # 在2019年1月10日結(jié)束回測(cè) universe = DynamicUniverse('HS300') # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) freq = 'm' refresh_rate = (2, ['10:30', '14:30']) accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') print context.now
下面展示了全部調(diào)倉(cāng)時(shí)間,每2個(gè)交易日,在10:30和14:30進(jìn)行調(diào)倉(cāng):
2019-01-04 10:30:00 2019-01-04 14:30:00 2019-01-06 10:30:00 2019-01-06 14:30:00 2019-01-10 10:30:00 2019-01-10 14:30:00
· 使用(Weekly(1, -1), ['10:30', '14:30']),表示每周第一個(gè)和最后一個(gè)交易日,指定特定時(shí)間,使用分鐘線數(shù)據(jù)進(jìn)行調(diào)倉(cāng)的策略,示例代碼如下:
start = '2019-01-01' # 在2019年1月1日開(kāi)始回測(cè) end = '2019-01-10' # 在2019年1月10日結(jié)束回測(cè) universe = DynamicUniverse('HS300') # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) freq = 'm' refresh_rate = (Weekly(1, -1), ['10:30', '14:30']) accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') print context.now
下面展示了全部調(diào)倉(cāng)時(shí)間,指定每周第一個(gè)和最后一個(gè)交易日,在10:30和14:30進(jìn)行調(diào)倉(cāng):
2019-01-06 10:30:00 2019-01-06 14:30:00 2019-01-09 10:30:00 2019-01-09 14:30:00
· 使用(Monthly(1), 120),表示每月第一個(gè)交易日,每隔120分鐘,使用分鐘線數(shù)據(jù)進(jìn)行調(diào)倉(cāng)的策略,示例代碼如下:
start = '2019-01-01' # 在2019年1月1日開(kāi)始回測(cè) end = '2019-03-01' # 在2019年3月1日結(jié)束回測(cè) universe = DynamicUniverse('HS300') # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) freq = 'm' refresh_rate = (Monthly(1), 120) accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') print context.now
下面展示了全部調(diào)倉(cāng)時(shí)間,表示每月第一個(gè)交易日,每隔120分鐘,使用分鐘線數(shù)據(jù)進(jìn)行調(diào)倉(cāng):
2019-01-03 09:30:00 2019-01-03 11:30:00 2019-02-03 09:30:00 2019-02-03 11:30:00 2019-03-01 09:30:00 2019-03-01 11:30:00
3.5 賬戶設(shè)置
3.5.1 accounts賬戶配置
回測(cè)框架的交易賬戶配置函數(shù),支持多個(gè)交易品種、多個(gè)交易賬戶同時(shí)進(jìn)行回測(cè),示例代碼如下:
accounts = { 'security_account': AccountConfig(account_type='security', capital_base= 10000000, position_base = {}, cost_base = {}, commission = Commission(buycost= 0.001, sellcost=0.002, unit='perValue'), slippage = Slippage(value=0.0, unit= 'perValue')) } # 股票(包含場(chǎng)內(nèi)基金)賬戶配置 accounts = { 'futures_account': AccountConfig(account_type='futures', capital_base= 10000000, commission = Commission(buycost=0.001, sellcost=0.002, unit= 'perValue'), slippage = Slippage(value=0.0, unit='perValue'), margin_rate = 0.1) } # 期貨賬戶配置 accounts = { 'otcfund_account': AccountConfig(account_type='otc_fund', capital_base= 10000000, commission = Commission(buycost=0.001, sellcost=0.002, unit= 'perValue'), slippage = Slippage(value=0.0, unit='perValue'), dividend_method = 'cash_dividend') } # 場(chǎng)外基金(不包含貨幣基金)賬戶配置
accounts賬戶配置的用法有如下3種。
· 單個(gè)賬戶配置,示例代碼如下:
start = '2018-01-01' # 回測(cè)起始時(shí)間 end = '2019-01-01' # 回測(cè)結(jié)束時(shí)間 universe = DynamicUniverse('HS300') # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) # 策略類型,'d’表示日間策略使用日線回測(cè),'m’表示日內(nèi)策略使用分鐘線回測(cè) freq = 'd' refresh_rate = 1 # 執(zhí)行handle_data的時(shí)間間隔 accounts = { 'security_account': AccountConfig(account_type='security', capital_base= 10000000, position_base = {'600000.XSHG':1000}, cost_base = {'600000.XSHG': 10.05}, commission = Commission(buycost=0.001, sellcost=0.002, unit='perValue'), slippage = Slippage(value=0.0, unit='perValue')) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('security_account')
· 多個(gè)賬戶配置,commission、slippage表示可以對(duì)多賬戶進(jìn)行全局配置,示例代碼如下:
start = '2018-01-01' # 回測(cè)起始時(shí)間 end = '2019-01-01' # 回測(cè)結(jié)束時(shí)間 universe = DynamicUniverse('HS300') + ['IFM0'] # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) # 策略類型,'d’表示日間策略使用日線回測(cè),'m’表示日內(nèi)策略使用分鐘線回測(cè) freq = 'd' refresh_rate = 1 # 執(zhí)行handle_data的時(shí)間間隔 # 對(duì)兩個(gè)賬戶進(jìn)行全局的交易費(fèi)用和滑點(diǎn)設(shè)置 commission = Commission(buycost=0.001, sellcost=0.002, unit='perValue') slippage = Slippage(value=0.0, unit='perValue') accounts = { 'security_account1': AccountConfig(account_type='security', capital_ base=10000000, position_base = {'600000.XSHG':1000}, cost_base = {'600000. XSHG':10.05}, commission = commission, slippage = slippage), 'security_account2': AccountConfig(account_type='security', capital_ base=20000000, position_base = {'600000.XSHG':2000}, cost_base = {'600000. XSHG':10.05}, commission = commission, slippage = slippage) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 account1 = context.get_account('security_account1') account2 = context.get_account('security_account2')
· 股票、期貨混合賬戶配置,示例代碼如下:
start = '2018-01-01' # 回測(cè)起始時(shí)間 end = '2019-01-01' # 回測(cè)結(jié)束時(shí)間 universe = DynamicUniverse('HS300') + ['IFM0'] # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) # 策略類型,'d’表示日間策略使用日線回測(cè),'m’表示日內(nèi)策略使用分鐘線回測(cè) freq = 'd' refresh_rate = 1 # 執(zhí)行handle_data的時(shí)間間隔 accounts = { 'security_account': AccountConfig(account_type='security', capital_ base=10000000, position_base = {'600000.XSHG':1000}, cost_base = {'600000. XSHG':10.05}, commission = Commission(buycost=0.001, sellcost=0.002, unit='perValue'), slippage = Slippage(value=0.0, unit='perValue')), 'futures_account': AccountConfig(account_type='futures', capital_base= 10000000, commission = Commission(buycost=0.001, sellcost=0.002, unit='perValue'), slippage = Slippage(value=0.0, unit='perValue'), margin_rate = 0.1) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 account1 = context.get_account('security_account') account2 = context.get_account('futures_account')
3.5.2 AccountConfig賬戶配置
對(duì)單個(gè)交易賬戶進(jìn)行配置。策略在初始化時(shí)會(huì)根據(jù)賬戶配置,需要?jiǎng)?chuàng)建對(duì)應(yīng)的交易賬戶。AccountConfig賬戶配置參數(shù)如下。
· 必選參數(shù):account_type、capital_base。
· 可選參數(shù):position_base、cost_base、commission、slippage。
· 期貨專用參數(shù):margin_rate。
· 場(chǎng)外基金專用參數(shù):dividend_method。
1.account_type
account_type表示設(shè)置交易賬戶的類型。
參數(shù)類型:str。包括4個(gè)值,即’security’表示股票和場(chǎng)內(nèi)基金、'futures’表示期貨、'otc_fund'表示場(chǎng)外基金(不含貨幣基金), 'index’表示指數(shù)。
示例代碼如下:
account_type = 'security'
2.capital_base
capital_base表示設(shè)置交易賬戶的初始資金。
參數(shù)類型:float或int。
示例代碼如下:
capital_base = 100000
3.position_base
position_base表示設(shè)置交易賬戶的初始持倉(cāng)(僅適用于配置股票賬戶)。
參數(shù)類型:dict。包括兩個(gè)值,即key為股票代碼、value為數(shù)量。
示例代碼如下:
# 初始持倉(cāng):1000股平安銀行,2000股浦發(fā)銀行 position_base = {'000001.XSHE':1000, '600000.XSHG':2000}
4.cost_base
cost_base表示設(shè)置交易賬戶的初始成本(僅適用于配置股票賬戶)。
參數(shù)類型:dict。包括兩個(gè)值,即key為股票代碼、value為成本。
示例代碼如下:
# 初始持倉(cāng)成本:平安銀行為12.30元,浦發(fā)銀行為11.50元 cost_base = {'000001.XSHE':12.30, '600000.XSHG':11.50}
5.commission
commission表示交易手續(xù)費(fèi)。
參數(shù)說(shuō)明如下。
· buycost表示買入成本。
參數(shù)類型:float。
· sellcost表示賣出成本。
參數(shù)類型:float。
· unit表示手續(xù)費(fèi)單位。
參數(shù)類型:str。
unit參數(shù)包括如下兩個(gè)值。
? perValue:按成交金額的百分比收取手續(xù)費(fèi)。
? perShare:按成交的股數(shù)收取手續(xù)費(fèi)(僅用于配置期貨賬戶)。
示例代碼如下:
# 按成交金額的百分比收取買入0.3‰,賣出2‰的費(fèi)用 commission = Commission(buycost = 0.0003, sellcost = 0.002, unit = 'perValue')
6.slippage
slippage用于設(shè)置交易滑點(diǎn)標(biāo)準(zhǔn),并處理市場(chǎng)沖擊問(wèn)題。
參數(shù)說(shuō)明如下。
· value:策略進(jìn)行交易時(shí)的滑點(diǎn)值。
參數(shù)類型:float。
· unit:計(jì)算滑點(diǎn)的方式,分為固定滑點(diǎn)和百分比滑點(diǎn)兩種計(jì)算方式。
參數(shù)類型:str。
unit參數(shù)包括如下兩個(gè)值。
? perValue:百分比滑點(diǎn)。按股價(jià)百分比進(jìn)行滑點(diǎn)調(diào)整,滑點(diǎn)設(shè)置后買入價(jià)格調(diào)整為“股價(jià)×(1+滑點(diǎn)值)”,賣出價(jià)格調(diào)整為“股價(jià)×(1-滑點(diǎn)值)”。
? perShare:固定滑點(diǎn)。按每股股價(jià)進(jìn)行滑點(diǎn)調(diào)整,最小單位是0.01,表示0.01元;滑點(diǎn)設(shè)置后買入價(jià)格調(diào)整為“股價(jià)+滑點(diǎn)值”,賣出價(jià)格調(diào)整為“股價(jià)-滑點(diǎn)值”。
示例代碼如下:
# 將滑點(diǎn)設(shè)置成百分比滑點(diǎn)0.001 slippage = Slippage(value=0.001, unit='perValue')
7.margin_rate
margin_rate用于設(shè)置保證金率,僅用于期貨策略。
參數(shù)類型:float或dict。支持如下兩種設(shè)置方法。
全局設(shè)置方法:為所有品種設(shè)置同一個(gè)保證金率(通常在只回測(cè)一個(gè)品種的時(shí)候,這種方法比較常見(jiàn))。
根據(jù)品種設(shè)置:為某個(gè)或某些品種設(shè)置特定的保證金率。
示例代碼如下:
margin_rate = 0.1 margin_rate = {'IF': 0.16, 'RB': 0.1}
8.dividend_method
dividend_method用于設(shè)置基金分紅方式,僅用于場(chǎng)外基金策略。
參數(shù)類型:str。包括兩個(gè)值,即’cash_dividend’表示現(xiàn)金分紅,'reinvestment’表示紅利再投。
示例代碼如下:
dividend_method='cash_dividend'
3.6 策略基本方法
1.initialize策略初始化函數(shù)
策略初始化函數(shù)示例代碼如下:
def initialize(context)
策略初始化函數(shù)用于配置策略運(yùn)行環(huán)境context對(duì)象的屬性或自定義各種變量。在策略運(yùn)行周期中只執(zhí)行一次。可以通過(guò)給context添加新的屬性,從而自定義各種變量。
context在策略運(yùn)行(回測(cè)或模擬交易)啟動(dòng)時(shí)被創(chuàng)建,持續(xù)整個(gè)策略的生命周期。策略在運(yùn)行時(shí)可以讀取context的已有系統(tǒng)屬性或自定義屬性。
2.handle_data策略運(yùn)行邏輯
策略運(yùn)行邏輯的示例代碼如下:
def handle_data(context)
3.post_trading_day盤后處理函數(shù)
在每天運(yùn)行策略結(jié)束時(shí),可以使用post_trading_day函數(shù)進(jìn)行盤后操作,比如進(jìn)行當(dāng)日交易總結(jié)、預(yù)計(jì)算因子值等操作。
post_trading_day()函數(shù)的參數(shù)為context,示例代碼如下:
start = '2019-01-01' # 回測(cè)起始時(shí)間 end = '2019-01-05' # 回測(cè)結(jié)束時(shí)間 universe = ['600000.XSHG'] # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) # 策略類型,'d’表示日間策略使用日線回測(cè),'m’表示日內(nèi)策略使用分鐘線回測(cè) freq = 'd' refresh_rate = 1 # 執(zhí)行handle_data的時(shí)間間隔 accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000, position_base = {'600000.XSHG':1000}, cost_base = {'600000.XSHG': 10.05}) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') current_universe = context.get_universe('stock', exclude_halt=True) for stk in current_universe: stock_account.order_to(stk, 100) def post_trading_day(context): print context.now
3.7 策略運(yùn)行環(huán)境
context表示策略運(yùn)行環(huán)境,包含運(yùn)行時(shí)間、行情數(shù)據(jù)等內(nèi)容,還可以用于存儲(chǔ)策略中生成的臨時(shí)數(shù)據(jù)。策略框架會(huì)在啟動(dòng)時(shí)創(chuàng)建context的對(duì)象實(shí)例,并以參數(shù)形式傳遞給initialize(context)和handle_data(context),用于策略調(diào)度。
在回測(cè)時(shí),context包含運(yùn)行時(shí)間、回測(cè)參數(shù)、回測(cè)運(yùn)行時(shí)數(shù)據(jù)等。在模擬交易時(shí),包含運(yùn)行時(shí)間、模擬交易參數(shù)、實(shí)時(shí)運(yùn)行數(shù)據(jù)等。
3.7.1 now
now表示獲取策略運(yùn)行時(shí)的當(dāng)前時(shí)刻,示例代碼如下:
context.now
返回類型:datetime。
用法:只能在handle_data方法中使用,并且不允許修改。
例如,獲取分鐘線策略運(yùn)行時(shí)的當(dāng)前時(shí)刻,代碼如下:
start = '2019-01-04' # 在2019年1月4日開(kāi)始回測(cè) end = '2019-01-04' # 在2019年1月4日結(jié)束回測(cè) freq = 'm' refresh_rate = (1, 2) accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') print context.now
每個(gè)交易日的每2分鐘都有調(diào)倉(cāng),下面展示了部分調(diào)倉(cāng)時(shí)間:
2019-01-04 09:30:00 2019-01-04 09:32:00 2019-01-04 09:34:00 ... 2019-01-04 14:56:00 2019-01-04 14:58:00
3.7.2 current_date
current_date表示獲取策略運(yùn)行的當(dāng)前日期,示例代碼如下:
context.current_date
context.current_date和context.now的區(qū)別為:當(dāng)進(jìn)行日線頻率回測(cè)時(shí),兩者結(jié)果完全一致,當(dāng)進(jìn)行分鐘線頻率回測(cè)時(shí),context.now包含小時(shí)、分鐘等一個(gè)交易日內(nèi)的時(shí)間信息,而context.current_date不包含。
返回類型:datetime。
用法:只能在handle_data方法中使用,并且不允許修改。
例如,獲取策略運(yùn)行時(shí)的當(dāng)前日期,代碼如下:
start = '2019-01-01' # 在2019年1月1日開(kāi)始回測(cè) end = '2019-02-01' # 在2019年2月1日結(jié)束回測(cè) freq = 'd' refresh_rate = 1 accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') print context.current_date
下面展示了部分調(diào)倉(cāng)日期:
2019-01-03 00:00:00 2019-01-04 00:00:00 2019-01-05 00:00:00 ... 2019-01-25 00:00:00 2019-01-26 00:00:00
3.7.3 previous_date
previous_date表示獲取當(dāng)前回測(cè)日期的前一交易日數(shù)據(jù),示例代碼如下:
context.previous_date
返回類型:datetime。
用法:只能在handle_data方法中使用,并且不允許修改。同current_date一致。
3.7.4 current_minute
current_minute表示獲取當(dāng)前運(yùn)行時(shí)的分鐘值,如果在分鐘線策略中使用,建議用context.now替換。示例代碼如下:
context.current_minute
返回類型:str,如10:00。
用法:只能在handle_data方法中使用,并且不允許修改。
輸出結(jié)果的格式如下:
09:30
3.7.5 current_price
current_price表示獲取當(dāng)前的參考價(jià)格,即最后成交價(jià)。在開(kāi)盤前運(yùn)行,獲得的是前一天的收盤價(jià);在盤中運(yùn)行,獲得的是最后一次的成交價(jià)。示例代碼如下:
context.current_price(symbol)
參數(shù)為symbol,即想要獲取的價(jià)格的證券,參數(shù)需要在之前定義的universe中存在。
參數(shù)類型:str。
返回類型:float,表示最后一刻的價(jià)格。
例如,獲取平安銀行前一天的收盤價(jià),代碼如下:
start = '2019-01-01' # 回測(cè)起始時(shí)間 end = '2019-01-04' # 回測(cè)結(jié)束時(shí)間 universe = ['000001.XSHE'] # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) # 策略類型,'d’表示日間策略使用日線回測(cè),'m’表示日內(nèi)策略使用分鐘線回測(cè) freq = 'd' refresh_rate = 1 # 執(zhí)行handle_data的時(shí)間間隔 accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') print context.current_price('000001.XSHE')
輸出結(jié)果如下:
9.38 9.19 9.28
3.7.6 get_account
get_account表示獲取交易賬戶。例如,獲取賬戶名稱為account_name的交易賬戶,代碼如下:
context.get_account(account_name)
參數(shù):account_name,表示策略初始化時(shí)設(shè)置的賬戶名稱。
參數(shù)類型:str。
返回交易賬戶對(duì)象。
示例代碼如下:
start = '2019-01-01' # 回測(cè)起始時(shí)間 end = '2019-01-04' # 回測(cè)結(jié)束時(shí)間 universe = ['000001.XSHE'] # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) # 策略類型,'d’表示日間策略使用日線回測(cè),'m’表示日內(nèi)策略使用分鐘線回測(cè) freq = 'd' refresh_rate = 1 # 執(zhí)行handle_data的時(shí)間間隔 accounts = { 'account_name': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('account_name')
3.7.7 get_universe
get_universe表示獲取當(dāng)前交易日的證券池,是策略初始化參數(shù)中universe的子集。在這種配置情況下,context.get_universe()僅體現(xiàn)資產(chǎn)的上市狀態(tài),只要資產(chǎn)在策略運(yùn)行當(dāng)天處于上市狀態(tài),就可通過(guò)context.get_universe()獲取當(dāng)前交易日的證券池。支持多種資產(chǎn)類型。示例代碼如下:
context.get_universe(asset_type, exclude_halt=False)
參數(shù)說(shuō)明如下。
· asset_type,表示資產(chǎn)類型。
參數(shù)類型:str。
參數(shù)值包括’stock’表示股票列表、'index’表示指數(shù)成分股列表、'exchange_fund’表示場(chǎng)內(nèi)基金列表、'otc_fund’表示場(chǎng)外基金列表、'futures’表示期貨合約列表、'base_futures’表示普通期貨合約列表、'continuous_futures’表示連續(xù)期貨合約列表。
· exclude_halt,表示去除資產(chǎn)池中的停牌股票,僅適用于股票,默認(rèn)值為False。
參數(shù)類型:布爾型。
返回類型:list,符合篩選條件的當(dāng)天上市狀態(tài)的證券池,返回的列表中可能有部分資產(chǎn)處于停盤等不可交易狀態(tài)。
例如,獲取上證50股票剔除停牌股票后的股票池,代碼如下:
start = '2019-01-01' # 回測(cè)起始時(shí)間 end = '2019-01-03' # 回測(cè)結(jié)束時(shí)間 universe = DynamicUniverse('SH50') # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) # 策略類型,'d’表示日間策略使用日線回測(cè),'m’表示日內(nèi)策略使用分鐘線回測(cè) freq = 'd' refresh_rate = 1 # 執(zhí)行handle_data的時(shí)間間隔 accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 current_universe = context.get_universe('stock', exclude_halt=True) print current_universe
部分輸出結(jié)果如下:
['600000.XSHG', '600016.XSHG', '600019.XSHG', '600028.XSHG', '600029. XSHG', '600036.XSHG'...'603993.XSHG']
又如,分別獲取滬銅1810、滬深300期貨當(dāng)月對(duì)應(yīng)的期貨合約列表、普通期貨合約列表、連續(xù)期貨合約列表的代碼如下:
start = '2018-01-01' # 回測(cè)起始時(shí)間 end = '2019-01-01' # 回測(cè)結(jié)束時(shí)間 universe = ['CU1810', 'IFL0'] # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) # 策略類型,'d’表示日間策略使用日線回測(cè),'m’表示日內(nèi)策略使用分鐘線回測(cè) freq = 'd' refresh_rate = 1 # 執(zhí)行handle_data的時(shí)間間隔 accounts = { 'futures_account': AccountConfig(account_type='futures', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 print context.get_universe('futures') print context.get_universe('base_futures') print context.get_universe('continuous_futures')
部分輸出結(jié)果如下:
['CU1810', 'IFL0'] ['CU1810'] ['IFL0'] ...
3.7.8 transfer_cash
transfer_cash用于實(shí)現(xiàn)賬戶間的資金劃轉(zhuǎn),示例代碼如下:
context.transfer_cash(origin, target, amount)
參數(shù)說(shuō)明如下。
· origin:資金流出的賬戶名稱。
參數(shù)類型:str。
· target:資金流入的賬戶名稱。
參數(shù)類型:str。
· amount:劃轉(zhuǎn)的資金量。
參數(shù)類型:float。
示例代碼如下:
start = '2019-01-01' # 回測(cè)起始時(shí)間 end = '2019-01-10' # 回測(cè)結(jié)束時(shí)間 universe = ['000001.XSHE', 'IFM0'] # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) # 策略類型,'d’表示日間策略使用日線回測(cè),'m’表示日內(nèi)策略使用分鐘線回測(cè) freq = 'd' refresh_rate = 1 # 執(zhí)行handle_data的時(shí)間間隔 accounts = { 'stock_account': AccountConfig('security', capital_base=1e6), 'futures_account': AccountConfig('futures', capital_base=1e6) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): stock_account = context.get_account('stock_account') futures_account = context.get_account('futures_account') if context.current_date.strftime('%Y-%m-%d') == '2017-01-05': context.transfer_cash(origin=stock_account, target=futures_account, amount=1e5) assert stock_account.cash, futures_account.cash == (900000, 1100000) assert stock_account.portfolio_value + futures_account.portfolio _value == 2000000 if context.current_date.strftime('%Y-%m-%d') == '2017-01-06': context.transfer_cash(origin=futures_account, target=stock_account, amount=2e5) assert stock_account.cash, futures_account.cash == (1100000, 900000) assert stock_account.portfolio_value + futures_account.portfolio_ value == 2000000
3.8 獲取和調(diào)用數(shù)據(jù)
3.8.1 history
history用于獲取指定證券的歷史行情、因子等時(shí)間序列數(shù)據(jù),示例代碼如下:
context.history(symbol, attribute=['closPrice'], time_range=1, freq='1d', style='sat', rtype='frame')
參數(shù)說(shuō)明如下。
· symbol:需要獲取的數(shù)據(jù)的證券列表,支持單個(gè)證券或證券列表,必須是初始化參數(shù)universe涵蓋的證券范圍。
參數(shù)類型:str或list。
· attribute:需要獲取的屬性,支持單個(gè)屬性或?qū)傩粤斜怼?/p>
參數(shù)類型:str或list。
資產(chǎn)類型可選參數(shù)說(shuō)明如表3-5(日線數(shù)據(jù))和表3-6(分鐘線數(shù)據(jù))所示。
表3-5

表3-6

· time_range:需要回溯的歷史K線條數(shù),和freq屬性相對(duì)應(yīng)。日線數(shù)據(jù)默認(rèn)最大值為30,分鐘線數(shù)據(jù)默認(rèn)最大值為240,可以使用max_history_window設(shè)置最大限度取值范圍。
參數(shù)類型:int。
· freq:K線圖周期。
參數(shù)類型:str。
參數(shù)用法如下。
? 日線K線圖:1d。
? 分鐘線K線圖:1m、5m、15m、30m、60m。
· style:數(shù)據(jù)返回的格式。參數(shù)值包括ast、sat、tas 3種。a表示attribute, s表示symbol, t表示time,它們分別對(duì)應(yīng)3個(gè)維度呈現(xiàn)的順序。例如,ast表示返回的字典中的鍵是attribute,其值是列為symbol、行為time的DataFrame,以此類推。
參數(shù)類型:str。
不同資產(chǎn)對(duì)象支持的參數(shù)如表3-7(日線數(shù)據(jù))和表3-8(分鐘線數(shù)據(jù))所示。
表3-7

表3-8

可以同時(shí)獲取多個(gè)品種資產(chǎn)對(duì)應(yīng)的所有支持?jǐn)?shù)據(jù),當(dāng)包含期貨品種時(shí),數(shù)據(jù)返回類型必須為style = 'sat'。
· rtype:返回值的數(shù)據(jù)類型。
參數(shù)類型:str。包括兩個(gè)值,即’frame'、'array'。
返回類型:dict。key為資產(chǎn)符號(hào),value的格式由rtype來(lái)決定。
以日線數(shù)據(jù)可以獲取單個(gè)品種資產(chǎn)對(duì)應(yīng)的所有支持的數(shù)據(jù)為例,資產(chǎn)類型可以是股票(含場(chǎng)內(nèi)基金)、期貨、場(chǎng)外基金、指數(shù)。獲取日線數(shù)據(jù)時(shí)需要將回測(cè)初始化參數(shù)中的freq的值設(shè)置為d, refresh_rate的值設(shè)置為整數(shù),代碼如下:
# 取平安銀行向前10個(gè)交易日的日線數(shù)據(jù) start = '2019-01-01' # 回測(cè)起始時(shí)間 end = '2019-02-01' # 回測(cè)結(jié)束時(shí)間 universe = ['000001.XSHE'] # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) # 策略類型,'d’表示日間策略使用日線回測(cè),'m’表示日內(nèi)策略使用分鐘線回測(cè) freq = 'd' refresh_rate = 1 # 執(zhí)行handle_data的時(shí)間間隔 accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') data = context.history(['000001.XSHE'], ['openPrice', 'highPrice', 'lowPrice', 'closePrice', 'preClosePrice', 'turnoverVol', 'turnoverValue', 'adjFactor'], 10, freq='1d', rtype='frame', style='sat') print data
部分輸出結(jié)果如下:
{'000001.XSHE': closePrice turnoverValue turnoverVol lowPrice highPrice \ 2018-12-17 10.29 5.846795e+0857127487.0 10.10 10.33 2018-12-18 10.12 5.471576e+0853774430.0 10.10 10.32 2018-12-19 9.94 6.000902e+0859800701.0 9.90 10.18 2018-12-20 9.71 9.642029e+0899028479.0 9.63 9.97 2018-12-21 9.45 9.444603e+08100061676.0 9.33 9.70 2018-12-24 9.42 4.771869e+0850911767.0 9.31 9.45 2018-12-25 9.34 5.452356e+0858661545.0 9.21 9.43 2018-12-26 9.30 3.932151e+0842114060.0 9.27 9.42 2018-12-27 9.28 5.863438e+0862459327.0 9.28 9.49 2018-12-28 9.38 5.415710e+0857660400.0 9.31 9.46 openPrice adjFactor preClosePrice 2018-12-17 10.16 1.0 10.17 2018-12-18 10.20 1.0 10.29 2018-12-19 10.14 1.0 10.12 2018-12-20 9.92 1.0 9.94 2018-12-21 9.68 1.0 9.71 2018-12-24 9.40 1.0 9.45 2018-12-25 9.29 1.0 9.42 2018-12-26 9.35 1.0 9.34 2018-12-27 9.45 1.0 9.30 2018-12-28 9.31 1.0 9.28 } ...
以日線數(shù)據(jù)同時(shí)獲取多個(gè)品種資產(chǎn)的數(shù)據(jù),并且只能選擇多種資產(chǎn)共用的參數(shù)為例,代碼如下:
# 取平安銀行和期貨主力合約向前10個(gè)交易日的日線數(shù)據(jù) start = '2019-01-01' # 回測(cè)起始時(shí)間 end = '2019-02-01' # 回測(cè)結(jié)束時(shí)間 universe = ['000001.XSHE', 'IFM0'] # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) # 策略類型,'d’表示日間策略使用日線回測(cè),'m’表示日內(nèi)策略使用分鐘線回測(cè) freq = 'd' refresh_rate = 1 # 執(zhí)行handle_data的時(shí)間間隔 accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') data = context.history(['000001.XSHE', 'IFM0'], ['openPrice', 'highPrice', 'lowPrice', 'closePrice', 'preClosePrice', 'turnoverVol', 'turnoverValue', 'adjFactor'], 10, freq='1d', rtype='frame', style='sat') print data
以分鐘線數(shù)據(jù)獲取單個(gè)品種資產(chǎn)對(duì)應(yīng)的所有支持的數(shù)據(jù)為例,可以是股票(含場(chǎng)內(nèi)基金)、期貨、指數(shù)。獲取分鐘線數(shù)據(jù)時(shí)需要將回測(cè)初始化參數(shù)中的freq的值設(shè)置為m, refresh_rate的值設(shè)置為(a, b)結(jié)構(gòu),如需幫助可以查看freq和refresh_rate,代碼如下:
# 取平安銀行向前10條1分鐘K線的分鐘線數(shù)據(jù) start = '2019-01-01' # 回測(cè)起始時(shí)間 end = '2019-01-05' # 回測(cè)結(jié)束時(shí)間 universe = ['000001.XSHE'] # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) # 策略類型,'d’表示日間策略使用日線回測(cè),'m’表示日內(nèi)策略使用分鐘線回測(cè) freq = 'm' refresh_rate = (1, 30) # 執(zhí)行handle_data的時(shí)間間隔 max_history_window = (10, 300) # 分鐘線默認(rèn)最大向前獲取240條K線,如果要獲取更多,請(qǐng)?jiān)O(shè)置max_history_window=(日線 條數(shù),分鐘線條數(shù)) accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') data = context.history(['000001.XSHE'], ['openPrice', 'highPrice', 'lowPrice', 'closePrice', 'turnoverVol', 'turnoverValue'], 10, freq='1m', rtype='frame', style='sat') print data
部分輸出結(jié)果如下:
{'000001.XSHE': closePrice highPrice lowPrice openPrice turnoverValue \ tradeTime 2019-01-04 14:21 9.68 9.69 9.66 9.663890507.74 2019-01-04 14:22 9.67 9.69 9.67 9.692936305.80 2019-01-04 14:23 9.69 9.70 9.68 9.684796156.30 2019-01-04 14:24 9.68 9.69 9.67 9.692680228.00 2019-01-04 14:25 9.68 9.70 9.68 9.682173928.00 2019-01-04 14:26 9.69 9.70 9.69 9.694548130.00 2019-01-04 14:27 9.70 9.70 9.68 9.692600399.00 2019-01-04 14:28 9.71 9.71 9.69 9.693516762.00 2019-01-04 14:29 9.73 9.73 9.70 9.704719750.60 2019-01-04 14:30 9.72 9.73 9.72 9.725949170.00 turnoverVol tradeTime 2019-01-04 14:21402082.0 2019-01-04 14:22303220.0 2019-01-04 14:23495200.0 2019-01-04 14:24276700.0 2019-01-04 14:25224400.0 2019-01-04 14:26469000.0 2019-01-04 14:27268300.0 2019-01-04 14:28362460.0 2019-01-04 14:29485660.0 2019-01-04 14:30611900.0 }
取平安銀行和期貨主力合約向前10條15分鐘K線的分鐘線數(shù)據(jù),示例代碼如下:
# 取平安銀行和期貨主力合約向前10條15分鐘K線的分鐘線數(shù)據(jù) start = '2019-01-01' # 回測(cè)起始時(shí)間 end = '2019-01-05' # 回測(cè)結(jié)束時(shí)間 universe = ['000001.XSHE', 'IFM0'] # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) # 策略類型,'d’表示日間策略使用日線回測(cè),'m’表示日內(nèi)策略使用分鐘線回測(cè) freq = 'm' refresh_rate = (1, 15) # 執(zhí)行handle_data的時(shí)間間隔 accounts = { 'stock_account': AccountConfig(account_type='security', capital_base=10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') data = context.history(['000001.XSHE', 'IFM0'], ['openPrice', 'highPrice', 'lowPrice', 'closePrice', 'turnoverVol', 'turnoverValue'], 10, freq='15m', rtype='frame', style='sat') print data
1.max_history_window
在使用context.history獲取數(shù)據(jù)時(shí),默認(rèn)對(duì)日線支持30個(gè)交易日數(shù)據(jù),分鐘線支持240條K線數(shù)據(jù),當(dāng)回溯長(zhǎng)度超出范圍時(shí)需要手動(dòng)指定。因?yàn)榛厮輹r(shí)間變長(zhǎng)會(huì)影響回測(cè)速度,所以盡量不要取過(guò)長(zhǎng)的回溯長(zhǎng)度。
max_history_window的用法如下:
max_history_window = 40 # 設(shè)置日線數(shù)據(jù)回溯長(zhǎng)度為向前40個(gè)交易日 # 設(shè)置分鐘線數(shù)據(jù)回溯長(zhǎng)度為向前300條K線、20個(gè)交易日的K線長(zhǎng)度 max_history_window = (20, 300)
2.獲取因子數(shù)據(jù)
可以直接使用context.history獲取因子數(shù)據(jù)。
用法:如下示例注冊(cè)了PE、PB兩個(gè)因子來(lái)獲取因子數(shù)據(jù):
start = '2019-01-01' # 回測(cè)起始時(shí)間 end = '2019-03-01' # 回測(cè)結(jié)束時(shí)間 universe = ['000001.XSHE'] # 證券池,支持股票、基金、期貨 benchmark = 'HS300' # 策略參考基準(zhǔn) # 策略類型,'d’表示日間策略使用日線回測(cè),'m’表示日內(nèi)策略使用分鐘線回測(cè) freq = 'd' refresh_rate = 1 # 執(zhí)行handle_data的時(shí)間間隔 accounts = { 'stock_account': AccountConfig(account_type='security', capital_base= 10000000) } def initialize(context): # 初始化策略運(yùn)行環(huán)境 pass def handle_data(context): # 核心策略邏輯 stock_account = context.get_account('stock_account') data = context.history(['000001.XSHE'], ['PE', 'PB'], 5, freq='1d', rtype='frame', style='sat') print data
返回的部分結(jié)果如下:
{'000001.XSHE': PB PE 2019-02-21 0.9061 7.9641 2019-02-22 0.9204 8.0903 2019-02-25 1.0010 8.7983 2019-02-26 0.9731 8.5530 2019-02-27 0.9890 8.6932} {'000001.XSHE': PB PE 2019-02-22 0.9204 8.0903 2019-02-25 1.0010 8.7983 2019-02-26 0.9731 8.5530 2019-02-27 0.9890 8.6932 2019-02-28 0.9858 8.6651}
3.8.2 get_symbol_history
get_symbol_history用于獲取指定證券的歷史行情、因子等時(shí)間序列數(shù)據(jù),示例代碼如下:
context.get_symbol_history(symbol, time_range=1, attribute= ['closePrice'], freq='1d', style='sat', rtype='frame')
參數(shù)說(shuō)明如下。
· symbol:需要獲取的數(shù)據(jù)的證券列表,支持單個(gè)證券或證券列表,必須是初始化參數(shù)universe涵蓋的證券范圍。
參數(shù)類型:str。
· time_range:需要回溯的歷史K線條數(shù),和freq屬性相對(duì)應(yīng)。日線數(shù)據(jù)默認(rèn)最大值為30,分鐘線數(shù)據(jù)默認(rèn)最大值為240,可以使用max_history_window設(shè)置最大限度取值范圍。
參數(shù)類型:int。
· attribute:需要獲取的屬性,支持單個(gè)屬性或?qū)傩粤斜怼?/p>
參數(shù)類型:str或list。
資產(chǎn)類型可選參數(shù)說(shuō)明如表3-9(日線數(shù)據(jù))和表3-10(分鐘線數(shù)據(jù))所示。
表3-9

表3-10

· freq:K線圖周期。
參數(shù)類型:str。
參數(shù)用法如下。
? 日線K線圖:1d。
? 分鐘線K線圖:1m、5m、15m、30m、60m。
· style:數(shù)據(jù)返回的格式。參數(shù)值包括ast、sat、tas 3種。a表示attribute, s表示symbol, t表示time,它們分別對(duì)應(yīng)3個(gè)維度呈現(xiàn)的順序。例如,ast表示返回的字典中的鍵是attribute,其值是列為symbol、行為time的DataFrame,以此類推。
參數(shù)類型:str。
不同資產(chǎn)對(duì)象支持的參數(shù)如表3-11(日線數(shù)據(jù))和表3-12(分鐘線數(shù)據(jù))所示。
表3-11

表3-12

可以同時(shí)獲取多個(gè)品種資產(chǎn)對(duì)應(yīng)的所有支持?jǐn)?shù)據(jù),當(dāng)包含期貨品種時(shí),數(shù)據(jù)返回類型必須為style = 'sat'。
· rtype:返回值的數(shù)據(jù)類型。
參數(shù)類型:str。包括兩個(gè)值,即’frame'、'array'。
返回類型:dict。key為資產(chǎn)符號(hào),value的格式由rtype決定。
3.8.3 get_attribute_history
get_attribute_history用于獲取指定證券的歷史行情、因子等時(shí)間序列數(shù)據(jù),示例代碼如下:
context.get_attribute_history(attribute, time_range=1, symbol=None, freq= '1d', style='sat', rtype='frame')
參數(shù)說(shuō)明如下。
· attribute:需要獲取的屬性,支持單個(gè)屬性或?qū)傩粤斜怼?/p>
參數(shù)類型:str。
可選參數(shù)說(shuō)明如表3-13(日線數(shù)據(jù))和表3-14(分鐘線數(shù)據(jù))所示。
表3-13

表3-14

· time_range:需要回溯的歷史K線條數(shù),和freq屬性相對(duì)應(yīng)。日線數(shù)據(jù)默認(rèn)最大值為30,分鐘線數(shù)據(jù)默認(rèn)最大值為240,可以使用max_history_window設(shè)置最大限度取值范圍。
參數(shù)類型:int。
· symbol:需要獲取的數(shù)據(jù)的證券列表,支持單個(gè)證券或證券列表,必須是初始化參數(shù)universe涵蓋的證券范圍。
參數(shù)類型:str或list。
· freq:K線圖周期。
參數(shù)類型:str。
參數(shù)用法如下。
? 日線K線圖:1d。
? 分鐘線K線圖:1m、5m、15m、30m、60m。
· style:數(shù)據(jù)返回的格式。參數(shù)值包括ast、sat、tas 3種。a表示attribute, s表示symbol, t表示time,它們分別對(duì)應(yīng)3個(gè)維度呈現(xiàn)的順序。例如,ast表示返回的字典中的鍵是attribute,其值是列為symbol、行為time的DataFrame,以此類推。
參數(shù)類型:str。
參數(shù)用法如表3-15(日線數(shù)據(jù))和表3-16(分鐘線數(shù)據(jù))所示。
表3-15

表3-16

可以同時(shí)獲取多個(gè)品種資產(chǎn)對(duì)應(yīng)的所有支持?jǐn)?shù)據(jù),當(dāng)包含期貨品種時(shí),數(shù)據(jù)返回類型必須為style = 'sat'。
· rtype:返回值的數(shù)據(jù)類型。
參數(shù)類型:str。包括兩個(gè)值,即’frame'、'array'。
返回類型:dict。key為資產(chǎn)符號(hào),value的格式由rtype決定。
3.8.4 DataAPI
DataAPI是獲取優(yōu)礦提供的數(shù)據(jù)的主要方式,包含股票、基金、期貨、指數(shù)、債券、基本面、宏觀等多種數(shù)據(jù)。可以在Notebook中調(diào)用DataAPI對(duì)象的某個(gè)方法來(lái)獲取特定的數(shù)據(jù)。
- 數(shù)據(jù)分析實(shí)戰(zhàn):基于EXCEL和SPSS系列工具的實(shí)踐
- Java Data Science Cookbook
- MySQL基礎(chǔ)教程
- 大數(shù)據(jù)營(yíng)銷:如何讓營(yíng)銷更具吸引力
- 數(shù)據(jù)庫(kù)原理與應(yīng)用(Oracle版)
- Remote Usability Testing
- Learning Proxmox VE
- 網(wǎng)站數(shù)據(jù)庫(kù)技術(shù)
- 云原生數(shù)據(jù)中臺(tái):架構(gòu)、方法論與實(shí)踐
- SAS金融數(shù)據(jù)挖掘與建模:系統(tǒng)方法與案例解析
- 數(shù)據(jù)庫(kù)技術(shù)及應(yīng)用
- Oracle 11g+ASP.NET數(shù)據(jù)庫(kù)系統(tǒng)開(kāi)發(fā)案例教程
- openGauss數(shù)據(jù)庫(kù)核心技術(shù)
- Unity for Architectural Visualization
- 數(shù)據(jù)庫(kù)基礎(chǔ)與應(yīng)用