안녕하세요, 육성라이프입니다 😊
7편에서 15개 팩터를 섞은 멀티팩터 순위가 10년 워크포워드 검증에서 연 +7.6%를 냈다고 정리했습니다. 이번에는 그 코드를 ChatGPT와 Gemini 두 곳에 통째로 보여 주고 “어디가 약하냐”고 물어봤습니다. 두 AI가 내놓은 제안은 열 가지가 넘었는데, 그대로 다 넣지는 않았습니다. 하나씩 제 10년 데이터로 직접 검증해서 숫자가 받쳐 주는 것만 반영했습니다.
그 과정에서 가장 크게 흔들린 것은 의외로 화려한 신호가 아니라 거래비용 한 줄이었습니다. 지금까지는 모든 종목에 왕복 비용 0.3%를 똑같이 뺐는데, 거래가 적은 소형주에서는 이 숫자가 너무 낙관적이었습니다. 비용을 현실에 가깝게 바꾸자 기존 방식의 성과는 절반 가까이 줄었고, 대신 거래대금이 큰 종목만 고르는 방식이 더 좋은 결과를 냈습니다.
① 거래비용을 거래대금별로 다르게 빼자, 기존 멀티팩터 20종목은 월 초과수익 +0.64%p → +0.41%p(t 1.1), 연 +7.6% → +4.7%로 줄었습니다.
② 20일 평균 거래대금 100억 원 이상 종목에서만 고르면 월 +1.24%p(t 2.6), 연 +8.7%였고, 비용을 더 비싸게 잡아도 유지됐습니다.
③ 영업이익 개선 공시(B1)는 진입 시점·상한가·비용을 모두 점검해도 결론이 그대로였습니다.
④ 시장 국면(지수의 이동평균선) 필터는 차이가 우연 범위라 넣지 않았습니다.
⑤ 그래도 같은 기간 시가총액 가중(지수)은 연 +12.7% — 지수가 중심, 스크리너는 보조라는 결론은 바뀌지 않았습니다.
사진: hyolee2 · Wikimedia Commons (CC BY-SA 3.0)
1. AI 두 곳의 코드 리뷰, 무엇을 받고 무엇을 버렸나
두 AI 모두 코드 구조는 좋게 평가했지만, 제안의 절반가량은 이미 제 데이터에서 효과가 없다고 나온 내용을 다시 다듬자는 것이었습니다. 예를 들어 1편부터 써 온 ‘거래량 흡수’ 신호를 3배·5배·8배로 나눠 점수를 더 주자는 제안이 있었는데, 이 신호는 7편에서 10년 중 한 해도 플러스가 아니었던 ‘피할 신호’입니다. 점수를 더하면 성과가 나빠집니다.
| 제안 | 처리 | 이유 |
|---|---|---|
| 소형주 체결 가능성·슬리피지 반영 | 검증 후 반영 | 초과수익이 소형주에 몰려 있어 가장 위험한 가정이었음 |
| 공시 시각·상한가 진입 점검 | 검증(결론 유지) | 영업이익 개선 신호에 적용해 확인 |
| 시장 국면별 추천 강도 조절 | 검증 후 제외 | 국면별 차이가 우연 범위(p 0.3~0.55) |
| 추천 이유 출력 | 형태를 바꿔 반영 | 팩터별 상위 %와 ‘주의’ 항목만, 신뢰도 %는 뺌 |
| 장 마감 후 알림 | 반영(선택 기능) | 공시 신호는 며칠만 유효해 알림이 의미 있음 |
| 거래량 흡수 점수화·가산 | 버림 | 10년 검증에서 피할 신호 |
| 손절가·목표가 강조 | 버림 | −7% 손절이 평균 수익을 깎았음(7편) |
| 종목별 ‘신뢰도 87%’ 표시 | 버림 | 20종목 묶음으로 검증한 방법이라 근거 없는 정밀도 |
| 내부자 매수 종류별 세분화 | 보류 | 자료가 2024년 10월 이후뿐이라 원래 신호도 검증 불가 |
AI의 코드 리뷰는 “놓친 위험”을 찾는 데는 정말 쓸모가 있었습니다. 다만 제안을 채택할지는 제 데이터가 결정해야 한다는 걸 다시 느꼈습니다. 그럴듯한 제안일수록 검증 없이 넣으면 백테스트를 망치기 쉽습니다.
2. 백테스트 거래비용 0.3%, 왜 소형주에서는 틀리나
주식을 한 번 사고팔 때 드는 비용은 크게 세 가지입니다. 증권사 수수료, 팔 때 내는 증권거래세, 그리고 눈에 잘 안 보이는 호가 차이·체결 충격(슬리피지)입니다. 앞의 두 가지는 종목과 상관없이 거의 같지만, 세 번째는 종목마다 크게 다릅니다. 하루 거래대금이 수백억 원인 종목은 사려는 가격 근처에 물량이 두껍게 쌓여 있어 원하는 가격에 거의 다 삽니다. 반대로 거래대금이 10억~20억 원인 종목은 호가 사이가 벌어져 있고, 조금만 사도 가격이 밀려 올라갑니다.
그런데 지금까지 제 백테스트는 모든 종목에 왕복 0.3%를 똑같이 뺐습니다. 이게 문제가 된 이유는 7편의 결과 자체에 있었습니다. 멀티팩터 초과수익이 시가총액 600위 밖 소형주에서 가장 컸기 때문입니다. 실제로 추천 규칙 그대로 뽑은 20종목을 확인해 보니, 10년 동안 평균 58%가 20일 평균 거래대금 30억 원 미만이었고 거래대금 중앙값은 24억 원이었습니다. 비용 가정이 가장 낙관적인 곳에 수익이 몰려 있었던 셈입니다.
그래서 거래대금 구간별로 왕복 비용을 다르게 잡았습니다. 구간은 개인투자자가 체감하는 호가 차이를 기준으로 보수적으로 정했고, 더 비싼 ‘보수’ 시나리오도 함께 돌렸습니다.
| 20일 평균 거래대금 | 기존 | 보통 시나리오 | 보수 시나리오 |
|---|---|---|---|
| 100억 원 이상 | 0.3% | 0.3% | 0.4% |
| 30억~100억 원 | 0.3% | 0.5% | 0.7% |
| 30억 원 미만 | 0.3% | 0.8% | 1.2% |

