Commit Graph

17 Commits

Author SHA1 Message Date
1b9257c4d2 fix: 매매 파라미터 3중 소스 정합 + 리스크 가드 복원 + 죽은 코드 2,695줄 제거
## 배경
"전략이 혼란스럽고 현재와 맞지 않는다"를 조사한 결과, 전략 설계가 아니라
전략을 검증했다는 도구와 파라미터 소스가 어긋나 있었다.

## 파라미터 소스 단일화
- 우선순위가 adaptive > strategy_cfg(DB) > config.py 인데 문서는 맨 마지막인
  config.py 를 기술하고 있었다. 11곳이 불일치(BULL RSI 46 vs DB 30, SL -7% vs -6%).
- DEFAULT_PARAMS 를 config.py 에 정합 + alembic 0012 로 기존 DB 행 갱신
  (운영자가 UI 로 바꾼 값은 보존, 옛 기본값과 같은 행만 갱신, 테이블 가드·멱등)

## 백테스트를 실전 로직에 정합
- calculate_adx_simple 이 정확히 period 배(14.0×) 발산 → Aggressive 게이트
  `ADX>25` 가 전 레짐 100% 통과. 전환 빈도 5.6%→2.0%(-65%), 성과 상방 편향
- 백테스트 RSI 는 SMA, 실전은 Wilder → 진입 판정 10~11% 불일치
- us_backtest_engine RSI 1봉 지연 제거 (룩어헤드 없음을 절단 테스트로 증명)
- backend/backtest_results/ 25건은 폐기 대상 (§8.4)

## 리스크 가드 복원
- 4% 절대 상한이 try 블록 안에 있어 예외 시 적응형 6~7% 가 통과 → try 밖으로
- 청산을 매수보다 먼저 평가 (보유 종목이 추천에 들면 손절 대신 물타기가 나갔다)
- 리스크 가드 4개를 매수 전용화 → MDD -10%·보유한도 도달 시에도 손절 작동
- MDD 갱신 5회 연속 실패 시 신규 진입 차단 fail-safe (청산은 계속 허용)
- 스윙 청산이 DT 보유분까지 매도하던 문제, sell_pct 기준 혼재 정정

## 죽은 코드 제거 (2,695줄)
- short_term_strategy, kosdaq_scanner, app/strategy/ 패키지
- app/trading/ + korea_investment_api_adapter (real_market_api 정본은
  korea_investment_api.py:1482, adapter 는 import 0건)

## 지표·사이징 단일화 (수치 무변경 증명)
- indicators_core.py: 3,274건 비교 최대 오차 0.000e+00
- sizing_core.py: 42,105건 비교 불일치 0
- 미국 전략 상수 13개 config 편입 (hex 까지 동일, 3,168 케이스 전수 비교)

## 테스트 안전 (실 KIS 호출 차단)
- 유닛 테스트가 실제 KIS 에 매도 주문을 2회 전송하고 있었다. 리팩터링이
  close_stale_positions 의 대상을 _execute_exit → _execute_exit_stale 로
  바꿨는데 목이 전자에 걸려 빗나갔다. test_api_endpoints 도 캡처된 싱글톤
  참조 누수로 실제 잔고 조회를 타 141초를 소비했다.
- backend/tests/conftest.py 신설: 주문·토큰·시세·잔고를 호출 즉시 예외로 차단.
  예외는 BaseException 파생(프로덕션 except Exception 폴백에 삼켜지지 않게),
  클래스 메서드에 적용(캡처된 참조까지 덮음), DATABASE_URL `_test` 가드 강제
- 전체 유닛 스위트: 365초/6 failed → 11.8초/0 failed (소켓 차단 하 559 passed)

## 신규 (둘 다 플래그 OFF, 백테스트 미검증)
- range_trading_strategy.py — SIDEWAYS 담당 전략이 없던 빈 칸. 미배선
- check_bear_buy_signal_v2 — BEAR 4중 AND(발화율 2.3%) → 점수제(12.4%)

