Arsitektur Sistem¶
Subsistem¶
Dua subsistem independen di src/, deploy sebagai container Docker terpisah, plus satu image Docker terpisah untuk dashboard:
| Subsistem | Path | Peran |
|---|---|---|
| Screener Pipeline | src/jobs/ |
Job terjadwal (scheduler.py, polling 30 detik) — tidak ada web server |
| Bot Interaktif | src/bot/ |
FastAPI webhook (app.py), di-deploy terpisah supaya bisa di-scale sendiri |
| Admin Dashboard | dashboard/ |
Streamlit, image Docker sendiri (TensorFlow/scikit-learn/Plotly terisolasi) |
Manajemen Proxy Pool (Dynamic Worker Queue)¶
Yahoo Finance membatasi lewat TLS-fingerprint (diatasi curl_cffi impersonate=chrome) dan volume request. Mitigasi volume request memakai arsitektur 3-tier di src/jobs/main.py:
- Tier 1 — Dynamic Worker Queue (
dynamic_worker_queue_fetch,direct_proxy_urls,proxy_pool_status) — semua ticker masuk satuasyncio.Queue, satu worker async per proxy statis sehat (Webshare "Direct" plan) menariknya dalam batch kecil. Worker yang kena timeout/429 requeue batch-nya, blacklist proxy-nya sendiri sementara (_ban_proxy), lalu mati. - Tier 2 — tvdatafeed (TradingView) (
_fill_missing_via_tvdatafeed) — kalau semua worker proxy Tier 1 mati dengan ticker tersisa, provider dan IP yang sama sekali berbeda dari Yahoo dicoba, mendukung bar harian maupun intraday (5m). - Tier 3 — Fallback GitHub Actions — kalau tvdatafeed masih menyisakan ticker, dispatch job ke
.github/workflows/yfinance-fallback.yml(IP GitHub), hasil di-POST balik ke webhook internal dan ditulis ke tabelyfinance_fallback_jobs.
Fallback Gemini API (3-Tier Cascading)¶
Semua kandidat sinyal dikirim dalam satu batch prompt ke Gemini (analyze_batch_with_gemini), dengan exponential backoff di HTTP 429 (src/jobs/gemini_utils.py's call_gemini_with_backoff) plus cascading 3-tier API key:
Tier berbayar (_BACKUP_PAY) hanya dipakai untuk daily_screener dan watchlist_recommender — tidak pernah untuk MICRO_RADAR.
Live Node Graph (Pyvis)¶
Tab Proxy & Live Stream dashboard (dashboard/tabs/tab_pipeline_flow.py) merender status pipeline real-time sebagai graf hub-and-spoke interaktif memakai Pyvis, menampilkan node Scheduler, tiap job (daily_screener, micro_radar, tracker, weekly_report), dan Proxy Pool secara live — termasuk status real/simulated proxy dan progress job yang sedang berjalan.
Autentikasi Dashboard Admin¶
Login dashboard (dashboard/auth.py, backend src/bot/admin.py) memakai dua faktor berurutan:
- Location Permission (Hard Gate) — tombol "Kirim OTP" tetap disabled sampai browser mengembalikan koordinat GPS asli lewat
navigator.geolocation. Timezone browser turut dikirim tanpa perlu izin. Jika lokasi diblokir permanen oleh browser, halaman menampilkan instruksi manual (tidak ada API browser yang bisa memaksa membuka ulang dialog permission). - Request Telegram OTP — setelah lokasi terverifikasi, admin menekan "Kirim OTP" (
POST /api/admin/request-otp, rate-limited 60 detik) yang mengirim kode 6 digit keTELEGRAM_ADMIN_CHAT_ID, disertai GeoIP (IP-based) dan koordinat GPS asli untuk konteks keamanan login. - Verifikasi OTP → JWT — kode dicocokkan (
POST /api/admin/verify-otp), berhasil mengembalikan JWT (JWT_SECRET) yang dipakai sebagaiAuthorization: Beareruntuk seluruh endpoint admin lainnya.
Visualisasi Codebase (Graphify)¶
Struktur relasi antar-modul, komunitas kode, dan "god nodes" pada codebase ini divisualisasikan sebagai knowledge graph interaktif oleh graphify, di-embed langsung di bawah: