바이낸스
바이낸스 Execution Report 뜻 2026|주문 상태·부분 체결·평균 가격 읽기
Spot executionReport의 사건과 상태, 이번 체결량과 누적 체결량을 구분합니다. 평균 가격 Z/z, 수수료 자산, STP 조건부 필드와 재연결 후 대조 절차를 정리했습니다.

바이낸스 Execution Report 뜻 2026|주문 상태·부분 체결·평균 가격 읽기
바이낸스 Execution Report는 Spot User Data Stream에서 주문 변화를 전달하는 executionReport 이벤트입니다. 주문을 접수했다는 사실, 일부가 체결됐다는 사실, 취소나 만료가 발생했다는 사실을 구분해서 읽는 데 사용합니다. 이름에 Execution이 들어가지만 모든 메시지가 새로운 체결을 뜻하지는 않습니다.
자동 주문 프로그램은 주문 전송에 성공하는 것만큼 실행 결과를 정확하게 반영하는 일이 중요합니다. 부분 체결을 전량 체결로 오해하거나, 누적 수량을 매번 더하거나, 취소 메시지를 보고 과거 체결까지 지워버리면 내부 잔고와 실제 계정 상태가 달라질 수 있습니다.
이 글은 Binance Spot User Data Stream의 JSON 주문 업데이트를 기준으로 설명합니다. 2026년 10월 27일 공식 개발 문서를 확인했습니다. 선물 스트림의 이벤트 이름이나 필드를 현물과 동일하다고 가정하지 않으며, 예시 숫자는 실제 거래가 아닌 설명용입니다.
가장 먼저 볼 필드
| 필드 | 공식 의미 | 읽는 관점 |
|---|---|---|
| e | 이벤트 종류 | executionReport인지 구분 |
| s | 심볼 | 어느 거래쌍인가 |
| c·i | clientOrderId·orderId | 어느 주문인가 |
| x | 현재 execution type | 이번에 어떤 변화가 생겼나 |
| X | 현재 order status | 변화 후 주문 상태가 무엇인가 |
| l·z | 이번 체결 수량·누적 체결 수량 | 증분과 누적을 구분 |
| L·Z | 이번 체결 가격·누적 quote 금액 | 마지막 가격과 평균의 차이 |
특히 소문자 x와 대문자 X, 소문자 l과 z, 대문자 L과 Z를 같은 것으로 취급하지 않는 것이 중요합니다. 필드가 짧다고 의미가 가벼운 것은 아닙니다. 대소문자를 보존해 파싱하고 내부에서는 설명적인 이름으로 매핑하는 편이 읽기 쉽습니다.
1. executionReport는 어디서 오는가
공식 User Data Stream 문서는 API 키를 사용하는 WebSocket API 구독과 계정 이벤트 전달을 안내합니다. 현재 JSON 예시에는 subscriptionId와 그 안의 event 객체 구조가 제시됩니다. 사용하는 연결 방식과 현재 스키마를 확인해야 합니다.
인터넷의 오래된 예제는 예전 연결 방식이나 다른 감싸기 구조를 전제로 할 수 있습니다. 필드 이름 몇 개가 같다는 이유로 전체 메시지 모양까지 동일하다고 가정하지 마세요. 실제 사용하는 API 버전과 공식 스키마를 기준으로 파서가 어떤 객체를 읽는지 점검합니다.
이 스트림은 공개 가격 스트림과 목적이 다릅니다. 공개 거래 데이터에서 체결이 보였다고 자신의 주문이 체결됐다는 뜻은 아닙니다. 본인 계정의 주문 식별자와 계정 이벤트를 연결해야 합니다. 시장 전체의 거래와 개인 주문 실행을 분리하는 것이 출발점입니다.
REST 응답과의 관계
REST 주문 응답은 요청에 대한 응답이고, executionReport는 주문 변화에 대한 이벤트입니다. 둘 중 하나를 받았다는 이유로 다른 경로의 기록을 무조건 버리거나 별개의 주문으로 저장하면 안 됩니다. 같은 주문을 가리키는지 식별자를 통해 연결해야 합니다.
응답이 늦거나 유실된 경우에도 스트림에서 상태를 확인할 수 있는 상황이 있습니다. 반대로 스트림이 끊어지면 공식 조회 경로로 상태를 대조해야 할 수 있습니다. 어느 한 경로가 항상 완벽하게 모든 장애를 해결한다고 보장하지 않습니다.
2. x와 X: 사건과 상태
소문자 x는 이번 실행 유형이고, 대문자 X는 현재 주문 상태입니다. 예를 들어 체결이라는 사건이 발생해도 주문 전체는 아직 PARTIALLY_FILLED일 수 있습니다. 사건이 TRADE라고 해서 곧바로 주문 전체가 FILLED라고 판단하면 안 됩니다.
주문을 하나의 작업이라고 보면 x는 “이번에 무엇이 일어났나”, X는 “그 뒤 전체 작업이 어떤 상태인가”에 가깝습니다. 이 둘을 한 필드로 합치면 부분 체결과 최종 완료, 취소와 만료 등의 차이를 표현하기 어렵습니다.
공식 ENUM 문서는 NEW, PARTIALLY_FILLED, FILLED, CANCELED, REJECTED, EXPIRED, EXPIRED_IN_MATCH 같은 주문 상태를 설명합니다. 현재 문서에 있는 다른 상태도 사용하는 주문 종류에 따라 확인해야 합니다. 임의로 모든 상태를 성공·실패 두 값으로 줄이지 않습니다.
상태가 의미하는 것과 의미하지 않는 것
NEW는 주문이 엔진에 받아들여졌다는 의미이지 체결이 완료됐다는 의미가 아닙니다. PARTIALLY_FILLED는 일부가 체결된 상태이고, FILLED는 주문이 완료된 상태입니다. CANCELED는 취소 상태이지만 이전 체결량을 0으로 만들라는 뜻은 아닙니다.
EXPIRED는 주문 종류의 규칙이나 거래소 처리에 따른 종료와 관련될 수 있습니다. EXPIRED_IN_MATCH는 STP 관련 상태로 설명됩니다. 이름만 보고 모두 같은 “실패 주문”으로 분류하면 실제 체결과 방지된 수량을 혼동할 수 있습니다.
3. 이번 체결량과 누적 체결량
소문자 l은 마지막으로 실행된 수량, 소문자 z는 누적 체결 수량입니다. 한 주문이 여러 번 나뉘어 체결되면 l은 각 체결의 크기를 나타내고 z는 그 시점까지의 합계를 나타냅니다. 두 값을 동시에 누적하면 같은 체결을 이중 반영할 수 있습니다.
예를 들어 첫 이벤트에서 l=2, z=2이고 다음 이벤트에서 l=3, z=5라면 총 체결량은 5입니다. z를 매번 더해 2+5=7로 계산하면 잘못된 결과가 됩니다. 이 숫자는 설명을 위한 가상 값이며 실제 자산 단위와 필터는 별도로 확인해야 합니다.
내부 상태를 누적값으로 덮어쓰는 방식과 개별 체결을 합산하는 방식은 목적이 다릅니다. 어떤 방식을 선택하든 중복 이벤트, 재연결, 조회 대조를 고려해야 합니다. 누적 수량은 현재 상태 확인에 유용하지만 개별 수수료·체결 가격 기록을 모두 대신하지는 않습니다.
주문 수량 q와의 관계
q는 주문 수량을 나타내는 필드입니다. z와 비교하면 얼마나 체결됐는지 이해하는 데 도움이 됩니다. 다만 수량 수정, STP 처리, 주문 종류 등 별도 조건이 있는 경우 단순한 빼기만으로 모든 의미를 설명하려고 해서는 안 됩니다.
잔량을 화면에 보여줄 때는 현재 주문 상태와 최신 주문 수량을 함께 확인합니다. 수정 전 수량을 계속 사용하면 이후 계산이 어긋날 수 있습니다. 수량 변경 이력과 현재 상태를 연결해 두는 것이 중요합니다.
4. 마지막 체결 가격과 평균 체결 가격
대문자 L은 마지막 체결 가격이고, 대문자 Z는 누적 quote 자산 거래량입니다. 공식 문서는 평균 가격을 Z를 z로 나누어 구할 수 있다고 설명합니다. 단, z가 0이면 나눗셈을 수행할 수 없으므로 미체결 상태를 별도로 처리해야 합니다.
마지막 체결 가격만 표시하면 전체 주문의 평균 가격과 다를 수 있습니다. 여러 가격대에서 나뉘어 체결된 주문에서는 각 체결의 수량이 다르기 때문입니다. 가격을 단순 산술 평균하는 방식도 수량 가중치를 반영하지 않아 잘못된 결과가 될 수 있습니다.
평균 체결 가격과 수수료를 포함한 실제 순비용은 구분해야 합니다. Z/z는 공식 필드 기반의 평균 가격 계산이며, 수수료 자산이 다르거나 별도 비용이 있으면 총 비용 분석은 추가 기록이 필요합니다. 평균 가격 하나를 계정 손익 전체로 해석하지 마세요.
소수 계산의 주의점
JSON 예시의 가격·수량은 문자열로 표현되는 경우가 있습니다. 이를 부정확한 부동소수 처리로 반복 합산하면 작은 오차가 누적될 수 있습니다. 사용 언어에서 정확한 소수 계산 방법을 검토하고 원본 문자열도 보존하는 편이 진단에 도움이 됩니다.
화면 표시를 위해 반올림한 값과 원장 계산에 쓰는 값은 분리하는 것이 좋습니다. 보기 좋게 두 자리로 줄인 숫자로 다시 체결량이나 평균을 계산하면 원본 결과와 차이가 생길 수 있습니다. 표시 정밀도가 실제 거래 규칙을 대신하지는 않습니다.
5. 수수료와 체결 식별
n은 수수료 금액, N은 수수료 자산을 나타냅니다. 금액만 합치고 자산을 버리면 서로 다른 자산으로 부과된 비용을 같은 단위처럼 더하는 실수가 생길 수 있습니다. 수수료 기록은 금액과 자산을 함께 보관해야 합니다.
t는 trade ID, I는 execution ID로 설명됩니다. 주문 전체를 찾는 i와 c와 역할이 다릅니다. 하나의 주문에서 여러 체결이 발생할 수 있으므로 주문 식별자만으로 개별 체결을 모두 구분하려고 하지 않습니다.
체결이 아닌 이벤트에서는 개별 체결 필드를 실제 거래처럼 반영하면 안 됩니다. 이벤트 유형과 상태를 먼저 읽고, 해당 메시지가 새 체결 기록을 추가할 상황인지 판단합니다. 예시 JSON에 숫자 필드가 존재한다는 사실만으로 모든 메시지에서 의미 있는 거래량이 발생했다고 볼 수 없습니다.
6. 시간 필드 읽기
E는 이벤트 시각, T는 거래 처리 시각, O는 주문 생성 시각으로 설명됩니다. W는 주문이 호가장에 놓인 경우 등장하는 Working Time 관련 필드입니다. 여러 시각을 하나의 “시간”으로 덮어쓰면 전송 지연과 주문의 실제 처리 순서를 구분하기 어렵습니다.
공식 문서는 JSON 시간값을 기본 밀리초로 안내합니다. 화면에 한국시간으로 표시할 때는 표시 변환을 하되 원본 시각과 단위를 보존하는 것이 좋습니다. 날짜 문자열로 바꾸는 과정에서 시간대가 중복 적용되지 않도록 확인하세요.
로컬 수신 시각도 별도로 기록할 수 있습니다. 이는 네트워크와 처리 지연을 진단하는 데 도움이 되지만 거래소가 제공한 공식 이벤트 시각과 동일한 개념은 아닙니다. “내 프로그램에 늦게 도착했다”와 “거래소에서 늦게 처리됐다”를 구분해야 합니다.
7. 조건부 필드와 STP
executionReport에는 모든 주문에 항상 나타나는 것이 아닌 조건부 필드가 있습니다. 공식 문서는 trailing 관련 값, strategy 관련 값, STP 관련 값, SOR·배정 관련 값, pegged order 관련 값, 만료 사유 등을 구분해 설명합니다.
예를 들어 STP 때문에 방지된 수량을 나타내는 A·B 같은 값은 실제 체결량 z와 같은 의미가 아닙니다. 체결되지 않도록 방지된 수량을 매수 완료 수량에 더하면 잔고와 원장이 맞지 않게 됩니다. 조건부 필드의 등장 조건과 의미를 함께 저장해야 합니다.
eR은 주문이 만료됐을 때 나타나는 만료 사유로 설명됩니다. 모든 메시지에 이 값이 있어야 정상이라고 검사하면 정상 이벤트를 오류로 처리할 수 있습니다. 반대로 값이 없다는 이유로 원인을 임의로 채워 넣어서도 안 됩니다.
없는 값과 0은 다르다
필드가 생략됐다는 것은 그 조건이 적용되지 않았거나 해당 메시지에 제공되지 않았다는 의미일 수 있습니다. 이를 모두 숫자 0으로 바꾸면 “실제로 0이 확인됨”과 “정보 없음”을 구분할 수 없습니다. 내부 자료형에서 이 차이를 표현하는 것이 좋습니다.
새 필드가 추가되는 상황도 고려해야 합니다. 모르는 필드가 하나 생겼다고 모든 메시지 처리를 중단하는 구조는 운영을 어렵게 만들 수 있습니다. 다만 알려지지 않은 상태를 임의로 성공 처리하지 않고, 원본 보존과 검토 절차를 두는 것이 중요합니다.
8. 이벤트 처리 순서
1단계: 메시지 종류와 구조 확인
연결에서 받은 메시지가 계정 잔고 업데이트인지, 주문 업데이트인지, 주문 목록 관련 메시지인지 구분합니다. 모든 계정 메시지를 executionReport 파서에 넣지 않습니다. 현재 스키마의 감싸기 구조와 이벤트 객체 위치를 확인하는 것이 먼저입니다.
파싱에 실패한 원본을 비밀값 없이 보존하면 변화 원인을 분석하는 데 도움이 됩니다. 다만 계정 데이터는 공개 자료가 아니므로 저장 위치와 공유 범위를 관리해야 합니다. 무조건 전체 메시지를 공개 로그로 전송하는 방식은 피하세요.
2단계: 계정·심볼·주문 연결
메시지의 심볼과 주문 식별자를 내부 원장에 연결합니다. 여러 계정 또는 테스트·운영 환경을 함께 다루는 프로그램이라면 환경 구분이 빠지지 않도록 합니다. 같은 숫자 ID라는 이유만으로 다른 맥락의 기록을 합치지 않습니다.
원장에 없는 주문이 들어왔을 때의 정책도 필요합니다. 사용자가 수동으로 만든 주문일 수도 있고 이전 실행에서 기록하지 못한 주문일 수도 있습니다. 이를 즉시 삭제하거나 새로운 자동 주문 신호로 해석하지 말고 확인 대상으로 분류하는 편이 좋습니다.
3단계: 사건·상태·수량을 함께 반영
x와 X를 읽고 이번 체결량, 누적 체결량, 수수료를 각각 맞는 목적에 반영합니다. 체결 이벤트가 아니라면 새 체결 원장을 추가하지 않는 식으로 의미별 처리를 분리합니다. 하나의 거대한 성공 처리 함수에 모든 상태를 넣으면 예외가 늘기 쉽습니다.
최신 누적값을 저장할 때는 어떤 시점의 관측인지 함께 남깁니다. 늦게 도착한 과거 메시지가 최신 상태를 덮어쓰는지 검토할 수 있습니다. 이 글은 모든 전송 순서가 보장된다고 가정하지 않으며, 실제 조회 결과와 대조하는 절차를 권합니다.
4단계: 중복과 누락 가능성 관리
재연결이나 내부 재처리 과정에서 같은 자료를 다시 반영할 수 있으므로 중복 처리 정책이 필요합니다. 주문·체결 식별자와 현재 저장 상태를 비교하고, 이미 반영한 체결을 또 더하지 않도록 합니다. 이는 클라이언트 운영 설계입니다.
연결이 끊긴 동안 아무 이벤트가 오지 않았다는 사실은 아무 거래도 없었다는 증거가 아닙니다. 재연결 후 공식 조회로 미체결 주문과 최근 체결 등을 필요한 범위에서 대조하는 절차를 마련하세요. 조회 자체의 요청 제한도 함께 고려해야 합니다.
5단계: 운영 화면에 사실의 범위 표시
“스트림 연결됨”과 “주문 상태 최신 확인됨”은 다릅니다. 연결이 살아 있어도 처리 지연이나 파싱 오류가 있을 수 있습니다. 마지막 수신 시각, 마지막 처리 시각, 마지막 대조 시각을 나눠 보여주면 이상을 찾기 쉽습니다.
주문이 결과 불명확 상태라면 이를 완료로 꾸미지 않습니다. 사용자가 재주문하기 전에 원래 주문을 확인할 수 있게 상태와 식별자를 보여줍니다. 이벤트 해석의 목적은 화려한 실시간 화면보다 실제 주문과 내부 기록의 일치입니다.
9. 다섯 가지 계산·판독 예시
예시 1: NEW는 체결 완료가 아니다
가상의 주문에서 x=NEW, X=NEW, z=0이라는 메시지를 받았다고 가정합니다. 이는 접수 관련 상태를 읽는 상황이며, 체결량이 0이므로 자산을 매수 완료했다고 기록할 근거가 없습니다. 주문이 호가장에 놓였는지 등 추가 필드의 의미도 구분해서 봅니다.
프로그램은 접수 확인 상태로 갱신하고 이후 체결·취소·만료 업데이트를 기다릴 수 있습니다. “응답이 왔으니 성공”이라는 표현을 쓰더라도 그것이 접수 성공인지 체결 성공인지 명확히 해야 합니다. 운영자와 코드가 같은 용어를 쓰는 것이 중요합니다.
예시 2: 두 번 나뉜 체결
첫 체결 수량이 2, 다음 체결 수량이 3이라면 누적 수량은 5입니다. 첫 이벤트의 z=2와 다음 이벤트의 z=5를 합쳐 7로 만들면 잘못된 원장이 됩니다. 각 l을 중복 없이 합치거나 최신 z를 상태 값으로 사용하는 방법을 구분해야 합니다.
두 방식으로 계산한 결과가 다르면 중복·누락·순서·정밀도 문제를 조사할 수 있습니다. 차이가 있다는 이유로 한 값을 임의로 덮어쓰고 끝내지 말고 원본 체결 기록과 공식 조회 결과를 대조합니다. 진단을 위한 비교값과 회계상 확정값을 구분하세요.
예시 3: 평균 가격 계산
가상의 자산 2개가 가격 100에, 3개가 가격 110에 체결됐다고 가정합니다. 누적 수량 z는 5이고 누적 quote 금액 Z는 530이므로 평균 가격은 106입니다. 마지막 체결 가격 110과 다르며, 두 가격의 단순 평균 105와도 다릅니다.
이 계산은 수량 가중 평균을 설명합니다. 수수료를 포함한 순매수 비용을 구하려면 n과 N 등 별도 기록을 확인해야 합니다. 수수료 자산이 다른 경우 임의 환율을 넣어 확정 비용처럼 표시하지 말고 평가 기준과 시점을 명시합니다.
예시 4: 부분 체결 뒤 CANCELED
수량 10의 주문이 4만 체결된 뒤 취소됐다고 가정합니다. 최종 상태가 CANCELED여도 실제 체결량 4는 남습니다. 상태가 취소라는 이유로 누적 체결량을 0으로 초기화하면 계정 잔고와 내부 기록이 맞지 않게 됩니다.
원장에는 최종 주문 상태와 누적 체결량을 함께 보관합니다. 취소된 잔량과 과거 체결을 별도로 표시하면 사용자가 어떤 부분이 실행됐는지 이해할 수 있습니다. 취소 요청 시각과 실제 체결 시각이 가까웠다면 공식 내역을 대조해 최종 결과를 확인합니다.
예시 5: STP로 방지된 수량
자기 거래 방지에 의해 일부 수량이 실행되지 않은 상황에서는 STP 관련 조건부 필드가 나타날 수 있습니다. 방지된 수량은 실제 체결량이 아니므로 자산 잔고 증가나 거래량에 그대로 더하면 안 됩니다. EXPIRED_IN_MATCH 같은 상태와 관련 필드를 함께 읽습니다.
이 경우 단순히 “주문 실패”라고만 표시하면 왜 실행되지 않았는지 알기 어렵습니다. 방지된 수량, 실제 누적 체결량, 종료 상태를 구분해서 기록하세요. STP 모드별 세부 처리와 지원 여부는 별도 공식 규칙을 확인해야 합니다.
10. 연결 중단과 복구
스트림 연결이 끊겼을 때 자동으로 연결만 다시 만드는 것으로 모든 기록이 복원됐다고 보지 않습니다. 마지막으로 확인한 주문 상태와 재연결 후 현재 상태 사이에 차이가 있을 수 있습니다. 연결 회복과 데이터 정합성 회복을 별도 단계로 다루는 편이 좋습니다.
복구 과정에서는 필요한 주문과 체결을 공식 조회 경로로 대조할 수 있습니다. 전체 계정 내역을 무제한 반복 조회하기보다 확인 범위와 식별자를 사용해 필요한 정보를 확인합니다. 호출량은 Request Weight와 주문 관련 제한을 고려해 관리해야 합니다.
내부 처리기가 오류로 멈췄는데 네트워크 연결만 살아 있는 상황도 있습니다. 따라서 연결 상태뿐 아니라 메시지 처리 지연과 실패 건수를 관찰해야 합니다. 마지막 수신 메시지가 언제인지, 마지막 성공 반영이 언제인지 나눠 보면 이런 문제를 발견하기 쉽습니다.
수동 주문도 존재할 수 있다
자동화가 만든 주문만 계정에 있다고 가정하지 않습니다. 사용자가 앱에서 수동 주문을 하거나 다른 도구를 사용할 수 있습니다. 원장에 모르는 주문이 들어왔다고 이를 자동으로 취소하거나 복제하는 동작은 별도 승인과 설계 없이 수행하면 안 됩니다.
내부 전략 주문과 외부에서 발생한 주문을 구분해 표시하고, 계정 전체 상태를 대조할 때는 두 종류를 모두 고려합니다. 특정 clientOrderId 접두사만으로 완벽히 구분된다고 가정하지 말고 실제 운영 규칙과 기록을 확인하세요.
11. 오류 예방 표
| 잘못된 해석 | 문제 | 올바른 구분 |
|---|---|---|
| executionReport는 모두 체결 | 접수·취소도 거래량으로 반영 | x·X와 체결 필드 확인 |
| 누적 z를 매번 더하기 | 체결량 이중 계산 | 증분 l과 누적 z 분리 |
| L을 전체 평균으로 사용 | 다중 가격 체결 왜곡 | z가 양수일 때 Z/z |
| CANCELED면 체결량 0 | 과거 체결 삭제 | 상태와 누적 체결 동시 보관 |
| STP 방지량을 체결량에 합산 | 잔고·거래량 오류 | 방지와 실제 체결 구분 |
| 없는 필드는 모두 0 | 정보 없음과 실제 0 혼동 | 조건부 필드 처리 |
| 재연결 즉시 정상 완료 | 누락 기록 방치 | 현재 상태 대조 |
문제가 생기면 계산 결과만 고치기보다 어떤 메시지를 어떤 순서로 반영했는지 확인해야 합니다. 원본 자료를 보존하면 파서 수정 후 재검증할 수 있지만, 계정 자료의 접근과 보관 범위는 관리해야 합니다. 진단 목적이 공개 공유를 정당화하지는 않습니다.
이벤트 원장을 검증하는 구체적인 방법
주문 단위 검증과 계정 단위 검증
한 주문의 누적 체결량이 맞는지 확인하는 것과 계정 전체 잔고가 맞는지 확인하는 것은 범위가 다릅니다. 주문별로 수량이 맞아도 수수료 자산이나 수동 거래, 입출금·이체를 빠뜨리면 계정 잔고는 다를 수 있습니다. executionReport만으로 모든 계정 변화를 설명하려고 하지 않습니다.
공식 User Data Stream은 주문 업데이트 외에 계정 잔고와 잔고 변화 관련 이벤트도 구분합니다. 각각의 이벤트가 어떤 사실을 알려주는지 나누어 처리하고, 같은 변화를 여러 경로에서 보았을 때 이중 반영하지 않도록 설계합니다. 계정 원장은 여러 자료를 연결한 결과이지 단일 이벤트 필드의 복사본이 아닙니다.
거래량과 수수료 단위 검증
체결 수량은 base 자산, 누적 거래 금액은 quote 자산, 수수료는 N으로 표시된 자산이라는 식으로 단위를 함께 검토합니다. 숫자가 모두 소수 문자열로 보인다고 같은 단위로 합칠 수는 없습니다. 내부 데이터 모델에도 자산 종류가 연결돼 있어야 잘못된 합산을 찾을 수 있습니다.
가상의 평균 가격 예시에서 530을 5로 나누는 것은 quote 금액을 base 수량으로 나누는 계산입니다. 수수료 0.01이 별도 자산으로 부과됐다면 530에서 바로 빼는 것은 단위가 맞지 않을 수 있습니다. 평가 환율이 필요하다면 평가 시점과 출처를 별도로 정하고 원래 거래 기록은 보존해야 합니다.
상태 전이 점검
정상적인 주문 흐름을 기대하더라도 모든 메시지가 같은 순서와 간격으로 도착한다고 가정하지 않는 편이 좋습니다. 이미 종료를 확인한 주문에 오래된 접수 메시지를 다시 적용하는지, 부분 체결 이후의 누적값을 과거 값으로 되돌리는지 점검할 수 있습니다. 이상이 보이면 원본 시각과 식별자를 대조합니다.
다만 로컬에서 이상해 보인다는 이유로 공식 데이터를 임의로 수정해서는 안 됩니다. 조회 결과와 이벤트가 다르면 어느 자료가 어떤 시점의 상태인지 확인하고, 클라이언트 처리 오류가 있는지 조사해야 합니다. 불일치를 숨기는 것보다 확인 필요 상태로 남기는 편이 복구에 유리합니다.
재처리 시 동일한 결과가 나오는지
보관한 이벤트를 다시 읽었을 때 체결량이 또 증가한다면 중복 반영 문제가 있는지 확인해야 합니다. 원본 보관과 상태 반영을 분리하면 파서 수정 후 같은 자료로 결과를 비교할 수 있습니다. 실제 주문을 새로 실행하지 않고도 데이터 처리의 일관성을 점검할 수 있는 방법입니다.
이때 과거 자료의 스키마와 현재 파서가 맞는지도 고려합니다. 필드가 추가되거나 조건부 값이 달랐던 기록을 현재 규칙으로 무리하게 채워 넣지 않습니다. 자료를 받은 시점과 사용한 파서 버전을 남기면 변경 원인을 추적하기 쉽습니다.
알림을 보낼 기준
모든 이벤트마다 운영자에게 알리면 중요한 상태가 묻힐 수 있습니다. 접수 확인, 최종 종료, 결과 불명확, 기록 불일치처럼 의미 있는 변화에 초점을 맞출 수 있습니다. 다만 이는 알림 설계의 선택이며 실제 거래 판단을 자동으로 승인하는 기능은 아닙니다.
알림에는 주문 전체가 체결된 것인지 일부만 체결된 것인지 분명하게 적습니다. 평균 가격을 보여준다면 수수료 포함 여부와 기준 자산을 구분하세요. 짧은 메시지라도 단위와 상태를 정확하게 전달하면 사용자가 불필요하게 다시 주문하는 상황을 줄이는 데 도움이 됩니다.
주문 목록 이벤트와 함께 읽기
공식 문서는 주문이 목록에 속하는 경우 executionReport 외에 listStatus 이벤트가 전달될 수 있다고 설명합니다. 개별 주문의 상태와 목록 전체의 상태는 서로 다른 범위입니다. 목록이 종료됐다고 구성 주문이 모두 같은 방식으로 체결됐다고 가정하지 않습니다.
각 주문은 고유한 식별자와 체결 기록을 가지고, 목록은 그 주문들을 연결하는 관계를 제공합니다. 내부 원장에서 목록 ID를 개별 주문 ID 대신 사용하면 여러 주문의 체결을 한 주문으로 합칠 수 있습니다. 부모·자식 관계를 유지하고 각 주문의 실제 결과를 따로 확인해야 합니다.
데이터 검증에서 작은 표본을 고르는 기준
모든 정상 접수 메시지만 확인하면 부분 체결과 취소 오류를 발견하기 어렵습니다. 미체결 접수, 두 번 이상 나뉜 체결, 부분 체결 후 취소, STP 관련 종료, 연결 중단 뒤 대조처럼 의미가 다른 사례를 골라 검증할 수 있습니다. 이 글의 다섯 예시는 그런 구분을 연습하기 위한 자료입니다.
검증에서는 화면 숫자만 맞는지 보지 말고 원본 단위와 수수료 자산, 주문 상태, 최종 누적값이 함께 일치하는지 확인합니다. 한 항목을 맞추려고 다른 항목을 임의로 바꾸면 정합성 문제가 숨겨질 수 있습니다. 불일치가 남으면 원인을 기록하고 확인된 사실까지만 표시해야 합니다.
12. FAQ
Q1. 바이낸스 Execution Report는 거래 내역 다운로드인가요?
이 글의 executionReport는 Spot User Data Stream의 주문 업데이트 이벤트입니다. 파일로 내려받는 거래 보고서와 이름이 비슷해도 다른 기능입니다. 계정 이벤트를 실시간 처리하는 맥락에서 이해해야 합니다.
Q2. 모든 executionReport는 새 체결을 뜻하나요?
아닙니다. 주문 접수·취소·만료 등 여러 변화와 관련됩니다. 이벤트 유형과 주문 상태를 먼저 읽고 실제 체결이 있는 메시지인지 구분해야 합니다. 이름만 보고 거래량을 추가하지 마세요.
Q3. x와 X가 다른 이유는 무엇인가요?
이번 사건의 유형과 현재 주문 상태를 나누기 때문입니다. 체결 사건이 발생해도 전체 주문은 부분 체결 상태일 수 있습니다. 대소문자를 보존하고 내부에서 의미 있는 이름으로 분리해 처리하세요.
Q4. l과 z 중 어떤 값을 더해야 하나요?
l은 이번 체결량이고 z는 누적 체결량입니다. 개별 체결 합산과 현재 상태 저장의 목적을 구분해야 합니다. 누적 z를 이벤트마다 더하면 같은 체결을 중복 계산할 수 있습니다.
Q5. 평균 체결 가격은 어떻게 계산하나요?
공식 문서는 Z/z를 안내합니다. z가 0이면 나눗셈을 하지 않고 미체결 상태로 처리해야 합니다. 이 값은 수수료까지 포함한 계정 전체 순비용이나 손익을 자동으로 나타내지 않습니다.
Q6. 마지막 가격 L을 평균으로 써도 되나요?
한 가격에서만 체결된 경우와 여러 가격에서 나뉜 경우를 구분해야 합니다. L은 마지막 체결 가격이므로 전체 평균과 다를 수 있습니다. 수량 가중 평균을 보려면 누적 금액과 수량을 확인하세요.
Q7. 취소 상태면 체결량을 지워야 하나요?
아닙니다. 이미 체결된 부분은 취소로 되돌아가지 않습니다. 최종 상태와 누적 체결량을 함께 보관해야 하며, 부분 체결 후 취소된 주문을 전량 미체결처럼 표시하지 않습니다.
Q8. 수수료 n만 합치면 되나요?
수수료 자산 N도 함께 확인해야 합니다. 서로 다른 자산의 금액을 단위 없이 합산하면 의미가 없습니다. 필요 시 평가 기준을 정하되 원래 수수료 금액과 자산 기록을 보존하세요.
Q9. STP 방지량은 실제 거래량인가요?
아닙니다. 방지된 수량과 실제 체결된 수량은 다릅니다. 조건부 필드와 상태를 함께 읽어야 하며 방지량을 잔고 증가나 체결량에 그대로 더하면 안 됩니다.
Q10. 일부 필드가 없으면 오류인가요?
조건부 필드는 특정 상황에서만 나타납니다. 공식 문서의 등장 조건을 확인하세요. 정보가 없는 경우와 값이 실제 0인 경우를 구분하고, 누락된 값을 추측으로 채우지 않습니다.
Q11. 공개 거래 스트림으로 내 체결을 알 수 있나요?
시장 전체 거래와 본인 주문은 다릅니다. 본인 계정의 주문 식별자와 User Data Stream 또는 공식 주문 조회를 연결해야 합니다. 같은 가격의 거래가 보였다고 자신의 체결로 단정하지 마세요.
Q12. 연결이 살아 있으면 기록도 최신인가요?
반드시 그렇지는 않습니다. 메시지 처리 지연이나 파싱 오류가 있을 수 있습니다. 마지막 수신·처리·대조 시각을 구분하고 연결 복구 후 현재 주문 상태와 비교하는 절차를 마련하세요.
Q13. REST 응답과 스트림 메시지를 둘 다 받으면 중복인가요?
같은 주문에 관한 서로 다른 관측일 수 있습니다. 주문 식별자로 연결하고 같은 체결을 두 번 반영하지 않도록 해야 합니다. 원본 메시지는 별도로 보관하되 주문 원장은 일관되게 유지합니다.
Q14. 선물 이벤트도 같은 필드로 읽으면 되나요?
제품별 공식 문서를 확인해야 합니다. 이 글은 Spot executionReport에 한정합니다. 비슷한 개념이 있어도 이벤트 이름·구조·필드가 다를 수 있으므로 현물 파서를 그대로 적용하지 않습니다.
Q15. 다음으로 어떤 상태를 확인해야 하나요?
개별 주문 상태 외에 거래쌍 자체의 Trading Status가 있습니다. 주문이 NEW인지와 심볼이 TRADING인지에는 다른 의미가 있습니다. 거래 가능 상태와 계정 권한까지 구분하면 주문 거절 원인을 더 정확히 볼 수 있습니다.
13. 처리 체크리스트
- Spot User Data Stream의 현재 스키마를 확인했다.
- 공개 시세 스트림과 계정 주문 스트림을 구분한다.
- 계정·환경·심볼·주문 ID를 함께 연결한다.
- x와 X를 별도 의미로 처리한다.
- 이번 체결량 l과 누적 z를 혼동하지 않는다.
- z=0에서 평균 가격 나눗셈을 하지 않는다.
- 마지막 가격과 전체 평균을 구분한다.
- 수수료 금액과 자산을 함께 보관한다.
- 조건부 필드의 누락을 정상적으로 처리한다.
- STP 방지량을 실제 체결에 더하지 않는다.
- 취소 후에도 과거 체결을 보존한다.
- 중복 처리와 재연결 후 대조 정책이 있다.
- 로컬 수신 시각과 거래소 시각을 구분한다.
- 계정 원본 자료를 제한된 범위에 보관한다.
핵심 정리
| 관점 | 확인할 내용 |
|---|---|
| 어느 주문인가 | s·c·i와 계정·환경 |
| 무슨 변화인가 | x |
| 현재 어떤 상태인가 | X |
| 얼마나 체결됐나 | l·z |
| 평균 가격은 얼마인가 | z가 양수일 때 Z/z |
| 비용은 무엇인가 | n·N과 개별 체결 기록 |
| 복구가 끝났나 | 연결뿐 아니라 주문·체결 대조 |
바이낸스 Execution Report는 짧은 필드 이름 안에 서로 다른 의미를 담고 있습니다. 사건과 상태, 증분과 누적, 체결과 방지, 마지막 가격과 평균을 분리하면 자동 주문 결과를 더 정확하게 읽을 수 있습니다.
이 글은 데이터 해석을 위한 정보성 자료이며 특정 거래나 수익을 보장하지 않습니다. 실제 구현과 운영 전 최신 Binance 공식 스키마와 계정의 주문·체결 내역을 확인하세요.
바이낸스 가입하고 혜택 확인하기+
바이낸스 가입하기
바이낸스 회원가입부터 이메일 인증, KYC, OTP 설정까지 COINSIGN의 단계별 가이드를 확인하면서 진행할 수 있습니다.
바이낸스 가입하기바이낸스 가입방법 8단계 가이드 보기 →