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
Image
Build an image with Freqtrade, your config, your strategy, and a wrapper script.
Parameters
HyperOptimizer appends values such as --hpo-timeframe=5m.
Backtest
The wrapper runs freqtrade backtesting once for that parameter set.
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)
One container execution equals one backtest. HyperOptimizer handles the outer optimization loop.
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)}")
Recommended search space
Start narrow, confirm the integration works, then widen the search.
- Name
timeframe- Type
- choice
- Description
Try common values like
1m,5m,15m, and1h.
- 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.