LabHub
学习 学习路径 课程

资本市场与清结算

多打了一位数的订单会在哪里被拦下

在 LabHub 中继续学习

한국어 원문으로 표시합니다.

목표

주문 스트림에 단일 주문 한도·가격 대역·제한 종목·중복·누적 노출·킬 스위치를 한 겹씩 얹어 보고, 누적을 갱신하는 시점과 점검의 순서가 결과를 어떻게 바꾸는지 숫자로 확인합니다.

왜 중요한가

체결된 뒤에 찾아내는 것과 나가기 전에 막는 것은 다른 일입니다. 나간 주문은 이미 시장에 있고 되돌리는 값은 그대로 손실입니다. 그래서 점검은 주문 경로 위에 놓입니다. 그런데 점검은 켜 두는 것만으로 되지 않습니다. 거부된 주문까지 누적 한도에 넣으면 실제 노출이 한도의 절반인 사람이 막히고, 기준가가 없는 종목을 통과로 두면 점검이 있는 이유가 사라집니다. 보류를 거부로 세면 킬 스위치가 엉뚱한 자리에서 켜지고, 차단 상태를 메모리에만 두면 재시작 한 번에 풀립니다. 이 실습은 그 함정을 하나씩 직접 만들어 보고 숫자로 확인합니다.

단계

  1. python3/root/risk/dataorders.jsonl·limits.json·limits_tight.json·refprice.csv·restricted.txt·accounts.csv 를 만듭니다.
  2. 단일 주문 한도(수량·금액)만 걸어 /root/risk/single.csv 를 만듭니다.
  3. 가격 대역 점검을 더해 /root/risk/band.csv 를 만듭니다. 기준가가 없는 종목은 보류입니다.
  4. 제한 종목과 중복 주문 점검을 더해 /root/risk/screen.csv 를 만듭니다.
  5. 계좌·데스크 누적 노출 한도를 더해 /root/risk/exposure.csv 를 만들고, 거부된 주문까지 누적에 넣는 잘못된 구현이 막았을 주문을 /root/risk/naive_blocked.csv 에 적습니다.
  6. 킬 스위치를 더해 /root/risk/final.csv 를 만들고 차단 상태를 /root/risk/killswitch.json 에 남깁니다.
  7. 가격 대역 점검을 앞으로 당긴 순서로 다시 돌려 /root/risk/order_compare.csv/root/risk/order_compare.json 에 차이를 적습니다.
  8. 사유별 통계를 /root/risk/stats.json 에, 한도를 조인 설정과의 비교를 /root/risk/tuning.json 에 적습니다.

참고

주문 스트림과 한도 정의 만들기

python3/root/risk/dataorders.jsonl·limits.json·limits_tight.json·refprice.csv·restricted.txt·accounts.csv 를 만듭니다. 난수를 쓰지 않는 생성 스크립트를 그대로 쓰세요.

고객의 주문 로그를 그대로 가져올 수 없으니 같은 모양의 합성 자료를 만듭니다. 난수를 쓰지 않아야 누가 몇 번을 돌려도 같은 자료가 나오고 서로의 판정을 대조할 수 있습니다. 시각도 자료에 못박습니다 — 오늘 날짜로 만들면 내일 돌릴 때 판정이 달라집니다. 채점기는 자료를 표준형으로 바꿔 지문을 대조하므로 손으로 고치면 뒤 단계가 전부 막힙니다.

단일 주문 한도 걸기

/root/risk/single.csv 에 첫 줄 order_id,decision,reason,notional 을 두고, 수량 상한과 금액 상한만 걸어 주문 47건을 모두 한 줄씩 적으세요.

금액은 수량 곱하기 지정가입니다. 수량 상한만 두면 비싼 종목에서 새어 나가므로 둘 다 봅니다. 표준 순서에서 수량이 금액보다 앞이므로, 둘 다 넘는 주문의 사유는 앞의 것입니다. 통과한 주문의 사유는 OK 이고, 금액은 소수 둘째 자리까지 적습니다.

가격 대역과 기준가 없는 종목

/root/risk/band.csv 에 첫 줄 order_id,decision,reason 을 두고, 앞 단계의 두 점검에 가격 대역 점검을 더해 주문 47건을 모두 적으세요. 기준가가 없는 종목은 HOLDNO_REF_PRICE 입니다.

기준가에서 허용 백분율 이상 벗어난 지정가를 막습니다. 비교할 때 나눗셈을 쓰면 반올림이 끼어드니, 차이에 100을 곱해 허용 백분율 곱하기 기준가와 견주세요. 기준가가 없는 종목을 통과로 두면 점검이 있는 이유가 사라집니다. 통과도 거부도 아닌 자리를 하나 만드세요.

제한 종목과 중복 주문 걸러 내기

/root/risk/screen.csv 에 첫 줄 order_id,decision,reason 을 두고, 앞 단계에 제한 종목 점검과 중복 주문 점검을 더해 주문 47건을 모두 적으세요.

제한 종목은 명단 대조라 가장 싸므로 표준 순서에서 맨 앞입니다. 중복은 계좌·종목·방향·수량·지정가가 모두 같고 창 안에 들어온 주문인데, 견주는 대상은 앞서 통과한 주문뿐입니다. 거부된 주문을 기준으로 삼으면 한 번 실수한 사람이 두 번째 정상 주문까지 막힙니다.

누적 노출 한도와 잘못된 구현 비교하기

/root/risk/exposure.csv 에 계좌·데스크 누적 한도까지 건 판정을 order_id,decision,reason 으로 적고, /root/risk/naive_blocked.csv 에 첫 줄 order_id,account,desk,reason_naive 를 두고 거부된 주문까지 누적에 넣는 구현이 막았을 주문을 적으세요.

누적은 계좌별·데스크별로 따로 셉니다. 통과한 주문의 금액만 더하고, 거부와 보류는 누적을 소진하지 않습니다. 그 다음 일부러 틀린 구현을 하나 더 만드세요 — 주문 로그를 그대로 훑어 모든 주문의 금액을 더하는 것입니다. 두 결과에서 올바른 쪽은 통과인데 틀린 쪽은 통과가 아닌 주문이 억울하게 막힌 주문입니다.

킬 스위치를 올리고 상태를 파일로 남기기

/root/risk/final.csv 에 킬 스위치까지 건 판정을 order_id,decision,reason 으로 적고, /root/risk/killswitch.jsonengaged·engaged_at·trigger_order_id·rejects_in_window·threshold·window_sec·blocked_orders 를 적으세요.

개별 거부와 전체 차단은 다른 동작입니다. 창 안에 거부가 기준만큼 쌓이면 그때부터 경로를 통째로 닫습니다. 보류와 차단은 거부로 세지 않습니다. 켜지게 만든 주문 자신은 원래 판정을 그대로 두고, 그 다음 주문부터 전부 차단입니다. 그리고 차단 상태는 반드시 파일로 남기세요 — 메모리에만 두면 재시작 한 번에 풀립니다.

점검 순서를 한 자리 바꿔 다시 돌리기

가격 대역 점검을 수량 상한 앞으로 당긴 순서로 다시 돌려, /root/risk/order_compare.csvorder_id,decision_canonical,reason_canonical,decision_band_first,reason_band_first 로 달라진 주문만 적고, /root/risk/order_compare.json 에 두 순서의 요약을 적으세요.

사유만 달라질 것 같지만 그렇지 않습니다. 기준가가 없는 종목은 보류가 되는데 보류는 거부로 세지 않으므로, 대역 점검이 앞으로 오면 거부 한 건이 보류로 바뀌고 킬 스위치가 켜지는 자리가 밀립니다. 그 사이에 들어온 주문은 막히지 않고 나갑니다. 요약에는 accept_canonical·accept_band_first·reject_canonical·reject_band_first·hold_canonical·hold_band_first·blocked_canonical·blocked_band_first·kill_trigger_canonical·kill_trigger_band_first·diff_orders 를 넣으세요.

사유별 통계와 한도를 조인 설정의 비교

/root/risk/stats.jsonorders·accept·reject·hold·blocked·by_reason 을 적고, /root/risk/tuning.jsonbase_accept·tight_accept·newly_rejected_count·newly_rejected·tight_by_reason 을 적으세요. newly_rejected 는 지금 설정에서는 통과였는데 조인 설정에서는 통과가 아닌 주문의 목록입니다.

통계는 6단계의 판정, 그러니까 킬 스위치까지 켠 결과에서 냅니다. 그 다음 같은 하루를 limits_tight.json 으로 한 번 더 돌립니다. 두 설정의 차이는 사유별 수뿐 아니라 통과 건수 자체에서 드러납니다. newly_rejected 는 주문 번호 오름차순으로 적고, 한도를 조이면 왜 킬 스위치까지 영향을 받는지 출력으로 확인하세요.