LabHub
배우기 러닝패스 코스

자본시장과 결제 · 주문이 나가기 전에 거는 위험 한도 · 이론

주문은 나가기 전에 막아야 한다

LabHub 에서 이어서 보기

한 줄 요약

사람이 자리 수를 하나 더 치는 일은 반드시 일어난다. 그것을 막는 것은 사람의 주의가 아니라 주문 경로에 박힌 점검이고, 점검은 켜 두는 것만으로 되지 않는다 — 무엇을 누적에 넣는지, 어떤 순서로 거는지가 결과를 바꾼다.

왜 이게 필요했나

체결된 뒤에 찾아내는 것과 나가기 전에 막는 것은 완전히 다른 일이다. 나간 주문은 이미 시장에 있고, 되돌리려면 반대 매매를 하거나 거래소에 취소를 빌어야 한다. 그 사이의 가격 변동은 그대로 손실이다. 그래서 위험 점검은 주문 경로 위, 그러니까 주문이 시장으로 나가기 전 구간에 놓인다.

이것이 관행이 아니라 규정인 나라도 있다. 미국 증권거래위원회 규칙 15c3-5 는 시장 접근을 제공하는 중개사에게 주문이 나가기 전에 재무·규제 위험 통제를 적용하도록 요구한다. 규정 본문은 [eCFR 의 240.15c3-5](https://www.ecfr.gov/current/title-17/chapter-II/part-240/section-240.15c3-5) 에서 읽을 수 있고, 왜 이런 규칙이 필요했는지는 [연방관보의 채택 고시](https://www.federalregister.gov/documents/2010/11/15/2010-28268/risk-management-controls-for-brokers-or-dealers-with-market-access)에 남아 있다. 규정이 요구하는 것은 "점검을 걸어라" 이지 "한도를 얼마로 하라" 가 아니다. 숫자는 각자 정한다. 이 글과 실습에 나오는 한도 수치는 전부 합성값이다.

어떻게 동작하나

점검은 대개 여섯 갈래로 나뉜다.

단일 주문 한도. 한 건의 수량과 금액에 상한을 둔다. 자리 수를 하나 더 친 주문은 여기서 대부분 걸린다. 금액은 수량 곱하기 가격이므로, 수량 상한만 두면 비싼 종목에서 새어 나간다.

가격 대역. 기준가에서 몇 퍼센트 이상 벗어난 지정가를 막는다. 여기서 반드시 마주치는 질문이 하나 있다 — 기준가가 없는 종목은 어떻게 하는가. 신규 상장이거나 시세 피드가 끊겼거나 종목 코드가 틀렸을 수 있다. 이때 "비교할 게 없으니 통과" 로 두면 점검이 있는 이유가 사라진다. 통과도 거부도 아닌 보류로 빼서 사람이 보게 하는 것이 정석이다. 보류는 거부와 다르게 세어야 한다. 뒤에서 이 차이가 크게 벌어진다.

제한 종목 목록과 중복 주문. 앞의 것은 단순한 명단 대조이고, 뒤의 것은 같은 조건의 주문이 짧은 시간에 되풀이되는 것을 잡는다. 화면이 멈춘 줄 알고 단추를 두 번 누르는 일, 재시도 로직이 응답을 못 받고 다시 보내는 일이 여기서 걸린다.

누적 한도. 계좌·트레이더·데스크 단위로 미체결 노출의 합에 상한을 둔다. 여기에 이 글에서 가장 중요한 규칙이 있다. 거부된 주문은 누적을 소진하지 않는다. 당연해 보이지만 틀리기 쉽다 — 주문 로그를 그대로 훑어 합을 내면 거부된 주문까지 들어가고, 그러면 한도가 실제보다 빨리 차서 멀쩡한 주문이 줄줄이 막힌다. 막힌 사람은 이유를 모른다. 화면에는 "한도 초과" 라고만 나오고, 그 사람의 실제 노출은 한도의 절반이기 때문이다.

킬 스위치. 개별 거부와 전체 차단은 다른 동작이다. 짧은 시간 안에 거부가 몰린다면 그것은 주문 하나가 잘못된 것이 아니라 보내는 쪽이 고장 난 것일 가능성이 크다. 그때는 그 경로를 통째로 닫는다. 그리고 이 상태는 파일이나 저장소에 남겨야 한다. 메모리에만 두면 프로세스가 재시작하는 순간 차단이 풀리고, 고장 난 쪽은 여전히 고장 나 있다.

점검의 순서. 순서가 바뀌면 같은 주문에 붙는 사유가 달라진다. 사유만 달라지면 보고서 문제지만, 보류와 거부를 가르는 점검이 앞뒤로 움직이면 이야기가 달라진다. 보류는 거부로 세지 않으므로, 가격 대역 점검을 앞으로 당기는 것만으로 킬 스위치가 켜지는 시점이 밀린다. 그 사이에 들어온 주문은 막히지 않고 나간다.

금액 비교는 [decimal](https://docs.python.org/3/library/decimal.html) 로 한다. 부동소수로 한도를 견주면 정확히 한도와 같은 금액이 어떤 날은 통과하고 어떤 날은 막힌다. 주문 메시지의 필드 이름과 뜻은 [FIX 표준](https://www.fixtrading.org/standards/)이 정해 둔 것을 따른다.

현장에서 만나는 모습

한 번은 특정 데스크의 주문이 오후마다 막힌다는 신고가 올라왔다. 노출을 세어 보니 한도의 절반이었다. 원인은 누적을 주문 로그에서 세고 있었던 것이었다. 오전에 거부된 큰 주문 몇 건이 한도를 먹고 있었고, 거부는 화면 어디에도 노출로 표시되지 않았다.

또 한 번은 킬 스위치가 켜졌는데 10분 뒤에 저절로 풀렸다. 배포가 돌면서 프로세스가 재시작했고, 차단 상태는 메모리에만 있었다. 같은 장애가 그날 두 번 더 났다.

다음 실습에서 할 것

주문 47건과 한도 정의를 만들고, 단일 주문 한도부터 시작해 가격 대역·제한 종목·중복·누적 노출·킬 스위치를 한 겹씩 얹습니다. 거부된 주문까지 누적에 넣는 잘못된 구현과 견주어 어떤 주문이 억울하게 막히는지 목록으로 뽑고, 점검 순서를 한 자리 바꿔 킬 스위치가 켜지는 주문이 달라지는 것을 확인합니다. 마지막에는 한도를 조인 두 번째 설정으로 같은 하루를 다시 돌려, 지금 설정이 놓치고 있던 주문을 뽑아냅니다.