Faza 3 — dnevni catchup i symbol churn

2026-05-20 infra

Novi scheduler kontejner, catchup u 05:00 UTC i churn ponedeljkom. Dva buga uhvaćena u validaciji: BTC parovi lažno delisted i provider koji je pisao otvorene sveće.

↑ Svi izveštaji ← Faza 2 — KlinesProvider Faza 4 — precompute feature-a →

Status: deploy gotov, oba job-a verifikovana

Klines cache sad ima automatsko održavanje. Dva nova cron job-a u scheduler-u:

Šta je deploy-ovano

1. src/klines_cache_maintenance.py (novi modul, ~250 lines)

Dva entry-point-a:

Karakteristike:

2. src/scheduler.py izmene

Dodato:

Schedule setup: Scan every 5 minutes, Monitor every 10 minutes, Generator live every 10s,
                Klines catchup daily at 05:00 UTC, Symbol churn weekly Mon at 06:00 UTC

3. src/config.py — 2 nova ENV podržana

4. src/web_app.py — nova 2 admin endpoint-a

5. docker-compose.yml — novi scheduler service

scheduler:
  build:
    context: .
    network: host
  restart: always
  command: python scheduler_service.py
  environment:
    - DATABASE_URL=postgresql://...
    - REDIS_URL=redis://redis:6379/0
    - ENABLE_SCHEDULER=true
  env_file:
    - .env
  volumes:
    - ./reports:/app/reports
    - ./database:/app/database
  depends_on:
    - db
    - redis

Razlog: web container koristi gunicorn app:app koji ne pokreće scheduler.start_scheduler(). Bez separate scheduler containera, nijedan cron job nije aktivan.

Backup originalnog compose-a: docker-compose.yml.bak.2026-05-20-v2

Bug otkriveni tokom validacije

Bug 1: BTC pairs lažno označeni kao delisted

Originalni _async_get_eligible vraćao samo USDT verzije. Pošto cache sadrži oba (generator računa btc_growth_pct), 71 BTC pair je lažno označen kao delisted. Fix: eligible sad vraća OBA {base}USDT i {base}BTC.

Posle fix-a: 139 cached, 136 eligible, 3 stvarno delisted (BTCUSDT [koji nema BTCBTC pair], ENAUSDT i ENABTC).

Bug 2: KlinesProvider._write_cache je pisao open candles

Otkriveno: clean_stale_open_candles.py --dry-run našao 275 stale rows posle Faze 2 equivalence test-a. Source: KlinesProvider._write_cache nije imao open-candle skip. Fix: dodat if close_ms > now_ms: continue. Posle deploy-a + restart-a web/celery containera (gunicorn worker re-import), 0 stale rows.

Validacija

Smoke test (manual trigger)

Daily catchup (1d only): elapsed=32.8s, symbols=139, 69 fetched (open candles, skipped on insert)
Symbol churn: cached=139, eligible=136, new=0, delisted=3 (BTCUSDT, ENABTC, ENAUSDT)
Stale rows after run: 0

Schedule registered

Iz scheduler container log-a:

2026-05-20 16:38:27 [INFO] src.scheduler: Schedule setup: ..., Klines catchup daily at 05:00 UTC, Symbol churn weekly Mon at 06:00 UTC
2026-05-20 16:38:27 [INFO] src.scheduler: Scheduler started
2026-05-20 16:38:27 [INFO] __main__: Scheduler service running

Operativni značaj

Pre Faze 3

Posle Faze 3

Pre-flight provere (sve ✅)

Sledeći koraci (Faza 4 i 5)

Provenance

Izvor: crypto_scanner/reports/analysis/2026-05-20_faza3_cron_maintenance.md