mirror of
https://github.com/freqtrade/freqtrade.git
synced 2024-11-10 10:21:59 +00:00
ruff format: hyperopt-loss
This commit is contained in:
parent
ab3dbb7fbc
commit
f1ef537dfa
|
@ -4,6 +4,7 @@ CalmarHyperOptLoss
|
|||
This module defines the alternative HyperOptLoss class which can be used for
|
||||
Hyperoptimization.
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from pandas import DataFrame
|
||||
|
@ -21,15 +22,21 @@ class CalmarHyperOptLoss(IHyperOptLoss):
|
|||
"""
|
||||
|
||||
@staticmethod
|
||||
def hyperopt_loss_function(results: DataFrame, trade_count: int,
|
||||
min_date: datetime, max_date: datetime,
|
||||
config: Config, *args, **kwargs) -> float:
|
||||
def hyperopt_loss_function(
|
||||
results: DataFrame,
|
||||
trade_count: int,
|
||||
min_date: datetime,
|
||||
max_date: datetime,
|
||||
config: Config,
|
||||
*args,
|
||||
**kwargs,
|
||||
) -> float:
|
||||
"""
|
||||
Objective function, returns smaller number for more optimal results.
|
||||
|
||||
Uses Calmar Ratio calculation.
|
||||
"""
|
||||
starting_balance = config['dry_run_wallet']
|
||||
starting_balance = config["dry_run_wallet"]
|
||||
calmar_ratio = calculate_calmar(results, min_date, max_date, starting_balance)
|
||||
# print(expected_returns_mean, max_drawdown, calmar_ratio)
|
||||
return -calmar_ratio
|
||||
|
|
|
@ -4,6 +4,7 @@ MaxDrawDownHyperOptLoss
|
|||
This module defines the alternative HyperOptLoss class which can be used for
|
||||
Hyperoptimization.
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from pandas import DataFrame
|
||||
|
@ -13,7 +14,6 @@ from freqtrade.optimize.hyperopt import IHyperOptLoss
|
|||
|
||||
|
||||
class MaxDrawDownHyperOptLoss(IHyperOptLoss):
|
||||
|
||||
"""
|
||||
Defines the loss function for hyperopt.
|
||||
|
||||
|
@ -22,19 +22,23 @@ class MaxDrawDownHyperOptLoss(IHyperOptLoss):
|
|||
"""
|
||||
|
||||
@staticmethod
|
||||
def hyperopt_loss_function(results: DataFrame, trade_count: int,
|
||||
min_date: datetime, max_date: datetime,
|
||||
*args, **kwargs) -> float:
|
||||
|
||||
def hyperopt_loss_function(
|
||||
results: DataFrame,
|
||||
trade_count: int,
|
||||
min_date: datetime,
|
||||
max_date: datetime,
|
||||
*args,
|
||||
**kwargs,
|
||||
) -> float:
|
||||
"""
|
||||
Objective function.
|
||||
|
||||
Uses profit ratio weighted max_drawdown when drawdown is available.
|
||||
Otherwise directly optimizes profit ratio.
|
||||
"""
|
||||
total_profit = results['profit_abs'].sum()
|
||||
total_profit = results["profit_abs"].sum()
|
||||
try:
|
||||
max_drawdown = calculate_max_drawdown(results, value_col='profit_abs')
|
||||
max_drawdown = calculate_max_drawdown(results, value_col="profit_abs")
|
||||
except ValueError:
|
||||
# No losing trade, therefore no drawdown.
|
||||
return -total_profit
|
||||
|
|
|
@ -4,6 +4,7 @@ MaxDrawDownRelativeHyperOptLoss
|
|||
This module defines the alternative HyperOptLoss class which can be used for
|
||||
Hyperoptimization.
|
||||
"""
|
||||
|
||||
from pandas import DataFrame
|
||||
|
||||
from freqtrade.constants import Config
|
||||
|
@ -12,7 +13,6 @@ from freqtrade.optimize.hyperopt import IHyperOptLoss
|
|||
|
||||
|
||||
class MaxDrawDownRelativeHyperOptLoss(IHyperOptLoss):
|
||||
|
||||
"""
|
||||
Defines the loss function for hyperopt.
|
||||
|
||||
|
@ -21,24 +21,20 @@ class MaxDrawDownRelativeHyperOptLoss(IHyperOptLoss):
|
|||
"""
|
||||
|
||||
@staticmethod
|
||||
def hyperopt_loss_function(results: DataFrame, config: Config,
|
||||
*args, **kwargs) -> float:
|
||||
|
||||
def hyperopt_loss_function(results: DataFrame, config: Config, *args, **kwargs) -> float:
|
||||
"""
|
||||
Objective function.
|
||||
|
||||
Uses profit ratio weighted max_drawdown when drawdown is available.
|
||||
Otherwise directly optimizes profit ratio.
|
||||
"""
|
||||
total_profit = results['profit_abs'].sum()
|
||||
total_profit = results["profit_abs"].sum()
|
||||
try:
|
||||
drawdown_df = calculate_underwater(
|
||||
results,
|
||||
value_col='profit_abs',
|
||||
starting_balance=config['dry_run_wallet']
|
||||
results, value_col="profit_abs", starting_balance=config["dry_run_wallet"]
|
||||
)
|
||||
max_drawdown = abs(min(drawdown_df['drawdown']))
|
||||
relative_drawdown = max(drawdown_df['drawdown_relative'])
|
||||
max_drawdown = abs(min(drawdown_df["drawdown"]))
|
||||
relative_drawdown = max(drawdown_df["drawdown_relative"])
|
||||
if max_drawdown == 0:
|
||||
return -total_profit
|
||||
return -total_profit / max_drawdown / relative_drawdown
|
||||
|
|
|
@ -4,6 +4,7 @@ OnlyProfitHyperOptLoss
|
|||
This module defines the alternative HyperOptLoss class which can be used for
|
||||
Hyperoptimization.
|
||||
"""
|
||||
|
||||
from pandas import DataFrame
|
||||
|
||||
from freqtrade.optimize.hyperopt import IHyperOptLoss
|
||||
|
@ -17,10 +18,9 @@ class OnlyProfitHyperOptLoss(IHyperOptLoss):
|
|||
"""
|
||||
|
||||
@staticmethod
|
||||
def hyperopt_loss_function(results: DataFrame, trade_count: int,
|
||||
*args, **kwargs) -> float:
|
||||
def hyperopt_loss_function(results: DataFrame, trade_count: int, *args, **kwargs) -> float:
|
||||
"""
|
||||
Objective function, returns smaller number for better results.
|
||||
"""
|
||||
total_profit = results['profit_abs'].sum()
|
||||
total_profit = results["profit_abs"].sum()
|
||||
return -1 * total_profit
|
||||
|
|
|
@ -7,6 +7,7 @@ Drawdown objective which can be used for Hyperoptimization.
|
|||
Possible to change `DRAWDOWN_MULT` to penalize drawdown objective for
|
||||
individual needs.
|
||||
"""
|
||||
|
||||
from pandas import DataFrame
|
||||
|
||||
from freqtrade.data.metrics import calculate_max_drawdown
|
||||
|
|
|
@ -4,6 +4,7 @@ SharpeHyperOptLoss
|
|||
This module defines the alternative HyperOptLoss class which can be used for
|
||||
Hyperoptimization.
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from pandas import DataFrame
|
||||
|
@ -21,15 +22,21 @@ class SharpeHyperOptLoss(IHyperOptLoss):
|
|||
"""
|
||||
|
||||
@staticmethod
|
||||
def hyperopt_loss_function(results: DataFrame, trade_count: int,
|
||||
min_date: datetime, max_date: datetime,
|
||||
config: Config, *args, **kwargs) -> float:
|
||||
def hyperopt_loss_function(
|
||||
results: DataFrame,
|
||||
trade_count: int,
|
||||
min_date: datetime,
|
||||
max_date: datetime,
|
||||
config: Config,
|
||||
*args,
|
||||
**kwargs,
|
||||
) -> float:
|
||||
"""
|
||||
Objective function, returns smaller number for more optimal results.
|
||||
|
||||
Uses Sharpe Ratio calculation.
|
||||
"""
|
||||
starting_balance = config['dry_run_wallet']
|
||||
starting_balance = config["dry_run_wallet"]
|
||||
sharp_ratio = calculate_sharpe(results, min_date, max_date, starting_balance)
|
||||
# print(expected_returns_mean, up_stdev, sharp_ratio)
|
||||
return -sharp_ratio
|
||||
|
|
|
@ -4,6 +4,7 @@ SharpeHyperOptLossDaily
|
|||
This module defines the alternative HyperOptLoss class which can be used for
|
||||
Hyperoptimization.
|
||||
"""
|
||||
|
||||
import math
|
||||
from datetime import datetime
|
||||
|
||||
|
@ -20,31 +21,38 @@ class SharpeHyperOptLossDaily(IHyperOptLoss):
|
|||
"""
|
||||
|
||||
@staticmethod
|
||||
def hyperopt_loss_function(results: DataFrame, trade_count: int,
|
||||
min_date: datetime, max_date: datetime,
|
||||
*args, **kwargs) -> float:
|
||||
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.
|
||||
"""
|
||||
resample_freq = '1D'
|
||||
resample_freq = "1D"
|
||||
slippage_per_trade_ratio = 0.0005
|
||||
days_in_year = 365
|
||||
annual_risk_free_rate = 0.0
|
||||
risk_free_rate = annual_risk_free_rate / days_in_year
|
||||
|
||||
# apply slippage per trade to profit_ratio
|
||||
results.loc[:, 'profit_ratio_after_slippage'] = \
|
||||
results['profit_ratio'] - slippage_per_trade_ratio
|
||||
results.loc[:, "profit_ratio_after_slippage"] = (
|
||||
results["profit_ratio"] - slippage_per_trade_ratio
|
||||
)
|
||||
|
||||
# create the index within the min_date and end max_date
|
||||
t_index = date_range(start=min_date, end=max_date, freq=resample_freq,
|
||||
normalize=True)
|
||||
t_index = date_range(start=min_date, end=max_date, freq=resample_freq, normalize=True)
|
||||
|
||||
sum_daily = (
|
||||
results.resample(resample_freq, on='close_date').agg(
|
||||
{"profit_ratio_after_slippage": 'sum'}).reindex(t_index).fillna(0)
|
||||
results.resample(resample_freq, on="close_date")
|
||||
.agg({"profit_ratio_after_slippage": "sum"})
|
||||
.reindex(t_index)
|
||||
.fillna(0)
|
||||
)
|
||||
|
||||
total_profit = sum_daily["profit_ratio_after_slippage"] - risk_free_rate
|
||||
|
@ -55,7 +63,7 @@ class SharpeHyperOptLossDaily(IHyperOptLoss):
|
|||
sharp_ratio = expected_returns_mean / up_stdev * math.sqrt(days_in_year)
|
||||
else:
|
||||
# Define high (negative) sharpe ratio to be clear that this is NOT optimal.
|
||||
sharp_ratio = -20.
|
||||
sharp_ratio = -20.0
|
||||
|
||||
# print(t_index, sum_daily, total_profit)
|
||||
# print(risk_free_rate, expected_returns_mean, up_stdev, sharp_ratio)
|
||||
|
|
|
@ -3,6 +3,7 @@ ShortTradeDurHyperOptLoss
|
|||
This module defines the default HyperoptLoss class which is being used for
|
||||
Hyperoptimization.
|
||||
"""
|
||||
|
||||
from math import exp
|
||||
|
||||
from pandas import DataFrame
|
||||
|
@ -32,8 +33,7 @@ class ShortTradeDurHyperOptLoss(IHyperOptLoss):
|
|||
"""
|
||||
|
||||
@staticmethod
|
||||
def hyperopt_loss_function(results: DataFrame, trade_count: int,
|
||||
*args, **kwargs) -> float:
|
||||
def hyperopt_loss_function(results: DataFrame, trade_count: int, *args, **kwargs) -> float:
|
||||
"""
|
||||
Objective function, returns smaller number for better results
|
||||
This is the Default algorithm
|
||||
|
@ -42,10 +42,10 @@ class ShortTradeDurHyperOptLoss(IHyperOptLoss):
|
|||
* 0.25: Avoiding trade loss
|
||||
* 1.0 to total profit, compared to the expected value (`EXPECTED_MAX_PROFIT`) defined above
|
||||
"""
|
||||
total_profit = results['profit_ratio'].sum()
|
||||
trade_duration = results['trade_duration'].mean()
|
||||
total_profit = results["profit_ratio"].sum()
|
||||
trade_duration = results["trade_duration"].mean()
|
||||
|
||||
trade_loss = 1 - 0.25 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5.8)
|
||||
trade_loss = 1 - 0.25 * exp(-((trade_count - TARGET_TRADES) ** 2) / 10**5.8)
|
||||
profit_loss = max(0, 1 - total_profit / EXPECTED_MAX_PROFIT)
|
||||
duration_loss = 0.4 * min(trade_duration / MAX_ACCEPTED_TRADE_DURATION, 1)
|
||||
result = trade_loss + profit_loss + duration_loss
|
||||
|
|
|
@ -4,6 +4,7 @@ SortinoHyperOptLoss
|
|||
This module defines the alternative HyperOptLoss class which can be used for
|
||||
Hyperoptimization.
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from pandas import DataFrame
|
||||
|
@ -21,15 +22,21 @@ class SortinoHyperOptLoss(IHyperOptLoss):
|
|||
"""
|
||||
|
||||
@staticmethod
|
||||
def hyperopt_loss_function(results: DataFrame, trade_count: int,
|
||||
min_date: datetime, max_date: datetime,
|
||||
config: Config, *args, **kwargs) -> float:
|
||||
def hyperopt_loss_function(
|
||||
results: DataFrame,
|
||||
trade_count: int,
|
||||
min_date: datetime,
|
||||
max_date: datetime,
|
||||
config: Config,
|
||||
*args,
|
||||
**kwargs,
|
||||
) -> float:
|
||||
"""
|
||||
Objective function, returns smaller number for more optimal results.
|
||||
|
||||
Uses Sortino Ratio calculation.
|
||||
"""
|
||||
starting_balance = config['dry_run_wallet']
|
||||
starting_balance = config["dry_run_wallet"]
|
||||
sortino_ratio = calculate_sortino(results, min_date, max_date, starting_balance)
|
||||
# print(expected_returns_mean, down_stdev, sortino_ratio)
|
||||
return -sortino_ratio
|
||||
|
|
|
@ -4,6 +4,7 @@ SortinoHyperOptLossDaily
|
|||
This module defines the alternative HyperOptLoss class which can be used for
|
||||
Hyperoptimization.
|
||||
"""
|
||||
|
||||
import math
|
||||
from datetime import datetime
|
||||
|
||||
|
@ -20,9 +21,14 @@ class SortinoHyperOptLossDaily(IHyperOptLoss):
|
|||
"""
|
||||
|
||||
@staticmethod
|
||||
def hyperopt_loss_function(results: DataFrame, trade_count: int,
|
||||
min_date: datetime, max_date: datetime,
|
||||
*args, **kwargs) -> float:
|
||||
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.
|
||||
|
||||
|
@ -31,30 +37,32 @@ class SortinoHyperOptLossDaily(IHyperOptLoss):
|
|||
Sortino Ratio calculated as described in
|
||||
http://www.redrockcapital.com/Sortino__A__Sharper__Ratio_Red_Rock_Capital.pdf
|
||||
"""
|
||||
resample_freq = '1D'
|
||||
resample_freq = "1D"
|
||||
slippage_per_trade_ratio = 0.0005
|
||||
days_in_year = 365
|
||||
minimum_acceptable_return = 0.0
|
||||
|
||||
# apply slippage per trade to profit_ratio
|
||||
results.loc[:, 'profit_ratio_after_slippage'] = \
|
||||
results['profit_ratio'] - slippage_per_trade_ratio
|
||||
results.loc[:, "profit_ratio_after_slippage"] = (
|
||||
results["profit_ratio"] - slippage_per_trade_ratio
|
||||
)
|
||||
|
||||
# create the index within the min_date and end max_date
|
||||
t_index = date_range(start=min_date, end=max_date, freq=resample_freq,
|
||||
normalize=True)
|
||||
t_index = date_range(start=min_date, end=max_date, freq=resample_freq, normalize=True)
|
||||
|
||||
sum_daily = (
|
||||
results.resample(resample_freq, on='close_date').agg(
|
||||
{"profit_ratio_after_slippage": 'sum'}).reindex(t_index).fillna(0)
|
||||
results.resample(resample_freq, on="close_date")
|
||||
.agg({"profit_ratio_after_slippage": "sum"})
|
||||
.reindex(t_index)
|
||||
.fillna(0)
|
||||
)
|
||||
|
||||
total_profit = sum_daily["profit_ratio_after_slippage"] - minimum_acceptable_return
|
||||
expected_returns_mean = total_profit.mean()
|
||||
|
||||
sum_daily['downside_returns'] = 0.0
|
||||
sum_daily.loc[total_profit < 0, 'downside_returns'] = total_profit
|
||||
total_downside = sum_daily['downside_returns']
|
||||
sum_daily["downside_returns"] = 0.0
|
||||
sum_daily.loc[total_profit < 0, "downside_returns"] = total_profit
|
||||
total_downside = sum_daily["downside_returns"]
|
||||
# Here total_downside contains min(0, P - MAR) values,
|
||||
# where P = sum_daily["profit_ratio_after_slippage"]
|
||||
down_stdev = math.sqrt((total_downside**2).sum() / len(total_downside))
|
||||
|
@ -63,7 +71,7 @@ class SortinoHyperOptLossDaily(IHyperOptLoss):
|
|||
sortino_ratio = expected_returns_mean / down_stdev * math.sqrt(days_in_year)
|
||||
else:
|
||||
# Define high (negative) sortino ratio to be clear that this is NOT optimal.
|
||||
sortino_ratio = -20.
|
||||
sortino_ratio = -20.0
|
||||
|
||||
# print(t_index, sum_daily, total_profit)
|
||||
# print(minimum_acceptable_return, expected_returns_mean, down_stdev, sortino_ratio)
|
||||
|
|
Loading…
Reference in New Issue
Block a user