Creating of my own strategy based on mean reversion
-
Hi,
I try to create my own strategy which is based on mean reversion strategy. The code passed in Backtrader but it didn't give me a desired output. Could you please write me, what I am doing wrong?
I am still a beginner, but hope there won't be plenty of mistakes and any suggestion will be greatly appreciated. :-)
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 and buy price/commission self.order = None self.buyprice = None self.buycomm = None # Add Indicators self.sma = bt.indicators.SimpleMovingAverage(self.data, period = self.params.period) self.std = bt.indicators.StandardDeviation(self.data, period = self.params.period) self.zscore = (self.dataclose - self.sma) / self.std (self.data)
Defining new variables state and signal:
def state(self): if np.sign(self.zscore[0]) == np.sign(self.zscore[-1]): if self.zscore[0] > 1: return 1 elif self.zscore[0] < -1: return -1 else: return self.state[-1] else: return 0 def signal(self): if self.state[0] == self.state[-1]: return 0 else: return self.state[0] - self.state[-1]
then the own strategy:
def notify_order(self, order): # Buy/Sell order submitted/accepted by broker (nothing to do) if order.status in [order.Submitted, order.Accepted]: return # Check if an order has been completed (broker could reject order if not enough cash) if order.status in [order.Completed]: if order.isbuy(): self.log( 'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.buyprice = order.executed.price self.buycomm = order.executed.comm else: # Sell self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.bar_executed = len(self) elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('Order Canceled/Margin/Rejected') self.order = None def notify_trade(self, trade): if not trade.isclosed: return self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm)) def next(self): # 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 if not self.position: # Not in the market, we might buy... if self.signal[0] == -1: # BUY! (with all possible default parameters) self.log('BUY CREATED {}'.format(self.dataclose[0])) # Keep track of the created order to avoid a 2nd order self.order = self.buy() elif self.signal[0] == 1: self.log('SELL CREATE, %.2f' % self.dataclose[0]) # Keep track of the created order to avoid a 2nd order self.order = self.sell()
-
@Jana-Stará said in Creating of my own strategy based on mean reversion:
if self.signal[0] == -1:
I could be wrong but I think you need to call
self.signal
andself.state
with rounded brackets:self.signal() self.state()
-
IN addition to that @run-out has pointed out. self.zscore is the line object, but self.state is not. if you need self.state[-1] then either make self.state a line object or make a variable self.prev_state and update for every step.
-
@rajanprabu Thank you for your help. I got your point but I don't know exactly how to do it. Could you please write me some hint, how to make a self.state a line object?
-
As for as I understand, you only need two values self.signal[0] and self.signal[-1]. So making it as a line object may not be optimal. Just initialise two variables under init say self.prev_state, self.state and and update the values of self.prev_state during next().
-
This is a reasonably complicated indicator for a beginner. You should create a custom indicator.
Look here for further help:
https://www.backtrader.com/blog/posts/2015-07-18-developing-an-indicator/developing-an-indicator/https://medium.com/@danjrod/custom-indicator-development-in-python-with-backtrader-bc775552dc3e