克隆策略

日内通道突破策略

交易回测基本参数

  • 交易合约:RB1901
  • 交易时间:2018-04-20 ~ 2018-05-20
  • 数据频率:分钟
  • 保证金比例:7%
  • 交易成本:
    • 开仓成本:万分之5
    • 平仓成本:万分之5

交易信号逻辑

我们借鉴唐奇安通道的思想,把它应用到期货日内的交易中。在当日交易中,我们会构建一个回溯周期60个bar的通道,每一个bar都是一分钟的蜡烛tick。当下一根bar收盘价高于这个通道的上限,则做多; 当下一根bar收盘价低于这个通道的下限,则做空。为避免交易次数过多,我们每天最多交易三次。并且我们会在当日晚盘快结束时,了结当日仓位。

In [1]:
import talib as ta
# 1. 策略基本参数
start_date = '2018-04-20 09:01:00'
end_date = '2018-05-20 15:15:00'
benchmark = instruments = 'RB1901.SHF'
TRADING_UNIT = 5
DAILY_TRADING_LIMITS = 2
LOOKBACK_WINDOW = 60
DAY_END_HOUR = 22
DAY_END_MINUTE = 50
EMPTY_POSITION = 0

# 2. 策略主体函数
# 初始化虚拟账户状态,只在第一个交易日运行
def initialize(context):
    # 设置手续费,买入时万3,卖出是千分之1.3,不足5元以5元计
    context.set_commission(futures_commission=PerContract(cost={'RB':(0.000045, 0.000045, 0.000045)}))
    context.set_margin('RB', 0.07)
    context.index = 1              #日期记录
    context.position_counts = 0
    
# 策略交易逻辑,handle_data函数会每个周期(日/分)运行一次,可以把行情数据理解成K线,
# 然后handle_data函数会在每个K线上依次运行
def handle_data(context, data):
    today = data.current_dt#.strftime('%Y-%m-%d-%H-%M')
    instrument_symbol = context.future_symbol(context.instruments[0]) # 交易标的
    curr_position = context.portfolio.positions[instrument_symbol].amount # 持仓数量
    
    if context.index < LOOKBACK_WINDOW: # 日内数据超过窗口范围
        context.index += 1
        return
    if today.hour >= DAY_END_HOUR and today.minute >= DAY_END_MINUTE:
        context.index = 1              # 下标初始化
        context.position_counts = 0
        # 了结当日仓位
        if curr_position != EMPTY_POSITION:
            context.order_target(instrument_symbol, EMPTY_POSITION)
        return
    
    price = data.history(instrument_symbol, 'close', LOOKBACK_WINDOW, '1m') 

    # 如果当前没有仓位,且大于通道价格上限,long开仓
    if curr_position <= 0 and price.iloc[-1] > price.iloc[(-1-LOOKBACK_WINDOW):-1].max() and context.position_counts < DAILY_TRADING_LIMITS:
        context.position_counts += 1 
        context.order_target(instrument_symbol, TRADING_UNIT)
    elif curr_position >= 0 and price.iloc[-1] < price.iloc[(-1-LOOKBACK_WINDOW):-1].min() and context.position_counts < DAILY_TRADING_LIMITS:
        context.position_counts += 1
        context.order_target(instrument_symbol, -TRADING_UNIT)
    

# 3. 启动回测
m = M.trade.v4(
    instruments=instruments,
    start_date=start_date,
    end_date=end_date,
    initialize=initialize,
    handle_data=handle_data,
    # 股票买入的时候,假设以次日开盘价成交
    order_price_field_buy='open',
    # 股票卖出的时候,假设以次日开盘价成交
    order_price_field_sell='open',
    capital_base=50000,
    benchmark=benchmark,
    volume_limit=0,
    data_frequency='minute',
    product_type='future',
    m_deps=np.random.rand()
)
[2018-10-09 16:34:01.149245] INFO: bigquant: backtest.v8 开始运行..
[2018-10-09 16:34:01.157068] INFO: bigquant: biglearning backtest:V8.1.0
[2018-10-09 16:34:01.158224] INFO: bigquant: product_type:future by specified
[2018-10-09 16:34:05.348657] INFO: algo: TradingAlgorithm V1.2.9
[2018-10-09 16:34:53.651325] INFO: Performance: Simulated 19 trading days out of 19.
[2018-10-09 16:34:53.652341] INFO: Performance: first open: 2018-04-20 09:01:00+00:00
[2018-10-09 16:34:53.652980] INFO: Performance: last close: 2018-05-18 15:00:00+00:00
  • 收益率26.72%
  • 年化收益率2213.14%
  • 基准收益率3.42%
  • 阿尔法2.68
  • 贝塔1.38
  • 夏普比率5.55
  • 胜率0.59
  • 盈亏比2.08
  • 收益波动率59.26%
  • 信息比率0.35
  • 最大回撤4.77%
[2018-10-09 16:34:58.580781] INFO: bigquant: backtest.v8 运行完成[57.431588s].