## 문서
- CLAUDE.md 를 실제 코드 기준으로 재작성. §0 파라미터 우선순위, §4.1 테스트 규약,
  §6.4 문서화되지 않았던 진입 차단 게이트 9종, §8.4 백테스트 폐기 근거,
  §8.5 미해결 19항목
- 루트 md 6개 → 2개(docs/ 이동), 중복 배치 문서 병합, 스테일 worktree 제거

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-28 08:58:18 +09:00
85cb5cbc09 fix: 감사 잔여 항목 — 잔량 출처 DB화·ORB 영속화·미국 부분청산·듀얼전략 태깅·NULL 가격
- portfolio_cache_bridge: 잔량 산출을 Portfolio(DB) 기준으로. 캐시는 sync 실패 시 최대
  5분 낡아 실제와 다른 잔량이 기록될 수 있었음(감사 #14). 조회 실패 시 캐시 폴백.
- ORB 캐시 Redis 영속화(save/load_orb_cache) — 재배포 시 인메모리가 날아가 당일 ORB
  전략이 통째로 불가능했음. 수집 후 저장, 스케줄러 기동·수집 시 복원.
- us_market_scheduler: 부분청산이 Portfolio.quantity 를 갱신하지 않던 문제 → reflect_sell 연동.
- 듀얼 전략(MOMENTUM_BREAKOUT/PULLBACK_BUY)이 ActiveTrade.strategy_name 에 저장되지 않아
  CLAUDE.md §8.4 모멘텀 전용 청산(+10%/+20% 분할)이 한 번도 실행된 적 없었음 → 태깅 전달.
  매도 시에는 실제 행의 strategy_name 으로 close (swing 으로 닫으면 유령 행 잔존).
- 수동매도: current_price NULL 시 TypeError 로 주문 후 상태 갱신이 통째로 누락되던 엣지 수정.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 11:11:20 +09:00
8971a648e2 fix(P2): 주문 멱등성·취소 보호·다중행·v2/수동매도 정합
- korea_investment_api: 주문 계열 엔드포인트는 내부 재시도 금지(_NON_IDEMPOTENT_ENDPOINTS).
  상위 _place_order_with_retry 와 중첩돼 타임아웃 시 동일 주문 최대 12회 전송 가능했음.
  get_todays_orders() 추가.
- trade_executor: 예외 후 재시도 전에 당일 주문내역으로 접수 여부 확인(_find_recent_order)
  → 접수됐으면 재주문하지 않고 기존 주문 반환.
- daytrading/exit_service: 주문 체결 이후 상태 반영을 _finalize_exit 로 분리하고
  asyncio.shield 로 보호 — 스케줄러 단계 타임아웃이 이 구간을 취소하면 브로커는 팔았는데
  인메모리는 그대로라 다음 사이클이 재매도.
- swing/position_manager: active 행이 2개면 MultipleResultsFound 로 해당 종목 청산이
  통째로 스킵됐음(손절 미작동) → 최신 행 사용.
- swing/exit_service: 큐 지연·DLQ 시 같은 분할매도가 반복되지 않도록 180초 인메모리 쿨다운.
- portfolio_v2: 부분매도 ActiveTrade 잔량 갱신 + 전략명 매핑(daytrading→day_trade,
  us_swing→us_mean_reversion) — 매칭 실패로 active 행이 영구 잔존했음.
- portfolio.sell_stock: safe_place_order 경유(세마포어·분산락) + DT 인메모리 잔량 반영.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 10:57:40 +09:00
70def8fe0b fix(P0): 인증 누락·레거시 DT 엔진 병존·혼재 종목 재태깅·자정 후 스테일 청산 무력화
감사 CRITICAL 4건:
- /daytrading/{watchlist,execute,close-all,cycle} 에 require_api_key 누락 → 인증 없이
  전량 청산 가능했음 (CLAUDE.md §4 위반)
- 레거시 day_trading._positions 가 엔진 day_trading_state 와 별도로 기동 시 복원돼
  같은 포지션이 두 엔진에 존재 → /close-all 시 이중 매도. 복원 제거 + close-all/cycle 을
  엔진에 위임, /execute 실매수는 410(엔진 미관리 포지션 방지)
- reflect_buy 가 기존 행을 daytrading 으로 재태깅 → 같은 종목 스윙 보유분이
  get_swing_holdings 에서 빠져 손절·익절 정지. 신규 행일 때만 태깅
- close_stale_positions 가 인메모리만 순회 → 자정 reset 후 대상이 사라져 무력.
  ActiveTrade(day_trade/active/전일) 조회 기반으로 변경하고 인메모리가 비어도 실행

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 10:49:30 +09:00
f32bf412f3 fix: 로그 분석으로 찾은 버그 4건 (과다매도·수량 0 오염·LSTM 무력화·sync 충돌)
1) DT 분할매도가 ActiveTrade.quantity를 갱신하지 않아 재기동 복원 시 원래 수량이 되살아남
   → 잔량 4주인데 7주 매도되어 같은 종목 스윙 보유분 3주까지 청산됨(2026-09-23 LG씨엔에스).
