도구가 절반만 답하던 이유 — 잔고를 안 건드리는 주문으로 판단을 끝까지 재기

판단은 내는데 그것이 맞았는지 자기가 못 재던 도구들을 시험 주문에 올려 본 절차입니다. 도구 서른한 개를 실제로 넣어 봤고, 손 안 대고 들어온 것은 하나였습니다.

도구가 절반만 답하던 이유 — 잔고를 안 건드리는 주문으로 판단을 끝까지 재기

이 글의 완료 조건: 독자가 자기 도구의 판단 한 건을 「닫는 조건까지」 등록해서, 계좌를 전혀 건드리지 않고 그 판단의 성적표를 받을 수 있으면 성공입니다.

하는 일 도구가 낸 판단을 청산 조건과 함께 등록해, 잔고를 안 건드리는 별도 원장에서 끝까지 평가하고 그 기록을 다시 도구에게 먹입니다
맞는 사람 도구를 여러 개 돌려 봤는데 "그래서 어느 쪽이 맞았나"를 못 재 본 사람
안 맞는 사람 비중(포트폴리오 %)이 산출의 핵심인 도구만 쓰는 사람. 이 경로는 수량을 서버가 정해서 비중이 사라집니다
이 글의 결과물 방향·청산 조건·발동 사유·비용이 전부 적힌 거래 기록 CSV, 그리고 도구끼리 나란히 놓을 수 있는 공통 수량
준비물·비용 코드 0원 · 모델 비용 0원(이 글에서 쓰는 채점 도구들은 LLM 을 안 씁니다) · weltiq pro 계정
시간·난도 도구가 이미 깔려 있다면 30분 · 중 (curl·JSON)
weltiq 와의 관계 이 글이 전부 그 이야기입니다 — 절차 글이라 5절이 따로 없습니다
검증 환경·날짜 2026-09-27 (KST) · 격리 서버 · 합성 호가 (6절에 그 한계를 그대로 적었습니다)
제휴 고지 필자는 weltiq 로부터 이 연재의 원고료를 받습니다. 아래 숫자는 전부 필자가 직접 돌린 것이고, 예상과 달랐던 것과 아직 막힌 것도 그대로 적었습니다

1. 왜 이 절차가 필요한가

투자 판단을 내는 오픈소스 도구를 서른 개쯤 돌려 보면, 이상한 공통점이 하나 보입니다.

도구들은 판단을 냅니다. 그런데 그 판단이 맞았는지를 자기가 못 잽니다.

그냥 게으른 게 아닙니다. 재려면 닫힌 거래가 필요한데, 닫힌 거래를 만들려면 주문을 내야 하고, 주문을 내려면 계좌가 있어야 합니다. 도구 대부분은 거기서 멈춥니다.

실제로 막혔던 세 자리

제가 이 연재에서 돌려 본 기록에서 그대로 가져옵니다.

① 잔고. 어떤 도구는 자기 기준으로 0.116 BTC 를 사라고 했습니다. 그 시점 가격 86,026.32 를 곱하면 계좌의 10,000 을 한참 넘습니다. 결과는 insufficient_balance — 판단의 품질과 아무 상관 없는 이유로 그 회차가 사라졌습니다. 자본을 늘려서 풀 문제도 아닙니다. 도구마다 사이징 근거가 달라서, 자본을 맞추면 이번엔 다른 도구가 튕깁니다.

② 유효기간. 판단에 "언제까지"가 없는 도구가 많습니다. 제가 여섯 달 전에 나온 레벨을 그대로 옮겨 넣어 본 적이 있는데, 30일에 3,889거래를 돌고 −225.29 로 끝났습니다. 도구가 틀린 게 아니라, 유통기한이 지난 판단을 제가 계속 먹인 것입니다.

③ 수량이 저마다 달라 비교가 안 됨. 한 도구는 43주, 다른 도구는 0.1 BTC, 또 다른 도구는 6.44주를 냅니다. 0.1 BTC 는 그 도구 초기자본의 8.6% 였습니다 — "자본의 2%만 걸어라" 같은 규칙을 애초에 쓸 수 없는 크기입니다. 이 셋을 나란히 놓으면 판단의 질이 아니라 사이징 취향을 비교하게 됩니다.

④ 그리고 「언제까지」가 없습니다. ②의 유통기한 문제를 뒤집어 말한 것인데, 따로 세는 이유가 있습니다 — 뒤에 보시겠지만 시험 주문이 유일하게 강제하는 칸이 바로 이것이고, 도구 서른한 개 중 쓸 수 있는 형태로 이걸 내는 도구가 없었습니다. 이 글에서 제일 오래 붙들게 된 문제입니다.

그리고 가장 아까운 자리 — 도구가 스스로 계산해 둔 요구

어떤 복기 도구는 자기 리포트에 필요한 표본 수를 직접 계산해서 적어 둡니다: 승률을 ±5% 안에서 확인하려면 384건, 기댓값을 확인하려면 1,705건.

그 도구가 실제로 갖고 있던 신호는 43개였습니다.

또 다른 확신도 채점 도구는 보정에 관측 30건 이상이 필요하다고 스스로 적어 두고, n=1 에서 자기가 거절했습니다.

도구들이 달라고 적어 둔 것을, 아무도 주지 않고 있었습니다.


2. 전체 그림

시험 주문은 거래 하나를 닫을 조건까지 함께 등록하고 서버가 그 수명 전체를 책임지는 기능입니다. 롱·숏 둘 다 포함하는 이름이고, 체결은 모의·실거래 계좌와 분리된 시험 원장에만 남습니다.

핵심은 세 줄입니다.

  1. 잔고에 영향이 없습니다. 현금·보유량·손익·손실 한도·성과 집계가 움직이지 않습니다. 위 ①이 사라집니다.
  2. 청산 조건이 필수입니다. 시한(close_at 또는 close_after_seconds) 중 하나 이상을 반드시 줘야 합니다. 위 ②가 계약 단계에서 막힙니다.
  3. 수량을 서버가 정합니다. qty 를 보내면 거절됩니다. 위 ③이 사라집니다 — 대신 대가가 있고, 6절에 적었습니다.

절차는 네 칸으로 돕니다.

칸 누가 무엇
테두리 우리 시한 필수 · 월 한도 · 잔고 무영향
주문 도구 → 우리 도구는 방향과 청산 조건만 냅니다. 수량은 서버가
결과 우리 시험 원장 — 발동 사유 · 발동 호가 · 체결가 · 수수료
고침 우리 → 도구 내보낸 기록을 도구의 복기·채점 절차에 먹입니다

세 번째 칸이 이 글의 핵심입니다. 도구가 요구하던 재료가 거기서 나옵니다.


3. 준비물

WELTIQ_BASE_URL=https://weltiq.ai
curl -sS "$WELTIQ_BASE_URL/v1/forward-tests/usage" -H "Authorization: Bearer $WELTIQ_API_KEY"

제 격리 서버에서는 이렇게 나왔습니다 — limit 1000 · used 0 · remaining 1000 · plan pro · can_enter true, 리셋 2026-10-01T00:00:00Z. 월 한도는 UTC 달력월이고 이월이 없습니다.

하루 33건입니다. 도구 서른한 개를 하루 한 바퀴 돌릴 수 있는 크기입니다. 이 숫자를 기억해 두면 4절이 왜 이렇게 설계됐는지 보입니다.


4. 한 바퀴 돌려봅시다

4.1 롱 하나 — 수량을 서버에게 맡기기

curl -sS -X POST "$WELTIQ_BASE_URL/v1/trial-buys" \
  -H "Authorization: Bearer $WELTIQ_API_KEY" -H 'Content-Type: application/json' \
  -d '{
    "venue": "binance-spot", "symbol": "BTCUSDT",
    "client_order_id": "my-tool-run-1",
    "side": "long",
    "exit_plan": {"close_after_seconds": 60, "take_profit": "51000", "stop_loss": "49000"},
    "max_duration_hours": 24,
    "memo": "거래량 조건 뒤 한 봉 더 확인",
    "client_tracking_id": "my-experiment-17",
    "tags": ["confirm-next-bar"],
    "metadata": {"tool": "29B-review.py", "external_run_id": "local-run-1"}
  }'

201 이 오고, 제가 보지 않은 칸이 채워져 있습니다.

"qty": "0.00013",
"qty_basis": {
  "rule": "smallest_lot_multiple_meeting_min_notional_within_price_headroom",
  "lot": "0.00001", "min_notional": "5", "reference_px": "50000.5", "price_headroom_pct": 20
},
"auto_close": {"managed": true, "state": "waiting_entry",
               "effective_close_at": "…", "effective_close_basis": "max_duration",
               "relative_clock_started": false},
"affects_account": false,
"usage": {"used": 1, "remaining": 999, "counted": 1}

세 가지를 읽어 두면 좋습니다.

qty_basis 가 규칙을 공개합니다. 최소 주문금액이 5 USDT 인데 왜 6.5 USDT 어치를 잡았나 — 기준가에서 20% 내려도 최소 금액을 넘는 최소 단위를 고르기 때문입니다. 손으로 확인해 봤습니다: 0.00012 × 40000.4 = 4.80 은 5 미만이라 탈락, 0.00013 × 40000.4 = 5.20 이 통과. 몰래 늘리는 게 아니라 규칙과 여유폭과 기준가를 같이 돌려줍니다.

effective_close_basis 가 "지금 기준으로 무엇이 이기고 있나"를 말합니다. 첫 체결 전에는 close_after_seconds 의 시계가 아직 안 돕니다(relative_clock_started: false). 그래서 이 시점에 종료를 정하는 것은 max_duration 입니다.

affects_account: false. 이 한 줄이 1절 ①의 답입니다.

60초 뒤 상태를 보면:

exit_trigger = close_reason = "close_after"
relative_from    22:22:32.285872   ← 첫 체결의 공개 시각
relative_close_at 22:23:32.285872   ← 정확히 +60초
exit_trigger_px  null

exit_trigger_px 가 null 인 것을 봐 두세요. 시한으로 닫힌 거래에는 "발동 호가"가 없습니다. 있는 척 채워 넣지 않습니다. 이런 칸이 0 으로 채워져 오는 시스템에서는 나중에 통계가 조용히 망가집니다.

4.2 숏 — 그리고 조건 가격은 체결가가 아닙니다

  -d '{"venue": "binance-usdm", "symbol": "BTCUSDT",
       "client_order_id": "my-tool-run-2", "side": "short",
       "exit_plan": {"close_after_seconds": 3600, "take_profit": "49000", "stop_loss": "51000"}}'

숏은 목표가가 손절가보다 아래입니다. 진입은 0.002 @ 49994.49995 로 체결됐습니다 — 숏은 매도이므로 bid 쪽으로 미끄러집니다.

그 뒤 목표가가 성립했을 때가 이 글에서 제일 중요한 장면입니다.

값 시각
발동 판정에 쓴 호가 48901 22:22:34.304
실제 청산 체결가 48906.39005 22:22:35.315

1.01초 차이에 5.39 만큼 벌어졌습니다. 서버는 조건이 성립한 것을 판정하고 청산 주문을 접수할 뿐이고, 체결은 그 뒤 처음 공개되는 시세에서 기존 체결 규칙대로 일어납니다. 슬리피지와 수수료가 붙습니다.

조건 가격으로 체결해 주는 백테스트를 믿으면 안 되는 이유가 이 표 한 줄입니다. 실현손익은 +2.07731891, 그중 수수료가 0.09890089 였습니다.

이건 제 합성 호가에서만 그런 게 아닙니다

같은 날 운영 쪽에서 실제 Binance 시세로 돌린 검증 기록이 따로 있습니다. 그중 한 건의 자동 청산이 이렇습니다.

진입 0.00008 @ 84825.64171550 · 10:52:52.217132
상대 시간 기준 10:52:57.654862 (첫 체결의 공개 시각)
발동 10:53:27.654862 (등록 계획 = 상대 30초, 정확히 +30초)
청산 체결 0.00008 @ 84795.64958650 · 10:53:30.282224
비용 0.01356970 USDT · 순손익 −0.0159690703200 USDT

발동에서 체결까지 2.63초입니다. 재시도도 1회 있었습니다. 제 합성 호가에서 1.01초였던 그 간격이 실시세에서도 같은 성질로 나타납니다 — 조건은 청산을 시작할 뿐이고 체결은 그 뒤 처음 공개되는 시세에서 일어납니다.

그 검증에서 네 건이 돌았고 네 건 다 손실입니다 — 현물 롱(−0.0157) · USD-M 숏(−0.0990) · 슬롯 롱(−0.0144) · 최종 배포 롱(−0.0160), 전부 USDT. 30초 안에 가격이 수수료를 넘길 만큼 움직이지 않았기 때문입니다. 이게 정상입니다. 30초짜리 시험에서 기대할 것은 수익이 아니라 기록입니다.

4.3 안 되는 것으로 경계를 배우기

거절을 일부러 받아 보는 게 이 도구를 이해하는 제일 빠른 길입니다. 거절 코드가 서로 다르다는 게 핵심입니다.

무엇을 했나 응답 뜻
binance-spot 에 side: "short" 422 unsupported_direction 방향 문제. 현물에는 무보유 매도가 없습니다
미국 주식에 숏 (라이선스 안 열린 인스턴스) 422 market_not_licensed 시장 권한 문제. 방향과 무관합니다
미국 주식에 숏 (일요일) 접수는 201, 그 뒤 close_reason: "rejected:market_closed" 세션 문제. 방향은 통과했습니다
qty 를 넣어 보냄 422 (loc: ["body","qty"]) 수량은 사용자가 정할 수 없습니다
시간 조건 없이 목표가·손절가만 422 exit_plan_deadline_required 시한이 필수입니다

첫 줄의 응답에 딸려 오는 목록이 유용합니다.

"short_venues": ["binance-usdm", "bybit-linear", "cme", "us-equity"]

이 목록을 외우지 말고 응답에서 읽으세요. 저는 이 글을 쓰는 날 us-equity 가 이 목록에 새로 들어오는 것을 봤습니다. 판정이 한 곳(시장 프로필)에서 나오도록 돼 있어서, 시장 설정이 바뀌면 이 목록도 같이 바뀝니다.

세 번째 줄도 눈여겨볼 만합니다. 방향은 통과하고 세션에서 막혔습니다 — 그러니까 "숏이 안 된다"와 "지금 장이 닫혔다"를 코드로 구분할 수 있습니다. 하나의 400 Bad Request 로 뭉개지 않는 것이 자동화하는 쪽에는 꽤 큽니다.

4.4 같은 걸 두 번 보내기

에이전트를 돌리면 같은 판단이 두 번 나갑니다. 재시작하거나, 같은 봉을 다시 처리하거나, 타임아웃 뒤 재시도할 때.

보낸 것 응답 한도
같은 client_order_id + 같은 본문 200, idempotent_replay: true, 최초 응답 그대로 안 씁니다
같은 client_order_id + memo 한 글자만 다름 409 client_order_id_conflict 안 씁니다

두 번째 줄이 관대하지 않은 게 맞습니다. 본문이 달라졌다면 다른 판단이므로, 같은 이름으로 덮어쓰게 두면 나중에 기록을 못 믿습니다.

슬롯(우리 안에서 도는 규칙)에서 쓸 때는 client_order_id 를 직접 만들 필요도 없습니다 — sha256(배포 | 슬롯버전 | 봉 시각 | 규칙 id | action) 으로 자동 생성되므로, 같은 봉을 다시 흘려도 주문이 하나입니다.

4.5 내보내기 — 외부 도구가 읽는 자리

여기가 이 절차의 목적지입니다.

curl -sS "$WELTIQ_BASE_URL/v1/forward-tests/$TEST_ID/export.csv" \
  -H "Authorization: Bearer $WELTIQ_API_KEY"

CSV 머리글이 30열이고, 제가 확인하고 싶었던 6열이 끝에 있습니다.

… quote_source,published_at,side,exit_plan,exit_trigger,exit_trigger_at,exit_trigger_px,close_reason

이 6열이 없으면 스프레드시트로 읽는 도구가 "왜 닫혔는지"를 모릅니다. 수익률만 있고 사유가 없는 기록으로는 복기가 안 됩니다. close_reason 은 여덟 값입니다 — take_profit · stop_loss · close_at · close_after · max_duration · manual_exit · user_stop · window_expired.

그리고 제가 보낸 연결 필드가 그대로 돌아옵니다.

보낸 것 CSV 에서
client_tracking_id my-experiment-17
tags confirm-next-bar
metadata {"tool":"29B-review.py","external_run_id":"local-run-1"}
memo 원문 그대로

external_run_id 가 이 절차의 이음쇠입니다. 도구의 자기 런 번호를 여기 넣어 두면, 나중에 도구의 복기 스크립트가 "내 3번 런이 실제로 어떻게 끝났나"를 자기 기록과 조인할 수 있습니다.

JSON 내보내기도 있고, 그쪽 comparison 은 상세 API 의 것과 완전히 같습니다(딕셔너리 동등 비교로 확인했습니다). 두 경로가 다른 숫자를 주면 둘 다 못 믿게 되니까요.

서버가 만든 자동 청산 주문 줄도 CSV 에 함께 나옵니다 — client_order_id 는 exit-plan:<round_id>:1, memo 는 "등록된 청산 조건에 따른 자동 청산". 내 주문과 서버가 낸 주문이 기록에서 구분됩니다.

4.6 계좌가 정말 안 움직였는지 직접 보기

affects_account: false 를 믿지 말고 세 봤습니다. 시작 전과 끝난 뒤에 계좌 관련 표 아홉 개를 전량 비교했습니다 — 계좌·포트폴리오·슬리브·원장·방향 리스·감축 예약·주문 의도·체결·상태 전이.

완전히 동일했습니다. 현금 100,000 USDT 그대로, 보유·손익 0, 의도·체결 0행.

시험 주문 세 건이 접수되고 체결되고 청산되는 동안, 본계좌 쪽은 한 행도 쓰이지 않았습니다.


5. 돌려보니 무엇이 달랐나

5.1 처음으로 도구들을 나란히 놓을 수 있게 됐습니다

서버가 정하는 수량이 시장마다 이렇게 나왔습니다.

시장 종목 서버가 정한 수량 노셔널 규칙
binance-spot BTCUSDT 0.00013 6.50 USDT 최소 금액 + 20% 여유폭
binance-usdm BTCUSDT 0.002 100.00 USDT 같은 규칙 (최소 금액 50)
us-equity AAPL 1주 230.01 USD 1주 또는 1계약

주식·선물은 1주·1계약, 코인은 최소 주문금액을 넘는 최소 단위. 이게 1절 ③의 답입니다. 이제 43주와 0.1 BTC 와 6.44주를 비교하지 않고, 같은 수량 위에서 판단만 비교합니다.

5.2 도구가 요구했던 것이 무엇으로 채워지나

제가 이 연재에서 돌려 본 도구들을 이 기준으로 다시 보면 이렇게 정리됩니다.

도구가 요구했던 것 실측된 부족 시험 주문이 주는 것
표본 384건 / 1,705건 (승률·기댓값 확인) 신호 43개 월 1,000회 = 하루 33건. 계좌를 안 쓰므로 자본과 무관
관측 30건 이상 (확신도 보정) n=1 에서 자기 거절 같음. 게다가 시한만으로 닫으면 표본이 오염되지 않습니다 — 아래
매매 순서를 섞을 거래 다발 왕복 30건으로 손절선을 정했다 같음. 순서 섞기는 표본 수가 곧 힘입니다
청산 사유별 내역 자기 엔진에 수수료·슬리피지 계산이 한 줄도 없다 close_reason 여덟 값 + 비용이 실린 사유별 기록
판단의 유효기간 없어서 3,889거래 −225.29 시한이 필수 필드
비용을 바꿔 가며 같은 봉 재생 최소 티켓이 자본의 8.6% 라 사이징 규칙을 못 썼다 수량이 서버 판정 + 잔고 무영향

