2026-06-24 (수) 개발일지
오늘은 bit-scalp 트레이딩 봇의 손익 비대칭을 잡았다.
처음엔 SL/TP 로직 자체가 깨졌다고 생각했는데, 파보니 트레일링 잠금 조건이 너무 빨리 발동해서 수익이 조기 청산되고 손실은 끝까지 흘리는 구조였다. 결국 settings.py 네 개 값을 조정으로 균형을 맞췄다.
bit-scalp 손익 비대칭 — 트레일링이 수익을 조기 차단한 구조
운영 로그를 보다 보면 이상한 패턴이 눈에 띄었다. 14건의 거래 중 8승 6패로 승률 57%인데, 회당 평균 손익이 +$0.12로 박빙이었다. 더 자세히 뜯어보니 손실 평균은 -$2.77 (-2.37%) 인 반면 수익 평균은 +$1.59 (+1.21%) 로, 손실이 수익보다 약 2배 컸다. SL/TP가 제대로 걸려 있지 않거나 트레일링이 망가진 게 분명했다.
처음엔 settings.py의 default_stop_loss_pct와 default_take_profit_pct 값 자체가 엉킨 줄 알았다. orchestrator가 regime_tp_sl 딕셔너리를 참조하는지 확인했지만 — 코드를 따라가 보니 orchestrator는 settings.trading.default_stop_loss_pct만 직접 읽고, regime_tp_sl은 전혀 사용하지 않았다. 원인은 더 깊은 곳에 있었다.
수익 8건의 분포를 다시 봤다. 7건이 +0.7% ~ +1.7% 사이에 몰려 있었고, 단 1건만 +2%를 넘었다. 반면 손실 6건은 -2.4% ~ -2.7% 로 거의 default_stop_loss_pct=3.0%에 근접해 있었다. 수익이 특정 구간에서 잘리는 패턴이 명확했다 — 트레일링이 수익을 중간에 가로막고 있다는 신호였다.
settings.py의 트레일링 값을 확인했다. trailing_activation_pct=2.5% — 이 값을 넘으면 트레일링이 활성화된다. 그런데 문제는 trailing_stop_loss_pct=1.0%. SHORT 포지션에서 +2.5%까지 올랐다가 0.5%만 되돌려도 청산 조건에 걸렸다. 즉 진입 후 +2.5%에서 +1.5%로 떨어지면 바로 청산되는데, 이게 표본의 +1.2% 근처 청산을 설명했다.
더 큰 문제는 손실 쪽이었다. trailing_breakeven_pct=0.15% — 0.15%만 이득을 봐도 손절가를 진입가로 이동시키는 설정인데, 변동성이 작은 종목에선 이 조건을 충족하기 힘들었다. 결국 손실은 default_stop_loss_pct=3.0%까지 그대로 흘러 -2.4~2.7%로 마감됐다. 수익은 1.5%에서 잘리고, 손실은 3%까지 흐르는 2배 비대칭이 완성된 셈이었다.
해법은 단순했다. 네 개 값을 조정해 트레일링이 더 넉넉하게 움직이면서도 손실은 줄이는 방향으로:
| 항목 | 기존 | 신규 | 효과 |
|---|---|---|---|
default_stop_loss_pct |
3.0% | 2.0% | 손실 폭 축소 |
trailing_activation_pct |
2.5% | 3.0% | 작은 출렁임에 안 끌리도록 |
trailing_stop_loss_pct |
1.0% | 1.2% | 최소 되돌림폭 확대 |
trailing_breakeven_pct |
0.15% | 0.5% | BE 이동 조건 현실화 |
default_stop_loss_pct를 3.0%에서 2.0%로 내린 건 — 기존 손실이 -2.4~2.7%에서 발생했으니 SL을 2.0%로 좁혀도 실제 손실은 유사하거나 더 작아진다는 계산이었다. trailing_activation_pct를 2.5%→3.0%로 올려서, 활성화 전에 더 많은 상승 여유를 줬다. trailing_stop_loss_pct는 1.0%→1.2%로 최소 되돌림폭을 넓혀 조기 청산을 막았다. trailing_breakeven_pct는 0.15%→0.5%로, 변동성에도 BE가 안정적으로 걸리도록 조정했다.
V5도 같은 값 문제를 가지고 있었지만, V5는 현재 진입 0건이라 영향이 없었다. V5 동기화는 이후에 결정하기로 하고 일단 V2만 수정했다. settings.py 수정 후 V2를 재기동(PID 7692)했다.
검증: 수정 직후 바로 트레이딩 로그가 쌓이진 않았지만, 설정값 자체의 일관성은 확인했다. V5와 V2가 같은 settings.py를 공유하므로, V5가 나중에 진입해도 동일한 트레일링 로직이 적용된다.
남은 과제: V5의 short_trailing_activation_pct=1.0은 V2와 달라서 평균회귀 전략 의도일 수 있다 — 이건 사용자가 결정할 문제. 수정 후 실제 거래 20~30건 정도 모아서 수익 분포가 이전처럼 +1.5%에서 잘리는지, 아니면 -2.0% SL 근처에서 손실이 정리되는지 모니터링할 필요가 있다.
오늘의 한줄
트레일링 조건 하나가 수익 분포 전체의 지형을 바꾼다 — 설정값은 항상 실제 손익 분포와 비교하며 튜닝해야 한다.