Optimize Freqtrade strategies

Use HyperOptimizer to run Freqtrade backtests as managed HPO trials. You keep your strategy code and Docker image; HyperOptimizer runs parameter combinations, collects metrics, and ranks results in the dashboard.

Why optimize Freqtrade with HyperOptimizer

Freqtrade strategies often depend on parameters such as timeframe, stoploss, ROI thresholds, indicator periods, trailing stop settings, and custom strategy variables. Searching those combinations by hand is slow, and long local hyperopt runs can tie up your machine.

HyperOptimizer turns each Freqtrade backtest into one containerized trial. That makes the experiment repeatable, parallelizable, and easy to compare.

Managed compute

Run many backtest trials without keeping a local hyperopt session alive.

Dashboard results

Compare Sharpe, drawdown, profit, trade count, and custom metrics in one place.

Bring your strategy

Keep using your Freqtrade strategy, config, and data workflow inside your image.

HyperOptimizer vs Freqtrade Hyperopt

Freqtrade has a built-in freqtrade hyperopt command. It is useful for local optimization, but it runs inside the Freqtrade workflow. HyperOptimizer is different: it treats Freqtrade as a workload that can be run repeatedly in managed infrastructure.

Freqtrade Hyperopt

  • Runs local optimization through Freqtrade.
  • Great when you want an integrated Freqtrade-native loop.
  • Compute, logs, and experiment history stay local unless you build more tooling.

HyperOptimizer

  • Runs each backtest as a managed container trial.
  • Works with any parameter you expose through CLI args.
  • Collects stdout metrics and shows ranked results in the dashboard.

Integration architecture

1

Image

Build an image with Freqtrade, your config, your strategy, and a wrapper script.

2

Parameters

HyperOptimizer appends values such as --hpo-timeframe=5m.

3

Backtest

The wrapper runs freqtrade backtesting once for that parameter set.

4

Metrics

The wrapper parses results and prints hpo.metrics.* lines.

1. Parse parameters

Use a wrapper script to parse the parameters you configure in the dashboard.

import argparse

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--hpo-timeframe", type=str, default="5m")
    parser.add_argument("--hpo-max-open-trades", type=int, default=3)
    parser.add_argument("--hpo-stoploss", type=float, default=-0.1)
    return parser.parse_args()

args = parse_args()

2. Run one backtest

Each trial should run one Freqtrade backtest. Do not run your own loop over many parameter sets inside the container.

import subprocess

cmd = [
    "freqtrade",
    "backtesting",
    "--strategy",
    "MyStrategy",
    "--config",
    "user_data/config.json",
    "--timeframe",
    args.hpo_timeframe,
    "--max-open-trades",
    str(args.hpo_max_open_trades),
    "--export",
    "trades",
]

result = subprocess.run(cmd, capture_output=True, text=True, check=True)

3. Emit Freqtrade metrics

Parse the backtest output or exported result and print metrics in HyperOptimizer format.

import json

metrics = {
    "total_profit_pct": 5.48,
    "absolute_profit": 54.774,
    "total_trades": 77,
    "sharpe": 3.75,
    "sortino": 2.48,
    "profit_factor": 1.29,
    "max_drawdown": 0.12,
}

for key, value in metrics.items():
    print(f"hpo.metrics.{key}={json.dumps(value, default=str)}")

Start narrow, confirm the integration works, then widen the search.

  • Name
    timeframe
    Type
    choice
    Description

    Try common values like 1m, 5m, 15m, and 1h.

  • Name
    max_open_trades
    Type
    integer
    Description

    Tune position concurrency for the strategy and exchange constraints.

  • Name
    stoploss
    Type
    float
    Description

    Search a bounded range and monitor drawdown as a guardrail.

  • Name
    strategy variables
    Type
    custom
    Description

    Expose indicator periods, thresholds, and risk multipliers through your wrapper.

Next, review the metric format or build the base Docker image.

Was this page helpful?