두 번째 줄에 한 줄 더 붙이고 싶습니다. 가격 조건 없이 시한만으로 닫는 선택지가 있다는 게 채점에 꽤 중요합니다. 목표가·손절가를 걸면 "이긴 거래가 먼저 닫히는" 편향이 표본에 들어갑니다. 시한만 걸면 잘된 것과 안된 것이 같은 규칙으로 닫히므로, 확신도를 채점할 표본이 깨끗합니다. 이건 계약이 주는 것이지 제가 만든 기법이 아닙니다.

5.3 예상과 달랐던 것 — 한도가 3이 아니라 2였습니다

접수는 3건이 승인됐고 중간에 used 가 3까지 올라가는 것을 봤습니다. 그런데 끝나고 보니 2 였습니다.

한도 원장이 이유를 그대로 말해 줬습니다.

+1  entry_accepted                     (1번)
+1  entry_accepted                     (2번)
+1  entry_accepted                     (3번)
-1  placement_rejected:market_closed    (3번 보상)

접수는 됐지만 서버가 브로커에 내보낼 때 거절된 진입은 한 번을 되돌려줍니다. 체결이 한 번도 없었으니까요. 제가 이 글을 쓰기 전에 읽은 계약 문서에는 이 보상의 기제는 적혀 있고 발동 조건이 빠져 있었습니다 — 제보했고 문서에 채워졌습니다.

참고로 접수 뒤 미체결 취소나 만료는 1회 그대로 차감입니다. 그쪽은 이미 시장에 나갔던 주문이니 다릅니다.

5.4 그래서 서른한 개를 전부 넣어 봤습니다

여기까지는 제 호출이었습니다. 그런데 "도구의 판단이 이 칸에 맞는다"는 말은 실제로 넣어 봐야 아는 것이라, 이 연재에서 돌려 둔 서른한 개의 기록된 산출물을 그대로 시험 주문에 밀어 넣었습니다. 도구를 다시 설치하지는 않았습니다 — 검증할 것이 이관이고, 그 입력은 이미 각 편의 실행 기록에 있으니까요. 127번 호출했습니다.

규율을 하나 걸었습니다. 없는 값을 지어내지 않기. 도구 기록에 시한이 없으면 지어내지 말고 먼저 시한 없이 보내 거절을 받아 그 사실을 결과로 남겼고, 실수 레벨도 먼저 그대로 보내 거절을 받고 그 다음 반올림했습니다.

편수
기계 변환만으로 들어온다 4 한 편은 아무 변환도 없었고, 한 편은 시장만 바꿨고, 두 편은 틱 반올림만 했습니다
사람이 값을 채워야 들어온다 23 거의 전부 청산 시한입니다
안 들어온다 4 둘은 방향·시한이 기록에 아예 없고, 둘은 우리와 시장이 안 겹칩니다

아무것도 안 고치고 들어온 도구는 서른한 개 중 하나였습니다.

그 하나는 레벨 두 개와 시한 48시간을 자기가 다 냈습니다. 나머지와 무엇이 달랐나 — 특별한 재주가 아니라 "언제까지"를 숫자로 적어 둔 것 하나입니다.

규칙 세 개가 나왔습니다

① 시한을 쓸 수 있게 내는 도구가 없습니다. 시한을 기록한 편이 여덟인데 전부 못 씁니다 — 절대 시각을 적은 넷은 전부 과거이고(기록이니까 당연합니다), 기간을 적은 넷은 7일 상한을 넘습니다(3개월 · 63일 · 3~6개월 · 그리고 하나 더).

② 7일 상한이 도구의 판단을 자릅니다. 어떤 도구가 "3~6개월"을 냈는데 그 자리에 7일을 넣으면, 제가 재는 것은 그 도구의 판단이 아닙니다. 이건 반올림과 급이 다릅니다 — 반올림은 값을 보정하고, 절단은 판단을 바꿉니다. 6절 ⑧에 다시 적었습니다.

