Skip to content

Instantly share code, notes, and snippets.

@18182324
Created April 7, 2023 18:51
Show Gist options
  • Save 18182324/4fc3d4024f8bbc7fc30f658fa8360573 to your computer and use it in GitHub Desktop.
Save 18182324/4fc3d4024f8bbc7fc30f658fa8360573 to your computer and use it in GitHub Desktop.
Momentum Trading in Python
import pandas as pd
import backtrader as bt
# Define the strategy
class MyStrategy(bt.Strategy):
params = dict(
ma_length=50,
obv_ma_length=200,
target=5000,
stop=4000
)
def __init__(self):
self.ma = bt.indicators.SimpleMovingAverage(
self.data.close, period=self.params.ma_length
)
self.obv = bt.indicators.OnBalanceVolume(
self.data.close, self.data.volume
)
self.obv_ma = bt.indicators.SimpleMovingAverage(
self.obv, period=self.params.obv_ma_length
)
def next(self):
if self.data.close[0] > self.ma[0]:
if (
self.data.open[0] > self.data.low[-1]
or self.data.open[-1] > self.ma[-1] > self.data.low[-1]
):
if (
self.data.close[0] > self.ma[0]
and self.obv[0] > self.obv_ma[0]
and self.data.datetime.date(0).weekday() in [0, 2, 3, 4]
):
self.buy(
size=self.params.target / self.data.close[0],
exectype=bt.Order.Market
)
def notify_order(self, order):
if order.status in [bt.Order.Completed, bt.Order.Canceled, bt.Order.Rejected]:
self.order = None
# Download data for SPY
data = bt.feeds.YahooFinanceData(
dataname='SPY',
fromdate=datetime(2007, 1, 1),
todate=datetime(2022, 4, 7),
reverse=False
)
# Create a cerebro instance
cerebro = bt.Cerebro()
# Add the data feed
cerebro.adddata(data)
# Add the strategy
cerebro.addstrategy(MyStrategy)
# Set the broker and cash
cerebro.broker.setcash(1000000)
# Set the commission and slippage
cerebro.broker.setcommission(commission=0.001)
cerebro.broker.set_slippage_fixed(
fixed=0.01, slip_open=True, slip_limit=True, slip_match=True, slip_out=True
)
# Set the position sizing
cerebro.addsizer(bt.sizers.PercentSizer, percents=10)
# Add the analyzers
cerebro.addanalyzer(bt.analyzers.PyFolio, _name='pyfolio')
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe')
cerebro.addanalyzer(bt.analyzers.Returns, _name='returns')
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')
# Run the backtest
results = cerebro.run()
# Print the final results
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
print('Sharpe Ratio:', results[0].analyzers.sharpe.get_analysis()['sharperatio'])
print('Total Returns:', results[0].analyzers.returns.get_analysis()['rtot'])
print('Max Drawdown:', results[0].analyzers.drawdown.get_analysis()['max']['drawdown'])
print('Returns:', results[0].analyzers.pyfolio.get_analysis()['returns'])
print('Positions:', results[0].analyzers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment