자동매매 봇의 안전장치 설계

English version

TECH INSIGHT / EXPLAINED

안전장치는 봇이 아는 상태, 허용되는 행동, 요청 결과가 불명확할 때의 복구 방법을 규정해야 합니다. 장치를 갖춰도 전략은 크게 손실 볼 수 있으며, 특정 오류를 줄이는 것이지 손실 한도를 보장하지는 않습니다.

동료 세 명이 주문 안전 상태와 복구 주제를 그림으로 설명하는 모습
이해를 돕기 위한 AI 생성 설명 일러스트. 실제 운영 화면이나 실적 자료가 아닙니다.

실제 프로젝트의 로컬 실행 화면

기존 프로젝트의 화면 또는 함수를 로컬에서 실행해 촬영했습니다. 개인정보 없는 샘플 입력을 사용했으며, 실행한 범위는 각 이미지 아래에 설명했습니다.

실제 프로젝트의 설정 창을 로컬에서 열어 monitor_only, 최대 포지션 수, 자동 진입·청산 항목을 확인했습니다. 값은 샘플이며 저장이나 주문은 실행하지 않았습니다. 이 화면만으로 서버의 안전장치 동작을 검증한 것은 아닙니다.
실제 프로젝트의 설정 창을 로컬에서 열어 monitor_only, 최대 포지션 수, 자동 진입·청산 항목을 확인했습니다. 값은 샘플이며 저장이나 주문은 실행하지 않았습니다. 이 화면만으로 서버의 안전장치 동작을 검증한 것은 아닙니다.
원본 check_caps()의 허용·차단 분기를 가상 수량으로 실행했습니다. 이 버전은 일일·총노출·계좌 비중 제한이 비활성이고 1주 주문에 예외가 있어, 본문이 설명하는 전체 위험 예산을 모두 구현한 것으로 보면 안 됩니다. 주문 전 상태 대사·예약·실제 주문은 실행하지 않았습니다.
원본 check_caps()의 허용·차단 분기를 가상 수량으로 실행했습니다. 이 버전은 일일·총노출·계좌 비중 제한이 비활성이고 1주 주문에 예외가 있어, 본문이 설명하는 전체 위험 예산을 모두 구현한 것으로 보면 안 됩니다. 주문 전 상태 대사·예약·실제 주문은 실행하지 않았습니다.

의도·접수·체결을 구분한다

전송한 진입 주문은 대기 상태이며 이미 체결된 포지션이 아닙니다. 전송 전에 의도 ID와 위험 예산을 저장·예약해 다른 신호가 중복 사용하지 못하게 합니다. 접수 후 주문 ID를, 대사한 체결 후 실제 수량을 갱신하세요. 응답 유실 시 조회한 뒤 재시도합니다. 뮤텍스와 30초 디바운스만으로 재시작이나 지연 응답까지 중복 방지할 수 없습니다.

미보유 -> 진입대기 -> 부분체결/보유
진입대기 + 타임아웃 -> 불명 -> 대사
보유 -> 청산대기 -> 부분체결/미보유
해소되지 않은 차이 -> 신규진입 중지

청산은 관측하는 절차다

세션 종료 전에 신규 진입을 막고 주문·포지션을 대사한 뒤 감소 주문을 내며 실제 남은 수량을 확인합니다. 시장가도 미끄러짐·거절·거래정지로 미체결될 수 있습니다. 무조건 세 번 재주문하면 중복 또는 반대 포지션이 생길 수 있으므로 기존 주문 ID와 지원되는 reduce-only 규칙을 사용합니다. 시각은 모든 시장에 15:20을 적용하지 말고 상품별 거래일·세션으로 정하세요.

임의 임계값 대신 위험 예산을 계산한다

가상의 보유+대기 명목금액 한도가 1,000이고 보유 700, 대기 250이면 새 주문 100은 거절해야 합니다. 아직 포지션 플래그가 없어도 이미 예약한 위험입니다. 스프레드, 전체 주문 수량에 대한 깊이, 시세 나이, 가격 제한을 검사하세요. 임계값은 상품별로 검증하며 필요 수량의 절반만 표시돼도 안전하다는 보편 규칙은 없습니다.

복구와 자격증명

재시작하면 내구성 있는 체크포인트를 읽고 거래소 주문·체결·잔고와 대사한 뒤 신규 진입을 허용합니다. 기준선에는 시장 시간대와 세션을 저장합니다. 자격증명은 OS 저장소 또는 별도로 관리한 암호화 키로 보호하세요. 암호문 옆에 키를 두면 보호가 제한되고 AES-GCM도 오류 확인·nonce 비재사용이 필요합니다. 정지 모드에서도 대사와 긴급 알림은 유지해야 합니다.

부분체결 중 취소를 하나의 사고 훈련으로 만든다

가상의 매수 주문 수량이 10이고 4가 체결됐을 때 나머지를 취소한다고 가정합니다. 취소 요청이 이동하는 동안 2가 더 체결되면 최종 보유는 6, 취소 대상은 나머지 4입니다. 취소 버튼을 누른 순간 보유를 4로 확정하거나 주문 전체의 위험 예약을 풀면 다음 주문이 잘못된 여유 예산을 사용합니다. 취소 요청 접수와 최종 주문 상태를 별도 전이로 취급하세요.

체결을 반영할 때는 확인된 고유 체결 ID를 중복 적용하지 않고, 체결된 부분의 예약을 실제 노출로 전환합니다. 아직 살아 있는 잔량의 예약은 유지하며 취소 확정 뒤 해당 부분만 해제합니다. 수수료가 차감되는 자산과 수량 규칙도 반영해야 하므로 단순 주문 수량 합계만으로 실제 가용 잔고를 확정하지 않습니다.

정지 상태에서도 허용할 행동을 명시한다

동작정지 중 정책의 예
신규 위험 증가차단
주문·체결 조회인증과 조회 경로가 정상일 때 유지
기존 주문 취소대상 신원 확인 후 제한적으로 허용
포지션 감소 요청확인된 수량과 상품 규칙 안에서 판단

'위험 감소'라는 이름을 붙여도 모든 매도 요청이 안전해지지는 않습니다. 이미 제출된 청산 주문이나 다른 프로세스의 주문을 모르고 추가로 보내면 과매도나 반대 포지션이 생길 수 있습니다. 상태 불명이면 먼저 확인 가능한 증거를 모으고, 자동 행동의 범위를 넘는 불일치는 운영자에게 남깁니다. 정지 사유, 발생 시각, 재개 조건도 상태로 보존합니다.

단일 주문 응답을 계좌 전체의 진실로 보지 않는다

빗썸 개별 주문 조회 문서는 주문 식별자로 조회하는 경로를 제공합니다. 이 조회는 주문 하나의 대사에 유용하지만, 수동 주문·다른 봇·입출금이 있는 계좌 전체를 설명하지는 못합니다. 주문 목록, 고유 체결, 잔고를 각각의 관측 시각과 함께 모아 설명 가능한 차이와 설명되지 않는 차이를 나누세요.

서로 다른 시각의 조회 결과는 자동으로 하나의 원자적 스냅샷이 되지 않습니다. 조회 사이에 체결이 발생했다면 관련 구간을 다시 읽고 같은 체결을 두 번 더하지 않는 방식으로 수렴시킵니다. 오래된 상태 응답이 뒤늦게 도착했을 때 최신 체결 수량을 덮어쓰지 않도록 버전·조회 시작 시각·제공되는 순서 정보를 함께 사용합니다.

복구 훈련에는 재개를 거절하는 성공도 있다

오프라인 모의 실행에는 제출 직후 종료, 취소 중 추가 체결, 중복 체결 통보, 순서가 뒤바뀐 조회, 수동 주문으로 생긴 잔고 차이를 넣습니다. 각 단계에서 신규 주문 수, 확인된 보유, 살아 있는 예약, 미해결 의도를 검사하세요. 불명 주문이 남은 상태에서 재시작을 여러 번 해도 주문 수가 늘지 않아야 합니다.

재개는 단순한 오류 카운터 초기화가 아닙니다. 시세 신선도, 주문·잔고 일치, 위험 설정 버전, 필수 기능 상태를 다시 확인하고 어떤 증거로 재개했는지 기록합니다. 해결되지 않은 차이가 있으면 신규 진입을 계속 막는 결과가 올바른 시험 통과일 수 있습니다. 이 절차는 가상의 실패를 다루는 설계이며 수익이나 최대 손실을 보장하는 실거래 성과가 아닙니다.

공식 문서와 이어 읽기

내용·예제 검토: 2026-10-01

댓글