2) reflect_sell이 '전략 포지션 잔량'을 Portfolio 행 잔량으로 사용 → DT 전량청산이 스윙
   보유분까지 0으로 만듦. 행 잔량은 항상 (행 수량 - 매도 수량)으로 계산.
3) LSTM 체크포인트에 numpy 배열이 들어가 weights_only=True 로드가 매번 실패 → 앙상블에서
   LSTM이 조용히 빠진 채 예측 중이었음. 저장을 list로 바꾸고, 기존 파일은 MODEL_DIR 내부일
   때만 완화 재시도.
4) 수동 매도(행 삭제)와 sync 동시 실행 시 StaleDataError로 sync 전체 실패 → 전량 매도는
   행 삭제 대신 수량 0, sync는 충돌 시 실패 기록 없이 다음 주기 재시도.
   추가로 비강제 sync는 락 점유 중이면 30초 대기 없이 캐시 반환.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 10:24:45 +09:00
d8550a2241 fix: 스케줄러 단계별 타임아웃 — KIS 무응답 시 EOD 청산 누락 방지
로그 분석(2026-09-22): 15:03:46 진입 스캔 이후 데이트레이딩 스케줄러가 16:52 재배포까지
1시간 49분간 아무 로그도 남기지 않음 = KIS API 무응답(500/Server disconnected 연속)으로
await가 반환되지 않아 루프 정지 → 15:20 EOD 강제청산 미실행 → 포지션 익일 보유.
- _guard(): 각 단계를 asyncio.wait_for로 감싸 초과 시 취소 후 다음 사이클 진행
- 단계별 상한: MDD 30s / watchlist 120s / ORB·EOD청산 300s / 청산·진입 180s
- MDD 판단 불가 시 보수적으로 신규 진입 차단
- 테스트 3건

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 10:18:00 +09:00
a659de09e3 feat: 전일 미청산 데이트레이딩 포지션 즉시 청산 안전장치
15:20 EOD 강제청산이 누락/실패하면 포지션이 하룻밤 갭 리스크에 노출된 채 다음 날
일반 청산 로직을 탄다(2026-09-22 LG씨엔에스 7주 → 익일 09:30 분할매도).
- exit_service.close_stale_positions(): 진입일이 오늘이 아닌 포지션을 장중 시장가 전량 청산,
  현재가 조회 실패 시 진입가 폴백, 실패 시 다음 30초 사이클에서 재시도
