用python写期货量化策略,期货单品种MACD择时加ATR止损

13 篇文章 3 订阅
7 篇文章 2 订阅
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
    

 

  • 14
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值