SSD Nodes Learn 8GB RAM — 연 $66
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-01

트레이딩 봇 VPS 선택, 실제로 중요한 기준

트레이딩 봇 VPS는 속도보다 systemd 재시작, 정확한 시간, API 키 보호, heartbeat가 중요합니다. 99.9% 가동 시간의 한계와 지연 시간을 현실적으로 설명합니다.

트레이딩 봇에 VPS가 제공해야 하는 기능

트레이딩 봇용 VPS는 4가지 기준으로 평가합니다. 프로세스가 중단된 후 다시 실행되는지, 시간이 정확한지, API (application programming interface) 키를 탈취하기 어려운지, 그리고 중단 사실을 알 수 있는지가 기준입니다. 개인용 봇에서는 원시 처리 속도가 우선순위가 아닙니다. 주문 경로에서 지연이 발생하는 주된 위치는 Python을 실행하는 호스트가 아니라 브로커와 브로커까지의 거리이기 때문입니다.

이 문서는 엔지니어링 가이드입니다. 여기에서는 금융 조언을 제공하지 않으며, 어떤 전략도 다루지 않습니다.

가동 시간은 영업 페이지의 숫자가 아니라 재시작 관리입니다

모든 호스트는 99.9% 가동 시간을 광고합니다. 이 수치는 사용자의 bot이 아니라 hypervisor의 가동 시간을 나타냅니다. 처리되지 않은 예외, 재연결하지 않는 websocket 또는 OOM (out of memory) killer 때문에 bot이 종료되어도 서버 자체는 계속 실행될 수 있습니다. 따라서 중요한 질문은 프로세스가 종료된 후 10초 동안 어떤 일이 발생하는가입니다.

bot을 systemd 서비스로 실행하고 init 시스템이 재시작을 관리하도록 합니다. unit 파일 6줄이면 이 작업을 수행할 수 있습니다.

[Unit]
Description=Trading bot
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=0

[Service]
Type=simple
User=bot
WorkingDirectory=/opt/tradingbot
EnvironmentFile=/etc/tradingbot/api.env
ExecStart=/opt/tradingbot/venv/bin/python -m tradingbot
Restart=always
RestartSec=10
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/var/lib/tradingbot

[Install]
WantedBy=multi-user.target

StartLimitIntervalSec=0는 사람들이 빠뜨리는 줄입니다. 기본적으로 systemd는 10초 동안 5번 재시작되면 포기하고 unit을 failed 상태로 영구적으로 남깁니다. 이는 03:00에 발생해서는 안 되는 동작입니다. 값을 0으로 설정하면 속도 제한이 비활성화됩니다. 따라서 crash-loop가 발생하는 bot은 조용히 중단되는 대신 계속 재시작을 시도합니다. RestartSec=10는 이 루프가 거래소에 재연결 요청을 반복해서 보내는 것을 막습니다.

파일을 신뢰하기 전에 검사한 다음 서비스를 시작합니다.

sudo systemd-analyze verify /etc/systemd/system/tradingbot.service
sudo systemctl daemon-reload
sudo systemctl enable --now tradingbot
systemctl status tradingbot

enable는 재부팅 후에도 유지되는 부분입니다. 커널 업데이트를 수행하면 재부팅이 필요합니다. bot이 조용히 종료되고 있는지 확인하려면 systemd에 재시작 카운터를 요청합니다.

systemctl show tradingbot -p NRestarts
journalctl -u tradingbot --since "24 hours ago" | tail -50

일주일 후 NRestarts=0이면 bot이 정상적으로 작동하고 있는 것입니다. NRestarts=812이면 밤새 재연결을 반복하는 프로세스로 거래하고 있었다는 뜻입니다. 일일 보고서와 같은 예약 작업에 사용하는 timer를 포함한 전체 unit 파일 구조는 systemd 서비스로 프로그램 실행에서 설명합니다.

시계를 UTC로 설정하고 동기화 상태를 확인합니다