사진: nappa · Wikimedia Commons (CC BY 2.0)
3. 다시 계산한 결과: 성과가 절반으로, 그리고 반전
검증 방식은 7편과 같습니다. 2018년 11월부터 2026년 9월까지 95개월 동안, 매달 말 그때까지의 자료만으로 고른 점수 상위 20종목(업종당 3종목, 최근 유상증자 등 희석 공시 제외)을 다음 날 시가에 같은 금액으로 사서 한 달 들고 있는 방식입니다. 달라진 것은 새로 산 종목마다 위 표의 비용을 뺀 것뿐입니다.
| 멀티팩터 20종목 | 월 초과수익 | t값 | 연평균 |
|---|---|---|---|
| 기존 방식, 비용 0.3% 일률 | +0.64%p | 1.8 | +7.6% |
| 기존 방식, 보통 비용 | +0.41%p | 1.1 | +4.7% |
| 기존 방식, 보수 비용 | +0.20%p | 0.6 | +2.1% |
| 거래대금 100억 원↑만, 보통 비용 | +1.24%p | 2.6 | +8.7% |
| 거래대금 100억 원↑만, 보수 비용 | +1.19%p | 2.5 | +8.2% |
기존 방식은 비용을 현실에 가깝게 잡는 순간 t값이 1.1로 떨어져 우연과 구별하기 어려워졌습니다. 소형주에서 나던 초과수익의 상당 부분이 사실은 내가 낼 수 없는 가격으로 사고판 결과였을 가능성이 큽니다.
“100억”은 골라 맞춘 숫자가 아닐까?
여러 값을 시험한 뒤 가장 좋은 하나만 보여 주면 그것도 과최적화입니다(5편의 ‘여러 번 시험’ 함정). 그래서 거래대금 하한을 여러 단계로 바꿔 모두 공개합니다. 비용은 모두 보통 시나리오입니다.
| 거래대금 하한 | 월 초과 | t값 | 연평균 | 후보 종목 수(중앙) |
|---|---|---|---|---|
| 없음 | +0.41%p | 1.1 | +4.7% | 1,041 |
| 30억 원 | +0.93%p | 2.0 | +8.8% | 639 |
| 50억 원 | +0.96%p | 1.9 | +8.1% | 481 |
| 70억 원 | +1.10%p | 2.2 | +8.8% | 388 |
| 100억 원 (채택) | +1.24%p | 2.6 | +8.7% | 310 |
| 150억 원 | +1.36%p | 2.8 | +10.4% | 231 |
| 200억 원 | +1.46%p | 2.9 | +11.5% | 181 |
하한을 올릴수록 초과수익이 거의 일정하게 커졌습니다. 한 값에서만 튀는 결과라면 의심해야 하지만, 이렇게 방향이 일관되면 ‘우연히 맞춘 숫자’일 가능성은 낮아집니다. 100억 원을 고른 이유는 가장 좋은 값이어서가 아니라, 효과가 뚜렷해지는 구간이면서 업종당 3종목 제한을 지키고도 후보가 300개 넘게 남는 지점이기 때문입니다. 추가로 확인한 것은 다음과 같습니다.
- 기간 앞·뒤 절반: +0.81%p / +1.66%p — 둘 다 플러스
- 연도별: 9년 중 7년 플러스 (2018년·2020년 마이너스)
- 위약 시험: 점수를 무작위로 섞어 20번 돌리면 t값 최대 0.8, 평균 초과는 비용만큼 마이너스(−0.34%p) — 계산 과정의 착시는 없었습니다
그래도 지수보다는 낮았다
여기서 착각하기 쉬운 점이 하나 있습니다. 거래대금 100억 원 이상 종목을 ‘아무거나’ 샀다면 같은 기간 연 −7.1%였습니다. 거래가 몰리는 종목은 대개 이미 뜨거운 종목이라 그다음 달 성과가 나빴던 것입니다. 그래서 초과수익(+1.24%p)이 실제보다 커 보일 수 있습니다. 절대 수익으로 보면 연 +8.7%(최대 낙폭 −38%)이고, 같은 기간 시가총액 가중(지수와 비슷한 대형주 중심)은 연 +12.7%였습니다. 지수 ETF를 중심에 두고 스크리너는 작은 비중의 보조로 쓴다는 6편의 결론은 이번에도 그대로입니다.
처음 돌린 비용 재계산에서는 하한을 높여도 결과가 이상하게 나빴습니다. 무작위로 고른 종목의 비용이 0.3%여야 하는데 0.76%가 나와서 코드를 다시 보니, 구간별 비용 함수가 모든 종목에 가장 비싼 0.8%를 매기고 있었습니다. 고친 뒤의 숫자가 위 표입니다. 위약 시험을 습관처럼 돌리지 않았다면 틀린 결론을 그대로 블로그에 올릴 뻔했습니다.

