Importing Pandas Data in Minute Intervals
-
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?
-
@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()