feat: add market regime filter and compound reinvestment
- Add market_regime.py: BTC/ETH/SOL/XRP weighted 2h trend score Bull(≥+1.5%) / Neutral / Bear(<-1%) regime detection with 10min cache - strategy.py: dynamic TREND/VOL thresholds based on current regime Bull: 3%/1.5x, Neutral: 5%/2.0x, Bear: 8%/3.5x - price_collector.py: always include leader coins in price history - trader.py: compound reinvestment (profit added to budget, floor at initial) - notify.py: regime info in hourly report, P&L icons (✅/❌, 💚/🔴) - main.py: hourly status at top-of-hour, filter positions held 1h+ - backtest.py: timestop/combo comparison modes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
29
main.py
29
main.py
@@ -20,23 +20,32 @@ logging.basicConfig(
|
||||
from core.monitor import run_monitor
|
||||
from core.notify import notify_error, notify_status
|
||||
from core.price_collector import backfill_prices, run_collector
|
||||
from core.trader import get_positions, restore_positions
|
||||
from core.price_db import get_cumulative_krw_profit
|
||||
from core.trader import get_positions, get_budget_info, restore_positions
|
||||
from daemon.runner import run_scanner
|
||||
|
||||
STATUS_INTERVAL = 3600 # 1시간마다 요약 전송
|
||||
|
||||
|
||||
def run_status_reporter(interval: int = STATUS_INTERVAL) -> None:
|
||||
"""주기적으로 포지션 현황을 Telegram으로 전송."""
|
||||
def run_status_reporter() -> None:
|
||||
"""매 정각마다 1시간 이상 보유 포지션 현황 전송."""
|
||||
import datetime as _dt
|
||||
logger = logging.getLogger("status")
|
||||
logger.info(f"상태 리포터 시작 (주기={interval//60}분)")
|
||||
time.sleep(interval) # 첫 전송은 1시간 후
|
||||
logger.info("상태 리포터 시작 (매 정각 트리거)")
|
||||
while True:
|
||||
now = _dt.datetime.now()
|
||||
# 다음 정각까지 대기
|
||||
secs_to_next_hour = (60 - now.minute) * 60 - now.second
|
||||
time.sleep(secs_to_next_hour)
|
||||
try:
|
||||
notify_status(dict(get_positions()))
|
||||
budget = get_budget_info()
|
||||
cum = get_cumulative_krw_profit()
|
||||
notify_status(
|
||||
dict(get_positions()),
|
||||
max_budget=budget["max_budget"],
|
||||
per_position=budget["per_position"],
|
||||
cum_profit=cum,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"상태 리포트 오류: {e}")
|
||||
time.sleep(interval)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
@@ -55,7 +64,7 @@ def main() -> None:
|
||||
)
|
||||
monitor_thread.start()
|
||||
|
||||
# 1시간 주기 상태 리포트 스레드
|
||||
# 매 정각 상태 리포트 스레드 (1시간 이상 보유 포지션만)
|
||||
status_thread = threading.Thread(
|
||||
target=run_status_reporter, daemon=True, name="status"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user