指数平均数也叫EXPMA指标,它是一种趋向类指标,指数平均数指标是以指数式递减加权的移动平均。其构造原理是对股票收盘价进行算术平均,并根据计算结果来进行分析,用于判断价格未来走势的变动趋势。
与MACD指标、DMA指标相比,EXPMA指标由于其计算公式中着重考虑了价格当天(当期)行情的权重,因此指标自身的计算公式决定了作为一类趋势分析指标,它在使用中克服了MACD指标信号对于价格走势的滞后性。同时也在一定程度中消除了DMA指标在某些时候对于价格走势所产生的信号提前性,是一个非常有效的分析指标。
EXPMA=(当日或当期收盘价-上一日或上期EXPMA)/N 上一日或上期EXPMA,其中,首次上期EXPMA值为上一期收盘价,N为天数。
寻找出最符合沪深300指数的单EMA、双EMA、多EMA
"""导入常用模块"""import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport datetimefrom jqdata import *from jqlib.technical_analysis import *from environment import * # 导入大树工作室开发的回测模块
securirty = '000300.XSHG'EMA_data = [] HS_data = [] trade_date = get_trade_days(start_date= '2010-01-01', end_date= '2018-12-31') HS_data = get_price(security='000300.XSHG', start_date='2010-1-1', end_date='2018-12-31', frequency='daily', fields=None, skip_paused=False, fq='pre')def get_ema(time_date):return EMA('000300.XSHG', check_date= time_date, timeperiod=25)[securirty] EMA_data = list(map(get_ema, trade_date)) EMA_data = pd.Series(EMA_data, index= HS_data['close'].index) plt.figure(figsize=(20, 9)) plt.plot(HS_data['close'], linewidth = '2') plt.plot(EMA_data, linewidth = '2') plt.title('沪深300指数从2010年到2018的价格曲线') plt.legend(['指数价格', 'EMA均线'], loc=2) plt.show()
由图可得知EMA与MA有相同之处,但比MA更敏感,选择最优的EMA对于趋势判断会有很大帮助,我们就来对比看看多EMA的情况。
plt.figure(figsize=(20, 9)) EMA_list = [15, 30, 45, 60, 75, 90, 105, 120, 135]for number in EMA_list: EMA_data = []for time_date in trade_date: EMA_value = EMA('000300.XSHG', check_date= time_date, timeperiod= number)[securirty] EMA_data.append(EMA_value) EMA_data = pd.Series(EMA_data, index= HS_data['close'].index) EMA_data.plot(linewidth = '2') plt.title('2010年到2018的多EMA曲线图') plt.legend(EMA_list, loc=2) plt.show()
理论:价格在EMA均线之上表示多头行情,价格在EMA均线之下表示空头行情——这种情况是否有效?接下来,做一个数据回测。
因为是做评估,所以这里选择了沪深300指数来交易。可能这有点让人接受不了,人有会说:“指数怎么能交易呢?”笔者是这么想的,对于指标的判断,放在个股上,有的适用,有的则不适用。因其股性的不同,倒不如测试代表标的集合的指数。虽然指数不可交易,但不妨碍我们对其历史数据进行分析。因此,笔者自行搭建了一个回测环境,在交易的时候,默认全仓交易,不考虑交易费用、滑点等不可控因素,所有的数据皆以收盘价为准,并且,成交量也不以每股计算,而是能成交多少算多少,这是为了充分使用资金的原因。因此,这里对数据的评估是存在一定的过拟合现象的。
为了排除这种过拟合现象,我们的应对方法是,当做出评估结果后,再重新写一个回测策略,对验证评估效果,这样的交叉验证可以最大程度的还原数据与评估结果之间的关系。
我们期望的交易模式如下:红圈表示买点,绿圈表示卖点。
securirty = '000300.XSHG'EMA_da = [] HS_da = [] trade_da = get_trade_days(start_date= '2017-01-01', end_date= '2018-12-31') HS_da = get_price(security='000300.XSHG', start_date='2017-1-1', end_date='2018-12-31', frequency='daily', fields=None, skip_paused=False, fq='pre') HS_da_close = HS_da['close']def get_ema(time_date):return EMA('000300.XSHG', check_date= time_date, timeperiod=15)[securirty] EMA_da = list(map(get_ema, trade_da)) EMA_da = pd.Series(EMA_da, index= HS_da_close.index) plt.figure(figsize=(20, 9)) plt.plot(HS_da_close, linewidth=2, color='orange') plt.plot(EMA_da, linewidth=2, c='b')# 找出买点与卖点,分别用红绿圈画出for i in range(1, len(HS_da_close)):if HS_da_close[i-1] < EMA_da[i-1] and HS_da_close[i] > EMA_da[i]: plt.scatter(HS_da_close.index[i], EMA_da[i], color='', marker='o', edgecolors='r', s=300, linewidths=2)elif HS_da_close[i-1] > EMA_da[i-1] and HS_da_close[i] < EMA_da[i]: plt.scatter(HS_da_close.index[i], EMA_da[i], color='', marker='o', edgecolors='g', s=300, linewidths=2) plt.title('沪深300指数从2017年到2018的25EMA买卖点示例图') plt.legend(['收盘价', '25EMA均线'], loc=2) plt.show()
接下来,将上述理念转化成交易策略,并查看其结果:
"""初始化以下内容"""context = Context() # 账户对象order = Order(context) # 下单对象trade = Trade(context, order) # 回测对旬context.start_date = '2010-01-01'context.end_date = '2018-12-31'context.universe = ['000300.XSHG'] context.base = '000300.XSHG'"""策略主体"""def handle(context, order):stock = context.universe[0] HS_da = get_price(security=stock, end_date= context.current_dt, frequency= 'daily', fields= None, skip_paused= False, fq='pre', count= 50)['close'] EMA_da_2 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=15)[stock] EMA_da_1 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=15)[stock]if HS_da[-2] < EMA_da_2 and HS_da[-1] > EMA_da_1: order.buy(stock, HS_da[-1], context.cash // HS_da[-1])elif HS_da[-2] > EMA_da_2 and HS_da[-1] < EMA_da_1: if stock not in context.position.keys():returnorder.sell(stock, HS_da[-1], context.position[stock]['count'])"""执行策略"""trade.trade(handle)
trade_list = [] EMA_list = [15, 30, 45, 60, 75, 90, 105, 120, 135]for _EMA in EMA_list:# 策略结构context = Context() order = Order(context) trade = Trade(context, order) context.start_date = '2010-01-01'context.end_date = '2018-12-31'context.universe = ['000300.XSHG'] context.base = '000300.XSHG'def handle(context, order):stock = context.universe[0] ema_count = _EMA HS_da = get_price(security=stock, end_date= context.current_dt, frequency= 'daily', fields= None, skip_paused= False, fq='pre', count= 150)['close'] EMA_da_2 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count)[stock] EMA_da_1 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count)[stock]if HS_da[-2] < EMA_da_2 and HS_da[-1] > EMA_da_1: order.buy(stock, HS_da[-1], context.cash // HS_da[-1])elif HS_da[-2] > EMA_da_2 and HS_da[-1] < EMA_da_1: if stock not in context.position.keys():returnorder.sell(stock, HS_da[-1], context.position[stock]['count']) trade.trade(handle, False) trade_list.append(trade)# 展示Trade.show_ratio_compare('EMA', EMA_list, trade_list, 3, 3)
Trade.show_result('EMA', EMA_list, trade_list)
由上图数据表对比分析,符合沪深300指数的EMA值为30,即月线EMA。于熊市时候,策略收益图下跌的斜率明显低于其他EMA数值的策略,于牛市时候,策略收益图上涨的斜率会高于其他EMA数值的策略,而且对比其他指标,最大回撤、胜率、策略收益、年化收益排名同列于第一,说明EMA值30是有效的最优参数。
从整体来看,EMA均线比较敏感,值越小开单数也越多,我们可以寻找它本身类似于MA均线的特性来运用于趋势判断来减少开单数,减少不必要的机会成本浪费。
EMA趋势判断逻辑:
EMA单均线判断,今日与隔日EMA均线判断,今日大于隔日为上升趋势,反之为下跌趋势。
EMA单均线判断,今日于一定间隔日EMA均线判断,斜率向上即为上升趋势,反之为下跌趋势。
"""初始化以下内容"""context = Context() # 账户对象order = Order(context) # 下单对象trade = Trade(context, order) # 回测对旬context.start_date = '2010-01-01'context.end_date = '2018-12-31'context.universe = ['000300.XSHG'] context.base = '000300.XSHG'"""策略主体"""def handle(context, order):stock = context.universe[0] HS_da = get_price(security=stock, end_date= context.current_dt, frequency= 'daily', fields= None, skip_paused= False, fq='pre', count= 50)['close'] EMA_da_2 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=30)[stock] EMA_da_1 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=30)[stock]if HS_da[-2] < EMA_da_2 and HS_da[-1] > EMA_da_1:if EMA_da_1 < EMA_da_2:returnorder.buy(stock, HS_da[-1], context.cash // HS_da[-1])elif HS_da[-2] > EMA_da_2 and HS_da[-1] < EMA_da_1: if stock not in context.position.keys():returnorder.sell(stock, HS_da[-1], context.position[stock]['count'])"""执行策略"""trade.trade(handle)
数据回测是以EMA均线30为基础,从数据的指标对比,策略各方面有明显的改善,说明趋势判断是有效的。但是,单以当前一个EMA均线下去对比,是不能够完全突显出效果的,我们就以多个数据来对比。
trade_list = [] EMA_list = [15, 30, 45, 60, 75, 90, 105, 120, 135]for _EMA in EMA_list:# 策略结构context = Context() order = Order(context) trade = Trade(context, order) context.start_date = '2010-01-01'context.end_date = '2018-12-31'context.universe = ['000300.XSHG'] context.base = '000300.XSHG'def handle(context, order):stock = context.universe[0] ema_count = _EMA HS_da = get_price(security=stock, end_date= context.current_dt, frequency= 'daily', fields= None, skip_paused= False, fq='pre', count= 10)['close'] EMA_da_2 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count)[stock] EMA_da_1 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count)[stock]if HS_da[-2] < EMA_da_2 and HS_da[-1] > EMA_da_1:if EMA_da_1 < EMA_da_2:returnorder.buy(stock, HS_da[-1], context.cash // HS_da[-1])elif HS_da[-2] > EMA_da_2 and HS_da[-1] < EMA_da_1: if stock not in context.position.keys():returnorder.sell(stock, HS_da[-1], context.position[stock]['count']) trade.trade(handle, False) trade_list.append(trade)# 展示Trade.show_ratio_compare('EMA', EMA_list, trade_list, 3, 3)
Trade.show_result('EMA', EMA_list, trade_list)
综合上面所有数据来看,EMA均线参数在:30、105、90的取值最为突出,但是临近的EMA均线对比做趋势还是有弊端的,大周期下的小周期会影响到当前的趋势条件。
因此,我们就借用一个间隔跨度来测试数据,取得一个比较能接受的数值来过滤掉大周期下的小周期。
"""初始化以下内容"""context = Context() # 账户对象order = Order(context) # 下单对象trade = Trade(context, order) # 回测对旬context.start_date = '2010-01-01'context.end_date = '2018-12-31'context.universe = ['000300.XSHG'] context.base = '000300.XSHG'"""策略主体"""def handle(context, order):stock = context.universe[0] HS_da = get_price(security=stock, end_date= context.current_dt, frequency= 'daily', fields= None, skip_paused= False, fq='pre', count= 50)['close'] EMA_da_2 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=30)[stock] EMA_da_1 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=30)[stock] EMA_da_30 = EMA('000300.XSHG', check_date= HS_da.index[-30], timeperiod=30)[stock]if HS_da[-2] < EMA_da_2 and HS_da[-1] > EMA_da_1:if EMA_da_1 < EMA_da_30:returnorder.buy(stock, HS_da[-1], context.cash // HS_da[-1])elif HS_da[-2] > EMA_da_2 and HS_da[-1] < EMA_da_1: if stock not in context.position.keys():returnorder.sell(stock, HS_da[-1], context.position[stock]['count'])"""执行策略"""trade.trade(handle)
数据回测是以EMA均线30为基础,日间隔为30,从数据的指标对比,趋势效应加强了策略各方面,收益率的增长0.3535,夏普比率增长0.8311,但是回撤增长0.011,虽然加强了策略,依旧存在有的不足,我们需要找出最优的日间隔。
_list = [] trade_list = [] EMA_list = [15, 30, 45, 60, 75, 90, 105, 120, 135] parmas = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]for _EMA in EMA_list:for pam in parmas:# 策略结构context = Context() order = Order(context) trade = Trade(context, order) context.start_date = '2010-01-01'context.end_date = '2018-12-31'context.universe = ['000300.XSHG'] context.base = '000300.XSHG'_list.append(str(_EMA) ',' str(pam))def handle(context, order):stock = context.universe[0] ema_count = _EMA HS_da = get_price(security=stock, end_date= context.current_dt, frequency= 'daily', fields= None, skip_paused= False, fq='pre', count= 5*pam)['close'] EMA_da_2 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count)[stock] EMA_da_1 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count)[stock] EMA_da_parma = EMA('000300.XSHG', check_date= HS_da.index[-pam], timeperiod=ema_count)[stock]if HS_da[-2] < EMA_da_2 and HS_da[-1] > EMA_da_1:if EMA_da_1 < EMA_da_parma:returnorder.buy(stock, HS_da[-1], context.cash // HS_da[-1])elif HS_da[-2] > EMA_da_2 and HS_da[-1] < EMA_da_1: if stock not in context.position.keys():returnorder.sell(stock, HS_da[-1], context.position[stock]['count']) trade.trade(handle, False) trade_list.append(trade)# 展示Trade.show_all_ratio('EMA', EMA_list, trade_list)
Trade.show_result('EMA', _list, trade_list)
EMA多数据以及日间隔参数回测数据如上,其告诉我们EMA均线30与日间隔参数70是最优搭配,而EMA均线30恰恰是我们曾经单EMA均线历史回测的最优选择之一,间隔70日参数基本是搭配了周期趋势,过滤部分小周期,让策略更加有效。
单EMA均线最优参数以及趋势间隔参数,从实际的运用出发,并不能满足于当前市场的指标。因此,双EMA均线也是必不可少的一部分,所谓“双剑合璧”, 在市场中也能起到互相扶持作用。
trade_list = [] EMA_list = [(15, 30)]for _EMA in EMA_list:# 策略结构context = Context() order = Order(context) trade = Trade(context, order) context.start_date = '2010-01-01'context.end_date = '2018-12-31'context.universe = ['000300.XSHG'] context.base = '000300.XSHG'def handle(context, order):stock = context.universe[0] ema_count = _EMA HS_da = get_price(security=stock, end_date= context.current_dt, frequency= 'daily', fields= None, skip_paused= False, fq='pre', count= 35)['close'] EMA_da_11 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[0])[stock] EMA_da_12 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[0])[stock] EMA_da_21 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[1])[stock] EMA_da_22 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[1])[stock]if EMA_da_12 < EMA_da_22 and EMA_da_11 > EMA_da_21: order.buy(stock, HS_da[-1], context.cash // HS_da[-1])elif EMA_da_12 > EMA_da_22 and EMA_da_11 < EMA_da_21: if stock not in context.position.keys():returnorder.sell(stock, HS_da[-1], context.position[stock]['count']) trade.trade(handle)
trade_list = [] EMA_list = [(5, 15), (15, 30), (30, 45), (45, 60), (60, 75), (75, 90), (90, 105), (105, 120), (120, 135)]for _EMA in EMA_list:# 策略结构context = Context() order = Order(context) trade = Trade(context, order) context.start_date = '2010-01-01'context.end_date = '2018-12-31'context.universe = ['000300.XSHG'] context.base = '000300.XSHG'def handle(context, order):stock = context.universe[0] ema_count = _EMA HS_da = get_price(security=stock, end_date= context.current_dt, frequency= 'daily', fields= None, skip_paused= False, fq='pre', count= 140)['close'] EMA_da_11 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[0])[stock] EMA_da_12 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[0])[stock] EMA_da_21 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[1])[stock] EMA_da_22 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[1])[stock]if EMA_da_12 < EMA_da_22 and EMA_da_11 > EMA_da_21: order.buy(stock, HS_da[-1], context.cash // HS_da[-1])elif EMA_da_12 > EMA_da_22 and EMA_da_11 < EMA_da_21: if stock not in context.position.keys():returnorder.sell(stock, HS_da[-1], context.position[stock]['count']) trade.trade(handle, False) trade_list.append(trade)# 展示Trade.show_ratio_compare('EMA', EMA_list, trade_list, 3, 3)
Trade.show_result('EMA', EMA_list, trade_list)
双EMA均线回测数据表,给我们(15,30)EMA均线为当前均线搭配组合中最优的搭配。前期数据的老伙伴参数30依旧存在,所以我们可以进一步认可30数值在EMA均线中的作用还是有一定影响力的。接下来我们需要加上趋势的对比,来验证是否有优化情况。
_list = [] trade_list = [] EMA_list = [(15, 30)] parmas = [70]for _EMA in EMA_list:for pam in parmas:# 策略结构context = Context() order = Order(context) trade = Trade(context, order) context.start_date = '2010-01-01'context.end_date = '2018-12-31'context.universe = ['000300.XSHG'] context.base = '000300.XSHG'_list.append(str(_EMA) ',' str(pam))def handle(context, order):stock = context.universe[0] ema_count = _EMA HS_da = get_price(security=stock, end_date= context.current_dt, frequency= 'daily', fields= None, skip_paused= False, fq='pre', count= 140)['close'] EMA_da_11 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[0])[stock] EMA_da_12 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[0])[stock] EMA_da_21 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[1])[stock] EMA_da_22 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[1])[stock] EMA_da_pam = EMA('000300.XSHG', check_date= HS_da.index[-pam], timeperiod=ema_count[1])[stock]if EMA_da_12 < EMA_da_22 and EMA_da_11 > EMA_da_21:if EMA_da_21 < EMA_da_pam:returnorder.buy(stock, HS_da[-1], context.cash // HS_da[-1])elif EMA_da_12 > EMA_da_22 and EMA_da_11 < EMA_da_21: if stock not in context.position.keys():returnorder.sell(stock, HS_da[-1], context.position[stock]['count']) trade.trade(handle)
_list = [] trade_list = [] EMA_list = [(5, 15), (15, 30), (30, 45), (45, 60), (60, 75), (75, 90), (90, 105), (105, 120), (120, 135)] parmas = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]for _EMA in EMA_list:for pam in parmas:# 策略结构context = Context() order = Order(context) trade = Trade(context, order) context.start_date = '2010-01-01'context.end_date = '2018-12-31'context.universe = ['000300.XSHG'] context.base = '000300.XSHG'_list.append(str(_EMA) ',' str(pam))def handle(context, order):stock = context.universe[0] ema_count = _EMA HS_da = get_price(security=stock, end_date= context.current_dt, frequency= 'daily', fields= None, skip_paused= False, fq='pre', count= 140)['close'] EMA_da_11 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[0])[stock] EMA_da_12 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[0])[stock] EMA_da_21 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[1])[stock] EMA_da_22 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[1])[stock] EMA_da_pam = EMA('000300.XSHG', check_date= HS_da.index[-pam], timeperiod=ema_count[1])[stock]if EMA_da_12 < EMA_da_22 and EMA_da_11 > EMA_da_21:if EMA_da_21 < EMA_da_pam:returnorder.buy(stock, HS_da[-1], context.cash // HS_da[-1])elif EMA_da_12 > EMA_da_22 and EMA_da_11 < EMA_da_21: if stock not in context.position.keys():returnorder.sell(stock, HS_da[-1], context.position[stock]['count']) trade.trade(handle, False) trade_list.append(trade)# 展示Trade.show_all_ratio('EMA', EMA_list, trade_list)
Trade.show_result('EMA', _list, trade_list)
在双EMA均线与趋势组合的数据中,开始出现了不同的情况,组合(5, 15),(15, 30)排头,然后斜率也各自不同,前者搭配了80-90,后者搭配了20-30的间隔参数。组合的数值会让人想到倍数情况,然后斜率也出现同样的思考,从EMA均线的原理来思考,两个组合的斜率搭配是不是有点相似,但是开单数却完全不同,这个原因是在于EMA的敏感问题,可以说(5, 15)属于高频交易类型,也就是积进,而(15, 30)属于中等频交易类型。这样选择,就要看个人的风格和喜好了。
双EMA均线数据对比有利于研究市场,自然会有多均线情况,短、中、长均线搭配,大多数人会比较喜好,短线情绪,中线风控,长线趋势。我们就来看看,会有什么样的变化。
trade_list = [] EMA_list = [(5, 15, 30)]for _EMA in EMA_list:# 策略结构context = Context() order = Order(context) trade = Trade(context, order) context.start_date = '2010-01-01'context.end_date = '2018-12-31'context.universe = ['000300.XSHG'] context.base = '000300.XSHG'def handle(context, order):stock = context.universe[0] ema_count = _EMA HS_da = get_price(security=stock, end_date= context.current_dt, frequency= 'daily', fields= None, skip_paused= False, fq='pre', count= 35)['close'] EMA_da_11 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[0])[stock] EMA_da_12 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[0])[stock] EMA_da_21 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[1])[stock] EMA_da_22 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[1])[stock] EMA_da_31 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[2])[stock] EMA_da_32 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[2])[stock]if EMA_da_12 < EMA_da_22 and EMA_da_11 > EMA_da_21:if EMA_da_21 < EMA_da_31: returnorder.buy(stock, HS_da[-1], context.cash // HS_da[-1])elif EMA_da_12 > EMA_da_22 and EMA_da_11 < EMA_da_21: if stock not in context.position.keys():returnorder.sell(stock, HS_da[-1], context.position[stock]['count']) trade.trade(handle)
2019-02-23 17:31:43.469758,回测完毕,用时0:00:21.368093
trade_list = [] EMA_list = [(5, 15, 30), (15, 30, 45), (30, 45, 60), (45, 60, 75), (60, 75, 90), (75, 90, 105), (90, 105, 120), (105, 120, 135), (120, 135, 150)]for _EMA in EMA_list:# 策略结构context = Context() order = Order(context) trade = Trade(context, order) context.start_date = '2010-01-01'context.end_date = '2018-12-31'context.universe = ['000300.XSHG'] context.base = '000300.XSHG'def handle(context, order):stock = context.universe[0] ema_count = _EMA HS_da = get_price(security=stock, end_date= context.current_dt, frequency= 'daily', fields= None, skip_paused= False, fq='pre', count= 160)['close'] EMA_da_11 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[0])[stock] EMA_da_12 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[0])[stock] EMA_da_21 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[1])[stock] EMA_da_22 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[1])[stock] EMA_da_31 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[2])[stock] EMA_da_32 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[2])[stock]if EMA_da_12 < EMA_da_22 and EMA_da_11 > EMA_da_21:if EMA_da_21 < EMA_da_31: returnorder.buy(stock, HS_da[-1], context.cash // HS_da[-1])elif EMA_da_12 > EMA_da_22 and EMA_da_11 < EMA_da_21: if stock not in context.position.keys():returnorder.sell(stock, HS_da[-1], context.position[stock]['count']) trade.trade(handle, False) trade_list.append(trade)# 展示Trade.show_ratio_compare('EMA', EMA_list, trade_list, 3, 3)
2019-02-23 17:32:58.042600,回测完毕,用时0:00:20.4705362019-02-23 17:33:19.926138,回测完毕,用时0:00:21.8833682019-02-23 17:33:43.443715,回测完毕,用时0:00:23.5174232019-02-23 17:34:07.823422,回测完毕,用时0:00:24.3795482019-02-23 17:34:32.905529,回测完毕,用时0:00:25.0819362019-02-23 17:34:59.589667,回测完毕,用时0:00:26.683975
/home/jquser/指标研究/environment.py:190: RuntimeWarning: divide by zero encountered in double_scalars return abs(ratio[ratio > 0].sum()/ratio[ratio < 0].sum())
2019-02-23 17:35:27.066525,回测完毕,用时0:00:27.4767032019-02-23 17:35:55.787378,回测完毕,用时0:00:28.7207022019-02-23 17:36:24.890741,回测完毕,用时0:00:29.103209
Trade.show_result('EMA', EMA_list, trade_list)
多EMA均线组合数据表明,(15, 30, 45)为当前组合的最优组合,可以看见老战友依旧还没战死,这是非常可喜的一个事情。整体数据与双EMA均线组合对比,最亮眼的是盈亏比数据,有明显的提升。
_list = [] trade_list = [] EMA_list = [(5, 15, 30)] parmas = [70]for _EMA in EMA_list:for pam in parmas:# 策略结构context = Context() order = Order(context) trade = Trade(context, order) context.start_date = '2010-01-01'context.end_date = '2018-12-31'context.universe = ['000300.XSHG'] context.base = '000300.XSHG'_list.append(str(_EMA) ',' str(pam))def handle(context, order):stock = context.universe[0] ema_count = _EMA HS_da = get_price(security=stock, end_date= context.current_dt, frequency= 'daily', fields= None, skip_paused= False, fq='pre', count= 140)['close'] EMA_da_11 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[0])[stock] EMA_da_12 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[0])[stock] EMA_da_21 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[1])[stock] EMA_da_22 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[1])[stock] EMA_da_31 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[2])[stock] EMA_da_32 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[2])[stock] EMA_da_pam = EMA('000300.XSHG', check_date= HS_da.index[-pam], timeperiod=ema_count[1])[stock]if EMA_da_12 < EMA_da_22 and EMA_da_11 > EMA_da_21:if EMA_da_21 < EMA_da_pam or EMA_da_21 < EMA_da_31:returnorder.buy(stock, HS_da[-1], context.cash // HS_da[-1])elif EMA_da_12 > EMA_da_22 and EMA_da_11 < EMA_da_21: if stock not in context.position.keys():returnorder.sell(stock, HS_da[-1], context.position[stock]['count']) trade.trade(handle)
2019-02-23 17:38:42.753355,回测完毕,用时0:00:23.896671
_list = [] trade_list = [] EMA_list = [(5, 15, 30), (15, 30, 45), (30, 45, 60), (45, 60, 75), (60, 75, 90), (75, 90, 105), (90, 105, 120), (105, 120, 135), (120, 135, 150)] parmas = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]for _EMA in EMA_list:for pam in parmas:# 策略结构context = Context() order = Order(context) trade = Trade(context, order) context.start_date = '2010-01-01'context.end_date = '2018-12-31'context.universe = ['000300.XSHG'] context.base = '000300.XSHG'_list.append(str(_EMA) ',' str(pam))def handle(context, order):stock = context.universe[0] ema_count = _EMA HS_da = get_price(security=stock, end_date= context.current_dt, frequency= 'daily', fields= None, skip_paused= False, fq='pre', count= 140)['close'] EMA_da_11 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[0])[stock] EMA_da_12 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[0])[stock] EMA_da_21 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[1])[stock] EMA_da_22 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[1])[stock] EMA_da_31 = EMA('000300.XSHG', check_date= HS_da.index[-1], timeperiod=ema_count[2])[stock] EMA_da_32 = EMA('000300.XSHG', check_date= HS_da.index[-2], timeperiod=ema_count[2])[stock] EMA_da_pam = EMA('000300.XSHG', check_date= HS_da.index[-pam], timeperiod=ema_count[1])[stock]if EMA_da_12 < EMA_da_22 and EMA_da_11 > EMA_da_21:if EMA_da_21 < EMA_da_pam or EMA_da_21 < EMA_da_31:returnorder.buy(stock, HS_da[-1], context.cash // HS_da[-1])elif EMA_da_12 > EMA_da_22 and EMA_da_11 < EMA_da_21: if stock not in context.position.keys():returnorder.sell(stock, HS_da[-1], context.position[stock]['count']) trade.trade(handle, False) trade_list.append(trade)# 展示Trade.show_all_ratio('EMA', EMA_list, trade_list)
Trade.show_result('EMA', _list, trade_list)
在多EMA均线与趋势组合的数据中,无独有偶,出现了特殊情况,组合(5, 15, 30),(15, 30,45)排头,然后斜率依旧为80-90与20-30的间隔参数。多个数据表明,30的数值在EMA均线中地位比较显赫。搭配的多EMA均线组合在开单方面,大大减少,在盈亏比中,提高也大,回撤也有一定程度的减小,它使得EMA均线在应对市场的时候,更沉稳了。
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程