# prasunray477/nfm-hyb architecture

> Architecture diagram of the GitHub repository prasunray477/nfm-hyb, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-26). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/prasunray477/nfm-hyb
- Repository: https://github.com/prasunray477/nfm-hyb

## Overview

1. **System shape**
   - This repo is a two-tier stock forecasting application: a **FastAPI backend** that performs data fetching and model inference/training, and a **Streamlit frontend** that presents predictions, comparisons, and analysis to users.
   - The core boundary is between the **presentation layer** (`frontend/`) and the **forecasting engine** (`app/` + `ml/`).

2. **Backend entry point and API surface**
   - `app/main.py` is the FastAPI application entrypoint.
   - API routes are split by responsibility in `app/api/routes/`:
     - `health.py` for service checks
     - `predict.py` for synchronous forecasting
     - `train.py` for background training runs
   - Request/response contracts are centralized in `app/models/schemas.py`, which keeps the API boundary explicit.

3. **Backend orchestration layer**
   - The backend is not just a thin API wrapper; it likely orchestrates the full forecasting workflow.
   - `ml/pipeline.py` appears to be the main coordinator for the end-to-end “analysis engine” described in the README: data preparation, stationarity handling, neutrosophic transform, model fitting, prediction, weighting, and evaluation.
   - The `/api/predict` and `/api/train` routes are the main entry points into that pipeline.

4. **Data acquisition and service boundary**
   - `app/services/data_service.py` is the repository’s data ingestion layer.
   - The README indicates live market data comes from **Yahoo Finance via `yfinance`**, so this service is the external-data boundary for OHLCV retrieval.
   - This layer isolates the rest of the system from raw market API calls and likely normalizes downloaded data before it enters the ML pipeline.

5. **Preprocessing and signal transformation**
   - `ml/neutrosophic/` implements the domain-specific preprocessing:
     - `normalizer.py` for transforming raw series into neutrosophic components
     - `entropy.py` for indeterminacy/uncertainty calculation
   - `app/utils/stationarity.py` handles stationarity checks and differencing logic, which is especially important for the ARIMA branch.
   - This is the main feature-engineering boundary: raw time series becomes model-ready inputs.

6. **Modeling subsystem: two parallel predictors**
   - The forecasting engine combines two model families:
     - `ml/arima/model.py` for the classical time-series branch
     - `ml/bilstm/architecture.py`, `trainer.py`, and `predictor.py` for the TensorFlow Bi-LSTM branch
   - These are deliberately separate because they solve different subproblems:
     - ARIMA captures linear autocorrelation
     - Bi-LSTM captures nonlinear temporal patterns in neutrosophic sequences

7. **Ensemble and weighting logic**
   - `ml/aggregator/static_weights.py` and `adaptive_weights.py` implement the hybrid fusion strategy.
   - The repository supports both fixed weighting and validation-driven optimization, matching the README’s “weighted ensemble” design.
   - This subsystem is the decision point where the two model outputs are combined into a final forecast.

8. **Evaluation and comparative analysis**
   - `ml/evaluation/metrics.py` centralizes forecast quality metrics such as RMSE, MAE, MAPE, and Theil’s U.
   - The frontend’s “analysis” page aligns with the backend’s ability to compare multiple configurations, from baseline ARIMA to the full hybrid model.
   - This makes evaluation a first-class output, not just an internal training artifact.

9. **Frontend architecture**
   - `frontend/streamlit_app.py` is the Streamlit entry point.
   - `frontend/pages/` defines the user workflow:
     - `01_predict.py` for running forecasts
     - `02_analysis.py` for model comparison and diagnostics
     - `03_about.py` for explanation/documentation
   - `frontend/components/` contains reusable UI pieces for charts, metrics, and neutrosophic visualizations, which keeps the page logic thin.

10. **Persistence and local artifacts**
   - The `data/` directory is the local artifact store:
     - `data/models/arima/` and `data/models/bilstm/` store saved model outputs/checkpoints
     - `data/results/` stores forecast outputs and analysis results
   - This indicates the system is partly stateful: training and prediction can produce persisted artifacts that later runs may reuse.

