수정사항
This commit is contained in:
@@ -381,6 +381,46 @@ def calculate_position_size(
|
||||
return result
|
||||
|
||||
|
||||
def calculate_position_size_v2(
|
||||
total_assets: float,
|
||||
available_cash: float,
|
||||
current_strategy_allocation: float,
|
||||
regime: MarketRegime,
|
||||
rsi: Optional[float] = None,
|
||||
adx: Optional[float] = None,
|
||||
max_per_position: float = 0.04,
|
||||
max_strategy_capital_bull: float = 0.70,
|
||||
max_strategy_capital_bear: float = 0.30,
|
||||
) -> float:
|
||||
"""CLAUDE.md 섹션 6.1 + RSI/ADX 동적 포지션 사이징
|
||||
|
||||
calculate_position_size 기반으로 RSI·ADX 보정 추가:
|
||||
- RSI ≤ 20: ×1.2 (깊은 과매도 = 더 유리한 진입)
|
||||
- RSI ≤ 25: ×1.1
|
||||
- ADX > 30: ×0.8 (강추세 중 평균회귀 위험 = 포지션 축소)
|
||||
보정 후에도 종목당 4% 상한 재적용 (CLAUDE.md 절대 룰)
|
||||
"""
|
||||
base = calculate_position_size(
|
||||
total_assets, available_cash, current_strategy_allocation,
|
||||
regime, max_per_position, max_strategy_capital_bull, max_strategy_capital_bear,
|
||||
)
|
||||
if base <= 0:
|
||||
return 0.0
|
||||
|
||||
mult = 1.0
|
||||
if rsi is not None:
|
||||
if rsi <= 20:
|
||||
mult *= 1.2
|
||||
elif rsi <= 25:
|
||||
mult *= 1.1
|
||||
|
||||
if adx is not None and adx > 30:
|
||||
mult *= 0.8
|
||||
|
||||
max_allowed = total_assets * max_per_position
|
||||
return min(base * mult, max_allowed, available_cash)
|
||||
|
||||
|
||||
def check_h1_breakout_with_ma5(
|
||||
h1_closes: List[float],
|
||||
h1_current_close: float,
|
||||
|
||||
@@ -73,6 +73,7 @@ async def initialize_watchlist(
|
||||
top_codes = {row.stock_code for row in top_stocks}
|
||||
|
||||
added = 0
|
||||
scanner_added = 0
|
||||
added_codes: set[str] = set()
|
||||
scanner_slots = SCANNER_PRIORITY_SLOTS
|
||||
|
||||
@@ -90,6 +91,7 @@ async def initialize_watchlist(
|
||||
added_codes.add(row.stock_code)
|
||||
scanner_slots -= 1
|
||||
added += 1
|
||||
scanner_added += 1
|
||||
|
||||
# --- 2순위: 스캐너에만 있고 score 랭킹에는 없는 종목 (최대 scanner_slots개) ---
|
||||
extra = list(scanner_tickers - top_codes)
|
||||
@@ -113,6 +115,7 @@ async def initialize_watchlist(
|
||||
))
|
||||
added_codes.add(row.stock_code)
|
||||
added += 1
|
||||
scanner_added += 1
|
||||
|
||||
# --- 3순위: 나머지 슬롯 — score 상위 순 ---
|
||||
remaining = WATCHLIST_INIT_SIZE - added
|
||||
@@ -132,12 +135,11 @@ async def initialize_watchlist(
|
||||
|
||||
await session.commit()
|
||||
|
||||
scanner_added = added - remaining if remaining >= 0 else added
|
||||
logger.info(
|
||||
"📋 워치리스트 초기화: %d개 (scanner_signal=%d, morning_batch=%d, 기준일: %s)",
|
||||
added,
|
||||
len([c for c in added_codes]), # 로깅용 (simplified)
|
||||
remaining if remaining >= 0 else 0,
|
||||
scanner_added,
|
||||
added - scanner_added,
|
||||
analysis_date,
|
||||
)
|
||||
return added
|
||||
|
||||
Reference in New Issue
Block a user