AI #03 · AI 활용하기

Freqtrade NFI 봇
설치부터 24시간 운영까지

자동매매 봇은 전략보다 먼저 운영 환경이 중요함. 처음 하는 사람이 가장 많이 막히는 지점은 코드가 아니라 Python 버전, API 권한, config 경로, 텔레그램 Chat ID, 그리고 Dry Run 확인 순서다. 이번 글은 Freqtrade + NostalgiaForInfinityX7 조합을 바이낸스 USDT 선물 기준으로 세팅하되, 각 단계마다 “정상인지 확인하는 기준”까지 같이 정리한 실전 가이드임.

$ ./start_freqtrade.sh
INFO - Dry run is enabled. All trades are simulated.
INFO - Using strategy: NostalgiaForInfinityX7
INFO - Bot heartbeat. Trades: 0
INDEX
01설치 전에 반드시 준비할 것
02Python 환경과 Freqtrade 설치
03NFI X7 전략 파일과 config 구성
04민감정보 분리와 실행 스크립트
05Dry Run 검증, 실거래 전환, PM2 운영
06운영 중 자주 보는 명령어와 오류

01설치 전에 반드시 준비할 것

이 세팅은 바이낸스 USDT 선물, Python 3.12, macOS 또는 Linux 환경을 기준으로 한다. Freqtrade 공식 문서는 Python 3.11 이상을 요구하지만, 새로 세팅한다면 3.12로 맞추는 편이 깔끔하다. Windows 사용자는 네이티브 설치보다 WSL 또는 Docker 쪽이 덜 꼬인다.

초보자라면 먼저 목표를 분명히 해야 한다. 이 글의 목표는 “바로 돈을 벌기”가 아니라 로컬 또는 서버에서 봇이 안전하게 켜지고, 모의 거래가 돌고, 텔레그램과 WebUI로 상태 확인이 되는 환경을 만드는 것이다. 이 단계가 안정적으로 끝나기 전에는 실거래 버튼을 누르면 안 된다.

Exchange
바이낸스 API Key
읽기와 선물 거래 권한만 허용한다. 출금 권한은 절대 켜지 않는다. 가능하면 서버 IP만 허용하는 화이트리스트를 설정한다.
Telegram
봇 토큰과 Chat ID
BotFather로 봇을 만들고 HTTP API Token을 저장한다. Chat ID는 @userinfobot으로 확인한다.
Runtime
Python 3.12
Freqtrade 실행 환경이다. 오래된 Python 버전에서 설치 오류가 날 수 있으니 3.12 기준으로 맞춘다.
Policy
Dry Run 우선
처음부터 실거래로 켜지 않는다. 최소 2주 이상 모의 투자로 주문 흐름, 텔레그램 알림, 로그를 확인한다.
Security Rule
API Secret은 발급 화면에서 한 번만 보인다. 저장을 놓치면 다시 확인할 수 없다. 그리고 어떤 경우에도 출금 권한은 허용하지 않는다.

02Python 환경과 Freqtrade 설치

봇은 하나의 독립된 작업 폴더 안에서 운영한다. 가상환경을 분리해두면 시스템 Python이나 다른 프로젝트 패키지와 충돌하지 않는다. 먼저 내 컴퓨터가 Python 3.12를 제대로 인식하는지 확인한다.

python3.12 --version
# Python 3.12.x 가 나오면 진행

`python3.12: command not found`가 나오면 Python 설치부터 해결해야 한다. macOS라면 Homebrew로 Python 3.12를 설치하고, Ubuntu라면 배포판에 맞는 Python 3.12 패키지 또는 pyenv를 쓰는 방식이 일반적이다.

# 작업 디렉토리 생성
mkdir ~/freqtrade-bot
cd ~/freqtrade-bot

# Python 3.12 가상환경 생성
python3.12 -m venv .venv

# 가상환경 활성화
source .venv/bin/activate

# pip 업그레이드 후 Freqtrade 설치
pip install -U pip setuptools wheel
pip install freqtrade

설치가 끝나면 두 가지를 확인한다. 첫째, 지금 쓰는 Python이 `.venv` 안의 Python인지 확인한다. 둘째, `freqtrade` 명령이 정상으로 뜨는지 확인한다.

