Python零基礎(chǔ)該如何學(xué)習(xí)
這篇文章經(jīng)過(guò)敘述 [單股市均線戰(zhàn)略] 在 Ricequant 量化渠道的完成,了解渠道并迅速入門、創(chuàng)立自個(gè)的量化戰(zhàn)略代碼。
難易度:入門級(jí)
那么以下咱們就先從 [單股市均線戰(zhàn)略] 的代碼完成及進(jìn)行日等級(jí)回測(cè)講起吧。
1 確定框架:
[單股票均線策略] 的主要策略框架: 5 日均線高于 30 天均線,則全倉(cāng)買入股票 5 日均線低于 30 天均線,則賣出所持股票
從我們?nèi)粘=灰椎慕嵌龋话憬灰渍叩男袨榭梢圆鸱忠韵聝刹糠郑?/p>
1 選擇標(biāo)的(初始化):
在交易之前,我們通常會(huì)先選定要交易的股票池或者單個(gè)股票
2 交易(每天盯盤)
我們會(huì)觀察該股票的五日均線和 30 日均線,并進(jìn)行比較 如果該股票的五日均線在 30 天均線以上,則全倉(cāng)買入股票 如果該股票的五日均線在 30 天均線以下,則全倉(cāng)賣出(空倉(cāng))
那么程序中,我們是怎么做的呢?
先看看 Ricequant 平臺(tái)中對(duì)應(yīng)的代碼框架會(huì)是怎么樣的吧:
definit(context):#程序的初始化,預(yù)設(shè)股票池、設(shè)置參數(shù)和變量。 只運(yùn)行一次defhandle(context, bar_dict):#從回測(cè)的開(kāi)始日期至結(jié)束日期,根據(jù)選擇的頻率(日、分鐘)循環(huán)運(yùn)行
對(duì)照策略思路 及 Ricequant 代碼框架,你會(huì)發(fā)現(xiàn)我們可以很輕松地把 兩者結(jié)合起來(lái)
以上框架也是 Ricequant 平臺(tái)的最基本也最主要的框架,也就是
- 初始化
- 循環(huán) - 根據(jù)選擇的頻率(日、分鐘)循環(huán)運(yùn)行
2 初始化:
選擇標(biāo)的:本策略的交易股票設(shè)定為 300059 ”東方財(cái)富“。
definit(context):? ?context.stock ="300059.XSHE"?# 存入目標(biāo)股票 [東方財(cái)富 ]
延伸閱讀:
1 在 init 中實(shí)現(xiàn)程序的初始化,例如存入目標(biāo)股票池,設(shè)置滑點(diǎn)、基準(zhǔn)等參數(shù)以及設(shè)置其它變量。 context 是一個(gè)全局的容器,你可以通過(guò)它設(shè)置任何全局變量并初始化:如 context.stock 將會(huì)在后面代碼所被調(diào)用到。
2 代碼中 # 代表注釋,作為代碼說(shuō)明,執(zhí)行時(shí)會(huì)被跳過(guò)而不為程序所運(yùn)行。
3 如何填寫股票代碼:你會(huì)發(fā)現(xiàn)策略代碼中 股票代碼后帶有后綴,那么它們分別代表什么呢?
后綴為
- XSHE 代表在深交所上市交易的股票
- XSHG 在上交所上市交易的股票
例子:
- 300059.XSHE 為深交所上市的東方財(cái)富
- 600000.XSHG 為上交所上市的浦發(fā)銀行
我們的代碼編輯器還提供了非常便利的股票代碼自動(dòng)尋找和補(bǔ)全功能,在 Windows 中你可以用 ctrl+i , Mac 系統(tǒng)你可以用 cmd+i 激活證券代碼自動(dòng)補(bǔ)全功能。如下圖:

