gahusb c451f5313b fix(insta-render): BLMOVE dequeue가 짧은 socket_timeout으로 깨지던 문제 해결
REDIS_URL의 socket_timeout(<5s)이 ReliableQueue BLMOVE 5초 블록보다 짧아
idle dequeue마다 "Timeout reading"으로 잡을 못 꺼내 슬레이트가 draft에 정지(~2026-05-22~).
큐 연결을 socket_timeout=None + socket_keepalive로 생성(make_queue_redis)해 정상화.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 16:08:43 +09:00

web-ai

Windows AI 머신(AMD 9800X3D + RTX 5070 Ti 16GB)에서 동작하는 두 영역의 서비스:

  1. ai_trade — Confidence Signal Pipeline V2. NAS stock 백엔드와 KIS Open API를 결합해 매수/매도 신호를 생성하는 FastAPI 워커.
  2. services — NAS↔Windows 분산 렌더링 워커(인스타 카드 / 음악 / 영상 / 이미지) + task-watcher.

상위 워크스페이스 컨텍스트는 ../CLAUDE.md, 본 디렉토리 상세는 CLAUDE.md, 운영 체크포인트는 CHECK_POINT.md 참조.


디렉토리 구조

경로 역할 포트
ai_trade/ 자동매매 메인. Chronos-bolt(또는 Chronos-2) + 분봉 모멘텀 + KIS WebSocket 호가 + 매수/매도 신호 생성기. :8001
services/_shared/ 4개 render worker 공통 모듈 (ReliableQueue — BLMOVE + ack/fail + recovery).
services/insta-render/ Instagram 카드 Playwright 렌더 워커. NAS Redis queue:insta-render 소비. :18710
services/music-render/ Suno + MusicGen 음악 생성 워커. queue:music-render 소비. :18711
services/video-render/ sora / veo / kling / seedance 4 provider 영상 생성 게이트웨이. queue:video-render 소비. :18712
services/image-render/ gpt_image / nano_banana / flux(ComfyUI 로컬) 3 provider. queue:image-render 소비. :18714
services/task-watcher/ 박재오 작업 시간대에 queue:paused 토글 → 워커 일시 정지. :18713
legacy/signal_v1/ DEPRECATED (2026-05-19). LSTM 봇. 자동 실행 차단됨. OFF

ai_trade — Confidence Signal Pipeline V2

NAS stock 백엔드(:18500)에서 portfolio / news_sentiment / screener를 pull하고, KIS REST/WebSocket으로 분봉·호가를 보강한 뒤 Chronos 예측과 5분봉 모멘텀 분류로 매수/매도 신호를 생성한다.

매수 (screener Top-N + portfolio)

모두 충족 시 confidence 계산 → threshold 초과 시 emit:

  1. chronos.median > 0
  2. chronos.q90 - chronos.q10 < 0.6 (absolute spread)
  3. minute_momentum == strong_up
  4. asking_price.bid_ratio >= 0.6

종합 confidence = chronos_conf * 0.5 + minute_score * 0.3 + screener_norm * 0.2. > 0.7 시 emit.

매도 (portfolio only, 우선순위 stop_loss → anomaly → take_profit)

  • stop_loss: pnl_pct < -7% 즉시 (confidence=1.0)
  • anomaly: chronos.median < -1% + strong_down + bid_ratio < 0.4 + 종합 conf > 0.7
  • take_profit: pnl_pct > 15% 검토 (confidence=0.6)

핵심 파일

파일 책임
main.py FastAPI app + lifespan (의존성 wiring) + poll_loop task 생성
config.py Settings dataclass — 환경변수 로드
state.py PollState (process-wide singleton) — portfolio·screener·signals 등 + get_active_signals / purge_expired_signals
stock_client.py NAS stock 백엔드 pull (X-WebAI-Key + 메모리 캐시)
kis_client.py KIS REST 분봉/호가 + asyncio.Lock 직렬화 + 지수 backoff
kis_websocket.py KIS WebSocket 호가 + approval_key + 재연결
chronos_predictor.py HuggingFace Chronos zero-shot 분위수 예측 (FP32 강제)
minute_momentum.py 5분봉 → strong_up / weak_up / neutral / weak_down / strong_down
signal_generator.py 매수/매도 룰 엔진. cycle_id + expires_at 부착
pull_worker.py asyncio cron — 시간대별 분기 + post-close 트리거 + signal 생성 + expired purge
scheduler.py 폴링 윈도우 판정 (KST 캘린더 + 휴장일)
rate_limit.py 초당 N회 token bucket + SignalDedup SQLite WAL

시작

cd ai_trade
start.bat

Uvicorn running on http://0.0.0.0:8001, poll_loop started.

휴장일/장 외 시간엔 poll_loop만 idle.

헬스 / 로그

curl http://localhost:8001/health
Get-Content logs\ai_trade.log -Wait
nvidia-smi

services — NAS↔Windows 분산 워커

NAS측 lab 서비스(insta-lab / music-lab / video-lab / image-render NAS측)가 queue:<worker>-render 에 LPUSH로 작업을 enqueue. Windows worker가 BLMOVE로 atomic dequeue 후 처리, 완료 시 NAS internal webhook으로 결과 통지.

신뢰성 패턴 (_shared.ReliableQueue)

  • dequeue: BLMOVE main → processing:<queue>:<worker_id> (atomic).
  • ack: LREM processing 1 raw (성공).
  • fail: LREM processingattempts++ 후 main 재큐 또는 max_attempts 도달 시 dead_letter:<queue> 이동.
  • recover: startup 시 자신의 processing list orphan을 main queue로 (attempts 증가).

시작 (NAS, WSL2 Docker)

cd services
docker compose up -d insta-render music-render video-render image-render task-watcher

