導(dǎo)語:作為策略錦集第二篇,我們以滬深A(yù) 股市場出了名的“二八輪動”現(xiàn)象為基礎(chǔ),向大 家介紹經(jīng)典擇時策略:二八輪動策略。 一、策略闡述 在介紹二八輪動策略之前,我們首先來了解一下?lián)駮r交易,擇時交易是指利用某種方法 來判斷后市走勢,如果判斷是上漲,則買入持有;如果判斷是下跌,則賣出清倉;如果判斷 是震蕩,則進行高拋低吸,這樣可以獲得遠遠超越簡單買入持有策略的收益率,所以擇時交 易是收益率最高的一種交易方式。通俗的講,擇時即為選擇交易時機,投資者總是希望通過 擇時,在上漲前買入,在下跌前賣出。 “二八輪動”現(xiàn)象就是大小盤輪動現(xiàn)象,“二”代表數(shù)量占比20%左右的大盤權(quán)重股, “八”代表數(shù)量占比80%左右的中小盤股票,二八輪動策略就是指在大盤股與小盤股中間不 斷切換,輪流持有,在大小盤都看跌的時候,則買入債券或者貨幣基金。二八輪動策略的本 質(zhì)是擇時,從大小盤指數(shù)中選擇最佳交易時機。 二八輪動是如何輪動的呢? 擇時方法:對比當前交易日收盤數(shù)據(jù)與二十個交易日前的收盤數(shù)據(jù),選擇滬深300 指數(shù) 和中證500 指數(shù)中漲幅較大的一個,于下一個交易日切換為持有該指數(shù) ETF ,若兩個指數(shù)均 為下跌,則于下個交易日切換為空倉狀態(tài)。調(diào)倉 日為每周第一個交易 日。 以下為策略實現(xiàn)的基本信息: 策略實現(xiàn)難度:1 實現(xiàn)過程中所需要用到的API 函數(shù),ps:通過 MindGo 量化交易平臺 API 文檔快速掌握: 需要用到的API 函數(shù) 功能 run_weekly() 按周定時運行函數(shù) account.positions 獲取賬戶持倉信息 account.cash 獲取賬戶當前資金 history() 獲取多只股票多屬性的歷史行情數(shù)據(jù) ----------------------- Page 74----------------------- 二、代碼示意圖 三、編寫釋義 本策略的編寫難點在于根據(jù)信號值來調(diào)整持倉。以下是持倉調(diào)整邏輯梳理: 第一步:根據(jù)信號值,只可能會出現(xiàn)三種情況:分別是空倉、滬深300、中證500,其 中空倉是兩者信號值都小于 0,否則持倉為信號值大的那個。 第二步:以目標持倉為導(dǎo)向,根據(jù)當前持倉情況作出調(diào)倉操作: 目標持倉 當前持倉 操作 空倉 無持倉 無操作 有持倉 賣出持倉 滬深300 無持倉 買入滬深300 滬深300 不操作 中證500 賣出中證500,隨后買入滬深300 中證500 無持倉 買入中證500 滬深300 賣出滬深300,買入中證500 中證500 無操作 ----------------------- Page 75----------------------- 四、最終結(jié)果 策略回測區(qū)間:2014.01.01-2018.01.29 回測資金:100000 回測頻率:日級 回測結(jié)果:紅色曲線為策略收益率曲線,藍色曲線為對應(yīng)的基準指數(shù)收益率曲線 策略源代碼: import pandas as pd import numpy as np #=============================初始化賬戶=============================== def initialize(account): account.day = 20 #設(shè)置數(shù)據(jù)獲取長度為 20 account.security = ['000300.SH','000905.SH']#設(shè)滬深300 指數(shù),中證500 指數(shù) account.ETF300 = '510300.OF' #滬深300ETF 基金 account.ETF500 = '510500.OF' # 中證500ETF 基金 run_weekly(trade,date_rule=1) #=============交易函數(shù)============ def trade(account,data): #獲取信號值 signal=get_signal(account,data) hs300=signal[0] zz500=signal[1] #根據(jù)信號值,來調(diào)整至相應(yīng)倉位 #空倉 if hs300 <= 0 and zz500 <= 0: if len(account.positions) > 0: for stock in list(account.positions): order_target(stock, 0) ----------------------- Page 76----------------------- #滬深300 elif hs300 > zz500: if account.ETF500 in list(account.positions): order_target(account.ETF500, 0) if len(account.positions) < 1: order_target_value(account.ETF300, account.cash) # 中證500 elif hs300 < zz500: if account.ETF300 in list(account.positions): order_target(account.ETF300, 0) if len(account.positions) < 1: order_target_value(account.ETF500, account.cash) #======================信號獲取函數(shù)===================================== def get_signal(account,data): #獲取滬深300 與中證500 過去 20 日的收盤價 close=history(account.security, ['close'], 20, '1d', False, 'pre', is_panel=1)['close'] #計算漲跌幅 h=(close.iloc[-1]-close.iloc[0])/close.iloc[0] h300=h['000300.SH'] h500=h['000905.SH'] return h300,h500 ----------------------- Page 77----------------------- |
|