거래소 API는 타임스탬프로 요청에 서명하며, 허용된 시간 범위를 벗어난 요청을 거부합니다. 이 범위는 대개 5초 이하입니다. 시계가 틀어지면 인증 실패처럼 보이는 오류가 발생합니다. 따라서 사용자는 시간을 확인하기 전에 몇 시간 동안 키를 교체하기도 합니다. Binance 스타일 API에서는 메시지가 그대로 표시됩니다: Timestamp for this request was 1000ms ahead of the server's time.

서버를 UTC로 설정합니다. 로컬 시간대에서는 서머타임 전환으로 인해 거래 세션 중간에 시간이 변경될 수 있습니다.

sudo timedatectl set-timezone UTC
timedatectl

Ubuntu에는 SNTP(Simple Network Time Protocol) 클라이언트인 systemd-timesyncd가 포함되어 있습니다. 로그 기록에는 충분하지만, 몇 밀리초 이내의 정확도를 유지해야 하는 용도에는 적합하지 않습니다. 서버 하나만 조회하고 시계를 지속적으로 조정하지 않기 때문입니다. 대신 chrony를 사용합니다.

sudo apt update && sudo apt install -y chrony
sudo systemctl enable --now chrony
chronyc tracking
chronyc sources -v

chronyc tracking에서 확인할 항목은 System time입니다. 예시는 System time : 0.000031415 seconds fast of NTP time입니다. 몇 밀리초 미만이면 정상입니다. Leap status : Not synchronised로 표시되면 chrony가 아직 서버에 연결되지 않은 상태입니다. 일반적으로 외부로 나가는 UDP 123이 차단되어 있기 때문입니다. 1분 기다린 후 방화벽 규칙을 변경하기 전에 다시 확인합니다.

API 키를 복사하는 위치에 두지 않기

유출된 거래소 키는 유출된 SSH 키보다 위험합니다. 출금 권한이 있으면 즉시 자금으로 전환될 수 있기 때문입니다. 대부분의 위험은 다음 2가지 습관으로 줄일 수 있습니다.

첫째, 봇 키에 출금 권한을 부여하지 마십시오. 거래소에서 지원한다면 키를 서버의 IP 주소에 연결하십시오. 이 설정은 탈취된 키를 거의 쓸모없게 만드는 가장 중요한 제어 수단입니다.

둘째, 보안 키를 코드 디렉터리 외부에 보관하십시오. /opt/tradingbot 안에 있는 파일은 결국 git 저장소나 백업 아카이브에 포함됩니다. systemd만 읽을 수 있는 root 소유 파일에 보관하십시오.

sudo install -d -m 750 -o root -g bot /etc/tradingbot
sudo install -m 640 -o root -g bot /dev/null /etc/tradingbot/api.env
sudo nano /etc/tradingbot/api.env

이 파일에는 따옴표와 export가 없는 일반 KEY=value 줄을 저장합니다. 그룹을 bot로 설정한 Mode 640을 사용하면 서비스 사용자는 파일을 읽을 수 있고 다른 사용자는 읽을 수 없습니다. sudo -u bot cat /etc/tradingbot/api.env으로 확인한 다음 다른 사용자로도 확인하십시오. 다른 사용자로는 반드시 Permission denied이 실패해야 합니다.

봇 자체는 root 또는 로그인 사용자로 실행하지 않아야 합니다. 로그인에 사용할 셸과 홈 디렉터리가 없는 시스템 계정을 생성하십시오.

sudo useradd --system --shell /usr/sbin/nologin --home-dir /var/lib/tradingbot --create-home bot

각 플래그의 의미와 ProtectSystem=strict이 실제로 적용되는 범위는 권한이 없는 사용자로 서비스 실행에서 설명합니다. 나머지 서버 기본 설정인 SSH 키와 방화벽은 새 VPS에서 처음 10분 동안 수행할 작업에 정리되어 있습니다.

브로커보다 먼저 중단 사실을 확인합니다

systemctl status는 프로세스가 실행 중이라고 알려 줍니다. 봇이 실제로 작업 중이라는 뜻은 아닙니다. 중단된 websocket에 대해 재시도 루프에 갇힌 프로세스도 systemd가 수행할 수 있는 모든 검사를 통과합니다.

