For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
Hi I have problem. There is no graph in implementing the momentum strategy.
-
My code is as follows. I wonder how we can get the graph to print out.
And look at the code and point out if there's a problem.
Thank you in advance for all the people who will reply.import pandas as pd import numpy as np import backtrader as bt from scipy.stats import linregress import matplotlib matplotlib.use('Qt5Agg') import matplotlib.pyplot as plt import backtrader.plot from matplotlib.pyplot import figure from datetime import datetime import yfinance as yf # Date range start = '2010-01-01' end = '2020-03-25' ETF_TICKERS = ['XLB', 'XLE', 'XLF', 'XLI', 'XLK', 'XLP', 'XLU', 'XLV', 'XLY',"SPY"] prices = yf.download(ETF_TICKERS, start = start, end = end) prices = prices.dropna() def momentum_func(self, price_array): r = np.log(price_array) slope, _, rvalue, _, _ = linregress(np.arange(len(r)), r) annualized = (1 + slope) ** 252 return (annualized * (rvalue ** 2)) class Momentum(bt.ind.OperationN): lines = ('trend',) params = dict(period=90) func = momentum_func class Strategy(bt.Strategy): params = dict( momentum=Momentum, momentum_period=180, num_positions=2, when=bt.timer.SESSION_START, timer=True, monthdays=[1], monthcarry=True, printlog=True ) def log(self, txt, dt=None, doprint=False): ''' Logging function fot this strategy''' if self.params.printlog or doprint: dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): self.i = 0 self.securities = self.datas[1:] self.inds = {} self.add_timer( when=self.p.when, monthdays=self.p.monthdays, monthcarry=self.p.monthcarry ) for security in self.securities: self.inds[security] = self.p.momentum(security, period=self.p.momentum_period) def notify_timer(self, timer, when, *args, **kwargs): if self._getminperstatus() < 0: self.rebalance() def rebalance(self): rankings = list(self.securities) rankings.sort(key=lambda s: self.inds[s][0], reverse=True) pos_size = 1 / self.p.num_positions # Sell stocks no longer meeting ranking filter. for i, d in enumerate(rankings): if self.getposition(d).size: if i > self.p.num_positions: self.close(d) # Buy and rebalance stocks with remaining cash for i, d in enumerate(rankings[:self.p.num_positions]): self.order_target_percent(d, target=pos_size) def next(self): self.notify_timer(self, self.p.timer, self.p.when) def stop(self): self.log('| %2d | %2d | %.2f |' % (self.p.momentum_period, self.p.num_positions, self.broker.getvalue()), doprint=True) if __name__ == '__main__': assets_prices = [] for i in ETF_TICKERS[1:len(ETF_TICKERS) - 1]: prices_ = prices.drop(columns='Adj Close').loc[:, (slice(None), i)].dropna() prices_.columns = ['Close', 'High', 'Low', 'Open', 'Volume'] assets_prices.append(bt.feeds.PandasData(dataname=prices_, plot=True)) # Creating Benchmark bt.feeds benchdata = prices.drop(columns='Adj Close').loc[:, (slice(None), 'SPY')].dropna() benchdata.columns = ['Close', 'High', 'Low', 'Open', 'Volume'] benchdata = bt.feeds.PandasData(dataname=benchdata, plot=True) cerebro = bt.Cerebro(optreturn=False) for data in benchdata: cerebro.adddata(benchdata) for data in assets_prices: data.plotinfo.plotmaster = benchdata cerebro.adddata(data) print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Add Strategy stop = len(ETF_TICKERS) + 1 cerebro.optstrategy(Strategy, momentum_period=range(50, 300, 50), num_positions=range(1, len(ETF_TICKERS) + 1)) # Run the strategy. Results will be output from stop. cerebro.run(stdstats=False, tradehistory=False) cerebro.plot()
-
I'm not sure plotting works well with optstrategy (if at all). See: https://community.backtrader.com/topic/409/optstrategy-and-plotting
-
@vladisld said in Hi I have problem. There is no graph in implementing the momentum strategy.:
optstrategy
Thank you for your Reply .
I tried, but it didn't work out. ...................