③ 틱에 걸리는 도구는 정해져 있습니다. 비율이나 소수 체결가를 내는 도구는 전부 걸렸고(일곱), 정수 센트를 내는 도구는 안 걸렸습니다(넷). 4.5절에서 제가 "실수 레벨을 내는 도구는 전부 이걸 만난다"고 쓴 게 우연이 아니라 계통이었습니다.

덤으로 저희 결함 하나를 찾았습니다

시험 주문이 방향은 최신 시장 프로필로, 체결 규칙은 1번 버전으로 판정하고 있었습니다. 하필 그 때문에 "미국 주식 숏의 대차수수료가 0으로 계산된다"는 경고가 응답에 실리지 않고 있었습니다(6절 ④). 고쳤고, 그 경고가 실제로 도달하는지 검사로 박았습니다. 읽어서는 안 나왔고, 넣어 봐야 나왔습니다.


6. 아직 안 되는 것

이 절이 이 글에서 제일 중요합니다. 위 숫자들을 어디까지 믿어야 하는지가 여기 있습니다.

① 저는 합성 호가로 확인했습니다. 격리된 임시 데이터베이스에 제가 넣은 고정 호가(BTCUSDT 50000/50001, AAPL 230.00/230.02)로 돌렸고, 숏 목표가를 발동시키기 위해 런 중 한 번 호가를 48900/48901 로 내렸습니다. 그 시각은 증거 파일에 남아 있습니다.

그래서 확인된 것은 배선과 계약이고, 거래소 성능이나 실제 수수료 실증이 아닙니다. 위의 슬리피지 5.39 는 "우리 체결 모형이 이렇게 동작한다"는 뜻이고 "바이낸스에서 이만큼 밀린다"는 뜻이 아닙니다.

다만 실시세 기록이 아예 없는 것은 아닙니다 — 4.2절 뒤에 붙인 네 건이 실제 Binance 시세로 돌았습니다. 그것도 시험 원장이므로 거래소가 실계좌에 청구한 비용은 아닙니다. 수수료와 체결가 차이는 여전히 모형 결과입니다.

② 기능은 운영에 있지만, 이 글의 숫자는 격리 서버에서 나왔습니다. 시험 주문 자체는 운영에 배포돼 돌고 있습니다. 그런데 위 호출은 전부 제가 세운 격리 서버·합성 호가를 대상으로 했습니다 — 운영에서 같은 숫자가 나온다는 뜻이 아닙니다. 계약(필드 이름·거절 코드·CSV 열)은 같은 코드라 같고, 체결가·슬리피지·수수료는 다릅니다.

③ 숏은 절반만 열렸습니다. us-equity 가 새로 열렸고 binance-usdm·bybit-linear·cme 는 원래 열려 있었습니다. 현물(binance-spot·bybit-spot)과 한국 주식은 여전히 안 됩니다. 현물은 무보유 매도라는 게 애초에 없어서고, 한국 개인 공매도는 별개 문제입니다.

이게 실제로 아프게 걸립니다. 제가 앞선 편에서 "숏만 내던 도구"를 만난 적이 있는데(매수 0/9 · 매도 6), 그 도구는 현물 대상이라 숏 개방의 수혜가 0 입니다. 선물 쪽으로 옮겨야 살아납니다.

④ 미국 주식 숏의 대차수수료가 0 으로 계산됩니다. 실제로는 종목·일자별로 연 0.25%에서 수십 %까지 붙습니다. 0 으로 두면 숏을 오래 들고 있을수록 기록이 시장보다 유리해집니다.

시장 프로필이 이걸 스스로 "이 프로필의 유일한 비보수적 편향"이라고 적어 두고 있습니다. 다른 편향은 전부 비용을 과하게 잡는 방향인데 이것만 반대라서요. 시험 주문은 숏을 최대 168시간까지 열 수 있으니 이 편향을 가장 크게 안는 경로입니다.

그러니 "숏이 열렸다"를 "숏 손익을 잴 수 있다"로 읽으면 안 됩니다. 방향 전환의 타이밍은 잴 수 있고, 장기 숏의 손익은 아직 못 잽니다.

