Hello, trying to backtest a simple RSI strategy.
It sends a buy_bracket if current position==0 and rsi indicator crossup oversold thersold and close the position when the rsi crossdown the opposite threshold.
The opposite for selling; always only if current position==0.
What I cannot understand it is that sometimes multiple unwanted entries happen. I added some "check print" ad notify_order status in order to better understand but I gave up.
Here the logic:
import backtrader as bt
import datetime
class rsi_strategy(bt.Strategy):
params = (
('backtest', False),
('printLog', True),
('rsi_period', 19),
('rsi_overSold', 21),
('rsi_overBought', 77),
('stopLoss_perc', 7),
('takeProfit_perc', 20)
)
def __init__(self):
# self.live_bars = False
self.rsi_ind = bt.indicators.RSI(self.data.close,
period=self.p.rsi_period,
plot=True,
plotname='RSI',
subplot=True)
# Buy Signals
self.CrossedOS = bt.indicators.CrossUp(self.rsi_ind, self.p.rsi_overSold, plotname='x ↑ OS')
# Sell Signals
self.CrossedOB = bt.indicators.CrossDown(self.rsi_ind, self.p.rsi_overBought, plotname='x ↓ OB')
def next(self):
self.closePrice = self.data.close[0]
self.Bar_time = self.data.datetime.time()
self.Bar_date = self.data.datetime.date()
self.order_size = int((self.broker.cash / self.closePrice / 4))
self.highside_offset = round(self.closePrice * self.p.takeProfit_perc / 100, 2)
self.lowside_offset = round(self.closePrice * self.p.stopLoss_perc / 100, 2)
self.current_position = self.getposition().size
print(len(self))
print('BarDataTime >>', self.Bar_date, self.Bar_time, ' / Equity >>', int(self.broker.getvalue()),
' / Current Size >>', self.current_position)
print('close >>', self.closePrice, ' / RSI >>', self.rsi_ind[0].__round__(1))
print('-------------')
#
# # If flat and rsi Cross-up Over-Sold level then buy_bracket
if self.current_position == 0:
if self.broker.getvalue() > 9500 and self.CrossedOS:
print('Buy Condition met, current position size>>', self.current_position) # control string
self.buy_bracket(size=self.order_size, stopprice=self.closePrice - self.lowside_offset,
limitprice=self.closePrice + self.highside_offset,
exectype=bt.Order.Limit)
elif self.current_position < 0 and self.CrossedOS:
print('Close-Sell Condition met, current position size>>', self.current_position) # control string
self.close()
# If flat and rsi Cross-Down Over-Bought level then buy_bracket
if self.current_position == 0:
if self.broker.getvalue() > 9500 and self.CrossedOB:
print('Sell Condition met, current position size>>', self.current_position) # control string
self.sell_bracket(size=self.order_size, stopprice=self.closePrice + self.lowside_offset,
limitprice=self.closePrice - self.highside_offset,
exectype=bt.Order.Limit)
elif self.current_position > 0 and self.CrossedOB:
print('Close-Buy Condition met, current position size>>', self.current_position) # control string
self.close()
def notify_order(self, order):
if order.status in [order.Submitted]:
print('Order Submitted')
if order.status in [order.Accepted]:
print('Order Accepted')
if order.status in [order.Completed]:
print('Order Completed')
the plot:

and some of the terminal prints for "standard behaviour:
close >> 1.334 / RSI >> 20.5
-------------
62879
BarDataTime >> 2022-06-13 16:24:00 / Equity >> 10991 / Current Size >> 0
close >> 1.33425 / RSI >> 21.3
-------------
Buy Condition met, current position size>> 0
Order Submitted
Order Submitted
Order Submitted
Order Accepted
Order Accepted
Order Accepted
Order Completed
62880
BarDataTime >> 2022-06-13 16:27:00 / Equity >> 10987 / Current Size >> 2059
close >> 1.3325 / RSI >> 19.8
-------------
62881
BarDataTime >> 2022-06-13 16:30:00 / Equity >> 10992 / Current Size >> 2059
close >> 1.33475 / RSI >> 26.9
-------------
62882
BarDataTime >> 2022-06-13 16:33:00 / Equity >> 10998 / Current Size >> 2059
and of the strange behaviour:
62921
BarDataTime >> 2022-06-14 10:00:00 / Equity >> 10986 / Current Size >> 2059
close >> 1.332 / RSI >> 41.4
-------------
62922
BarDataTime >> 2022-06-14 10:03:00 / Equity >> 10979 / Current Size >> 2059
close >> 1.32875 / RSI >> 38.2
-------------
Order Completed
62923
BarDataTime >> 2022-06-14 10:06:00 / Equity >> 10971 / Current Size >> 3684
close >> 1.3255 / RSI >> 35.3
-------------
62924
BarDataTime >> 2022-06-14 10:09:00 / Equity >> 10971 / Current Size >> 3684
close >> 1.3255 / RSI >> 35.3
-------------
62925
BarDataTime >> 2022-06-14 10:12:00 / Equity >> 10966 / Current Size >> 3684
I really hope someone has already faced the problem and be kind to give explanation.
Thanks in advance
Gianluca