NOONOO TRADING무료 채팅방 입장

중복 주문 — 응답이 안 온 주문을 다시 내면 포지션이 두 배가 된다

주문 버튼을 눌렀는데 화면이 멈춥니다. 몇 초 기다려도 아무 반응이 없습니다. 대부분은 여기서 한 번 더 누릅니다. 자동매매 코드도 똑같이 합니다 — 응답이 없으면 실패로 보고 다시 보냅니다. 문제는 첫 번째 주문이 이미 체결됐을 수 있다는 점입니다.

"응답이 없다"는 "주문이 안 갔다"가 아니다

주문 요청은 두 방향으로 움직입니다. 내가 거래소로 보내는 길과, 거래소가 나에게 결과를 알려주는 길입니다. 이 중 돌아오는 길만 끊겨도 화면에는 똑같이 아무것도 안 보입니다.

응답 없음의 세 가지 실제 상태

① 요청이 거래소에 못 갔다
  → 주문 없음 · 재시도해도 안전

② 거래소가 받고 처리 중이다
  → 주문 생길 예정

③ 이미 체결됐는데 응답만 유실
  → 주문 있음 · 재시도하면 두 개

─────────────
내 쪽에서 보이는 화면
  세 경우 모두 똑같다
  (타임아웃 · 빈 응답)

①만 골라서 재시도할 방법은 없습니다. 구별이 안 되기 때문입니다. 이것은 웹소켓 끊김에서 다룬 문제와 뿌리가 같습니다 — 침묵은 정보가 아닙니다. 그런데 주문은 시세 조회와 달리 돈이 움직이는 요청이라, 한 번 더 보내는 것의 대가가 다릅니다.

재시도 한 번이 만드는 숫자

같은 요청을 두 번 보냈는데 둘 다 성공하면, 계좌에는 계획의 두 배가 들어옵니다. 배율이 붙은 계약이면 여기서 청산가까지 같이 움직입니다.

0.1 계약이 0.2가 되는 경우

계획
  BTC 롱 0.1 · 진입 100,000
  노셔널 10,000 · 20배
  증거금 500

1차 주문 → 응답 타임아웃
2차 주문 → 성공 응답

실제 체결
  0.1 + 0.1 = 0.2 계약
  노셔널 20,000
  증거금 1,000 (2배)

─────────────
가격이 −3% 갈 때
  계획대로면 손실 −300
  실제 손실 −600

봇 내부 기록
  0.1 계약이라고 적혀 있다

손실이 두 배가 된 것보다 더 나쁜 것은 마지막 줄입니다. 내부 기록에는 0.1만 남아 있으므로, 봇이 청산할 때도 0.1만 닫습니다. 나머지 0.1은 아무도 관리하지 않는 상태로 계좌에 남습니다. 봇은 포지션이 없다고 믿고 다음 신호에서 새로 진입하고, 그 사이 방치된 물량은 계속 손익이 흔들립니다.

청산가도 앞당겨집니다. 증거금 대비 노셔널이 두 배가 되면 같은 잔고로 버틸 수 있는 하락폭이 절반으로 줄어듭니다. 손절 계산을 아무리 정확히 해뒀어도, 수량이 계획과 다르면 그 계산은 처음부터 다른 이야기가 됩니다.

해결의 핵심 — 주문에 내가 이름표를 붙인다

대부분의 거래소는 주문을 낼 때 내가 직접 정한 식별자를 같이 보낼 수 있습니다. 흔히 클라이언트 주문번호라고 부릅니다. 같은 식별자로 두 번 보내면 거래소가 두 번째를 거절합니다.

이름표가 있을 때와 없을 때

없을 때
  1차 "롱 0.1 사줘" → 체결
  2차 "롱 0.1 사줘" → 또 체결
  거래소 입장 = 다른 주문 두 개

있을 때
  1차 "롱 0.1 · 이름 bot-9f3a" → 체결
  2차 "롱 0.1 · 이름 bot-9f3a"
  → 중복 오류로 거절

─────────────
이름 짓는 법
  · 그 거래 하나에 고정
  · 재시도해도 바뀌지 않아야 한다
  · 시각·난수만으로 만들면 안 된다
    (재시도마다 새 이름 = 이름표 없는 것)

여기서 가장 자주 하는 실수가 마지막 줄입니다. 식별자를 보낼 때마다 새로 만들면 이름표를 붙인 의미가 사라집니다. 재시도는 같은 주문을 다시 시도하는 것이므로, 이름도 같아야 합니다. 신호가 발생한 시점에 이름을 한 번 만들어 저장해두고, 재시도할 때는 그 저장된 이름을 그대로 씁니다.

거절 응답이 오면 그것은 실패가 아니라 "이미 접수됐다"는 확인입니다. 중복 오류를 일반 오류와 같이 처리해 또 재시도하면 원점입니다. 오류 코드를 구분해서, 중복이면 성공으로 간주하고 넘어가야 합니다.

이름표를 못 쓸 때 — 재시도 전에 물어본다

거래소나 라이브러리에 따라 클라이언트 주문번호를 못 쓰는 경우도 있습니다. 그럴 때 순서는 하나뿐입니다 — 다시 보내기 전에 먼저 조회합니다.

안전한 재시도 순서

주문 전송 → 응답 없음
  ↓ 1~2초 대기
미체결 주문 목록 조회
최근 체결 내역 조회
  ↓
내가 의도한 주문이 있나?
  있다 → 재시도 안 함 · 기록만 갱신
  없다 → 그때 다시 보냄

─────────────
절대 하면 안 되는 것
  응답 없음 → 즉시 재전송
  → 실패하면 또 재전송
  → 3회 반복 = 최대 3배 포지션

"의도한 주문"을 알아보려면 방향·수량·가격·시각을 함께 봐야 합니다. 이 조회 과정 자체가 요청을 늘리므로 요청 한도 초과(429)에 걸리지 않게 간격을 둡니다. 다만 한도에 걸리는 비용과 포지션이 두 배가 되는 비용은 비교 대상이 아닙니다 — 조회를 생략하는 쪽이 항상 더 비쌉니다.

취소와 재주문이 겹치는 순간

지정가를 걸어두고 가격이 멀어지면 취소 후 다시 거는 방식을 많이 씁니다. 이 두 동작 사이에 시간 차가 있고, 그 틈에서 어긋납니다.

취소–재주문 경쟁

12:00:00 지정가 롱 99,000 접수
12:00:04 가격 이동 → 취소 요청
12:00:04 거의 동시에 체결
12:00:05 취소 응답 = "그런 주문 없음"
12:00:05 봇 판단 = 취소됐구나
12:00:05 새 지정가 98,500 접수

─────────────
결과
  99,000 체결분 + 98,500 대기
  봇이 아는 포지션 = 0

대책
  취소 실패·모호 응답 → 재주문 금지
  → 포지션 조회부터 다시

"취소했으니 없겠지"는 가정입니다. 취소 응답이 애매하면 새 주문을 내는 대신 실제 상태를 확인하는 쪽으로 갑니다. 이렇게 벌어진 기록과 실제의 차이를 주기적으로 맞추는 방법은 포지션 대조에 정리돼 있습니다. 부분 체결이 섞이면 더 복잡해집니다 — 0.1 중 0.04만 체결된 상태에서 재주문하면 수량이 어중간하게 남습니다.

사람과 프로세스가 만드는 중복

네트워크만 문제가 아닙니다. 같은 봇을 두 번 실행해두는 것만으로 모든 주문이 두 배가 됩니다.

흔한 이중 집행

· 코드를 고치고 새로 켰는데
  예전 프로세스가 안 죽었다

· PC와 서버에서 같은 봇을 돌린다

· 화면이 멈춰 보여 버튼을 두 번 눌렀다

· 재시작 스크립트가 중복 실행 검사를 안 한다

─────────────
증상
  · 모든 거래 수량이 정확히 2배
  · 로그에 같은 신호가 두 줄
  · 수수료가 예상의 2배

대책
  실행 시작 시 중복 실행 검사
  이미 돌고 있으면 즉시 종료

이 유형은 처음 며칠 동안 눈에 잘 안 띕니다. 수익이 두 배로 보이기 때문입니다. 손실 구간에 들어가서야 드러납니다. 자동매매를 켤 때 프로세스가 몇 개 떠 있는지 확인하는 습관이 필요합니다.

점검 항목

연동 방식과 인증은 거래소 API 연동 가이드에, 키 관리는 API 키에 정리돼 있습니다. 중복 주문에 한정하면 아래가 전부입니다.

넣어둘 것

· 주문마다 고정된 이름표 부여
· 재시도 때 같은 이름 재사용
· 중복 오류는 성공으로 처리
· 이름표를 못 쓰면 조회 후 재시도
· 재시도 횟수 상한을 둔다
· 취소 응답이 모호하면 재주문 금지
· 시작 시 중복 실행 검사
· 주기적으로 실제 포지션과 대조

─────────────
기억할 한 줄
  주문은 조회와 다르다
  다시 물어보는 것은 공짜지만
  다시 내는 것은 공짜가 아니다

실수했을 때 되돌리기 쉬운 순서로 검증합니다. 소액으로 일부러 타임아웃을 만들어 보고, 그 상태에서 재시도 로직이 주문을 하나만 남기는지 확인합니다. 실전 수량에서 처음 시험하면 확인 비용이 포지션 크기만큼 커집니다.

정리

응답 없음은 주문 실패를 뜻하지 않는다
안 감·처리 중·이미 체결이 화면상 똑같다
재시도 한 번이면 수량·증거금이 2배
내부 기록은 1배라 절반이 방치된다
수량이 다르면 손절 계산이 무의미해진다
주문에 고정 이름표를 붙이면 거래소가 막아준다
재시도마다 이름을 새로 만들면 효과 없음
중복 오류는 실패가 아니라 접수 확인
이름표가 없으면 조회 → 재시도 순서
취소 응답이 애매하면 재주문하지 않는다
봇 이중 실행은 모든 주문을 2배로 만든다

한 줄로 줄이면 이렇습니다. 같은 요청을 몇 번 보내도 결과가 한 번인 구조를 먼저 만들어두면, 네트워크가 흔들려도 계좌는 흔들리지 않습니다. 전략을 다듬는 일은 그다음입니다.

주의

본문의 수량, 가격, 증거금, 배율, 대기 시간은 구조를 설명하기 위한 가정 예시이며 특정 거래소의 실제 측정값이 아닙니다. 클라이언트 주문번호의 이름·글자 수 제한·유효 기간, 중복 시 반환되는 오류 코드, 취소 응답 규격, 조회 한도는 거래소마다 다르므로 본인이 쓰는 거래소 문서에서 확인하고 소액으로 직접 시험해야 합니다. 레버리지 거래는 원금 전액을 잃을 수 있으며, 투자 판단과 그 결과는 본인 책임입니다.

NOONOO TRADING 무료 채팅방에서 실시간 트레이딩을 같이 보세요.

무료 채팅방 입장 →

📈 OKX 신규 가입 시 거래 수수료 할인

OKX 수수료 할인 가입 →