Files
auto-stock/.env.example
shuim b4a1fc79ab feat: 멀티테넌트 1단계 — 사용자별 KIS 계좌·포트폴리오·수동매매 (MULTI_TENANT_ENABLED 기본 OFF)
설계: docs/multi_tenant_design.md / 검수: docs/multi_tenant_phase1_review.md (High 0, MT=False 배포 가능)

데이터·인프라
- user_kis_credentials(Fernet 암호화, PBKDF2 키 파생, key_version), stock_bans_v2 신설,
  portfolio/trade_history/active_trades/trade_journals/trading_sessions 등 user_id nullable 추가
- alembic 0009~0011(idempotent, legacy owner 백필). main.py 기동 시 portfolio.user_id 스키마 검사(H1)
- Jenkinsfile: DB Migration 을 Deploy 앞으로, alembic 이력 없으면 stamp 0008 후 upgrade(N1)
- bootstrap: users 비어 있으면 BOOTSTRAP_ADMIN_* 로 관리자 시드 + .env KIS 자격증명 이관 + 백필(SAVEPOINT)

백엔드
- core/crypto.py, core/tenant_auth.py(get_current_user — 비활성 사용자 401, API 키→legacy owner,
  deny_non_owner_session_when_mt), core/dt_utils.py
- services/tenant: context, kis_pool, registry(UserContextRegistry, 락 최소화·복호화 to_thread), risk_factory
- KoreaInvestmentAPI.for_user(사용자별 인스턴스, 토큰캐시 users/{id}/, 시세는 공용 위임)
- trade_executor.safe_place_order_v2(사용자별 락/세마포어, legacy ctx 는 기존 키)
- mdd_manager/loss_tracker _v2 + ban_until tz-aware/naive 경계 정규화(레거시 경로 버그 포함 수정)
- db_worker: payload user_id 옵션 필터, upsert_stock_ban_v2, legacy ActiveTrade 조회 LIMIT 1
- API: /account/credentials(등록·마스킹조회·삭제·연결테스트·자동매매), /auth/admin/tenant/*,
  /portfolio/v2(조회·요약·sync·buy·sell), /trades/v2(+pending). PortfolioResponse Optional 수정

프론트
- /account 내 계좌 설정, useTenantMode(세션=v2 / API키=legacy, 미확정 시 쿼리·버튼 비활성),
  계좌 미등록 인라인 안내, v2 매수/매도/거래이력 분기

테스트: tests/integration(격리 Postgres, KIS 전면 mock) 20 passed / 1 xfailed(0012 이전 제약)
2단계(스케줄러 사용자화·legacy 라우터 격리) 전까지 MULTI_TENANT_ENABLED=True 전환 금지

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-21 10:26:51 +09:00

261 lines
17 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ═══════════════════════════════════════════════════════════════════════════════
# 자동 주식 매매 시스템 설정 파일 (.env)
# ═══════════════════════════════════════════════════════════════════════════════
#
# 모든 설정이 .env 파일 변수로 제어 가능합니다.
# 기본값은 config.py에 정의되어 있고, 여기서 오버라이드할 수 있습니다.
#
# 참조: CLAUDE.md - 섹션 1.2 환경 변수 참고
# ═══════════════════════════════════════════════════════════════════════════════
# 기본 애플리케이션 설정
# ═══════════════════════════════════════════════════════════════════════════════
ENVIRONMENT=development
DEBUG=false
LOG_LEVEL=INFO
# 백엔드 서버
BACKEND_HOST=0.0.0.0
BACKEND_PORT=8000
SECRET_KEY=your-secret-key-here
# 대시보드 로그인 — 계정은 DB(users)에 저장. 첫 가입자 = 관리자(자동 승인), 이후 가입자는 관리자 승인 필요
SIGNUP_ENABLED=true
SIGNUP_AUTO_APPROVE=false
SESSION_TOKEN_EXPIRE_HOURS=24
# 멀티테넌트(사용자별 매매) 1단계 — 기본 비활성. True 전환 전 §docs/multi_tenant_design.md 이행 순서 확인
MULTI_TENANT_ENABLED=false
CREDENTIALS_ENCRYPTION_KEY= # user_kis_credentials 암복호화 키 소스. 비우면 SECRET_KEY 폴백(SECRET_KEY 32자 이상 필수)
CREDENTIALS_ENCRYPTION_KEY_PREVIOUS= # 키 로테이션 중에만 설정(구 키, 복호화 전용)
BOOTSTRAP_ADMIN_USERNAME=admin # 앱 최초 기동 시 users 테이블이 비어있으면 시드할 관리자 계정명
BOOTSTRAP_ADMIN_PASSWORD= # 비우면 부트스트랩 관리자 시드를 건너뜀
# ═══════════════════════════════════════════════════════════════════════════════
# 데이터베이스 및 캐시
# ═══════════════════════════════════════════════════════════════════════════════
DATABASE_URL=postgresql://autostock:autostock_password@localhost:5432/autostock_db
REDIS_URL=redis://localhost:6379/0
RABBITMQ_URL=amqp://autostock:autostock_password@localhost:5672/
# PostgreSQL (도커 환경)
POSTGRES_USER=autostock
POSTGRES_PASSWORD=autostock_password
POSTGRES_DB=autostock
# ═══════════════════════════════════════════════════════════════════════════════
# 한국투자증권 (KIS) API 설정
# ═══════════════════════════════════════════════════════════════════════════════
# 모드 선택: "virtual" (모의투자) 또는 "real" (실전투자)
KIS_MODE=virtual
# 모의투자 (Paper Trading) 설정
KIS_VIRTUAL_APP_KEY=your_virtual_app_key
KIS_VIRTUAL_APP_SECRET=your_virtual_app_secret
KIS_VIRTUAL_ACCOUNT_NO=00000000-01
KIS_VIRTUAL_URL=https://openapivts.koreainvestment.com:29443
# 실전투자 설정
KIS_REAL_APP_KEY=your_real_app_key
KIS_REAL_APP_SECRET=your_real_app_secret
KIS_REAL_ACCOUNT_NO=00000000-01
KIS_REAL_URL=https://openapi.koreainvestment.com:9443
# WebSocket 접속키 (수동 지정 시 우선, 비어있으면 자동 발급)
KIS_WS_APPROVAL_KEY=
# WebSocket URL (커스토마이징 필요 시만 수정)
KIS_WS_REAL_URL=wss://openapi.koreainvestment.com:21000/websocket/realtime
KIS_WS_VIRTUAL_URL=wss://openapiwss.koreainvestment.com:29443/websocket/realtime
# KIS 실시간 스트림 타이밍 (초 단위)
KIS_SYNC_INTERVAL=10 # 구독 목록 동기화 주기
KIS_RECONNECT_WAIT=5 # 재연결 대기 시간
KIS_APPROVAL_KEY_TTL=82800 # approval_key 캐시 유효시간 (초, 23시간)
# 레거시 호환 (직접 지정 시 우선)
KOREA_INVESTMENT_APP_KEY=your_app_key_here
KOREA_INVESTMENT_APP_SECRET=your_app_secret_here
KOREA_INVESTMENT_ACCOUNT_NUMBER=your_account_number
KOREA_INVESTMENT_API_BASE_URL=https://openapi.koreainvestment.com:9443
# ═══════════════════════════════════════════════════════════════════════════════
# AI 프로바이더 설정
# ═══════════════════════════════════════════════════════════════════════════════
AI_PROVIDER=claude # "claude" 또는 "gemini"
ANTHROPIC_API_KEY=your_anthropic_api_key
# MCP 서버 설정
MCP_SERVER_URL=http://localhost:8001
MCP_VALIDATION_ENABLED=true # AI 검증 활성화
MCP_CONFIDENCE_THRESHOLD=0.5 # AI 신뢰도 최소값 (0.0~1.0)
# ═══════════════════════════════════════════════════════════════════════════════
# 거래 설정 (CLAUDE.md 섹션 5-8 기반)
# ═══════════════════════════════════════════════════════════════════════════════
# 기본 거래 파라미터
AUTO_TRADE_ENABLED=true # 자동매매 활성화
ANALYSIS_STOCK_COUNT=150 # 배치 분석 종목 수
AUTO_TRADE_TOP_N_PER_RULE=2 # 규칙당 자동매매 최대 종목 수
MAX_DAILY_TRADES=5
# 포지션 규칙 (섹션 5.1)
MAX_POSITION_SIZE=0.04 # 1종목당 최대 3-4% 자본
MAX_HOLDINGS_COUNT=20 # 동시 보유 최대 20종목
LEVERAGE_ETF_MAX_RATIO=0.20 # 레버리지/인버스 ETF 20% 이내
# 손절/익절 설정 (섹션 5.2)
STOP_LOSS_PERCENT=-6.0 # 저변동 종목 손절 -6%
STOP_LOSS_HIGH_VOL=-10.0 # 고변동 종목 손절 -10%
TAKE_PROFIT_PERCENT=5.0 # 익절 기본값
# ATR 기반 손절/트레일링 (섹션 5.2)
ATR_STOP_MULTIPLIER=2.5 # 2.5 × ATR 손절
ATR_TRAILING_MULTIPLIER=1.5 # 1.5 × ATR 트레일링
# MDD (최대 낙폭) 관리 (섹션 5.3)
MDD_PAUSE_THRESHOLD=-10.0 # -10% MDD: 신규진입 중단 + 30% 축소
MDD_FORCE_THRESHOLD=-20.0 # -20% MDD: 50% 강제 축소
# 가격 필터 (섹션 5.4)
MIN_PRICE_KRW=5000 # 국내 5,000원 이하 매수 금지
MIN_PRICE_USD=4.0 # 미국 $4 이하 매수 금지
# 연속 손실 관리 (섹션 7.4)
CONSECUTIVE_LOSS_BAN_COUNT=3 # 3회 연속 손실
CONSECUTIVE_LOSS_BAN_DAYS=30 # 30거래일 진입 금지
# ═══════════════════════════════════════════════════════════════════════════════
# 전략 A: RSI + 볼린저 밴드 평균회귀 (섹션 6)
# ═══════════════════════════════════════════════════════════════════════════════
MEAN_REVERSION_MAX_CAPITAL=0.30 # 전체 자본의 30% 이내 (섹션 7.5)
MEAN_REVERSION_RSI_THRESHOLD=30.0 # RSI 과매도 기준 (≤30)
MEAN_REVERSION_MULTIPLIER_STRONG=1.50 # RSI ≤ 20: 강한 신호 배수 (+50%)
MEAN_REVERSION_MULTIPLIER_NORMAL=1.25 # RSI ≤ 25: 중간 신호 배수 (+25%)
MEAN_REVERSION_MULTIPLIER_WEAK=1.00 # 기본 신호 배수 (4%)
# 시장 국면 필터 (7.5)
BEAR_MARKET_FILTER_ENABLED=true
BEAR_MARKET_MIN_SCORE=5
BEAR_MARKET_MAX_TRADES=3
BEAR_MARKET_POSITION_RATIO=0.5
# 급등 과열 필터 (섹션 5.4)
OVERHEAT_FILTER_ENABLED=true
OVERHEAT_3DAY_MAX=15.0 # 3일 최대 상승률 15%
OVERHEAT_5DAY_MAX=20.0 # 5일 최대 상승률 20%
OVERHEAT_10DAY_MAX=30.0 # 10일 최대 상승률 30%
OVERHEAT_DISPARITY_MAX=108.0 # 괴리율 최대 108%
# 트렌드 필터 (7.1)
TREND_FILTER_ENABLED=false
TREND_MA_SHORT=20 # 단기 MA 기간
TREND_MA_LONG=60 # 장기 MA 기간
TREND_TOLERANCE_PCT=0.005 # 허용 오차 0.5%
# ═══════════════════════════════════════════════════════════════════════════════
# 전략 B: 데이트레이딩 (섹션 8.2)
# ═══════════════════════════════════════════════════════════════════════════════
DAY_TRADE_ENABLED=true # 데이트레이딩 활성화
DAY_TRADE_MAX_POSITIONS=3 # 동시 최대 3종목
DAY_TRADE_CAPITAL_RATIO=0.25 # 전체 자본 대비 최대 25%
DAY_TRADE_MAX_RATIO_DT=0.25 # 전체 데이트레이딩 최대 25%
DAY_TRADE_PER_STOCK_RATIO=0.10 # 종목당 최대 10%
DAY_TRADE_MAX_CAPITAL_RATIO=0.10 # 종목당 최대 10%
# 데이트레이딩 손절/익절
DAY_TRADE_ORB_STOP_LOSS_PCT=0.02 # ORB 손절 -2%
DAY_TRADE_REVERSION_STOP_LOSS_PCT=0.025 # VWAP/RSI_BB 손절 -2.5%
DAY_TRADE_TRAILING_TRIGGER=0.015 # 트레일링 발동 +1.5%
DAY_TRADE_TRAILING_ATR_MULT=1.0 # 트레일링 ATR 배수
DAY_TRADE_ORB_BREAKOUT_MARGIN=0.002 # ORB 돌파 최소 여유 +0.2%
DAY_TRADE_COST_PCT=0.005 # 수수료+슬리피지 0.5%
# 데이트레이딩 일일/시간 제한
DAY_TRADE_DAILY_LOSS_LIMIT=-0.03 # 일일 손실 한도 -3%
DAY_TRADE_ENTRY_CUTOFF_HOUR=15 # 신규 진입 마감 시간 (15시)
DAY_TRADE_ENTRY_CUTOFF_MIN=0 # 신규 진입 마감 분
DAY_TRADE_EOD_HOUR=15 # EOD 강제 청산 시작 시간
DAY_TRADE_EOD_MIN=20 # EOD 강제 청산 시작 분
DAY_TRADE_RSI_BREAKEVEN_THRESHOLD=40.0 # RSI_BB 진입 기준 (5분봉 RSI ≤ 40)
# ═══════════════════════════════════════════════════════════════════════════════
# 단기 전략 (15분봉, 섹션 8.2)
# ═══════════════════════════════════════════════════════════════════════════════
SHORT_TERM_MIN_ATR_RATIO=0.008 # ATR/close ≥ 0.8% (거래비용 커버)
SHORT_TERM_RSI_LOOKBACK=3 # RSI 반등 확인 과거 봉 수
SHORT_TERM_VOLUME_MULTIPLIER=1.5 # 거래량 필터 배수 (1.5배)
# ═══════════════════════════════════════════════════════════════════════════════
# 감시 목록 관리 (watchlist.py)
# ═══════════════════════════════════════════════════════════════════════════════
WATCHLIST_INIT_SIZE=150 # 아침 배치 초기화 종목 수
WATCHLIST_MAX_SIZE=150 # 최대 관리 종목 수
WATCHLIST_ENTRY_SCORE=60 # 장중 신규 진입 기준 점수
WATCHLIST_EXIT_SCORE=20 # 장중 제거 기준 점수
# ═══════════════════════════════════════════════════════════════════════════════
# 기술적 지표 설정 (technical_indicators.py)
# ═══════════════════════════════════════════════════════════════════════════════
# RSI (Relative Strength Index)
RSI_PERIOD=14 # RSI 계산 기간 (14일)
RSI_OVERSOLD_LEVEL=30.0 # RSI 과매도 수준
RSI_OVERBOUGHT_LEVEL=70.0 # RSI 과매수 수준
RSI_RECOVERY_RANGE_MIN=30.0 # RSI 회복 범위 최소값 (30~45)
RSI_RECOVERY_RANGE_MAX=45.0 # RSI 회복 범위 최대값
RSI_STABLE_RANGE_MIN=45.0 # RSI 안정 범위 최소값 (45~60)
RSI_STABLE_RANGE_MAX=60.0 # RSI 안정 범위 최대값
# 볼린저 밴드
BOLLINGER_PERIOD=20 # 볼린저 밴드 기간 (20일)
BOLLINGER_STDDEV=2.0 # 표준편차 배수
# 이동평균 (Moving Average)
MA_SHORT_PERIOD=5 # 단기 MA (5일)
MA_MEDIUM_PERIOD=20 # 중기 MA (20일)
MA_LONG_PERIOD=60 # 장기 MA (60일)
# ATR (Average True Range)
ATR_PERIOD=14 # ATR 계산 기간 (14일)
# ═══════════════════════════════════════════════════════════════════════════════
# API 레이트 제한 및 안전 운영
# ═══════════════════════════════════════════════════════════════════════════════
API_MAX_RETRIES=3 # 최대 재시도 횟수
API_RETRY_DELAY=1.5 # 초기 재시도 대기 시간 (초)
API_RETRY_BACKOFF=2.0 # 지수 백오프 배율
API_MIN_REQUEST_INTERVAL=0.5 # 최소 요청 간격 (초)
API_MAX_CONCURRENT_REQUESTS=4 # 동시 최대 요청 수
API_TIMEOUT=30.0 # API 타임아웃 (초)
# API 모니터링
API_ERROR_THRESHOLD=0.3 # 오류율 임계값 (30%)
API_MONITORING_WINDOW=100 # 모니터링 윈도우 (최근 100개 요청)
# ═══════════════════════════════════════════════════════════════════════════════
# ML (머신러닝) 설정
# ═══════════════════════════════════════════════════════════════════════════════
ML_TF_ENABLED=true # ML 모델 기반 보조지표 사용
ML_ENSEMBLE_ENABLED=true # ML 앙상블 활성화
ML_ENSEMBLE_MODEL_DIR=models/ensemble
ML_ENSEMBLE_RULE_WEIGHT=0.3 # 룰베이스 스코어 비중 (30%)
ML_ENSEMBLE_ML_WEIGHT=0.7 # ML 스코어 비중 (70%)
ML_ENSEMBLE_BUY_THRESHOLD=60 # 매수 최소 앙상블 스코어 (0~100)
ML_ENSEMBLE_CONFIDENCE_MIN=0.5 # 최소 신뢰도
# ═══════════════════════════════════════════════════════════════════════════════
# 프론트엔드 (선택사항)
# ═══════════════════════════════════════════════════════════════════════════════
VITE_API_URL=http://localhost:8000
VITE_WS_URL=ws://localhost:8000/ws
# ═══════════════════════════════════════════════════════════════════════════════
# 기타 설정
# ═══════════════════════════════════════════════════════════════════════════════
TOKEN_SAVE_MODE=true # JSON 압축, 차트 데이터 30일 제한
NEWS_API_KEY=your_news_api_key