build context는 services/ 루트. 각 Dockerfile은 _shared 모듈을 함께 COPY하고 PYTHONPATH=/app.

운영 조작

# 워커 일시 정지 / 재개
redis-cli -h 192.168.45.54 SET queue:paused 1
redis-cli -h 192.168.45.54 DEL queue:paused

# 큐 / dead-letter 점검
redis-cli -h 192.168.45.54 LLEN queue:insta-render
redis-cli -h 192.168.45.54 LLEN dead_letter:queue:insta-render
redis-cli -h 192.168.45.54 KEYS 'processing:*'

환경 변수

변수 용도
REDIS_URL NAS Redis (redis://192.168.45.54:6379)
NAS_BASE_URL NAS 대상 서비스 URL (insta-lab :18700, music-lab :18600, video-lab :18801, image-render NAS측 :18802)
INTERNAL_API_KEY NAS internal webhook 인증
WORKER_ID (권장) <service>-prod-1 등 영속 ID. hostname 기반 default는 컨테이너 재기동 시 바뀌어 orphan 추적 불가
OPENAI_API_KEY / GEMINI_API_KEY / KLING_* / SEEDANCE_API_KEY / SUNO_API_KEY 각 provider 인증
COMFYUI_URL image-render FLUX 로컬 ComfyUI (http://host.docker.internal:8188)
FLUX_BLOCK_TRADING_HOURS 1 이면 장중(09:00~15:30) FLUX 차단 (Chronos GPU 보호)

환경 변수 (ai_trade)

변수 기본 설명
STOCK_API_URL (필수) NAS stock 백엔드 base URL
WEBAI_API_KEY (필수) stock 백엔드 호출 시 X-WebAI-Key
SIGNAL_V2_PORT 8001 uvicorn 포트
KIS_ENV_TYPE virtual virtual / real
KIS_REAL_APP_KEY / KIS_REAL_APP_SECRET / KIS_REAL_ACCOUNT KIS 실계좌
KIS_VIRTUAL_APP_KEY / KIS_VIRTUAL_APP_SECRET / KIS_VIRTUAL_ACCOUNT KIS 모의계좌
V1_TOKEN_PATH legacy/signal_v1/data/kis_token.json KIS 토큰 파일 (V1 토큰 read-only 공유)
CHRONOS_MODEL amazon/chronos-2 Chronos 모델 ID
STOP_LOSS_PCT -0.07 손절 임계
TAKE_PROFIT_PCT 0.15 익절 임계
CHRONOS_SPREAD_THRESHOLD 0.6 매수 hard gate spread 상한
ASKING_BID_RATIO_THRESHOLD 0.6 매수 hard gate 호가 비율
CONFIDENCE_THRESHOLD 0.7 매수 종합 confidence 하한
MIN_MOMENTUM_FOR_BUY strong_up 매수 hard gate 모멘텀 단계
SIGNAL_TTL_SECONDS 300 emit signal expires_at TTL

.env 는 web-ai 루트 (이 디렉토리)에 둔다. 절대 커밋 금지.


테스트

# ai_trade
python -m pytest ai_trade/tests -q

# services/_shared 공통 모듈
cd services/_shared && python -m pytest tests/ -q

# 각 worker
cd services/insta-render && python -m pytest tests/ -q
cd services/music-render && python -m pytest tests/ -q
cd services/video-render && python -m pytest tests/ -q
cd services/image-render && python -m pytest tests/ -q

.venv 한글 사용자 경로 깨짐으로 시스템 Python(C:\Users\jaeoh\AppData\Local\Programs\Python\Python312\python.exe) 사용 권장. 또는 py -3.12 -m pytest ….


알려진 함정

  1. KIS rate limit (EGW00201) — V1+V2 동시 실행 시 충돌. V1은 legacy/로 격리. ai_trade는 asyncio.Lock으로 throttle 직렬화 (kis_client.py).
  2. .venv 한글 경로 — 시스템 Python 사용.
  3. Chronos FP16 overflow — 한국 주가 5만원+ 시 inf. FP32 강제됨.
  4. post-close 트리거 — 상태기반(last_post_close_date)으로 변경됨. 16:00 이후 + 오늘 미실행이면 trigger.
  5. services worker_id — env로 명시 권장. hostname 기반 default는 컨테이너 재기동 시 바뀌어 orphan 분실 위험.
  6. dead-letter 누적redis-cli LLEN dead_letter:* 정기 점검 필요.
  7. Dockerfile build contextservices/ 루트 (각 worker 디렉토리 아님). compose 변경 동반.

Phase 진행 상태 (Confidence Signal Pipeline V2)

Phase 내용 상태
0 Architecture & contract spec
1 stock 백엔드 WebAI API 보강 (NAS)
1.5 V1 → signal_v1/ rename → legacy/ 격리
2 ai_trade pull worker + signal API client + scheduler
3a KIS REST 분봉 + WebSocket 호가 + NXT 스케줄
3b Chronos-bolt-base 추론 + 5분봉 모멘텀 분류기
4 Signal Generator + 로깅
4.5 코드 리뷰 F1-F6 hotfix (토큰 경로 / throttle Lock / post-close 상태기반 / Chronos abs / state.signals lifecycle / render queue 신뢰성)
5 agent-office /signal + Ollama Qwen3 14B + 이중 텔레그램
6 signal_v1 deprecation (legacy 완료, 아카이브만 남음) 일부
7 운영 모니터링 + 4주 IC 검증

상세 spec/plan은 ../web-ui/docs/superpowers/specs/ / ../web-ui/docs/superpowers/plans/ (별도 repo).


라이선스 / 사용

비공개. 박재오 개인 웹 플랫폼.

Description
No description provided
Readme 12 MiB
Languages
Python 95.6%
Jinja 4%
Dockerfile 0.4%