요약
항목 퀀트 관점 매도 로직 통합 매수 전략이 하나면 매도도 하나로 통합하는 게 맞고, 유지보수·일관성 측면에서 유리함. 동기화 타이밍 매수/매도와 같은 주기에서 “동기화 → 매도 → 매수” 순서로 묶어서 진행하는 게 좋음. 변동성 역가중 + 금액 균등화 역가중은 유지하고, 종목당 원화 상한(슬롯)을 추가해서 “비싼 것/싼 것 금액 비슷 → 손익률 비슷하면 원화 손익도 비슷”하게 가져가는 설계가 합리적임. 이 세 가지 모두 현재 코드 구조와 앞에서 말씀하신 요구(매도 통합, 동기화 동시성, 금액 균등화)와 잘 맞는 방향입니다. 하기 전
This commit is contained in:
@@ -1569,10 +1569,16 @@ class TradingBotV2:
|
||||
logger.info(f"🔍 [Pass-피뢰침] {name} {code}: 당일 변동폭 {daily_change_pct:.1f}% 과도 (최대 {max_daily_change}%)")
|
||||
return None
|
||||
|
||||
# [필터 3] 20일 이동평균선(MA20) 아래인지?
|
||||
# [필터 3] 20선 아래면 스킵 / 20선에서 너무 멀리 올라온 과열 구간도 스킵
|
||||
if current_price < ma20:
|
||||
logger.info(f"🔍 [Pass-MA20] {name} {code}: 현재가({current_price}) < MA20({ma20:.2f})")
|
||||
return None
|
||||
# 20선 초과 상한: MA20 대비 N% 이상 위면 고점 매수로 간주 → 스킵
|
||||
ma20_cap_pct = get_env_float("MA20_MAX_ABOVE_PCT", "3.0") # 기본 3% 초과 시 스킵
|
||||
if ma20 > 0 and current_price > ma20 * (1 + ma20_cap_pct / 100):
|
||||
gap_pct = (current_price - ma20) / ma20 * 100
|
||||
logger.info(f"🔍 [Pass-MA20과열] {name} {code}: 20선 대비 {gap_pct:.1f}% 위 (최대 {ma20_cap_pct}%)")
|
||||
return None
|
||||
|
||||
# [필터 4] 최소 거래량 필터 (평균의 30%도 안되면 패스)
|
||||
if current_vol < avg_vol * 0.3:
|
||||
@@ -2349,20 +2355,21 @@ class TradingBotV2:
|
||||
time.sleep(60)
|
||||
continue
|
||||
|
||||
# [유니버스 갱신] 5분 주기 (개미털기 스캔 + 계좌 동기화!)
|
||||
# 🔥 [계좌↔DB 동기화] 2분마다 (한온시스템 등 계좌에만 있는 종목 빠르게 반영!)
|
||||
if self.is_first_run or (current_minute % 2 == 0 and current_second < 5):
|
||||
self.sync_portfolio_from_api()
|
||||
if self.is_first_run:
|
||||
logger.info(f"🔄 [첫실행] 동기화 완료")
|
||||
|
||||
# [유니버스 갱신] 5분 주기 (개미털기 스캔)
|
||||
if self.is_first_run or (current_minute % 5 == 0 and current_second < 5):
|
||||
logger.info(f"🔄 [스캔 주기] 첫실행:{self.is_first_run} | 시각:{current_hour:02d}:{current_minute:02d}:{current_second:02d}")
|
||||
|
||||
# 🔥 실제 계좌 ↔ DB 동기화 (Dual처럼 5분마다!)
|
||||
self.sync_portfolio_from_api()
|
||||
|
||||
# 유니버스 갱신
|
||||
self.update_universe()
|
||||
|
||||
# 금지 종목 정리 (만료된 항목 제거)
|
||||
self.cleanup_banned_list()
|
||||
self.is_first_run = False
|
||||
logger.info("⏳ [주기] 유니버스 갱신 + 동기화 완료, 5초 대기")
|
||||
logger.info("⏳ [주기] 유니버스 갱신 완료, 5초 대기")
|
||||
time.sleep(5)
|
||||
|
||||
# 생존 신고 (1분마다)
|
||||
@@ -2372,15 +2379,18 @@ class TradingBotV2:
|
||||
logger.info(f"👀 [생존] 타겟:{len(targets)} | 보유:{active_count}/{self.max_stocks} | 예수금:{self.current_cash:,.0f}원")
|
||||
time.sleep(2)
|
||||
|
||||
# 2. 시간대별 리포트 (리포트 전 계좌 조회!)
|
||||
# 2. 시간대별 리포트 (리포트 전 계좌 조회 + 동기화!)
|
||||
if current_hour == 13 and current_minute == 0 and not self.morning_report_sent:
|
||||
self.refresh_account() # 최신 정보 조회
|
||||
self.refresh_account()
|
||||
self.sync_portfolio_from_api() # 리포트 전 DB 동기화
|
||||
self.send_morning_report()
|
||||
elif current_hour == 15 and current_minute == 15 and not self.closing_report_sent:
|
||||
self.refresh_account() # 최신 정보 조회
|
||||
self.refresh_account()
|
||||
self.sync_portfolio_from_api()
|
||||
self.send_closing_report()
|
||||
elif current_hour == 15 and current_minute >= 35 and not self.final_report_sent:
|
||||
self.refresh_account() # 최신 정보 조회
|
||||
self.refresh_account()
|
||||
self.sync_portfolio_from_api()
|
||||
self.send_final_report()
|
||||
|
||||
# 2-1. 뉴스 AI 분석 (하루 1회)
|
||||
|
||||
Reference in New Issue
Block a user