The Problem
Manually trading crypto across multiple exchanges is slow and error-prone. Freqtrade solves this by providing a Python-based trading bot that automates strategy execution, backtesting, and portfolio management, with support for spot and futures markets on major exchanges like Binance, Bybit, and Kraken.
What This Does
Freqtrade is a full trading lifecycle tool. It handles data download (freqtrade/commands/data_commands.py), strategy backtesting (freqtrade/optimize/backtesting.py), hyperparameter optimization (freqtrade/optimize/hyperopt_tools.py), and live trading via freqtrade/worker.py. It also includes FreqAI (freqtrade/freqai/), a machine-learning subsystem for adaptive prediction models.
The bot persists all state to SQLite via freqtrade/persistence/trade_model.py and exposes control through Telegram, a REST API (freqtrade/rpc/), and a web UI. Configuration flows through freqtrade/configuration/, with examples in config_examples/.
How It Is Wired
Execution starts at main in freqtrade/main.py, which routes to run in freqtrade/worker.py. That entry point reaches 381 functions. run calls _worker, then startup, then set_startup_time, which queries the database via Trade.session.query(Trade).order_by(Trade.open_date.asc()) — three hops from process start to a database read.
The architecture centers on a few high-blast-radius modules. freqtrade/exceptions.py is imported by 146 modules; changing OperationalException (called from 127 places) ripples everywhere. freqtrade/enums/__init__.py (128 importers) and freqtrade/constants.py (127 importers) are similarly central. The exchange layer (freqtrade/exchange/__init__.py) participates in an import cycle with freqtrade/util/__init__.py and freqtrade/configuration/__init__.py, which makes isolated changes to those files risky.
Key file responsibilities:
freqtrade/exchange/exchange.py— 166 functions, the exchange abstraction;get_patched_exchangeis called from 280 places.freqtrade/persistence/trade_model.py— trade lifecycle, DB writes, 112 functions.freqtrade/data/dataprovider.py— feeds strategy code with market data.freqtrade/strategy/interface.py— strategy base class and callback contract.
The code touches the outside world in 126 file operations, 21 network calls, 50 database interactions, and 6 cryptographic operations. Shortest path from main to filesystem is main -> main_exec -> load_config -> file.open.
How To Use It
git clone https://github.com/moses-y/freqtrade
cd freqtrade
pip install -r requirements.txt
freqtrade create-userdir --userdir user_data
freqtrade new-config --config config.json
freqtrade backtesting --strategy SampleStrategy --config config.json
freqtrade trade --strategy SampleStrategy --config config.json
Configuration lives in config.json (see config_examples/config_full.example.json). Docker users can use docker-compose.yml. The bot runs in dry-run mode by default — no API keys required until you set "dry_run": false and add exchange credentials.
Real-World Use
A common pattern: download historical data, backtest a strategy, then deploy it live. For example, a user running a mean-reversion strategy on Binance futures would:
- Download OHLCV data with
freqtrade download-data. - Validate the strategy with
freqtrade backtesting. - Run
freqtrade tradewith"trading_mode": "futures"and"margin_mode": "isolated"in the config.
Code Health & Issues
Static analysis found 342 issues: 190 high, 147 medium, 5 low. Key findings:
- High — Oversized files:
tests/conftest.pyat 3,177 lines;freqtrade/freqai/data_kitchen.pyandfreqtrade/optimize/backtesting.pyare similarly large. Hard to hold in one head; changes ripple. - High — 25 import-cycle members, including
freqtrade/util/__init__.pyandfreqtrade/exchange/__init__.py. Circular imports make refactoring these modules expensive. - High — 12 hub modules with 100+ dependents each (
freqtrade/exceptions.py,freqtrade/enums/__init__.py). Churn here is high-blast-radius. - Medium — Broad exception handling in
freqtrade/__init__.pyandfreqtrade/exchange/exchange.py; a file opened without a context manager infreqtrade/optimize/hyperopt_tools.py. - High — No lockfile for
ft_client/pyproject.toml; non-reproducible builds. - Medium — Container base image not pinned by digest; no dependency vulnerability scan in CI; two large binaries (17MB wheel, 10MB feather) committed; GitHub token persists after checkout.
The Bottom Line
This is a mature, well-documented trading bot with a large feature surface and solid test coverage (213 test files). The main risks are architectural — hub modules and import cycles make core changes slow — and supply-chain hygiene is weaker than it should be for a tool that moves money. Use it for strategy research and dry-run validation; treat live trading as a serious deployment requiring careful review of the exchange and persistence layers.