简介
前面只增加了一个简单的展示每天收盘价的逻辑。这次在策略里面增加卖和买的逻辑。具体可以参看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)
实践二:买卖
实现目标:
- 买入条件和原来一样三联跌后购买
- 持股5个交易日后,不论涨跌立即卖出
- 如果已经持有股票,不会再买入股票,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)