대신 heartbeat를 사용합니다. Uptime Kuma에는 push monitor가 있습니다. 이 기능은 봇이 일정한 간격으로 URL을 호출할 것을 기대하고, 호출이 더 이상 도착하지 않으면 경고를 보냅니다. 봇이 실행 중임을 입증하는 작업이 끝난 뒤, 예를 들어 시장 데이터를 성공적으로 읽은 뒤에 main loop의 마지막 부분에서 이 호출을 수행합니다.

curl -fsS "http://monitor.example.com:3001/api/push/YOUR_TOKEN?status=up&msg=loop_ok"

일반적인 지연으로 인해 불필요한 알림이 발생하지 않도록 monitor 간격을 loop 실행 시간의 약 2배로 설정합니다. monitor는 봇과 다른 서버에서 실행합니다. 감시 대상과 함께 monitor도 중단되면 아무것도 보고하지 못하기 때문입니다. 설정 방법은 Uptime Kuma를 사용한 자체 호스팅 상태 모니터링에서 설명합니다.

디스크 알림도 추가합니다. 상세 로그를 기록하는 봇은 몇 주 안에 root filesystem을 가득 채울 수 있습니다. 디스크가 가득 차면 network call이 아니라 database write가 중단되므로 증상이 이상하게 나타납니다. /etc/systemd/journald.confjournalctl --vacuum-time=14dSystemMaxUse= 행은 journal 크기를 제한합니다.

솔직히 말하면 지연 시간은 대부분 호스트의 문제가 아니다

여기서 트레이딩 VPS 제품 시장은 기술적인 영역을 벗어난다. 마케팅 페이지는 1밀리초 미만의 수치를 제시하며, 체결을 좌우하는 요소가 호스트인 것처럼 암시한다. 그러나 거의 모든 일반 개인용 봇에서는 그렇지 않다.

주문은 public internet을 통해 봇에서 거래소 또는 broker endpoint로 이동한다. 이 경로는 물리적 거리와 사용자 provider와 상대 provider 간 peering의 영향을 크게 받는다. Frankfurt의 server가 Tokyo의 endpoint와 통신하면 CPU가 아무리 빨라도 왕복에 대략 250밀리초가 걸린다. 여기에 broker 자체 시스템의 queue, risk check 및 rate limit이 추가된다. retail account에서는 이 시간이 일반적으로 수십 또는 수백 밀리초 단위다.

추측하지 말고 측정한다. curl은 실제 endpoint에 대한 connection time과 first-byte time을 보고한다.

curl -s -o /dev/null -w 'dns=%{time_namelookup}s connect=%{time_connect}s ttfb=%{time_starttransfer}s\n' \
  https://api.kraken.com/0/public/Time
mtr -rwzc 100 api.kraken.com

사용하기로 결정하기 전에 후보 server에서 이 명령을 실행한다. connect가 0.180초라면 잘못된 대륙에 있는 것이며, 이는 변경할 가치가 있다. connect가 0.004초이고 ttfb이 0.140초라면 남은 지연은 broker의 처리 시간이다. 호스트를 변경해도 이 시간은 줄어들지 않는다.

그렇다면 호스트는 언제 중요할까? venue와 colocate하거나 cross-connect하여 queue position을 두고 경쟁할 때다. 이는 다른 예산이 필요한 별도의 사업이다. 또한 자체 코드가 병목일 때도 중요하다. 예를 들어 매 tick마다 전체 history에 대해 indicator를 다시 계산하는 봇은 loop마다 CPU를 200밀리초 동안 사용할 수 있다. 이는 무료로 직접 줄일 수 있는 실제 지연이다. 더 빠른 server를 찾기 전에 loop를 profile한다.

선택한 호스트에서 중요한 요소는 geography, 안정적인 networking, 그리고 OOM killer가 개입할 필요가 없을 만큼 충분한 memory다. 2026년 7월 기준으로 수백 개의 symbol을 memory에 보관하는 단일 전략 Python 봇은 2 GB의 RAM과 2 vCPU에서 여유 있게 실행된다. tick history를 local database에 보관한다면 memory를 추가한다.

