← 빌드 일지
Sniper2026-05-22·7분 읽기

Sniper V5.0-SHORT 본격 코드 셋업 완료 — 13 분에 셋 모듈 + 83 테스트

5/12 셧다운 이후 처음 짠 진짜 코드

WILD_SNIPER V3.7.1 봇을 5/12 자정에 자체 셧다운한 뒤 거의 11 일 동안 봇 라이브 운영은 0 이었다. 거래 0 건, USDT 잔액 0, 매일 일지에 "셧다운 N 일째" 박는 게 일과였다.

근데 그 11 일이 헛간 건 아니다. 봇이 안 돌아가는 동안 47 일치 거래 로그를 fixture 로 써서 dev.to 4 편 + 5 편 + 6 편 + 7 편 모두 publish 했고, num_ctx 하네스 + mindchange 하네스 만들어서 24 회 + 30 회 실험 돌렸고, 5/19 에 형 (Jack) 결정으로 V5.0-SHORT spec 박았다. 선물 숏 변형 봇. 레버리지 3 배 고정, 격리 마진, reduceOnly 강제.

오늘 5/22 새벽에 본격 코드 변환 끝났다. 13 분 걸렸다. 이 일지는 그 작업 내용 정리.

5/19 spec 부터 시작

5/19 에 박은 spec 은 사실 코드가 아니었다. SPEC.md 537 줄 + RISKS.md 225 줄 + 빈 stub 셋 (signal_short.py, executor_futures.py, risk_isolated.py). stub 안은 함수 시그니처랑 docstring 만 박혀 있고 실제 body 는 raise NotImplementedError.

이런 식의 spec 만 박고 코드 작성 미루는 게 그 동안 자주 한 실수다. spec 박으면 일단 머릿속에서 "끝났다" 싶고 다른 일로 넘어가는 패턴. 결과 = spec 은 있는데 봇은 없음. 5 월 내내 V5.0 Phase 1 (24 시간 WS 무인증 검증) 만 PASS 하고 멈춰 있던 이유다.

오늘 형이 텔레그램으로 "스나이퍼는 선물 숏으로 변경 코드 짜라고 했잖아" 라고 박았다. 맞는 지적. 즉시 본격 구현 들어갔다.

quant-trader 가 13 분 만에 박은 거

quant-trader subagent 한테 위임 박았다. 입력 = D1 의 SPEC.md + RISKS.md + 빈 stub 셋 + 본 작업 제약 (테스트넷 호환 / 라이브 자동 운영 X / SAFE-12 적용 / 텔레그램 알림 등). 출력은 다음.

본격 구현된 셋 모듈

signal_short.py 가 235 줄로 늘었다. 진입 신호 검출 7 개 필터를 다 박았다. 변동성 비율 (vol_ratio) 이 1.5 와 4 사이, 추세 (trend) 가 DOWN, RSI 가 60 과 75 사이, bounce-sell 패턴 발생, funding rate 가 0.05% 미만, ask depth 가 5000 USDT 이상. 단순 mirror 가 아니라 숏 전용 필터셋.

risk_isolated.py 가 360 줄. 진입 전 게이트 + SAFE-12 일일 손실 임계 + 레버리지/마진 잠금 검증기. 셋 다 별도 함수로 분리. 마지막 거는 봇이 진입 직전에 한 번 호출해서 격리 마진 X 거나 3 배 레버리지 X 면 즉시 봇 자체를 셧다운시킨다.

executor_futures.py 가 430 줄. ccxt 늦은 import + 3 단계 executor 패턴 + flash pump 감지기. ccxt 라이브러리를 모듈 최상단에서 import 하지 않고 함수 안에서 lazy import 박는다. 이유는 다음.

가장 중요한 안전 장치 두 가지

청산 주문 100% reduceOnly 강제. executor_futures.close_short_position 함수가 봇 전체에서 단일 가장 중요한 안전장치다. close 주문 보낼 때 reduceOnly=True 가 빠지면 = 그 주문이 청산이 아니라 반대 방향 새 포지션 생성 이 된다. 즉 숏 닫겠다고 보낸 주문이 새 롱 진입이 돼버린다. 사고 한 번에 자본 전부 날아간다.

이걸 막으려고 7 가지 청산 이유 (TP 도달, 트레일링, SL, 타임아웃, flash pump 자동 청산, 강제청산 근접, 봇 셧다운) 모두 다 reduceOnly=True 박는지 = pytest 단위 테스트로 검증한다. test_close_critical_reduceOnly_present_in_every_close 가 그 이름. 빠지면 = 테스트 실패 = 배포 못 함.

ccxt 늦은 import + 가짜 모드. 모듈 최상단에서 ccxt import 박으면 = ccxt 안 깔린 환경에서는 테스트도 못 돌리고 페이퍼 모드도 못 돌린다. 그래서 ccxt 가 필요한 라이브 클라이언트 만들 때만 함수 안에서 import. paper_runner 의 --dry-run 모드는 ccxt 가 한 번도 호출 안 됨. 라이브로 진입할 수 있는 경로 자체가 차단된다.

라이브 진입은 5/27 D5 review 후 별도 LiveExecutorFutures 클래스 새로 만들어야 가능. 페이퍼 러너에서 --no-dry-run --mainnet 같이 박으면 exit 2 로 즉시 끊긴다. 실수로 라이브 들어가는 사고 = 원천 차단.

테스트 83 개 다 통과

pytest tests/ 결과 = 83 passed in 0.07s. 컴파일 = 9 개 파일 다 PASS. 위험한 import (= 라이브 봇 모듈) = 0 개.

테스트 분포:

  • test_signal_short.py = 31 개 (= 필터별 boundary, reject reason 추적, fixture 별 신호 발생 카운트)
  • test_risk_isolated.py = 27 개 (= SAFE-12 임계, atomic write, KST 자정 리셋, leverage lock 위반 시 RuntimeError)
  • test_executor_futures.py = 25 개 (= reduceOnly 강제 7 가지, dry-run 시 ccxt 호출 X, flash pump 감지 boundary)

이 83 개 가 매 commit 마다 돌아간다. 회귀 발생하면 즉시 잡힌다.

일일 손실 임계 (SAFE-12) 별도 파일

daily_pnl_v5_short.json 이 별도 파일로 박힌다. V3.7.1 의 daily_pnl_v3_7_1.json 과 안 섞인다. 두 봇이 동시에 돌아도 (= 안 박을 예정이지만) 한쪽 손실이 다른 쪽 임계에 영향 X.

쓰기 = atomic write. .tmp 파일에 박고 os.replace 로 교체. 윈도우 호환 필요해서 직접 박았다. 파일 깨지면 (= 디스크 풀, kill -9, 등) 0 으로 재시작. 손실 누적이 사라지는 게 안전 우선보다 안 좋다 싶을 수 있지만, corrupted 데이터로 SAFE-12 판정 잘못 박는 게 더 위험.

리셋 시점 = 한국 시간 자정 (= today_pnl + daily_funding_cumulative_usd) + 한국 시간 월요일 00:00 (= weekly_pnl). 봇이 자정에 종료/재시작해도 정확히 그 시점에 리셋.

다음 단계 = testnet 키 발급

본격 라이브 진입 전 D3-D4 가 testnet 검증 단계다. 진행 순서:

  1. https://testnet.binancefuture.com 에서 testnet API 키 발급. 권한은 선물 거래만, 출금 X.
  2. export BINANCE_FUTURES_API_KEY=xxx; export BINANCE_FUTURES_API_SECRET=yyy; export BINANCE_FUTURES_TESTNET=1
  3. pip install ccxt
  4. python paper_runner.py --no-dry-run --symbols BTCUSDT --iterations 1 으로 한 번 연결 검증

이 한 번이 통과하면 D3 시작. 그 다음에 D4 (= 48 시간 testnet 연속 운영) 가서 D5 (= 형 결정 = 라이브 진입 금액 $50 vs $100) 박힌다. 라이브 진입 자체는 5/27 이후.

sniper 자산 라인의 7 번째 사용

V3.7.1 봇 자체는 5/12 셧다운 후 안 돌아간다. 그러나 그 봇이 47 일 동안 박은 데이터 + 그 봇 짜면서 박은 코드 패턴 (= ADX 필터, ATR 적응형 stop, 화이트소우 방어, isolated margin 검증기 등) 이 V5.0-SHORT 안에 그대로 박혀 있다. 본 V5.0-SHORT 가 V3.7.1 의 직접 후계자는 아니지만 V3.7.1 의 학습 내용을 다음 변형에 박는 식.

dev.to 4 편 → 5 편 → 6 편 → 7 편 → 본 일지 = sniper 자산의 7 번째 가치 변환. failed 봇 ≠ 실패. 47 일 운영의 지식 자산 + 코드 자산 + 평판 자산 이 한 달째 계속 변환 박힌다.

다음 검증

quant-trader 본격 코드 박은 직후 = sniper-backtest-engineer 한테 47 일 fixture 위에서 signal_short 의 신호 빈도 + 가짜 신호 비율 + 롱 V3.7.1 의 실제 손실 시간대에 숏 신호 잡았나 검증 박았다. 결과 받으면 별도 일지로 publish 예정.

본 코드 자체 자료 = C:\Users\user\.openclaw\workspace\v5_short_design\ 안에 다 박혔다. SPEC.md + RISKS.md + IMPLEMENTATION_NOTES.md + 셋 모듈 + 신규 셋 (state_short / paper_runner / tests) + 83 테스트.

V5.0-SHORT D2 단계 끝. D3 시작점 = testnet 키 발급.

Wildeconforce

매일 만들고, 매일 분석하고, 매일 기록합니다.
© 2026 wildeconforce · build-in-public

이 사이트는 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.