当前位置 博文首页 > LY的博客:用python写期货量化策略,期货单品种MACD择时加ATR止

    LY的博客:用python写期货量化策略,期货单品种MACD择时加ATR止

    作者:[db:作者] 时间:2021-08-09 18:51

    import numpy as np
    import talib
    import time
    import jqdata
    import talib
    import smtplib
    from email.mime.text import MIMEText
    from email.header import Header
    
    ## 初始化函数,设定基准等等
    def initialize(context):
        #上海期货交易所产品
        '''AG8888.XSGE	白银期货指数	PB8888.XSGE	铅期货指数
        AU8888.XSGE	黄金期货指数	RB8888.XSGE	螺纹钢期货指数
        AL8888.XSGE	铝期货指数	RU8888.XSGE	天然橡胶期货指数
        BU8888.XSGE	石油沥青期货指数	SN8888.XSGE	锡期货指数
        CU8888.XSGE	铜期货指数	WR8888.XSGE	线材期货指数
        FU8888.XSGE	燃料油期货指数	ZN8888.XSGE	锌期货指数
        HC8888.XSGE	热轧卷板期货指数	NI8888.XSGE	镍期货指数
        SP8888.XSGE	纸浆主力合约		
        '''
        g.stockkind='AG'
        g.stockcode=str('AG9999.XSGE')
        #g.stockkind='AU'
        #g.stockkind='RB'
        
        # 设定XX期货作为基准
        set_benchmark('AG9999.XSGE')
        # 开启动态复权模式(真实价格)
        set_option('use_real_price', True)
        # 过滤掉order系列API产生的比error级别低的log
        # log.set_level('order', 'error')
        # 输出内容到日志 log.info()
        log.info('初始函数开始运行且全局只运行一次')
        
        # 开盘前运行
        run_daily( before_market_open, time='09:00', reference_security='AG9999.XSGE')
        
        ### 期货相关设定 ###
        # 设定账户为金融账户
        set_subportfolios([SubPortfolioConfig(cash=context.portfolio.starting_cash, type='index_futures')])
        # 期货类每笔交易时的手续费是:买入时万分之0.23,卖出时万分之0.23,平今仓为万分之23
        set_order_cost(OrderCost(open_commission=0.000023, close_commission=0.000023,close_today_commission=0.0023), type='index_futures')
        # 设定保证金比例
        set_option('futures_margin_rate', 0.15)
    
        # 设置期货交易的滑点
        set_slippage(StepRelatedSlippage(2))
        # 运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'IF8888.CCFX'或'IH1602.CCFX'是一样的)
        # 注意:before_open/open/close/after_close等相对时间不可用于有夜盘的交易品种,有夜盘的交易品种请指定绝对时间(如9:30)
        
    
    
     
    ## 开盘前运行函数
    def before_market_open(context):
    
        # 输出运行时间
        log.info('函数运行时间(before_market_open):'+str(context.current_dt.time()))
    
        # 给微信发送消息(添加模拟交易,并绑定微信生效)
        # send_message('美好的一天~')
        #stocklist=[]
        ## 获取主力合约
        g.domin=get_dominant_future(g.stockkind, date=context.previous_date)
        print (g.domin)
        
        #买入信号
        g.sign=0
        #当日清仓标志
        g.clear=0
    
    ## 开盘时运行函数
    def handle_data(context,data):
        
        log.info('函数运行时间(market_open):'+str(context.current_dt.time()))
        
        timeArray = context.current_dt.time().strftime('%H:%M:%S')
        #timeArray = time.strptime(context.current_dt.time(), "%H:%M:%S")
        clocktime=int(str(timeArray)[-5:-3])
        
        if clocktime % 5 == 0:  
            deal(context)
        else:
            pass
        
        
    
    def deal(context):
        ## 交易
    
        # 获取当月合约交割日期
        end_data = get_CCFX_end_date(g.domin)
        
        
        #判断g.sign  做macd交易判断
        df=get_price(g.stockcode ,count=40, end_date=context.current_dt, frequency='15m',fields='close')
        df2=get_price(g.stockcode ,count=40, end_date=context.current_dt, frequency='60m',fields='close')
        df3=get_price(g.stockcode ,count=40, end_date=context.current_dt, frequency='240m',fields='close')
        df4=get_price(g.stockcode ,count=40, end_date=context.current_dt, frequency='1d',fields='close')
        macd_15min=macd(df['close'])[0]
        
        macd_60min=macd(df2['close'])[0]
        macd_1h=macd_60min
        macd_4h=macd(df3['close'])[0]
        macd_4h_diff=macd(df3['close'])[1]
        macd_4h_dea=macd(df3['close'])[2]
        macd_1d=macd(df4['close'])[0]
        
        #print (macd_15min)
        #print (macd_60min)
        
    
        #止损清仓判断
        if tralling_stop(context, g.stockcode)==1:
            #止损多头
            order_target(g.domin, 0, side='long')
            g.sign=0
            g.clear=1
            
        elif tralling_stop(context, g.stockcode)==-1:
            
            #止损空头
            order_target(g.domin, 0, side='short')
            g.sign=0
            g.clear=-1
        
        #开仓同时保证自己当日没有过当前方向的清仓
        '''
        if macd_15min[-1]>0 and macd_15min[-2]<=0 and macd_60min[-1]>0 and g.clear<1:
            g.sign=1
        elif  macd_15min[-1]<0 and macd_15min[-2]>=0 and macd_60min[-1]<0 and g.clear>-1:
            g.sign=-1
        '''
        '''
        if macd_1h[-1]>0 and macd_1h[-2]<=0 and macd_1d[-1]>0 and g.clear<1:
            g.sign=1
        elif  macd_1h[-1]<0 and macd_1h[-2]>=0 and macd_1d[-1]<0 and g.clear>-1:
            g.sign=-1
            
        '''
        #单纯macd
        if macd_4h[-1]>0>macd_4h[-2] and macd_4h_diff[-1]>0 and macd_4h_dea[-1]>0:
            g.sign=1
        elif macd_4h[-1]<0<macd_4h[-2]and macd_4h_diff[-1]<0 and macd_4h_dea[-1]<0:
            g.sign=-1
            
        
        
    
        # 判断当月合约交割日当天不开仓,多头交易
        if (g.sign==1):
            if (context.current_dt.date() == end_data):
                
                pass
            else:
                #如果空仓>=0,开多仓
                if (len(context.portfolio.short_positions) >= 0 and len(context.portfolio.long_positions) == 0):
                    log.info('开多仓---:')
                    
                    if len(context.portfolio.short_positions) >0 :
                        # 平仓空头
                        order_target(g.domin, 0, side='short')
           
                    # 做多头合约
                    print('开多头合约')
                    if context.portfolio.available_cash>3500:
                        order_value(g.domin, 0.9*context.portfolio.available_cash , side='long')
                        g.sign=1
                    else:
                        print ('没钱开仓')
                    
    
                    
        #空头交易
        if (g.sign == -1):
            if (context.current_dt.date() == end_data):
                # return
                pass
            else:
                #如果多仓>=0,开空仓
                if (len(context.portfolio.short_positions) >= 0 and len(context.portfolio.long_positions) == 0):
                    log.info('开空仓---:')
                    
                    if len(context.portfolio.long_positions) >0 :
                        # 平仓多头
                        order_target(g.domin, 0, side='long')
                    # 开空头合约
                    print('开空头合约')
                    if context.portfolio.available_cash>3500:
                        order_value(g.domin, 0.9*context.portfolio.available_cash , side='short')
                        g.sign=-1
                    else:
                        print ('没钱开仓')
        else:
            pass
    
    
    def fasong(message,targetmail):
    
    
        '''发送邮箱'''
        sender = 'XXX@163.com' #企业263邮箱
        '''接收邮箱'''
        receiver = targetmail
        '''发送邮件主题'''
        subject = 'message stock'
        '''发送邮箱服务器'''
        smtpserver = 'smtp.163.com'
        '''发送邮箱用户/密码'''
        username = 'XXX@163.com'
        password = 'XXXXX'
        '''中文需参数‘utf-8’ ,单字节字符不需要'''
        msg = MIMEText(message,'plain','utf-8')
        msg['Subject'] = Header(subject, 'utf-8')
        msg['From'] = 'XX<XXXX@163.com>'
        msg['To'] = targetmail
        smtp = smtplib.SMTP()
        smtp.connect('smtp.163.com')
        smtp.login(username, password)
        smtp.sendmail(sender, receiver, msg.as_string())
        smtp.quit()
        print ("Email has been sent out!")   
        
        
    ########################## 获取期货合约信息,请保留 #################################
    # 获取金融期货合约到期日
    def get_CCFX_end_date(future_code):
        # 获取金融期货合约到期日
        return get_security_info(future_code).end_date
        
        
    ###############
    def macd(close):
        macdDIFF, macdDEA, macd = talib.MACDEXT(close, fastperiod=12, fastmatype=1, slowperiod=26, slowmatype=1, signalperiod=9, signalmatype=1)
        macd = macd * 2
        list1=[macd,macdDIFF,macdDEA]
        return list1
    
    
    
    
    def tralling_stop(context, stock_code):    
        ATR_timeperiod=14
        # 获取stock_code股票的历史数据
        Data_ATR=get_price(stock_code ,count=ATR_timeperiod+10, end_date=context.current_dt, frequency='15m',fields=['close','high','low'])
        close_ATR = Data_ATR['close']
        high_ATR = Data_ATR['high']
        low_ATR = Data_ATR['low']
    
        # 计算stock_code股票的AT
        atr = talib.ATR(high_ATR, low_ATR, close_ATR)
        highest20 = max(close_ATR[-20:])
        lowest20 = min(close_ATR[-20:])
        
          
        
        if ((highest20 - close_ATR[-1]) > (2*atr[-1])) and len(context.portfolio.long_positions) >0:
            print('ATR多头止损')
            return 1
        elif ((close_ATR[-1] - lowest20 ) > (2*atr[-1])) and len(context.portfolio.short_positions) >0:
            print('ATR空头止损')
            return -1
        else:
            return 0
        

    ?

    cs
    下一篇:没有了