美文网首页程序员
量化交易-MACD策略学习

量化交易-MACD策略学习

作者: 东南有大树 | 来源:发表于2018-11-04 15:44 被阅读103次

    MACD的基本概念,可以参考 https://www.joinquant.com/post/7095?f=18newyearjx ,感谢 Quant中找米吃的阿鼠 和 聚宽小秘书 Thanks♪(・ω・)ノ

    我认为MACD不适合采用轮动策略,经过回测,我将策略改成以下模式:😆

    • 选出基本面较好的股票
    • 剔除ST、停牌、退市的股票
    • 在DIF和DEA在0轴上形成金叉时买入
    • 在DIF他DEA的0轴下形成死叉时卖出
    • 加入止损:这次的止损买有根据股票的盈亏来判断,而是:
      • 记录持仓股票的每天的盈利,如果当天盈利比之前的盈利小,则不记录
      • 如果当天判断的盈利已经比记录的最大盈利小20%,则止损卖出

    下面👇是回测结果和源代码

    import numpy as np
    import pandas as pd
    # 导入技术分析库
    import talib as tb
    
    def 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.02
        set_slippage(FixedSlippage(0.02))
        
        # 设定2013年前与2013年后的交易费用
        dt = context.current_dt
        if 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]
        # 剔除st
        stocks_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'])
            # 将价格值转换成ndarray
            price = 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].avg_cost
            price = context.portfolio.positions[stock].price
            ret = (price/cost) - 1
            
            # 记录收益率,如果当前收益率比之前大,替换之前的记录
            # 如果当前收益率比记录的最大收益率小20%,止损,卖出
            if stock in g.retio.keys():
                if ret > g.retio[stock]:
                    g.retio[stock] = ret
                elif (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.available_cash / len(buy_list)
            for stock in buy_list:
                order_value(stock, Cash)
    

    相关文章

      网友评论

        本文标题:量化交易-MACD策略学习

        本文链接:https://www.haomeiwen.com/subject/jworxqtx.html