我想建立一个简单回测

新手专区
标签: #<Tag:0x00007fc06f8ef350>

(ylrh3) #1

我知道可以在软件里直接算,但是我想通过程序看看结果如何,就是2017.3.24号33.25元买入海虹控股1000股,然后2017.4.10号35.4卖出1000股,然后回测一下,看看这个模拟跑出来的收益是多少? 如何让程序帮我跑一跑,代码如何实现。谢谢大家


(iQuant) #3

@ylrh3 你好,这个简单的回测其实是比较容易实现的,只要对交易引擎比较熟悉,就不会很困难。

克隆策略
In [6]:
# 1. 策略基本参数

# 回测起始时间
start_date = '2017-03-01'
# 回测结束时间
end_date = '2017-06-01'
# 策略比较参考标准,以沪深300为例
benchmark = '000300.INDX'
# 证券池 以贵州茅台为例
instruments = ['000503.SZA']
# 起始资金
capital_base = 1000000

# 2. 策略主体函数

# 初始化虚拟账户状态,只在第一个交易日运行
def initialize(context):
    # 设置手续费,买入时万3,卖出是千分之1.3,不足5元以5元计
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))

# 策略交易逻辑,每个交易日运行一次
def handle_data(context, data):
    # 在这里添加策略代码
    date = data.current_dt.strftime('%Y-%m-%d') 
   
    sid = context.symbol(instruments[0])
  
    if date == '2017-03-24':#若要03-24实际成交,可以提前一天生成订单,即改成 date == '2017-03-23'
        order(sid, 1000)
        print('在日期%s 买入1000股'%date)
    
    elif date == '2017-04-10': # 同理,#若要04-10实际成交,可以提前一天生成订单,即改成 date == '2017-04-07'(当天刚好是周五)
        order(sid, -1000)
        print('在日期%s 卖出1000股'%date)
        
    
# 3. 启动回测

# 策略回测接口: https://bigquant.com/docs/module_trade.html
m = M.trade.v1(
    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=capital_base,
    benchmark=benchmark,
)
[2017-07-10 17:18:54.400669] INFO: bigquant: backtest.v6 start ..
在日期2017-03-24 买入1000股
在日期2017-04-10 卖出1000股
[2017-07-10 17:18:54.879867] INFO: Performance: Simulated 62 trading days out of 62.
[2017-07-10 17:18:54.890269] INFO: Performance: first open: 2017-03-01 14:30:00+00:00
[2017-07-10 17:18:54.898085] INFO: Performance: last close: 2017-06-01 19:00:00+00:00
  • 收益率1.86%
  • 年化收益率7.78%
  • 基准收益率1.3%
  • 阿尔法0.03
  • 贝塔0.11
  • 夏普比率1.01
  • 收益波动率3.38%
  • 信息比率0.29
  • 最大回撤0.59%
[2017-07-10 17:18:55.563005] INFO: bigquant: backtest.v6 end [1.162362s].

注:BigQuant回测引擎采取前一天下单后一天成交的形式,这样可以规避未来函数。因此本策略的实际成交时间为03-27和04-11

In [19]:
D.history_data(['000503.SZA'], start_date='2017-03-23', end_date='2017-04-11',fields=['open', 'close', 'adjust_factor'])
Out[19]:
adjust_factor date instrument close open
0 7.614551 2017-03-23 000503.SZA 264.224915 259.656189
1 7.614551 2017-03-24 000503.SZA 247.549057 264.377197
2 7.614551 2017-03-27 000503.SZA 253.869125 251.280182
3 7.614551 2017-03-28 000503.SZA 256.991089 254.173706
4 7.614551 2017-03-29 000503.SZA 264.453369 258.133270
5 7.614551 2017-03-30 000503.SZA 260.874512 262.701996
6 7.614551 2017-03-31 000503.SZA 260.341492 261.712128
7 7.614551 2017-04-05 000503.SZA 273.895386 260.341492
8 7.614551 2017-04-06 000503.SZA 276.027466 272.829376
9 7.614551 2017-04-07 000503.SZA 274.809143 279.454010
10 7.614551 2017-04-10 000503.SZA 271.763336 274.123840
11 7.614551 2017-04-11 000503.SZA 258.894745 270.316559
In [20]:
# 根据后复权计算收益率:
270.31/251.28-1
Out[20]:
0.07573225087551738
In [21]:
# 根据真实交易价格计算的收益率:
35.5/33-1
Out[21]:
0.07575757575757569

可以看出,BigQuant在回测过程中只是采取的后复权价格,因此和真实交易价格不一样,但这不影响绩效的计算,其盈利的比率是接近的。采取后复权也是为了更好的体现回测与实盘一致(尽量考虑分红、派现)


(ylrh3) #4

难道买不能设置成当天下单,当天买入吗,卖已经隔了几天,难道也不能设置成当天下单当天卖出吗,而且都是以自己预测的价格卖出。


(ylrh3) #5

有人能回答这个问题不?如果只能以开盘价格买入,开盘价格卖出,如果买入当天,开盘是跌停,卖出当天开盘也是跌停,那么损失岂不是相当大吗?


(小Q) #6

如果你想达到这个目的,那肯定可以实现的,提前一天下一个订单就可以,这个订单当天并不会成交,而是在下一天成交,因此成为虚拟单。这里解释一下为什么有虚拟单?
因为回测引擎采用事件驱动,每一个bar看做一个事件,为避免未来函数,即设置了当根bar下单,但不实际成交,在下一根bar成交,这样的处理机制也是和实际情形相符合的,比如根据今天的收盘价,确定出中国平安值得投资,那么在今天的这个日K线我们是没有办法交易的,只有等到明天实际成交。


(ylrh3) #7

那明天,只能开盘买入吗?我如果想,等它再跌到某个价位,再买入,不能设置吗?


(小Q) #8

可以的,我们最近正在构建分钟数据,有分钟数据后,这样的交易思路就能很好的实现。因为那个时候将会从现在的日K转化为分钟K线,就灵活多了。


(ylrh3) #9

哦,原来如此,谢谢尔。