Karan6124 commited on
Commit
f259a90
·
1 Parent(s): c76dd37

docs: create professional and detailed README files for all subfolders

Browse files
Files changed (4) hide show
  1. alembic/README.md +48 -0
  2. backend/README.md +90 -0
  3. frontend/README.md +32 -23
  4. worker/README.md +53 -0
alembic/README.md ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Database Migrations (Alembic)
2
+
3
+ This directory contains the database migration scripts managed by Alembic. Alembic handles automatic schema updates, tracking revisions, and syncing database tables with SQLAlchemy models.
4
+
5
+ ---
6
+
7
+ ## Migration Commands Reference
8
+
9
+ ### 1. Run Pending Migrations
10
+ To bring your local database (PostgreSQL/NeonDB) up to date with the latest schema changes:
11
+ ```bash
12
+ uv run alembic upgrade head
13
+ ```
14
+
15
+ ### 2. Generate a New Migration
16
+ To create a new migration after editing SQLAlchemy models in `backend/app/database/models.py`:
17
+ ```bash
18
+ uv run alembic revision --autogenerate -m "describe your changes"
19
+ ```
20
+
21
+ ### 3. Revert Migrations
22
+ To roll back the last applied migration:
23
+ ```bash
24
+ uv run alembic downgrade -1
25
+ ```
26
+
27
+ ---
28
+
29
+ ## Database Schema Evolution
30
+
31
+ The database schema has evolved through the following sequential revisions located in the `versions/` folder:
32
+
33
+ 1. **Initial Schema (`3d7629451f7d_initial_schema.py`)**
34
+ - Creates the core tables: `users` (credentials and subscription states), `watchlists` (user ticker lists), and `stock_history` (OHLCV candles).
35
+ 2. **User Verification (`99690d55ee16_add_user_verification_columns.py`)**
36
+ - Appends email verification tracking, registration verification codes, and expiration timestamps to the `users` table.
37
+ 3. **Subscriptions & Message Limits (`bbdbf37359be_add_subscription_and_message_limit_.py`)**
38
+ - Adds monthly credit bounds, API request trackers, and usage counters to enforce tiered subscription levels.
39
+ 4. **Strategy Execution Logs (`887a33df9c3e_add_strategy_logs_table.py`)**
40
+ - Creates the `strategy_logs` table to store quantitative backtesting parameters, accuracy scores, and performance logs.
41
+ 5. **Saved Strategy Configurations (`1ffb20394fc4_add_saved_strategies.py`)**
42
+ - Creates the `saved_strategies` table, allowing users to save and load strategy setups.
43
+ 6. **Model Predictions Tracking (`31f4439fab74_add_prediction_logs_table.py`)**
44
+ - Creates the `prediction_logs` table to log probability outputs, actual outcomes, and model scores from the specialized ONNX models.
45
+ 7. **Asset Category Fields (`ea96300d7e57_add_asset_class_columns.py`)**
46
+ - Adds category indicators (e.g. tech, crypto, index) to refine indicator logic per asset class.
47
+ 8. **Threshold Alerts (`15639881888f_add_alert_trigger_columns.py`)**
48
+ - Appends trigger states to the price alerts table to track when a stock crosses user-specified price bounds.
backend/README.md ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Backend Service Layer
2
+
3
+ The Backend is a high-performance FastAPI service designed to orchestrate the machine learning model pipeline, execute the Gemini ReAct agent loop, manage GraphQL subscriptions, handle HTTP endpoints, and process background Celery tasks.
4
+
5
+ ---
6
+
7
+ ## Architecture & Service Directory
8
+
9
+ ### 1. ONNX Model Hub & Dynamic Hot-Reloading
10
+ Upon service startup (`startup_event` in `backend/app/main.py`), the backend automatically connects to Hugging Face Hub via `hf_hub_download` to pull specialized machine learning models:
11
+ - `model_tech.onnx` (for technology stocks)
12
+ - `model_crypto.onnx` (for cryptocurrency assets)
13
+ - `model_index.onnx` (for broad market indices)
14
+
15
+ If downloading fails, the server falls back to a general `model.onnx` file stored locally.
16
+
17
+ #### Hot-Reloading Engine:
18
+ To support model retraining without system downtime, the function `get_onnx_session_for_type` monitors the model files. When a retraining task saves a new model file, the system detects the changed modification time (`os.path.getmtime`), terminates the old session, and hot-reloads the new `ort.InferenceSession` in-memory.
19
+
20
+ ---
21
+
22
+ ### 2. Gemini ReAct Agent Loop
23
+ The core analytical capabilities of QuantIQ are powered by the Gemini GenAI SDK (`gemini-2.5-flash`), running a reasoning-action loop.
24
+
25
+ #### Synchronous Tool closures:
26
+ The Gemini automatic function calling API executes tools synchronously. However, the database operations inside our FastAPI application are asynchronous. To solve this, the agent loop uses `asyncio.run_coroutine_threadsafe` and closures to safely schedule async queries back onto the main event loop from inside the synchronous tool calls.
27
+
28
+ #### Tool Ecosystem:
29
+ - `get_user_watchlist`: Retrieves the active ticker watchlist for the logged-in user.
30
+ - `get_stock_history_and_indicators`: Extracts recent price candles and calculates technical indicator values.
31
+ - `create_alert_threshold`: Allows the model to programmatically set alert boundaries.
32
+ - `trigger_model_prediction`: Evaluates the specialized ONNX model predictions.
33
+
34
+ ---
35
+
36
+ ### 3. Mathematical Indicator Formulas
37
+
38
+ The backend computes technical indicators over a 60-day historical window. The exact formulas are detailed below:
39
+
40
+ #### Volatility Target and Stop-Loss Levels (ATR-14)
41
+ To calculate risk-managed boundaries:
42
+ 1. Compute the True Range (TR) for each candle:
43
+ $$\text{TR} = \max(\text{High} - \text{Low}, |\text{High} - \text{Close}_{\text{prev}}|, |\text{Low} - \text{Close}_{\text{prev}}|)$$
44
+ 2. Compute the 14-period Average True Range (ATR) using Wilder's Smoothing:
45
+ $$\text{ATR}_t = \frac{\text{ATR}_{t-1} \times 13 + \text{TR}_t}{14}$$
46
+ 3. Set the target and stop-loss boundaries based on the signal action (with a default multiplier of 1.5):
47
+ - **BUY**:
48
+ $$\text{Stop Loss} = \text{Close} - (1.5 \times \text{ATR})$$
49
+ $$\text{Target Price} = \text{Close} + (3.0 \times \text{ATR})$$
50
+ - **SELL**:
51
+ $$\text{Stop Loss} = \text{Close} + (1.5 \times \text{ATR})$$
52
+ $$\text{Target Price} = \text{Close} - (3.0 \times \text{ATR})$$
53
+
54
+ If the asset history has fewer than 14 days, the system falls back to asset-class default percentages:
55
+ - **Crypto**: Target = 8%, Stop = 4%
56
+ - **Indices**: Target = 1.5%, Stop = 0.75%
57
+ - **Stocks (Tech/General)**: Target = 4%, Stop = 2%
58
+
59
+ #### Relative Strength Index (RSI-14)
60
+ Computes momentum boundaries using upward and downward price changes over 14 candles:
61
+ $$\text{RS} = \frac{\text{EMA}(\text{Gain}, 14)}{\text{EMA}(\text{Loss}, 14)}$$
62
+ $$\text{RSI} = 100 - \left(\frac{100}{1 + \text{RS}}\right)$$
63
+
64
+ #### MACD (Moving Average Convergence Divergence)
65
+ Measures trend-following momentum:
66
+ $$\text{MACD Line} = \text{EMA}(\text{Close}, 12) - \text{EMA}(\text{Close}, 26)$$
67
+ $$\text{Signal Line} = \text{EMA}(\text{MACD Line}, 9)$$
68
+ $$\text{Histogram} = \text{MACD Line} - \text{Signal Line}$$
69
+
70
+ ---
71
+
72
+ ### 4. Celery Tasks & Redis Logical Separation
73
+ Redis serves as both our Celery task broker and backend database cache. To prevent packet collisions and memory corruption, the databases are logically isolated:
74
+ - **Broker Channel**: Celery occupies Redis Logical Database 0 (`redis://localhost:6379/0`).
75
+ - **Cache Channel**: Technical indicators caching, yfinance hourly caching, and ATR calculations occupy Redis Logical Database 1 (`redis://localhost:6379/1`).
76
+
77
+ ---
78
+
79
+ ### 5. Strawberry GraphQL Integration
80
+ The client connects to a Strawberry-powered GraphQL router mounted at `/graphql`.
81
+ - **JWT Authorization Parser**: On each request, the custom `get_graphql_context` dependency extracts the HTTP `Authorization: Bearer <token>` header, decodes the JWT signature, extracts the user ID UUID, and fetches the user ORM object to inject it directly into the execution context.
82
+ - **Database Context**: Attaches the active `AsyncSession` to the GraphQL context, ensuring database queries run within safe transaction boundaries.
83
+
84
+ ---
85
+
86
+ ### 6. Prometheus Metrics Instrumentation
87
+ The backend uses `prometheus-fastapi-instrumentator` to export operational metrics.
88
+ - Enpoints metrics are published on the `/metrics` path.
89
+ - The route is protected using HTTP Basic Authentication (`admin` / `admin`).
90
+ - Tracks API latency, HTTP response codes, active WebSocket counts, Gemini token expenditures, and agent reasoning steps.
frontend/README.md CHANGED
@@ -1,32 +1,41 @@
1
- # React + TypeScript + Vite
2
 
