수집 이상을 감지하는 설계를 하면서 임계값을 과거 데이터로 검증하고 싶었다. 여기에는 함정이 있는데 런타임이 재는 신호와 백테스트가 재는 신호가 다르면 튜닝한 임계값이 무의미해진다는 것이다.
Table of contents
Open Table of contents
신호가 같은지의 조건
런타임은 이번 실행에서 몇 건을 수집했는지를 보고 백테스트는 그 기간에 테이블에 몇 행이 쌓였는지를 본다. 둘이 같으려면 중복 제거가 어디서 일어나는지가 조건이 된다.
저장 계층을 열어 보니 받은 데이터를 그대로 삽입하고 자체 중복 판정을 하지 않았다. 상위 흐름에만 존재 확인이 있어서 이미 있으면 건너뛰고 없으면 저장 계층을 부른다.
성립한 등식
그러면 그 실행에서 삽입된 행 수가 그 실행에서 새것으로 판정된 건 수이고 그것이 실제 수집한 신규 건 수와 정확히 같다. 테이블의 행만 보면 그때 얼마나 수집했는지를 알 수 있다는 뜻이다.
계측 코드가 없던 시기의 실적도 생성 시각으로 묶으면 재구성되므로 새 인프라를 하나도 안 넣고 백테스트를 할 수 있게 됐다. 저장 계층이 삽입 또는 갱신을 했다면 삽입 시도와 실제 삽입이 달라 이 등식이 깨진다.
확인이 필요했던 이유
그래서 저장 계층 본문까지 내려가 확인했다. 아마 상위에서만 하겠거니 하고 넘어갔으면 백테스트가 다른 것을 재고 있었을 수 있다.
그러면 임계값을 열심히 튜닝해 놓고 런타임에서 무의미해진다. 백테스트를 하기 전에 두 신호가 같은 것을 재는지부터 확인해야 한다.
좁아진 0건의 뜻
이 등식에는 이면도 있었다. 0건이 이번 실행에서 데이터베이스에 없던 신규 주문이 0건이라는 뜻이므로 조회 창을 늘려도 이미 있는 건은 안 세어 값이 안 커진다.
즉 0건은 조회 범위와 무관하다. 그런데 소량 대상은 정상 상태에서도 0이 흔하므로 수집이 죽은 경우와 판매가 없는 경우가 같은 0으로 나타나 건수만으로는 구분할 수 없다. 그 구분에는 대상 간 교차 비교나 실행 자체를 보는 신호가 따로 필요하다.
주석으로 막은 리팩터링
마지막으로 하나를 남겼는데 중복 제거 위치를 옮기는 리팩터링이 이 등식을 깨뜨려 과거 기반 분석을 전부 무효화한다는 것이다. 저장 계층에 삽입 또는 갱신을 넣으면 코드가 더 안전해 보이지만 등식이 깨진다.
개선처럼 보이는 변경이 다른 것의 전제를 무너뜨리는 경우다. 그래서 이 메서드가 의도적으로 중복 판정을 하지 않으며 그 결과로 어떤 등식이 성립하고 무엇으로 바꾸면 그것이 깨지는지를 주석으로 남겼다.
정리
- 백테스트 전에 런타임 신호와 백테스트 신호가 같은지 확인한다
- 중복 제거가 어느 계층에 있느냐가 그것을 정한다
- 저장 계층이 그대로 삽입하면 적재 행수가 곧 수집 신규 건수다
- 그러면 계측 없이도 과거 실적을 재구성할 수 있다
- 다만 0건은 조회 범위와 무관하다
- 죽음과 없음을 못 가르므로 다른 신호가 필요하다
- 개선처럼 보이는 변경이 다른 것의 전제를 무너뜨릴 수 있다
- 왜 안 하는가를 주석으로 남긴다