Commit Graph

285 Commits

Author SHA1 Message Date
agentson
0727f28f77 fix: 진화 전략 파일 3개 들여쓰기 구문 오류 수정 (issue #215)
Some checks failed
CI / test (pull_request) Has been cancelled
AI가 evaluate() 메서드 내부에 또 다른 evaluate() 함수를 중첩 정의하는
실수로 생성된 IndentationError 수정.

각 파일별 수정 내용:
- v20260220_210124_evolved.py: 중첩 def evaluate 제거, 상수/로직 8칸으로 정규화
- v20260220_210159_evolved.py: 중첩 def evaluate 제거, 16칸→8칸 들여쓰기 수정
- v20260220_210244_evolved.py: 12칸→8칸 들여쓰기 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 12:53:41 +09:00
agentson
ac4fb00644 feat: Daily 모드 ConnectionError 재시도 로직 추가 (issue #209)
Some checks failed
CI / test (pull_request) Has been cancelled
- _retry_connection() 헬퍼 추가: MAX_CONNECTION_RETRIES(3회) 지수 백오프
  (2^attempt 초) 재시도, 읽기 전용 API 호출에만 적용 (주문 제외)
- run_daily_session(): get_current_price / get_overseas_price 호출에 적용
- run_daily_session(): get_balance / get_overseas_balance 호출에 적용
  - 잔고 조회 전체 실패 시 해당 마켓을 skip하고 다른 마켓은 계속 처리
- 테스트 5개 추가: TestRetryConnection 클래스

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 12:51:15 +09:00
agentson
4fc4a57036 test: 테스트 커버리지 77% → 80% 달성 (issue #204)
Some checks failed
CI / test (pull_request) Has been cancelled
신규/추가 테스트:
- tests/test_logging_config.py: JSONFormatter, setup_logging 전체 커버 (14줄)
- tests/test_strategies_base.py: BaseStrategy 추상 클래스 커버 (6줄)
- tests/test_backup.py: BackupExporter 미커버 경로(빈 CSV, compress=True CSV,
  포맷 실패 로깅, 기본 formats) + CloudStorage boto3 모킹 테스트 20개 (113줄)
- tests/test_context.py: ContextSummarizer 전체 커버 22개 테스트 (50줄)

총 815개 테스트 통과, TOTAL 커버리지 80% (1046줄 미커버 / 5225줄 전체)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 12:48:08 +09:00
641f3e8811 Merge pull request 'feat: trades 테이블 mode 컬럼 추가 (#212)' (#221) from feature/issue-212-trades-mode-column into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #221
2026-02-23 12:34:26 +09:00
agentson
ebd0a0297c chore: PR #221 충돌 해결 — WAL 테스트(#210)와 mode 컬럼 테스트(#212) 병합
Some checks failed
CI / test (pull_request) Has been cancelled
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 12:34:06 +09:00
02a72e0f7e Merge pull request 'feat: DB WAL 모드 적용, .env.example 정리 (#210, #213, #216)' (#220) from feature/issue-210-213-216-db-wal-env-fix into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #220
2026-02-23 12:32:36 +09:00
478a659ac2 Merge pull request 'feat: 실전 투자 전환 — TR_ID 분기, URL, 신뢰도 임계값, 텔레그램 알림 (#201~#205, #208, #214)' (#219) from feature/issue-201-202-203-broker-live-mode into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #219
2026-02-23 12:32:21 +09:00
agentson
16b9b6832d fix: BULLISH confidence 임계값 75로 복원 (#205)
Some checks failed
CI / test (pull_request) Has been cancelled
CLAUDE.md 규칙 개정에 따라 BULLISH 시장은 75로 유지.
시장 전망별 임계값: BEARISH=90, NEUTRAL=80, BULLISH=75.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 12:30:51 +09:00
agentson
48b87a79f6 docs: CLAUDE.md confidence 규칙 BULLISH=75 명시 (#205)
시장 전망별 BUY confidence 최소 임계값:
- BEARISH: 90 (더 엄격)
- NEUTRAL/기본: 80
- BULLISH: 75 (낙관적 시장에서 완화)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 12:29:39 +09:00
agentson
ad79082dcc docs: CLAUDE.md 비협상 규칙 명시 강화 — BULLISH 시 confidence 임계값 포함 (#205)
Some checks failed
CI / test (pull_request) Has been cancelled
BULLISH 시장에서도 confidence < 80 → HOLD 규칙이 동일하게 적용됨을 명시.
시장 전망별 임계값: BEARISH=90(더 엄격), BULLISH/NEUTRAL=80(최소값).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 12:28:30 +09:00
agentson
11dff9d3e5 feat: trades 테이블 mode 컬럼 추가 (paper/live 거래 분리) (#212)
Some checks failed
CI / test (pull_request) Has been cancelled
- trades 테이블에 mode TEXT DEFAULT 'paper' 컬럼 추가
- 기존 DB 마이그레이션: ALTER TABLE으로 mode 컬럼 자동 추가
- log_trade() 함수에 mode 파라미터 추가 (기본값 'paper')
- trading_cycle(), run_daily_session()에서 settings.MODE 전달
- 테스트 5개 추가 (mode 저장, 기본값, 스키마 검증, 마이그레이션)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 10:33:02 +09:00
agentson
3c5f1752e6 feat: DB WAL 모드 적용, .env.example 정리 (#210, #213, #216)
Some checks failed
CI / test (pull_request) Has been cancelled
- #210: init_db()에 WAL 저널 모드 적용 (파일 DB에만, :memory: 제외)
  - 대시보드(READ)와 거래루프(WRITE) 동시 접근 시 SQLite 락 오류 방지
  - busy_timeout=5000ms 설정
- #213: RATE_LIMIT_RPS 기본값 2.0으로 통일 (.env.example이 5.0으로 잘못 표기됨)
- #216: .env.example 중요 변수 추가 및 정리
  - KIS_BASE_URL 모의/실전 URL 주석 명시 (포트 29443 수정 포함)
  - MODE, TRADE_MODE, ENABLED_MARKETS, PAPER_OVERSEAS_CASH 추가
  - GEMINI_MODEL 업데이트 (gemini-pro → gemini-2.0-flash-exp)
  - DASHBOARD 설정 섹션 추가

테스트 2개 추가 (WAL 파일 DB 적용, 메모리 DB 미적용 검증)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 10:30:47 +09:00
agentson
d6a389e0b7 feat: 실전 투자 전환 — TR_ID 분기, URL, 신뢰도 임계값, 텔레그램 알림 수정 (#201~#205, #208, #214)
Some checks failed
CI / test (pull_request) Has been cancelled
- #201: 국내/해외 TR_ID 실전/모의 자동 분기
  - get_balance: TTTC8434R(실전) / VTTC8434R(모의)
  - send_order: TTTC0012U/0011U(실전) / VTTC0012U/0011U(모의) [현금주문]
  - get_overseas_balance: TTTS3012R(실전) / VTTS3012R(모의)
  - send_overseas_order: TTTT1002U/1006U(실전) / VTTT1002U/1001U(모의)
- #202: KIS_BASE_URL 기본값 VTS 포트 9443→29443 수정
- #203: PAPER_OVERSEAS_CASH fallback 실전(MODE=live)에서 비활성화, 중복 코드 제거
- #205: BULLISH 시장 BUY confidence 임계값 75→80(기본값) 수정 (CLAUDE.md 비협상 규칙)
- #208: Daily 모드 CircuitBreakerTripped 시 텔레그램 알림 추가
- #214: 시스템 종료 시 notify_system_shutdown() 호출 추가

테스트 22개 추가 (TR_ID 분기 12개, confidence 임계값 1개 수정)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 10:28:24 +09:00
cd36d53a47 Merge pull request 'feat: 해외주식 미체결 SELL 시 이중 매수 방지 (#195)' (#200) from feature/issue-195-overseas-double-buy-prevention into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #200
2026-02-23 05:53:24 +09:00
agentson
1242794fc4 feat: 해외주식 미체결 SELL 시 이중 매수 방지 (#195)
Some checks failed
CI / test (pull_request) Has been cancelled
KIS VTS는 SELL 지정가 주문을 접수 즉시 rt_cd=0으로 반환하지만
실제 체결은 시장가 도달 시까지 지연된다. 이 기간 동안 DB는 포지션을
"종료"로 기록해 다음 사이클에서 이중 매수가 발생할 수 있었다.

- trading_cycle(): BUY 게이팅에 브로커 잔고 추가 확인 로직 삽입
- run_daily_session(): 동일 패턴의 BUY 중복 방지 로직 추가
- 두 함수 모두 이미 fetch된 balance_data 재사용 (추가 API 호출 없음)
- TestOverseasBrokerIntegration 클래스에 테스트 2개 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-23 05:52:35 +09:00
b45d136894 Merge pull request 'feat: 미구현 API 4개 대시보드 프론트 연결 (#198)' (#199) from feature/issue-198-dashboard-api-frontend into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #199
2026-02-23 05:37:33 +09:00
agentson
ce82121f04 feat: 미구현 API 4개 대시보드 프론트 연결 (#198)
Some checks failed
CI / test (pull_request) Has been cancelled
- Playbook(/api/playbook/{date}): 프리마켓 플레이북 아코디언 패널 추가
- Scorecard(/api/scorecard/{date}): 일간 스코어카드 KPI 카드 그리드 추가
- Scenarios(/api/scenarios/active): 활성 시나리오 매칭 테이블 추가
- Context(/api/context/{layer}): L1-L7 컨텍스트 트리 테이블 추가

모든 패널 decisions-panel 아래에 섹션 추가 방식으로 배치.
refreshAll()에 4개 함수 포함하여 30초 자동 갱신 지원.

보안:
- esc() 헬퍼로 innerHTML 삽입 값 XSS 방지
- ctx limit 값 parseInt + 범위 클램핑(1-200) 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 13:47:20 +09:00
0e2987e66d Merge pull request 'feat: 대시보드 Circuit Breaker 게이지 추가 (#196)' (#197) from feature/issue-196-cb-gauge into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #197
2026-02-22 11:49:57 +09:00
agentson
cdd5a218a7 refactor: CB 게이지 저장소를 context tree → system_metrics 별도 테이블로 분리
Some checks failed
CI / test (pull_request) Has been cancelled
대시보드 표시 전용 데이터를 AI 의사결정용 context tree에 저장하는 것은
관심사 분리 위반. system_metrics 경량 테이블을 신설하여 완전히 분리. (PR #197 코드리뷰 반영)

- db.py: system_metrics 테이블 추가 (key/value/updated_at)
- main.py: context_store.set_context(L6_DAILY) → db_conn.execute(system_metrics)
- app.py: contexts 쿼리 → system_metrics 쿼리
- tests: _seed_cb_context를 system_metrics 삽입으로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 11:49:03 +09:00
agentson
f3491e94e4 refactor: CB 게이지 pnl_pct 저장 레이어를 L7 → L6_DAILY로 변경
Some checks failed
CI / test (pull_request) Has been cancelled
portfolio_pnl_pct는 일별 성과 지표이므로 실시간 종목 데이터(L7)보다
일별 P&L 레이어(L6_DAILY)가 더 적합함. (PR #197 코드리뷰 반영)

- main.py: L7_REALTIME + ISO timestamp → L6_DAILY + date(YYYY-MM-DD)
- app.py: contexts 쿼리 layer/timeframe 조건 동기화
- tests: _seed_cb_context L6_DAILY + today 날짜로 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 00:33:21 +09:00
agentson
342511a6ed feat: 대시보드 Circuit Breaker 게이지 추가 (#196)
Some checks failed
CI / test (pull_request) Has been cancelled
- trading_cycle()의 L7 context에 portfolio_pnl_pct_{market} 저장 추가
  → 대시보드가 최신 pnl_pct를 DB에서 직접 조회 가능해짐
- /api/status 응답에 circuit_breaker 섹션 추가
  (threshold_pct, current_pnl_pct, status: ok/warning/tripped/unknown)
  - warning: CB 임계값까지 1% 이내 (-2.0% 이하)
  - tripped: 임계값(-3.0%) 이하
- 대시보드 헤더에 CB 게이지 추가 (점멸 도트 + 진행 바 + 수치)
  - ok: 녹색, warning: 오렌지 점멸, tripped: 빨간 점멸
- CB 상태 테스트 4개 추가 (ok/warning/tripped/unknown)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 21:13:53 +09:00
2d5912dc08 Merge pull request 'feat: 대시보드 오픈 포지션 패널 추가 (#193)' (#194) from feature/issue-193-dashboard-positions into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #194
2026-02-21 21:07:53 +09:00
agentson
40ea41cf3c feat: 대시보드 오픈 포지션 패널 추가 (#193)
Some checks failed
CI / test (pull_request) Has been cancelled
- /api/positions 엔드포인트 신설: 마지막 거래가 BUY인 종목을 오픈 포지션으로 반환
- _connect()에 WAL 모드 + busy_timeout=8000 추가 (트레이딩 루프와 동시 읽기 안전)
- init_db()에 idx_trades_stock_market_ts 인덱스 추가 (포지션 쿼리 최적화)
- index.html: 카드와 P&L 차트 사이에 포지션 패널 삽입 (종목/시장/수량/진입가/보유시간)
- 포지션 패널 테스트 3개 추가 (open BUY 반환, SELL 제외, 빈 DB 처리)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 20:52:51 +09:00
af5bfbac24 Merge pull request 'fix: BUY 결정 전 기존 포지션 체크 추가 — 중복 매수 방지 (#191)' (#192) from feature/issue-191-duplicate-buy-fix into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #192
2026-02-21 09:38:59 +09:00
agentson
7e9a573390 fix: BUY 결정 전 기존 포지션 체크 추가 — 중복 매수 방지 (#191)
Some checks failed
CI / test (pull_request) Has been cancelled
어제(2026-02-20) 거래 로그에서 NP 7번, KNRX 5번 중복 매수 발생.
trading_cycle()의 BUY 브랜치에 get_open_position() 체크를 추가하여
이미 보유 중인 종목은 HOLD로 전환, 재매수를 차단함.

- src/main.py: BUY 결정 직후 기존 포지션 확인 → 있으면 HOLD 변환
- tests/test_main.py: 테스트 2개 추가
  - test_buy_suppressed_when_open_position_exists
  - test_buy_proceeds_when_no_open_position

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 09:35:39 +09:00
7dbc48260c Merge pull request 'fix: 해외주식 모의투자 SELL TR_ID 오류 수정 VTTT1006U → VTTT1001U (#189)' (#190) from feature/issue-189-overseas-sell-tr-id-fix into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #190
2026-02-21 03:14:34 +09:00
agentson
4b883a4fc4 docs: KIS API TR_ID 공식 문서 참조 규칙 추가 (#189)
Some checks failed
CI / test (pull_request) Has been cancelled
docs/commands.md에 "KIS API TR_ID 참조 문서" 섹션 추가:
- 공식 문서 경로 명시: 한국투자증권_오픈API_전체문서_20260221_030000.xlsx
- 모의투자/실전투자 TR_ID 표 정리
- 비공식 자료(블로그 등) 사용 금지 경고
- 출처 주석 작성 가이드

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 03:14:00 +09:00
agentson
98071a8ee3 fix: 해외주식 모의투자 SELL TR_ID 오류 수정 VTTT1006U → VTTT1001U (#189)
Some checks failed
CI / test (pull_request) Has been cancelled
KIS 공식 문서(20260221) '해외주식 주문' 시트 확인 결과:
- 모의투자 미국 매수: VTTT1002U (기존 정상)
- 모의투자 미국 매도: VTTT1001U (기존 VTTT1006U → 잘못된 TR_ID)

VTTT1006U는 존재하지 않는 TR_ID로, 모든 해외 SELL 주문이
"모의투자에서는 해당업무가 제공되지 않습니다." 오류로 거부되었음.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 03:12:00 +09:00
agentson
f2ad270e8b docs: 2026-02-21 요구사항 로그 업데이트 (#187)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 00:34:16 +09:00
04c73a1a06 Merge pull request 'fix: SELL 주문에서 Fat Finger 오탐 수정 — 손절/익절 차단 버그 (#187)' (#188) from feature/issue-187-sell-fat-finger-fix into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #188
2026-02-21 00:33:46 +09:00
agentson
4da22b10eb fix: SELL 주문에서 Fat Finger 오탐 수정 — 손절/익절 차단 버그 (#187)
Some checks failed
CI / test (pull_request) Has been cancelled
SELL 주문은 현금을 소비하지 않고 받는 것이므로 Fat Finger 체크 대상이
아님. 포지션 가치가 잔여 현금의 30%를 초과해도 SELL은 정상 실행돼야 함.

- realtime/daily 사이클 두 곳 모두 수정
- SELL: check_circuit_breaker만 호출 (Fat Finger 스킵)
- BUY: 기존대로 validate_order 호출 (Fat Finger + Circuit Breaker)
- 테스트 2개 추가: SELL Fat Finger 스킵, SELL 서킷브레이커 적용 확인

재현 사례 (2026-02-21):
  JELD stop-loss -6.20% → FAT FINGER: 49,548 is 99.1% of cash 50,000
  RXT take-profit +46.13% → FAT FINGER: 88,676 is 177.4% of cash 50,000

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 00:32:11 +09:00
c920b257b6 Merge pull request 'improve: implied_rsi 포화 임계점 개선 12.5%→25% (#181)' (#186) from feature/issue-181-implied-rsi-saturation into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #186
2026-02-20 10:35:10 +09:00
9927bfa13e Merge pull request 'fix: Telegram 409 다중 인스턴스 충돌 시 WARNING + 30초 백오프 (#180)' (#185) from feature/issue-180-telegram-instance-lock into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #185
2026-02-20 09:52:15 +09:00
agentson
aceba86186 fix: Telegram 409 감지 시 백오프 대신 polling 즉시 종료 (#180)
Some checks failed
CI / test (pull_request) Has been cancelled
409 충돌 감지 시 30초 백오프 후 재시도하는 방식에서
_running = False로 polling을 즉시 중단하는 방식으로 변경.

다중 인스턴스가 실행 중인 경우 재시도는 의미 없고 충돌만 반복됨.
이제 409 발생 시 이 프로세스의 Telegram 명령어 polling을 완전히 비활성화.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:35:33 +09:00
agentson
b961c53a92 improve: implied_rsi 계수 4.0→2.0으로 완화 — 포화 임계점 12.5%→25% (#181)
Some checks failed
CI / test (pull_request) Has been cancelled
SmartScanner의 implied_rsi 공식에서 계수를 4.0에서 2.0으로 수정.
12.5% 이상 변동률에서 RSI=100으로 포화되던 문제를 개선.

변경 전: 50 + (change_rate * 4.0) → 12.5% 변동 시 RSI=100
변경 후: 50 + (change_rate * 2.0) → 25% 변동 시 RSI=100

이제 10% 상승 → RSI=70, 12.5% 상승 → RSI=75 (의미 있는 구분 가능)
해외 소형주(NYSE American 등)의 RSI=100 집단 현상 완화.

- smart_scanner.py 3곳 동일 공식 모두 수정
- TestImpliedRSIFormula 클래스 5개 테스트 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:33:35 +09:00
76a7ee7cdb Merge pull request 'fix: 잔액 부족 주문 실패 후 10분간 BUY 재시도 방지 (#179)' (#183) from feature/issue-179-insufficient-balance-cooldown into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #183
2026-02-20 09:31:08 +09:00
agentson
77577f3f4d fix: Telegram 409 충돌 시 WARNING 로그 + 30초 백오프 적용 (#180)
Some checks failed
CI / test (pull_request) Has been cancelled
다중 인스턴스 실행 시 Telegram getUpdates 409 응답을 ERROR가 아닌 WARNING으로
처리하고, 30초 동안 polling을 일시 중단하여 충돌을 완화.

- _conflict_backoff_until 속성 추가
- 409 감지 시 명확한 "another instance is polling" 메시지 출력
- poll_loop에서 백오프 활성 중 polling 스킵
- TestGetUpdates에 409 관련 테스트 2개 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:31:04 +09:00
17112b864a Merge pull request 'fix: uvicorn 미설치 시 dashboard 오해 없는 실패 처리 (#178)' (#184) from feature/issue-178-dashboard-log-order into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #184
2026-02-20 09:30:48 +09:00
agentson
28bcc7acd7 fix: uvicorn 미설치 시 dashboard 실패를 동기적으로 감지하여 오해 없는 로그 출력 (#178)
Some checks failed
CI / test (pull_request) Has been cancelled
스레드 시작 전에 uvicorn import를 검증하도록 _start_dashboard_server 수정.
uvicorn 미설치 시 "started" 로그 없이 즉시 WARNING 출력 후 None 반환.

- 사전 import 검증으로 "started" → "failed" 오해 소지 있는 로그 쌍 제거
- uvicorn 미설치 시 명확한 경고 메시지 출력
- test_start_dashboard_server_returns_none_when_uvicorn_missing 테스트 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:28:23 +09:00
agentson
39b9f179f4 fix: 잔액 부족 주문 실패 후 10분간 BUY 재시도 방지 (issue #179)
Some checks failed
CI / test (pull_request) Has been cancelled
잔액 부족(주문가능금액 부족) 에러 발생 시 해당 종목을 10분간 BUY 시도에서
제외하는 cooldown 메커니즘을 realtime/daily 루프 모두에 적용.

- _BUY_COOLDOWN_SECONDS = 600 상수 추가
- trading_cycle()에 buy_cooldown 파라미터 추가
- 잔액 부족 에러(주문가능금액) 감지 후 cooldown 설정
- BUY 실행 전 cooldown 체크 (realtime + daily session 모두)
- TestBuyCooldown 테스트 클래스 4개 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:26:09 +09:00
bd2b3241b2 Merge pull request 'feat: use market_outlook to adjust BUY confidence threshold (#173)' (#177) from feature/issue-173-market-outlook-threshold into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #177
2026-02-20 08:38:52 +09:00
561faaaafa Merge pull request 'feat: use playbook allocation_pct in position sizing (#172)' (#176) from feature/issue-172-playbook-allocation-sizing into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #176
2026-02-20 08:37:59 +09:00
a33d6a145f Merge pull request 'feat: add position-aware conditions to StockCondition (#171)' (#175) from feature/issue-171-position-aware-conditions into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #175
2026-02-20 08:36:07 +09:00
7e6c912214 Merge pull request 'feat: include current holdings in pre-market AI prompt (#170)' (#174) from feature/issue-170-holdings-in-prompt into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #174
2026-02-20 08:35:16 +09:00
agentson
d6edbc0fa2 feat: use market_outlook to adjust BUY confidence threshold (#173)
Some checks failed
CI / test (pull_request) Has been cancelled
- Import MarketOutlook at module level in main.py
- After scenario evaluation, check market_outlook and apply BUY confidence
  threshold: BEARISH→90, BULLISH→75, others→settings.CONFIDENCE_THRESHOLD
- BUY actions below the adjusted threshold are downgraded to HOLD with
  a descriptive rationale including the outlook and threshold values
- Add 5 integration tests covering bearish suppression, bearish allow,
  bullish allow, bullish suppression, and neutral default threshold

Closes #173

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 08:31:24 +09:00
agentson
c7640a30d7 feat: use playbook allocation_pct in position sizing (#172)
Some checks failed
CI / test (pull_request) Has been cancelled
- Add playbook_allocation_pct and scenario_confidence parameters to
  _determine_order_quantity() with playbook-based sizing taking priority
  over volatility-score fallback when provided
- Confidence scaling: confidence/80 multiplier (confidence 96 → 1.2x)
  clipped to [POSITION_MIN_ALLOCATION_PCT, POSITION_MAX_ALLOCATION_PCT]
- Pass matched_scenario.allocation_pct and match.confidence from
  trading_cycle so AI's allocation decisions reach order execution
- Add 4 new tests: playbook priority, confidence scaling, max clamp,
  and fallback behavior

Closes #172

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 08:29:09 +09:00
agentson
60a22d6cd4 feat: add position-aware conditions to StockCondition (#171)
Some checks failed
CI / test (pull_request) Has been cancelled
- Add unrealized_pnl_pct_above/below and holding_days_above/below fields
  to StockCondition so AI can generate rules like 'P&L > 3% → SELL'
- Evaluate new fields in ScenarioEngine.evaluate_condition() with same
  AND-combining logic as existing technical indicator fields
- Include position fields in _build_match_details() for audit logging
- Parse new fields from AI JSON response in PreMarketPlanner._parse_scenario()
- Update prompt schema example to show new position-aware condition fields
- Add 13 tests covering all new condition combinations and edge cases

Closes #171

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 08:27:44 +09:00
agentson
b1f48d859e feat: include current holdings in pre-market AI prompt (#170)
Some checks failed
CI / test (pull_request) Has been cancelled
- Add current_holdings parameter to generate_playbook() and _build_prompt()
- Inject '## Current Holdings' section into Gemini prompt with qty, entry
  price, unrealized PnL%, and holding days for each held position
- Instruct AI to generate SELL/HOLD scenarios for held stocks even if not
  in scanner candidates list
- Allow held stock codes in _parse_response() valid_codes set so AI-
  generated SELL scenarios for holdings pass validation
- Add 6 tests covering prompt inclusion, omission, and response parsing

Closes #170

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 08:25:38 +09:00
03f8d220a4 Merge pull request 'fix: use broker balance API as source of truth for SELL qty and holdings (#164 #165)' (#169) from feature/issue-164-165-broker-api-holdings into main
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #169
2026-02-20 07:52:26 +09:00
agentson
305120f599 fix: use broker balance API as source of truth for SELL qty and holdings (#164 #165)
Some checks failed
CI / test (pull_request) Has been cancelled
DB의 주문 수량 기록은 실제 체결 수량과 다를 수 있음(부분 체결, 외부 수동 거래).
브로커 잔고 API(output1)를 source of truth로 사용하도록 수정.

## 변경 사항

### SELL 수량 (#164)
- _extract_held_qty_from_balance() 추가
  - 국내: output1의 ord_psbl_qty (→ hldg_qty fallback)
  - 해외: output1의 ovrs_cblc_qty (→ hldg_qty fallback)
- _determine_order_quantity()에 broker_held_qty 파라미터 추가
  - SELL 시 broker_held_qty 반환 (0이면 주문 스킵)
- trading_cycle / run_daily_session 양쪽 호출 지점 수정
  - 이미 fetch된 balance_data에서 수량 추출 (추가 API 호출 없음)

### 보유 종목 루프 (#165)
- _extract_held_codes_from_balance() 추가
  - ord_psbl_qty > 0인 종목 코드 목록 반환
- 실시간 루프에서 스캔 시점에 get_balance() 호출해 보유 종목 병합
  - 스캐너 후보 + 실제 보유 종목 union으로 trading_cycle 순회
  - 실패 시 경고 로그 후 스캐너 후보만으로 계속 진행

### 테스트
- TestExtractHeldQtyFromBalance: 7개 (국내/해외/fallback/미보유)
- TestExtractHeldCodesFromBalance: 4개 (qty>0 포함, qty=0 제외 등)
- TestDetermineOrderQuantity: 5개 (SELL qty, BUY sizing)
- test_sell_order_uses_broker_balance_qty_not_db:
  DB 10주 기록 vs 브로커 5주 확인 → 브로커 값(5) 사용 검증
- 기존 SELL/stop-loss/take-profit 테스트에 output1 mock 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 07:40:45 +09:00