3 獲取均價(jià):
我們分別獲取該股票 5 日和 30 日的均價(jià)
# 用法:變量 = bar_dict[股票代碼].mavg(天數(shù), frequency='day')# 獲取近五日股票收盤價(jià)均價(jià),命名為 fast? ?fast= bar_dict[context.stock].mavg(5, frequency='day')# ?同上,獲取近二十日的收盤價(jià)均價(jià),命名為 slow :? ?slow = bar_dict[context.stock].mavg(30, frequency='day')
4 判斷買賣條件:
獲得均價(jià)數(shù)據(jù)之后,我們就可以進(jìn)行一個(gè)判斷決定是否買賣了:
iffast>slow:# 若快線在慢線之上則用所有現(xiàn)金買入該股票? ? ? ? ?#買入操作? ? ? ? ? ? ? ? ?eliffast<slow:# 若慢線在快線之上則清空所持股票? ? ? ? ? ?#賣出操作
在判斷之前,我們還漏了一步,那是什么呢?就是要知道我們有多少現(xiàn)金,那么在程序中是如何獲得現(xiàn)金的呢?我們使用以下代碼
# 用法:變量 = context.portfolio.cashcash= context.portfolio.cash#取得當(dāng)前的現(xiàn)金量,命名為 cash
延伸閱讀: portfolio 中 包含所有的投資組合的信息,請(qǐng)參考文檔 -?Portfolio 對(duì)象
5 買入 /賣出:
在判定買賣的條件成立之后,我們會(huì)對(duì)股票進(jìn)行買入或者賣出的操作:
#用法 order_value(股票代碼,買賣金額) ? 金額為正則為買入,負(fù)數(shù)則為賣出#將所有現(xiàn)金買入 300059 東方財(cái)富order_value(context.stock, cash)#用法: order_target_value(股票代碼,目標(biāo)持倉(cāng)比例) ? 比例在 1 與 0 之間#此處將持倉(cāng)比例調(diào)整為 0 ,則等同于全部賣出order_target_percent(context.stock,0)
6 策略回測(cè)
以上,我們用幾行代碼就把策略的框架完整地搭建起來(lái)了,最終的完整代碼為:
definit(context):?#初始化? ?context.stock ="300059.XSHE"? ? ? ?#存入要交易的股票代碼defhandle_bar(context, bar_dict):? ? ? ?#每日循環(huán)運(yùn)行 ?#獲取 30 日均線????slow = bar_dict[context.stock].mavg(30, frequency='day') ?#獲取 5 日均線????fast = bar_dict[context.stock].mavg(5, frequency='day') ?????cash = context.portfolio.cash ? ? ? ? ? ? ? ? ?#獲取持有現(xiàn)金金額????iffast>slow: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#判定買入條件????????order_value(context.stock, cash) ? ? ? ?#買入目標(biāo)股票????eliffast<slow:????????order_target_percent(context.stock,0) ?#賣出目標(biāo)股票
寫完了策略,那么我們接下去做什么呢? 先對(duì)我們的策略進(jìn)行一次歷史回測(cè),看看它的歷史表現(xiàn)是如何吧。
在策略編輯頁(yè)面右上方,選擇從 2015 年 1 月 4 日至 2016 年 10 月 4 日,用資金 10 萬(wàn)元進(jìn)行日回測(cè)吧,請(qǐng)點(diǎn)擊 運(yùn)行回測(cè)

如代碼沒(méi)有問(wèn)題,在數(shù)秒之后,我們就會(huì)拿到該策略的歷史表現(xiàn)結(jié)果:

