From ba29a2ffe4b723ed2025568e0b31df490e316bf4 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 3 Dec 2019 21:30:50 +0300 Subject: [PATCH 1/4] Move docs on loss function creation to a separate doc file --- docs/advanced-hyperopt.md | 63 +++++++++++++++++++++++++++++++++++++++ docs/hyperopt.md | 58 +---------------------------------- 2 files changed, 64 insertions(+), 57 deletions(-) create mode 100644 docs/advanced-hyperopt.md diff --git a/docs/advanced-hyperopt.md b/docs/advanced-hyperopt.md new file mode 100644 index 000000000..b69b671d2 --- /dev/null +++ b/docs/advanced-hyperopt.md @@ -0,0 +1,63 @@ +# Advanced Hyperopt + +This page explains some advanced Hyperopt issues that may require higher +coding skills and Python knowledge than creation of an ordinal hyperoptimization +class. + +## Creating and using a custom loss function + +To use a custom loss function class, make sure that the function `hyperopt_loss_function` is defined in your custom hyperopt loss class. +For the sample below, you then need to add the command line parameter `--hyperopt-loss SuperDuperHyperOptLoss` to your hyperopt call so this fuction is being used. + +A sample of this can be found below, which is identical to the Default Hyperopt loss implementation. A full sample can be found [user_data/hyperopts/](https://github.com/freqtrade/freqtrade/blob/develop/user_data/hyperopts/sample_hyperopt_loss.py) + +``` python +from freqtrade.optimize.hyperopt import IHyperOptLoss + +TARGET_TRADES = 600 +EXPECTED_MAX_PROFIT = 3.0 +MAX_ACCEPTED_TRADE_DURATION = 300 + +class SuperDuperHyperOptLoss(IHyperOptLoss): + """ + Defines the default loss function for hyperopt + """ + + @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 better results + This is the legacy algorithm (used until now in freqtrade). + Weights are distributed as follows: + * 0.4 to trade duration + * 0.25: Avoiding trade loss + * 1.0 to total profit, compared to the expected value (`EXPECTED_MAX_PROFIT`) defined above + """ + total_profit = results.profit_percent.sum() + trade_duration = results.trade_duration.mean() + + 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 + return result +``` + +Currently, the arguments are: + +* `results`: DataFrame containing the result + The following columns are available in results (corresponds to the output-file of backtesting when used with `--export trades`): + `pair, profit_percent, profit_abs, open_time, close_time, open_index, close_index, trade_duration, open_at_end, open_rate, close_rate, sell_reason` +* `trade_count`: Amount of trades (identical to `len(results)`) +* `min_date`: Start date of the hyperopting TimeFrame +* `min_date`: End date of the hyperopting TimeFrame + +This function needs to return a floating point number (`float`). Smaller numbers will be interpreted as better results. The parameters and balancing for this is up to you. + +!!! Note + This function is called once per iteration - so please make sure to have this as optimized as possible to not slow hyperopt down unnecessarily. + +!!! Note + Please keep the arguments `*args` and `**kwargs` in the interface to allow us to extend this interface later. diff --git a/docs/hyperopt.md b/docs/hyperopt.md index c4db6da87..0661896a0 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -183,63 +183,7 @@ Currently, the following loss functions are builtin: * `OnlyProfitHyperOptLoss` (which takes only amount of profit into consideration) * `SharpeHyperOptLoss` (optimizes Sharpe Ratio calculated on the trade returns) -### Creating and using a custom loss function - -To use a custom loss function class, make sure that the function `hyperopt_loss_function` is defined in your custom hyperopt loss class. -For the sample below, you then need to add the command line parameter `--hyperopt-loss SuperDuperHyperOptLoss` to your hyperopt call so this fuction is being used. - -A sample of this can be found below, which is identical to the Default Hyperopt loss implementation. A full sample can be found [user_data/hyperopts/](https://github.com/freqtrade/freqtrade/blob/develop/user_data/hyperopts/sample_hyperopt_loss.py) - -``` python -from freqtrade.optimize.hyperopt import IHyperOptLoss - -TARGET_TRADES = 600 -EXPECTED_MAX_PROFIT = 3.0 -MAX_ACCEPTED_TRADE_DURATION = 300 - -class SuperDuperHyperOptLoss(IHyperOptLoss): - """ - Defines the default loss function for hyperopt - """ - - @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 better results - This is the legacy algorithm (used until now in freqtrade). - Weights are distributed as follows: - * 0.4 to trade duration - * 0.25: Avoiding trade loss - * 1.0 to total profit, compared to the expected value (`EXPECTED_MAX_PROFIT`) defined above - """ - total_profit = results.profit_percent.sum() - trade_duration = results.trade_duration.mean() - - 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 - return result -``` - -Currently, the arguments are: - -* `results`: DataFrame containing the result - The following columns are available in results (corresponds to the output-file of backtesting when used with `--export trades`): - `pair, profit_percent, profit_abs, open_time, close_time, open_index, close_index, trade_duration, open_at_end, open_rate, close_rate, sell_reason` -* `trade_count`: Amount of trades (identical to `len(results)`) -* `min_date`: Start date of the hyperopting TimeFrame -* `min_date`: End date of the hyperopting TimeFrame - -This function needs to return a floating point number (`float`). Smaller numbers will be interpreted as better results. The parameters and balancing for this is up to you. - -!!! Note - This function is called once per iteration - so please make sure to have this as optimized as possible to not slow hyperopt down unnecessarily. - -!!! Note - Please keep the arguments `*args` and `**kwargs` in the interface to allow us to extend this interface later. +Creation of a custom loss function is covered in the [Advanced Hyperopt](advanced-hyperopt.md) part of the documentation. ## Execute Hyperopt From ddf86d6342f642db900b3400c3010d7add477a01 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 3 Dec 2019 21:36:25 +0300 Subject: [PATCH 2/4] Adjust docs index --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index 43d6acc1d..d53687c64 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -24,6 +24,7 @@ nav: - Plotting: plotting.md - SQL Cheatsheet: sql_cheatsheet.md - Advanced Post-installation Tasks: advanced-setup.md + - Advanced Hyperopt: advanced-hyperopt.md - Sandbox Testing: sandbox-testing.md - Deprecated Features: deprecated.md - Contributors Guide: developer.md From ac3e061508083d7f5854c51a70aebbca19c4aa13 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Tue, 3 Dec 2019 23:20:00 +0300 Subject: [PATCH 3/4] Resolve issues stated in the review --- docs/advanced-hyperopt.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/advanced-hyperopt.md b/docs/advanced-hyperopt.md index b69b671d2..4c0f91c77 100644 --- a/docs/advanced-hyperopt.md +++ b/docs/advanced-hyperopt.md @@ -1,15 +1,15 @@ # Advanced Hyperopt -This page explains some advanced Hyperopt issues that may require higher +This page explains some advanced Hyperopt topics that may require higher coding skills and Python knowledge than creation of an ordinal hyperoptimization class. ## Creating and using a custom loss function To use a custom loss function class, make sure that the function `hyperopt_loss_function` is defined in your custom hyperopt loss class. -For the sample below, you then need to add the command line parameter `--hyperopt-loss SuperDuperHyperOptLoss` to your hyperopt call so this fuction is being used. +For the sample below, you then need to add the command line parameter `--hyperopt-loss SuperDuperHyperOptLoss` to your hyperopt call so this function is being used. -A sample of this can be found below, which is identical to the Default Hyperopt loss implementation. A full sample can be found [user_data/hyperopts/](https://github.com/freqtrade/freqtrade/blob/develop/user_data/hyperopts/sample_hyperopt_loss.py) +A sample of this can be found below, which is identical to the Default Hyperopt loss implementation. A full sample can be found in [freqtrade/templates/](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_loss.py) ``` python from freqtrade.optimize.hyperopt import IHyperOptLoss From 8a7fe3f1d69ddd82465f9b58ccec8104160c963a Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 4 Dec 2019 07:01:09 +0100 Subject: [PATCH 4/4] The file will (for users) be in user_data - just in the repo it's in templates --- docs/advanced-hyperopt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/advanced-hyperopt.md b/docs/advanced-hyperopt.md index 4c0f91c77..20af0aaab 100644 --- a/docs/advanced-hyperopt.md +++ b/docs/advanced-hyperopt.md @@ -9,7 +9,7 @@ class. To use a custom loss function class, make sure that the function `hyperopt_loss_function` is defined in your custom hyperopt loss class. For the sample below, you then need to add the command line parameter `--hyperopt-loss SuperDuperHyperOptLoss` to your hyperopt call so this function is being used. -A sample of this can be found below, which is identical to the Default Hyperopt loss implementation. A full sample can be found in [freqtrade/templates/](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_loss.py) +A sample of this can be found below, which is identical to the Default Hyperopt loss implementation. A full sample can be found in [userdata/hyperopts](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_loss.py). ``` python from freqtrade.optimize.hyperopt import IHyperOptLoss