138 lines
6.9 KiB
Python
138 lines
6.9 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
단타 봇용 환경변수 DB 업데이트 스크립트
|
||
- .env 파일의 단타 설정값을 DB에 저장
|
||
"""
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
SCRIPT_DIR = Path(__file__).resolve().parent
|
||
sys.path.insert(0, str(SCRIPT_DIR))
|
||
|
||
from database import TradeDB
|
||
|
||
def update_short_bot_env():
|
||
"""단타 봇 환경변수 업데이트"""
|
||
db_path = SCRIPT_DIR / "quant_bot.db"
|
||
db = TradeDB(db_path=str(db_path))
|
||
|
||
# 기존 최신 설정 불러오기
|
||
latest = db.get_latest_env()
|
||
if latest and latest.get("snapshot"):
|
||
current = latest["snapshot"]
|
||
print(f"📋 기존 설정 불러옴 (ID: {latest['id']})")
|
||
else:
|
||
current = {}
|
||
print("⚠️ 기존 설정 없음 - 새로 생성")
|
||
|
||
# 단타 봇 설정값 (.env 23-140줄 기준)
|
||
short_bot_updates = {
|
||
# ========== 기본 거래 설정 ==========
|
||
"MAX_STOCKS": "7", # 최대 보유 종목 수
|
||
"STOP_LOSS_PCT": "-0.18", # 종목별 손절 기준 (-18%)
|
||
"USE_SLOT_CAP": "true", # 종목당 금액 상한(슬롯) 적용
|
||
"SLOT_CAP_PCT": "0.9", # 슬롯 계산 시 예수금 반영 비율 (90%)
|
||
|
||
# ========== 리스크 관리 (손실 한도) ==========
|
||
"USE_RISK_CHECK": "false", # 일일 손실 한도 체크
|
||
"DAILY_STOP_LOSS_PCT": "-0.05", # 일일 손실 한도 (-5%)
|
||
"CONSECUTIVE_LOSS_LIMIT": "7", # 연속 손절 한도 (7회)
|
||
|
||
# ========== 금지 종목 관리 (재매수 방지) ==========
|
||
"USE_BAN_SYSTEM": "true", # 금지 종목 관리 시스템
|
||
"BAN_HOURS": "24", # 금지 시간 (24시간)
|
||
|
||
# ========== 종목 필터링 (쓰레기 종목 제외) ==========
|
||
"USE_STOCK_FILTER": "true", # 종목 필터링
|
||
|
||
# ========== 작은 수익 보호 (30분 내) ==========
|
||
"USE_QUICK_PROFIT_PROTECTION": "true", # 작은 수익 보호
|
||
|
||
# ========== 리스크 관리 (Ver2 신규) ==========
|
||
"RISK_PCT_PER_TRADE": "0.015", # 1회 거래 시 허용 손실 비율 (1.5%)
|
||
"MAX_POSITION_PCT": "0.20", # 종목당 최대 투자 비중 (20%)
|
||
"MIN_POSITION_AMOUNT": "20000", # 최소 매수 금액 (2만원)
|
||
|
||
# ========== 켈리 공식 (Ver2 신규) ==========
|
||
"USE_KELLY": "false", # 하프 켈리 공식 활성화
|
||
|
||
# ========== ML 승률 예측 (Ver2 신규 - 실험적!) ==========
|
||
"USE_ML_SIGNAL": "false", # ML 기반 매수 신호 필터링
|
||
"ML_MIN_PROBABILITY": "0.57", # ML 승률 임계값 (57%)
|
||
|
||
# ========== 뉴스 AI 분석 (Ver2 신규 - 참고용!) ==========
|
||
"USE_NEWS_ANALYSIS": "false", # 뉴스 AI 분석 활성화
|
||
"NEWS_ANALYSIS_HOUR": "9", # 뉴스 분석 시간 (9시)
|
||
"NEWS_MAX_COUNT": "5", # 크롤링할 뉴스 개수 (5개)
|
||
|
||
# ========== 랜덤 분할 매수 (Dual 방식 - 승률 최적화!) ==========
|
||
"USE_RANDOM_SPLIT": "true", # 랜덤 분할 매수 활성화
|
||
|
||
# ========== TWAP 분할 매수 (Ver2 신규) ==========
|
||
"USE_TWAP": "false", # TWAP 분할 매수 활성화
|
||
"TWAP_MIN_SPLIT": "500000", # 1회 최소 주문 금액 (50만원)
|
||
"TWAP_MAX_SPLIT": "2000000", # 1회 최대 주문 금액 (200만원)
|
||
"TWAP_MIN_DELAY": "30", # 분할 매수 간 최소 딜레이 (초)
|
||
"TWAP_MAX_DELAY": "180", # 분할 매수 간 최대 딜레이 (초)
|
||
|
||
# ========== 디버그용 장 상태 강제 오픈 ==========
|
||
"FORCE_MARKET_OPEN": "true", # 장 상태에 관계없이 항상 매매 로직 실행 (테스트용!)
|
||
|
||
# ========== 매수 전략 파라미터 ==========
|
||
"RSI_OVERHEAT_THRESHOLD": "78", # RSI 과열 기준 (진입 보류 기준)
|
||
"SHOULDER_CUT_PCT": "0.03", # 어깨 매도 기준 (고점 대비 하락률)
|
||
|
||
# ========== 🚨 피뢰침 방지 필터 (강화!) ==========
|
||
"HIGH_PRICE_CHASE_THRESHOLD": "0.96", # 일일 최고가 추격 매수 방지 기준
|
||
"MAX_DAILY_CHANGE_PCT": "18.0", # 당일 최대 변동폭 (%)
|
||
"MA20_MAX_ABOVE_PCT": "8.8", # 20선 과열 방지: MA20 대비 이 % 초과 위면 매수 스킵
|
||
|
||
"MIN_RECOVERY_RATIO": "0.32", # 꼬리 잡기 최소 회복 비율
|
||
"MAX_RECOVERY_RATIO": "1.15", # 꼬리 잡기 최대 회복 비율
|
||
"CANDLE_OPEN_PRICE_BUFFER": "0.98", # 시가 대비 현재가 버퍼 (음봉 꼬리 위험 방지)
|
||
"VOLUME_AVG_MULTIPLIER": "0.50", # 거래량 평균 대비 배율
|
||
|
||
"INTRADAY_INVESTOR_NET_BUY_THRESHOLD": "-1000", # 장중 투자자 순매수 기준
|
||
|
||
# ========== ATR 배율 설정 ==========
|
||
"STOP_ATR_MULTIPLIER_TAIL": "2.5", # TAIL_CATCH_3M 전략 손절가 (ATR × 2.5)
|
||
"TARGET_ATR_MULTIPLIER_TAIL": "8.0", # TAIL_CATCH_3M 전략 목표가 (ATR × 8.0)
|
||
|
||
# 단타 봇 전용 설정 (기존 값 유지 또는 기본값)
|
||
"TAKE_PROFIT_PCT": current.get("TAKE_PROFIT_PCT", "0.05"), # 익절 기준 (5%)
|
||
"MIN_DROP_RATE": current.get("MIN_DROP_RATE", "0.03"), # 최소 낙폭 (3%)
|
||
"MIN_RECOVERY_RATIO_SHORT": current.get("MIN_RECOVERY_RATIO_SHORT", "0.5"), # 최소 회복 비율 (50%)
|
||
}
|
||
|
||
# 기존 값과 병합 (단타 봇 설정으로 덮어쓰기)
|
||
new_snapshot = {**current, **short_bot_updates}
|
||
|
||
# 새 스냅샷 저장
|
||
env_id = db.insert_env_snapshot(new_snapshot)
|
||
if env_id:
|
||
print(f"✅ 단타 봇 환경변수 저장 완료! (새 스냅샷 ID: {env_id})")
|
||
print()
|
||
print("📋 저장된 주요 설정:")
|
||
print(f" - MAX_STOCKS: {short_bot_updates['MAX_STOCKS']}")
|
||
print(f" - STOP_LOSS_PCT: {short_bot_updates['STOP_LOSS_PCT']}")
|
||
print(f" - USE_RANDOM_SPLIT: {short_bot_updates['USE_RANDOM_SPLIT']}")
|
||
print(f" - RSI_OVERHEAT_THRESHOLD: {short_bot_updates['RSI_OVERHEAT_THRESHOLD']}")
|
||
print(f" - FORCE_MARKET_OPEN: {short_bot_updates['FORCE_MARKET_OPEN']} (테스트용!)")
|
||
print()
|
||
print("💡 팁:")
|
||
print(" - 봇을 재시작하면 새 설정이 적용됩니다.")
|
||
print(" - FORCE_MARKET_OPEN=true는 테스트용이므로 실전에서는 false로 변경하세요.")
|
||
else:
|
||
print("❌ 저장 실패!")
|
||
|
||
db.close()
|
||
return env_id
|
||
|
||
if __name__ == "__main__":
|
||
try:
|
||
update_short_bot_env()
|
||
except Exception as e:
|
||
print(f"\n\n❌ 에러: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|