11. **Configuration, logging, and runtime concerns**
   - `app/core/config.py` centralizes environment-driven settings, with `.env.example` showing the app expects runtime configuration outside source control.
   - `app/core/logger.py` provides structured logging, which is important for observability across the API and ML workflow.
   - The repo targets **Python 3.11+**, with **FastAPI**, **Streamlit**, and **TensorFlow 2.15** as the key runtime technologies.

12. **Deployment and delivery**
   - `Dockerfile`, `render.yaml`, and `.github/workflows/deploy.yml` show the project is designed for containerized deployment with CI/CD automation.
   - The architecture therefore includes deployment concerns directly in-repo: reproducible packaging, environment configuration, and cloud deployment hooks.

13. **Testing boundary**
   - `tests/` covers the major subsystems separately:
     - aggregation
     - ARIMA
     - Bi-LSTM
     - neutrosophic logic
     - the pipeline
   - This reflects the system’s modular design: each major architectural slice can be validated independently.

14. **High-level data flow for an inference request**
   - A user submits a ticker and forecast options in the frontend or via `/api/predict`.
   - The backend fetches market data, applies stationarity and neutrosophic preprocessing, runs ARIMA and Bi-LSTM prediction paths, combines them via the aggregator, evaluates outputs, and returns the final result.
   - The frontend then renders charts, metrics, and comparative analysis from that response.