사진: Ox1997cow · Wikimedia Commons (CC BY-SA 3.0)
4. 영업이익 개선 공시 신호는 살아남았다
Gemini가 짚은 ‘공시 시각’과 ‘상한가 진입’ 문제는 원래 거래량 흡수 신호에 대한 지적이었지만, 진짜 확인이 필요한 곳은 유일하게 통과한 영업이익 개선(B1) 신호였습니다. 공시 후 5거래일 안에만 효과가 있어서 진입 시점에 아주 민감하기 때문입니다.
- 미래 정보 점검: DART가 주는 접수일은 날짜만 있고 시각은 없습니다. 제 백테스트는 접수일(휴일이면 다음 거래일)의 다음 거래일 시가에 사도록 되어 있었고, 6,559건 모두 그 규칙대로였습니다. 장중 공시라면 오히려 당일 상승분을 놓치는 보수적인 가정입니다.
- 상한가로 시작해 못 샀을 사건: 6,559건 중 5건뿐이었습니다. 빼고 계산해도 60일 초과수익 +2.41%p(t 2.78), 하루 늦게 산 것으로 바꿔도 +2.42%p로 결론이 같았습니다. 정기보고서는 잠정실적으로 미리 알려진 경우가 많아 다음 날 갭 상승이 크지 않았던 것으로 보입니다.
- 현실 비용: 보통 비용 +2.15%p(t 2.6), 보수 비용 +1.89%p(t 2.5). 한 번 사서 60거래일을 들고 있는 방식이라 매달 바꾸는 멀티팩터보다 비용 영향이 작았습니다.
흥미로운 점은 거래대금별로 나눴을 때였습니다. 30억 원 미만 종목의 B1은 +3.56%p, 30억~100억 원은 +2.23%p였지만, 100억 원 이상 종목에서는 +0.79%p로 뚜렷하지 않았습니다. 많은 사람이 지켜보는 종목은 실적 정보가 빨리 가격에 반영되는 것으로 보입니다. 멀티팩터와는 정반대 모습이라, 이 신호는 거래대금 하한을 두지 않고 대신 ‘주의’ 칸에 표시만 하도록 했습니다. 나눠 본 결과에 맞춰 규칙을 바로 바꾸면 그것도 과최적화가 될 수 있어서입니다.
5. 시장 국면 필터는 넣지 않았다
ChatGPT는 “코스피가 20일선·60일선 아래면 신규 추천을 줄이라”고 제안했습니다. 직관적으로 그럴듯해서 시가총액 가중 지수를 직접 만들어 국면별로 다음 달 초과수익을 나눠 봤습니다(이 비교는 비용 현실화 전 방식 기준입니다).
| 월말 시장 국면 | 개월 수 | 다음 달 초과수익 |
|---|---|---|
| 상승 (지수 > 20일선 > 60일선) | 33 | +1.09%p |
| 중립·약세 (그 외) | 20 | +0.41%p |
| 하락 (지수 < 60일선) | 42 | +0.40%p |
상승장에서 더 좋아 보이지만, 차이를 검정하면 p값이 0.40~0.55로 우연 범위였습니다. 20일선 하나로만 나눠도 p 0.34였습니다. 게다가 멀티팩터는 ‘아무 종목보다 얼마나 나은가’를 노리는 방법이라, 지수가 내려가는 달에도 초과수익 자체는 플러스였습니다. 오히려 지수가 20일선 아래였던 달의 다음 달 절대 수익이 더 높았습니다(+1.51% vs +0.16%). 근거 없이 필터를 넣으면 반등장을 놓치는 비용만 생길 수 있어 넣지 않았습니다.

