신규 모듈: recommendation.py, backtest.py. 신규 엔드포인트: GET /recommendations, GET /backtest/{symbol}.
신규 BE는 없음 — 알림 등록은 POST /api/v1/alerts 재사용.
Terminology
PRD를 따른다.
Define Problem
AS-IS
단일 종목 시그널만 존재. 후보 선정·검증 없음.
TO-BE
후보 병렬 스코어링 → 필터·랭킹 → 진입 제안, 워크포워드 백테스트.
Possible Solutions
방안 비교
방안
설명
채택
미채택 사유
후보 병렬 스코어링
ThreadPoolExecutor(5)로 시그널 동시 계산
✅
—
순차 스코어링
후보 N개를 직렬 호출
✗
claude 호출이 느려 직렬 시 응답 지연 큼
진입가=현재가 고정
단순
✗
추격매수 위험. 지지/되돌림 기반이 정보량↑
감성 포함 백테스트
과거 시점 감성 복원
✗
과거 헤드라인 시계열 API 없음(룩어헤드·복원 불가)
Detail Design
추천 흐름
후보 = watchlist(BE GET /api/v1/watchlist, timeout 5s, 실패 시 []) ∪ CURATED_SYMBOLS
점수 = ThreadPoolExecutor(max_workers=5) → _safe_signal(symbol) # 실패 종목 제외
필터 = composite_score > 0.15
랭킹 = 내림차순, 상위 limit
각 종목 = suggest_entry()
suggest_entry 규칙
조건
entry_price
timing
current ≤ MA20
current
”즉시 분할 매수 고려”
current > MA20
max(MA20, recent_low)
“눌림목(되돌림) 대기”
composite ≥ 0.5
(위 진입가 유지)
접두사 “강세 — “
백테스트 (워크포워드)
warmup = 20 (초기 스킵)
for t in [20, len-horizon-1]:
momentum = score(prices[0:t+1]) # 룩어헤드 없음
ret = (prices[t+horizon] - prices[t]) / prices[t]
overall_win_rate = 양수 ret 비율 (전체)
signal_win_rate = 양수 ret 비율 (momentum > 0.15 구간)
edge = signal_avg_return - overall_avg_return
note: 뉴스 감성 미포함 — 기술 모멘텀만 검증
Sequence Diagram — 추천
sequenceDiagram
participant C as Client
participant M as main.py
participant BE as backend watchlist
participant P as ThreadPool
participant R as recommendation
C->>M: GET /recommendations?limit
M->>BE: GET /api/v1/watchlist (graceful)
BE-->>M: symbols (또는 실패→[])
M->>P: _safe_signal(symbol) ×N 병렬
P-->>M: signals
M->>R: rank(filter>0.15, sort, top-N)
M->>R: suggest_entry(each)
M-->>C: recommendations[]
ERD
영속 스토리지 없음. watchlist는 BE에서 조회, 시세·캔들은 토스에서 조회.
Testing Plan
recommendation.py: 진입가 규칙(current ≤ MA20 → 즉시 매수 / current > MA20 → 눌림목 대기), 강세 접두사(composite ≥ 0.5), 필터(> 0.15) 및 내림차순 정렬 검증
backtest.py: 워크포워드 룩어헤드 배제 확인, 승률(overall/signal) 및 edge 계산 정합성 검증
main.py (통합): watchlist 조회 실패 시 큐레이션만으로 정상 추천 반환 검증
외부 호출(claude·토스 API·BE watchlist)은 pytest mocking으로 처리
edge 음수·samples=0 등 엣지케이스 포함
Release Scenario
시그널 서비스에 모듈·엔드포인트 추가 후 재기동.
BACKEND_BASE_URL로 BE watchlist 연동(없어도 graceful).
롤백: /recommendations·/backtest 라우터 비활성. 알림 등록은 기존 API라 영향 없음.
Observability
관측 포인트
방법
임계 / 조건
병렬 스코어링 실패 종목
로그 WARN skipped symbol={symbol} reason={e}
실패율 > 50% 시 추천 결과 0건 위험
BE watchlist 조회 실패
로그 WARN watchlist fetch failed, using curated only
매 요청마다 발생하면 BE 연동 점검
/recommendations 응답 시간
로그 응답 ms
> 10s 시 ThreadPool 병목 의심
/backtest samples=0
로그 INFO backtest samples=0 symbol={symbol}
lookback 파라미터·데이터 부족 여부 확인
edge < 0
결과 note에 한계 노출 (이미 명시)
운영 알림 불필요, 데이터 투명 공개 목적
FE 영향 분석
RecommendationCard(진입가 자동 알림: targetPrice=entry, direction=BELOW), BacktestSummary.
추천/백테스트는 ML 직접 호출, 알림 등록은 BE POST /api/v1/alerts 재사용.
Project Information
항목
내용
담당자
biuea
일정
2026-06-19 착수
티켓 수
7개 (STK3-01 ~ STK3-07)
신규 BE
없음 (기존 API 재사용)
신규 ML 모듈
recommendation.py, backtest.py
신규 엔드포인트
GET /recommendations, GET /backtest/{symbol}
Document History
날짜
변경 내용
작성자
2026-06-19
최초 작성 (Background~Release Scenario)
biuea
2026-06-19
Observability 상세화, Project Information·Document History 추가
biuea
2026-06-21
스킬 포맷 통일 (클래스 역할 표 제거, Testing Plan bullet 변환, Phase 표현 제거)