- deep_learning.py: INPUT_SIZE=7 (close/open/high/low/volume/rsi/macd), feature_scaler/target_scaler 분리, ModelRegistry LRU 종목별 격리 (v3 체크포인트) - kis.py: get_daily_ohlcv() OHLCV 전체 반환, KISAsyncClient 비동기 배치 조회 추가, order() 지정가/조건부 주문 지원 - strategy/process.py: ATR/ADX 기반 동적 손절익절, 트레일링 스탑, 포지션 사이징 강화 - config.py: OLLAMA_NUM_THREAD=8 (9800X3D 최적화), LSTM_COOLDOWN/FAST_EPOCHS 환경변수화 - macro.py: 거시경제 지표 계산 개선 - ollama.py: VRAM 여유량 기반 선택적 언로드 - monitor.py: CPU 서킷 브레이커 연속 횟수 조건 추가 - ipc.py: IPC_STALENESS 600초로 확대 - news.py: 비동기 뉴스 수집 개선 - telegram.py, runner.py: 안정성 개선 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
91 lines
2.9 KiB
Python
91 lines
2.9 KiB
Python
"""
|
|
멀티프로세스 방식 - 텔레그램 봇 프로세스
|
|
트레이딩 봇과 완전히 분리된 독립 프로세스로 실행
|
|
"""
|
|
import os
|
|
import sys
|
|
import time
|
|
import multiprocessing
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
|
|
def run_telegram_bot_standalone(ipc_lock=None, command_queue=None, shutdown_event=None):
|
|
"""텔레그램 봇만 독립적으로 실행"""
|
|
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../')))
|
|
|
|
from modules.services.telegram_bot.server import TelegramBotServer
|
|
from modules.utils.ipc import SharedIPC
|
|
from modules.utils.process_tracker import ProcessTracker
|
|
|
|
token = os.getenv("TELEGRAM_BOT_TOKEN")
|
|
if not token:
|
|
print("[Telegram] TELEGRAM_BOT_TOKEN not found in .env")
|
|
sys.exit(1)
|
|
|
|
ProcessTracker.register("Telegram Bot Standalone")
|
|
print(f"[Telegram Bot Process] Starting... (PID: {os.getpid()})")
|
|
|
|
# IPC 초기화 (shared memory + command queue)
|
|
ipc = SharedIPC(lock=ipc_lock, command_queue=command_queue)
|
|
|
|
conflict_retries = 0
|
|
MAX_CONFLICT_RETRIES = 10
|
|
|
|
while True:
|
|
# shutdown 체크
|
|
if shutdown_event and shutdown_event.is_set():
|
|
print("[Telegram Bot] Shutdown signal received.")
|
|
break
|
|
|
|
try:
|
|
bot_server = TelegramBotServer(token, ipc=ipc, shutdown_event=shutdown_event)
|
|
|
|
# 초기 데이터 로드
|
|
try:
|
|
instance_data = ipc.get_bot_instance_data()
|
|
if instance_data:
|
|
bot_server.set_bot_instance(instance_data)
|
|
except Exception:
|
|
pass
|
|
|
|
bot_server.run()
|
|
|
|
if bot_server.should_restart:
|
|
print("[Telegram Bot] Restarting instance...")
|
|
conflict_retries = 0 # 정상 재시작 시 카운터 리셋
|
|
time.sleep(1)
|
|
continue
|
|
else:
|
|
print("[Telegram Bot] Process exiting.")
|
|
break
|
|
|
|
except KeyboardInterrupt:
|
|
print("[Telegram Bot] Stopped by user")
|
|
break
|
|
except Exception as e:
|
|
if "Conflict" in str(e):
|
|
conflict_retries += 1
|
|
if conflict_retries >= MAX_CONFLICT_RETRIES:
|
|
print(f"[Telegram Bot] Conflict max retries ({MAX_CONFLICT_RETRIES}) reached. Exiting.")
|
|
break
|
|
wait_secs = min(5 * conflict_retries, 30)
|
|
print(f"[Telegram Bot] Conflict detected. Waiting {wait_secs}s before retry "
|
|
f"({conflict_retries}/{MAX_CONFLICT_RETRIES})...")
|
|
time.sleep(wait_secs)
|
|
continue
|
|
else:
|
|
print(f"[Telegram Bot] Error: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
break
|
|
|
|
# 정리
|
|
ipc.cleanup()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
multiprocessing.freeze_support()
|
|
run_telegram_bot_standalone()
|