VVibeTrading
Back to Blog
Also available in中文
TutorialsJuly 13, 202618 min read

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.

#freqtrade#crypto#bot#tutorial
Risk Disclaimer: This content is for educational purposes only. Trading involves significant risk of loss. Past performance does not guarantee future results. Always do your own research before using any trading tool or strategy.

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.

TermMeaning
StrategyA Python class that defines buy, sell, stop-loss, and risk-management rules.
PairA trading pair such as BTC/USDT or ETH/USDT.
TimeframeThe candle interval the strategy uses, for example 5m, 1h, or 1d.
Dry-runPaper trading mode. Orders are simulated using live order-book data.
BacktestA historical simulation that replays your strategy on past candles.
EdgeA module that estimates position size based on historical win rate and expectancy.
HyperoptFreqtrade's built-in tool for optimizing strategy parameters.
PairlistThe 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_data

The 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 -i

The setup script creates a virtual environment and installs all dependencies. Activate it with:

source .venv/bin/activate

Verify the Installation

Once installed, check the version:

docker compose run --rm freqtrade --version
# or for native:
freqtrade --version

If 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.json

The 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.

SettingTypical ValueWhy It Matters
dry_runtrueKeeps the bot in paper-trading mode until you are confident.
dry_run_wallet1000Simulated starting capital in USDT.
stake_currency"USDT"The currency used to size positions.
stake_amount"unlimited" or a fixed numberHow much capital to put into each trade.
max_open_trades3Limits 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 / secretYour API credentialsRequired 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 dataframe

How the Strategy Works

This strategy uses two exponential moving averages and the RSI to find long entries in an uptrend.

ComponentPurpose
ema9 / ema21Identify short-term versus medium-term trend direction.
rsiFilter out overbought conditions.
volume_meanConfirm that the breakout happens on above-average volume.
stoplossCut any trade that falls 10% against you.
trailing_stopLock in profits once a 5% trailing gain is reached.
minimal_roiTake 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.

CheckWhy It Matters
Class inherits from IStrategyRequired base class with hooks the bot expects.
INTERFACE_VERSION = 3Matches the current Freqtrade API.
Defines timeframeTells the bot which candles to download.
Defines stoplossMandatory risk-management field.
Sets populate_indicatorsPrepares columns used by entry and exit logic.
Sets populate_entry_trendCreates the enter_long signal column.
Sets populate_exit_trendCreates 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/USDT

For 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-20260701

After the run finishes, Freqtrade prints a summary table. Pay attention to these metrics.

MetricWhat It Tells You
Total profit %Overall return across the backtest period.
Profit factorGross profit divided by gross loss. Above 1.0 means the strategy made more than it lost.
Max drawdownLargest peak-to-trough drop in equity. Smaller is better for sleep quality.
Win ratePercentage of trades that closed profitably.
Avg profit %Average profit per trade after fees.
Sharpe ratioRisk-adjusted return; higher is better.
Trade countMore 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.

PeriodPurpose
In-sample dataOptimize parameters and discover rules.
Out-of-sample dataValidate that rules work on unseen history.
Dry-run forward testValidate 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 FirstStrategy

If 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.

RiskDescriptionMitigation
OverfittingStrategy looks great on historical data but fails live.Use out-of-sample tests, fewer parameters, and longer dry-runs.
Market regime changeA trend-following bot suffers in choppy markets.Add market filters or reduce position size in uncertain conditions.
Exchange riskDelays, downtime, or delistings can trap positions.Choose reputable exchanges and monitor API health.
API key theftLeaked keys can lead to unauthorized trades or withdrawals.Use IP whitelisting, withdrawal restrictions, and secrets management.
Slippage and feesReal fills may be worse than backtest assumptions.Model fees accurately and account for spread in low-cap pairs.
Behavioral riskDisabling 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.