⑤ 미국 선물(CME)은 막혀 있습니다. 시세·차트는 되지만 주문 목적이 아직 열리지 않았습니다. 선물을 겨누는 조합은 여기서 멈춥니다.

⑥ 실수 레벨은 그대로 안 들어갑니다. 어떤 도구가 낸 756.2436 같은 값은 미국 주식 틱(0.01)의 배수가 아니라서 거절됩니다. 조용히 반올림해 주지 않습니다 — 조건 가격도 실제 주문과 같은 격자에 있어야 하고, 사용자가 준 가격을 서버가 몰래 바꾸면 그게 더 위험합니다. 호출하는 쪽에서 틱에 맞춰 반올림하세요. 실수 레벨을 내는 도구는 전부 이걸 만납니다.

⑦ 비중이 사라집니다. 수량을 서버가 정하니까 "이 종목에 자본의 10%"가 1주로 접힙니다. 규모와 무관한 지표(R 배수·기댓값 %·Brier)를 쓰는 도구는 아무 손해가 없지만, 비중 자체가 산출인 도구는 이 경로에서 절반을 잃습니다.

⑧ 수명 상한이 7일입니다 — 그리고 이게 ⑥보다 무겁습니다. max_duration_hours 는 1~168 입니다. 실측에서 네 도구가 여기 걸렸습니다(3개월 · 63일 · 3~6개월 · 그 밖 하나). 7일로 자르면 접수는 되는데, 자른 회차의 성적표를 그 도구의 성적표로 읽으면 안 됩니다. 지금 기록에는 「잘렸다」는 표시가 없습니다 — 자를 때 그 사실을 기록에 남기도록 고쳐 달라고 올렸습니다.

⑨ 수량이 작아서 생기는 문제가 하나 있습니다 — 먼지 잔량. 5.1절의 기준 수량은 최소 주문금액을 겨우 넘는 크기입니다. 그래서 부분 체결이 나면 남은 잔량이 최소 주문금액에 못 미치는 일이 생깁니다.

운영 검증에 그 사례가 있습니다. 진입 0.00013 @ 50006.50005 가 체결됐는데 잔량 0.00013 이 남았고, 청산 주문이 여섯 번 나가서 한 번만 체결됐습니다. 집행 거절 코드가 liquidation_rejected:min_notional, 재시도 5회. 화면이 이렇게 말합니다 — "시세가 돌아와도 풀리지 않습니다. 서버는 없는 체결을 만들거나 수량을 임의로 늘려 맞추지 않습니다."

맞는 설계입니다. 없는 체결을 지어내는 쪽이 훨씬 나쁘니까요. 다만 그 회차는 「청산 대기」로 남고 손익이 확정되지 않습니다 — 채점에 넣을 때 이 상태를 빼거나 따로 세야 합니다.

그래서 결론은 "시험 주문으로 다 하라"가 아닙니다. 비중이 중요한 도구는 기존 경로로, 판단의 적중을 재고 싶은 도구는 시험 주문으로 — 둘은 대체가 아니라 병행입니다.


7. 다음 편 예고

5.4절에서 이관까지는 서른한 개를 다 봤으니, 다음 편은 반대 방향 — 내보낸 기록을 도구의 복기 절차에 실제로 먹이는 쪽입니다. 후보를 대량으로 뽑는 도구가 앞에 서고, 표본 수를 요구하던 복기 도구가 뒤에 서는 조합입니다. 하루 33건이라는 예산을 어떻게 나눠 쓰는지도 그때 같이 적겠습니다.

그리고 6절 ④를 좁힐 방법이 하나 보입니다 — 브로커가 이미 종목별로 "빌리기 쉬운가"를 알려 주고 있고, 그 값이 이미 저장은 되고 있는데 읽히지 않고 있습니다. 그게 들어오면 대차 0 편향을 종목 단위로 줄일 수 있습니다.


이 글의 증거: 실측 로그 · 케이스별 요청·응답 원문 · 재현용 스크립트. 위 숫자는 전부 그 기록에서 가져왔고, 예상과 달랐던 5.3 절과 아직 막힌 6절도 같은 기록에 있습니다.