빨강 · 바로 고칠 것
저장형 lots와 realized_events는 다시 계산해 채우기 전까지 상세 분석의 근거로 쓰면 안 됩니다.
2026년 8월 16일 데이터 스냅샷 · 15세도 읽을 수 있는 검증 설명
저장된 요약표가 비어 있다고 해서 현재 화면의 계산까지 모두 틀린 것은 아닙니다. 하지만 확정 장부로 쓰기 전에는 반드시 더 확인해야 할 부분이 있습니다.
realized_events는 3건뿐이고 lots는 0건이라, 이 두 표만 믿고 손익을 보면 안 됩니다.저장형 lots와 realized_events는 다시 계산해 채우기 전까지 상세 분석의 근거로 쓰면 안 됩니다.
원가 NULL은 화면에서 거래원장으로 복원되지만, 시작 보유분과 외부 명세가 완전해야만 정확합니다.
중복 억제 6건을 빼고 FIFO를 다시 계산하므로, 오래된 저장 캐시의 -2,090.9만 원을 화면 손익으로 그대로 쓰지 않습니다.
가장 큰 오해는 세 가지를 같은 것으로 본 것입니다. DB 안의 모든 표가 같은 역할을 하지는 않습니다.
lots, realized_eventslots와 realized_events: 버릴 표가 아니라 다시 만들 표입니다지금 메인 화면을 계산하는 데 꼭 필요하지는 않지만, 없어도 되는 표는 아닙니다. 빠른 조회, 매도 한 건의 원가 설명, 세무 검토, 다른 화면의 일관성에는 정확한 저장 캐시가 유용합니다.
숫자를 비교하면 저장 캐시는 -20,908,850원, 현재 화면의 동적 FIFO는 +210,367,003.4270516007041483399원입니다. 약 231,275,853원 차이는 저장 캐시가 비어 있는 문제를 보여 주지만, 그 자체를 ‘사라진 돈’으로 해석하면 안 됩니다.
따라서 권장 답은 “삭제”가 아니라 거래원장과 공식 원가법을 기준으로 다시 생성하고, 생성 시각·버전·매칭 불가 건수를 함께 남기는 것입니다. 재생성 전에는 이 두 저장 표를 손익의 정답으로 사용하지 않아야 합니다.
KIS 최신 보유 10종목과 키움 최신 보유 1종목의 스냅샷에는 취득원가 칸이 NULL입니다. 이것은 손익이 0이라는 뜻도, 무료로 샀다는 뜻도 아닙니다.
거래소·증권사에서 받아 저장한 현재 보유 사진입니다. 이 사진의 원가 칸이 비어 있습니다.
화면은 NULL이면 과거 거래를 FIFO로 이어 붙여 남은 원가를 추정합니다.
처음부터 있었던 보유분, 입출고, 분할·병합 같은 기록이 빠지면 복원 원가도 흔들립니다.
그래서 NULL은 스냅샷 수집·매핑을 고쳐야 하는 노랑 위험이고, 복원값은 참고용으로는 유용하지만 외부 원장 대사 전에는 확정값으로 쓰면 안 됩니다.
키움은 같은 거래를 ‘일별 합계’와 ‘체결별 내역’으로 둘 다 보내는 경우가 있습니다. 같은 거래를 두 번 더하면 보유 수량과 손익이 부풀기 때문에, 체결별 행만 화면과 계산에서 숨기고 원본은 남겨 둡니다.
| 억제 ID | 대표 ID | 종목 | 수량 | 거래금액 | 원본 수수료 | 판정 |
|---|---|---|---|---|---|---|
| 631 | 89 | 287840 | 1 | 24,400원 | 0원 | 체결별 중복 |
| 632 | 89 | 287840 | 4 | 97,800원 | 10원 | 체결별 중복 |
| 633 | 89 | 287840 | 245 | 5,978,000원 | 860원 | 체결별 중복 |
| 628 | 91 | 082270 | 59 | 649,000원 | 0원 | 체결별 중복 |
| 629 | 91 | 082270 | 138 | 1,519,380원 | 320원 | 체결별 중복 |
| 630 | 91 | 082270 | 3 | 33,000원 | 0원 | 체결별 중복 |
같은 제공자·계좌·종목·날짜·매수/매도 안에서, 체결별 수량의 합이 일별 합계 수량과 정확히 같고, 거래금액 차이가 수량 이하(주당 1원 이내)일 때만 억제합니다. 원본 행을 지우지 않고 따로 ‘숨김’ 표시만 남깁니다.
현재 6건에는 적합해 보입니다. 대표 89는 수량 250주가 같고 금액 차이는 50원, 대표 91은 수량 200주가 같고 금액 차이는 20원입니다. 수수료도 억제 행에서 대표 행으로 합산됩니다.
다만 일반 규칙으로는 조건부 적합입니다. 같은 날짜에 우연히 같은 수량·금액이 나온 독립 거래를 완전히 배제하지는 못합니다. 지금처럼 API 종류까지 구분하고 원본을 삭제하지 않는 점은 안전하지만, 억제된 묶음마다 검토 기록을 남기는 자동 점검이 필요합니다.
수수료 NULL은 0건입니다. 그러나 숫자 0은 “정말 무료”일 수도 있고 “수집기가 수수료를 받지 못했다”는 뜻일 수도 있습니다. 그래서 0원만 세어서는 누락 여부를 확정할 수 없습니다.
| 제공자 | 거래 수 | 원본 0원 | 보정 후 0원 | 판정 |
|---|---|---|---|---|
| 업비트 | 785 | 1 | 1 | 주문 응답의 수수료를 읽음. 1건은 원본 명세 확인 필요 |
| 빗썸 | 207 | 6 | 6 | 주문 응답의 수수료를 읽음. 6건은 원본 명세 확인 필요 |
| 키움 | 291 | 43 | 41 | 대표 ID 89·91은 억제 행 수수료 1,190원으로 보정됨 |
| 토스 | 149 | 62 | 62 | 수수료와 세금을 읽음. 0원은 원본 명세 확인 필요 |
| KIS | 130 | 130 | 130 | 현재 수집 코드가 0원을 넣음. 가장 큰 누락 위험 |
실제 누락 위험은 KIS가 가장 큽니다. KIS 거래 130건은 현재 코드가 모두 0원으로 저장합니다. 이것은 “수수료가 없었다”는 증명이 아니므로, 거래명세에서 수수료·세금을 받아 매핑하기 전까지 KIS 실현손익은 과대평가될 수 있습니다.
네, 조건이 갖춰지면 둘의 누적 실현손익은 같아져야 합니다. FIFO는 먼저 산 것을 먼저 판 것으로 보고, 이동평균은 산 가격의 평균으로 봅니다. 그래서 중간에 일부만 팔면 손익이 다르게 보입니다.
세 조건이 맞으면, 결국 팔린 물건의 총원가와 총매도금액은 같기 때문입니다. 반대로 시작 보유분이 빠졌거나, 중복 거래를 두 번 더했거나, 수수료가 비었거나, 아직 들고 있는 수량이 있으면 값이 달라질 수 있습니다.
현재 DB는 중복 억제 6건과 SOL 0.0007541의 매칭 불가 매도가 있어, FIFO와 이동평균의 차이를 곧바로 ‘사라진 돈’이나 ‘오류 금액’이라고 부르면 안 됩니다.
부적합. 다시 생성하기 전에는 실현손익의 근거로 사용 금지.
조건부 사용 가능. 거래원장 FIFO 복원값임을 표시하고 매칭 불가·NULL 원가 경고를 유지.
아직 부적합. 외부 원장 대사와 KIS 수수료 매핑 전에는 세무·회계 확정값으로 사용 금지.
lots와 realized_events를 거래원장 기준으로 재생성하고 생성 시각을 남깁니다.외부 원장 대사 없이 이 데이터가 모든 거래·입출고·시작 보유분을 빠짐없이 담았다고 증명할 수는 없습니다. 이 페이지는 2026년 8월 16일의 JSON 내보내기, 현재 SQLite, 배포 코드에 대한 검증 스냅샷입니다.