Repository: freqtrade/freqtrade

Issue:
Using Hyperopt output to input Strategy run and backtesting
<!-- 
Note: this section will not show up in the issue.
Have you search for this feature before requesting it? It's highly likely that a similar request was already filed.
-->


## Describe the enhancement

Export a Json File with hyperopt result as a strategy name and timeframe pattern on the name, eg.: Stragegy_5m.json with ROI, stop-loss, hyperopt parameters, etc.




*Explain the enhancement you would like*

I'm not a python developer to best implement this.

Automatically or parameter load generated file during backtesting and execution strategy overriding parameter in strategy, using this dict like param is used in hyperopt file, make only one code to hyperopt and strategy execution.



Discussion:
I personally don't think that's a good enhancement.

Usually, you'll have a lot more indicators while running hyperopt, than what you'll be using in the final strategy.

By using the same code - you're basically forced to keep calculation of all indicators in the final strategy, which will heavily reduce performance of a production bot - and waste a lot of money (you need a bigger VPS).

Also, the transfer step (from hyperopt to strategy) makes you think about the strategy and try to understand the basics (at least it should) - so you can maybe identify an obvious bug / problem which would otherwise not be applicable.

The main workflow in my opinion is as follows:
* Have a strategy idea
* try to implement it as strategy - backtest it
* if it seems to work, optimize (hyperopt) that strategy to get the best out of it.

Coming with no idea at all, and just "dumping everything" into a hyperopt file hoping for some outcome will not work - as it'll
* have hyperopt take forever due to the very large search space
* induce false hopes in the outcome - as users will not even bother to look at the outcome cleanly other than "does good profits" - but then be surprised if the stoploss at -0.5 (50%) is hit and half of the capital is gone on the first trade (no matter how good a strategy is - the first trade can always be a loss  - and i'm yet to see a strategy that doesn't hit stoploss).

---

For these reasons - to me this is not something we should have documentation for - or even provide samples for.

One note maybe - it's not impossible at this moment - as a strategy can do many things as it's in the end, just python code that get's executed.



The hyperopt file itself is kept - so using `freqtrade list-hyperopt` you can see every result in the outcome (only from the last hyperopt execution) - but improving this and keeping a history of hyperopt runs is a different topic.
you are 100% right, my mistake
no mistake detected - 
In addition to that, I'd like to keep this open just a little longer to give others the chance to read and contribute as well if you don't mind.

I'm just one guy with one opinion - just because i don't like it / have concerns doesn't mean it can't be useful ... 
my old idea here was to add the `--strategy-params JSON_STRING` option, which accepts the strategy params as json (from the `hyperopt`/`hyperopt-list`/`hyperopt-show` output printed with `--print-json`) and overrides attributes of the strategy class instance with the provided values
i knew you'd have an opinion on this :laughing: 

using a json-string in the cli might fail depending on the content ... so i don't think that's a good solution.

as said above, it can be solved within a strategy - but personally, i don't think this should be a supported method (reasons - see above).

> i knew you'd have an opinion on this :laughing: 

I also knew you knew it... 😆 

string values in json are surrounded in single quotes `'...'`, so the whole json can always be specified in the double quotes, I do not think it can fail in cli...
but it's a bad interface nonetheless - as you specify a json (something meant to be stored or transmitted) in a cli - which people will start to modify and make syntax errors - it'll then fail - and i do not intend to support that - as it'll be almost impossible to determine why it doesn't work.
This idea is used by [RoninAI](https://roninai.com/), and to make it work, they make you buy a box (a steroid doped Raspberry Pi like) with a $1,200/year subscription to their ML/AI software.

![photo_2020-06-08_20-49-04](https://user-images.githubusercontent.com/29242247/84279691-52777200-ab04-11ea-90b6-6f2b37289704.jpg)

Ah, ok, I understand, but my idea is to interact better with these two modules, some work is needed in developing strategies to use this, my PR #3461 is to facilitate this, but if possible, to facilitate it even more

In the hyperopt, pass a parameter to generate this stored data, return a key / name; in trade / backtesting, pass this key / name as a parameter to use strategy data replacement, as @hroff-1902 mentioned.
> This idea is used by [RoninAI](https://roninai.com/), and to make it work, they make you buy a box (a steroid doped Raspberry Pi like) with a $1,200/year subscription to their ML/AI software.
> 
> ![photo_2020-06-08_20-49-04](https://user-images.githubusercontent.com/29242247/84279691-52777200-ab04-11ea-90b6-6f2b37289704.jpg)

Someway add this graph in plot module is really another great improvement
I don't think we'll do much to the plotting module at this point.

It's rather clumsy to use as it's static and inflexible - not just because of that we're currently working on a proper UI for freqtrade (https://github.com/freqtrade/frequi) - which will almost certainly not use plotly anymore, as the performance is ... not so good ...

I think it is best that there to some degree is a "bar to entry" to using the bot. 

#1 Because it is so powerfull as it is and better than the paid crypto bots. 

#2 We would have everybody/every retard in the crypto space using freqtrade if the bot can convert your hyperopt results into a working strategy by it self. - I dont think that is in anybodys interest. Imagen the 100.000+ noob posts a year here on GitHub lol. 

#3 I think you your self can imagen all the other backlashes from 10.000x'ing the number of people using freqtrade. 

Have a lovely day guys and as always thanks for your hard work on the bot. 

Confucius_The_Great
> I don't think we'll do much to the plotting module at this point.
> 
> It's rather clumsy to use as it's static and inflexible - not just because of that we're currently working on a proper UI for freqtrade (https://github.com/freqtrade/frequi) - which will almost certainly not use plotly anymore, as the performance is ... not so good ...

When you can, please give us some pictures of how it is sort of going to look like =D I'm super excited already! 
@qkum channel #frequi in slack has some screenshots ... :) 

we'll add them to the documentation once we know it won't change anymore ... which is not the case at the moment.

Resolving patch:
diff --git a/freqtrade/optimize/hyperopt.py b/freqtrade/optimize/hyperopt.py
--- a/freqtrade/optimize/hyperopt.py
+++ b/freqtrade/optimize/hyperopt.py
@@ -73,6 +73,7 @@ def __init__(self, config: Dict[str, Any]) -> None:
         self.backtesting = Backtesting(self.config)
 
         self.custom_hyperopt = HyperOptResolver.load_hyperopt(self.config)
+        self.custom_hyperopt.__class__.strategy = self.backtesting.strategy
 
         self.custom_hyperoptloss = HyperOptLossResolver.load_hyperoptloss(self.config)
         self.calculate_loss = self.custom_hyperoptloss.hyperopt_loss_function
diff --git a/freqtrade/optimize/hyperopt_interface.py b/freqtrade/optimize/hyperopt_interface.py
--- a/freqtrade/optimize/hyperopt_interface.py
+++ b/freqtrade/optimize/hyperopt_interface.py
@@ -12,6 +12,7 @@
 from freqtrade.exceptions import OperationalException
 from freqtrade.exchange import timeframe_to_minutes
 from freqtrade.misc import round_dict
+from freqtrade.strategy import IStrategy
 
 
 logger = logging.getLogger(__name__)
@@ -34,6 +35,7 @@ class IHyperOpt(ABC):
     """
     ticker_interval: str  # DEPRECATED
     timeframe: str
+    strategy: IStrategy
 
     def __init__(self, config: dict) -> None:
         self.config = config


Test patch: