How to reset the tradehistory
-
Hello,
In my code I loop through all my symbols. In detail I backtest a strategy with cerebro on a symbol and if it is ready I loop through the next stock.
For analyzing the results I use the "class trade_list(bt.Analyzer):" (https://community.backtrader.com/topic/1274/closed-trade-list-including-mfe-mae-analyzer)
If I just loop through 1 Stock there is no problem and the code runs well. But if I loop through 2 or more Stocks, than this error message shows:
"TypeError: 'list' object is not callable"
I think the problem is with this line in my cerebro plot:
strats = cerebro.run(tradehistory=True)
I think I have to reset the trade history, if the next Stock is looping. (If I print my Sticks than I can see, that the first stock loops through and as soo as the second Stock comes, the code stops)
Is there a opportunitie to reset the tradehystory, if my loop starts with the next Stock. For example like this:
if i == 0: set_tradehystory = False else: set_tradehistory=true
thank you for your help :=)
best regards
Christian -
It would be great if you could share the full code and the full backtrace of the exception you've got.
AFAIU the trade history is kept per trade, where the trades are accumulated per strategy. The strategy instances are kept per cerebro instance. If you are using a new cerebro instance per symbol - which I understand is what happening - no trading history need to be cleaned.
However until we see the whole source code - it is hard to tell.
-
Hello vladisld,
I can't post my whole code, but I try to give you an overview about my logic:
class trade_list(bt.Analyzer): # --> pasted code of the link in the problem description class ZigZagStrategy(bt.Strategy): # --> my Strategy if __name__ == '__main__': for i in range(len(alleSymbole)): print("(", alleSymbole[i][0],")", ".... process complete .... ",round(i/len(alleSymbole)*100,2),"%") cerebro = bt.Cerebro() datapath = DATA_LOCATION+alleSymbole[i][0]+".csv" data_df = pd.read_csv(datapath, index_col=0, usecols=["date", "open","high", "low", "close"]) data_df.index = pd.to_datetime(data_df.index) feed = bt.feeds.PandasData(dataname=data_df,name=alleSymbole[i][0]) cerebro.adddata(feed) cerebro.broker.setcash(STARTING_CAP) cerebro.broker.setcommission(commission=COMMISSION, leverage=2) cerebro.addanalyzer(TotalTrades, _name='total_trades') strats = cerebro.run(tradehistory=True) # get analyzers data trade_list = strats[0].analyzers.trade_list.get_analysis() trade_list_tabuliert = tabulate(trade_list, headers="keys") trade_list_pandas = pd.DataFrame(trade_list) # 1. calculating profit factor winners = 0 winner_counter = 0 loosers = 0 looser_counter = 0 for q in range(len(trade_list_pandas["pnl"])): if trade_list_pandas["pnl"][q] >= 0: winners += trade_list_pandas["pnl"][q] winner_counter += 1 else: loosers += trade_list_pandas["pnl"][q] looser_counter += 1 winners = winners / winner_counter loosers = (loosers / looser_counter) * (-1) profit_factor[i] = round(winners/loosers,2) for l in range(len(trade_list_pandas["cumpnl"])): Stock_Equity[l][i] = round(trade_list_pandas["cumpnl"][l],2) symbole = np.empty(len(alleSymbole),dtype=str) for i in range(len(alleSymbole)): symbole[i] = alleSymbole[i][0] pandas = pd.DataFrame(Stock_Equity.tolist(),columns=symbole) PATHi = "/Users/MYPATH.xlsx" pandas.to_excel(PATHi, index=True)
My Error message is here:
File "/Users/PATH", line 484, in <module> strats = cerebro.run(tradehistory=True) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/backtrader/cerebro.py", line 1127, in run runstrat = self.runstrategies(iterstrat) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/backtrader/cerebro.py", line 1257, in runstrategies strat._addanalyzer(ancls, *anargs, **ankwargs) Fi**le "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/backtrader/strategy.py", line 247, in _addanalyzer analyzer = ancls(*anargs, **ankwargs) TypeError: 'list' object is not callable
-
@chhrissi2909 said in How to reset the tradehistory:
cerebro.addanalyzer(TotalTrades, _name='total_trades')
How the TotalTrades class is defined?
-
@vladisld said in How to reset the tradehistory:
TotalTrades
class TotalTrades(bt.Analyzer): def __init__(self): self.tradeanalyzer = bt.analyzers.TradeAnalyzer() def get_analysis(self): tradeanalyzer = self.tradeanalyzer.get_analysis() try: tot_trades = tradeanalyzer.total.closed except: tot_trades = 0 return tot_trades
-
@chhrissi2909
and I run these analyzers like this:results = cerebro.run() total_trades[i] = results[0].analyzers.total_trades.get_analysis()
so I use
strats = cerebro.run(tradehistory=True)
for the pasted class trade_list
andresults = cerebro.run()
for my own analyzers..
could this be the problem?
-
@chhrissi2909 said in How to reset the tradehistory:
analyzer = ancls(*anargs, **ankwargs)
TypeError: 'list' object is not callableCould be a stupid question: are you sure there are no other variable called TotalTrades in your code ? ( according to the error message a simple list instance was passed to the
addanalyzer
method instead of class name ) -
@vladisld said in How to reset the tradehistory:
TotalTrades
Hello vladisld,
no that is not a stupid question, but in my whole script the "word" "TotalTrades" only appears twice. The first in the class name:class TotalTrades(bt.Analyzer):
and secondly in the addanalyzer:
cerebro.addanalyzer(TotalTrades, _name='total_trades')
-
Sorry, wasn't able to repro given the provided code sample. I've filled the missing part of code by some common sense code - and it was running without raising any exception.
Since no full original code is available I can only assume the problem is somewhere in your code and not in Backtrader's code.
Would suggest to try to debug it yourself by breaking at the
cerebro.runstrategies
and see what has been passed to thestrat._addanalyzer
call. -
Every time you call "cerebro = bt.Cerebro()" it resets it. Place this in your loop prior to calling "bt.feeds" and it should do the trick.