Deployed 7e7e475 to develop in en with MkDocs 1.6.1 and mike 2.1.4
This commit is contained in:
@@ -1611,6 +1611,17 @@
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#space-options" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Space options
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
@@ -1918,6 +1929,17 @@
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#space-options" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
Space options
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
@@ -1953,51 +1975,53 @@ class.</p>
|
||||
<p>To use a custom loss function class, make sure that the function <code>hyperopt_loss_function</code> is defined in your custom hyperopt loss class.
|
||||
For the sample below, you then need to add the command line parameter <code>--hyperopt-loss SuperDuperHyperOptLoss</code> to your hyperopt call so this function is being used.</p>
|
||||
<p>A sample of this can be found below, which is identical to the Default Hyperopt loss implementation. A full sample can be found in <a href="https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/templates/sample_hyperopt_loss.py">userdata/hyperopts</a>.</p>
|
||||
<p>``` python
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict</p>
|
||||
<p>from pandas import DataFrame</p>
|
||||
<p>from freqtrade.constants import Config
|
||||
from freqtrade.optimize.hyperopt import IHyperOptLoss</p>
|
||||
<p>TARGET_TRADES = 600
|
||||
EXPECTED_MAX_PROFIT = 3.0
|
||||
MAX_ACCEPTED_TRADE_DURATION = 300</p>
|
||||
<p>class SuperDuperHyperOptLoss(IHyperOptLoss):
|
||||
"""
|
||||
Defines the default loss function for hyperopt
|
||||
"""</p>
|
||||
<div class="codehilite"><pre><span></span><code>@staticmethod
|
||||
def hyperopt_loss_function(
|
||||
*,
|
||||
results: DataFrame,
|
||||
trade_count: int,
|
||||
min_date: datetime,
|
||||
max_date: datetime,
|
||||
config: Config,
|
||||
processed: dict[str, DataFrame],
|
||||
backtest_stats: dict[str, Any],
|
||||
starting_balance: float,
|
||||
**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_ratio'].sum()
|
||||
trade_duration = results['trade_duration'].mean()
|
||||
<div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">datetime</span><span class="w"> </span><span class="kn">import</span> <span class="n">datetime</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Dict</span>
|
||||
|
||||
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
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">pandas</span><span class="w"> </span><span class="kn">import</span> <span class="n">DataFrame</span>
|
||||
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">freqtrade.constants</span><span class="w"> </span><span class="kn">import</span> <span class="n">Config</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">freqtrade.optimize.hyperopt</span><span class="w"> </span><span class="kn">import</span> <span class="n">IHyperOptLoss</span>
|
||||
|
||||
<span class="n">TARGET_TRADES</span> <span class="o">=</span> <span class="mi">600</span>
|
||||
<span class="n">EXPECTED_MAX_PROFIT</span> <span class="o">=</span> <span class="mf">3.0</span>
|
||||
<span class="n">MAX_ACCEPTED_TRADE_DURATION</span> <span class="o">=</span> <span class="mi">300</span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">SuperDuperHyperOptLoss</span><span class="p">(</span><span class="n">IHyperOptLoss</span><span class="p">):</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> Defines the default loss function for hyperopt</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="nd">@staticmethod</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">hyperopt_loss_function</span><span class="p">(</span>
|
||||
<span class="o">*</span><span class="p">,</span>
|
||||
<span class="n">results</span><span class="p">:</span> <span class="n">DataFrame</span><span class="p">,</span>
|
||||
<span class="n">trade_count</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
|
||||
<span class="n">min_date</span><span class="p">:</span> <span class="n">datetime</span><span class="p">,</span>
|
||||
<span class="n">max_date</span><span class="p">:</span> <span class="n">datetime</span><span class="p">,</span>
|
||||
<span class="n">config</span><span class="p">:</span> <span class="n">Config</span><span class="p">,</span>
|
||||
<span class="n">processed</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">DataFrame</span><span class="p">],</span>
|
||||
<span class="n">backtest_stats</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">],</span>
|
||||
<span class="n">starting_balance</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span>
|
||||
<span class="o">**</span><span class="n">kwargs</span><span class="p">,</span>
|
||||
<span class="p">)</span> <span class="o">-></span> <span class="nb">float</span><span class="p">:</span>
|
||||
<span class="w"> </span><span class="sd">"""</span>
|
||||
<span class="sd"> Objective function, returns smaller number for better results</span>
|
||||
<span class="sd"> This is the legacy algorithm (used until now in freqtrade).</span>
|
||||
<span class="sd"> Weights are distributed as follows:</span>
|
||||
<span class="sd"> * 0.4 to trade duration</span>
|
||||
<span class="sd"> * 0.25: Avoiding trade loss</span>
|
||||
<span class="sd"> * 1.0 to total profit, compared to the expected value (`EXPECTED_MAX_PROFIT`) defined above</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">total_profit</span> <span class="o">=</span> <span class="n">results</span><span class="p">[</span><span class="s1">'profit_ratio'</span><span class="p">]</span><span class="o">.</span><span class="n">sum</span><span class="p">()</span>
|
||||
<span class="n">trade_duration</span> <span class="o">=</span> <span class="n">results</span><span class="p">[</span><span class="s1">'trade_duration'</span><span class="p">]</span><span class="o">.</span><span class="n">mean</span><span class="p">()</span>
|
||||
|
||||
<span class="n">trade_loss</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">-</span> <span class="mf">0.25</span> <span class="o">*</span> <span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="p">(</span><span class="n">trade_count</span> <span class="o">-</span> <span class="n">TARGET_TRADES</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span> <span class="o">/</span> <span class="mi">10</span> <span class="o">**</span> <span class="mf">5.8</span><span class="p">)</span>
|
||||
<span class="n">profit_loss</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">total_profit</span> <span class="o">/</span> <span class="n">EXPECTED_MAX_PROFIT</span><span class="p">)</span>
|
||||
<span class="n">duration_loss</span> <span class="o">=</span> <span class="mf">0.4</span> <span class="o">*</span> <span class="nb">min</span><span class="p">(</span><span class="n">trade_duration</span> <span class="o">/</span> <span class="n">MAX_ACCEPTED_TRADE_DURATION</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="n">trade_loss</span> <span class="o">+</span> <span class="n">profit_loss</span> <span class="o">+</span> <span class="n">duration_loss</span>
|
||||
<span class="k">return</span> <span class="n">result</span>
|
||||
</code></pre></div>
|
||||
|
||||
<p>```</p>
|
||||
<p>Currently, the arguments are:</p>
|
||||
<ul>
|
||||
<li><code>results</code>: DataFrame containing the resulting trades.
|
||||
@@ -2022,86 +2046,82 @@ def hyperopt_loss_function(
|
||||
</div>
|
||||
<h2 id="overriding-pre-defined-spaces">Overriding pre-defined spaces<a class="headerlink" href="#overriding-pre-defined-spaces" title="Permanent link">¶</a></h2>
|
||||
<p>To override a pre-defined space (<code>roi_space</code>, <code>generate_roi_table</code>, <code>stoploss_space</code>, <code>trailing_space</code>, <code>max_open_trades_space</code>), define a nested class called Hyperopt and define the required spaces as follows:</p>
|
||||
<p>```python
|
||||
from freqtrade.optimize.space import Categorical, Dimension, Integer, SKDecimal</p>
|
||||
<p>class MyAwesomeStrategy(IStrategy):
|
||||
class HyperOpt:
|
||||
# Define a custom stoploss space.
|
||||
def stoploss_space():
|
||||
return [SKDecimal(-0.05, -0.01, decimals=3, name='stoploss')]</p>
|
||||
<div class="codehilite"><pre><span></span><code> # Define custom ROI space
|
||||
def roi_space() -> List[Dimension]:
|
||||
return [
|
||||
Integer(10, 120, name='roi_t1'),
|
||||
Integer(10, 60, name='roi_t2'),
|
||||
Integer(10, 40, name='roi_t3'),
|
||||
SKDecimal(0.01, 0.04, decimals=3, name='roi_p1'),
|
||||
SKDecimal(0.01, 0.07, decimals=3, name='roi_p2'),
|
||||
SKDecimal(0.01, 0.20, decimals=3, name='roi_p3'),
|
||||
]
|
||||
<div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">freqtrade.optimize.space</span><span class="w"> </span><span class="kn">import</span> <span class="n">Categorical</span><span class="p">,</span> <span class="n">Dimension</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">SKDecimal</span>
|
||||
|
||||
def generate_roi_table(params: Dict) -> dict[int, float]:
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">MyAwesomeStrategy</span><span class="p">(</span><span class="n">IStrategy</span><span class="p">):</span>
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">HyperOpt</span><span class="p">:</span>
|
||||
<span class="c1"># Define a custom stoploss space.</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">stoploss_space</span><span class="p">():</span>
|
||||
<span class="k">return</span> <span class="p">[</span><span class="n">SKDecimal</span><span class="p">(</span><span class="o">-</span><span class="mf">0.05</span><span class="p">,</span> <span class="o">-</span><span class="mf">0.01</span><span class="p">,</span> <span class="n">decimals</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'stoploss'</span><span class="p">)]</span>
|
||||
|
||||
roi_table = {}
|
||||
roi_table[0] = params['roi_p1'] + params['roi_p2'] + params['roi_p3']
|
||||
roi_table[params['roi_t3']] = params['roi_p1'] + params['roi_p2']
|
||||
roi_table[params['roi_t3'] + params['roi_t2']] = params['roi_p1']
|
||||
roi_table[params['roi_t3'] + params['roi_t2'] + params['roi_t1']] = 0
|
||||
<span class="c1"># Define custom ROI space</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">roi_space</span><span class="p">()</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Dimension</span><span class="p">]:</span>
|
||||
<span class="k">return</span> <span class="p">[</span>
|
||||
<span class="n">Integer</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">120</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'roi_t1'</span><span class="p">),</span>
|
||||
<span class="n">Integer</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">60</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'roi_t2'</span><span class="p">),</span>
|
||||
<span class="n">Integer</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'roi_t3'</span><span class="p">),</span>
|
||||
<span class="n">SKDecimal</span><span class="p">(</span><span class="mf">0.01</span><span class="p">,</span> <span class="mf">0.04</span><span class="p">,</span> <span class="n">decimals</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'roi_p1'</span><span class="p">),</span>
|
||||
<span class="n">SKDecimal</span><span class="p">(</span><span class="mf">0.01</span><span class="p">,</span> <span class="mf">0.07</span><span class="p">,</span> <span class="n">decimals</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'roi_p2'</span><span class="p">),</span>
|
||||
<span class="n">SKDecimal</span><span class="p">(</span><span class="mf">0.01</span><span class="p">,</span> <span class="mf">0.20</span><span class="p">,</span> <span class="n">decimals</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'roi_p3'</span><span class="p">),</span>
|
||||
<span class="p">]</span>
|
||||
|
||||
return roi_table
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">generate_roi_table</span><span class="p">(</span><span class="n">params</span><span class="p">:</span> <span class="n">Dict</span><span class="p">)</span> <span class="o">-></span> <span class="nb">dict</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">]:</span>
|
||||
|
||||
def trailing_space() -> List[Dimension]:
|
||||
# All parameters here are mandatory, you can only modify their type or the range.
|
||||
return [
|
||||
# Fixed to true, if optimizing trailing_stop we assume to use trailing stop at all times.
|
||||
Categorical([True], name='trailing_stop'),
|
||||
<span class="n">roi_table</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="n">roi_table</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">params</span><span class="p">[</span><span class="s1">'roi_p1'</span><span class="p">]</span> <span class="o">+</span> <span class="n">params</span><span class="p">[</span><span class="s1">'roi_p2'</span><span class="p">]</span> <span class="o">+</span> <span class="n">params</span><span class="p">[</span><span class="s1">'roi_p3'</span><span class="p">]</span>
|
||||
<span class="n">roi_table</span><span class="p">[</span><span class="n">params</span><span class="p">[</span><span class="s1">'roi_t3'</span><span class="p">]]</span> <span class="o">=</span> <span class="n">params</span><span class="p">[</span><span class="s1">'roi_p1'</span><span class="p">]</span> <span class="o">+</span> <span class="n">params</span><span class="p">[</span><span class="s1">'roi_p2'</span><span class="p">]</span>
|
||||
<span class="n">roi_table</span><span class="p">[</span><span class="n">params</span><span class="p">[</span><span class="s1">'roi_t3'</span><span class="p">]</span> <span class="o">+</span> <span class="n">params</span><span class="p">[</span><span class="s1">'roi_t2'</span><span class="p">]]</span> <span class="o">=</span> <span class="n">params</span><span class="p">[</span><span class="s1">'roi_p1'</span><span class="p">]</span>
|
||||
<span class="n">roi_table</span><span class="p">[</span><span class="n">params</span><span class="p">[</span><span class="s1">'roi_t3'</span><span class="p">]</span> <span class="o">+</span> <span class="n">params</span><span class="p">[</span><span class="s1">'roi_t2'</span><span class="p">]</span> <span class="o">+</span> <span class="n">params</span><span class="p">[</span><span class="s1">'roi_t1'</span><span class="p">]]</span> <span class="o">=</span> <span class="mi">0</span>
|
||||
|
||||
SKDecimal(0.01, 0.35, decimals=3, name='trailing_stop_positive'),
|
||||
# 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive',
|
||||
# so this intermediate parameter is used as the value of the difference between
|
||||
# them. The value of the 'trailing_stop_positive_offset' is constructed in the
|
||||
# generate_trailing_params() method.
|
||||
# This is similar to the hyperspace dimensions used for constructing the ROI tables.
|
||||
SKDecimal(0.001, 0.1, decimals=3, name='trailing_stop_positive_offset_p1'),
|
||||
<span class="k">return</span> <span class="n">roi_table</span>
|
||||
|
||||
Categorical([True, False], name='trailing_only_offset_is_reached'),
|
||||
]
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">trailing_space</span><span class="p">()</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Dimension</span><span class="p">]:</span>
|
||||
<span class="c1"># All parameters here are mandatory, you can only modify their type or the range.</span>
|
||||
<span class="k">return</span> <span class="p">[</span>
|
||||
<span class="c1"># Fixed to true, if optimizing trailing_stop we assume to use trailing stop at all times.</span>
|
||||
<span class="n">Categorical</span><span class="p">([</span><span class="kc">True</span><span class="p">],</span> <span class="n">name</span><span class="o">=</span><span class="s1">'trailing_stop'</span><span class="p">),</span>
|
||||
|
||||
# Define a custom max_open_trades space
|
||||
def max_open_trades_space() -> List[Dimension]:
|
||||
return [
|
||||
Integer(-1, 10, name='max_open_trades'),
|
||||
]
|
||||
<span class="n">SKDecimal</span><span class="p">(</span><span class="mf">0.01</span><span class="p">,</span> <span class="mf">0.35</span><span class="p">,</span> <span class="n">decimals</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'trailing_stop_positive'</span><span class="p">),</span>
|
||||
<span class="c1"># 'trailing_stop_positive_offset' should be greater than 'trailing_stop_positive',</span>
|
||||
<span class="c1"># so this intermediate parameter is used as the value of the difference between</span>
|
||||
<span class="c1"># them. The value of the 'trailing_stop_positive_offset' is constructed in the</span>
|
||||
<span class="c1"># generate_trailing_params() method.</span>
|
||||
<span class="c1"># This is similar to the hyperspace dimensions used for constructing the ROI tables.</span>
|
||||
<span class="n">SKDecimal</span><span class="p">(</span><span class="mf">0.001</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">,</span> <span class="n">decimals</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'trailing_stop_positive_offset_p1'</span><span class="p">),</span>
|
||||
|
||||
<span class="n">Categorical</span><span class="p">([</span><span class="kc">True</span><span class="p">,</span> <span class="kc">False</span><span class="p">],</span> <span class="n">name</span><span class="o">=</span><span class="s1">'trailing_only_offset_is_reached'</span><span class="p">),</span>
|
||||
<span class="p">]</span>
|
||||
|
||||
<span class="c1"># Define a custom max_open_trades space</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">max_open_trades_space</span><span class="p">()</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Dimension</span><span class="p">]:</span>
|
||||
<span class="k">return</span> <span class="p">[</span>
|
||||
<span class="n">Integer</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'max_open_trades'</span><span class="p">),</span>
|
||||
<span class="p">]</span>
|
||||
</code></pre></div>
|
||||
|
||||
<p>```</p>
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">Note</p>
|
||||
<p>All overrides are optional and can be mixed/matched as necessary.</p>
|
||||
</div>
|
||||
<h2 id="dynamic-parameters">Dynamic parameters<a class="headerlink" href="#dynamic-parameters" title="Permanent link">¶</a></h2>
|
||||
<p>Parameters can also be defined dynamically, but must be available to the instance once the <a href="../strategy-callbacks/#bot-start"><code>bot_start()</code> callback</a> has been called.</p>
|
||||
<p>``` python</p>
|
||||
<p>class MyAwesomeStrategy(IStrategy):</p>
|
||||
<div class="codehilite"><pre><span></span><code>def bot_start(self, **kwargs) -> None:
|
||||
self.buy_adx = IntParameter(20, 30, default=30, optimize=True)
|
||||
<div class="highlight"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="nc">MyAwesomeStrategy</span><span class="p">(</span><span class="n">IStrategy</span><span class="p">):</span>
|
||||
|
||||
# ...
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">bot_start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">buy_adx</span> <span class="o">=</span> <span class="n">IntParameter</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="mi">30</span><span class="p">,</span> <span class="n">optimize</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># ...</span>
|
||||
</code></pre></div>
|
||||
|
||||
<p>```</p>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">Warning</p>
|
||||
<p>Parameters created this way will not show up in the <code>list-strategies</code> parameter count.</p>
|
||||
</div>
|
||||
<h2 id="overriding-base-estimator">Overriding Base estimator<a class="headerlink" href="#overriding-base-estimator" title="Permanent link">¶</a></h2>
|
||||
<p>You can define your own optuna sampler for Hyperopt by implementing <code>generate_estimator()</code> in the Hyperopt subclass.</p>
|
||||
<p>```python
|
||||
class MyAwesomeStrategy(IStrategy):
|
||||
class HyperOpt:
|
||||
def generate_estimator(dimensions: List['Dimension'], **kwargs):
|
||||
return "NSGAIIISampler"</p>
|
||||
<p>```</p>
|
||||
<div class="highlight"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="nc">MyAwesomeStrategy</span><span class="p">(</span><span class="n">IStrategy</span><span class="p">):</span>
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">HyperOpt</span><span class="p">:</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">generate_estimator</span><span class="p">(</span><span class="n">dimensions</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="s1">'Dimension'</span><span class="p">],</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="s2">"NSGAIIISampler"</span>
|
||||
</code></pre></div>
|
||||
<p>Possible values are either one of "NSGAIISampler", "TPESampler", "GPSampler", "CmaEsSampler", "NSGAIIISampler", "QMCSampler" (Details can be found in the <a href="https://optuna.readthedocs.io/en/stable/reference/samplers/index.html">optuna-samplers documentation</a>), or "an instance of a class that inherits from <code>optuna.samplers.BaseSampler</code>".</p>
|
||||
<p>Some research will be necessary to find additional Samplers (from optunahub) for example.</p>
|
||||
<div class="admonition note">
|
||||
@@ -2113,23 +2133,23 @@ If you're unsure about this, best use one of the Defaults (<code>"NSGAIIISampler
|
||||
<summary>Using <code>AutoSampler</code> from Optunahub</summary>
|
||||
<p><a href="https://hub.optuna.org/samplers/auto_sampler/">AutoSampler docs</a></p>
|
||||
<p>Install the necessary dependencies
|
||||
<code>bash
|
||||
pip install optunahub cmaes torch scipy</code>
|
||||
<div class="highlight"><pre><span></span><code>pip<span class="w"> </span>install<span class="w"> </span>optunahub<span class="w"> </span>cmaes<span class="w"> </span>torch<span class="w"> </span>scipy
|
||||
</code></pre></div>
|
||||
Implement <code>generate_estimator()</code> in your strategy</p>
|
||||
<p>``` python</p>
|
||||
<h1 id="_1">...<a class="headerlink" href="#_1" title="Permanent link">¶</a></h1>
|
||||
<p>from freqtrade.strategy.interface import IStrategy
|
||||
from typing import List
|
||||
import optunahub</p>
|
||||
<h1 id="_2">...<a class="headerlink" href="#_2" title="Permanent link">¶</a></h1>
|
||||
<p>class my_strategy(IStrategy):
|
||||
class HyperOpt:
|
||||
def generate_estimator(dimensions: List["Dimension"], **kwargs):
|
||||
if "random_state" in kwargs.keys():
|
||||
return optunahub.load_module("samplers/auto_sampler").AutoSampler(seed=kwargs["random_state"])
|
||||
else:
|
||||
return optunahub.load_module("samplers/auto_sampler").AutoSampler()</p>
|
||||
<p>```</p>
|
||||
<div class="highlight"><pre><span></span><code><span class="c1"># ...</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">freqtrade.strategy.interface</span><span class="w"> </span><span class="kn">import</span> <span class="n">IStrategy</span>
|
||||
<span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">List</span>
|
||||
<span class="kn">import</span><span class="w"> </span><span class="nn">optunahub</span>
|
||||
<span class="c1"># ... </span>
|
||||
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">my_strategy</span><span class="p">(</span><span class="n">IStrategy</span><span class="p">):</span>
|
||||
<span class="k">class</span><span class="w"> </span><span class="nc">HyperOpt</span><span class="p">:</span>
|
||||
<span class="k">def</span><span class="w"> </span><span class="nf">generate_estimator</span><span class="p">(</span><span class="n">dimensions</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="s2">"Dimension"</span><span class="p">],</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="s2">"random_state"</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
|
||||
<span class="k">return</span> <span class="n">optunahub</span><span class="o">.</span><span class="n">load_module</span><span class="p">(</span><span class="s2">"samplers/auto_sampler"</span><span class="p">)</span><span class="o">.</span><span class="n">AutoSampler</span><span class="p">(</span><span class="n">seed</span><span class="o">=</span><span class="n">kwargs</span><span class="p">[</span><span class="s2">"random_state"</span><span class="p">])</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">optunahub</span><span class="o">.</span><span class="n">load_module</span><span class="p">(</span><span class="s2">"samplers/auto_sampler"</span><span class="p">)</span><span class="o">.</span><span class="n">AutoSampler</span><span class="p">()</span>
|
||||
</code></pre></div>
|
||||
<p>Obviously the same approach will work for all other Samplers optuna supports.</p>
|
||||
</details>
|
||||
<h2 id="space-options">Space options<a class="headerlink" href="#space-options" title="Permanent link">¶</a></h2>
|
||||
@@ -2141,8 +2161,8 @@ import optunahub</p>
|
||||
<li><code>Real</code> - Pick from a range of decimal numbers with full precision (e.g. <code>Real(0.1, 0.5, name='adx')</code></li>
|
||||
</ul>
|
||||
<p>You can import all of these from <code>freqtrade.optimize.space</code>, although <code>Categorical</code>, <code>Integer</code> and <code>Real</code> are only aliases for their corresponding scikit-optimize Spaces. <code>SKDecimal</code> is provided by freqtrade for faster optimizations.</p>
|
||||
<p><code>python
|
||||
from freqtrade.optimize.space import Categorical, Dimension, Integer, SKDecimal, Real # noqa</code></p>
|
||||
<div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">freqtrade.optimize.space</span><span class="w"> </span><span class="kn">import</span> <span class="n">Categorical</span><span class="p">,</span> <span class="n">Dimension</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">SKDecimal</span><span class="p">,</span> <span class="n">Real</span> <span class="c1"># noqa</span>
|
||||
</code></pre></div>
|
||||
<div class="admonition hint">
|
||||
<p class="admonition-title">SKDecimal vs. Real</p>
|
||||
<p>We recommend to use <code>SKDecimal</code> instead of the <code>Real</code> space in almost all cases. While the Real space provides full accuracy (up to ~16 decimal places) - this precision is rarely needed, and leads to unnecessary long hyperopt times.</p>
|
||||
|
||||
Reference in New Issue
Block a user