2026년 8월 16일 데이터 스냅샷 · 15세도 읽을 수 있는 검증 설명

자산전략 데이터,
무엇이 맞고 무엇이 비어 있나

저장된 요약표가 비어 있다고 해서 현재 화면의 계산까지 모두 틀린 것은 아닙니다. 하지만 확정 장부로 쓰기 전에는 반드시 더 확인해야 할 부분이 있습니다.

Executive Summary · 먼저 결론

빨강 · 바로 고칠 것

저장형 lotsrealized_events는 다시 계산해 채우기 전까지 상세 분석의 근거로 쓰면 안 됩니다.

노랑 · 조건부 값

원가 NULL은 화면에서 거래원장으로 복원되지만, 시작 보유분과 외부 명세가 완전해야만 정확합니다.

초록 · 현재 화면의 장점

중복 억제 6건을 빼고 FIFO를 다시 계산하므로, 오래된 저장 캐시의 -2,090.9만 원을 화면 손익으로 그대로 쓰지 않습니다.

영수증 상자, 요약 노트, 계산기는 서로 다릅니다

가장 큰 오해는 세 가지를 같은 것으로 본 것입니다. DB 안의 모든 표가 같은 역할을 하지는 않습니다.

1거래원장
매수·매도 영수증 1,562건
2저장 캐시
lots, realized_events
지금은 오래되거나 비어 있음
3현재 화면
보이는 거래 1,556건을 FIFO로 다시 계산
핵심: 저장 캐시가 부적합한 것은 사실입니다. 하지만 현재 화면은 그 캐시를 합산하지 않습니다. 그래서 “캐시가 -2,090.9만 원이니 화면도 -2,090.9만 원”이라는 결론은 맞지 않습니다.

lotsrealized_events: 버릴 표가 아니라 다시 만들 표입니다

지금 메인 화면을 계산하는 데 꼭 필요하지는 않지만, 없어도 되는 표는 아닙니다. 빠른 조회, 매도 한 건의 원가 설명, 세무 검토, 다른 화면의 일관성에는 정확한 저장 캐시가 유용합니다.

현재 저장 상태lots 0건
현재 저장 상태realized_events 3건
현재 화면 계산FIFO 매칭 이벤트 1,209건

숫자를 비교하면 저장 캐시는 -20,908,850원, 현재 화면의 동적 FIFO는 +210,367,003.4270516007041483399원입니다. 약 231,275,853원 차이는 저장 캐시가 비어 있는 문제를 보여 주지만, 그 자체를 ‘사라진 돈’으로 해석하면 안 됩니다.

따라서 권장 답은 “삭제”가 아니라 거래원장과 공식 원가법을 기준으로 다시 생성하고, 생성 시각·버전·매칭 불가 건수를 함께 남기는 것입니다. 재생성 전에는 이 두 저장 표를 손익의 정답으로 사용하지 않아야 합니다.

NULL 원가: ‘0원에 샀다’가 아니라 ‘원본 칸이 비었다’는 뜻입니다

KIS 최신 보유 10종목키움 최신 보유 1종목의 스냅샷에는 취득원가 칸이 NULL입니다. 이것은 손익이 0이라는 뜻도, 무료로 샀다는 뜻도 아닙니다.

원본 스냅샷

거래소·증권사에서 받아 저장한 현재 보유 사진입니다. 이 사진의 원가 칸이 비어 있습니다.

화면의 복원

화면은 NULL이면 과거 거래를 FIFO로 이어 붙여 남은 원가를 추정합니다.

왜 완전 정답은 아닌가

처음부터 있었던 보유분, 입출고, 분할·병합 같은 기록이 빠지면 복원 원가도 흔들립니다.

그래서 NULL은 스냅샷 수집·매핑을 고쳐야 하는 노랑 위험이고, 복원값은 참고용으로는 유용하지만 외부 원장 대사 전에는 확정값으로 쓰면 안 됩니다.

중복 거래 억제 6건 전체: 무엇을 숨겼고, 왜 수수료가 옮겨졌나

키움은 같은 거래를 ‘일별 합계’와 ‘체결별 내역’으로 둘 다 보내는 경우가 있습니다. 같은 거래를 두 번 더하면 보유 수량과 손익이 부풀기 때문에, 체결별 행만 화면과 계산에서 숨기고 원본은 남겨 둡니다.

억제 ID대표 ID종목수량거래금액원본 수수료판정
63189287840124,400원0원체결별 중복
63289287840497,800원10원체결별 중복
633892878402455,978,000원860원체결별 중복
6289108227059649,000원0원체결별 중복
629910822701381,519,380원320원체결별 중복
63091082270333,000원0원체결별 중복

지금 규칙은 어떻게 작동하나요?

같은 제공자·계좌·종목·날짜·매수/매도 안에서, 체결별 수량의 합이 일별 합계 수량과 정확히 같고, 거래금액 차이가 수량 이하(주당 1원 이내)일 때만 억제합니다. 원본 행을 지우지 않고 따로 ‘숨김’ 표시만 남깁니다.

현재 6건에는 적합해 보입니다. 대표 89는 수량 250주가 같고 금액 차이는 50원, 대표 91은 수량 200주가 같고 금액 차이는 20원입니다. 수수료도 억제 행에서 대표 행으로 합산됩니다.

다만 일반 규칙으로는 조건부 적합입니다. 같은 날짜에 우연히 같은 수량·금액이 나온 독립 거래를 완전히 배제하지는 못합니다. 지금처럼 API 종류까지 구분하고 원본을 삭제하지 않는 점은 안전하지만, 억제된 묶음마다 검토 기록을 남기는 자동 점검이 필요합니다.

수수료: 0원 표기와 진짜 누락은 다릅니다

수수료 NULL은 0건입니다. 그러나 숫자 0은 “정말 무료”일 수도 있고 “수집기가 수수료를 받지 못했다”는 뜻일 수도 있습니다. 그래서 0원만 세어서는 누락 여부를 확정할 수 없습니다.

제공자거래 수원본 0원보정 후 0원판정
업비트78511주문 응답의 수수료를 읽음. 1건은 원본 명세 확인 필요
빗썸20766주문 응답의 수수료를 읽음. 6건은 원본 명세 확인 필요
키움2914341대표 ID 89·91은 억제 행 수수료 1,190원으로 보정됨
토스1496262수수료와 세금을 읽음. 0원은 원본 명세 확인 필요
KIS130130130현재 수집 코드가 0원을 넣음. 가장 큰 누락 위험
대표 거래의 예: ID 89의 원본 수수료는 0원이지만 억제 ID 631·632·633의 수수료 0원+10원+860원이 합쳐져 유효 수수료 870원이 됩니다. ID 91도 0원+0원+320원+0원으로 320원입니다. 두 묶음의 보정 수수료는 1,190원입니다.

실제 누락 위험은 KIS가 가장 큽니다. KIS 거래 130건은 현재 코드가 모두 0원으로 저장합니다. 이것은 “수수료가 없었다”는 증명이 아니므로, 거래명세에서 수수료·세금을 받아 매핑하기 전까지 KIS 실현손익은 과대평가될 수 있습니다.

FIFO와 이동평균: 전량 청산하면 언제 같아지나?

네, 조건이 갖춰지면 둘의 누적 실현손익은 같아져야 합니다. FIFO는 먼저 산 것을 먼저 판 것으로 보고, 이동평균은 산 가격의 평균으로 봅니다. 그래서 중간에 일부만 팔면 손익이 다르게 보입니다.

반드시 같아야 하는 조건 1같은 시작 보유분
조건 2모든 매수·매도·수수료가 포함
조건 3마지막에 전량 청산

세 조건이 맞으면, 결국 팔린 물건의 총원가와 총매도금액은 같기 때문입니다. 반대로 시작 보유분이 빠졌거나, 중복 거래를 두 번 더했거나, 수수료가 비었거나, 아직 들고 있는 수량이 있으면 값이 달라질 수 있습니다.

현재 DB는 중복 억제 6건과 SOL 0.0007541의 매칭 불가 매도가 있어, FIFO와 이동평균의 차이를 곧바로 ‘사라진 돈’이나 ‘오류 금액’이라고 부르면 안 됩니다.

최종 판정과 다음 확인

저장 캐시

부적합. 다시 생성하기 전에는 실현손익의 근거로 사용 금지.

현재 화면

조건부 사용 가능. 거래원장 FIFO 복원값임을 표시하고 매칭 불가·NULL 원가 경고를 유지.

확정 장부

아직 부적합. 외부 원장 대사와 KIS 수수료 매핑 전에는 세무·회계 확정값으로 사용 금지.

다음에 꼭 확인할 것

  1. 공식 원가법을 FIFO 또는 이동평균 중 하나로 정하고, 시작 보유분도 함께 등록합니다.
  2. lotsrealized_events를 거래원장 기준으로 재생성하고 생성 시각을 남깁니다.
  3. KIS 거래명세에서 수수료·세금을 가져와 130건의 0원 처리 여부를 대사합니다.
  4. 중복 억제 묶음과 매칭 불가 매도를 자동 경고로 남겨 사람이 확인하게 합니다.
이 보고서가 답하지 못하는 질문

외부 원장 대사 없이 이 데이터가 모든 거래·입출고·시작 보유분을 빠짐없이 담았다고 증명할 수는 없습니다. 이 페이지는 2026년 8월 16일의 JSON 내보내기, 현재 SQLite, 배포 코드에 대한 검증 스냅샷입니다.