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

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
    

 

<think>好的,我现在要帮用户了解或实现期货量化交易策略,包括实现方法、示例代码和算法设计。首先,我需要回顾用户提供的引用内容,看看有没有相关的信息可以直接应用。 用户提供的引用[1]提到设计和实现量化交易策略的关键步骤,包括策略构思、数据处理、策略开发、风险管理等。这对于期货量化交易同样适用,所以可以借鉴这个框架来组织回答。 引用[4]中的示例代码是关于股票Amihud非流动性因子的计算,虽然针对的是股票,但数据处理和分组的方法可能对期货数据处理有参考价值。比如,期货数据也需要按合约和日期处理,可能需要进行类似的分组计算。 引用[3]讨论了蚁群算法的优化问题,但用户提到他们的问题需要一种新的通用算法,这可能意味着在期货策略中,传统算法可能需要调整。不过,用户当前的问题可能不需要这么复杂的优化算法,可能更基础的策略比如均线交叉、动量策略更适合示例代码。 接下来,我需要考虑期货量化交易的特殊性。期货通常涉及保证金、杠杆、多空双向交易,还有不同合约的到期处理,比如滚动合约。这些在策略实现时需要特别注意。 用户需要实现方法,示例代码和算法设计。实现方法部分可以按照引用[1]的结构展开,但具体到期货。示例代码部分可能需要一个简单的策略,比如双均线策略,因为容易实现,并且能展示数据处理和信号生成的过程。算法设计方面,需要说明策略的逻辑,比如入场出场条件,风险管理措施。 另外,风险管理和回测是关键步骤,所以在示例代码中应该包含简单的风险管理,比如仓位控制。但考虑到代码复杂度,可能先展示基本框架,再提到扩展的可能性。 需要确保代码部分使用Python,因为引用[4]中的代码也是Python,并且量化领域常用Python。可能需要用到pandas进行数据处理,backtrader或者zipline等回测框架,但为了简化,可能用基础的pandas和手动回测,以便用户更容易理解。 可能的问题:如何处理期货合约滚动?在示例中可能暂时忽略,或者简单处理为使用主力连续合约,假设数据已经处理好。数据源方面,用户可能需要自己获取,但示例代码可以假设已经有OHLC数据。 算法设计部分,双均线策略的逻辑是当短期均线上穿长期均线时做多,下穿时做空或平仓。需要说明参数选择,比如均线周期,如何生成信号,以及执行交易。 风险管理部分,可以包括固定比例仓位,设置止损止盈,但示例代码可能先实现信号生成,风险管理作为扩展点提及。 最后,生成的相关问题需要围绕期货量化策略的不同方面,比如风险管理具体方法、主力合约处理、策略优化方法,以及趋势跟踪策略的其他例子。</think>### 期货量化交易策略实现方法 #### 1. 策略设计流程 1. **策略构思** 选择期货品种(如商品期货、股指期货),定义交易逻辑: - 趋势跟踪(如双均线策略) - 套利策略(跨期/跨品种套利) - 高频交易(盘口价差捕捉)[^1] 2. **数据处理** - 获取期货主力连续合约的OHLC数据 - 处理合约换月时的价格跳空 - 添技术指标(如MACD、布林带) $$MA_{fast} = \frac{1}{n}\sum_{i=1}^{n}Close_{t-i}$$ $$MA_{slow} = \frac{1}{m}\sum_{i=1}^{m}Close_{t-i} \quad (m > n)$$ 3. **策略开发** 定义信号生成规则(示例): - 当$MA_{fast} > MA_{slow}$时做多 - 当$MA_{fast} < MA_{slow}$时平仓 4. **风险管理** - 单笔交易最大仓位≤5% - 动态止损(如3倍ATR止损) #### 2. 示例代码Python) ```python import pandas as pd # 数据预处理(假设df包含datetime, open, high, low, close) df['ma_fast'] = df['close'].rolling(window=5).mean() df['ma_slow'] = df['close'].rolling(window=20).mean() # 生成交易信号 df['signal'] = 0 df.loc[df['ma_fast'] > df['ma_slow'], 'signal'] = 1 # 做多 df.loc[df['ma_fast'] < df['ma_slow'], 'signal'] = 0 # 平仓 # 计算收益(忽略手续费和滑点) df['returns'] = df['close'].pct_change() df['strategy_returns'] = df['signal'].shift(1) * df['returns'] # 输出累计收益 cumulative_returns = (1 + df['strategy_returns']).cumprod() print(f"累计收益率: {cumulative_returns.iloc[-1]:.2%}") ``` #### 3. 算法设计要点 | 模块 | 实现要点 | |--------------|---------------------------------| | 信号生成 | 动态阈值避免过度交易 | | 订单执行 | 根据tick级数据模拟实际成交 | | 风险控制 | 实时监测保证金比例和波动率 | | 绩效分析 | 计算夏普比率、最大回撤等指标[^4] |
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值