Files
kis_bot/kis_trader
Your Name 36a3e2b4a1 feat: Enhance trading system with new permanent subscription features and order book management
Changes:
- Added a new API endpoint for managing permanent subscriptions, allowing users to enable or disable subscriptions dynamically.
- Implemented a function to fill candle data from Kiwoom, ensuring that only relevant data is inserted into the database.
- Introduced a mechanism to handle master subscription states, improving the management of subscription statuses.
- Updated the database schema to include new fields for managing subscription states and order book filtering.

Impact:
- These enhancements improve the flexibility and reliability of the trading system, allowing for better management of subscriptions and order book data, while reducing the risk of data inconsistencies.

히스토리 align 제거 븅신같은 초기설계 아예 제거
진입모드에 구멍메움
호가진입을 켜도 호가가 안들어올때 호가 안보고 그냥 사버림
2026-08-15 23:01:14 +09:00
..
2026-05-05 21:04:17 +09:00

kis_trader — 통합 트레이딩 봇

스캘핑(SCALP) + 꼬리잡기(SHORT, Tail Catch) 두 전략을 단일 프로세스에서 각자 독립 쓰레드로 돌리는 통합 봇. KIS REST/WebSocket 호출을 단일 허브로 묶고, 주문은 단일 OrderManager 를 경유해 ODNO 기반으로 추적한다.

디렉터리

kis_trader/
├── main.py                  # 오케스트레이터 (각 전략을 쓰레드로 기동)
├── utils/
│   ├── env.py               # env_config (DB) + os.environ 통합 조회
│   ├── logger.py            # 공용 로거 / 안전 JSON 저장 / 알림(MM/TG)
│   └── request_handler.py   # SafeRequest: rate-limit + 재시도
├── network/
│   └── ws_manager.py        # 단일 WS 허브 (kis_ws 재사용, 구독 ref-counting)
├── strategies/
│   ├── base.py              # BaseStrategy (threading.Thread)
│   ├── scalping.py          # scalping_engine 래퍼
│   └── tail_catch.py        # tail_engine 래퍼
├── execution/
│   ├── kis_client.py        # 통합 KIS REST 클라이언트 (ODNO 반환)
│   └── order_manager.py     # Master Executor (종목 Lock + 실잔고검증)
├── database/
│   └── db_manager.py        # TradeDBExt: 기존 TradeDB + orders 테이블
└── backtest/
    └── backtest_web.py      # 기존 backtest_web.py 재호출 래퍼

아키텍처 한 눈에

[SCALP 쓰레드]  ──┐
                   │─▶ OrderRequest ─▶  OrderManager  ─▶  KISClient  ─▶  KIS API
[SHORT 쓰레드]  ──┘                       │  │  │
                                          │  │  └── DB(orders) ← ODNO PK
                                          │  └───── DB(active_trades, trade_history)
                                          └──────── 실잔고 검증 (get_broker_holdings)

공유 인프라 (1개 인스턴스)
  • KISClient      : 토큰/Throttle/재시도
  • WSManager      : 단일 WS 세션, 구독 ref counting
  • TradeDBExt     : orders 테이블 + 기존 TradeDB
  • OrderManager   : 종목 Lock, 동일 종목 다전략 정책, ODNO 저장

왜 이 구조인가

기존 문제 새 구조에서의 해결
봇이 잡고 있는 holdings 가 실제 계좌와 어긋남 매도/매수 직전 OrderManager.get_broker_holdings(force=True) 호출로 실잔고 검증
두 봇이 같은 종목에 동시 매수 → 이중 포지션 OrderManager._code_locks[code] 로 직렬화 + orders 테이블 UNIQUE(strategy,code,side,date)
주문번호(ODNO) 미저장 → 사후 추적 불가 kis_client._order() 가 ODNO 반환 → TradeDBExt.insert_order() 로 PK 저장
토큰 재발급 경합 / REST 호출 폭주 KISClient 하나 + kis_token_manager 공유 + SafeRequest 쿨다운
두 봇이 WS 각자 → 구독 수/approval_key 경합 WSManager 단일 세션 + 구독 레퍼런스 카운팅
설정 하드코딩 모든 값은 env_configos.environ → 기본값 순으로 조회

실행

cd ~/kis_bot

# 기본(두 전략 모두 ON)
python -m kis_trader.main

# 스캘핑만
STRATEGY_SCALP_ENABLED=true STRATEGY_SHORT_ENABLED=false python -m kis_trader.main

# 꼬리잡기만
STRATEGY_SCALP_ENABLED=false STRATEGY_SHORT_ENABLED=true python -m kis_trader.main

DB 설정 테이블 (2026-05 분리)

