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/

    Importing Pandas Data in Minute Intervals

    General Code/Help
    timeframe interval klines ticks
    1
    2
    657
    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.
    • K
      krypterro last edited by

      I am unable to get my strategy to recognize my minute data, although hourly works fine. It seems I need to switch the cerebro default from daily to minutes, but the code out found here to do that...

      cerebro.adddata(data, timeframe=bt.Timeframe.Minutes, compression=1)
      

      throws this error:

      Traceback (most recent call last):
       File "autotest2.py", line 196, in <module>
         main()
       File "autotest2.py", line 54, in main
         x = threading.Thread(target=runner(db1, df, interval), args=(index,))
       File "autotest2.py", line 103, in runner
         cerebro.adddata(data, timeframe=bt.Timeframe.Minutes, compression=1)
      AttributeError: module 'backtrader' has no attribute 'Timeframe'
      

      Has something changed in the current version? How do I utilize Pandas data in minutes properly so that cerebro recognizes and processes them correctly?

      K 1 Reply Last reply Reply Quote 0
      • K
        krypterro @krypterro last edited by

        @krypterro
        The following code works, but still does not process buy/sell functions in the strategy. I am using the generic sma example strategy from Backtrader docs. Works on hourly data perfectly, but not per minute data, but now with no errors. I am pulling data from MySQL, into a Pandas DataFrame with the code below, and using bta-lib in Pandas before passing the DataFrame into cerebro. How do I get cerebro to work with minute data if not this way?

        from __future__ import (absolute_import, division, print_function,
                                unicode_literals)
        import random
        import datetime  # For datetime objects
        import os.path  # To manage paths
        import sys  # To find out the script name (in argv[0])
        import threading
        
        import pandas as pd
        import btalib
        from colorama import init
        from colorama import Fore, Back, Style
        from loguru import logger
        
        import backtrader as bt
        import backtrader.analyzers as btanalyzers
        import backtrader.feeds as btfeeds
        import backtrader.strategies as btstrats
        
        from DBA import Binance
        from DB import DB1
        from Strategy2 import MinStrategy
        from Toolbox import Hammers
        
        def main():
            go_time = datetime.datetime.now()
            init()
            db1 = DB1()
            os.system('clear')
            
            runs = 1
            interval = 'minutes'
            start_time = datetime.datetime.strptime('1 Aug 2020', '%d %b %Y')
            
            # period select
            print('retrieving data...')
            btc_list = Binance.get_btc_minutes_cut(db1, start_time)
            print('loading dataframe...')
            data_df = pd.DataFrame(btc_list)
            df = data_df.set_index('stamp')
            print('begining analysis...')
            print('--------------------')
            print(Fore.CYAN)
            # ---------------------
            
            threads = list()
            for index in range(runs):
                x = threading.Thread(target=runner(db1, df, interval), args=(index,))
                threads.append(x)
                x.start()
        
            for index, thread in enumerate(threads):
                thread.join()
            
            # ---------------------
            print(Style.RESET_ALL)
            print('BackTesting Complete')
            stop_time = datetime.datetime.now() - go_time
            run_time = stop_time.total_seconds()
            print('Toal Run Time:', run_time)
            avg_run = run_time / runs
            print('Average Run Time:', avg_run)
            
        def runner(db1, df, interval):
            start_time = df.index[0]
            end_time = df.index[-1]
            span_list = [1,2,4,6,15,60,120,240]
            in_data = {}
            in_data['strategy'] = 'btcemaroll'
            in_data['cash_in'] = 10000
            in_data['commission'] = .002
            in_data['span'] = random.choice(span_list)
            in_data['pip_value'] = 0.01
            in_data['range_under'] = random.randint(1, 2000)
            in_data['range_over'] = random.randint(2000, 3000)
            in_data['diff_under'] = random.randint(1, 100)
            in_data['diff_over'] = random.randint(100, 300)
            in_data['min_profit'] = .01 #random.randint(1, 50)
            
            # add bta-lib indicators
            #df['sma'] = btalib.sma(df.high, period=in_data['span']).df
            df['ema'] = btalib.ema(df.close, period=in_data['span']).df
        
            # Create a cerebro obj and populate
            cerebro = bt.Cerebro()
            #cerebro.addstrategy(MinStrategy, in_data)
            cerebro.addstrategy(MinStrategy, in_data)
        
            # ---------------
            # pandas data setup
            data = PandasData_Extend(dataname=df, timeframe=bt.TimeFrame.Minutes, compression = 1)
            cerebro.adddata(data)
            # ---------------
            
            cerebro.broker.setcash(in_data['cash_in'])
            cerebro.broker.setcommission(commission=in_data['commission'])
        
            # Analyzer
            cerebro.addanalyzer(btanalyzers.SharpeRatio, _name='out_sharpe')
            cerebro.addanalyzer(btanalyzers.DrawDown, _name='out_drawdown')
            #cerebro.addanalyzer(btanalyzers.AnnualReturn, _name='out_annual')
        
            # Add a FixedSize sizer according to the stake
            #cerebro.addsizer(bt.sizers.FixedSize, stake=10)
            
            print('Starting Portfolio Value: ', as_currency(cerebro.broker.getvalue()))
            print('Start Time:', start_time)
            print('End Time:', end_time)
            start_cap = cerebro.broker.getvalue()
            
            # Run over everything
            thestrats = cerebro.run()
            thestrat = thestrats[0]
        
            sharpe_data = dict(thestrat.analyzers.out_sharpe.get_analysis())
            sharpe_ratio = sharpe_data['sharperatio']
            drawdown_data = dict(thestrat.analyzers.out_drawdown.get_analysis())
            drawdown_data = drawdown_data['max']
            #annual_data = dict(thestrat.analyzers.out_annual.get_analysis())
        
            # format text
            drawdown_percentage = round(drawdown_data['drawdown'],2)
            drawdown_money = as_currency(drawdown_data['moneydown'])
            net_profit = (cerebro.broker.getvalue() - start_cap
                          ) / cerebro.broker.getvalue() * 100
            net_profit = round(net_profit, 2)
            final_total = as_currency(cerebro.broker.getvalue())
            
            # build dictionary for results db
            out_data = {}
            out_data['cash_in'] = final_total
            out_data['max_drawdown_hours'] = drawdown_data['len']
            out_data['max_drawdown_per'] = drawdown_percentage
            out_data['max_drawdown_money'] = round(drawdown_data['moneydown'],2)
            out_data['sharpe'] = sharpe_ratio
            out_data['cash_out'] = round(cerebro.broker.getvalue(),2)
            out_data['net_profit'] = net_profit
            
            # Print out the final result
            #Binance.add_backtest(db1, interval, start_time, end_time, in_data, out_data)
            print('Minimum Profit:', in_data['min_profit'], '%')
            print('Span:', in_data['span'], interval)
            print('Max Drawdown Length:', drawdown_data['len'], 'hours')
            print('Max Drawdown Percentage:', drawdown_percentage, '%')
            print('Max Drawdown Money:', drawdown_money)
            print('Sharpe Ratio:', sharpe_ratio)
            print('Final Portfolio Value: ', final_total)
            print('Net Profit: ', net_profit, '%')
            print('------------------------')
            
        def as_currency(amount):
            if amount >= 0:
                return '${:,.2f}'.format(amount)
            else:
                return '-${:,.2f}'.format(-amount)
        
        
        class PandasData_Extend(btfeeds.PandasData):
            lines = (('btc_id','btc_hour','volume','close_time','quote_av','trades','tb_base_av','tb_quote_av','ema'))
            params = (
                ('btc_id', -1),
                ('btc_hour', -1),
                ('volume', -1),
                ('close_time', -1),
                ('quote_av', -1),
                ('trades', -1),
                ('tb_base_av', -1),
                ('tb_quote_av', -1),
                ('ema', -1)
                )
        
        main()
        
        1 Reply Last reply Reply Quote 0
        • 1 / 1
        • First post
          Last post
        Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors