Loading the catalog…
Loading the catalog…
백테스트 숫자를 파고들었다 — 그리고 안 좋은 소식이었다 실제 60일 워크포워드 백테스트 자산 곡선 (초기자본 1000만원) 지난 글에서 이 자율매매 엔진은 로컬 LLM이 결정하는 게 아니라 규칙 엔진( _guard_decisions )이 최종 결정을 내린다고 썼다. 손절/익절 강제, 국면별 매수 차단, 종목당 비중 한도 같은 것들이다. 그런데 규칙이 "안전하다"는 것과 그 규칙 조합이 "돈을 번다"는 것은 완전히 다른 질문이다. 이번 글은 그 질문에 정면으로 답한 기록이다. 워크포워드 백테스트는 뭘 하는 코드인가 run_walk_forward_backtest 는 과거 가격 히스토리를 하루하루 순회하면서 그날 시점까지의 데이터만 가지고 신호를 계산한다(미래 데이터를 미리 들여다보는 룩어헤드 편향을 막기 위해서다). 하루 루프 안에서 벌어지는 일은 이렇다. 보유 포지션마다 당일 시가 기준 수익률을 계산해서 손절(-5%)/익절(+12%)/기술점수 급락(-25 이하) 조건에 걸리면 매도 남은 슬롯( AI_BACKTEST_MAX_POSITIONS , 기본 8개) 안에서 기술점수 25 이상이면서 전일 급등 15% 미만인 종목을 점수 순으로 매수 매수 가능 종목들의 기술점수가 죄다 약세 쪽으로 쏠려 있으면(양의 점수 비중이 35% 이하) 그날은 아예 신규 매수를 걸지 않음 모든 체결에 슬리피지·수수료·매도세를 반영한 체결가( _fill_price )를 적용 이렇게 만들어진 자산 곡선에서 최종적으로 다음 지표를 뽑는다: 총수익률, 동일가중 벤치마크 대비 알파, 최대낙폭, 승률, 손익비(profit factor = 이익 합 / 손실 합) , 회전율(turnover = 누적 거래대금 / 초기자본) . 실제로 돌려본 숫자 (2026-09-01 기준) 기간 수익률 벤치마크 알파 최대낙폭 승률 손익비 회전율 판정 60일 +2.81% +26.77% -23.95%p -16.25% 30.4% 0.95 1223% fail 120일 +2.81% +18.43% -15.62%p -16.25% 30.4% 0.95 1223% fail 252일 +2.81% +18.43% -15.62%p -16.25% 30.4% 0.95 1223% fail 120일과 252일 결과가 똑같이 나온 건 버그가 아니라 단순한 이유다 — DB에 쌓인 가격 히스토리가 아직 64거래일치밖에 없어서, 120일 60일 워크포워드 백테스트 전략 성과 스코어카드 과 252일을 요청해도 실제로는 있는 데이터만큼만 돌기 때문이다. 데이터가 쌓일수록 세 기간의 숫자는 갈라질 것이다. _verdict 함수의 판정 기준은 이렇다: 최대낙폭이 -20% 이하이거나 알파가 -10%p 이하면 fail , 최대낙폭 -12% 이하이거나 알파가 음수면 warn , 나머지는 pass . 세 기간 전부 알파가 -15~-24%p 구간이라 가차없이 fail 이다. 숫자가 말하는 것 손익비 0.95는 이익 거래로 번 돈보다 손실 거래로 잃은 돈이 근소하게 더 크다는 뜻이다. 1 밑이면 거래를 반복할수록 평균적으로 까먹는 구조라는 뜻이고, 승률 30%라는 낮은 숫자와 합쳐 읽으면 "적게 이기고 크게 잃는" 패턴은 아니고 그냥 전반적으로 이기는 확률 자체가 낮다는 뜻에 가깝다. 회전율 1223%는 60거래일 동안 초기 자본의 12배가 넘는 금액이 매매로 오갔다는 뜻이다. 슬리피지 5bp + 수수료 1.5bp + 매도세 15bp를 합친 왕복 비용이 대략 0.2% 안팎인데, 회전율이 이렇게 높으면 이 작은 비용도 누적되면서 알파를 깎아먹는다. 규칙 자체의 방향성이 맞다 해도, 이 정도 회전율이면 거래 비용만으로 상당한 손해를 보고 시작하는 셈이다. 결론적으로 지금 조합(기술점수 임계값 25, 손절 -5%/익절 +12%, 8종목 분산)은 이 60 64일 구간에서 시장을 못 이겼다. 벤치마크(그냥 종목 50개를 동일 비중으로 사서 들고만 있는 것)가 +18 27%인데 실제 전략은 +2.8%다. 백테스트가 실제로 배포를 막아준 사례 이전 글들에서 다룬 로테이션 매도(기술 전망이 약해진 보유 종목을 선제적으로 정리하는 기능)와 거래량 상한 캡을 KIS 실계좌 엔진에 붙이면서, 로컬 시뮬레이터 엔진에도 같은 기능을 켤지 검토한 적이 있다. 코드를 켜기 전에 먼저 백테스트로 검증해봤는데, 결과가 알파 -48%p 안팎, 승률 33%, 손익비 0.89로 지금 숫자보다 더 나빴다. 그래서 로컬 엔진에는 이 기능을 켜지 않고 보류했다. 이게 이 검증 파이프라인의 실질적인 쓸모다 — "이 아이디어 괜찮아 보이는데?"라는 직감이 있어도, 백테스트 숫자가 더 나쁘게 나오면 배포하지 않는다. 코드를 다 짜놓고도 안 쓴 기능이 있다는 게 이상하게 들릴 수 있는데, 그게 이 파이프라인이 제 역할을 했다는 증거이기도 하다. 이 백테스트도 완벽하진 않다 체결가를 항상 당일 시가로 가정한다. 실제로는 그 가격에 그 수량이 다 체결된다는 보장이 없다 — 이전 글에서 다룬 유동성 문제가 여기엔 반영 안 돼 있다. 과거 데이터 위에서 잘 안 나온 조합이 미래에도 안 나온다는 보장은 없고, 반대로 과거에 잘 나왔다고 미래에도 잘 나온다는 보장도 없다. 워크포워드 방식이 룩어헤드는 막아주지만 과최적화까지 막아주진 않는다. 지금 데이터가 64거래일뿐이라 표본이 작다. 승률 30%, 손익비 0.95는 이 표본 안에서의 숫자이지, 통계적으로 안정된 장기 기대값은 아니다. 그래도 숫자를 감추지 않고 그대로 공개하는 이유는 똑같다. 파이프라인을 만드는 것과 그 파이프라인이 돈을 버는 것은 별개의 문제라는 걸, 이 프로젝트를 하는 나 스스로도 계속 확인하고 싶어서다. 이 프로젝트는 학습/실험 목적의 모의투자 시스템이며, 실제 투자 조언이 아닙니다. 코드는 개인 레포에서 관리 중입니다. GitHub 저장소: sunwoo8478/kis-paper-trading
What RADAR observed and classified to build this opportunity. It is what the source published, not a verification that the offer is still active.
백테스트 숫자를 파고들었다 — 그리고 안 좋은 소식이었다. 백테스트 숫자를 파고들었다 — 그리고 안 좋은 소식이었다 실제 60일 워크포워드 백테스트 자산 곡선 (초기자본 1000만원) 지난 글에서 이 자율매매 엔진은 로컬 LLM이 결정하는 게 아니라 규칙 엔진( _guard_decisions )이 최종 결정을 내린다고 썼다. 손절/익절 강제, 국면별 매수 차단, 종목당 비중 한도 같은 것들이다. 그런데 규칙이 "안전하다"는 것과 그 규칙 조합이 "돈을 번다"는 것은 완전히 다른 질문이다. 이번 글은 그 질문에 정면으로 답한 기록이다. 워크포워드 백테스트는 뭘 하는 코드인가 run_walk_forward_backtest 는 과거 가격 히스토리를 하루하루 순회하면서 그날 시점까지의 데이터만 가지고 신호를…
Open source