8 / 12 · AUTO TRADING WIKI
페이퍼 주문을 시작하기 전 확인할 것
시뮬레이션의 누락·중복·미래 데이터 사용을 점검하고 진행 기준을 정합니다.
과거 시뮬레이션이 끝나도 바로 반복 실행을 시작하지 않는다. 이번 장에서는 결과가 재현되는지, 데이터 문제가 숨겨져 있지 않은지, 가상 자금과 주문 상태를 기록할 준비가 되었는지 확인한다.
이 책에서 paper는 로컬 프로그램이 가상 주문·체결·잔고를 기록하는 학습 모드다. 한국투자증권의 모의투자 서버를 이용하는 방식과 구분한다. 이번 장에서도 외부 주문 요청을 보내지 않으며, 예시 숫자는 실제 투자 결과가 아니다.
1. 성과 판단과 기술적 준비를 구분하기
시뮬레이션 수익률이 높다는 이유로 페이퍼 실행을 허용하면 계산 오류가 좋은 결과처럼 통과할 수 있다. 반대로 손실 결과라고 해서 날짜와 원장이 정확한 프로그램을 고장이라고 판단할 필요도 없다. 이번 점검은 프로그램의 처리·기록 품질을 대상으로 한다.
| 검토 영역 | 질문 | 이번 장의 판단 |
|---|---|---|
| 데이터 | 같은 입력을 다시 찾을 수 있는가 | 누락과 변경을 추적 |
| 계산 | CCI와 T+1 연결이 규칙에 맞는가 | 작은 사례로 대조 |
| 실행 | 중단과 재실행이 중복을 만들지 않는가 | 실패 주입으로 확인 |
| 전략 | 향후에도 수익을 낼 것인가 | 이 점검으로 결론 내리지 않음 |
CCI20의 -100 상향 돌파, T+1 시가 진입, 진입일 포함 5번째 거래 세션 종가 청산이라는 예제 규칙을 유지한다. 준비 점검 중 결과를 좋게 만들려고 기간이나 청산 규칙을 바꾸면 비교 기준이 사라진다.
2. 재현 자료를 하나의 묶음으로 만들기
7장의 결과 폴더와 연결되는 readiness_id를 만든다. 원본 데이터 전체를 보고서에 복사할 필요는 없지만, 어떤 원본을 사용했는지 다시 찾을 수 있어야 한다.
outputs/readiness/demo-review-01/
input_manifest.json
checks.csv
summary.json
failed_cases.csv
input_manifest.json에 시뮬레이션 run_id, dataset_id, 코드 버전, 설정 해시, 대상 종목의 기준일, 조회 시작·끝 날짜를 적는다. checks.csv에는 점검 항목별 PASS, FAIL, NOT_EVALUATED와 증거 파일 경로를 기록한다.
증거가 없는 항목은 PASS가 아니다. 아직 만들지 않은 복구 시험을 “향후 확인 예정”이라고 적었다면 NOT_EVALUATED로 남기고 다음 단계 허용을 보류한다. 로그가 없거나 파일을 읽을 수 없는 경우도 같은 방식으로 다룬다.
3. 다섯 종목에서 전체 대상으로 확장하기
작은 사례가 통과하면 대상 목록을 확장하되 한 번에 계산 규칙까지 바꾸지 않는다. 처음 다섯 종목의 결과가 전체 실행에서도 동일한지 대조하고, 새로 추가된 종목의 가격 누락과 조정 정책을 확인한다.
daily_prices에서 다음 쿼리는 키 중복을 찾아낸다. 기본 키가 이미 중복을 막더라도 수집 전 임시 데이터와 수입 과정에도 같은 검사를 적용한다.
SELECT symbol, trade_date, COUNT(*) AS cnt
FROM daily_prices
GROUP BY symbol, trade_date
HAVING COUNT(*) > 1;
SELECT symbol, trade_date, open, high, low, close, volume
FROM daily_prices
WHERE open <= 0 OR close <= 0 OR volume < 0
OR high < low OR high < GREATEST(open, close)
OR low > LEAST(open, close);이 쿼리가 0행이어도 데이터 검증이 끝난 것은 아니다. 아예 빠진 거래일은 행이 없어서 위 조건에 걸리지 않는다. 수집 대상·거래 캘린더·원본 조회 결과를 비교해 누락을 찾는다. 거래정지와 단순 수집 실패도 구분한다.
대상 목록을 “현재 코스피200”으로만 구했다면 과거 구성 종목 전체를 재현한 연구가 아니라 현재 목록에 대한 과거 계산이다. 이 제한을 보고서 첫 부분에 명시하고, 그 결과를 장기 성과 검증으로 표현하지 않는다.
4. 통과 조건을 점검 전에 작성하기
config/paper_readiness.json의 기준은 결과를 확인하기 전에 정한다. 다음 숫자는 교육용 기능 시험의 기준이며 투자 적합성을 나타내는 수치가 아니다.
{
"review_version": "paper-gate-v1",
"required_fixture_cases": 8,
"max_duplicate_keys": 0,
"max_unexplained_missing_sessions": 0,
"max_reconciliation_difference": "0.00",
"required_repeat_consistency": true,
"required_failure_recovery": true,
"require_all_checks_evaluated": true,
"permit_mode": "paper"
}8개 사례는 상승·하락·비용 후 손실·신호 없음·데이터 부족·중복 신호·재실행·중간 실패로 구성한다. 각 사례의 입력과 기대 상태를 따로 저장한다. 이미 나온 결과를 그대로 기대값으로 복사하는 방식은 오류를 찾지 못한다.
비용 후 손실 사례에는 예를 들어 매수가와 매도가가 모두 10,000인 거래를 넣는다. 비용 전 손익은 0이지만 수수료·가정 세금을 빼면 순손익은 음수여야 한다. “가격이 같으면 항상 보합”이라고 분류하는 오류를 잡을 수 있다.
5. 요약표에 분모와 제외 사유를 함께 넣기
다음은 가상 결과다. 숫자의 크기보다 같은 기준으로 집계했는지 살펴본다.
| 항목 | 예시 | 해석 |
|---|---|---|
| 전체 신호 | 21건 | 모든 처리 결과의 분모 |
| 완료 | 15건 | 진입·청산 가격이 모두 존재 |
| 보유 중 제외 | 2건 | 중복 진입 금지 규칙 적용 |
| 기간 끝 미완료 | 4건 | 청산 가격 미확정 |
| 원인 불명 누락 | 0건 | 있다면 차단 |
| 중복 결과 | 0건 | 있다면 차단 |
| 원장 차이 | 0.00 | 현금·수량·체결 대조 |
평균 손익과 승률에는 완료 건수라는 분모를 표시한다. 여러 종목의 거래 수익률 평균을 전체 자산 수익률로 쓰지 않는다. 최대 낙폭을 계산하려면 같은 시점별 현금, 보유 수량, 평가 가격을 사용한 자산 곡선이 별도로 필요하다.
현재 시뮬레이션이 종목별 독립 계산이라면 “동시에 모든 신호를 살 자금이 있었다”는 가정을 내포할 수 있다. 다음 장에서는 초기 가상 현금, 주문당 한도, 최대 보유 수, 현금 예약을 넣어 이 차이를 드러낸다.
6. 비용과 기간에 대한 민감도 확인하기
기준 실행을 보관한 채 비용만 바꾼 별도 실행을 만든다. 예를 들어 슬리피지 가정이 커질수록 순손익이 어떻게 달라지는지 확인한다. 요율은 소수로 읽는지 bp로 읽는지 함께 적는다. 5bp = 0.0005이므로 0.05와 혼동하면 비용이 100배가 된다.
기간도 학습 구간과 검토 구간을 시간순으로 나눈다. 검토 구간 결과를 본 뒤 매번 규칙을 고쳐 다시 검토하면 그 구간도 개발에 사용한 셈이다. 어떤 기간을 언제 보았는지 변경 기록에 남긴다.
일봉에서 장중 손절·익절 순서를 알 수 없다는 제한은 그대로 유지된다. 민감도 표에 가정만 추가했다고 체결 품질이 입증되지는 않는다. 고정 청산 예제의 범위와 데이터 해상도를 보고서에 함께 쓴다.
7. 준비 판정을 기계가 읽을 수 있게 남기기
단순히 “통과”라는 파일이 존재하는지만 검사하면 예전 결과가 새 설정에도 사용될 수 있다. 판정에는 입력의 버전과 허용 범위를 함께 넣고, 이후 실행이 달라지면 무효로 취급한다.
{
"readiness_id": "demo-review-01",
"decision": "READY_FOR_LOCAL_PAPER",
"strategy_version": "cci20_cross_up_m100_v1",
"dataset_id": "fixture-v1",
"config_hash": "EXAMPLE_ONLY_REPLACE_WITH_COMPUTED_HASH",
"checks_passed": 8,
"checks_failed": 0,
"not_evaluated": 0,
"scope": "local_paper_only",
"external_orders_permitted": false
}이 예시 파일을 복사하는 것만으로 점검이 통과되지는 않는다. 실제 프로그램은 자신의 입력에서 해시를 계산하고 시험 결과로 판정을 생성해야 한다. 해시 계산의 기본 API는 Python 공식 hashlib 문서를 참고한다.
8. Codex에 검토 범위를 분명하게 전달하기
7장의 시뮬레이션을 로컬 paper 실행으로 확장할 준비가 되었는지 검토해줘.
소스·설정·데이터 식별자를 연결한 checks.csv와 summary.json을 만들어줘.
8개 가상 사례의 기대값을 먼저 정하고 날짜·비용·중복·중간 실패를 확인해.
종목 전체 확장에서는 처음 5개 결과의 일관성과 누락 사유를 대조해.
성과 지표와 기술 통과 조건을 구분하고 미검사 항목을 PASS로 처리하지 마.
파일 이름이나 실행 옵션은 현재 프로젝트에 맞게 제안하고 근거를 적어줘.
투자 적합성 판단, 실전 주문, 증권사 모의주문 요청은 수행하지 마.
검토 결과가 BLOCKED라면 모든 파일을 다시 만들지 않는다. 실패 항목과 관련된 가장 작은 입력을 재현하고, 수정 후 그 항목과 연관 검사를 다시 실행한다. 수정 전 결과도 남겨 원인을 비교한다.
9. 완료 기준과 문제 해결
이번 장을 마쳤다는 뜻은 준비 보고서가 존재하고 모든 기술 조건의 증거를 찾을 수 있다는 것이다. 보고서가 막힌 상태라면 다음 장을 읽을 수는 있지만 반복 실행을 허용하지 않는다. 기술 점검의 통과는 실전 거래 허가가 아니다.
| 증상 | 확인할 내용 |
|---|---|
| 승률만 있고 완료 건수가 없음 | 집계의 분모와 미완료 제외 방식 |
| 전체 확장 후 기존 결과가 달라짐 | 대상별 계산 경계, 정렬, 데이터 버전 |
| 설정 변경 후에도 이전 통과 사용 | 설정 해시 대조와 판정 무효화 |
| 비용을 높여도 순손익이 그대로임 | 비용 계산이 보고서에 반영되는지 |
| 미검사 항목이 통과로 표시됨 | 기본 상태를 NOT_EVALUATED로 두었는지 |
한국투자증권의 모의투자나 실전 API 사용 조건은 이 로컬 준비 보고서의 범위 밖이다. 해당 환경을 별도로 검토할 때는 KIS Developers 공식 안내의 API 문서와 현재 공지를 확인한다. 다음 장에서는 외부 주문 연결 없이 가상 주문 원장을 만든다.
공유 링크를 복사해 이어서 읽을 수 있습니다.