- 청산 사이클(check_and_exit_positions) 및 스케줄러 기동 직후 양쪽에서 호출
- 테스트 5건, CLAUDE.md §7.3 반영

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 10:01:00 +09:00
546cf17edb fix: 장 마감 중 30분 sleep이 09:00 개장을 건너뛰어 ORB 수집 누락
데이트레이딩 스케줄러는 장 마감 시 무조건 1800초를 자서, 08:31~09:00 사이에 잠들면
09:01~09:30에 깨어나 ORB 수집 구간(09:00~09:30)을 통째로 놓쳤음(2026-09-23 감시종목 0 확인).
- market_schedule.seconds_until_market_open() 추가 (주말·공휴일 건너뜀)
- 스케줄러: 마감 중 sleep = min(1800, 개장까지 남은 시간), 개장 3분 전 watchlist 선구성
- 회귀 테스트 4건

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 09:05:36 +09:00
a57c720559 feat: 데이트레이딩 포지션 화면 표시 + 모든 매도 즉시 화면 반영
- portfolio_cache_bridge 신설: 매매 엔진 체결 시 Portfolio(db_worker 큐) + 인메모리 캐시 즉시 갱신.
  DT 매수는 strategy_type='daytrading'으로 태깅되어 보유 종목 패널의 '데이트레이딩' 그룹에 표시되고
  스윙 청산 로직(strategy_type='swing' 대상)에서 제외됨. (기존엔 KIS 동기화로 'swing'으로 유입돼
  DT 포지션이 안 보이고 스윙 엔진이 같이 관리하는 문제)
- DT 매도·스윙 자동 매도도 캐시에서 즉시 제거/차감 + 최근매도 기록(동기화 되살림 방지).
- 동기화 시 DT 엔진 보유 종목은 'daytrading'으로 태깅.
- 프론트: 수동 매도 성공 시 낙관적 갱신으로 서버 재조회 전 즉시 목록에서 제거.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 16:49:46 +09:00
496529782b fix: 수동 매도 즉시 반영 + 매도/매수 결과 토스트 + 당일 매도대금 가용현금 반영
- 프론트: 토스트 알림 시스템(lib/toast + ToastHost) 추가, 매도/매수 성공·실패를 화면에 표시
  (기존엔 console.log만, 실패는 블로킹 alert). 성공 토스트에 손익 표시.
- 매도 직후 예수금/평가액 요약 즉시 갱신(apply_sell), 최근 5분 내 수동 매도 종목은
  KIS 잔고 반영 지연으로 동기화가 되살리지 않도록 스킵(recent_sells).
- 예수금이 D+2 결제 기준(dnca_tot_amt)이라 당일 매도대금이 화면·데이트레이딩 가용현금에
  반영되지 않던 문제: 매수가능조회(inquire-psbl-order) ord_psbl_cash 를 우선 사용.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 14:40:39 +09:00
e0178aaf0d feat: 데이트레이딩 ORB 복구 + 스윙:DT 자본 50:50 + 시간대 제한 완화
- ORB: 09:00에 당일 분석이 없으면 최근 분석일 결과로 watchlist 선채움 → ORB 수집 가능.
  자동 목록은 30분마다 갱신(당일 분석 완료 시 교체), 수동 설정 목록은 덮어쓰지 않음.
- 자본 배분: DAY_TRADE_MAX_RATIO_DT 0.25→0.50, 종목당 4%→6%, 동시 3→8종목.
  SWING_MAX_CAPITAL_RATIO=0.50 신설 — 스윙 합산 투자액 초과 시 스윙 신규 매수 차단(trade_executor).
- 시간대: 점심(11:30~13:00) VWAP/RSI_BB 제한 제거, 하드코딩 14:30 마감 → 설정값 15:00.
- 회귀 테스트 3건, CLAUDE.md §6/§7.3/§8.2 갱신.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-22 13:29:02 +09:00
028a1c352b feat: 자동매매 신뢰성 개선 — 시세 실서버 라우팅·일일 한도 전역화·수동 매수 API
- korea_investment_api: KIS_QUOTES_VIA_REAL — 모의투자 모드에서 시세/차트/호가 조회를
  실계좌 시세 서버(20/s)로 위임, 주문·잔고는 모의서버 유지 (EGW00201 대응)
- recommendations: execute_auto_trade_background asyncio.Lock 중복 실행 방지 +
  MAX_DAILY_TRADES를 당일 BUY 건수 차감 전역 기준으로 적용 (11종목 동시 매수 재발 방지)
- manual_buy.py 신규: POST /api/v1/portfolio/buy (리스크 가드 + safe_place_order + db_worker)
- mcp-server: claude_code_client(claude -p 헤드리스 모드) 추가, trade_monitor 부분매도 시
  active 유지·remaining_pct 갱신, API 키 헤더·/api/v1 경로 수정, ODNO 주문ID 수정
