量化策略系列教程:16二八輪動策略

今天再上個新策略~大家拿去跑跑看,改改參數,看看收益率如何呀~證經社量化社區 - 證經社

1. 策略原理:

二八輪動策略是基於A股市場中大盤股和小盤股走勢作為信號的策略。「二」指的是權重股,大盤股;「八」指的是中小盤股,非權重股。「輪動」指的是大盤股和中小盤股之間的相互切換。一般情況下,滬深300走勢表示大盤股的整體走勢,中證500指數綜合反映滬深證券市場內小市值公司的整體狀況。

(1)獲取指數000300、000905前一日收盤價以及前20日數據;

(2)計算前20日變動;

(3)獲取ETF300(510300)及ETF500(510500)的持倉數據;

(4)

a. 如果000300趨勢下降且有持倉,則賣出ETF300;

b. 如果000905趨勢下降且有持倉,則賣出ETF500;

c. 如果300指數增幅大於500指數增幅,且300指數增幅大於0,且ETF300及ETF500無持倉,則買入ETF300;

d. 如果300指數增幅小於500指數增幅,且500指數增幅大於0,且ETF300及ETF500無持倉,則買入ETF500;

2. 代碼解讀:

2.1 strategy.ini

[strategy]nusername=npassword=nmode=4ntd_addr=localhost:8001nstrategy_id=nsubscribe_symbols=SHSE.000300.bar.daily,SHSE.000905.bar.dailyn[backtest]nstart_time = 2015-05-01 09:00:00nend_time = 2015-5-31 16:00:00n;策略初始資金ninitial_cash=1000000nn;委託量成交比率,默認=1(每個委託100%成交)ntransaction_ratio=1nn;手續費率,默認=0(不計算手續費)ncommission_ratio=0nn;滑點比率,默認=0(無滑點)nslippage_ratio=0nn[para]n#bar_type=60nwindow_size=20nnmarket_exchange_a=SHSEnmarket_secid_a=000300nnmarket_exchange_b=SHSEnmarket_secid_b=000905nnntrade_exchange_a=SHSEntrade_secid_a=510300ntrade_unit_a=100nntrade_exchange_b=SHSEntrade_secid_b=510500ntrade_unit_b=100nn#hour=14n#minute=53nn#sigma=2.34nn##############################################################n# logger settingsn##############################################################n[loggers]nkeys=rootnn[logger_root]nlevel=DEBUGnhandlers=console,filenn[handlers]nkeys=console,filenn[handler_file]nclass=handlers.RotatingFileHandlern;args=(strategy_sa.log,a,maxBytes=10000,backupCount=5)nargs=(strategy_sa.log,a,10000,5)nformatter=simplenn[handler_console]nclass=StreamHandlernargs = (sys.stdout,)nformatter=simplenn[formatters]nkeys = simplenn[formatter_simple]nformat=%(asctime)s - %(name)s - %(levelname)s - %(message)sndatefmt=n

2.2 strategy.py