which python
which freqtrade
freqtrade --version
Install Fallback
일부 macOS ARM64 환경이나 Linux 서버에서는 `pip install freqtrade` 단계에서 빌드 오류가 날 수 있다. 이 경우 억지로 에러를 뚫기보다 Freqtrade 공식 설치 스크립트 또는 Docker 방식을 쓰는 편이 빠르다. 초보자는 “설치 성공”보다 “재현 가능한 운영 환경”이 더 중요하다.

다음으로 Freqtrade가 사용할 기본 폴더 구조를 만든다.

freqtrade create-userdir --userdir user_data
ls user_data/

정상이라면 `backtest_results`, `data`, `hyperopts`, `logs`, `models`, `notebooks`, `strategies`, `templates` 같은 폴더가 생성된다. 우리가 전략 파일을 넣을 위치는 `user_data/strategies`임.

여기까지 끝났을 때의 성공 기준은 단순하다. `~/freqtrade-bot` 폴더 안에 `.venv`와 `user_data`가 있고, 가상환경을 켠 상태에서 `freqtrade --version`이 실행되면 다음 단계로 넘어가면 된다.

03NFI X7 전략 파일과 config 구성

NFI는 NostalgiaForInfinity 전략 계열이고, 여기서는 `NostalgiaForInfinityX7.py` 파일을 사용한다. 전략 파일은 `strategies` 폴더 안에 있어야 Freqtrade가 인식한다.

cd user_data/strategies
curl -LO https://raw.githubusercontent.com/iterativv/NostalgiaForInfinity/main/NostalgiaForInfinityX7.py
ls -lh NostalgiaForInfinityX7.py
cd ../..

`ls -lh` 결과에서 파일 크기가 너무 작으면 다운로드가 실패했거나 404 페이지를 저장했을 가능성이 있다. 파일을 열었을 때 Python 코드가 아니라 HTML 에러 페이지처럼 보이면 다시 내려받아야 한다.

그 다음 핵심은 `user_data/config.json`이다. 아래는 바이낸스 USDT 선물, 격리 마진, Static PairList, 텔레그램, WebUI를 전제로 한 기본 골격이다. API 키와 텔레그램 토큰은 여기에 직접 넣지 않고 다음 섹션에서 환경변수로 분리한다. 처음 세팅하는 사람은 종목 수를 너무 많이 넣지 말고, BTC/ETH/SOL/XRP 정도로 시작해서 봇의 움직임을 먼저 관찰하는 편이 낫다.

{
  "trading_mode": "futures",
  "margin_mode": "isolated",
  "max_open_trades": 12,
  "stake_currency": "USDT",
  "stake_amount": "unlimited",
  "tradable_balance_ratio": 0.99,
  "fiat_display_currency": "USD",
  "dry_run": true,
  "dry_run_wallet": 1000,
  "cancel_open_orders_on_exit": false,
  "timeframe": "5m",
  "use_exit_signal": true,
  "exit_profit_only": false,
  "ignore_roi_if_entry_signal": true,
  "exchange": {
    "name": "binance",
    "key": "",
    "secret": "",
    "enable_ws": true,
    "markets_refresh_interval": 240,
    "pair_whitelist": [
      "BTC/USDT:USDT",
      "ETH/USDT:USDT",
      "SOL/USDT:USDT",
      "XRP/USDT:USDT"
    ],
    "pair_blacklist": [
      "BNB/USDT:USDT",
      "(AEUR|FDUSD|BUSD|CUSD|CUSDT|DAI|SUSD|TUSD|USDC|USDN|USDP|USDT|UST|USTC|AUSD|EURI|USDS)/USDT:USDT",
      ".*3L/USDT:USDT",
      ".*3S/USDT:USDT",
      ".*BULL/USDT:USDT",
      ".*BEAR/USDT:USDT"
    ]
  },
  "pairlists": [{ "method": "StaticPairList" }],
  "telegram": {
    "enabled": true,
    "allow_custom_messages": true,
    "token": "",
    "chat_id": ""
  },
  "api_server": {
    "enabled": true,
    "listen_ip_address": "127.0.0.1",
    "listen_port": 8080,
    "verbosity": "error",
    "enable_openapi": false,
    "jwt_secret_key": "",
    "CORS_origins": [],
    "username": "",
    "password": ""
  },
  "bot_name": "freqtrade_Nostalgia",
  "initial_state": "running",
  "force_entry_enable": false,
  "internals": {
    "process_throttle_secs": 2,
    "heartbeat_interval": 60
  }
}
파라미터권장값의미
dry_runtrue처음에는 반드시 모의 투자로 시작한다.
max_open_trades12동시에 열 수 있는 포지션 슬롯 수다.
stake_amount"unlimited"잔고를 슬롯 기준으로 나눠 사용한다.
margin_mode"isolated"코인별 리스크를 분리하는 격리 마진이다.
timeframe"5m"NFI X7 기준 운영 타임프레임이다.
Pair List
예시에는 주요 코인만 짧게 넣었지만, 실제 운영에서는 본인이 감당할 수 있는 종목만 넣어야 한다. 종목 수가 많아지면 동시 포지션과 DCA 리스크도 같이 커진다.

