Cyberpunk

 Cyberpunk is Dead - “It was an embarrasser; what did I want? I hadn’t thought that far ahead.
Me, caught without a program!” —Bruce Bethke, “Cyberpunk” (1983)

John Semley
no. 48, November 2019
Andi
Book Club Meeting 38, August 2026

Freqtrade is a free and open source crypto trading bot written in Python. It is designed to support all major exchanges and be controlled via Telegram or webUI. It contains backtesting, plotting and money management tools as well as strategy optimization by machine learning.

Freqtrade is a modular monolith bot that runs as a single process. It is event-driven and built around an event loop, with pluggable strategies and exchange adapters. The loop drives the bot and calls into a pluggable class called Strategy, a Python file where you write your mental trading rules as code.

The core runs in a loop, calling calling methods on the Strategy class, which generates buy/sell signals from your rules. The Strategy class does three main things:

Adds indicators
Calculates things like RSI or Moving Averages on price data (populate_indicators).
Sets entry rules
Defines exactly when to buy (populate_entry_trend).
Sets exit rules
Defines when to sell, plus your stop-loss and profit targets (populate_exit_trend).

Check page basics for more detailed information.

Profile

Edit ~/.profile and add:

# Add  freqtrade commands
PATH=/usr/local/lib/freqtrade/venv/bin:$PATH

Source it;

source ~/.profile

Config

At top level of ~/freqtrade/config.json set;

"user_data_dir": "/home/bot_client01/freqtrade",
"datadir": "/home/bot_client01/freqtrade/data"

Default configuration run in dry-run, the bot on live market data but with fake money. This tests if it works in real-time without risking cash.

KuCoin requires an extra passphrase in your exchange section, unlike most other exchanges;

"exchange": {
    "name": "kucoin",
    "key": "your_api_key",
    "secret": "your_secret",
    "password": "your_passphrase",
    "ccxt_config": {},
    "pair_whitelist": [
      "XRP/USDT"
    ],
}

Set user and password for the API and web interface;

"api_server": {
    "username": "your_username",
    "password": "your_password",
    "jwt_secret_key": "some_long_random_string_here"
}

Enable force entry in the same api_server section, this unlocks the Force Entry button in the web interface and the forceenter API endpoint;

"force_entry_enable": true

Dry run should mirror the real KuCoin account. To read the account values use the history script in the bot user home, it fetches balance, fees and fills read-only;

bash ~/kucoin_history.sh

Note; KuCoin fills queries are limited to 7 day windows, the script handles it. Then set the wallet to the real USDT balance and the plan rules at top level of config.json; unlimited stake so the strategy sizes each tranche, +10% take profit, no stoploss, one trade at a time with one reserve tranche;

"dry_run_wallet": 1.62,
"stake_amount": "unlimited",
"max_open_trades": 1,
"minimal_roi": {"0": 0.10},
"stoploss": -0.99,
"use_exit_signal": false,
"position_adjustment_enable": true,
"max_entry_position_adjustment": 1

Check page configuration for more detailed information.

Strategy

Start new strategy file cyb_strategy using sample as default;

cp strategies/sample_strategy.py strategies/cyb_strategy.py
sed -i 's/class SampleStrategy/class CybStrategy/' strategies/cyb_strategy.py
sed -i 's/SampleStrategy/CybStrategy/g' strategies/cyb_strategy.py

Set new strategy class in config.json;

"strategy": "CybStrategy"

Edit strategy pairs;

def informative_pairs(self):
        """
        Define additional, informative pair/interval combinations to be cached from the exchange.
        These pair/interval combinations are non-tradeable, unless they are part
        of the whitelist as well.
        For more information, please consult the documentation
        :return: List of tuples in the format (pair, interval)
            Sample: return [("ETH/USDT", "5m"),
                            ("BTC/USDT", "15m"),
                            ]
        """
        return [("XRP/USDT", "5m")]

The strategy implements the two tranche plan with relative rules, independent of price and amount; tranche one enters on RSI dips with half the available capital, tranche two deploys the remaining capital when price falls 7 to 9 percent below the trade average entry, and the trade exits at +10 percent of the blended entry. The zone is set in the strategy class;

RESERVE_ZONE_PCT_LOW = 0.91
RESERVE_ZONE_PCT_HIGH = 0.93

Clean start

To start bot from new configuration and strategy file and remove sample strategy data or previous state for dry-run;

sh /etc/init.d/freqtrade-client01 stop
stopped
rm tradesv3.dryrun.sqlite
sh /etc/init.d/freqtrade-client01 start
started

Check page quick start? for more detailed information.

Position adoption

To make dry-run simulate an existing real position, force a placeholder entry and retune it to the real fill. With the bot running, create the placeholder from the web interface Force Entry button for XRP/USDT, or from the shell as bot_client01;

bash ~/enter3.sh

Stop the bot, retune the placeholder to the real position with the adoption script, then start again;

sh /etc/init.d/freqtrade-client01 stop
sh /etc/init.d/freqtrade-client01 start

The trade now tracks the real entry and exits at +10% like the real limit sell on KuCoin, and the capital returns to the dry-run wallet when it closes. Both scripts live in the bot user home; adapt_edit.sh holds the real rate, amount and date at its top, update them before each adoption.

Backtest

Freqtrade historical price data is called OHLCV data used to backtest against past market data. backtest up to the present day, the second date should be 20260925;

Run the backtests 5m short-term

freqtrade download-data \
  --config /home/bot_client01/freqtrade/config.json \
  --exchange kucoin \
  --pairs XRP/USDT \
  --timeframes 5m \
  --timerange 20240101-20260925

Intraday, 1h swing / medium-term;

freqtrade download-data \
  --config /home/bot_client01/freqtrade/config.json \
  --exchange kucoin \
  --pairs XRP/USDT \
  --timeframes 1h \
  --timerange 20240101-20260925

Long-term / positional;

freqtrade download-data \
  --config /home/bot_client01/freqtrade/config.json \
  --exchange kucoin \
  --pairs XRP/USDT \
  --timeframes 1d \
  --timerange 20240101-20260925

Note; download-data accepts multiple timeframes in one run, backtesting is the opposite, it takes exactly one --timeframe per run, so run it once per horizon;

Backtest 5m short-term;

freqtrade backtesting \
  --strategy CybStrategy \
  --timeframe 5m \
  --config /home/bot_client01/freqtrade/config.json \
  --timerange 20260601-20260925 \
  --export none

Backtest 1h swing / medium-term;

freqtrade backtesting \
  --strategy CybStrategy \
  --timeframe 1h \
  --config /home/bot_client01/freqtrade/config.json \
  --timerange 20260601-20260925 \
  --export none

Backtest 1d long-term / positional;

freqtrade backtesting \
  --strategy CybStrategy \
  --timeframe 1d \
  --config /home/bot_client01/freqtrade/config.json \
  --timerange 20240101-20260925 \
  --export none

Only after it is profitable in dry-run and back testing, consider let pass some time before you connect real funds.