• QQ空间
  • 回复
  • 收藏

事件驱动策略(基于业绩快报)

KUO 数据策略 2020-11-12 15:03 136023人围观

事件驱动(Event Driven)属于量化投资之中的一个重要类别,涵盖投资机会广泛。广义上说,市场上任何发生的有可能与股票市场相关的新闻、事件、公告均有可能成为事件驱动的投资机会。 目前我国业界事件驱动策略中包括的常用重大事件有:业绩预告、业绩快报、分红送转、大股东增减持、高管增减持、定向增发、限售股解禁、股权激励、重组并购、ST摘和评级上调等,如下图所示。

可以看出,目前市场经过验证有效的事件已经不少,涵盖了影响股票价格的多个方面。事件驱动策略由于其策略逻辑的独特性,因此与其他常规股票策略相关性很低,再加上事件众多,资金容量大这一特点,使得事件驱动策略成为国外对冲基金非常大类的投资策略。

BigQuant回测引擎能够快速验证事件的有效性,从而开发事件驱动策略。为方便小伙伴顺利开发事件驱动策略,本文以业绩快报中净利润大幅增长为事件,验证该事件是否可以带来超额收益,未来我们会发布更多的基于其他事件的策略,敬请耐心等待。

在回测之前,我们先看策略的完整介绍:

  • 策略逻辑:认为业绩快报中净利润大幅增长为利好消息,会导致价格在一定期限内上涨
  • 事件定义:当业绩快报中公布净利润同比增增长超过30%
  • 股票持有不超过50只,仅当持有数量小于50只时,才买入股票
  • 持有时间:40个交易日

我们的策略流程是:每日更新数据,查看当日发布财务报表并且(归属母公司)净利润季度同比增长率超过30%的公司,如果出现这样的事件,就买入该股票。策略回测结果为:

从测试结果来看,该事件驱动策略为长期正收益系统。因为财报公布事件会有一个期限规定(年度报告是每年结束后4个月内,半年度是上半年结束后2个月内,季度报告是季度结束后1个月内),所以某些时间段不会有公司公布财务报表,当然那段时间就不会出现业绩快报净利润大幅增长的事件,因此仓位很多时候并不是100%。

备注:上市公司财报披露时间一般是财报发布日期的前一天晚上8点,因此策略回测中订单生成时间是财报公布日前一天,目的是便于回测和实盘保持一致性。

想要查看完整策略,点击 克隆策略一键搞定。

事件驱动策略:基于业绩快报

数据准备函数

def prepare(context):
    instruments = context.instruments
    start_date = context.start_date
    end_date = context.end_date
    # 获取数据
    data = D.financial_statements(instruments, start_date, end_date, 
          fields=['instrument','fs_publish_date','fs_quarter_year',
          'fs_quarter_index','fs_net_profit_yoy'])
    # 选择净利润同比增长率大于30%的股票
    selected = data[data['fs_net_profit_yoy'] > 30] 

    # 获取交易日历
    date = D.trading_days(start_date=start_date,end_date=end_date)
    # 将日期型格式转化为字符型格式
    date = date['date'].apply(lambda x : x.strftime('%Y-%m-%d'))
    # 为尽量接近实盘,事件日期应为财报公布日的前一天
    publish_date = date.shift(-1)
    shift = dict(zip(date, publish_date))

    # 建立事件表
    event = {}
    for dt in date:
        if type(shift[dt]) is str:
            event[dt] = list(selected[selected['fs_publish_date'] == shift[dt]].sort_values(
                'fs_net_profit_yoy',ascending=False ).instrument)
        else:
            event[dt] = []    
    context.event = event 

策略逻辑主体函数

def initialize(context):
   
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5)) 
    context.daily_buy_stock = context.event
    context.hold_periods = 40 # 持有40天,固定持仓期
    context.stock_max_num = 50 # 最大持仓数量为50只
    context.hold_days = {}
     
def handle_data(context,data):
  
    date = data.current_dt.strftime('%Y-%m-%d') # 日期
    
    # 目前仓位里面的股票列表
    equities = {e.symbol: e for e, p in context.perf_tracker.position_tracker.positions.items()}
    
    for k in equities.keys():
        # 如果持仓时间大于40天
        if context.trading_day_index - context.hold_days[k] >= context.hold_periods \
               and data.can_trade(context.symbol(k)):
            # 卖完
            context.order_target_percent(context.symbol(k),0)
   
    # 还允许建仓的股票数目
    stock_can_buy_num = context.stock_max_num - len(equities)
    # 获取当日买入股票的代码
    stock_to_buy = context.daily_buy_stock[date][:stock_can_buy_num]

    # 等权重买入 
    weight =  1 / context.stock_max_num
    
    # 买入
    for stock in stock_to_buy:
        if data.can_trade(context.symbol(stock)):
            context.order_target_percent(context.symbol(stock), weight)
            # 记录建仓时间的日期索引
            context.hold_days[stock] = context.trading_day_index  