- config: MCP_REQUEST_TIMEOUT, MCP_RISK_CACHE_TTL, BATCH_ANALYSIS_INTERVAL,
  SWING_INDEX_BREAKER_ENABLED(OFF), API_TRIGGERED_AUTO_TRADE(OFF) 추가
- docker-compose: 포트 충돌 해소 (postgres 15433, frontend 3001)
- frontend: 추천 패널 매수 버튼, 차트/호가/저널 패널 개선
- CLAUDE.md 압축 최적화 (규칙 변경 없음), _sweep_single_axis.py 백테스트 단일축 스윕

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 23:37:08 +09:00
408bcce62e fix: 자동매매 신뢰성·소액계좌 안전배치 5종
감사에서 드러난 신뢰성·조용한실패 버그 수정. 전략값(§5)·시그니처(§4) 불변.

① KIS API 신뢰성(korea_investment_api, config): 스로틀에 _throttle_lock 추가로
   thundering herd(8코루틴 동시발사) 제거, API_TIMEOUT 10→20초, circuit_breaker
   임계 15→7, 재시도 백오프 지터. → 시간당 121건 실패의 근원 완화.
② portfolio summary 보존(portfolio): 잔고 API 실패 시 summary가 영영 None으로
   남아 현금 0→매수 스킵되던 것을, 최초 실패 시 holdings 기반 부분 summary로 채움.
③ output2 빈리스트 가드: KIS가 output2=[] 반환 시 IndexError로 MDD 업데이트가
   조용히 스킵(하방보호 비활성)되던 것 방어. swing/scheduler·adaptive_strategy
   (실버그) + daytrading 2곳(정규화). trade_executor:555는 load-bearing 가드라
   의도적 미변경.
④ MIN_BUY_AMOUNT config화+소액완화(trade_executor, config): 하드코딩 50만을
   MIN_BUY_AMOUNT_KRW로. 자산 833만↓ 계좌가 전종목 차단되던 것을 자산 대비로
   완화(큰 계좌는 기존 50만 하한 불변).
⑤ adaptive 서브버그(adaptive_strategy): fallback 시 _last_update_ts 갱신(refresh
   남발 방지), force_mode_override 전체필드(crisis의 max_daily_trades=0 실제 적용),
   get_event_loop→get_running_loop.