config를 저장한 뒤에는 JSON 문법이 깨지지 않았는지 먼저 확인한다. Python이 설치되어 있다면 아래 명령으로 쉼표 누락, 따옴표 오류 같은 기본 실수를 바로 잡을 수 있다.

python -m json.tool user_data/config.json > /tmp/freqtrade-config-check.json

04민감정보 분리와 실행 스크립트

API 키, 텔레그램 토큰, WebUI 비밀번호는 `config.json`에 직접 쓰지 않는 편이 좋다. Freqtrade는 `FREQTRADE__섹션__키` 형태의 환경변수로 config 값을 덮어쓸 수 있다.

# .env.freqtrade
FREQTRADE__EXCHANGE__KEY=발급받은_바이낸스_API_KEY
FREQTRADE__EXCHANGE__SECRET=발급받은_바이낸스_SECRET
FREQTRADE__TELEGRAM__TOKEN=BotFather에서_받은_토큰
FREQTRADE__TELEGRAM__CHAT_ID=본인_Chat_ID_숫자
FREQTRADE__API_SERVER__USERNAME=freqtrader
FREQTRADE__API_SERVER__PASSWORD=안전한_비밀번호_설정
FREQTRADE__API_SERVER__JWT_SECRET_KEY=랜덤_긴_문자열_직접_입력
chmod 600 .env.freqtrade

다음은 실행 스크립트다. 매번 환경변수를 직접 불러오고 명령어를 길게 입력할 필요가 없어진다.

#!/bin/sh
set -eu

SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
ENV_FILE="$SCRIPT_DIR/.env.freqtrade"

if [ ! -f "$ENV_FILE" ]; then
  echo "Error: .env.freqtrade 파일이 없습니다: $ENV_FILE" >&2
  exit 1
fi

set -a
. "$ENV_FILE"
set +a

cd "$SCRIPT_DIR"
exec "$SCRIPT_DIR/.venv/bin/python" -m freqtrade trade \
  --config user_data/config.json \
  --strategy NostalgiaForInfinityX7
chmod +x start_freqtrade.sh
Git Ignore
`.env.freqtrade`는 절대 Git에 올리면 안 된다. 개인 저장소라도 API Secret이 남으면 사고로 이어진다. `.gitignore`에 반드시 추가한다.

실행 전에 최종 config가 의도대로 합쳐졌는지도 확인한다. Freqtrade는 환경변수가 config보다 우선 적용되므로, 아래 명령으로 key, telegram, api_server 값이 들어갔는지 확인할 수 있다. 기본 출력은 민감값을 가려서 보여주므로 검증용으로 쓰기 좋다.

set -a
. ./.env.freqtrade
set +a
freqtrade show-config --config user_data/config.json

여기서 `dry_run`이 `true`인지, `exchange.name`이 `binance`인지, `trading_mode`가 `futures`인지, `telegram.enabled`가 `true`인지 확인한다. 초보자는 이 확인을 생략하지 않는 게 좋다. 실제로 많은 문제는 봇 코드가 아니라 환경변수 이름 오타에서 발생한다.

05Dry Run 검증, 실거래 전환, PM2 운영

처음 실행은 Dry Run으로 한다. 여기서 확인할 것은 수익이 아니라 봇이 제대로 시장 데이터를 받고, 전략 파일을 인식하고, 텔레그램과 WebUI가 정상 작동하는지임.

source .venv/bin/activate
./start_freqtrade.sh

Dry Run을 켠 첫날에는 수익률을 보지 말고 운영 체크리스트를 봐야 한다. 로그가 계속 쌓이는지, 텔레그램 명령이 먹히는지, WebUI가 끊기지 않는지, 봇이 어떤 종목을 감시하는지, 포지션이 열릴 때 stake가 의도한 크기인지 확인한다.

