Skip to content

Commit

Permalink
scripts for RsiBollingerBandsStrategy and SimpleMovingAverageStrategy…
Browse files Browse the repository at this point in the history
… added
  • Loading branch information
derejehinsermu committed Jun 22, 2024
1 parent 1bb3258 commit f85fdba
Showing 1 changed file with 92 additions and 6 deletions.
98 changes: 92 additions & 6 deletions scripts/backtest_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,65 @@ def next(self):
if self.rsi > self.params.overbought or self.data.close >= self.bbands.lines.top:
self.sell()

class SimpleMovingAverageStrategy(bt.Strategy):
params = (
('maperiod', 15),
)

def __init__(self):
self.dataclose = self.datas[0].close
self.order = None
self.buyprice = None
self.buycomm = None
self.sma = bt.indicators.SimpleMovingAverage(self.datas[0], period=self.params.maperiod)
# Additional indicators for plotting
bt.indicators.ExponentialMovingAverage(self.datas[0], period=25)
bt.indicators.WeightedMovingAverage(self.datas[0], period=25, subplot=True)
bt.indicators.StochasticSlow(self.datas[0])
bt.indicators.MACDHisto(self.datas[0])
rsi = bt.indicators.RSI(self.datas[0])
bt.indicators.SmoothedMovingAverage(rsi, period=10)
bt.indicators.ATR(self.datas[0], plot=False)

def log(self, txt, dt=None):
dt = dt or self.datas[0].datetime.date(0)
print('%s, %s' % (dt.isoformat(), 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('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:
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):
self.log('Close, %.2f' % self.dataclose[0])
if self.order:
return
if not self.position:
if self.dataclose[0] > self.sma[0]:
self.log('BUY CREATE, %.2f' % self.dataclose[0])
self.order = self.buy()
else:
if self.dataclose[0] < self.sma[0]:
self.log('SELL CREATE, %.2f' % self.dataclose[0])
self.order = self.sell()

def run_backtest(strategy, symbol, start_date, end_date):
data = fetch_data(symbol, start_date, end_date)

Expand All @@ -73,27 +132,54 @@ def run_backtest(strategy, symbol, start_date, end_date):
cerebro = bt.Cerebro()
cerebro.addstrategy(strategy)
cerebro.adddata(data_feed)
cerebro.broker.set_cash(10000)
cerebro.broker.set_cash(100000)
cerebro.broker.setcommission(commission=0.002)
# cerebro.addsizer(bt.sizers.FixedSize, stake=5)

# Add analyzers for performance metrics
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe')
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='trades')
cerebro.addanalyzer(bt.analyzers.Returns, _name='returns')

# Print starting conditions
print(f'Starting Portfolio Value: {cerebro.broker.getvalue():.2f}')
start_value = cerebro.broker.getvalue()
print(f'Starting Portfolio Value: {start_value:.2f}')

# Run backtest
cerebro.run()
results = cerebro.run()

# Print ending conditions
print(f'Ending Portfolio Value: {cerebro.broker.getvalue():.2f}')
end_value = cerebro.broker.getvalue()
print(f'Ending Portfolio Value: {end_value:.2f}')

# Extract and print analyzers results
strat = results[0]

# Prepare results
result_dict = {
"Starting Portfolio Value": start_value,
"Ending Portfolio Value": end_value,
"Sharpe Ratio": strat.analyzers.sharpe.get_analysis().get('sharperatio', 'N/A'),
"Max Drawdown": strat.analyzers.drawdown.get_analysis().get('max', {}).get('drawdown', 'N/A'),
"Total Trades": strat.analyzers.trades.get_analysis().get('total', {}).get('total', 'N/A'),
"Winning Trades": strat.analyzers.trades.get_analysis().get('won', {}).get('total', 'N/A'),
"Losing Trades": strat.analyzers.trades.get_analysis().get('lost', {}).get('total', 'N/A'),
"Total Return": strat.analyzers.returns.get_analysis().get('rtot', 'N/A')
}

# Plot the results
cerebro.plot()
cerebro.plot(style='candlestick')

return result_dict


if __name__ == "__main__":
symbol = 'BTC/USDT'
start_date = '2023-06-20'
end_date = '2024-06-20'

for strategy in [RsiBollingerBandsStrategy]:
for strategy in [RsiBollingerBandsStrategy,RsiBollingerBandsStrategy]:
run_backtest(strategy, symbol, start_date, end_date)

try:
Expand Down

0 comments on commit f85fdba

Please sign in to comment.