테이블 내용
env_config 공통 — KIS/키움 API, MM, WS, 전략 ON/OFF, 수수료, SLOT_MONEY_DEFAULT
config_scalp 스캘핑 SCALP_*
config_short 꼬리 SHORT_* / TAIL_* / SHOULDER_* / 익절 호가 SELL_ORDERBOOK_*
config_momentum 모멘텀 MOMENTUM_*
config_breakout 돌파 BREAKOUT_*
config_updow 하락매수 UPDOW_*
  • 코드는 get_latest_env() / get_env_from_db()병합 flat dict 를 그대로 씁니다 (하위 호환).
  • 최초 분리·재마이그레이션: python3 -m kis_trader.scripts.migrate_split_env_config
  • 키 분류 규칙: 프로젝트 루트 config_schema.py

주요 환경변수

이름 기본 설명
STRATEGY_SCALP_ENABLED true 스캘핑 전략 활성화
STRATEGY_SHORT_ENABLED true 꼬리잡기 전략 활성화
STRATEGY_SAME_CODE_POLICY allow 같은 종목을 다른 전략이 active_trades에 있어도 allow(허용) / block(차단)
REAL_BALANCE_VERIFY_BEFORE_BUY false false=타 전략·수동 보유 있어도 매수 가능 / true+MODE=strategy면 동일 전략 DB만 차단
REAL_BALANCE_VERIFY_BEFORE_BUY_MODE strategy strategy | global(실계좌 1주라도 있으면 매수 차단, 레거시)
REAL_BALANCE_VERIFY_BEFORE_SELL true 매도 전 실 잔고 재조회 (0주면 active_trades 정리)
ORDER_CASH_PCT 0.95 예수금 부족 시에만 가용금×N%÷MAX_STOCKS 로 qty 축소 (기존 산식 우선)
ORDER_CASH_FEE_BUFFER 1.01 주문금액 대비 수수료 여유 (1.01=1%)
ORDER_CASH_DIVIDE_BY_MAX_STOCKS 1 1=종목당 예수금÷MAX_STOCKS, 0=나누지 않음
ACCOUNT_CASH_PERSIST_SEC 60 예수금 캐시 kv_store 저장 주기(체결 시 즉시 저장)
SCALP_LIVE_BACKTEST_ALIGN true 스캘핑: 신호봉(직전 확정) → 진입봉(현재 확정)=백테 다음봉 시가
SHORT_LIVE_BACKTEST_ALIGN true 꼬리(3분): 동일 패턴
MOMENTUM_LIVE_BACKTEST_ALIGN true 모멘텀(1분): 동일 패턴
BREAKOUT_LIVE_BACKTEST_ALIGN true 돌파(1분): 동일 + 진입가 진입봉 시가 우선
*_LIVE_SIGNAL_LOOKBACK_BARS 1 직전 N개 신호봉까지 소급 검사
MAX_STOCKS 3 전략당 동시 보유 최대 종목 수
REENTRY_COOLDOWN_SEC 300 매도 후 같은 종목 재진입 쿨다운(초)
WS_TIMEFRAMES 1,3,15,60 WS 봉 집계 타임프레임(분)
PERMANENT_WS_CODES 069500,229200 WS 영구 구독 코드(쉼표)
SCALP_STOP_LOSS_PCT / SCALP_TAKE_PROFIT_PCT -0.015 / 0.015 스캘핑 손절/익절 비율
STOP_LOSS_PCT / TAKE_PROFIT_PCT -0.04 / 0.05 꼬리잡기 손절/익절 비율
MAX_LOSS_PER_TRADE_KRW 200000 1회 거래 최대 손실 허용액(원)
SLOT_MONEY_DEFAULT 3000000 1슬롯 기본 투자 금액(원)

전략 ON/OFF 동작 방식

TradingOrchestrator 는 시작 시 STRATEGY_*_ENABLED 를 읽어서 해당 전략 클래스를 쓰레드로 등록한다. 따라서:

  1. 꼬리잡기만 끄고 싶을 때 → env_config 또는 OS env 에 STRATEGY_SHORT_ENABLED=false
  2. 재시작 필요 (동작 중 on/off 전환은 지원 안 함, 대신 공격적 재시작 스크립트 사용)

백테스트

python -m kis_trader.backtest.backtest_web

엔진별로 백테·실매가 동일 함수를 호출한다 (체결·유니버스는 별도).

전략 엔진 청산
SCALP reversal scalping_engine 어깨 → 익절 → 손절
MOMENTUM momentum_engine 어깨·트레일 → 손절 → tp_max 상한
SHORT(꼬리) tail_engine ATR·어깨·EOD
BREAKOUT breakout.py 익절 우선 (돌파 전용)

주의사항

  • 프로젝트 루트의 기존 파일 (scalping_engine.py, tail_engine.py, kis_ws.py, kis_token_manager.py, risk_manager.py, database.py 등) 을 그대로 사용한다. kis_trader/ 는 이들을 조립하는 얇은 래퍼 층이다.
  • DB 스키마에 orders 테이블이 자동 생성된다 (TradeDBExt._ensure_orders_table).
  • 기존 kis_scalping_ver2.py / kis_short_ver3.py 는 남겨두되, 중복 실행 금지 (계좌/토큰/WS 경합).