사진: Carol M. Highsmith · Wikimedia Commons (퍼블릭 도메인, 미국 의회도서관 소장)
6. 프로그램은 이렇게 바꿨습니다
- 거래대금별 비용: 멀티팩터 검증에서 새로 산 종목마다 20일 평균 거래대금 구간별 왕복 비용(0.3%·0.5%·0.8%)을 뺍니다.
- 거래대금 하한: 멀티팩터 추천과 검증 모두 20일 평균 거래대금 100억 원 이상 종목에서만 고릅니다. 검증과 실제 추천이 같은 규칙을 써야 백테스트 숫자가 의미를 가집니다.
- 비교 줄 추가: 결과 엑셀에 ‘하한 없이(이전 방식)’ 성과와 거래대금 구간별 성과를 함께 보여 줘서, 매달 두 방식의 차이를 계속 확인할 수 있게 했습니다.
- ‘주의’ 칸: 최근 1개월 +15% 이상 급등한 종목, 영업이익수익률이 비정상적으로 높은 종목(일회성 이익·지주사 연결 실적 확인), 거래대금 100억 원 이상 종목의 영업이익 개선 신호에 표시를 붙입니다.
- 대조군 맞추기: 실전 추적에서 비교하는 ‘점수 하위 20종목’도 같은 거래대금 범위에서 고르게 바꿨습니다. 범위가 다르면 비교가 공정하지 않습니다.
- 장 마감 후 알림(선택): 텔레그램 봇 정보를 넣어 두면 새로 나온 공시 신호와 이번 달 목록을 보내 줍니다. 공시 신호는 며칠만 유효하기 때문입니다.

