1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| import backtrader as bt import math
class GridStrategy(bt.Strategy): params=( ('number', 10), ('open_percent', 0.5), ('distance', 0), ('base_price',0) )
def __init__(self): self.open_flg=False self.last_index = 0 self.per_size=0 self.max_index = 0 self.min_index = 0 self.order=None
def log(self, txt, dt=None): dt = dt or self.data.datetime[0] dt = bt.num2date(dt).date() print(f'{dt}: {txt}')
def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: return
if order.status in [order.Completed]: if order.isbuy(): self.log('买单执行,%s, %.3f, %i' % (order.data._name, order.executed.price, order.executed.size)) elif order.issell(): self.log('卖单执行, %s, %.3f, %i' % (order.data._name, order.executed.price, order.executed.size)) print('佣金 %.2f, 市值 %.2f, 现金 %.2f' % ( order.executed.comm, self.broker.getvalue(), self.broker.getcash())) else: self.log('订单作废 %s, %s, isbuy=%i, size %i, open price %.2f' % (order.data._name, order.getstatusname(), order.isbuy(), order.created.size, order.data.open[0])) self.order=None
def next(self): if self.open_flg: index = (self.data.close[0] - self.p.base_price) // self.p.distance
if index < self.min_index: index = self.min_index elif index > self.max_index: index = self.max_index
self.log("上一交易日挡位:{}".format(self.last_index)) self.log("当前交易日挡位:{}".format(index))
change_index = index - self.last_index if change_index > 0: self.sell(data=self.data, size=change_index*self.per_size) elif change_index < 0: self.buy(data=self.data, size=change_index*self.per_size) self.last_index = index if not self.open_flg and math.fabs(self.data.close[0]-self.p.base_price)/self.p.base_price < 0.01:
buy_size = self.broker.getvalue() / self.data.close[0] * self.p.open_percent // 100 * 100 self.buy(data=self.data, size=buy_size)
self.last_index = 0 self.per_size = self.broker.getvalue() / self.data.close[0] / self.p.number // 100 * 100 self.max_index = round(self.p.number * self.p.open_percent) self.min_index = self.max_index - self.p.number
self.open_flg = True self.log('已买入初始订单')
self.log("当前持仓规模:{},市值:{},现金:{}".format(self.getposition(self.data).size,self.broker.getvalue(), self.broker.getcash()))
|