검증: code-verifier 통과(CONFIRMED 버그/회귀 없음, 4개 위험지점 안전), pytest 442 통과.
(day_trading.py·entry_service.py는 소량 인접 선재편집 포함 — 검증 완료.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBmzf1HDnvFHLraJ8eaaKJ
2026-09-16 16:59:59 +09:00
168b06f833 수정
Some checks failed
CI/CD Pipeline / test-backend (push) Has been cancelled
CI/CD Pipeline / test-frontend (push) Has been cancelled
CI/CD Pipeline / build-and-push (push) Has been cancelled
2026-04-06 18:15:13 +09:00
5f0f839039 전략 취약점 15건 수정 (코드 리뷰 기반)
## CRITICAL/HIGH (S1-S8)
- S1: Aggressive 모드 %B 스케일링 캡 1.3 (BB 중앙선 위 매수 방지)
- S2: ML scaler train-only fit (데이터 누수 제거)
- S3: SIDEWAYS = ADX<20 AND slope≈0 (트렌드 초기 차단 해소)
- S4: EOD 청산 실패 시 재시도 + CRITICAL 로그
- S5: 일일 손실 한도에 미실현 P&L 포함
- S6: trailing stop 고점 매 사이클 갱신
- S7: 섹터 필터 미매핑 종목 "기타" 분류 (max 3 적용)
- S8: 스캐너 RSI 기준 25→46, BB 점수 -3%~+1.5% 구간

## MEDIUM (M1-M7)
- M1: 스캐너 최소 거래량 100만→10만주
- M2: ADX 히스테리시스 18/22 (국면 플리핑 방지)
- M3: 분할매도 최소 수익 1.0%→0.5%
- M4: ORB 갭 필터 4% + 레인지 폭 0.3% 최소
- M5: 쿨다운 스트릭 부분매도 시 미변경
- M6: MDD 강제매도 loss_tracker 기록 제거 (허위 ban 방지)
- M7: RSI Wilder 스무딩으로 통일

## 인프라/보안
- 인증 누락 엔드포인트 수정 (analysis, journals)
- nginx 보안 헤더 location 블록 누락 수정
- Alembic 마이그레이션 IF NOT EXISTS 가드 추가
- SellRequest/UsOrderRequest 입력 검증 강화
- 차트 네이버 폴백 추가 (DB 데이터 없을 때)
- 서버 이전 시 자동 DB 마이그레이션 + KRX 초기 수집
- CLAUDE.md 섹션 5.1 백테스트 값 동기화 (4%→6%, -6%→-7%)
- MAX_SWING_POSITIONS 25→20 (CLAUDE.md 준수)
- mdd_manager failed_count에서 skip 종목 제외

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 11:44:14 +09:00
f92479f3b0 fix: 전체 회의 CRITICAL 6건 수정 — 손절/리스크/성과/인프라
1. trade_executor: 손절값 -6.0 하드코딩 → -settings.STOP_LOSS_PERCENT (7%)
2. mdd_manager: MDD 강제매도 시 loss_tracker 호출 추가
3. risk_validator, day_trading: 가격필터 < → <= (5,000원 정확히 차단)
4. daytrading/entry_service: 글로벌 자본 사용률(95%) 가드 추가
5. trade_analyzer: 수익률 0%를 손실에서 제외 (< 0으로 변경)
6. db_worker: 종료 시 큐 drain + DLQ 백업으로 데이터 유실 방지

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:24:59 +09:00
de7921d270 fix: CRITICAL/HIGH 버그 30건 수정 + 전체 코드 주석 추가 + 중복 정리
## CRITICAL 수정 (20건)
- day_trading: global 선언 누락, loss_tracker 연동, ban 체크 추가
- trade_executor: BUY 체결가 order_price로 수정, remaining_pct 누적 계산
- risk_validator: get_current_price dict 파싱, MAX_POSITION_SIZE 동기화, DB 세션 누수
- risk_management/recommendations: date.today() → KST 변환
- mdd_manager: Lock 밖 executed_key 참조 수정
- correlation_filter: output → output2 키 수정
- portfolio: 해외 종목 USD/KRW 환율 적용 분리
- Sharpe Ratio 거래빈도 기반 연간화
- telegram_notifier: send_message() 공개 래퍼 추가
- position_manager: 앱 재시작 시 DB 포지션 복원
- swing exit_service: remaining_pct 조건 범위 수정
- run_backtest: original_qty 기반 remaining_pct 계산
- us_market_schedule: 2027년 미국 공휴일 추가
- Login.tsx: res.ok 검증 추가
- mean_reversion_strategy: RSI 로그 하드코딩 수정

## HIGH 수정 (10건)
- db_worker: DLQ 파일 백업 메커니즘 추가
- korea_investment_api: 만료 토큰 임의 연장 제거
- market_data: chart_cache 최대 100개 + TTL 만료
- main.py: rate_limit_store 1시간 미접근 IP 정리
- recommendations: fire-and-forget try/except 추가
- swing/scheduler: DB 세션 3개 분리
- Dashboard: wsMessages 전체 순회
- Layout: /health 엔드포인트 + 30초 폴링
- ml_ensemble: POST /train require_api_key 추가
- day_trading: record_trade_result_safe() 전환

## 코드 정리
- 프론트엔드: isUsStock, formatTime 공통 유틸 추출
- 백엔드: dead code 제거, 중복 import 통합
- MCP: JSON 파싱 헬퍼 추출 (~60줄 감소)
- 전체 ~100개 파일 한국어 주석 추가
- 테스트 13건 코드 기준 수정 (468 passed)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:05:41 +09:00