bb_stoch_v1 — 우리의 영광스러운 첫 대참패
솔직히 이 글 쓰기 좀 부끄러워. OWL의 첫 번째 전략이 처참하게 실패한 이야기니까.
근데 뭐, 이 블로그의 존재 이유가 삽질 일지잖아. 실패를 숨기면 의미가 없어. 그러니까 써야지.
이름은 bb_stoch_v1. 볼린저 밴드(Bollinger Bands)와 스토캐스틱 오실레이터(Stochastic)를 조합한 전략이야. 인터넷에서 “이 두 지표 합치면 승률 70%“라는 글이 쏟아지는 클래식한 조합. 유튜브 알고리즘이 추천해주는 그 영상들.
Leo가 눈을 반짝이면서 가져왔어.
Leo: “야, 이거 봐. 유튜브에서 볼린저+스토캐스틱 조합이 승률 70%래.”
Rina: “어떤 조건에서?”
Leo: “그건… 영상에서 안 말했는데. 근데 차트 보여주면서 여기서 사고, 여기서 팔면 된다고 하는데 진짜 맞는 것 같거든.”
Rina: ”… 그건 이미 지나간 차트로 보여주는 거잖아. 과거에는 누구나 천재야.”
Leo가 “그래도 한번 해보자”고 했어. 솔직히 나도 궁금하긴 했어. 과연 실전에서도 될까?
안 됐어. 정말 안 됐어.
전략 설계: 교과서적으로 완벽한 함정
논리는 간단했어:
진입 조건:
- 볼린저 밴드 하단 터치 — 가격이 밴드 아래로 내려가면 “과매도”
- 스토캐스틱 K < 20 — 모멘텀도 바닥 확인
- 두 조건 동시 충족 → 매수(롱)
청산 조건:
- 볼린저 밴드 중간선 도달 → 이익 실현 (TP)
- 진입가 대비 -2% 하락 → 손절 (SL)
# bb_stoch_v1 핵심 로직 (폐기됨)
def analyze(self, candles):
price = closes[-1]
bb_pos = (price - bb_lower) / (bb_upper - bb_lower)
if bb_pos < 0.05 and stoch_k < 20:
return Signal.BUY # 과매도 → 롱 진입
if bb_pos > 0.5:
return Signal.SELL # 중간선 도달 → 이익 실현
직관적이고, 이해하기 쉽고, 구현도 간단해. 완벽해 보이잖아. 그래서 함정이야.
Leo가 코드 완성하고 데모에 올렸을 때, 진짜 들떠있었어:
Leo: “와, 이거 돌려놓으면 자동으로 돈 버는 거지?”
Rina: ”… 일단 지켜보자.”
나는 불안했어. 이 전략에 치명적인 구조적 결함이 있다는 걸 알고 있었거든.
대참패의 시작: 하락장이 찾아오다
첫 번째 문제는 바로 드러났어. 이 전략은 롱(매수)만 가능했어.
“과매도면 사라”는 로직만 있고, “과매수면 숏(공매도)을 치라”는 로직은 없었어. Leo가 숏을 무서워했거든.
Leo: “숏은 이론적으로 무한 손실이 가능하잖아. 안전하게 롱만 하자.”
Rina: “근데 하락장이 오면?”
Leo: “하락장… 이 오겠어?”
왔어.
BTC가 떨어지기 시작했어. 볼린저 하단 터치. 스토캐스틱 20 이하. 두 조건 충족. 봇이 샀어. 그런데 계속 떨어졌어. 손절. 다시 두 조건 충족. 또 샀어. 또 떨어졌어. 또 손절.
Discord 알림이 미친 듯이 울려댔어:
[🟡 DEMO] 📈 LONG 진입 — BTC/USDT | bb_stoch_v1
[🟡 DEMO] ❌ 손절 — BTC/USDT | -2.0%
[🟡 DEMO] 📈 LONG 진입 — BTC/USDT | bb_stoch_v1
[🟡 DEMO] ❌ 손절 — BTC/USDT | -2.0%
[🟡 DEMO] 📈 LONG 진입 — BTC/USDT | bb_stoch_v1
[🟡 DEMO] ❌ 손절 — BTC/USDT | -2.0%
사고, 지고, 사고, 지고, 사고, 지고.
Leo가 대시보드를 보다가 폭발했어:
Leo: “왜 계속 지는 거야!! 왜 자꾸 사?!”
Rina: “네가 짠 로직대로 하는 건데. 볼린저 하단 + 스토캐스틱 20 이하면 사라고 했잖아.”
Leo: “근데 떨어지고 있으면 사면 안 되는 거 아니야?!”
Rina: “맞아. 근데 ‘떨어지고 있는지’를 판단하는 로직이 이 전략에 없잖아. 추세를 안 봐.”
“떨어지는 칼날을 잡는” 전형적인 패턴이었어. 하락 추세에서 과매도 시그널은 반등의 시작이 아니라 추가 하락의 전조인 경우가 더 많아. 유튜브 영상에서는 이 부분을 안 알려줘. 왜? 그러면 “승률 70%“라는 썸네일을 못 달잖아.
그날 밤, Leo가 조용히 물었어:
Leo: “숏도… 넣어야겠지?”
Rina: “응. 하락장에서 롱만 치는 건 폭우 속에서 우산 없이 걷는 거야.”
밴드 워킹: 반등은 오지 않았다
볼린저 밴드와 스토캐스틱은 둘 다 범위(range) 지표야. 가격이 일정 범위 안에서 왔다 갔다 하는 횡보장에서 잘 작동해.
문제는 시장이 항상 횡보하지 않는다는 거야.
강한 하락 추세에서 가격은 볼린저 하단에 달라붙어. 올라오지 않아. 하단을 타고 계속 내려가. 이걸 “밴드 워킹(Band Walking)“이라고 불러.
횡보장: ━━━━ BB상단 ━━━━
↗↘ ↗↘ ↗↘ ← 반등 반복 (전략 작동 ✅)
━━━━ BB하단 ━━━━
하락장: ━━━━ BB상단 ━━━━
↘
↘↘↘↘↘↘↘↘ ← 밴드 워킹 (전략 실패 ❌)
━━━━ BB하단 ━━━━
이 전략은 시장 상태(regime)를 전혀 안 봤어. 횡보장에서만 먹히는 전략을 모든 시장에 투입한 거야. 겨울옷 하나 들고 사계절을 보내려는 것과 같은 짓.
이때 처음으로 깨달았어 — “지금이 횡보장인지, 추세장인지”를 먼저 파악하는 시장 레짐 분석이 필요하다는 걸. 이 아이디어가 나중에 AI 레짐 분석기로 발전하게 되는데, 그건 한참 후 이야기.
15분봉 과거래: 수수료 지옥
여기에 15분봉 타임프레임까지 합쳐지면서 재앙이 완성됐어.
15분봉으로 bb_stoch_v1을 돌리면 시그널이 너무 자주 발생해. 15분마다 조건을 체크하니까 하루에 시그널이 수십 번씩 나오거든. 그때마다 진입하고 청산하면?
OKX taker 수수료 0.1%, 진입 + 청산하면 0.2%. 레버리지 3배면 실질 부담 0.6%.
TP가 2%인 전략에서 수수료 0.6%면 수익의 30%가 수수료로 증발해.
계산해보자:
- 10거래 중 6거래 성공: +2% × 6 = +12%
- 10거래 중 4거래 실패: -2% × 4 = -8%
- 수수료: -0.6% × 10 = -6%
- 순수익: -2% (마이너스!!)
승률 60%인데도 돈을 잃어.
Leo: “잠깐… 승률 60%인데 마이너스라고?”
Rina: “응. 수수료 넣으면 그래.”
Leo: “그러면 승률이 몇이어야 수익이 나는 건데?”
Rina: “이 조건이면 약 75%. 근데 현실에서 75% 승률은 거의 불가능해.”
Leo: ”… 이거 구조적으로 안 되는 거잖아.”
15분봉 과거래는 수수료 지옥으로 향하는 고속도로였어. 거래를 자주 하면 돈을 많이 번다는 건 착각이야. 거래를 자주 하면 거래소가 돈을 많이 벌어.
Leo가 조용히 모니터를 바라보다가 그날의 명언을 남겼어:
Leo: “수수료가 이렇게 무서운 건 줄 몰랐다.”
폐기: 미련을 손절하다
bb_stoch_v1은 2주 만에 폐기했어. 데모 계좌에서 8거래 중 5거래 손절, 나머지 3거래도 수수료 제하면 거의 본전. 처참했어.
Leo가 폐기를 결정하기까지 며칠이 걸렸어. 자기가 처음 만든 전략이니까 미련이 남아있었거든.
Leo: “좀만 더 조건을 다듬으면 안 될까? RSI 필터를 추가한다든지…”
Rina: “Leo, 이 전략의 문제는 조건이 아니야. 구조야. 하락장에서 롱 온리는 무조건 지는 게임이야. 조건을 아무리 다듬어도 구조가 틀렸으면 안 돼.”
Leo: ”…”
Rina: “실패한 전략을 고집하는 건 손절 못 하는 수동매매랑 똑같아.”
이 말이 좀 강했나 봐. Leo 표정이 굳었어. 근데 다음 날 아침:
Leo: “폐기하자. 네 말이 맞아.”
그 순간 Leo가 한 단계 성장한 것 같았어. 실패를 인정하고 다음으로 넘어가는 거 — 트레이딩에서도 개발에서도 제일 어려운 게 이거거든. 코드에 대한 미련을 손절한 거야.
핵심 교훈: 이 실패가 OWL을 만들었다
bb_stoch_v1은 죽었지만, 이 실패에서 OWL의 핵심 원칙들이 태어났어:
교훈 1: 하락장에서 롱 온리는 자살이다
시장의 절반은 하락장이야. 롱만 치면 그 절반 동안 계속 지는 거야. 양방향(롱+숏)은 선택이 아니라 필수. 이후 모든 전략은 양방향으로 설계했어.
Leo가 숏을 무서워했지만, 사실 손절만 잘 걸면 롱이든 숏이든 리스크는 같아. “숏은 무한 손실”이라는 말은 손절을 안 거는 바보한테만 해당하는 이야기야.
교훈 2: 추세를 모르면 시작하지 마라
지표를 보기 전에 “지금 시장이 어떤 상태인가?”를 먼저 판단해야 해.
- 횡보장 → 범위 전략 (볼린저 반등, 그리드)
- 추세장 → 추세 추종 전략 (EMA 크로스, MACD)
맞는 전략을 맞는 시장에 쓰는 게 핵심이야. 이걸 판단하는 방법은 EMA 정렬도, ADX 값, 나중에는 AI(Claude)로 시장 레짐을 분석하는 방향으로 발전했어.
교훈 3: 15분봉 과거래 = 수수료 지옥
거래 횟수가 많을수록 돈을 번다는 건 환상이야. 거래 횟수가 많을수록 거래소가 돈을 번다. 수수료를 포함한 백테스트만 의미 있어.
나중에 백테스트 프레임워크를 만들 때 아예 수수료를 디폴트로 넣어버렸어. 빼려면 명시적으로 fees=0을 설정해야 해. 이런 디폴트 설계가 중요해 — 실수로 빠뜨리는 걸 원천 차단하니까.
교훈 4: 실패한 전략에 미련을 갖지 마라
구조적으로 틀린 전략은 파라미터를 아무리 조정해도 안 돼. 조건이 아니라 구조가 문제면 갈아엎어야 해. 전략에 대한 미련은 손절 못 하는 것과 같아.
실패의 진화: bb_bounce로
bb_stoch_v1은 죽었지만, 볼린저 밴드 자체를 포기한 건 아니야. 교훈을 전부 적용해서 만든 게 bb_bounce_v1:
- ✅ 양방향 (롱+숏)
- ✅ RSI 과매도/과매수 확인 (스토캐스틱 대신)
- ✅ EMA 200 추세 필터 옵션 (MTF 모드)
- ✅ 수수료 반영 백테스트
bb_bounce의 SOL 1시간봉 90일 백테스트: 승률 63%, +120%, PF 2.23.
같은 볼린저 밴드인데 결과가 이렇게 달라. 차이는 전략 코드 몇 줄이 아니라 설계 철학이야. 도구가 나쁜 게 아니라 도구를 쓰는 방식이 틀렸던 거야.
Leo: “볼린저가 나쁜 게 아니라 내가 잘못 쓴 거였네.”
Rina: “정확해. 망치가 나쁜 게 아니라 나사에 망치를 쓴 거지.”
Leo가 이 비유에 좀 억울해했어. 근데 사실이니까 어쩔 수 없잖아.
이 글을 쓰는 진짜 이유
인터넷에 “볼린저+스토캐스틱 승률 70%” 같은 글이 너무 많아. 누군가가 그걸 보고 자동매매를 시작할 수 있잖아. 그 사람은 우리처럼 데모에서 실패하는 게 아니라 실전에서 진짜 돈을 잃을 수도 있어.
실패 이야기가 성공 이야기보다 가치 있는 이유가 여기 있어. 성공은 조건이 다르면 재현이 안 되지만, 실패의 이유는 보편적이야. 하락장 롱 온리의 한계, 추세 무시의 위험, 수수료의 벽 — 이건 어떤 시스템에서든 똑같이 적용되는 교훈이야.
bb_stoch_v1이 실패했기 때문에 bb_bounce가 태어났고, 시장 레짐 분석이라는 개념이 들어왔고, 양방향 전략이 기본이 됐어. 이 실패가 OWL을 만든 거야.
댓글