refactor: web-ai V1 assets → signal_v1/ (graduation prep)
Atomic mv of root V1 assets (main_server.py + modules/ + data/ + tests/ + entry scripts + docs + logs) into signal_v1/ subdirectory. load_dotenv() updated to load web-ai/.env explicitly via Path. Adds web-ai/CLAUDE.md (workspace guide) and web-ai/start.bat (signal_v1 entry wrapper). Prepares for signal_v2/ Phase 2. Tests: signal_v1/tests/unit baseline preserved (no regression). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
139
signal_v1/warmup_and_restart.py
Normal file
139
signal_v1/warmup_and_restart.py
Normal file
@@ -0,0 +1,139 @@
|
||||
"""
|
||||
LSTM 사전학습 + 봇 자동 시작 통합 스크립트
|
||||
- 구 봇 종료 후 이 스크립트가 백그라운드로 실행됨
|
||||
- 12개 종목 LSTM 사전학습 → 완료 시 main_server.py 자동 시작
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
import json
|
||||
|
||||
# 프로젝트 루트를 path에 추가
|
||||
ROOT = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, ROOT)
|
||||
os.chdir(ROOT)
|
||||
|
||||
LOG_FILE = os.path.join(ROOT, "warmup.log")
|
||||
|
||||
def log(msg):
|
||||
ts = time.strftime("%H:%M:%S")
|
||||
line = f"[{ts}] {msg}"
|
||||
print(line, flush=True)
|
||||
with open(LOG_FILE, "a", encoding="utf-8") as f:
|
||||
f.write(line + "\n")
|
||||
|
||||
|
||||
def run_warmup():
|
||||
log("=" * 50)
|
||||
log("LSTM 사전학습 시작 (Warmup)")
|
||||
log("=" * 50)
|
||||
|
||||
try:
|
||||
from modules.config import Config
|
||||
from modules.services.kis import KISClient
|
||||
from modules.analysis.deep_learning import PricePredictor
|
||||
from modules.services.telegram import TelegramMessenger
|
||||
|
||||
messenger = TelegramMessenger()
|
||||
messenger.send_message(
|
||||
"🔄 <b>[Bot Restarting]</b>\n"
|
||||
"LSTM 사전학습 중... 완료 후 자동 시작됩니다.\n"
|
||||
f"대상: Watchlist 전체 종목"
|
||||
)
|
||||
|
||||
kis = KISClient()
|
||||
with open(Config.WATCHLIST_FILE, "r", encoding="utf-8") as f:
|
||||
watchlist = json.load(f)
|
||||
|
||||
log(f"대상 종목: {len(watchlist)}개")
|
||||
|
||||
predictor = PricePredictor()
|
||||
total = len(watchlist)
|
||||
success = 0
|
||||
failed = 0
|
||||
total_time = 0.0
|
||||
|
||||
for i, (ticker, name) in enumerate(watchlist.items(), 1):
|
||||
log(f"[{i}/{total}] {name} ({ticker}) 학습 중...")
|
||||
try:
|
||||
# 100일 데이터로 LSTM 학습 (기간별시세 API)
|
||||
prices = kis.get_daily_price(ticker, count=100)
|
||||
if not prices or len(prices) < 70:
|
||||
log(f" ⚠️ 데이터 부족 ({len(prices) if prices else 0}개)")
|
||||
failed += 1
|
||||
continue
|
||||
|
||||
t0 = time.time()
|
||||
result = predictor.train_and_predict(prices, ticker=ticker)
|
||||
elapsed = time.time() - t0
|
||||
total_time += elapsed
|
||||
|
||||
if result:
|
||||
log(f" ✅ {result['epochs']}에포크 | loss={result['loss']:.6f} | "
|
||||
f"{result['change_rate']:+.2f}% | {elapsed:.1f}초")
|
||||
success += 1
|
||||
else:
|
||||
log(f" ⚠️ 결과 없음 ({elapsed:.1f}초)")
|
||||
failed += 1
|
||||
|
||||
# KIS API 과호출 방지
|
||||
time.sleep(0.5)
|
||||
|
||||
except Exception as e:
|
||||
log(f" ❌ 오류: {e}")
|
||||
failed += 1
|
||||
|
||||
log("=" * 50)
|
||||
log(f"Warmup 완료: 성공 {success}개 / 실패 {failed}개 / 총 {total_time:.0f}초")
|
||||
log("=" * 50)
|
||||
|
||||
messenger.send_message(
|
||||
f"✅ <b>[Warmup 완료]</b>\n"
|
||||
f"성공: {success}종목 / 실패: {failed}종목\n"
|
||||
f"소요: {total_time/60:.1f}분\n"
|
||||
f"→ 봇 시작 중..."
|
||||
)
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
log(f"❌ Warmup 실패: {e}")
|
||||
import traceback
|
||||
log(traceback.format_exc())
|
||||
return False
|
||||
|
||||
|
||||
def start_bot():
|
||||
log("봇 시작: main_server.py")
|
||||
try:
|
||||
# 새 콘솔 창에서 봇 실행 (Windows)
|
||||
if sys.platform == "win32":
|
||||
subprocess.Popen(
|
||||
[sys.executable, "main_server.py"],
|
||||
creationflags=subprocess.CREATE_NEW_CONSOLE,
|
||||
cwd=ROOT
|
||||
)
|
||||
else:
|
||||
subprocess.Popen(
|
||||
[sys.executable, "main_server.py"],
|
||||
cwd=ROOT
|
||||
)
|
||||
log("✅ 봇 프로세스 시작 완료")
|
||||
return True
|
||||
except Exception as e:
|
||||
log(f"❌ 봇 시작 실패: {e}")
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# warmup.log 초기화
|
||||
with open(LOG_FILE, "w", encoding="utf-8") as f:
|
||||
f.write(f"Warmup 시작: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
|
||||
|
||||
warmup_ok = run_warmup()
|
||||
|
||||
if warmup_ok:
|
||||
time.sleep(2)
|
||||
start_bot()
|
||||
else:
|
||||
log("⚠️ Warmup 실패. 봇을 수동으로 시작해주세요: python main_server.py")
|
||||
Reference in New Issue
Block a user