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. ...................


Log in to reply
 

});