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.