사진: Ank Kumar · Wikimedia Commons (CC BY-SA 4.0)
마치며: 가장 비싼 가정은 ‘비용 0.3%’였다
솔직히 이번 결과에 놀랐습니다. 지금까지는 어떤 신호를 넣고 뺄지에만 신경 썼는데, 정작 결론을 가장 크게 바꾼 것은 비용 가정 한 줄이었습니다. 백테스트에서 소형주가 좋아 보인다면, 그 수익을 실제로 낼 수 있는 가격에 사고팔 수 있었는지부터 의심해 보시길 권합니다. 그리고 실제 주문은 거래대금이 큰 종목이라도 시장가로 한 번에 몰아치기보다 지정가로 나눠 넣는 편이 비용을 줄입니다.
다음 단계는 실전 기록입니다. 이번에 바꾼 규칙이 백테스트처럼 움직이는지, 대조군과 나란히 놓고 몇 달 동안 관찰한 뒤 다시 정리하겠습니다.
자주 묻는 질문
Q. 백테스트 거래비용은 얼마로 잡아야 하나요?
A. 정답은 없지만 종목에 따라 달라야 합니다. 수수료와 세금은 거의 같아도 호가 차이·체결 충격은 거래대금이 작을수록 커집니다. 적어도 거래대금 구간별로 나눠 보고, 더 비싼 시나리오에서도 결론이 유지되는지 확인하는 것을 권합니다.
Q. 슬리피지는 어떻게 줄일 수 있나요?
A. 거래대금이 충분한 종목을 고르고, 시장가로 한 번에 사기보다 지정가로 나눠 주문하는 것이 기본입니다. 투입 금액이 그 종목 하루 거래대금에서 차지하는 비중이 클수록 비용도 커집니다.
Q. 그럼 소형주 팩터 투자는 의미가 없나요?
A. 점수 상위 20% 묶음으로 보면 소형주 쪽 팩터 효과는 여전히 컸습니다. 다만 개인이 20종목만 골라 매달 바꾸는 방식에서는 비용이 그 효과를 대부분 먹었습니다. 보유 기간을 늘리거나 교체를 줄이는 방법은 따로 검증이 필요합니다.
Q. AI에게 코드 리뷰를 받는 게 도움이 되나요?
A. 놓친 위험을 찾는 데는 큰 도움이 됐습니다. 다만 이번에도 제안의 절반가량은 제 데이터에서 효과가 없던 신호를 다듬자는 내용이었습니다. 채택 여부는 반드시 직접 검증으로 정하는 것이 안전합니다.
정리
- 거래비용을 0.3%로 똑같이 빼면 거래가 적은 소형주 성과가 부풀려집니다.
- 거래대금별 비용으로 다시 계산하자 기존 멀티팩터 20종목은 연 +7.6%에서 +4.7%로 줄었습니다.
- 거래대금 100억 원 이상에서만 고르면 월 +1.24%p(t 2.6), 연 +8.7%였고 하한을 올릴수록 일관되게 좋아졌습니다.
- 영업이익 개선 공시 신호는 진입 시점·상한가·비용 점검을 모두 통과했습니다.
- 시장 국면 필터는 차이가 우연 범위라 넣지 않았고, 지수(연 +12.7%)보다 낮다는 사실도 그대로입니다.
“백테스트 거래비용 현실화 | 소형주 초과수익이 사라진 이유”에 대한 2개의 생각