운영 전 최종 점검 목록

  1. systemctl is-enabled tradingbot이(가) enabled을(를) 출력하고 서비스가 sudo reboot 이후에도 계속 실행됩니다.
  2. chronyc tracking이(가) 시스템 시간 오프셋이 몇 밀리초 미만이라고 보고합니다.
  3. API key에 거래 권한이 있고 출금 권한은 없습니다. 거래소에서 지원하는 경우 IP allowlist도 설정합니다.
  4. sudo systemctl kill -s SIGKILL tradingbot로 프로세스를 종료하면 RestartSec 이내에 프로세스가 다시 실행됩니다.
  5. bot을 의도적으로 중지하면 heartbeat monitor가 한 주기 이내에 알림을 보냅니다.
  6. 로그 크기가 제한되어 있고 df -h에서 root filesystem에 여유 공간이 있습니다.

실제 자금을 사용하기 전에 거래소의 sandbox 또는 paper mode에서 전체 시스템을 일주일 동안 실행합니다. 위 항목은 모두 그 일주일 동안 최소 한 번은 실패합니다. 일주일 동안 테스트하는 목적이 바로 이것입니다.

FAQ

트레이딩 봇에 낮은 지연 시간의 서버나 bare metal 서버가 필요합니까?

같은 거래소에서 다른 자동화 참여자와 실행 속도를 경쟁하는 경우에만 필요합니다. 이 경우에는 일반적인 VPS보다 colocation이 일반적입니다. 일반적인 개인 트레이딩 봇에서는 왕복 시간이 지리적 거리와 broker 자체의 처리 시간에 좌우됩니다. 따라서 API endpoint와 가까운 서버를 선택하고, 더 빠른 서버에 비용을 지불하기 전에 curlmtr로 측정합니다.

트레이딩 봇에는 RAM과 CPU가 얼마나 필요합니까?

대부분의 단일 전략 봇은 network-bound 상태이며 이벤트 사이에는 유휴 상태입니다. 2026년 7월 기준으로 2 vCPU와 2 GB RAM이면 수백 개의 instrument를 추적하는 Python 봇을 실행할 수 있습니다. tick history를 프로세스 내부에 보관하거나 로컬 database를 실행하면 memory가 제약 조건이 됩니다. 추측하지 말고 free -h과 journal에서 OOM kill 메시지를 모니터링합니다.

거래소 API가 timestamp 오류와 함께 요청을 거부하는 이유는 무엇입니까?

server clock이 거래소의 signing window를 벗어나도록 drift되었기 때문입니다. 보통 몇 초 정도의 차이입니다. chrony를 설치하고, chronyc tracking에서 작은 System time offset과 동기화된 leap 상태가 표시되는지 확인합니다. 또한 daylight saving 변경으로 시간이 바뀌지 않도록 machine을 UTC로 설정합니다. API key를 교체해도 clock 문제는 해결되지 않습니다.

봇이 실행 중이라는 사실을 모른 채 밤새 중단되는 것을 어떻게 방지합니까?

Restart=alwaysStartLimitIntervalSec=0과 함께 systemd에서 실행합니다. 그러면 crash loop가 영구적으로 중단되지 않고 계속 재시도합니다. 그런 다음 각 성공적인 loop가 끝날 때 봇이 보내는 heartbeat를 추가합니다. restart는 process를 처리합니다. heartbeat는 process가 살아 있지만 멈춘 경우를 감지합니다.

봇과 monitoring을 같은 VPS에서 실행해도 됩니까?

실행할 수는 있지만, 정작 필요한 날에는 monitoring이 잘못된 상태를 보고합니다. 봇을 중단시키는 outage가 monitor도 함께 중단시키기 때문입니다. Alerting은 별도의 machine에 유지합니다. 가능하면 다른 provider 또는 region을 사용합니다. 봇의 server는 봇과 해당 log에만 사용합니다.

#trading#bots#vps#uptime#systemd#monitoring