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/

    How to initialize bt.analyzers.SharpeRatio?

    General Code/Help
    5
    14
    409
    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.
    • S
      soulmachine last edited by

      I'm backtesting a BTC/USDT strategy, I have only two months realtime trading data, and I've already built 1-minute OHLCV bars based on the data.

      Since I don't have one year data, so the following code will always give me None:

      cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='mysharpe')
      

      How should I chose params for the class SharpeRatio?

      Thanks!

      1 Reply Last reply Reply Quote 0
      • S
        soulmachine last edited by

        My Jupyter notebook: https://github.com/soulmachine/crypto-notebooks/blob/master/backtest/backtrader-SMA-Cross.ipynb

        1 Reply Last reply Reply Quote 0
        • vladisld
          vladisld last edited by

          AFAIU you may try to set the timeframe and compression attributes for the analyzer. They are TimeFrame.Years and `1

          1 Reply Last reply Reply Quote 0
          • vladisld
            vladisld last edited by

            Ops (hit submit by mistake)

            AFAIU you may try to set the timeframe and compression attributes for the analyzer. They are TimeFrame.Years and 1 by default.

            cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='mysharpe', timeframe=bt.TimeFrame.Months, compression=1)
            
            S 1 Reply Last reply Reply Quote 0
            • run-out
              run-out last edited by

              @soulmachine Thanks for asking this question. I ran into issues with this a while ago and was to lazy to dig up the answer.

              @vladisld is correct in how you put in the timeframes. Small caveat to his comment, the compression only works on intraday timeframes. So typically say 1min compression to 30 or 60 minutes.

                  cerebro.addanalyzer(bt.analyzers.SharpeRatio, timeframe=bt.TimeFrame.Minutes, compression=30, _name="mysharpe_1")
                  cerebro.addanalyzer(bt.analyzers.SharpeRatio, timeframe=bt.TimeFrame.Minutes, compression=60, _name="mysharpe_2")
              
              # Output
              mysharpe_1: -2.3099,      mysharpe_2: -1.7835
              
              

              If you try the same thing with say Weekly or Monthly timeframes, there's no impact on results.

              cerebro.addanalyzer(bt.analyzers.SharpeRatio, timeframe=bt.TimeFrame.Weeks, compression=2, _name="mysharpe_1")
                      cerebro.addanalyzer(bt.analyzers.SharpeRatio, timeframe=bt.TimeFrame.Weeks, compression=4, _name="mysharpe_2")
              
              # Output
              mysharpe_1: -0.3472,      mysharpe_2: -0.3472
              

              For more information you can look in the docs or directly at the code.

              1 Reply Last reply Reply Quote 1
              • S
                soulmachine @vladisld last edited by

                Hi @vladisld , @run-out , thanks for your answers, I'm still quite confused by compression, I never met this concept in any papers, is there any doc describing it intuitively?

                I've read its source code at https://github.com/mementum/backtrader/blob/master/backtrader/analyzer.py#L399-L406:

                # Apply compression to update point position (comp 5 -> 200 // 5)
                point = point // self.compression
                
                # Move to next boundary
                point += 1
                
                # Restore point to the timeframe units by de-applying compression
                point *= self.compression
                

                What's the purpose of the above code?

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

                  @soulmachine said in How to initialize bt.analyzers.SharpeRatio?:

                  is there any doc describing it intuitively?

                  https://www.backtrader.com/docu/data-resampling/data-resampling/

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

                    @run-out The link you posted above explains compression clearly, thanks a lot!

                    1 Reply Last reply Reply Quote 1
                    • S
                      soulmachine last edited by

                      @run-out I got different sharpe ratio values if using different params, my data are 1-minute OHLCV bars from 2020-05-09 to 2020-05-15.

                      Params Sharpe ratio
                      timeframe=bt.TimeFrame.Days, compression=1, factor=365 0.26936215606006514
                      timeframe=bt.TimeFrame.Days, compression=2, factor=365 0.26936215606006514
                      timeframe=bt.TimeFrame.Days, compression=3, factor=365 0.26936215606006514
                      timeframe=bt.TimeFrame.Minutes, compression=1, factor=365 -0.02323860385901048
                      timeframe=bt.TimeFrame.Minutes, compression=2, factor=365 -0.012041289387197245
                      timeframe=bt.TimeFrame.Minutes, compression=3, factor=365 -0.006921681345592514
                      timeframe=bt.TimeFrame.Minutes, compression=24*60, factor=365 0.26936215606006514

                      I set factor=365 because Bitcoin is trading 24 hours a day and 7 days a week.

                      Since my data are 1-minute OHLCV bars, I think I should use timeframe=bt.TimeFrame.Minutes and compression=1, but sharpe ratio varies with different compression.

                      What compression is the correct value in this situation?

                      S 1 Reply Last reply Reply Quote 0
                      • S
                        soulmachine @soulmachine last edited by

                        Anyone knows what's the difference between timeframe=bt.TimeFrame.Days, compression=1, factor=365 and timeframe=bt.TimeFrame.Minutes, compression=24*60, factor=365? My data are 1-minute OHLCV bars from 2020-05-09 to 2020-05-15.

                        1 Reply Last reply Reply Quote 0
                        • S
                          soulmachine last edited by

                          After reading some source code and several experiments, my guess is that the timeframe in SharpeRatio has no relation to the timeframe of the data feed. The timeframe in SharpeRatio means how frequent you want to snapshot the equity curve.

                          1 Reply Last reply Reply Quote 0
                          • S
                            soulmachine last edited by

                            After reading the source code I think I've figured out.

                            timeframe and compression are used at analyzers/sharpe.py#L153:

                            returns = list(itervalues(self.timereturn.get_analysis()))
                            
                            • timeframe=bt.TimeFrame.Days, compression=1, means TimeReturn will take a snapshot on the equity curve per day
                            • timeframe=bt.TimeFrame.Minutes, compression=24*60, means TimeReturn will take a snapshot on the equity curve per 24*60 minutes, which is the same as a day

                            returns is a list of (timestamp, percentage), sharpe ratio is calculated on top of this list.

                            timeframe, compression --> TimeReturn -->returns --> sharpe_ratio
                            

                            The factor is used to convert riskfreerate to rate, which used at analyzers/sharpe.py#L186:

                            ret_free = [r - rate for r in returns]
                            

                            Since I snapshot on the equity curve per day, and one year contains 365 trading days(crypto exchanges never stop on weekends, which is different with stocks).

                            Recommended configurations:

                            • Prerequisites: make sure you have over 2 days data and make over 2 trades during backtesting, otherwise you'll get None
                            • Always set annualize =True, because sharpe ratio is usually in annual form.
                            • Set riskfreerate=0.01 and convertrate=True, Backtrader already sets them default
                            • Set timeframe and compression to make TimeReturn take a snapshot on equity curve per day, if the timeframe of your data feed is equal or less than 1 day, set timeframe=bt.TimeFrame.Days, compression=1, otherwise set timeframe=bt.TimeFrame.Days, compression=data_feed
                            • Set factor to 252 for stocks and 365 for cryptocurrencies.

                            Examples:

                            • 1-day OHLCV bars for US stocks, timeframe=bt.TimeFrame.Days, compression=1, factor=252,annualize =True
                            • 3-day OHLCV bars for US stocks, timeframe=bt.TimeFrame.Days, compression=3, factor=252,annualize =True
                            • 1-day OHLCV bars for cryptocurrency, timeframe=bt.TimeFrame.Days, compression=1, factor=365,annualize =True
                            • 3-day OHLCV bars for cryptocurrency, timeframe=bt.TimeFrame.Days, compression=3, factor=365,annualize =True
                            • 15-minutes OHLCV bars for cryptocurrency, timeframe=bt.TimeFrame.Days, compression=1, factor=365,annualize =True
                            Quỳnh H Nguyễn kian hong Tan 2 Replies Last reply Reply Quote 3
                            • Quỳnh H Nguyễn
                              Quỳnh H Nguyễn @soulmachine last edited by

                              @soulmachine

                              I'm just a rookies here. But I think Sharpe ratio is a ratio compare to risk free only. The timeframe and length of series data are important for strategy, the Sharpe result in analyzer is a forecast/far-seeing for standard 1 year from the current series data (less than a year series data).

                              So, the most important mean of Sharpe is compare to risk free with THE RISK of strategy in trading result.

                              1 Reply Last reply Reply Quote 0
                              • kian hong Tan
                                kian hong Tan @soulmachine last edited by

                                @soulmachine Hello, tks for your explanation. I'm testing cryptocurrency too, on 30 mins data. If I'm testing more than a year of data, I do not need to change the default parameters right? maybe only change the factor to 365?

                                1 Reply Last reply Reply Quote 0
                                • 1 / 1
                                • First post
                                  Last post
                                Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
                                $(document).ready(function () { app.coldLoad(); }); }