자동매매 보안 진단 완벽 구축 | 토스 개발기 #22

🌐 Read in English → English version

💡 이번 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개의 생각

댓글 남기기