재무제표 기반으로 매수/매도를 판단하고, 최소 3단계 이상의 AI 자체 검증을 거쳐 모의투자 계좌에서 실행하는 에이전트 프로토타입입니다.
- 🔴 중복 재분석 방지:
decisions테이블에report_date컬럼을 추가하고,pipeline/orchestrator.py의process_ticker()가 1단계를 부르기 전에 같은(ticker, report_date)로 이미 판단한 적이 있는지 먼저 확인합니다. 있으면 그 결정을 그대로 반환하고 LLM을 다시 부르지 않습니다 - 스케줄러가 몇 번을 다시 돌아도 같은 재무제표를 매번 재분석하던 문제(리소스 낭비 + 판단이 사이클마다 흔들리던 문제)를 해결. - 분기보고서 코드 동적 계산:
data_sources/dart_client.get_latest_available_report()을 추가해서, 1분기보고서(11013)로 하드코딩되어 있던 걸 오늘 날짜 기준으로 사업/1분기/반기/3분기보고서 중 실제로 최신일 것으로 기대되는 걸 계산하도록 고쳤습니다 (server/scheduler.py,discovery/screener.py). - DART 오류 구분:
DartNoDataError(아직 보고서가 없는 정상 상황, status 013/014)와DartAPIError(인증키/요청한도/시스템점검 등 진짜 오류)를 별도 예외로 분리. 스케줄러가 진짜 오류만 모아서 하루 1회 알림을 보냅니다. - 헬스체크/하트비트: 메인 사이클 스레드와 독립적으로 도는 감시 스레드를 추가해서, 장중에
HEARTBEAT_STALE_MINUTES(기본 90분) 동안 사이클이 한 번도 안 돌면 알림을 보냅니다. 같은 정지 구간에 대해 중복 알림은 안 가고, 정상화되면 다시 알림 가능 상태로 리셋됩니다. - 청산 사유별 리포트 분리:
reporting/report_generator.py가protective_exits테이블을 근거로 SELL을 "AI 판단", "손절", "익절" 세 가지로 나눠서sell_breakdown필드에 반환합니다. - 설정값 자체 검증:
config.py가 임포트되는 즉시_validate_config()가 돌면서 모순된 설정 (예: 기각 임계값이 자동실행 임계값보다 큰 경우, 최소 현금버퍼+최대노출이 100% 초과 등)을ConfigError로 바로 잡아냅니다. - 일일 예산 사전 추정:
llm_client.estimate_worst_case_daily_cost()+/api/agent/budget-estimate엔드포인트 + 대시보드 "AI 사용량" 탭에 카드 추가. 현재 워치리스트 크기 기준 "이론상 하루 최대 비용"을 실제 키를 넣기 전에 미리 보여줍니다. - 발굴 스크리너 수동 실행 UI: "종목 발굴" 탭에 전체/미니 발굴 버튼을 각각 추가하고, 누르면 바로 실행되지 않고 확인 메시지가 먼저 뜹니다. 실행 중엔 스피너 + 진행 단계/진행률이 표시됩니다.
- 🔴 평단가 가중평균 버그 수정 (
execution/paper_trading_executor.py,backtest/engine.py): 같은 종목을 나눠서 추가매수하면avg_price가 최근 매수가로 덮어써지던 버그를 가중평균 계산으로 고쳤습니다.stop_loss.py/take_profit.py가 이 값을 기준으로 판단하므로, 이 버그가 손절/익절 발동 시점 자체를 왜곡시키고 있었습니다. - 🟡 백테스트에 손절/익절 통합 (
backtest/engine.py):BacktestExecutor.apply_protective_exits()를 추가해서, 실전 스케줄러의check_stop_losses/check_take_profits와 동일한 기준을 라이브 DB 접근 없이period["prices"]기준으로 매 기간마다 시뮬레이션합니다. risk_manager.py에backtest_mode플래그 추가: 쿨다운/유동성/캘리브레이션/상관관계/모멘텀처럼 라이브 DB(protective_exits, decisions, price_history)를 참조하는 규칙은 백테스트에서 스킵하고, DB와 무관한 결정론적 규칙(종목당 상한/총노출/현금버퍼/신뢰도 임계값)만 적용합니다. 이전엔 백테스트가 실행 중 라이브 DB에 부수효과를 남기던 문제가 있었습니다.- 이중 발굴 스크리너 (
discovery/screener.py,server/scheduler.py,db.py):- 전체 발굴(
mode="full"): 매달 넷째 주 월요일 1회, 전체 상장사 + 섹터 리서치까지 새로 수행, 기존 워치리스트를 완전히 재구성. - 미니 발굴(
mode="mini"): 매주 1회, 무작위 표본(DISCOVERY_MINI_UNIVERSE_SAMPLE_SIZE)만 가볍게 훑고, 섹터 리서치는 재사용, 기존 워치리스트를 지우지 않고 신규 종목만 추가. discovery_runs테이블에mode컬럼 추가 (구버전 DB도 자동 마이그레이션).
- 전체 발굴(
- 회귀 테스트 추가:
tests/test_paper_trading_executor.py(가중평균/peak_price),tests/test_backtest_engine.py(백테스트 가중평균 + 손절/익절 시뮬레이션),tests/test_scheduler_discovery.py(넷째 주 월요일 판별 - 5주짜리 달 엣지케이스 포함, 미니 발굴이 전체 발굴 워치리스트를 안 지우는지). 기존tests/test_risk_manager.py는 DB 미초기화 상태에서 단독 실행하면 실패하던 기존 결함도 함께 고쳤습니다. (전체 26개 테스트 통과 확인)
pip install -r requirements.txt
python -m pytest tests/ -vpip install -r requirements.txt
python demo_run.pyAPI 키 없이도 바로 실행됩니다 (아래 "동작 모드" 참고).
cp .env.example .env그 다음 .env 파일을 열어서 필요한 값만 채우세요. 전부 다 채울 필요는 없고,
쓰고 싶은 기능에 해당하는 것만 채우면 됩니다. 값을 다 채우거나 일부만 채운 뒤,
서버를 완전히 재시작해야 반영됩니다. 제대로 인식됐는지는
http://localhost:8000/api/agent/config-check 에서 확인할 수 있습니다.
| 환경변수 | 동작 |
|---|---|
ANTHROPIC_API_KEY 없음 |
규칙 기반 시뮬레이션으로 4단계 파이프라인 전체를 데모 |
ANTHROPIC_API_KEY 설정 |
실제 Claude API로 각 단계 판단 (Haiku=스크리닝, Sonnet=심층분석/검증/최종결정) |
DART_API_KEY 설정 |
data_sources/dart_client.py의 실제 DART 공시 조회 함수 사용 가능 |
config.py의 WATCHLIST_SOURCE(기본값 "both")에 따라 사람이 지정한 종목 +
AI가 스스로 찾은 종목을 함께/따로 감시할 수 있습니다.
- 전체 발굴: 매달 넷째 주 월요일 1회 (
DISCOVERY_FULL_RUN_WEEKDAY,DISCOVERY_FULL_RUN_WEEK_OF_MONTH). 전체 상장사 + 섹터 리서치를 새로 수행하고 워치리스트를 완전히 재구성합니다. - 미니 발굴: 매주 1회 (
DISCOVERY_MINI_INTERVAL_DAYS, 기본 7일). 전체 유니버스에서 작은 표본(DISCOVERY_MINI_UNIVERSE_SAMPLE_SIZE)만 가볍게 훑어서, 한 달 사이 놓친 기회를 보완합니다. 기존 워치리스트는 지우지 않고 새 종목만 추가합니다. - "종목 발굴" 탭에서 수동 실행도 가능합니다 (
POST /api/discovery/run?mode=full|mini).
data_sources/dart_client.py 재무제표 수집 (실제 DART API / 샘플 데이터)
↓
pipeline/stage1_screening.py 1단계: 저비용 모델 스크리닝
pipeline/stage2_deep_analysis.py 2단계: 심층 분석 (재무 트렌드 + 사업 미래가치)
pipeline/stage3_devils_advocate 3단계: 반대 심문 (확증편향 방지)
pipeline/stage4_final_decision 4단계: 최종 종합 + 포지션 사이징
↓
risk/risk_manager.py 하드코딩 리스크 규칙 (LLM 미개입, 항상 강제)
↓
execution/paper_trading_executor 모의투자 실행 (실전 전환 시 KIS API로 교체)
↓
db.py 모든 단계 근거 + 거래 내역 SQLite 로깅
↓
reporting/report_generator.py 수익률 + 결정별 사후 적중률 리포트
병렬로 risk/stop_loss.py / risk/take_profit.py가 AI 판단과 무관하게 항상 동작하고,
backtest/engine.py가 동일한 로직을 백테스트에서도 재현합니다.
- DART API 키 발급,
Claude API 키 설정, 모의투자 계좌 연동 (README 이전 버전과 동일) - 충분한 검증 기간: 최소 몇 달, 여러 시장 국면을 거친 뒤 실전 전환 검토.
backtest_real_run.py로 실제 과거 데이터 백테스트를 먼저 돌려보고, 가능하면 기간을 나눠(walk-forward) 특정 시장 국면에 과최적화되지 않았는지 확인하는 걸 권장합니다. - 실전 전환 후에도 리스크 규칙은 그대로 유지 — 오히려 더 보수적으로 시작하는 것을 권장합니다.
- 캘리브레이션 표본 크기(
MIN_CALIBRATION_SAMPLE_SIZE=20)가 통계적으로 넓은 신뢰구간을 갖는 문제 - 더 보수적인 기준이나 베이지안 방식 고려. - 상한가/하한가·부분체결 미반영 (주문량=체결량으로 가정).
- 실현/미실현 손익 분리 표시.
- 액면분할 등 기업행동(corporate action) 미반영.
이 코드는 프로토타입이며 투자자문이 아닙니다. 실전 매매 전 관련 법규 및 증권사 약관을 반드시 확인하시고, 투자 손실에 대한 책임은 본인에게 있습니다.