我认为MACD不适合采用轮动策略,经过回测,我将策略改成以下模式:
我认为MACD不适合采用轮动策略,经过回测,我将策略改成以下模式:😆
下面👇是回测结果和源代码
import numpy as npimport pandas as pd# 导入技术分析库import talib as tbdef initialize(context):"""初始化函数"""# 记录股票的收益率g.retio = {}# 设置中证500为参考基准set_benchmark('000905.XSHG')# 使用真实价格交易set_option('use_real_price', True)# 设定日志级别log.set_level('order', 'error')# 指定周期*易函数run_daily(trade, 'every_bar')def before_trading_start(context):"""开盘前设置交易费用"""# 设定所有类型的交易品种的交易滑点为0.02set_slippage(FixedSlippage(0.02))# 设定2013年前与2013年后的交易费用dt = context.current_dtif dt>datetime.datetime(2013,1, 1):set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')else:set_order_cost(OrderCost(open_tax=0, open_commission=0.003,close_commission=0.003, close_tax=0.001,min_commission=5), type='stock')def trade(context):"""交易函数"""# g.days += 1# if g.days % g.refresh_rate != 1:# return'''一、挑选出高质量的股票'''stocks_choose = get_fundamentals(query(valuation.code).filter(valuation.pe_ratio < 40,valuation.pe_ratio > 10,indicator.eps > 0.3,indicator.inc_net_profit_annual > 0.30,indicator.roe > 15).order_by(valuation.pb_ratio.asc()).limit(50), date=None)# 将股票代码集转成ndarray,因为它比列表的计算速度更快stocks_pool = stocks_choose['code'].values'''二、剔除st、停牌、退市的股票'''current_data = get_current_data()# 剔除停牌stocks_pool = [stock for stock in stocks_pool if not current_data[stock].paused]# 剔除ststocks_pool = [stock for stock in stocks_pool if not current_data[stock].is_st]# 剔除退市stocks_pool = [stock for stock in stocks_pool if not '退' in current_data[stock].name]'''三、股票交易条件判断'''# 买入列表stocks_long = []# 卖出列表stocks_short = []# 继续持有列表stocks_hold = []#MACD判断for stock in stocks_pool:# 获得之前300天的收盘价prices = attribute_history(stock, 300, '1d', ['close'])# 将价格值转换成ndarrayprice = np.array(prices['close'])# 计算MACD值DIF, DEA, MACD = tb.MACD(price, fastperiod=12, slowperiod=26, signalperiod=20)# 在0轴上金叉买入if DIF[-1] > 0 and DEA[-1] > 0:if (DIF[-2] <= DEA[-2]) and (DIF[-1] > DEA[-1]):stocks_long.append(stock)# 在0轴之下死叉卖出elif DIF[-1] < 0 and DEA[-1] < 0:if (DIF[-2] >= DEA[-2]) and (DIF[-1] < DEA[-1]):stocks_long.append(stock)
'''四、卖出持仓中符合卖出条件的股票'''# 持仓hold_list = list(context.portfolio.positions.keys())# 判断for stock in hold_list:# 计算持仓股票的收益率cost = context.portfolio.positions[stock].*g_costprice = context.portfolio.positions[stock].priceret = (price/cost) - 1# 记录收益率,如果当前收益率比之前大,替换之前的记录# 如果当前收益率比记录的最大收益率小20%,止损,卖出if stock in g.retio.keys():if ret > g.retio[stock]:g.retio[stock] = retelif (ret - g.retio[stock]) < -0.2:order_target_value(stock, 0)del g.retio[stock]else:g.retio[stock] = ret# 将在卖出列表中的股票卖出if stock in stocks_short:order_target_value(stock, 0)# 继续持仓的股票else:stocks_hold.append(stock)'''五、买入符合条件的股票'''# 买入列表,已经持仓的不再重复买入buy_list = list(set(stocks_long) - set(stocks_hold))# 买入if len(buy_list) > 0:Cash = context.portfolio.*ailable_cash / len(buy_list)for stock in buy_list:order_value(stock, Cash)