Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Swapping price and SMA data to match UK stock prices?

    General Code/Help
    code lse price sma
    2
    8
    36
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • V
      Void last edited by

      So quick bit of background...

      The London Stock Exchange (LSE) prices are formatted like this : 129.02 for the stock Vodafone (ticker VOD on the LSE, and VOD.L on Yahoo Finance)

      However, the actual price of a single share of Vodafone is £1.29 and not £129.02 as it is being read by backtrader as it is assuming it is dollars instead of UK pence.

      The stock price is already exchanged to the UK price as it is using the LSE price so there is no exchange rate issues here.

      Now we can fix the price format by taking the data.close[0] of our UK stock and dividing it by 100 to move the decimal place, which is okay and returns the correct amount now, e.g £1.29.

      The problem now comes from using indicators like SMA which are still operating in effectively dollar amounts.

      For example : Figure_0.png

      In the image above we can see that the price of the stock is 1.30 or £1.30 but the Fast and Slow SMA are reading 131.31 and 119.71 respectively.

      My question is how would one go about potentially implementing a similar fix as discussed above to each SMA.

      If that is not possible, then what would be the alternative to manipulating the SMA output so that it can effectively be used for UK price formatted stocks.

      If you need any more information or clarification then don't hesitate to ask.

      1 Reply Last reply Reply Quote 1
      • V
        Void last edited by

        class ShortSMA(backtrader.Strategy):
            params = (('fast', 20), ('slow',100 ), ('order_precentage', 0.95), ('ticker', 'VOD'))
            
            def __init__(self):
        
        
                self.fast_moving_average = backtrader.indicators.SMA(
                    self.data.close, period = self.p.fast , plotname ='5 Day Moving Average'
                )
        
        
                self.slow_moving_average = backtrader.indicators.SMA(
                    self.data.close, period = self.p.slow, plotname ='19 Day Moving Average'
                )
                
        
                self.crossover = backtrader.indicators.CrossOver(self.fast_moving_average, self.slow_moving_average)
        

        Forgot to include a code snippet, as you can see it is just a simple SMA crossover strategy.

        run-out 1 Reply Last reply Reply Quote 0
        • run-out
          run-out @Void last edited by

          @void The easiest way to handle this is pre-process the data. Use yfinance to get your yahoo data in a dataframe, adjuste the ohlc values, and then import using Pandas Feed into backtrader.

          V 2 Replies Last reply Reply Quote 1
          • V
            Void @run-out last edited by

            @run-out thanks for the input, that is really helpful.

            I am just wondering if this is a viable option for live trading as this is the plan in the future? I did read up on it and they say there are obviously better paid APIs out there (which I can't really get involved with right now) if you are going down the full live trading route.

            My main goal for the project is to build a solid base with backtrader and a handful of strategies coded that I can switch between US and UK price formats and then hopefully integrate Backtrader in to MT5 for actual trading.

            Any advice on this please?

            1 Reply Last reply Reply Quote 0
            • V
              Void @run-out last edited by

              @run-out following on to my previous reply, if it isn't the best for live trading then that is okay, as I could replicate the live trading Strategies directly inside of MT5 with their scripting platform, i believe, correct?

              And then MT5 could handle the actual algo trading? And backtrader could be solely for testing strategies in preparation for moving the best ones over to MT5? This would allow me to use your recommendation of yfinance for the problem in my original post and save me having to code the live trading aspect of backtrader as I'm semi-new to python which is a time saver.

              But I would like the opinion of someone who knows their stuff!

              run-out 1 Reply Last reply Reply Quote 0
              • run-out
                run-out @Void last edited by

                @void Some people use backtrader for both backtesting and live trading, but I would guess most use it jet for backtesting, then implement their algos elsewhere. But that's just a guess.

                V 1 Reply Last reply Reply Quote 0
                • V
                  Void @run-out last edited by

                  @run-out That's fair, thank you for the reply.

                  run-out 1 Reply Last reply Reply Quote 1
                  • run-out
                    run-out @Void last edited by

                    @void Your question made me think. I was wondering what would happen if you change the value of say, self.data.close in the init of the strategy. Would that work? Appears to.

                    def __init__(self):
                        self.data.close = self.data.close / 100
                        self.sma = bt.ind.SMA(self.data.close, period=20)
                    

                    Results in:

                    2020-11-20, o  117.40	h  119.98	l  117.26	c    1.19	sma  1.09
                    2020-11-23, o  119.73	h  120.29	l  116.95	c    1.18	sma  1.10
                    2020-11-24, o  119.44	h  121.01	l  118.90	c    1.21	sma  1.10
                    2020-11-25, o  121.65	h  122.63	l  119.68	c    1.20	sma  1.12
                    2020-11-26, o  120.14	h  121.36	l  119.22	c    1.21	sma  1.13
                    2020-11-27, o  120.72	h  121.68	l  120.23	c    1.21	sma  1.14
                    2020-11-30, o  120.64	h  121.05	l  119.33	c    1.19	sma  1.14
                    2020-12-01, o  119.42	h  121.37	l  119.35	c    1.21	sma  1.15
                    2020-12-02, o  120.29	h  122.73	l  118.88	c    1.23	sma  1.16
                    2020-12-03, o  122.19	h  123.79	l  121.80	c    1.23	sma  1.17
                    

                    I have to wonder if there aren't dangers being missed here. I think I would still likely preprocess with Pandas unless this method was thoroughly tested.

                    Here's the whole code.

                    import datetime
                    import backtrader as bt
                    
                    class Strategy(bt.Strategy):
                    
                        def log(self, txt, dt=None):
                            """ Logging function fot this strategy"""
                            dt = dt or self.data.datetime[0]
                            if isinstance(dt, float):
                                dt = bt.num2date(dt)
                            print("%s, %s" % (dt.date(), txt))
                    
                        def print_signal(self):
                            self.log(
                                "o {:7.2f}\th {:7.2f}\tl {:7.2f}\tc {:7.2f}\tsma {:5.2f}".format(
                                    self.datas[0].open[0],
                                    self.datas[0].high[0],
                                    self.datas[0].low[0],
                                    self.datas[0].close[0],
                                    self.sma[0],
                                )
                            )
                    
                        def __init__(self):
                            self.data.close = self.data.close / 100
                            self.sma = bt.ind.SMA(self.data.close, period=20)
                    
                    
                        def next(self):
                            self.print_signal()
                    
                    
                    
                    if __name__ == "__main__":
                    
                        cerebro = bt.Cerebro()
                    
                        data = bt.feeds.YahooFinanceData(
                            dataname="VOD.L",
                            timeframe=bt.TimeFrame.Days,
                            fromdate=datetime.datetime(2020, 10, 25),
                            todate=datetime.datetime(2020, 12, 31),
                            reverse=False,
                        )
                        cerebro.adddata(data)
                    
                        cerebro.addstrategy(Strategy)
                    
                        cerebro.run()
                    
                    1 Reply Last reply Reply Quote 3
                    • 1 / 1
                    • First post
                      Last post
                    Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
                    $(document).ready(function () { app.coldLoad(); }); }