Live Gate
실거래 전환 조건은 “Dry Run에서 수익이 났다”가 아니다. 최소 2주 동안 오류 없이 켜져 있었고, 봇이 언제 진입하고 언제 포지션을 줄이는지 설명할 수 있고, 최대 동시 포지션과 1회 주문 크기를 감당할 수 있을 때만 전환한다.

실거래 전환은 `user_data/config.json`에서 `dry_run`을 `false`로 바꾸고 재시작하면 된다. 다만 이 단계는 최소 2주 이상 Dry Run을 돌리고, 전략의 진입 빈도와 손실 구간을 눈으로 확인한 뒤 진행해야 한다.

"dry_run": false

장시간 운영은 PM2로 관리한다. 터미널을 닫아도 프로세스가 유지되고, 재시작과 로그 확인이 편해진다.

npm install -g pm2
// ecosystem.config.js
module.exports = {
  apps: [
    {
      name: 'freqtrade_Nostalgia',
      script: './start_freqtrade.sh',
      cwd: '/절대경로/freqtrade-bot',
      interpreter: 'none',
      autorestart: true,
      watch: false,
      max_restarts: 10,
      restart_delay: 5000,
      log_date_format: 'YYYY-MM-DD HH:mm:ss',
      out_file: './user_data/logs/freqtrade-out.log',
      error_file: './user_data/logs/freqtrade-err.log',
      merge_logs: true
    }
  ]
};
pm2 start ecosystem.config.js
pm2 save
pm2 startup

PM2로 올린 뒤에는 터미널을 닫기 전에 반드시 프로세스 상태와 로그를 확인한다. `online`으로 떠 있고 heartbeat가 계속 찍히면 무중단 운영의 기본 조건은 충족된 것이다.

pm2 list
pm2 logs freqtrade_Nostalgia
Every 2 sec
포지션과 주문 점검
열린 포지션, 주문 상태, 보호 로직을 반복 확인한다.
Every 5 min
신규 캔들 분석
NFI X7 전략이 진입과 청산 신호를 계산한다.
Every 60 sec
Heartbeat 기록
봇이 살아 있는지 로그로 상태를 남긴다.
Operator
텔레그램 감시
포지션, 수익, 잔고, 긴급 청산 명령을 원격으로 확인한다.

06운영 중 자주 보는 명령어와 오류

텔레그램은 운영자의 리모컨이다. 특히 서버에 직접 접속하지 못하는 상황에서 상태 확인과 긴급 대응을 빠르게 할 수 있다.

명령어기능
/status table현재 보유 포지션과 수익률 확인
/profit전체 누적 수익 집계
/daily 7최근 7일 일별 수익 통계
/balance현재 잔고 확인
/count열린 포지션 수와 최대 슬롯 확인
/stop신규 진입 중단, 기존 포지션은 유지
/forceexit all긴급 상황에서 모든 포지션 즉시 청산

NFI X7를 이해할 때 중요한 지점

NFI X7는 단순한 하나의 조건식이 아니라 여러 진입 조건을 조합하는 앙상블형 전략에 가깝다. RSI, EMA, 볼린저 밴드, 거래량 같은 조건이 복합적으로 작동하고, 포지션이 불리해졌을 때는 Derisk와 Grinding 방식으로 포지션을 관리한다.

그래서 하드 스톱로스가 매우 넓게 잡혀 있어도 그것을 “손절을 안 한다”로 이해하면 안 된다. 전략 내부의 방어 로직이 먼저 작동하고, 하드 스톱로스는 마지막 방어선에 가깝다. 선물에서는 이 구조를 이해하지 못한 상태로 큰 금액을 넣으면 위험하다.

자주 발생하는 오류

핵심 정리
  • Freqtrade NFI 봇은 전략 설치보다 운영 환경 구성이 먼저다.
  • 바이낸스 API는 읽기와 선물 거래만 허용하고 출금 권한은 절대 켜지 않는다.
  • `config.json`에는 구조를 두고, 실제 Secret은 `.env.freqtrade`로 분리한다.
  • 처음 2주는 반드시 Dry Run으로 주문 흐름과 알림을 검증한다.
  • 24시간 운영은 PM2로 관리하고, 로그와 텔레그램 명령어를 자주 확인한다.
  • NFI X7는 하락장 반등과 포지션 관리 로직을 포함하지만, 선물 청산 위험은 사라지지 않는다.