策略回测接口

m=M.trade.v2( 
    instruments=D.instruments(market='CN_STOCK_A'),
    start_date='2010-01-01', 
    end_date='2017-08-01',
    prepare=prepare,
    initialize=initialize,
    handle_data=handle_data,
    order_price_field_buy='open',
    order_price_field_sell='open',
    capital_base=1000000,
    benchmark='000300.INDX',
)
[2018-03-22 19:58:10.576019] INFO: bigquant: backtest.v7 开始运行..
[2018-03-22 19:58:24.447598] INFO: algo: set price type:backward_adjusted
[2018-03-22 20:00:02.144660] INFO: Blotter: 2011-03-01 cancel order Equity(3437 [000973.SZA]) 
[2018-03-22 20:00:02.186730] INFO: Blotter: 2011-03-02 cancel order Equity(1775 [000977.SZA]) 
[2018-03-22 20:00:02.451034] INFO: Blotter: 2011-03-04 cancel order Equity(2962 [000629.SZA]) 
[2018-03-22 20:00:02.512531] INFO: Blotter: 2011-03-07 cancel order Equity(2647 [002422.SZA]) 
[2018-03-22 20:00:02.574669] INFO: Blotter: 2011-03-08 cancel order Equity(2298 [600114.SHA]) 
[2018-03-22 20:00:02.641604] INFO: Blotter: 2011-03-09 cancel order Equity(1213 [600179.SHA]) 
[2018-03-22 20:00:02.667457] INFO: Blotter: 2011-03-10 cancel order Equity(3087 [600567.SHA]) 
[2018-03-22 20:00:02.696841] INFO: Blotter: 2011-03-11 cancel order Equity(617 [600728.SHA]) 
[2018-03-22 20:00:02.754833] INFO: Blotter: 2011-03-15 cancel order Equity(3354 [600221.SHA]) 
[2018-03-22 20:00:02.787623] INFO: Blotter: 2011-03-16 cancel order Equity(355 [002210.SZA]) 
[2018-03-22 20:00:02.857295] INFO: Blotter: 2011-03-17 cancel order Equity(1132 [002092.SZA]) 
[2018-03-22 20:00:02.908875] INFO: Blotter: 2011-03-18 cancel order Equity(2574 [600584.SHA]) 
[2018-03-22 20:00:02.943216] INFO: Blotter: 2011-03-21 cancel order Equity(773 [000902.SZA]) 
[2018-03-22 20:00:11.496672] INFO: Blotter: 2012-03-01 cancel order Equity(2922 [000799.SZA]) 
[2018-03-22 20:00:11.542353] INFO: Blotter: 2012-03-02 cancel order Equity(1863 [300105.SZA]) 
[2018-03-22 20:00:11.637673] INFO: Blotter: 2012-03-05 cancel order Equity(2656 [300127.SZA]) 
[2018-03-22 20:00:11.705130] INFO: Blotter: 2012-03-06 cancel order Equity(2992 [600702.SHA]) 
[2018-03-22 20:00:11.736938] INFO: Blotter: 2012-03-07 cancel order Equity(456 [002321.SZA]) 
[2018-03-22 20:00:11.767191] INFO: Blotter: 2012-03-08 cancel order Equity(3062 [000795.SZA]) 
[2018-03-22 20:00:11.811717] INFO: Blotter: 2012-03-09 cancel order Equity(3379 [000822.SZA]) 
[2018-03-22 20:00:11.848026] INFO: Blotter: 2012-03-12 cancel order Equity(3301 [300195.SZA]) 
[2018-03-22 20:00:11.909838] INFO: Blotter: 2012-03-13 cancel order Equity(1836 [600203.SHA]) 
[2018-03-22 20:00:11.947694] INFO: Blotter: 2012-03-14 cancel order Equity(3364 [300142.SZA]) 
[2018-03-22 20:00:11.995203] INFO: Blotter: 2012-03-16 cancel order Equity(3465 [000030.SZA]) 
[2018-03-22 20:09:49.689308] INFO: Performance: Simulated 1841 trading days out of 1841.
[2018-03-22 20:09:49.694649] INFO: Performance: first open: 2010-01-04 01:30:00+00:00
[2018-03-22 20:09:49.696548] INFO: Performance: last close: 2017-08-01 07:00:00+00:00


路过

雷人

握手

鲜花

鸡蛋
来自: bigquant
关注微信