Freqtrade Beginner’s Guide: Backtest and Paper Trade Your First Crypto Bot
A step-by-step Freqtrade tutorial for beginners. Learn how to install, configure, write a Python strategy, backtest, and run your first crypto trading bot in dry-run mode.
If you have ever wondered whether you can automate your crypto trades without paying for an expensive subscription bot, Freqtrade is probably the first project you should try. It is free, open-source, actively maintained, and gives you full control over your strategies. You write the rules in Python, test them against years of historical data, and run them in paper-trading mode before risking a single dollar.
This guide is written for complete beginners. We will cover what Freqtrade is, how to install it, how to configure config.json, how to write a simple strategy, how to backtest, and how to run your first dry-run bot safely. We will also talk honestly about risks, because no bot is a money machine.
What Is Freqtrade?
Freqtrade is an open-source cryptocurrency trading bot framework written in Python. It connects to exchanges through the popular CCXT library, downloads market data, executes trades according to a strategy you define, and reports results through a built-in web interface or Telegram bot.
Unlike black-box SaaS bots, Freqtrade exposes every part of the logic to you. That means you can:
- Define exact entry and exit rules.
- Combine multiple technical indicators.
- Optimize hyperparameters with machine-learning-friendly tools.
- Run backtests across multiple years of data.
- Trade in dry-run mode to simulate real exchange behavior.
- Deploy the same bot on your laptop, a Raspberry Pi, or a cloud server.
The trade-off is that you need to be comfortable with a command line and basic Python. If that sounds intimidating, do not worry. By the end of this article you will have a working bot configuration that you can extend at your own pace.
Freqtrade Core Concepts
Before we install anything, it helps to understand the vocabulary Freqtrade uses.
| Term | Meaning |
|---|---|
| Strategy | A Python class that defines buy, sell, stop-loss, and risk-management rules. |
| Pair | A trading pair such as BTC/USDT or ETH/USDT. |
| Timeframe | The candle interval the strategy uses, for example 5m, 1h, or 1d. |
| Dry-run | Paper trading mode. Orders are simulated using live order-book data. |
| Backtest | A historical simulation that replays your strategy on past candles. |
| Edge | A module that estimates position size based on historical win rate and expectancy. |
| Hyperopt | Freqtrade's built-in tool for optimizing strategy parameters. |
| Pairlist | The list of pairs the bot is allowed to trade, generated by filters or static settings. |
Understanding these terms makes the rest of the guide much easier to follow.
Installation
Freqtrade runs on Linux, macOS, and Windows via Docker or WSL. The recommended path for beginners is Docker, because it avoids Python environment headaches. If you already have Python 3.10 or newer and feel comfortable with pip, the native installation works too.
Option A: Docker Installation
Make sure Docker and Docker Compose are installed. Then create a directory for your bot and run the official setup script.
mkdir ~/freqtrade-bot && cd ~/freqtrade-bot
curl https://raw.githubusercontent.com/freqtrade/freqtrade/stable/docker-compose.yml -o docker-compose.yml
docker compose pull
docker compose run --rm freqtrade create-userdir --userdir user_dataThe last command creates a user_data folder that holds your configuration, strategies, and historical data.
Option B: Native Installation
On Ubuntu or macOS with Homebrew Python, run:
git clone https://github.com/freqtrade/freqtrade.git
cd freqtrade
git checkout stable
./setup.sh -iThe setup script creates a virtual environment and installs all dependencies. Activate it with:
source .venv/bin/activateVerify the Installation
Once installed, check the version:
docker compose run --rm freqtrade --version
# or for native:
freqtrade --versionIf you see a version number, you are ready to configure the bot.
Docker is the easiest way to keep your environment consistent. If you plan to run the bot 24/7 on a server, Docker also simplifies restarts and logging.
config.json Setup
Freqtrade stores its main settings in config.json. You can generate a starter template with the following command.
docker compose run --rm freqtrade new-config --config user_data/config.jsonThe interactive wizard will ask you for an exchange, API keys, and a default strategy name. For this tutorial, choose Binance or Bybit and enable dry-run when asked.
Minimum Viable Configuration
Below is a simplified version of the settings a beginner should understand. You do not need to memorize every field; focus on the ones in this table.
| Setting | Typical Value | Why It Matters |
|---|---|---|
dry_run | true | Keeps the bot in paper-trading mode until you are confident. |
dry_run_wallet | 1000 | Simulated starting capital in USDT. |
stake_currency | "USDT" | The currency used to size positions. |
stake_amount | "unlimited" or a fixed number | How much capital to put into each trade. |
max_open_trades | 3 | Limits how many positions can be open at once. |
timeframe | "5m" | Default candle interval for strategies that do not override it. |
exchange.name | "binance" | Which exchange to connect to. |
exchange.key / secret | Your API credentials | Required for live trading; use read-only keys in dry-run. |
A minimal config.json looks like this:
{
"max_open_trades": 3,
"stake_currency": "USDT",
"stake_amount": "unlimited",
"dry_run": true,
"dry_run_wallet": 1000,
"timeframe": "5m",
"cancel_open_orders_on_exit": false,
"trading_mode": "spot",
"exchange": {
"name": "binance",
"key": "",
"secret": "",
"ccxt_config": {},
"ccxt_async_config": {},
"pair_whitelist": [
"BTC/USDT",
"ETH/USDT",
"SOL/USDT",
"ADA/USDT"
]
},
"pairlists": [
{ "method": "StaticPairList" }
],
"bot_name": "freqtrade-beginner",
"initial_state": "running",
"force_entry_enable": false,
"internals": {
"process_throttle_secs": 5
}
}API Key Safety
Even in dry-run mode, it is good practice to create an API key that cannot withdraw funds. On your exchange, disable withdrawal permission and restrict the key to the IP address where the bot runs. Store the key outside version control; never commit config.json with real credentials.
Treat your exchange API secret like a bank password. If it leaks, someone can trade or withdraw your funds. Use environment variables or a secrets manager when you move to live trading.
Writing Your First Python Strategy
Strategies live in user_data/strategies/. Each strategy is a Python class that inherits from IStrategy and implements a few key methods. The bot calls the strategy every candle to decide whether to enter, exit, or adjust a position.
Create the Strategy File
Create user_data/strategies/FirstStrategy.py and add the following starter code.
from freqtrade.strategy import IStrategy
from pandas import DataFrame
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
class FirstStrategy(IStrategy):
INTERFACE_VERSION = 3
timeframe = "5m"
stoploss = -0.10
trailing_stop = True
trailing_stop_positive = 0.05
trailing_only_offset_is_reached = False
minimal_roi = {
"0": 0.15,
"120": 0.05,
"240": 0.025,
"360": 0
}
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe["ema9"] = ta.EMA(dataframe, timeperiod=9)
dataframe["ema21"] = ta.EMA(dataframe, timeperiod=21)
dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
dataframe["volume_mean"] = dataframe["volume"].rolling(window=20).mean()
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(dataframe["ema9"] > dataframe["ema21"]) &
(dataframe["ema9"].shift(1) <= dataframe["ema21"].shift(1)) &
(dataframe["rsi"] > 50) &
(dataframe["rsi"] < 70) &
(dataframe["volume"] > dataframe["volume_mean"])
),
"enter_long"
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(dataframe["ema9"] < dataframe["ema21"]) &
(dataframe["ema9"].shift(1) >= dataframe["ema21"].shift(1))
),
"exit_long"
] = 1
return dataframeHow the Strategy Works
This strategy uses two exponential moving averages and the RSI to find long entries in an uptrend.
| Component | Purpose |
|---|---|
ema9 / ema21 | Identify short-term versus medium-term trend direction. |
rsi | Filter out overbought conditions. |
volume_mean | Confirm that the breakout happens on above-average volume. |
stoploss | Cut any trade that falls 10% against you. |
trailing_stop | Lock in profits once a 5% trailing gain is reached. |
minimal_roi | Take profits at fixed targets after specific holding periods. |
The entry rule fires when the faster EMA crosses above the slower EMA, RSI is between 50 and 70, and volume is above its 20-candle average. The exit rule fires on the opposite crossover.
This is not a holy grail. It is a teaching example. Real strategies usually require more filters, market-regime detection, and robust risk management.
Strategy File Checklist
Before backtesting, make sure your strategy file satisfies these requirements.
| Check | Why It Matters |
|---|---|
Class inherits from IStrategy | Required base class with hooks the bot expects. |
INTERFACE_VERSION = 3 | Matches the current Freqtrade API. |
Defines timeframe | Tells the bot which candles to download. |
Defines stoploss | Mandatory risk-management field. |
Sets populate_indicators | Prepares columns used by entry and exit logic. |
Sets populate_entry_trend | Creates the enter_long signal column. |
Sets populate_exit_trend | Creates the exit_long signal column. |
If any of these are missing, Freqtrade will refuse to load the strategy and print a helpful error message.
Downloading Historical Data
Backtests need historical candles. Freqtrade includes a data-download command that fetches data from your exchange.
docker compose run --rm freqtrade download-data \
--config user_data/config.json \
--timeframes 5m 1h \
--days 365 \
--pairs BTC/USDT ETH/USDT SOL/USDT ADA/USDTFor a longer backtest, increase --days or use --timerange. The first download can take a few minutes. Data is stored in user_data/data/<exchange>/.
Download data before every serious backtest so your simulation uses realistic spreads, gaps, and delistings. Stale data leads to over-optimistic results.
Backtesting Your Strategy
Backtesting is where most beginners fall in love with trading automation. It shows how the strategy would have performed in the past. Remember: past performance is not a promise of future results.
Run a backtest with this command:
docker compose run --rm freqtrade backtesting \
--config user_data/config.json \
--strategy FirstStrategy \
--timeframe 5m \
--timerange 20250101-20260701After the run finishes, Freqtrade prints a summary table. Pay attention to these metrics.
| Metric | What It Tells You |
|---|---|
| Total profit % | Overall return across the backtest period. |
| Profit factor | Gross profit divided by gross loss. Above 1.0 means the strategy made more than it lost. |
| Max drawdown | Largest peak-to-trough drop in equity. Smaller is better for sleep quality. |
| Win rate | Percentage of trades that closed profitably. |
| Avg profit % | Average profit per trade after fees. |
| Sharpe ratio | Risk-adjusted return; higher is better. |
| Trade count | More trades give more statistical confidence, but too many can mean overfitting. |
Reading the Results
Suppose your backtest shows a 42% total return, a profit factor of 1.3, and a max drawdown of 18%. That looks decent on the surface, but ask yourself:
- Did the strategy rely on one or two huge winners?
- Does performance hold in bear markets, or only in strong uptrends?
- Are fees and slippage realistic for your account size?
- Did you optimize the parameters on the same data you tested them on?
A strategy that looks perfect on the training data and fails on new data is called overfitted. The easiest way to reduce overfitting is to keep the number of parameters low and validate results on data the strategy has never seen.
Never skip forward testing. A beautiful backtest can evaporate the moment real money is on the line.
Walk-Forward Testing
A simple way to validate a strategy is walk-forward analysis. Split history into multiple periods, optimize on one period, and test on the next. If the strategy remains profitable across several unseen periods, it is more likely to be robust.
| Period | Purpose |
|---|---|
| In-sample data | Optimize parameters and discover rules. |
| Out-of-sample data | Validate that rules work on unseen history. |
| Dry-run forward test | Validate behavior with live market microstructure. |
Only after all three stages look reasonable should you consider small live trading.
Running the Bot in Dry-Run Mode
Dry-run is Freqtrade's paper-trading mode. It simulates order execution against live order books, so you can see how the bot behaves in real market conditions without risking capital.
Start the bot with:
docker compose run --rm freqtrade trade \
--config user_data/config.json \
--strategy FirstStrategyIf your config has "dry_run": true, the bot will log that it is running in dry-run mode and will not place real orders. It will still fetch live prices, open simulated positions, and report simulated profits.
Monitoring the Bot
Freqtrade exposes a web interface on port 8080 by default. Add this to config.json to enable it:
"api_server": {
"enabled": true,
"listen_ip_address": "0.0.0.0",
"listen_port": 8080,
"username": "admin",
"password": "change-me-please"
}Open http://localhost:8080 in your browser. You will see open trades, daily profit, total profit, and a trade history table. You can also force actions, pause the bot, and view logs.
Dry-Run Best Practices
Run dry-run for at least a few weeks before considering live trading. During that time, watch for:
- Unexpected entries during high-volatility events.
- Stop-losses that hit more often than the backtest suggested.
- API errors or exchange rate limits.
- Gaps between simulated fills and what you see on the exchange chart.
Keep a trading journal of bot behavior. Notes like "bot entered three times during a flash crash" help you improve filters later.
Risks and Realistic Expectations
Crypto trading bots can lose money. Automation does not remove risk; it often amplifies it by executing faster than a human can react.
Every beginner should understand the most common failure modes.
| Risk | Description | Mitigation |
|---|---|---|
| Overfitting | Strategy looks great on historical data but fails live. | Use out-of-sample tests, fewer parameters, and longer dry-runs. |
| Market regime change | A trend-following bot suffers in choppy markets. | Add market filters or reduce position size in uncertain conditions. |
| Exchange risk | Delays, downtime, or delistings can trap positions. | Choose reputable exchanges and monitor API health. |
| API key theft | Leaked keys can lead to unauthorized trades or withdrawals. | Use IP whitelisting, withdrawal restrictions, and secrets management. |
| Slippage and fees | Real fills may be worse than backtest assumptions. | Model fees accurately and account for spread in low-cap pairs. |
| Behavioral risk | Disabling stop-losses or increasing size after losses. | Write rules in code and avoid manual overrides during drawdowns. |
A useful mindset is to treat a bot like a dishwasher, not a slot machine. It automates a process you already understand. If your manual strategy is unprofitable, automation will simply lose money faster.
Where to Go Next
Once you have completed your first backtest and dry-run, you can deepen your Freqtrade skills in several directions.
- Hyperopt: Use Freqtrade's built-in optimizer to search for better parameter values, but be careful of overfitting.
- Pairlist filters: Replace a static whitelist with volume, volatility, or performance filters so the bot adapts to market conditions.
- Protections: Add cooldowns, stop-loss guards, and maximum drawdown protections to limit damage during bad periods.
- Custom indicators: Combine TA-Lib indicators with custom pandas logic.
- Telegram alerts: Configure the Telegram bot so you receive notifications for entries, exits, and errors.
Each of these topics could be its own article. Master them one at a time instead of trying to build the perfect bot on day one.
FAQ
Below are answers to the most common questions beginners ask about Freqtrade.
What is Freqtrade and who is it for?
Freqtrade is an open-source crypto trading bot written in Python. It is aimed at traders who want to automate strategies, run backtests, and paper trade on exchanges without writing exchange-specific plumbing code.
Do I need to know Python to use Freqtrade?
Basic Python helps because strategies are written in Python. However, you can start with the built-in sample strategies and modify them gradually while learning.
Is Freqtrade free to use?
Yes, Freqtrade itself is free and open-source under the MIT license. You only pay your exchange trading fees and any optional cloud hosting costs.
Can Freqtrade trade with real money?
Yes, but beginners should always start in dry-run (paper trading) mode. Real trading requires exchange API keys and carries risk of loss.
What exchanges does Freqtrade support?
Freqtrade supports many major exchanges including Binance, Bybit, OKX, Kraken, KuCoin, and Gate.io via the CCXT library. Always check the latest supported list in the official documentation.
How do I know if my strategy is profitable?
Run backtests on historical data and then forward-test in dry-run mode for several weeks. Never assume a backtest guarantees future profits.
What are the main risks of running a crypto trading bot?
Risks include market drawdowns, overfitted strategies, exchange downtime, API key theft, slippage, and behavioral mistakes such as disabling safeguards during a losing streak.
Bottom Line
Freqtrade is one of the best free tools available for learning algorithmic crypto trading. It forces you to think in terms of rules, risk, and evidence rather than hunches. Start with dry-run, keep your first strategy simple, and treat every backtest as a hypothesis that needs forward validation. Building a reliable trading bot takes time, but the skills you learn along the way will outlast any single strategy.
Ready to go deeper? Download Freqtrade, copy the strategy in this guide, and run your first backtest today.