3
- This template provides a minimal setup to get React working in Vite with HMR and some Oxlint rules.
4
 
5
- Currently, two official plugins are available:
6
 
7
- - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
8
- - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)
9
 
10
- ## React Compiler
 
 
 
 
11
 
12
- The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
13
 
14
- ## Expanding the Oxlint configuration
 
 
 
 
 
 
15
 
16
- If you are developing a production application, we recommend enabling type-aware lint rules by installing `oxlint-tsgolint` and editing `.oxlintrc.json`:
17
 
18
- ```json
19
- {
20
- "$schema": "./node_modules/oxlint/configuration_schema.json",
21
- "plugins": ["react", "typescript", "oxc"],
22
- "options": {
23
- "typeAware": true
24
- },
25
- "rules": {
26
- "react/rules-of-hooks": "error",
27
- "react/only-export-components": ["warn", { "allowConstantExport": true }]
28
- }
29
- }
30
- ```
31
 
32
- See the [Oxlint rules documentation](https://oxc.rs/docs/guide/usage/linter/rules) for the full list of rules and categories.
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Frontend Client Workspace
2
 
3
+ The frontend is a single-page React client built with TypeScript, Vite, Tailwind CSS, and lightweight UI components. It renders the trading workspace, manages websocket subscriptions, and displays real-time price trends.
4
 
5
+ ---
6
 
7
+ ## Technical Components & Integration Details
 
8
 
9
+ ### 1. TradingView Lightweight Charts (`StockChart.tsx`)
10
+ The centerpiece of the UI is the stock chart widget, which utilizes the `lightweight-charts` library:
11
+ - **WebSocket Real-Time Streaming:** The chart opens a connection to the backend WebSocket server (`ws://localhost:8000/api/v1/ws/ticks`). As ticks arrive from the Redpanda broker, they are pushed directly to the candlestick series update channel.
12
+ - **Tick Accumulation:** If a tick arrives for the current minute, its price updates the close of the current candle. If a new minute arrives, a new candle is created.
13
+ - **Historical Data Backfill:** When switching tickers, the chart calls the API to download the last 100 historical candles from NeonDB to prevent gaps in chart history.
14
 
15
+ ### 2. Component Directory Map
16
 
17
+ - **`App.tsx`**: Core routing, layout shell, and global authentication states.
18
+ - **`components/StockChart.tsx`**: Embeds the main candlestick chart, indicators toggle, and price-scaling canvas handlers.
19
+ - **`components/AIAnalyst.tsx`**: Interactive side-panel allowing users to query the Gemini ReAct agent loop. It displays reasoning steps, tool calls, and model outputs in real time.
20
+ - **`components/TrendingHub.tsx`**: A social trading feed displaying strategies and prediction records generated by the background ML models.
21
+ - **`components/WatchlistSidebar.tsx`**: Sidebar allowing users to add, remove, and manage monitored tickers. Saves state directly to NeonDB.
22
+ - **`components/PriceAlerts.tsx`**: Threshold settings page where users configure price levels for alerts.
23
+ - **`components/RechargeModal.tsx`**: A payment interface managing balance credits and subscription upgrades.
24
 
25
+ ---
26
 
27
+ ## Production Build & Deploy Verification
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ ### Strict TypeScript Constraints
30
+ The project runs clean type verification during compilation:
31
+ ```bash
32
+ npm run build
33
+ ```
34
+ Under the hood, this executes `tsc -b` and `vite build`. To prevent production crashes:
35
+ - Any declared variables, parameters, or import statements that are unused will throw compiler error `TS6133` and fail the build.
36
+ - Always check that your dependencies are imported correctly and clean up unused code before deploying.
37
+
38
+ ### Deployment Configuration
39
+ The client is optimized for Vercel deployment:
40
+ - **`vercel.json`**: Sets up URL routing rules to redirect all page requests to `index.html` to support React client-side routing.
41
+ - **Vite Proxy Config**: Proxy rules are configured to redirect `/api/v1` routes to the backend port during local development.
worker/README.md ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Ingestion Worker
2
+
3
+ The Ingestion Worker is a standalone service responsible for real-time asset price tracking, data streaming, and database candle aggregation. It operates on a continuous async loop to fetch ticker ticks and publish them to a message broker.
4
+
5
+ ---
6
+
7
+ ## Technical Architecture
8
+
9
+ ### 1. Multi-Threaded yfinance Ingestion
10
+ The Yahoo Finance (`yfinance`) library runs synchronous blocking network calls when querying tickers. To prevent blocking the main asyncio event loop, the worker runs all `fast_info` metrics retrievals inside a thread pool executor using `loop.run_in_executor(None, ...)` inside `get_latest_stock_data`.
11
+
12
+ ```python
13
+ loop = asyncio.get_event_loop()
14
+ yf_ticker = yf.Ticker(ticker)
15
+ info = await loop.run_in_executor(None, lambda: yf_ticker.fast_info)
16
+ ```
17
+
18
+ This ensures high concurrency and prevents websocket read latency on the frontend during polling cycles.
19
+
20
+ ### 2. Exponential Rate-Limit Cooldown
21
+ To bypass strict IP rate-limiting blocks from third-party APIs:
22
+ - If a `429 Too Many Requests` or rate-limiting exception string is caught during execution, the worker sets a global cooldown timestamp (`COOLDOWN_UNTIL`).
23
+ - The rate-limiting cooldown backoff starts at 60 seconds.
24
+ - On consecutive rate-limit violations, the backoff doubles exponentially up to a maximum limit of 15 minutes (900 seconds).
25
+ - Once the cooldown timer expires, the backoff resets to 60 seconds on the first successful fetch.
26
+
27
+ ### 3. Redpanda Event Streaming
28
+ All successfully fetched ticker events are formatted as JSON payloads containing the ticker name, latest price, cumulative volume, and UTC timestamp, then published to the Redpanda Cloud topic `stock-ticks`.
29
+ - The worker uses the asynchronous `aiokafka` client (`AIOKafkaProducer`).
30
+ - Payload serialization is handled using a native UTF-8 JSON encoder.
31
+
32
+ ### 4. 1-Minute Candle Aggregation
33
+ In addition to streaming, the worker buffers price and volume data points in memory to calculate 1-minute OHLCV candles:
34
+ - **Open**: The first price point of the minute.
35
+ - **High**: The maximum price point recorded in the minute.
36
+ - **Low**: The minimum price point recorded in the minute.
37
+ - **Close**: The last price point of the minute.
38
+ - **Volume**: The difference between the maximum and minimum cumulative volumes recorded in that minute.
39
+
40
+ #### Closed-Market Skipping Rules:
41
+ To avoid bloat in the database (e.g. NeonDB storage limitations), the worker filters out flat, inactive closed-market candles (where open equals high, low, and close, and the volume difference is zero).
42
+ - Non-crypto tickers (stocks and indices) will not be committed to the database during closed hours.
43
+ - Crypto tickers (e.g. ending in `-USD` or `-BTC`) bypass this rule and are saved 24/7 since cryptocurrency markets never close.
44
+
45
+ ---
46
+
47
+ ## Service Operations
48
+
49
+ ### Core Main Loop
50
+ The worker queries the database dynamically on each cycle to fetch active tickers from users' watchlists (`select(Watchlist.ticker).distinct()`). This guarantees that:
51
+ - The worker only polls tickers that users are actively monitoring.
52
+ - Adding a ticker to a watchlist dynamically begins polling it without requiring a worker restart.
53
+ - Polling calls are staggered with a 1.5-second sleep interval to spread load evenly.