# -*- coding: utf-8 -*-n"""nCreated on Tue Jan 24 13:32:56 2017nn@author: Lenovon"""nn#!/usr/bin/env pythonn# encoding: utf-8nnfrom gmsdk.api import StrategyBasenimport numpy as npnfrom collections import dequen#from gmsdk import *n#import arrown#from math import lognneps = 1e-6nnclass StatArb(StrategyBase):n n statistics arbitrage demon n def __init__(self, *args, **kwargs):n #import pdb; pdb.set_trace()n super( StatArb, self).__init__(*args, **kwargs)n # 策略初始化工作在這裡寫,從外部讀取靜態數據,讀取策略配置參數等工作,只在策略啟動初始化時執行一次。nn # 從配置文件中讀取配置參數n self.market_exchange_a = self.config.get(para, market_exchange_a) or SHSEn self.market_secid_a = self.config.get(para, market_secid_a) or 000300n self.market_symbol_a = ".".join([self.market_exchange_a, self.market_secid_a])nnn self.market_exchange_b = self.config.get(para, market_exchange_b) or SHSEn self.market_secid_b = self.config.get(para, market_secid_b) or 000905n self.market_symbol_b = ".".join([self.market_exchange_b, self.market_secid_b])nnn self.trade_exchange_a = self.config.get(para, trade_exchange_a) or SHSEn self.trade_secid_a = self.config.get(para, trade_secid_a) or 510300n self.trade_symbol_a = ".".join([self.trade_exchange_a, self.trade_secid_a])nnn self.trade_exchange_b = self.config.get(para, trade_exchange_b) or SHSEn self.trade_secid_b = self.config.get(para, trade_secid_b) or 510500n self.trade_symbol_b = ".".join([self.trade_exchange_b, self.trade_secid_b])nnn # self.hour = self.config.get(para,hour) or 14n # self.minute = self.config.get(para,minute) or 53nn self.window_size = self.config.getint(para,window_size) or 20nn self.trade_unit_a = self.config.getint(para,trade_unit_a) or 100n self.trade_unit_b = self.config.getint(para,trade_unit_b) or 100nnn self.closes_a_buffer = deque(maxlen=self.window_size)n self.closes_b_buffer = deque(maxlen=self.window_size)nn last_closes_a = [bar.close for bar in self.get_last_n_dailybars(self.market_symbol_a,self.window_size,end_time=self.start_time)]n last_closes_a.reverse()nn last_closes_b = [bar.close for bar in self.get_last_n_dailybars(self.market_symbol_b,self.window_size,end_time=self.start_time)]n last_closes_b.reverse()nn self.closes_a_buffer.extend(last_closes_a)n self.closes_b_buffer.extend(last_closes_b)nn def on_bar(self, bar):n if bar.sec_id == self.market_secid_a:n self.closes_a_buffer.append(bar.close)n self.last_price_a = bar.closen elif bar.sec_id == self.market_secid_b:n self.closes_b_buffer.append(bar.close)n self.last_price_b = bar.closen # t=arrow.get(bar.utc_time)n # if t.hour == self.hour and t.minute == self.minute:n self.algo_action()n def open_side_a(self):n self.open_long(self.trade_exchange_a, self.trade_secid_a, self.last_price_a, self.trade_unit_a)n #self.open_long(self.trade_exchange_a, self.trade_secid_a, 0, self.trade_unit_a)nn def open_side_b(self): n self.open_long(self.trade_exchange_b, self.trade_secid_b, self.last_price_b, self.trade_unit_b)n # self.open_long(self.trade_exchange_b, self.trade_secid_b, 0, self.trade_unit_b)nn def close_side_a(self):n Position_a = self.get_position(self.trade_exchange_a,self.trade_secid_a,1)n self.close_long(self.trade_exchange_a, self.trade_secid_a, self.last_price_a, Position_a.volume)n # self.close_long(self.trade_exchange_a, self.trade_secid_a, 0, Position_a.volume)nn def close_side_b(self):n Position_b = self.get_position(self.trade_exchange_b,self.trade_secid_b,1)n self.close_long(self.trade_exchange_b, self.trade_secid_b, self.last_price_b, Position_b.volume)n #self.close_long(self.trade_exchange_b, self.trade_secid_b, 0, Position_b.volume)nn def algo_action(self):n close_a = np.asarray(self.closes_a_buffer)n close_b = np.asarray(self.closes_b_buffer)n Change_a = (close_a[self.window_size-1]-close_a[0])/close_a[0]n Change_b = (close_b[self.window_size-1]-close_b[0])/close_b[0]n Position_a = self.get_position(self.trade_exchange_a,self.trade_secid_a,1)n Position_b = self.get_position(self.trade_exchange_b,self.trade_secid_b,1)n av = Position_a.volume if Position_a else 0n bv = Position_b.volume if Position_b else 0n diff = Change_a - Change_b n if diff > eps and Change_a > 0 and av == 0 and bv == 0:n self.open_side_a()n elif diff < eps and Change_b > 0 and av == 0 and bv == 0:n self.open_side_b()n elif Change_a < 0 and av > 0:n self.close_side_a()n elif Change_b < 0 and bv > 0:n self.close_side_b()nnif __name__ == __main__:n #import pdb; pdb.set_trace()n dm = StatArb(config_file=strategy.ini)n ret = dm.run()n print ("Statistics Arbitrage: ", ret, dm.get_strerror(ret))n

如果想了解相關的python函數和掘金介面函數,走下方通道:

http://zjshe.cn/q/forum.php?mod=viewthread&tid=74

有不了解的可以給小編留言哦,小編會細心為大家解答~

推薦閱讀:

時間序列分析----結合ARMA的卡爾曼濾波演算法
RNN最大化條件概率參數模型預測時間序列

TAG:Python入门 | 策略 | 量化 |