자동매매 봇 대시보드 구축하기 | 토스 개발기 #24

🌐 Read in English

💡 이번 Phase 7-6 요약

  • 목적: 감시 봇 재시작 없이 브라우저에서 조작하는 자동매매 봇 대시보드 구축
  • 핵심 포인트: SQLite strategy_configs 테이블을 매 감시 주기마다 읽어와 엔진에 즉시 반영하는 구조 설계
  • 검증: pytest 단위 테스트 130개 100% 통과, 실제 API 토큰 연동 진단 성공

지금까지 이 봇은 목표가 하나 바꾸려면 코드를 고치고 재시작해야 했어. 그래서 이번 Phase에서는 자동매매 봇 대시보드를 만들어서, 브라우저에서 조건을 바꾸면 감시 엔진이 재시작 없이 그걸 그대로 흡수하는 구조로 뜯어고쳤어.

자동매매 봇 대시보드 구축하기 (dashboard.py, db.py)

제일 먼저 SQLite에 strategy_configs 테이블을 새로 만들었어. 종목코드, 매수 목표가, 주문 수량, 익절 비율, 손절 비율을 여기 저장해두고 auto_trader.py가 매 감시 주기마다 이 테이블을 다시 읽는 방식이야.

대시보드 자체는 FastAPI 공식 문서 기준으로 구현했고, 폼 입력을 처리하려고 python-multipart 패키지를 새로 붙였어. 엔드포인트는 이렇게 나눴어:

POST /api/strategies      # 조건 추가/수정
DELETE /api/strategies/delete   # 조건 삭제

이 자동매매 봇 대시보드의 핵심은 “엔진이 DB를 신뢰의 원천(source of truth)으로 삼는다”는 점이야. 대시보드는 그냥 DB에 값을 쓰기만 하고, 실제 반영은 감시 루프가 다음 주기에 알아서 읽어가는 식이라 웹서버와 트레이딩 엔진이 서로 강하게 결합되지 않아.

가상 매수-매도(익절/손절) 라이프사이클 검증

DRY_RUN = True 상태를 유지한 채로, 삼성전자(005930) 목표가 도달 시 가상 매수 → 실시간 수익률 계산 → 익절(+5%) 또는 손절(-3%) 도달 시 가상 매도까지 전체 사이클을 돌려봤어. 매도가 발생하면 trades 테이블에 기록이 남고, 대시보드에서 그 이력을 바로 확인할 수 있어.

SK하이닉스(000660)로도 같은 흐름을 돌려서 종목이 여러 개일 때도 각자 독립적으로 상태가 관리되는지 확인했어. 실제 계좌 정보와 손익 수치는 전부 가상값으로 대체했어.

알림 이중화 모듈 리팩터링 (notifier.py)

원래 auto_trader.py 안에 흩어져 있던 알림 로직을 notifier.py로 분리했어. 등급별로 라우팅이 갈리는데:

  • INFO → 텔레그램 + DB 기록만
  • WARNING / ERROR / CRITICAL → 텔레그램 + 이메일(SMTP) 이중 발송

여기서 중요했던 설계는 “best-effort” 원칙이야. 텔레그램 API가 타임아웃 나거나 SMTP 서버가 죽어도 예외를 흡수해서 감시 엔진이나 백그라운드 스케줄러는 절대 멈추지 않게 처리했어.

종합 보안 진단 스크립트 (security_check.py)

security_check.pySQLite 공식 문서.env 관리 방식을 참고해서 만든 비파괴 진단 도구야. 체크 항목은:

  • .env 파일 존재 여부와 .gitignore 등록 여부 (Git 노출 방지)
  • 5중 안전 브레이크 상태: DRY_RUN=True, TARGET_BUY_PRICE=1원, MAX_ORDER_QUANTITY_PER_TRADE=10주, MAX_CUMULATIVE_LOSS_PCT=10%, 주문 API 물리적 차단
  • OAuth2 토큰 발급 및 계좌 연결 상태, 시세 조회 API 접근 권한
실제 API 토큰으로 진단을 돌렸을 때 5중 브레이크가 전부 정상 작동 중임을 콘솔 리포트로 확인했어.

pytest 130개 검증

대시보드 API, DB 트랜잭션, 알림 라우팅, 보안 진단 로직까지 포함해서 pytest 단위 테스트를 돌렸고 총 130개가 100% 통과했어. python-multipart 연동 부분도 별도 테스트 케이스로 커버했어.

다음 단계

다음 Phase에서는 이 자동매매 봇 대시보드에 실시간 손익 그래프를 붙이고, 다중 계정 확장 가능성을 검토해볼 예정이야.

FAQ

Q1. 대시보드에서 조건을 바꾸면 바로 반영되나요?

즉시는 아니고, 다음 감시 주기(다음 루프)에 DB에서 다시 읽어오면서 반영돼. 재시작은 필요 없어.

Q2. DRY_RUN 상태에서는 실제 돈이 움직이나요?

아니야. DRY_RUN=True일 때는 실제 주문 API 호출 자체가 물리적으로 차단돼 있어서 전부 가상 거래로만 처리돼.

Q3. python-multipart는 왜 필요한가요?

FastAPI가 HTML 폼(form-data) 요청을 파싱하려면 이 패키지가 필요해. 대시보드의 조건 입력 폼이 이 방식으로 데이터를 보내.

Q4. 알림 이메일이 안 오면 봇이 멈추나요?

아니야. notifier.py는 best-effort 방식이라 SMTP 발송이 실패해도 예외를 흡수하고 감시 엔진은 계속 돌아가.

댓글 남기기