kernc / backtesting.py

:mag_right: :chart_with_upwards_trend: :snake: :moneybag: Backtest trading strategies in Python.
https://kernc.github.io/backtesting.py/
GNU Affero General Public License v3.0
5.04k stars 987 forks source link

Get more than one statistic when optimize #1147

Open ironhak opened 1 month ago

ironhak commented 1 month ago

When I optimize a strategy I can get only a chosen statistic to see for every combinations, for example:

stats, heatmap = bt.optimize(dc_period = range(3,30,3),close_after = range(3,30,3),maximize = 'Return [%]',return_heatmap=True)

If I print(heatmap) I get:

dc_period  close_after
3          3             0.91800
           6             1.65825
           9             1.37100
           12            1.11650
           15            2.13875
                           ...  
27         15            0.46700
           18            1.14275
           21            0.91300
           24            1.07525
           27            1.50150
Name: Return [%], Length: 81, dtype: float64

So I see the two parameters and corresponding return of that combination, but say I also want to see winrate and average trade % of every combination? How can I do that?

Thank's.

coder145 commented 3 weeks ago

To the best of my knowledge, there isn't a way it can be done directly in the library, but you could always rerun the parameters you are interested in to obtain your statistic of choice.

chrisgft commented 2 weeks ago

You can run this yourself a different route and get the same results as well as the stats for every run.


from itertools import product

def run_backtest(params):
    ema_period, keltner_atr_multiplier = params
    bt = Backtest(df_training, Test, cash=CASH, commission=0.0005, margin=0.02, trade_on_close=True, hedging=True)
    stats = bt.run(
        ema_period=ema_period,
        keltner_atr_multiplier=keltner_atr_multiplier
    )
    return stats

# Define ranges for each parameter
ema_period_range = range(30, 50, 10)
keltner_atr_multiplier_range = range(3, 6, 1)

# Generate all possible combinations of parameters
params_list = list(product(ema_period_range, keltner_atr_multiplier_range))

# Use ThreadPoolExecutor to run backtests
with concurrent.futures.ThreadPoolExecutor() as executor:
    results = list(executor.map(run_backtest, params_list))

max_result = None
for result in results:
    if (max_result == None):
        max_result = result['Equity Final [$]']
    else:
        max_result = max(result['Equity Final [$]'], max_result)```