From 66aad3d8089e5b6c79e68008e801108edbcd2ac8 Mon Sep 17 00:00:00 2001 From: Yazeed Al Oyoun Date: Fri, 31 Jan 2020 05:12:09 +0100 Subject: [PATCH] added daily sharpe ratio hyperopt loss method, ty @djacky --- freqtrade/commands/cli_options.py | 2 +- .../optimize/hyperopt_loss_sharpe_daily.py | 69 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 freqtrade/optimize/hyperopt_loss_sharpe_daily.py diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py index 490f26cfa..6d8d13129 100644 --- a/freqtrade/commands/cli_options.py +++ b/freqtrade/commands/cli_options.py @@ -256,7 +256,7 @@ AVAILABLE_CLI_OPTIONS = { help='Specify the class name of the hyperopt loss function class (IHyperOptLoss). ' 'Different functions can generate completely different results, ' 'since the target for optimization is different. Built-in Hyperopt-loss-functions are: ' - 'DefaultHyperOptLoss, OnlyProfitHyperOptLoss, SharpeHyperOptLoss.' + 'DefaultHyperOptLoss, OnlyProfitHyperOptLoss, SharpeHyperOptLoss, SharpeHyperOptLossDaily.' '(default: `%(default)s`).', metavar='NAME', default=constants.DEFAULT_HYPEROPT_LOSS, diff --git a/freqtrade/optimize/hyperopt_loss_sharpe_daily.py b/freqtrade/optimize/hyperopt_loss_sharpe_daily.py new file mode 100644 index 000000000..24a992250 --- /dev/null +++ b/freqtrade/optimize/hyperopt_loss_sharpe_daily.py @@ -0,0 +1,69 @@ +""" +SharpeHyperOptLoss + +This module defines the alternative HyperOptLoss class which can be used for +Hyperoptimization. +""" +from datetime import datetime + +from pandas import DataFrame +import numpy as np + +from freqtrade.optimize.hyperopt import IHyperOptLoss + + +class SharpeHyperOptLossDaily(IHyperOptLoss): + """ + Defines the loss function for hyperopt. + + This implementation uses the Sharpe Ratio calculation. + """ + + @staticmethod + def hyperopt_loss_function( + results: DataFrame, + trade_count: int, + min_date: datetime, + max_date: datetime, + *args, + **kwargs + ) -> float: + """ + Objective function, returns smaller number for more optimal results. + + Uses Sharpe Ratio calculation. + """ + total_profit = results.profit_percent + # days_period = (max_date - min_date).days + + # adding slippage of 0.1% per trade + total_profit = total_profit - 0.0005 + # expected_yearly_return = total_profit.sum() / days_period + + # if np.std(total_profit) != 0.0: + # sharp_ratio = expected_yearly_return / np.std(total_profit) * np.sqrt(365) + # else: + # # Define high (negative) sharpe ratio to be clear that this is NOT optimal. + # sharp_ratio = -20.0 + + # # print(expected_yearly_return, np.std(total_profit), sharp_ratio) + # return -sharp_ratio + + sum_daily = ( + results.resample("D", on="close_time").agg( + {"profit_percent": sum, "profit_abs": sum} + ) + * 100.0 + ) + + if np.std(total_profit) != 0.0: + sharp_ratio = ( + sum_daily["profit_percent"].mean() + / sum_daily["profit_percent"].std() + * np.sqrt(365) + ) + else: + # Define high (negative) sharpe ratio to be clear that this is NOT optimal. + sharp_ratio = -20.0 + + return -sharp_ratio