AI를 활용한 재밌는 것들을 개발합니다

2026년 5월 8일 금요일

키움 REST API 퀀트 종목교체 리밸런싱 자동화 — V2 시스템 설계 [Claude Code · 키움리밸런싱 · 7편]

퀀트전략 키움증권 REST API FastAPI Python

키움 REST API 퀀트 종목교체 리밸런싱 자동화
— V2 시스템 설계

보유 종목 균등배분에서 전략적 종목교체로 — 두 번째 버전을 만들게 된 이유

V1을 넘어 V2를 만든 이유

V1(1~6편)은 보유 종목을 균등 배분하는 자동 리밸런싱 프로그램이었습니다. 잘 동작했지만, 한 가지 한계가 있었습니다.

V1은 현재 보유 종목을 유지하면서 비중만 맞춥니다. 퀀트 투자자라면 주기적으로 팩터 기반 분석을 통해 종목 자체를 교체해야 합니다. 수동으로 하면 실수가 잦고 감정이 개입됩니다.

V2 핵심 아이디어: 사용자가 신규 목표 종목 B를 입력하면, 현재 보유 종목 A와 비교해 자동으로 매도 종목과 매수 종목을 계산하고 분할 실행한다.
항목V1 균등배분V2 퀀트전략
종목 결정현재 보유 종목 유지사용자 지정 목표 종목 B로 교체
비중전 종목 균등목표 종목 기준 균등
엔진RebalancingEngineQuantEngine + RebalancingEngine
모드단일듀얼 (quant / rebalance)
종목 관리제외/편입 (portfolio_manager)목표 집합 B (target_manager)
예약 실행날짜만 저장날짜 + 모드 함께 저장
수익률 표시없음종목별 평가손익 색상 표시
실행 포트80008001
V2 퀀트 리밸런싱 시스템 아키텍처 다이어그램

V2 시스템 구조 — FastAPI + QuantEngine + 키움 REST API

종목교체 리밸런싱 핵심 개념 — 집합 연산

퀀트 종목교체 리밸런싱의 핵심은 집합 이론입니다. 현재 보유 종목을 A, 신규 목표 종목을 B라 하면 세 가지로 분류됩니다.

구분조건처리
A − B (매도 전용)기존 보유, 목표에 없음전량 매도 (분할)
A ∩ B, 초과 보유중복, 평가금액 > 목표금액초과분만 매도
A ∩ B, 부족 보유중복, 평가금액 < 목표금액부족분 매수
A ∩ B, 균형중복, 차이 1주 미만건너뜀 (hold)
B − A (매수 전용)신규 목표 종목목표금액 전체 매수 (분할)

목표 균등금액은 (전체 평가금액 + 예수금) ÷ 목표 종목 수로 계산합니다.

8편에서는 이 로직이 실제 Python 코드로 구현된 QuantEngine.classify()를 살펴봅니다. 8편 — QuantEngine 집합 분류 알고리즘

V2 파일 구조 — V1 인프라 재활용

개발 시간을 줄이기 위해 V1 인프라 코드 8개 파일을 그대로 복사해 사용했습니다. 신규로 작성한 파일은 4개입니다.

quant_rebalancing/
├── main.py                    # 신규: 진입점, 의존성 조립
├── kiwoom_client.py           # V1 복사 (변경 없음)
├── account_manager.py         # V1 복사 (변경 없음)
├── order_queue.py             # V1 복사 (변경 없음)
├── order_manager.py           # V1 복사 (변경 없음)
├── history_manager.py         # V1 복사 (변경 없음)
├── telegram_notifier.py       # V1 복사 (변경 없음)
├── scheduled_notifier.py      # V1 복사 (변경 없음)
├── config.py                  # V1 복사, 기본 포트 8001
├── quant_engine.py            # 신규: 집합 분류 + 계획 생성
├── target_manager.py          # 신규: 목표 종목 B 관리
├── quant_schedule_manager.py  # 신규: 듀얼 모드 스케줄
├── web_server.py              # 신규: FastAPI + quant 라우트
└── frontend/

V1의 OrderQueue, OrderManager 등 검증된 주문 인프라를 그대로 씁니다. 주문 실행 로직을 다시 짤 필요 없이 상위 전략 레이어만 새로 구현했습니다.

듀얼 모드 — 하나의 앱으로 두 전략 전환

V2의 독특한 설계 포인트는 듀얼 모드입니다. 단 하나의 설정값으로 두 전략을 전환합니다.

# settings.json
"mode": "quant"     # 퀀트 종목교체 모드
"mode": "rebalance" # 보유 종목 리밸런싱 모드 (V1 로직)

웹 UI의 라디오 버튼으로 모드를 실시간 전환하면 settings.json에 즉시 저장됩니다.

예약 실행 시 모드가 날짜와 함께 저장되는 이유: 예약 설정 이후 UI에서 모드를 바꿔도 예약은 설정 시점 모드로 실행되어야 하기 때문입니다.

def set_reserved_date(self, date_str: str, mode: str = "") -> None:
    self._reserved_date = date_str
    self._reserved_mode = mode or self.mode  # 설정 시점 모드 고정

# 예약 실행 시
exec_mode = self._reserved_mode or self.mode
self.mode = exec_mode
await self.start()  # 고정된 모드로 실행

settings.json 구조 변화

V1 대비 가장 크게 바뀐 부분입니다. excluded_stocks, added_stocks가 사라지고 target_stocks가 추가됐습니다.

{
  "mode": "quant",
  "accounts": {
    "계좌번호": {
      "target_stocks": [
        {
          "code": "005930", "name": "삼성전자",
          "price": 75400, "valid": true,
          "added_at": "2026-05-01T09:00:00"
        }
      ]
    }
  },
  "schedule": { ... },
  "reservation": {
    "date": "2026-05-06",
    "mode": "quant"
  }
}

다음 편에서는 이 모든 것의 핵심인 QuantEngine 코드를 공개합니다.

시리즈 전체 목차
1~6편 — V1 균등배분 리밸런싱
7편 — V2 기획 & 시스템 설계
8편 — QuantEngine 집합 분류 알고리즘
9편 — 웹 UI & 실제 화면 공개

댓글 없음:

댓글 쓰기

가장 많이 본 글