量化交易研究

量化交易回测框架Backtrader给策略增加买卖逻辑

2020-04-12  本文已影响0人  一块自由的砖

简介

前面只增加了一个简单的展示每天收盘价的逻辑。这次在策略里面增加卖和买的逻辑。具体可以参看Backtrader官方文档quickstart

原理

核心逻辑是重写策略Strategy的两个重要函数:notify_order和next。notify_order被next的buy和sell触发后回调,执行具体的买和卖,同时根据买卖状态,需要自己实现对应的处理。

实践

实践一:买

实现目标:如果股票价格三连跌的话,就以第二天的开盘价买入1股,为啥是第二天,因为只有前天收盘了,才会做判定,是否三连跌。

#############################################################
#class
#############################################################
# Create a Stratey
class TestStrategy(bt.Strategy):
    def log(self, txt, dt=None):
        ''' Logging function for this strategy'''
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(), txt))
    def __init__(self):
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close

    def next(self):
        # Simply log the closing price of the series from the reference
        self.log('Close, %.2f' % self.dataclose[0])

        if self.dataclose[0] < self.dataclose[-1]:
            # current close less than previous close

            if self.dataclose[-1] < self.dataclose[-2]:
                # previous close less than the previous close

                # BUY, BUY, BUY!!! (with all possible default parameters)
                self.log('BUY CREATE, %.2f' % self.dataclose[0])
                self.buy()

思路:
今天的价格小于昨天,昨天的价格小于前天的价格,即发生了三连跌,这时候触发买的动作。
全代码请到github上clone了。github地址:[qtbt](https://github.com/horacepei/qtbt.git

实践二:买卖

实现目标:

  1. 买入条件和原来一样三联跌后购买
  2. 持股5个交易日后,不论涨跌立即卖出
  3. 如果已经持有股票,不会再买入股票,5个交易日内出现三连跌也不会再买入。
#############################################################
#class
#############################################################
# Create a Stratey
class TestStrategy(bt.Strategy):
    def log(self, txt, dt=None):
        ''' Logging function for this strategy'''
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(), txt))

    def __init__(self):
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close
        # To keep track of pending orders
        self.order = None
    
    #订单状态改变回调方法
    def notify_order(self, order):
        if order.status in [order.Submitted, order.Accepted]:
            # Buy/Sell order submitted/accepted to/by broker - Nothing to do
            return
        # Check if an order has been completed
        # Attention: broker could reject order if not enough cash
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log('BUY EXECUTED, %.2f' % order.executed.price)
            elif order.issell():
                self.log('SELL EXECUTED, %.2f' % order.executed.price)
            self.bar_executed = len(self)
        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('Order Canceled/Margin/Rejected')
        # Write down: no pending order
        self.order = None

    def next(self):
        # Simply log the closing price of the series from the reference
        self.log('Close, %.2f' % self.dataclose[0])
        # Check if an order is pending ... if yes, we cannot send a 2nd one
        if self.order:
            return
        # Check if we are in the market(当前账户持股情况,size,price等等)
        if not self.position:
            # Not yet ... we MIGHT BUY if ...
            if self.dataclose[0] < self.dataclose[-1]:
                    # current close less than previous close
                    if self.dataclose[-1] < self.dataclose[-2]:
                        # previous close less than the previous close
                        # BUY, BUY, BUY!!! (with default parameters)
                        self.log('BUY CREATE, %.2f' % self.dataclose[0])
                        # Keep track of the created order to avoid a 2nd order
                        self.order = self.buy()
        else:
            # Already in the market ... we might sell
            if len(self) >= (self.bar_executed + 5):
                # SELL, SELL, SELL!!! (with all possible default parameters)
                self.log('SELL CREATE, %.2f' % self.dataclose[0])
                # Keep track of the created order to avoid a 2nd order
                self.order = self.sell()

思路:
判断5个交易日,通过使用python len self来判定类似list的类型的对象数据的长度。每次买入后,会重新计算一下bar_executed变量,用来记录买入的时间。这块不好理解的话,可以准备一个全局变量来记录交易计数器。
全代码请到github上clone了。github地址:[qtbt](https://github.com/horacepei/qtbt.git

上一篇下一篇

猜你喜欢

热点阅读