Main entry points: [`ml/pipeline.py`](https://github.com/prasunray477/nfm-hyb/blob/dev/ml/pipeline.py) (Pipeline), [`app/api/routes/predict.py`](https://github.com/prasunray477/nfm-hyb/blob/dev/app/api/routes/predict.py) (Predict route), [`app/main.py`](https://github.com/prasunray477/nfm-hyb/blob/dev/app/main.py) (API app), [`app/api/routes/train.py`](https://github.com/prasunray477/nfm-hyb/blob/dev/app/api/routes/train.py) (Train route)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_backend["Backend"]
  node_app_main["API app<br/>fastapi entrypoint<br/>[main.py]"]
  node_api_predict["Predict route<br/>api route<br/>[predict.py]"]
  node_api_train["Train route<br/>api route<br/>[train.py]"]
  node_api_health["Health route<br/>api route<br/>[health.py]"]
  node_schemas["Schemas<br/>contracts<br/>[schemas.py]"]
  node_data_service[("Data service<br/>market data<br/>[data_service.py]")]
  node_stationarity["Stationarity<br/>preprocess<br/>[stationarity.py]"]
  node_config_logger["Config & logs<br/>runtime support<br/>[config.py]"]
end

subgraph group_ml["Forecast Engine"]
  node_pipeline["Pipeline<br/>orchestrator<br/>[pipeline.py]"]
  node_normalizer["Normalizer<br/>neutrosophic prep<br/>[normalizer.py]"]
  node_entropy["Entropy<br/>uncertainty<br/>[entropy.py]"]
  node_arima_model(("ARIMA model<br/>classical model<br/>[model.py]"))
  node_bilstm_arch(("Bi-LSTM<br/>deep model<br/>[architecture.py]"))
  node_bilstm_train["Trainer<br/>training<br/>[trainer.py]"]
  node_bilstm_predict["Predictor<br/>inference<br/>[predictor.py]"]
  node_weights{{"Ensemble weights<br/>fusion"}}
  node_metrics["Metrics<br/>evaluation<br/>[metrics.py]"]
end

subgraph group_frontend["Frontend"]
  node_frontend_app["Streamlit app<br/>ui entrypoint<br/>[streamlit_app.py]"]
  node_page_predict["Predict page<br/>ui page<br/>[01_predict.py]"]
  node_page_analysis["Analysis page<br/>ui page<br/>[02_analysis.py]"]
  node_components["UI components<br/>ui widgets<br/>[charts.py]"]
end

subgraph group_ops["Ops"]
  node_artifacts[("Artifacts<br/>local state<br/>[.gitkeep]")]
  node_deploy["Deploy config<br/>delivery"]
end

node_app_main -->|"mounts"| node_api_health
node_app_main -->|"mounts"| node_api_predict
node_app_main -->|"mounts"| node_api_train
node_api_predict -->|"uses"| node_schemas
node_api_train -->|"uses"| node_schemas
node_api_predict -->|"invokes"| node_pipeline
node_api_train -->|"invokes"| node_pipeline
node_pipeline -->|"loads"| node_data_service
node_pipeline -->|"preprocesses"| node_stationarity
node_pipeline -->|"transforms"| node_normalizer
node_pipeline -->|"derives"| node_entropy
node_pipeline -->|"runs"| node_arima_model
node_pipeline -->|"trains"| node_bilstm_train
node_pipeline -->|"infers"| node_bilstm_predict
node_pipeline -->|"fuses"| node_weights
node_pipeline -->|"evaluates"| node_metrics
node_bilstm_train -->|"builds"| node_bilstm_arch
node_bilstm_predict -->|"loads"| node_bilstm_arch
node_weights -->|"compares"| node_metrics
node_frontend_app -->|"routes"| node_page_predict
node_frontend_app -->|"routes"| node_page_analysis
node_page_predict -->|"renders"| node_components
node_page_analysis -->|"renders"| node_components
node_page_predict -->|"calls"| node_api_predict
node_page_analysis -->|"shows"| node_metrics
node_api_predict -.->|"reads/writes"| node_artifacts
node_api_train -.->|"writes"| node_artifacts
node_pipeline -.->|"persists"| node_artifacts
node_config_logger -->|"supports"| node_app_main
node_deploy -.->|"packages"| node_app_main
node_deploy -.->|"packages"| node_frontend_app

click node_app_main "https://github.com/prasunray477/nfm-hyb/blob/dev/app/main.py"
click node_api_predict "https://github.com/prasunray477/nfm-hyb/blob/dev/app/api/routes/predict.py"
click node_api_train "https://github.com/prasunray477/nfm-hyb/blob/dev/app/api/routes/train.py"
click node_api_health "https://github.com/prasunray477/nfm-hyb/blob/dev/app/api/routes/health.py"
click node_schemas "https://github.com/prasunray477/nfm-hyb/blob/dev/app/models/schemas.py"
click node_data_service "https://github.com/prasunray477/nfm-hyb/blob/dev/app/services/data_service.py"
click node_stationarity "https://github.com/prasunray477/nfm-hyb/blob/dev/app/utils/stationarity.py"
click node_config_logger "https://github.com/prasunray477/nfm-hyb/blob/dev/app/core/config.py"
click node_pipeline "https://github.com/prasunray477/nfm-hyb/blob/dev/ml/pipeline.py"
click node_normalizer "https://github.com/prasunray477/nfm-hyb/blob/dev/ml/neutrosophic/normalizer.py"
click node_entropy "https://github.com/prasunray477/nfm-hyb/blob/dev/ml/neutrosophic/entropy.py"
click node_arima_model "https://github.com/prasunray477/nfm-hyb/blob/dev/ml/arima/model.py"
click node_bilstm_arch "https://github.com/prasunray477/nfm-hyb/blob/dev/ml/bilstm/architecture.py"
click node_bilstm_train "https://github.com/prasunray477/nfm-hyb/blob/dev/ml/bilstm/trainer.py"
click node_bilstm_predict "https://github.com/prasunray477/nfm-hyb/blob/dev/ml/bilstm/predictor.py"
click node_weights "https://github.com/prasunray477/nfm-hyb/blob/dev/ml/aggregator/adaptive_weights.py"
click node_metrics "https://github.com/prasunray477/nfm-hyb/blob/dev/ml/evaluation/metrics.py"
click node_frontend_app "https://github.com/prasunray477/nfm-hyb/blob/dev/frontend/streamlit_app.py"
click node_page_predict "https://github.com/prasunray477/nfm-hyb/blob/dev/frontend/pages/01_predict.py"
click node_page_analysis "https://github.com/prasunray477/nfm-hyb/blob/dev/frontend/pages/02_analysis.py"
click node_components "https://github.com/prasunray477/nfm-hyb/blob/dev/frontend/components/charts.py"
click node_artifacts "https://github.com/prasunray477/nfm-hyb/blob/dev/data/results/.gitkeep"
click node_deploy "https://github.com/prasunray477/nfm-hyb/tree/dev/Dockerfile"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app_main,node_api_predict,node_api_train,node_api_health,node_schemas,node_data_service,node_stationarity,node_config_logger toneBlue
class node_pipeline,node_normalizer,node_entropy,node_arima_model,node_bilstm_arch,node_bilstm_train,node_bilstm_predict,node_weights,node_metrics toneAmber
class node_frontend_app,node_page_predict,node_page_analysis,node_components toneMint
class node_artifacts,node_deploy toneRose
```

## Components

### Backend

FastAPI API, services, and runtime configuration.

- [API app](https://github.com/prasunray477/nfm-hyb/blob/dev/app/main.py): fastapi entrypoint · Creates and hosts the FastAPI application. · `app/main.py`
- [Predict route](https://github.com/prasunray477/nfm-hyb/blob/dev/app/api/routes/predict.py): api route · Synchronous forecasting endpoint. · `app/api/routes/predict.py`
- [Train route](https://github.com/prasunray477/nfm-hyb/blob/dev/app/api/routes/train.py): api route · Background training endpoint. · `app/api/routes/train.py`
- [Health route](https://github.com/prasunray477/nfm-hyb/blob/dev/app/api/routes/health.py): api route · Service status endpoint. · `app/api/routes/health.py`
- [Schemas](https://github.com/prasunray477/nfm-hyb/blob/dev/app/models/schemas.py): contracts · Request and response models for the API boundary. · `app/models/schemas.py`
- [Data service](https://github.com/prasunray477/nfm-hyb/blob/dev/app/services/data_service.py): market data · Fetches and normalizes live market data. · `app/services/data_service.py`
- [Stationarity](https://github.com/prasunray477/nfm-hyb/blob/dev/app/utils/stationarity.py): preprocess · Checks and transforms series for modeling. · `app/utils/stationarity.py`
- [Config & logs](https://github.com/prasunray477/nfm-hyb/blob/dev/app/core/config.py): runtime support · Environment settings and structured logging. · `app/core/config.py`

### Forecast Engine

Data prep, models, ensemble logic, and evaluation.

- [Pipeline](https://github.com/prasunray477/nfm-hyb/blob/dev/ml/pipeline.py): orchestrator · Coordinates preparation, training, prediction, weighting, and evaluation. · `ml/pipeline.py`
- [Normalizer](https://github.com/prasunray477/nfm-hyb/blob/dev/ml/neutrosophic/normalizer.py): neutrosophic prep · Transforms series into neutrosophic components. · `ml/neutrosophic/normalizer.py`
- [Entropy](https://github.com/prasunray477/nfm-hyb/blob/dev/ml/neutrosophic/entropy.py): uncertainty · Computes indeterminacy and uncertainty measures. · `ml/neutrosophic/entropy.py`
- [ARIMA model](https://github.com/prasunray477/nfm-hyb/blob/dev/ml/arima/model.py): classical model · Linear time-series forecasting branch. · `ml/arima/model.py`
- [Bi-LSTM](https://github.com/prasunray477/nfm-hyb/blob/dev/ml/bilstm/architecture.py): deep model · Neural forecasting architecture for temporal patterns. · `ml/bilstm/architecture.py`
- [Trainer](https://github.com/prasunray477/nfm-hyb/blob/dev/ml/bilstm/trainer.py): training · Fits and updates the Bi-LSTM model. · `ml/bilstm/trainer.py`
- [Predictor](https://github.com/prasunray477/nfm-hyb/blob/dev/ml/bilstm/predictor.py): inference · Runs Bi-LSTM inference on prepared inputs. · `ml/bilstm/predictor.py`
- [Ensemble weights](https://github.com/prasunray477/nfm-hyb/blob/dev/ml/aggregator/adaptive_weights.py): fusion · Combines ARIMA and Bi-LSTM outputs using fixed or adaptive weighting. · `ml/aggregator/adaptive_weights.py`
- [Metrics](https://github.com/prasunray477/nfm-hyb/blob/dev/ml/evaluation/metrics.py): evaluation · Forecast quality measures and comparisons. · `ml/evaluation/metrics.py`

### Frontend

Streamlit user interface and reusable components.

- [Streamlit app](https://github.com/prasunray477/nfm-hyb/blob/dev/frontend/streamlit_app.py): ui entrypoint · Main Streamlit application shell. · `frontend/streamlit_app.py`
- [Predict page](https://github.com/prasunray477/nfm-hyb/blob/dev/frontend/pages/01_predict.py): ui page · User workflow for requesting forecasts. · `frontend/pages/01_predict.py`
- [Analysis page](https://github.com/prasunray477/nfm-hyb/blob/dev/frontend/pages/02_analysis.py): ui page · Model comparison and diagnostics. · `frontend/pages/02_analysis.py`
- [UI components](https://github.com/prasunray477/nfm-hyb/blob/dev/frontend/components/charts.py): ui widgets · Reusable charts, metrics, and neutrosophic visualizations. · `frontend/components/charts.py`

### Ops

Deployment and local stateful artifacts.

- [Artifacts](https://github.com/prasunray477/nfm-hyb/blob/dev/data/results/.gitkeep): local state · Saved models and stored forecast results. · `data/results/.gitkeep`
- [Deploy config](https://github.com/prasunray477/nfm-hyb/tree/dev/Dockerfile): delivery · Container and CI/CD deployment configuration. · `Dockerfile`

## Connections

- API app → Health route: mounts · Registers the health route.
- API app → Predict route: mounts · Registers prediction endpoints.
- API app → Train route: mounts · Registers training endpoints.
- Predict route → Schemas: uses · Validates request and response payloads.
- Train route → Schemas: uses · Shares API contracts.
- Predict route → Pipeline: invokes · Starts the forecasting workflow.
- Train route → Pipeline: invokes · Starts training and optimization runs.
- Pipeline → Data service: loads · Fetches market data for analysis.
- Pipeline → Stationarity: preprocesses · Prepares time series for modeling.
- Pipeline → Normalizer: transforms · Builds neutrosophic inputs.
- Pipeline → Entropy: derives · Computes uncertainty features.
- Pipeline → ARIMA model: runs · Executes the classical forecast branch.
- Pipeline → Trainer: trains · Fits the neural branch when needed.
- Pipeline → Predictor: infers · Runs neural inference for forecasts.
- Pipeline → Ensemble weights: fuses · Combines branch outputs into the final prediction.
- Pipeline → Metrics: evaluates · Scores forecasts and comparisons.
- Trainer → Bi-LSTM: builds · Uses the neural architecture for fitting.
- Predictor → Bi-LSTM: loads · Uses the trained architecture for inference.
- Ensemble weights → Metrics: compares · Supports model comparison and selection.
- Streamlit app → Predict page: routes · Exposes the forecast workflow.
- Streamlit app → Analysis page: routes · Exposes analysis and diagnostics.
- Predict page → UI components: renders · Uses shared charts and metric displays.
- Analysis page → UI components: renders · Uses shared visualization components.
- Predict page → Predict route: calls · Requests forecasts from the backend.
- Analysis page → Metrics: shows · Presents evaluation results and comparisons.
- Predict route → Artifacts: reads/writes · May reuse saved models and persist outputs.
- Train route → Artifacts: writes · Stores trained models and run outputs.
- Pipeline → Artifacts: persists · Emits reusable results and checkpoints.
- Config & logs → API app: supports · Provides runtime settings and logging.
- Deploy config → API app: packages · Defines how the backend is built and run.
- Deploy config → Streamlit app: packages · Defines how the UI is built and run.
