증권사 OpenAPI 세션 만료 및 웹소켓 재접속(Keep-Alive) 자동 복구 데몬 스레드 설계

아키텍처 요약 및 실전 엔지니어링 개요

국내 주요 증권사의 OpenAPI는 24시간 연속 가동을 염두에 두고 설계되지 않았습니다. OAuth 2.0 접근 토큰(Access Token)은 통상 24시간 후 만료되며, 실시간 시세를 수신하는 웹소켓(WebSocket) 세션은 통신사 회선 지연이나 증권사 메인프레임 점검 시 아무런 예고 없이 일방적으로 끊어집니다. 본 리포트에서는 토큰 만료 1시간 전 무중단 백그라운드 사전 갱신(Token Pre-refresh)과 네트워크 단절 시 지수 백오프(Exponential Backoff)를 적용한 자동 재접속 하트비트 데몬의 완전한 설계 명세를 분석합니다.

1. OAuth 접근 토큰의 생명주기와 비동기 사전 갱신 메커니즘

가장 어처구니없는 트레이딩 봇의 장애 중 하나는 급박한 손절 타이밍에 `EGW00123: 토큰이 만료되었습니다` 에러를 반환받으며 주문이 거부되는 상황입니다. 토큰이 만료된 후에야 새로운 토큰을 발급받으려고 REST 요청을 보내면 1~2초의 지연이 발생하여 타이밍을 완전히 놓치게 됩니다.

[Token Lifecycle Manager] ──(TTL Monitor: Every 60s)──> [Check Remaining Seconds]
│
(If TTL < 3600s: Pre-Refresh) ▼ [Async Token Exchanger] ───(Issue New Token in Background)───> [Atomic Swap in Memory]

따라서 토큰의 남은 유효 시간(TTL)을 주기적으로 감시하다가, 만료 60분 전에 백그라운드 비동기 태스크로 신규 토큰을 발급받아 메모리의 활성 토큰 포인터를 원자적(Atomic)으로 교체하는 무중단 토큰 스왑 파이프라인이 필수적입니다.

토큰 관리 방식 만료 직전 반응 주문 집행 지연시간 세션 안정성
수동/하드코딩 토큰 24시간 후 무조건 전체 시스템 마비 주문 전면 실패 극도로 위험
사후 갱신 (에러 발생 시 재발급) 주문 실패 후 토큰 발급 (1~2초 랙) 1,800~2,400 ms 지연 발생 불안정 (슬리피지 심각)
사전 갱신 (만료 1시간 전 자동 스왑) 사용자는 만료 자체를 인지 못함 0.00 ms (지연 제로) 100% 무중단 연속 가동

2. 실시간 웹소켓 핑퐁(Ping-Pong) 및 자동 재접속(Reconnection) 데몬

웹소켓은 TCP 연결이 살아있더라도 중간 라우터나 NAT 게이트웨이가 비활성 연결을 강제로 끊어버리는 현상(Silent Disconnect)이 발생합니다. 클라이언트는 연결이 살아있다고 착각하지만 실제로는 더 이상 틱 데이터가 들어오지 않는 ‘고스트 세션’ 상태입니다. 이를 방지하기 위해 30초 주기의 애플리케이션 레벨 하트비트 핑을 교환하고, 지수 백오프 알고리즘으로 자동 재접속을 집행해야 합니다.

# 실전 무중단 웹소켓 재접속 데몬 (보안 마스킹 규격 준수)
import asyncio
import os
import websockets
import json

class ResilientWebSocketClient:
    def __init__(self, symbol="005930"):
        self.symbol = symbol
        self.ws_url = "ws://ops.koreainvestment.com:21000/tryitout/H0STASP0"
        self.approval_key = os.environ.get("KIS_APPROVAL_KEY", "MASKED_KEY")
        self.is_running = True

    async def run_resilient_loop(self):
        backoff_delay = 1.0 # 초기 재시도 대기시간 1초
        max_backoff = 30.0

        while self.is_running:
            try:
                print(f"[WS] Connecting to KIS server...")
                async with websockets.connect(self.ws_url, ping_interval=20, ping_timeout=10) as ws:
                    print(f"[WS] Connected successfully! Resetting backoff.")
                    backoff_delay = 1.0 # 연결 성공 시 백오프 리셋
                    
                    # 호가 등록 패킷 전송
                    sub_msg = {"header": {"approval_key": self.approval_key, "tr_type": "1"}, "body": {"input": {"tr_id": "H0STASP0", "tr_key": self.symbol}}}
                    await ws.send(json.dumps(sub_msg))
                    
                    while True:
                        msg = await ws.recv()
                        self.on_tick_received(msg)
                        
            except (websockets.ConnectionClosed, asyncio.TimeoutError, Exception) as e:
                print(f"[WS WARNING] Connection lost: {e}. Reconnecting in {backoff_delay:.1f}s...")
                await asyncio.sleep(backoff_delay)
                # 지수 백오프 (Exponential Backoff with Jitter)
                backoff_delay = min(backoff_delay * 1.5, max_backoff)

    def on_tick_received(self, raw_msg):
        # 틱 수신 시 하트비트 타임스탬프 갱신
        pass

3. 증권사 일일 서버 리셋(점검 시간) 대응 스케줄러

국내 증권사 서버는 매일 새벽(통상 05:00~06:30)과 장 마감 후 정기 배치 작업을 위해 시스템을 일시 셧다운합니다. 이 시간대에 무의미하게 재접속을 1초마다 시도하면 증권사 방화벽(IP 차단)에 블랙리스트로 등록될 위험이 있습니다. 시장 운영 시간(오전 8시 30분 ~ 오후 4시)을 인지하는 스마트 스케줄러를 탑재하여 불필요한 네트워크 트래픽을 지능적으로 차단해야 합니다.

시간대 (KST 기준) 시장 상태 트레이딩 시스템 운영 모드 웹소켓 연결 정책
05:00 ~ 07:00 증권사 메인프레임 정기 점검 슬립 모드 (Sleep Mode) 소켓 강제 종료 및 폴링 중단
08:00 ~ 08:30 장 시작 전 준비 시간 토큰 사전 발급 및 헬스체크 단일 핑 검증 후 소켓 대기
08:30 ~ 15:30 정규 장 및 시간외 단일가 실전 초고속 HFT 가동 무중단 스트리밍 및 0.01초 감시
16:00 ~ 익일 05:00 장 마감 후 야간 분석 당일 거래 틱 데이터 DB 백업 및 통계 소켓 안전 종료 (Idle)

4. 결론: 영구 세션 유지를 위한 3중 방어막 구축

안정적인 세션 관리의 핵심은 ‘토큰 사전 갱신’, ‘지수 백오프 자동 재접속’, ‘장외 시간 지능형 휴면’의 3중 방어막입니다. 이 인프라가 갖추어져야만 사람이 매일 아침 HTS를 켜고 로그인할 필요 없이, 365일 스스로 켜지고 꺼지며 무결점 거래를 집행하는 완벽한 자율 트레이딩 에이전트를 완성할 수 있습니다.

실무 엔지니어링 팁: IP 변경 감지와 모바일 핫스팟 테더링 백업

유선 인터넷 회선 장애 시 시스템이 완전히 마비되는 것을 방지하기 위해, 라우터 장애 감지 즉시 LTE/5G USB 동글이나 모바일 핫스팟으로 기본 게이트웨이(Default Route)를 자동 전환하는 멀티 WAN 페일오버(Multi-WAN Failover) 라우팅을 구축하면 통신사 장애 상황에서도 안전하게 포지션을 청산할 수 있습니다.

댓글 남기기