我們可以看到回測(cè)詳情中有精致的圖表,詳細(xì)的各項(xiàng)風(fēng)險(xiǎn)收益指標(biāo)、以及持倉(cāng)、落單等詳情輔助你進(jìn)一步了解你的策略的表現(xiàn)。
到這里,一個(gè)完整的從 [構(gòu)建策略思路] 到 [策略代碼編寫] 到 [回測(cè)結(jié)果檢驗(yàn)] 的流程就結(jié)束了。
7 從日回測(cè)到分鐘回測(cè):
在循環(huán)部分, handle 函數(shù)根據(jù)選擇的頻率(日、分鐘)循環(huán)運(yùn)行,在以上的日回測(cè)中, handle 內(nèi)的代碼會(huì)每日被觸發(fā)一次
defhandle(context, bar_dict):
如果是進(jìn)行分鐘回測(cè)或模擬實(shí)盤,那么這個(gè) handle 里的代碼就會(huì)被每分鐘觸發(fā)一次;
因此,我們的代碼邏輯也勢(shì)必要進(jìn)行一定的改進(jìn),使得策略按照我們的邏輯正常地運(yùn)行。
我們先把修改好的代碼貼上來(lái):
definit(context):? ?context.stock ="300059.XSHE"# 每日開(kāi)盤前運(yùn)行一次,可以進(jìn)行選股、設(shè)置參數(shù)等行為 ? ?defbefore_trading(context):? ?# 設(shè)定并重置 context.fired 的值為 0? ?context.fired =0? ?#從回測(cè)的開(kāi)始日期至結(jié)束日期,根據(jù)選擇的頻率(日、分鐘)循環(huán)運(yùn)行defhandle_bar(context, bar_dict):? ?# 判定今日是否有下過(guò)單,若未下單則進(jìn)行下列代碼的操作? ?if(context.fired ==0): ? ? ? ?slow = bar_dict[context.stock].mavg(30, frequency='day') ? ? ? ?fast = bar_dict[context.stock].mavg(5, frequency='day') ? ? ? ?cash = context.portfolio.cash ? ? ? ? ? ? ? ?iffast>slow: ? ? ? ? ? ?order_value(context.stock, cash) ? ? ? ?eliffast < slow: ? ? ? ? ? ?order_target_percent(context.stock,0) ? ? ? ?# 設(shè)置 fired 等于 1 ,表示執(zhí)行完畢 ? ? ? ? ?? ? ? ?context.fired =1
可以看到這里改動(dòng)并不多,
這里需要介紹到框架中常用到的函數(shù) before_trading :
# 每日開(kāi)盤前運(yùn)行一次,可以進(jìn)行選股、設(shè)置參數(shù)等行為 ? ?defbefore_trading(context):
我們?cè)?before_trading 中設(shè)置一個(gè)變量命名為 fired ,賦值為 0
# 設(shè)定并重置 context.fired 的值為 0? ?context.fired =0
由于 before_trading 是每天開(kāi)盤前運(yùn)行一次,所以 context.fired 會(huì)被每天重置為 0
在 handle 函數(shù)中,我們加入了判斷,如 context.fired 為 0 ,則繼續(xù)執(zhí)行下面的代碼,否則本次循環(huán)結(jié)束。
# 判定今日是否有下過(guò)單,若未下單則進(jìn)行下列代碼的操作if(context.fired ==0):
并在執(zhí)行完判斷和買賣操作之后,設(shè)定 context.fired 的值等于 1 ,使得當(dāng)日余下的分鐘循環(huán)操作均被跳過(guò)。
# 設(shè)置 fired 等于 1 ,表示今天已下過(guò)單 ? ? ? ? ? ?context.fired =1
在完成以上代碼后,我們開(kāi)始進(jìn)行分鐘回測(cè)吧: 在策略編輯頁(yè)面右上方,選擇從 2015 年 1 月 4 日至 2016 年 10 月 4 日,用資金 10 萬(wàn)元進(jìn)行分鐘回測(cè)吧,請(qǐng)點(diǎn)擊 運(yùn)行回測(cè)?

8 模擬交易:
模擬交易通過(guò)實(shí)時(shí)的分鐘切片數(shù)據(jù)進(jìn)行撮合,也就是 handle 函數(shù)會(huì)每分鐘被觸發(fā)一次循環(huán)。在開(kāi)啟你的策略的模擬交易之前,你必須要對(duì)它進(jìn)行一次分鐘回測(cè),才可以開(kāi)啟模擬交易。 在上面分鐘回測(cè)之后,你可以在策略回測(cè)詳情頁(yè)面點(diǎn)擊 開(kāi)啟模擬交易。然后你將在模擬交易列表中看到進(jìn)行中的策略。

9 開(kāi)啟微信通知,接收交易信號(hào):
點(diǎn)擊導(dǎo)航欄中的 [我的策略] ,可以在 [模擬交易] 一欄看到創(chuàng)建的模擬交易,如下圖:

點(diǎn)擊右邊的微信通知開(kāi)關(guān),將 OFF 調(diào)至 ON ,并按照指示掃描二維碼,綁定微信,就能通過(guò)微信接收交易信號(hào)了。
當(dāng)該策略進(jìn)行買賣操作,你的微信會(huì)收到類似下圖的信號(hào)提醒。微信推送的延遲非常小,使得你能根據(jù)信號(hào)進(jìn)行及時(shí)的下單操作。

是不是很輕松,數(shù)行代碼就可以把你的出資戰(zhàn)略成為代碼,我們都來(lái)試試吧!
馬哥教育-Python開(kāi)發(fā)-1群 335068227
馬哥教育-Python開(kāi)發(fā)-2群 608459685