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