연중무휴 24시간 $ 0 (Freqtrade + watchdog) 에 자가 복구 암호화폐 거래 봇 실행

작성자

카테고리:

← 피드로
DEV Community · matteo adorni · 2026-09-25 개발(SW)

Most “run a trading bot” tutorials stop at backtest passed, bot started. That is the easy 20%. The hard 80% is what happens on day 4 at 03:00 when the process is gone and you only notice three weeks later — with a flat equity curve and a dead clock.

This post is the part nobody writes: a production-shaped, zero-cost setup where the bot restarts itself, logs its own P&L, and hard-stops on a risk rule you define. Everything below was built and verified in a single afternoon on a $0 budget, using only open-source tooling. The dry-run trades are simulated — no exchange key, no real money, no risk.

Why a watchdog matters more than the strategy

A strategy is a hypothesis. A watchdog is what turns a hypothesis into data.

If your bot silently dies, every metric you were collecting stops: win rate, drawdown, profit factor. You think you are “running a 14-day validation” while in reality the last trade was nine days ago. A watchdog fixes three things cheaply:

  1. Availability — the process is restarted automatically.
  2. Observability — a P&L snapshot is appended to a log on every cycle, so you have a time series instead of a vibe.
  3. Risk — a global rule (e.g. stop if drawdown ≥ 10% of the wallet) is enforced by code, not by willpower.

Prerequisites

  • Linux (or WSL2) with ~3 GB RAM.
  • uv for the Python environment. On modern distros pip install into the system Python is blocked by PEP 668, and uv sidesteps that cleanly.
curl -LsSf https://astral.sh/uv/install.sh | sh
uv venv ~/freqtrade/.venv
source ~/freqtrade/.venv/bin/activate
uv pip install freqtrade

Enter fullscreen mode Exit fullscreen mode

A minimal, sane config

Start with a cosmetic config and tune later. The important bits for a safe dry-run:

{
  "max_open_trades": 3,
  "stake_currency": "USDT",
  "stake_amount": 50,
  "dry_run": true,
  "dry_run_wallet": 500,
  "trading_mode": "spot",
  "exchange": {
    "name": "binance",
    "key": "",
    "secret": "",
    "pair_whitelist": ["BTC/USDT", "ETH/USDT", "SOL/USDT"]
  },
  "pairlists": [{ "method": "StaticPairList" }],
  "api_server": {
    "enabled": true,
    "listen_ip_address": "127.0.0.1",
    "listen_port": 8080,
    "username": "hermes",
    "password": "CHANGE_ME",
    "jwt_secret_key": "CHANGE_ME_TOO",
    "ws_token": "CHANGE_ME_AS_WELL"
  },
  "bot_name": "dryrun",
  "initial_state": "running"
}

Enter fullscreen mode Exit fullscreen mode

Two rules that will save you hours:

  • Bind the API to 127.0.0.1, never 0.0.0.0. The API exposes order and config operations.
  • Set jwt_secret_key, ws_token and a real password even in dry-run. Empty secrets are a production foot-gun waiting to be copied into live.

Backtest before you believe anything

Download history and backtest several strategies in their native timeframe. A common mistake is backtesting a 5-minute scalp strategy on 1-hour candles and concluding it is bad — you are measuring the timeframe, not the strategy.

freqtrade download-data --config config.json --days 200 --timeframes 5m 15m 1h

for s in SwingHighToSky BbandRsi UniversalMACD; do
  freqtrade backtesting --config config.json --strategy "$s" \
    --timerange 20260310-20260925 --breakdown
done

Enter fullscreen mode Exit fullscreen mode

A real result set from a 200-day window (fees included) looked like this:

strategy timeframe trades win% profit profit factor max drawdown SwingHighToSky 15m 108 68.5% +1.60% 5.21 0.37% BbandRsi 1h 62 74.2% +3.99% 1.38 7.92% UniversalMACD 5m 6 100% +1.48% ∞ 0.00%

Read that table honestly. UniversalMACD shows a perfect win rate — on six trades. That is not an edge, that is a sample size. BbandRsi has the highest absolute return but a weak profit factor. SwingHighToSky is the only one passing all three filters (PF > 1.5, drawdown < 15%, win rate > 55%) on a statistically usable sample. Pick on the quality of the evidence, not on the biggest number.

Also note: none of them beat buy-and-hold over a window where the market rose ~31%. The dry-run’s job is to validate operational behaviour, not to beat the market. Be suspicious of any backtest that does.

The watchdog (the actually interesting part)

Here is a working watchdog, designed to run from cron and stay silent unless something is wrong.

