트레이딩 로그 설계 완전 가이드: 로그·리플레이·리뷰로 “왜 그 결정을 했는지” 남기는 법

최종 수정: 작성자: Finyul

전략이 흔들릴 때 진짜 문제는 “수익이 줄었다”가 아니라 원인을 못 찾는 것입니다. 이 글은 로그 구조(필드/스키마) → 리플레이(재현) → 리뷰 루틴(개선)으로 AI 트레이딩을 증거 기반으로 운영하는 방법을 제공합니다.

전체 폐루프(분석→예측→결정→실행) 큰 그림이 궁금하면 LLM 멀티에이전트 투자 시스템(MAS) 완전 가이드를 참고하세요.

트레이딩 로그 유무에 따른 디버깅 가능성 비교: 로그 없음(원인 불명) vs 로그 있음(원인 추적)
로그 없음(원인 불명) vs 로그 있음(원인 추적) 비교.

왜 로그가 ‘성과’보다 중요할 때가 많나: 재현·디버깅·감사의 기반

AI/멀티에이전트 시스템에서 성과가 나빠졌을 때, 원인은 보통 세 곳 중 하나입니다.

  • 입력이 바뀌었는데 모르고 있다(데이터 버전/윈도우/누락)
  • 출력이 흔들렸는데 “왜 흔들렸는지”가 없다(스키마/검증/재시도 기록 부재)
  • 실행에서 깨졌는데 백테스트처럼 생각한다(체결 실패/부분체결/슬리피지)

로그가 없으면 결국 “뉴스 때문인가?”, “지표 때문인가?”, “내가 멘탈이 흔들렸나?”로 끝납니다.

비교 항목로그 없음로그 있음
디버깅 시간길다짧다
재현성낮음높음
리뷰 품질낮음높음
규칙 준수확인 어려움검증 가능
책임 추적불가가능

용어 3개만 정리해도 설계가 빨라진다

용어정의구성·목적효과
관측성(Observability)운영 중 시스템이 “보이게” 만드는 것로그 / 트레이스 / 메트릭원인·상태를 언제든 확인 가능
리플레이(Replay)동일 입력·동일 설정으로 다시 실행해 결과를 재현하는 것원인 파악·재현성 검증같은 입력이면 같은 결과 보장
감사(Audit Trail)“왜 그런 결정을 했는지” 근거를 나중에 증명 가능한 형태로 남기는 것규칙 준수·개선 근거결정 근거·규칙 위반 추적 가능

보이게 → 재현하게 → 증명하게

좋은 로그의 원칙 7개: 무엇을 남길지부터 정하라

1) 5W1H로 필드 설계를 시작한다

  • When: 언제(as_of, timestamp)
  • What: 무엇을 봤나(input snapshot)
  • Who: 누가 판단했나(agent/model/prompt)
  • Why: 왜 그렇게 했나(rationale/evidence)
  • How: 어떻게 검증했나(validation/retry)
  • Result: 결과가 어땠나(order/fill/cost)

2) 입력 스냅샷은 “해시”로 고정한다

데이터가 바뀌면 결과도 바뀝니다. inputs_hash(예: sha256)로 “그날 봤던 데이터”를 고정하세요.

3) 출력은 스키마로 고정한다(흔들림 차단)

에이전트가 텍스트로 말하면 운영에서 다 무너집니다. JSON 스키마 + enum + 필수 필드로 “형식 환각”부터 막으세요. LLM 에이전트 출력 표준화: JSON 스키마 템플릿으로 분석→예측→결정 연결하기를 참고하세요.

4) 검증(Validation) 결과를 반드시 남긴다

schema_valid / domain_valid / failed_rule / retry_count / fallback(HOLD) 이유. 이게 없으면 “왜 HOLD였는지”도 못 찾습니다.

5) 실행은 백테스트가 아니다: 주문/체결을 별도 이벤트로 남긴다

주문 생성(Order)과 체결(Fill)은 다릅니다. 부분체결/거부/지연은 실행 로그에만 있습니다.

6) 변경 이력은 run_id로 분리한다(버전 관리)

모델/프롬프트/파라미터/데이터 소스가 바뀌면 같은 전략이 아닙니다. run_id로 분리하세요.

7) 사람용 요약과 기계용 원문을 분리 저장한다

“요약만” 남기면 나중에 검증이 안 됩니다. 원문 JSON은 그대로 저장하고, 요약은 별도 컬럼으로 두세요.

원칙이유실수 사례권장 필드
5W1H로 설계누락 시 리뷰/리플레이 불가timestamp 없이 요약만 저장as_of, input_ref, agent, rationale, validation, order_id
inputs_hash로 입력 고정데이터 변경 시 결과 달라짐inputs_hash 미저장inputs_hash (sha256 등)
출력 스키마/enum 고정형식 흔들림 → 파싱/검증 붕괴텍스트 출력만 저장schema_id, output(JSON 원문)
검증결과·재시도·폴백 기록HOLD/폴백 사유 추적failed_rule 미기록schema_valid, domain_valid, failed_rule, retry_count
주문/체결 분리 기록실행 현실 반영Order만 있고 Fill 없음Order 이벤트, Fill 이벤트(filled_qty, avg_price, fee_rate)
모델/프롬프트/파라미터 버전 분리(run_id)버전/실험 분리버전 섞여 리플레이 불가run_id (모든 이벤트 공통)
원문(JSON)과 요약 분리검증 시 원문 필요요약만 저장 후 재검증 불가summary(텍스트), raw(JSON)

로그 스키마 핵심: 이벤트 기반 LogEvent로 쪼개라

“거대한 한 줄 로그”는 리뷰할수록 지옥입니다. 아래처럼 이벤트 단위로 쪼개면 리플레이가 쉬워집니다.

이벤트 타입필수 필드예시저장 위치
InputSnapshotrun_id, as_of, asset, inputs_hash, data_windowdata_window: last_60dJSONL / DB
AgentOutputrun_id, as_of, asset, schema_id, agent, outputprediction → T5 up/down/sideJSONL / DB
Validationrun_id, as_of, schema_valid, domain_valid, retry_counttrue, true, 0JSONL / DB
Decisionrun_id, as_of, action, rationale, constraints_appliedincrease_20, ["T5 up 우세"]JSONL / DB
Orderrun_id, as_of, side, qty, order_typeBUY, qty, MKTJSONL / DB
Fillrun_id, as_of, filled_qty, avg_price, fee_ratefilled_qty, avg_price, fee_rateJSONL / DB

복붙용 미니 예시(JSONL 느낌)

InputSnapshot2025-01-10_REIT_X_0007
{
  "event": "InputSnapshot",
  "run_id": "2025-01-10_REIT_X_0007",
  "as_of": "2025-01-10T09:05:00+09:00",
  "asset": "REIT_X",
  "inputs_hash": "sha256:...",
  "data_window": "last_60d"
}
AgentOutput2025-01-10_REIT_X_0007
{
  "event": "AgentOutput",
  "agent": "prediction",
  "schema_id": "prediction_output_v1",
  "run_id": "2025-01-10_REIT_X_0007",
  "horizons": [
    "T1",
    "T5",
    "T20"
  ],
  "output": {
    "T5": {
      "up": 0.44,
      "down": 0.18,
      "side": 0.38
    }
  }
}
Validation2025-01-10_REIT_X_0007
{
  "event": "Validation",
  "run_id": "2025-01-10_REIT_X_0007",
  "schema_valid": true,
  "domain_valid": true,
  "retry_count": 0
}
Decision2025-01-10_REIT_X_0007
{
  "event": "Decision",
  "run_id": "2025-01-10_REIT_X_0007",
  "action": "increase_20",
  "rationale": [
    "T5 up 우세",
    "cap/step OK"
  ],
  "constraints_applied": [
    "position_cap",
    "step_size"
  ]
}
Order2025-01-10_REIT_X_0007
{
  "event": "Order",
  "run_id": "2025-01-10_REIT_X_0007",
  "side": "BUY",
  "qty": 100,
  "order_type": "MKT"
}
Fill2025-01-10_REIT_X_0007
{
  "event": "Fill",
  "run_id": "2025-01-10_REIT_X_0007",
  "filled_qty": 80,
  "avg_price": 101.2,
  "fee_rate": 0.0003
}
트레이딩 로그 이벤트 흐름 구조: 입력→출력→검증→결정→주문→체결
로그 이벤트 구조도(입력→출력→검증→결정→주문→체결).

저장/조회 설계: “남긴 로그를 찾을 수 있어야” 의미가 있다

  • JSONL: 개발/디버깅 친화(원문 그대로)
  • Parquet: 분석/집계 친화(대규모 백테스트 로그)
  • DB(또는 검색 인덱스): 운영 조회 친화(대시보드, 필터링)

권장 파티셔닝 키: date / strategy / asset / run_id

입력-출력-검증-주문 결과를 재실행하는 리플레이 대시보드 예시
로그/리플레이 대시보드 와이어프레임 예시.

리플레이(Replay): “같은 입력이면 같은 결과”를 보장하는 체크리스트

리플레이가 깨지는 가장 흔한 원인은 데이터/버전/랜덤성입니다.

리플레이 3종

  • Full replay: 입력부터 실행까지 전체 재실행
  • Step replay: 분석만/예측만/결정만 단계별 재실행(원인 파악에 최고)
  • What-if: 가정(가중치/제약/임계값)만 바꿔 비교

리플레이 체크리스트(필수)

  • inputs_hash 동일
  • 모델/프롬프트 버전 동일
  • 파라미터 스냅샷 동일(윈도우/임계값/가중치)
  • validation/retry 정책 동일(HOLD 폴백 포함)

리뷰 루틴: 로그는 쌓이면 쓰레기, 템플릿이 있어야 자산

데일리(1~3분): 3줄 리뷰

  • 오늘의 최종 결정(action)
  • 근거(evidence) 1줄
  • 규칙 위반/폴백(HOLD) 여부

주간(30분): 5개만 본다

항목정의기준선다음 액션
성과(수익/낙폭)주간 수익률·최대낙폭 등
규칙 준수율(%)검증 통과·제약 준수 비율
결정 변경 횟수(주간)같은 일/세션 내 최종 결정이 바뀐 횟수의 주간 합
폴백(HOLD) 비율 및 사유 Top3검증 실패 또는 Stop rule로 실행 보류한 비율·사유
실패 유형 Top3파싱/스키마/도메인/실행 실패 건수·유형
주간 규칙 준수율과 손익 추이(운영 로그 집계).
주간 ‘결정 변경 횟수’ 추이(운영 로그).

로그가 “원인 추적 시간”을 줄이는 실제 운영 시나리오

Before(로그 없음)

“뉴스가 불안해서 손절했는데, 나중에 보니 기술적으론 계속 추세였다” → 원인 추정만 반복.

After(로그/검증 있음)

  • AgentOutput에서 뉴스 신호 evidence_ref가 비었음 → 근거 부족
  • Validation에서 failed_rule=evidence_missing → HOLD 폴백이 맞았음
  • 다음 주에는 “뉴스 신호의 품질 규칙”을 강화(중복/출처 불명 강등)

즉, ‘감’이 아니라 로그가 다음 개선을 결정합니다.

운영 품질 지표 3종 정의

재현 실패율 · 검증 실패율 · 폴백 사유 Top5. 내부 로그 집계로 정의·추적.

지표정의집계(내부 로그)
재현 실패율동일 inputs_hash·동일 설정으로 재실행 시 출력/결정이 원본과 불일치한 run 비율4주 572 run 중 12건 불일치 → 2.1%
검증 실패율schema_valid 또는 domain_valid가 false인 AgentOutput 비율4주 584건 중 31건 실패 → 5.3%
폴백 사유 Top5Decision=HOLD 또는 실행 보류된 사유(Validation/Stop rule)별 건수
1) evidence_missing28건
2) position_cap19건
3) step_size14건
4) max_drawdown_breach9건
5) schema_parse_error5건

출처: 내부 로그(운영 환경 run_id·Validation·Decision 이벤트 집계).

한계와 주의사항

  • 로그가 완벽해도 입력 데이터가 틀리면 결과도 틀립니다(입력 품질이 최상위).
  • 실거래는 체결/슬리피지/지연이 있어 백테스트와 다릅니다 → Order/Fill 로그 필수
  • 계정/개인정보 등 민감 데이터는 마스킹/접근권한 분리/보관기간 정책이 필요합니다.

외부 참고:

  • NIST AI RMF— AI 리스크 관리 프레임워크
  • OpenTelemetry/CNCF— 관측성(로그·트레이스·메트릭) 표준
  • SEC · FINRA— 알고리즘·자동매매 리스크 고지 가이드 참고

FAQ

자주 묻는 질문

로그는 어디까지 남겨야 하나요?
리플레이에 필요한 "입력 스냅샷·출력 원문·검증 결과·주문/체결"까지는 필수입니다. 요약만 남기면 나중에 못 고칩니다.
리플레이가 안 되는 가장 흔한 이유는?
데이터가 업데이트됐는데 inputs_hash를 안 남긴 경우, 또는 모델/프롬프트 버전이 섞인 경우입니다.
멀티에이전트에서 누가 문제였는지 어떻게 찾나요?
Step replay(단계별 재실행) + Validation 로그(어떤 규칙이 깨졌는지) 조합이 가장 빠릅니다.

결론: “로그→리플레이→리뷰”가 돌아가면 시스템은 자동으로 강해진다

  • 입력을 해시로 고정하고
  • 출력은 스키마로 고정하고
  • 검증/재시도/폴백을 기록하고
  • 주문/체결까지 현실을 남기고
  • 주간 리뷰로 한 번에 하나씩 개선하세요.

전체 구조로 확장하려면 LLM 멀티에이전트 투자 시스템(MAS) 완전 가이드. 출력 흔들림부터 잡으려면 LLM 에이전트 출력 표준화: JSON 스키마 템플릿으로 분석→예측→결정 연결하기를 참고하세요.

데이터 기준 시점
2026-02-26
계산 방식
로그·리플레이·리뷰 설계 개념 정리. 투자 권유 아님.
한계점
실제 구현·저장소는 환경에 따라 다르며, 과장·보장 표현 없음.