vol_breakout 멀티종목 tick, vol_live HTML 모니터, 마감 봉만 저장하는 캔들 다운로드, 텔레그램 체결 알림, cron/watch 감시 스크립트 및 테스트를 포함한다. Co-authored-by: Cursor <cursoragent@cursor.com>
18 KiB
Bithumb
빗썸 KRW 마켓 암호화폐 캔들 수집 및 현물(spot) 매매 전략 파이프라인.
- 기본 축: 3분봉 BTC, 최근 10년 캔들 (
DOWNLOAD_DAYS=3650) - 데이터·문서:
data/common(공유 DB) ·data/spot/docs/spot(현물) - 현재 live 운영:
fractal_swing, MTF off, ledger + exchange reconcile + 5분 watch
목차
파이프라인 개요
flowchart LR
A[common<br/>캔들 수집] --> B[0단계 GT]
B --> C[1단계 GT sim]
C --> D[2단계 39종 기법]
D --> E[3단계 paper/live]
F[watch 5분] -.->|감시·조치| E
| 단계 | 목적 | 미래 데이터 | 실거래 |
|---|---|---|---|
| common | SQLite 캔들 DB 구축·증분 갱신 | — | — |
| spot 0단계 | GT v3 사후 최적 타점 (정답지) | 사용 (연구용) | 불가 |
| spot 1단계 | GT 타점 완벽 추종 sim 상한선 | GT 자체가 사후 | 불가 |
| spot 2단계 | 39종 인과 기법 평가·MTF 규칙 | 미사용 | 불가 |
| spot 3단계 | paper/live tick 운영 | 미사용 | 가능 |
핵심 원칙
- 0~1단계는 연구·벤치마크 (사후 GT 포함).
- 2단계는 인과 기법만으로 GT 재현도·sim을 비교.
- 3단계는 2단계에서 선택한 기법을 실시간 tick으로 체결. 백테스트와 동일 sim 엔진(
ground_truth/pnl.py) 사용.
단계별 요약 (0~3단계)
common — 캔들 수집
| 항목 | 내용 |
|---|---|
| 스크립트 | scripts/00_download.py (별칭 00_download_candles.py) |
| DB | data/common/coins.db |
| TF | 11개 (1,3,5,10,15,30,60,240,1440,10080,43200분) |
| 모드 | 증분(기본) / --full 전체 재수집 |
| 테이블 | {SYMBOL}_{분} (예: BTC_3, BTC_1440) |
3단계 tick에서는 sync_ops_candles()가 in-process로 동일 DB에 증분 INSERT (OPS_SYNC_CANDLES=true).
spot 0단계 — Ground Truth (GT) 타점
목적: 10년 3분봉에서 사후적으로 도출한 “이론적 최적” 매수·매도 타점. 이후 단계의 정답지·벤치마크.
| 스크립트 | scripts/0_ground_truth.py |
|---|---|
| 기간 | GT_LOOKBACK_DAYS=3650 (10년) |
| 봉 | GT_INTERVAL_MIN=3 |
GT v3 신호 체계
| 코드 | 유형 | 10년 GT 건수(대략) |
|---|---|---|
| B | 스윙 저점 매수 | 944 |
| B* | 눌림목 | 406 |
| B^ | 돌파 | 122 |
| Bd | 상승 다이버전스 | 115 |
| S | 스윙 고점 매도 | 944 |
| Sd | 하락 다이버전스 | 144 |
티어
| 티어 | 포함 신호 |
|---|---|
| v1 | B / S |
| v2 | + B* |
| v3 | + B^ / Bd / Sd |
산출물
data/spot/ground_truth/ground_truth_trades_v{1,2,3}.jsondocs/spot/0_ground_truth/ground_truth_chart_v*.html
spot 1단계 — GT sim (수익 상한선)
목적: GT v3 타점을 그대로 sim했을 때 3년 수익률. “이론적 상한” 벤치마크.
| 스크립트 | scripts/1_ground_truth_sim.py |
|---|---|
| sim 기간 | GT_SIM_LOOKBACK_DAYS=1095 (3년) |
| 초기 자본 | GT_INITIAL_CASH_KRW=200,000 |
| 엔진 | simulate_gt_signals_pnl (슬리피지 없음) |
산출물: docs/spot/1_simulation/ground_truth_chart_sim_v*.html
참고: GT는 사후 타점이므로 실거래 불가. 1단계 수익률은 “최적 타점을 보수적으로 따라갔을 때”의 기준선.
spot 2단계 — 인과 기법 분석 (39종)
목적: 미래 데이터 없이 GT v3를 얼마나 재현하는지 39종 기법을 평가. 3단계 전략 선택 근거.
| 순서 | 스크립트 | 산출물 |
|---|---|---|
| 2-1 | 2_run_techniques.py |
data/spot/techniques/*.json, comparison_report.html |
| 2-2 | 2_run_causal_sim.py |
causal_sim_report.html |
| 2-3 | 2_run_signal_type_align.py |
signal_type_report.html |
| 2-4 | 2_run_mtf_analysis.py |
mtf_rules_v3.json, mtf_correlation_report.html |
| 일괄 | bash scripts/2_run_stage2_all.sh |
위 전체 |
GT 정합 score 상위 (10년, ±480봉 허용)
| 순위 | 기법 | score | 비고 |
|---|---|---|---|
| 1 | fractal_swing | 0.914 | buy/sell recall 100%, 현재 live 운영 |
| 2 | pivot_swing | 0.911 | |
| 3 | minor_swing | 0.864 | |
| 4 | local_extrema | 0.839 | |
| 5 | zigzag_causal | 0.776 | 스윙 특화, 저빈도 |
| … | composite_v3 | 0.546 | leg recall 22.9% |
문서
spot 3단계 — paper / live 운영
목적: 선택 기법(fractal_swing)을 3분봉 tick으로 paper 또는 live 체결.
| 스크립트 | 역할 |
|---|---|
3_run_filtered_backtest.py |
운영 조건 3년 sim |
3_run_fractal_realistic_backtest.py |
슬리피지·일 상한 시나리오 |
3_render_live_chart.py |
docs/live/ 매매 차트 |
3_run_operations.py |
paper/live tick (loop 180초) |
3_preflight_live.py / 3_init_live_state.py |
live 사전 점검·상태 초기화 |
3_reconcile_signals.py |
backlog inspect / execute |
3_audit_ops_safety.py |
놓침·중복 종합 점검 |
3_watch_ops.py |
read-only 감시 + 불일치 조치 |
3_run_watch_cron.sh |
cron 5분용 래퍼 |
bash scripts/3_run_fractal_live.sh |
preflight → init → live loop |
설계: docs/spot/3_operations/stage3_design_guide.md
(초版은 composite_v3 중심 — 현재 .env 기본은 fractal_swing)
수익률 정리
공통 조건: BTC · 3분봉 · sim 기간 최근 3년(1095일) · 초기 자본 200,000원 · 편도 수수료 0.05% (GT_TRADING_FEE_RATE)
sim 수익률은 과거 데이터 재생 결과입니다. live는 슬리피지·체결 지연·유동성·운영 오류로 달라질 수 있으며, 특히 고빈도 전략은 슬리피지에 극도로 민감합니다.
1단계 — GT v3 벤치마크
| 항목 | 값 |
|---|---|
| 3년 수익률 | +94,154% |
| 최종 평가 | 약 1.89억 원 |
| 매수/매도 체결 | 239 / 151 |
| 의미 | 사후 최적 타점을 보수적으로 sim |
2단계 — 인과 sim (슬리피지 0, 일 상한 없음)
| 기법 | 3년 수익률 | 최종 평가(약) | 매수/매도 체결 | 일평균 매수 |
|---|---|---|---|---|
| fractal_swing | +7,560,826% | 151억 | 56,893 / 56,892 | ~52회 |
| pivot_swing | +4,687,495% | 94억 | 12,656 / 12,658 | ~12회 |
| minor_swing | +286,537% | 5.7억 | 831 / 887 | ~0.8회 |
| zigzag_causal | +92,711% | 1.86억 | 97 / 97 | ~0.09회 |
| composite_v3 | -97.5% | ~5,000원 | 1,885 / 1,237 | — |
| composite_v3 + MTF (3단계 필터) | +3.37% | — | — | — |
출처: docs/spot/2_analysis/stage2_final_summary.md, stage2_parity_sweep.json
3단계 — fractal_swing 운영 백테스트 (슬리피지 반영)
| 시나리오 | 슬리피지 | 일 체결 상한 | 3년 수익률 | 매수 체결 | 비고 |
|---|---|---|---|---|---|
| stage2 ideal | 0% | 없음 | +7,560,826% | 56,893 | 2단계와 동일 |
| ops_default | 0.05% | 100 | +1,873,140% | 53,589 | sizing_rules 100% (cluster1) |
| ops + sizing 튜닝 | 0.05% | 10,000 | +2,307,905% | 56,773 | cluster 100% (sizing_rules.json) |
| slippage 0.1% | 0.1% | 100 | -97.5% | 3,964 | 실거래 리스크 |
| slippage 0.1% (상한 없음) | 0.1% | 없음 | -97.5% | 3,962 | 동일 |
출처: fractal_realistic_backtest.json, fractal_filtered_backtest_report.json (2026-06-14)
해석
- 2단계 ideal 대비 ops_default는 약 24.8% 수준 (
fractal_ops_vs_stage2.json) — 슬리피지·일 상한·분할 매매 반영. - 슬리피지 **0.05% → 0.1%**만 올려도 sim은 **-97.5%**로 붕괴 → live에서 체결가·수수료 관리가 핵심.
1_tune_order_sizing.py로 cluster별 100% sizing 튜닝 시 sim +2,307,905% (sizing_rules.json+.envOPS_*_PCT=1.0).
live vs 백테스트
| 구분 | 백테스트 | live |
|---|---|---|
| 실행 | 3년 일괄 재생 | 180초 tick 누적 |
| 체결가 | 모델 슬리피지 | 빗썸 시장가 + 실제 스프레드 |
| 신호 | 캐시+tail | 동일 파이프라인 + ledger |
| 기대 | sim 수치 | sim 이하가 정상 |
3단계 live 운영
tick 아키텍처
flowchart TD
subgraph loop["3_run_operations.py --loop 180"]
A[sync_ops_candles] --> B[generate_raw_signals<br/>force_tail_refresh]
B --> C[filter_signals_for_ops]
C --> D[exchange reconcile]
D --> E[stale backlog 정산]
E --> F[ledger pending 체결]
F --> G[state.json + report]
end
subgraph watch["3_watch_ops.py (cron 5분)"]
H[불일치 감지] --> I{조치}
I -->|lock 획득| J[remediation tick]
I -->|tick stale| K[loop 재시작]
I --> T[텔레그램]
end
L[ops.tick.lock] --- loop
L --- watch
신호 누락·중복 방어 (2026-06-14)
| 기능 | 설명 |
|---|---|
| ledger pending | trade_history 기준 미정산 신호 추적 (커서와 분리) |
| force_tail_refresh | live에서 tail 800봉 신호 재계산 |
| catchup 480봉 | 최근 구간 재시도 |
| max_age 45분 | 과거 backlog 현재가 재체결 차단 (수수료 churn 방지) |
| exchange reconcile | 거래소 done 주문 ↔ 신호 대조, 재주문 없이 원장 반영 |
| ops.tick.lock | loop·watch tick 동시 실행 방지 |
| watch 5분 | 불일치 시 remediation tick 또는 loop 재시작 + 텔레그램 |
live 시작
conda activate ncue # 또는 xavis
export PYTHONPATH=src
# 1) 백테스트 확인
python scripts/3_run_filtered_backtest.py
# 2) live (preflight + init + loop)
bash scripts/3_run_fractal_live.sh
# 또는 직접
python scripts/3_run_operations.py --mode live --loop 180
watch cron (5분)
crontab -e
# 추가:
*/5 * * * * /Users/dsyoon/workspace/bithumb/scripts/3_run_watch_cron.sh >> /Users/dsyoon/workspace/bithumb/data/spot/operations/watch_cron.log 2>&1
vol_breakout cron (다운로드 + tick + 모니터)
TRX/NEAR/WLD 15m flip 운영용. 한 번에 등록:
bash scripts/install_crontab.sh --apply
crontab -l # 확인
| cron | 주기 | 스크립트 | 로그 |
|---|---|---|---|
| 캔들 증분 | 1분 | 00_run_download_cron.sh |
data/common/download_cron.log |
| vol tick | 1분 | 3_run_vol_breakout_cron.sh |
data/spot/operations/vol_breakout_cron.log |
| 모니터 JSON | 5분 | 3_run_vol_monitor_cron.sh |
data/spot/operations/vol_monitor_cron.log |
- hung 프로세스: 다운로드 20분·vol tick 10분 초과 시 자동 종료 후 lock 정리 (
scripts/_cron_env.sh) - Python:
coin/ncueconda 우선. 다른 환경이면.env또는 crontab에BITHUMB_PYTHON=...설정 - 모니터 UI (8766):
→ http://127.0.0.1:8766/vol_live_monitor.html
bash scripts/install_vol_monitor_launchd.sh --install # 권장 — 로그인·재부팅 후 자동 기동 bash scripts/3_run_vol_monitor_serve.sh # 수동 1회 기동 bash scripts/install_vol_monitor_launchd.sh --status # 상태 확인
Binance 모니터는 8765 — 포트가 다릅니다.
HTTP 서버(8766)는 별도 터미널에서 수동 실행:python scripts/3_run_vol_monitor.py
점검:
tail -f data/common/download_cron.log
tail -f data/spot/operations/vol_breakout_cron.log
bash scripts/00_run_download_cron.sh # 수동 1회
bash scripts/3_run_vol_breakout_cron.sh
fractal watch 점검
python scripts/3_audit_ops_safety.py # PASS 목표
python scripts/3_reconcile_signals.py --dry-run # pending 0 목표
python scripts/3_watch_ops.py --inspect-only
live 체크리스트
.env:OPS_MODE=live, API 키,OPS_EXCHANGE_RECONCILE=true3_run_filtered_backtest.py수익률 확인- paper 1~2일 또는 소액 live 모니터링
fractal_ops_report.json— tick duration,ledger_pending_count,exchange_reconciled_count- 텔레그램 체결·WATCH 알림 확인
설치·실행
요구사항
- Python 3.10+
- Conda
ncue또는xavis
설치
cd bithumb
conda activate ncue
pip install -r requirements.txt
cp .env.example .env # API 키·텔레그램 등
전체 파이프라인 (최초 1회)
export PYTHONPATH=src
python scripts/00_download.py --full
python scripts/0_ground_truth.py --interval 3 --days 3650 --tier all
python scripts/1_ground_truth_sim.py --tier all
bash scripts/2_run_stage2_all.sh
python scripts/3_run_filtered_backtest.py
python scripts/3_render_live_chart.py
fractal 운영 (일상)
bash scripts/3_run_fractal_ops.sh # backtest + paper loop
python scripts/3_run_operations.py --loop 180 --mode live
bash scripts/3_run_watch_cron.sh # 감시 1회 (또는 cron)
폴더 구조
bithumb/
├── src/bithumb/
│ ├── api/ # Public·Private REST
│ ├── data/ # 캔들 수집·DB
│ ├── ground_truth/ # GT·sim·pnl 엔진
│ ├── techniques/ # 39종 인과 기법
│ ├── mtf/ # MTF 필터·규칙
│ ├── evaluation/ # 2단계 리포트
│ ├── operations/ # runner·executor·ledger·watch·reconcile
│ └── notifications/ # 텔레그램
├── scripts/ # 단계별 CLI·shell
├── data/
│ ├── common/coins.db
│ └── spot/
│ ├── ground_truth/
│ ├── techniques/
│ ├── mtf/
│ └── operations/ # state·sizing·lock·pid
└── docs/
├── live/ # 운영 백테스트 차트
└── spot/
├── 0_ground_truth/
├── 1_simulation/
├── 2_analysis/
└── 3_operations/
환경 변수
전체: .env.example. 카테고리별 요약.
공통·GT
| 변수 | 설명 | 기본 |
|---|---|---|
SYMBOL |
코인 | BTC |
DB_PATH |
캔들 DB | data/common/coins.db |
DOWNLOAD_DAYS |
수집·GT 기간(일) | 3650 |
GT_INTERVAL_MIN |
GT·운영 봉(분) | 3 |
GT_SIM_LOOKBACK_DAYS |
sim·백테스트(일) | 1095 |
GT_INITIAL_CASH_KRW |
sim 초기 자본 | 200000 |
GT_TRADING_FEE_RATE |
편도 수수료 | 0.0005 |
3단계 운영 (fractal live)
| 변수 | 설명 | 기본 |
|---|---|---|
OPS_MODE |
paper / live |
paper |
OPS_TECHNIQUE_ID |
기법 | fractal_swing |
OPS_MTF_ENABLED |
MTF 필터 | false |
OPS_SLIPPAGE_RATE |
편도 슬리피지 | 0.0005 |
OPS_DAILY_MAX_TRADES |
일 체결 상한 | 100 (live .env는 10000) |
OPS_CATCHUP_BARS |
catchup 봉 | 480 |
OPS_LEDGER_LOOKBACK_DAYS |
ledger 스캔 | 1 |
OPS_LEDGER_EXECUTE_MAX_AGE_MINUTES |
backlog API 허용 | 45 |
OPS_LIVE_FORCE_TAIL_REFRESH |
live tail 재계산 | true |
OPS_EXCHANGE_RECONCILE |
거래소 대조 | true |
OPS_TICK_LOCK_PATH |
tick flock | ops.tick.lock |
OPS_LOOP_PID_FILE |
loop PID | ops_loop.pid |
OPS_WATCH_SIGNAL_GRACE_MIN |
감시 grace | 5 |
OPS_WATCH_TICK_STALE_MIN |
tick stale → 재시작 | 12 |
OPS_WATCH_AUTO_REMEDIATE |
조치 tick | true |
OPS_WATCH_AUTO_RESTART |
loop 재시작 | true |
COIN_TELEGRAM_* |
체결·WATCH 알림 | — |
BITHUMB_ACCESS_KEY / SECRET |
live API | — |
composite_v3 대안 프로필
OPS_TECHNIQUE_ID=composite_v3
OPS_MIN_SCORE=2.5
OPS_MTF_ENABLED=true
OPS_TREND_GATE_ENABLED=true
OPS_DAILY_MAX_TRADES=20
소스 모듈
| 모듈 | 역할 |
|---|---|
operations/runner.py |
tick·ledger·stale·watchdog |
operations/exchange_reconcile.py |
거래소 체결 ↔ 원장 |
operations/watch_ops.py |
5분 감시·조치 |
operations/ops_lock.py |
flock |
operations/candle_sync.py |
증분 캔들 sync |
operations/signal_pipeline.py |
신호 tail·MTF |
operations/executor.py |
paper/live 체결 |
operations/trade_engine.py |
사이징·포트폴리오 |
operations/backtest.py |
3년 sim |
ground_truth/pnl.py |
sim 엔진 (2·3단계 공용) |
api/bithumb_private.py |
잔고·주문·done 조회 |
notifications/telegram.py |
체결·오류·WATCH |
39종 인과 기법
src/bithumb/techniques/ — 단일 33 + 복합 6, 미래 데이터 미사용.
| ID | 기법 | 유형 |
|---|---|---|
fractal_swing |
프랙탈 스윙 | 스윙 (live) |
zigzag_causal |
인과 ZigZag | 스윙 |
pivot_swing |
피벗 스윙 | 스윙 |
minor_swing |
소형 스윙 | 하이브리드 |
local_extrema |
국소 극값 | 스윙 |
composite_v3 |
v3 통합 | 복합 |
| … | (전체 39종) | techniques/registry.py 참고 |
변경 이력
- 2026-06-14: ledger pending, exchange reconcile, max_age backlog, watch 5분 감시·조치, ops.tick.lock, README 전면 갱신
- 2026-06-13: fractal_swing live — 슬리피지·sync·tail·텔레그램; ops_default sim +1,873,140%
- 2026-06-13: 프로젝트명 Bithumb, 선물 파이프라인 제거
- 2026-06-12: data/docs common·spot 구조, 2단계 39종 완료, 3단계 초기 (composite_v3)
- 2026-06-08: GT v1/v2/v3
- 2026-06-07: 캔들 수집 모듈