#!/bin/bash
# - restarts the bot if the process died
# - appends a P&L snapshot to logs/daily_pnl.txt on every run
# - SILENT on success; speaks only on restart or risk-limit breach
set -u
BASE=/home/kali/freqtrade
VENV_PY=$(readlink -f "$BASE/.venv/bin/python")
cd "$BASE" || { echo "watchdog: cannot cd $BASE"; exit 1; }
PY=$BASE/.venv/bin/python
LOG=$BASE/logs/watchdog.log
ts() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }

# Print PIDs of the REAL bot processes (empty if none).
find_bot() {
  for p in /proc/[0-9]*; do
    pid=${p#/proc/}
    [ -r "$p/cmdline" ] || continue
    cmd=$(tr '\0' ' ' < "$p/cmdline" 2>/dev/null) || continue
    case "$cmd" in
      *"freqtrade trade --config"*)
        exe=$(readlink -f "$p/exe" 2>/dev/null)
        [ "$exe" = "$VENV_PY" ] && echo "$pid"
        ;;
    esac
  done
}

MSG=""
if [ -z "$(find_bot)" ]; then
  echo "$(ts) bot not running -> restarting" >> "$LOG"
  nohup "$BASE/.venv/bin/freqtrade" trade --config "$BASE/config.json" \
      --strategy SwingHighToSky --dry-run >> "$BASE/logs/trade_stdout.log" 2>&1 &
  sleep 30
  if [ -n "$(find_bot)" ]; then
    MSG="crypto-bot: process was gone, restarted at $(ts)."
  else
    echo "$(ts) restart FAILED" >> "$LOG"
    exit 1
  fi
fi

OUT=$("$PY" "$BASE/monitor_pnl.py" 2>&1); RC=$?
if [ $RC -eq 2 ]; then                      # drawdown limit hit
  for pid in $(find_bot); do kill "$pid" 2>/dev/null; done
  echo "$(ts) DRAWDOWN LIMIT HIT -> stopping bot" >> "$LOG"
  echo "crypto-bot: drawdown >= 10% of wallet. Bot STOPPED by risk rule." 
  echo "$OUT"
  exit 2
fi
echo "$OUT" >> "$LOG"
[ -n "$MSG" ] && echo "$MSG"
exit 0

Enter fullscreen mode Exit fullscreen mode

The gotcha that cost me an hour

Do not detect the process with pkill -f freqtrade or pgrep -f freqtrade. That pattern also matches the shell that invoked your script — because the string freqtrade appears in its command line — and the script kills itself. I hit exactly this. Scanning /proc and requiring both the freqtrade trade --config cmdline and an exe pointing into the venv is unambiguous and safe.

Make it run without babysitting

# every 15 minutes; quiet unless it acts
*/15 * * * * /home/kali/.hermes/scripts/crypto_watchdog.sh

Enter fullscreen mode Exit fullscreen mode

Verify it end-to-end the first time: kill the bot, run the watchdog, confirm the restart and the P&L line. A watchdog you have never seen fire is a watchdog you do not have.

The kill switch is the whole point

The drawdown rule (>= 10% of the wallet → stop the bot) is enforced outside the strategy, in the watchdog. Strategy-level stoplosses protect a trade; this protects the account. Keeping it in one place — not scattered across strategy parameters — means you can reason about your worst case at a glance.

Results after the first hours

wallet=500.10 closed_pnl=+0.000USDT (+0.00%) all_pnl=+0.003USDT (+0.00%) trades=0W/0L open=1

Enter fullscreen mode Exit fullscreen mode

Zero closed trades, one open position, equity essentially flat. That is the correct shape for hour one of a dry-run. The value is not the P&L yet — it is that the clock is now running on a validated, self-healing, risk-capped system, at zero cost.

What to do next

  1. Let it run for two weeks. Judge the behaviour: did the watchdog ever fire? did the kill switch ever trip? how did it behave around a volatility spike?
  2. Hyperopt deliberately — a handful of epochs with a Sharpe-based loss, then re-backtest. Do not hyperopt your way into a curve fit.
  3. Only then consider real capital — and only with an amount you are genuinely fine losing.

The whole setup costs nothing and removes the two failure modes that kill most hobby bots: a dead process and an unenforced risk rule.

If you build on this, the two files worth stealing are the /proc-based process check and the drawdown kill switch. Everything else is configuration.

Want this pre-built? I packaged the watchdog, the P&L logger, the backtest runner and the config
into a drop-in kit — Freqtrade Self-Healing Starter Kit ($9).
It is the exact code from this article plus a setup guide with the /proc gotcha already solved,
so you can go from zero to a self-healing bot in about five minutes.

Related in this series:

The watchdog from this post is open source: **https://github.com/moon-hacks/proc-watchdog* (MIT).*

Prefer someone to just do it? I also offer a **done-for-you setup* (https://tntofficial.gumroad.com/l/vweza) — Freqtrade installed, backtested and left running in dry-run with the watchdog active.*

원문에서 계속 ↗