enzoampil / fastquant

fastquant — Backtest and optimize your ML trading strategies with only 3 lines of code!
MIT License
1.52k stars 239 forks source link

[BUG]Optimize trading strategies with automated grid search #393

Closed microplc closed 2 years ago

microplc commented 2 years ago

Problem description

Example

from fastquant import backtest
from fastquant import get_stock_data
df = get_stock_data("JFC", "2018-01-01", "2019-01-01")
print(df.head())
res = backtest("smac", df, fast_period=range(15, 30, 3), slow_period=range(40, 55, 3), verbose=False)
print(res[['fast_period', 'slow_period', 'final_value']].head())

[*100%***] 1 of 1 completed

1 Failed download:

~\AppData\Local\Programs\Python\Python39\lib\site-packages\fastquant\backtest\backtest.py in backtest(strategy, data, commission, init_cash, plot, fractional, verbose, sort_by, sentiments, strats, return_history, return_plot, channel, symbol, allow_short, short_max, figsize, multi_line_indicators, data_class, data_kwargs, plotkwargs, fig, **kwargs) 236 print("=============================================") 237 print("Plotting backtest for optimal parameters ...") --> 238 , fig = backtest( 239 strategy, 240 data,

~\AppData\Local\Programs\Python\Python39\lib\site-packages\fastquant\backtest\backtest.py in backtest(strategy, data, commission, init_cash, plot, fractional, verbose, sort_by, sentiments, strats, return_history, return_plot, channel, symbol, allow_short, short_max, figsize, multi_line_indicators, data_class, data_kwargs, plot_kwargs, fig, **kwargs) 204 # clock the start of the process 205 tstart = time.time() --> 206 stratruns = cerebro.run() 207 208 # clock the end of the process

~\AppData\Local\Programs\Python\Python39\lib\site-packages\backtrader\cerebro.py in run(self, **kwargs) 1125 # let's skip process "spawning" 1126 for iterstrat in iterstrats: -> 1127 runstrat = self.runstrategies(iterstrat) 1128 self.runstrats.append(runstrat) 1129 if self._dooptimize:

~\AppData\Local\Programs\Python\Python39\lib\site-packages\backtrader\cerebro.py in runstrategies(self, iterstrat, predata) 1291 self._runonce_old(runstrats) 1292 else: -> 1293 self._runonce(runstrats) 1294 else: 1295 if self.p.oldsync:

~\AppData\Local\Programs\Python\Python39\lib\site-packages\backtrader\cerebro.py in _runonce(self, runstrats) 1693 1694 for strat in runstrats: -> 1695 strat._oncepost(dt0) 1696 if self._event_stop: # stop if requested 1697 return

~\AppData\Local\Programs\Python\Python39\lib\site-packages\backtrader\strategy.py in _oncepost(self, dt) 303 304 self.lines.datetime[0] = dt --> 305 self._notify() 306 307 minperstatus = self._getminperstatus()

~\AppData\Local\Programs\Python\Python39\lib\site-packages\backtrader\strategy.py in _notify(self, qorders, qtrades) 611 for analyzer in itertools.chain(self.analyzers, self._slave_analyzers): 612 analyzer._notify_cashvalue(cash, value) --> 613 analyzer._notify_fund(cash, value, fundvalue, fundshares) 614 615 def add_timer(self, when,

~\AppData\Local\Programs\Python\Python39\lib\site-packages\backtrader\analyzer.py in _notify_fund(self, cash, value, fundvalue, shares) 162 child._notify_fund(cash, value, fundvalue, shares) 163 --> 164 self.notify_fund(cash, value, fundvalue, shares) 165 166 def _notify_trade(self, trade):

~\AppData\Local\Programs\Python\Python39\lib\site-packages\backtrader\analyzers\drawdown.py in notify_fund(self, cash, value, fundvalue, shares) 91 if not self._fundmode: 92 self._value = value # record current value ---> 93 self._maxvalue = max(self._maxvalue, value) # update peak value 94 else: 95 self._value = fundvalue # record current value

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Expected behavior

Environment

YASHGUPTA2611 commented 2 years ago

is your query resolved?? Please help me, i'm also stuck while optimizing my strategy

mikeejazmines commented 2 years ago

Hi @microplc , this can be fixed by adding plot=False Plot will cause errors given that the result will be the final returns of multiple strategies as seen below

Screen Shot 2021-12-14 at 5 56 40 PM

So plotting will cause an error. The new backtest line should be:

res = backtest("smac", df, fast_period=range(15, 30, 3), slow_period=range(40, 55, 3), verbose=False, plot=False) and it should work

@YASHGUPTA2611 let me know if this fixes your issue as well. if not, please share your code block

YASHGUPTA2611 commented 2 years ago

@microplc Thanks for the reply and yeah it works. Thank You

mikeejazmines commented 2 years ago

Happy to help @YASHGUPTA2611 !

@microplc let me know if this fixes your case as well

YASHGUPTA2611 commented 2 years ago

Yes. it worked. ThankYou!

mikeejazmines commented 2 years ago

Closing issue as fix is provided above. Please comment if issue persists