🌐 Read in English → English version
📚 토스 자동매매 개발기 시리즈 (Phase 7-4 / 전체 22편 중)
- #0 토대 구축 (Phase 0)
- #0-1 통화 버그 수정 (Phase 0-1)
- #3 설정 분리 및 재시도 로직 통합 (Phase 1)
- #4 설정·재시도 후속 개선 (Phase 1-2)
- #5 pytest 테스트 도입 (Phase 1-3)
- #6 로그 로테이션 적용 (Phase 1-4)
- #7 전략 클래스 설계 (Phase 2-1)
- #8 다종목 모니터링 구현 (Phase 2-2)
- #9 데이터 영속성 설계 (Phase 3-1)
- #10 DB 모듈 구현 (Phase 3-2)
- #11 DB 통합 (Phase 3-3)
- #12 전략 플러그인 인터페이스 (Phase 2-3)
- #13 백테스트 엔진 구축 (Phase 4)
- #14 캔들 API 페이지네이션 처리 (Phase 4)
- #15 읽기 전용 대시보드 구축 (Phase 5)
- #16 텔레그램 제어 로직 구현 (Phase 5)
- #17 텔레그램 제어 로직 개선 (Phase 5)
- #18 스케줄러 워치독 구현 (Phase 6)
- #19 주문 한도 가드 구현 (Phase 7)
- #20 손실 한도 자동 일시정지 (Phase 7)
- #21 알림 이중화 1차 구현 (Phase 7-3)
← 이전 글: #21 알림 이중화 1차 구현 | 다음 글: 발행 전(추후 업데이트)
💡 이번 Phase 7-4 요약
- 목적: 실전 가동 직전 API 권한·보안 상태를 비파괴로 종합 진단하고, 알림 시스템의 단일점 장애를 없앰
- 핵심 포인트: 5중 안전 브레이크 상태를 코드가 아니라 진단 스크립트로 매번 자동 검증
- 검증: 실제 토스증권 Open API 연동 진단 성공, pytest 단위 테스트 140개 100% 통과
이번 글은 토스증권 자동매매 봇에 자동매매 보안 진단 모듈을 처음부터 어떻게 만들었는지, 그리고 알림 이중화를 어떻게 마무리했는지에 대한 기록이다. 배포 스크립트를 돌리기 전에 항상 똑같은 불안감이 있었다. “혹시 .env 파일이 커밋에 껴 있으면 어쩌지”, “안전장치 하나가 꺼진 채로 배포되면 어쩌지” 같은 생각들. 매번 눈으로 하나씩 체크리스트를 확인하는 게 지겨워져서, 이번엔 그 체크리스트 자체를 스크립트로 만들기로 했다.
왜 지금 자동매매 보안 진단이 필요했나
지금까지 DRY_RUN, 목표가 제한, 주문 수량 상한 같은 안전장치들은 코드 안에 흩어져 있었다. 문제는 이게 “코드에 존재한다”는 것과 “지금 이 순간 실제로 켜져 있다”는 게 다른 얘기라는 점이었다. 배포 직전에 실수로 값을 바꿔놓고 그대로 커밋해버리면 아무도 모르고 지나갈 수 있는 구조였다. 그래서 자동매매 보안 진단을 별도 모듈로 만들어 매번 실제 상태를 검사하기로 했다.
security_check.py — 비파괴 종합 진단
환경변수 & Git 노출 점검
.env 파일이 실제로 존재하는지, 그리고 .gitignore에 등록되어 있는지를 먼저 확인한다. 이 두 개가 빠지면 나머지 진단은 아예 의미가 없기 때문에 가장 먼저 체크한다.
def check_env_git_safety():
issues = []
if not os.path.exists(".env"):
issues.append("WARNING: .env 파일이 존재하지 않음")
with open(".gitignore", "r") as f:
gitignore_content = f.read()
if ".env" not in gitignore_content:
issues.append("CRITICAL: .env가 .gitignore에 등록되어 있지 않음")
return issues
5중 안전 브레이크 상태 검증
다음 다섯 가지가 실제로 “켜져 있는 상태”인지를 하나씩 확인하고 콘솔에 표로 출력한다.
DRY_RUN = True(시뮬레이션 모드 여부)TARGET_BUY_PRICE = 1(체결 불가 목표가로 고정돼 있는지)MAX_ORDER_QUANTITY_PER_TRADE(1회 주문 수량 상한, 가상 예시로 10주 이하 설정)MAX_CUMULATIVE_LOSS_PCT(누적 평가손실 한도, 가상 예시로 10% 설정)requests.post실제 주문 API 호출부가 주석 처리돼 있는지 정규식으로 검사
여기서 중요한 건 “값이 맞는지”가 아니라 “지금 이 순간 실제로 그렇게 되어 있는지”를 매번 다시 확인한다는 점이다. 설정값을 믿지 않고 실제 상태를 검사하는 쪽으로 방향을 잡았다.
API 토큰 & 권한 비파괴 진단
OAuth2 토큰 발급이 정상적으로 되는지, 계좌 일련번호(가상 예시: 삼성전자 005930 연동 계좌)가 제대로 연결됐는지, 시세 조회 권한이 있는지를 실제 주문 없이 확인한다. 진단 결과는 콘솔에 성공/실패 리포트로 출력된다.
notifier.py — 알림 이중화 최종 완비
기존에는 auto_trader.py 안에 알림 로직이 그대로 박혀 있었다. 이번에 이걸 전담 모듈로 분리하면서 두 가지를 같이 해결했다.
Best-Effort 예외 흡수
def send_alert(level, message):
try:
send_telegram(message)
except Exception as e:
log_error(f"Telegram failed: {e}")
if level in ("WARNING", "ERROR", "CRITICAL"):
try:
send_email(message)
except Exception as e:
log_error(f"SMTP failed: {e}")
# 알림이 실패해도 감시 엔진은 절대 멈추지 않는다
텔레그램이든 SMTP든 알림 발송 자체가 실패해도 매매 감시 엔진과 백그라운드 스케줄러는 계속 돌아가야 한다는 원칙을 코드로 강제했다.
등급별 이중 발송
INFO는 텔레그램+DB 기록만, WARNING/ERROR/CRITICAL은 텔레그램과 이메일 두 채널로 동시에 발송한다. 텔레그램 하나에만 의존하다가 API 장애로 알림을 못 받는 상황을 막기 위한 이중화다.
risk_control.py 연동
누적 평가손실이 한도(가상 예시 10%)를 넘으면 감시를 자동으로 일시정지하고, 이메일+텔레그램으로 비상 알림을 동시에 쏘도록 연동했다.
검증: Real API 진단 + pytest 140개
실제 토스증권 Open API 환경에서 자동매매 보안 진단 스크립트를 돌려 성공적으로 리포트를 받았고, pytest 단위 테스트 총 140개가 전부 통과했다. 여기까지 오면서 하나씩 쌓인 테스트라 숫자를 보니 확실히 뿌듯했다.
다음 단계
자동매매 보안 진단과 알림 이중화까지 갖췄으니, 다음은 실제 모의투자 환경에서의 장기 안정성 테스트를 계획 중이다.
“자동매매 보안 진단 완벽 구축 | 토스 개발기 #22”에 대한 3개의 생각