# keetasin/us-utilities-forecast architecture

> Architecture diagram of the GitHub repository keetasin/us-utilities-forecast, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/keetasin/us-utilities-forecast
- Repository: https://github.com/keetasin/us-utilities-forecast

## Overview

This is a Flask stock-analysis and forecasting application for five US utilities. Users browse stock prices and financial indicators, read recent company news, and request forecasts or compare ARIMA, SARIMA, SARIMAX, and LSTM results with backtest accuracy. The web layer reads and writes persisted application records; scheduled jobs refresh stock and news data. The README also documents an Airflow/Spark data-refresh path, but the sampled DAG excerpt does not show its task wiring, so that connection is left out. Forecast internals and several dashboard routes are only partially sampled.

Main entry points: [`src/web/views.py`](https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/views.py) (Web views), [`src/web/models.py`](https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/models.py) (Data models), [`src/web/utils/forecast.py`](https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/utils/forecast.py) (Forecast engine), [`src/web/utils/stock.py`](https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/utils/stock.py) (Stock data)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web experience"]
  node_flask["Flask app<br/>[__init__.py]"]
  node_routes["Web views<br/>[views.py]"]
end

subgraph group_forecast["Forecasting"]
  node_forecastutil["Forecast engine<br/>[forecast.py]"]
end

subgraph group_refresh["Data refresh"]
  node_stockutil["Stock data<br/>[stock.py]"]
  node_newsutil["News fetch<br/>[news.py]"]
  node_scheduler["Job scheduler<br/>[scheduler.py]"]
  node_airflowdag["Forecast DAG<br/>[forecast-stock.py]"]
  node_sparkpull["Market ingestion<br/>[pull_yf.py]"]
end

subgraph group_state["Persisted data"]
  node_models["Data models<br/>[models.py]"]
  node_database[("PostgreSQL")]
  node_parquet["Parquet output"]
end

node_investor(("Investor"))
node_marketdata["Yahoo Finance"]
node_newsapi["NewsAPI"]

node_investor -->|"uses"| node_flask
node_flask -->|"registers routes"| node_routes
node_routes -->|"queries"| node_models
node_routes -->|"requests forecasts"| node_forecastutil
node_routes -.->|"fetches analytics"| node_marketdata
node_routes -->|"renders views"| node_investor
node_models -->|"reads and writes"| node_database
node_scheduler -->|"schedules refresh"| node_stockutil
node_scheduler -->|"schedules refresh"| node_newsutil
node_stockutil -->|"fetches prices"| node_marketdata
node_stockutil -->|"updates stock records"| node_models
node_newsutil -->|"fetches articles"| node_newsapi
node_newsutil -->|"updates news records"| node_models
node_forecastutil -->|"fetches price history"| node_marketdata
node_forecastutil -->|"stores forecasts"| node_models
node_airflowdag -.-> node_sparkpull
node_sparkpull -->|"downloads market data"| node_marketdata
node_sparkpull -->|"writes parquet"| node_parquet

click node_flask "https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/__init__.py"
click node_routes "https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/views.py"
click node_stockutil "https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/utils/stock.py"
click node_newsutil "https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/utils/news.py"
click node_scheduler "https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/scheduler.py"
click node_forecastutil "https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/utils/forecast.py"
click node_airflowdag "https://github.com/keetasin/us-utilities-forecast/blob/main/src/dags/forecast-stock.py"
click node_sparkpull "https://github.com/keetasin/us-utilities-forecast/blob/main/src/spark/applications/spark_jobs/pull_yf.py"
click node_models "https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/models.py"

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_flask,node_routes toneBlue
class node_forecastutil toneAmber
class node_stockutil,node_newsutil,node_scheduler,node_airflowdag,node_sparkpull,node_newsapi toneMint
class node_models,node_database,node_parquet toneRose
class node_investor,node_marketdata toneIndigo
```

## Components

### Web experience

- [Flask app](https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/__init__.py): `src/web/__init__.py`
- [Web views](https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/views.py): `src/web/views.py`

### Forecasting

- [Forecast engine](https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/utils/forecast.py): `src/web/utils/forecast.py`

### Data refresh

- [Stock data](https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/utils/stock.py): `src/web/utils/stock.py`
- [News fetch](https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/utils/news.py): `src/web/utils/news.py`
- [Job scheduler](https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/scheduler.py): `src/web/scheduler.py`
- [Forecast DAG](https://github.com/keetasin/us-utilities-forecast/blob/main/src/dags/forecast-stock.py): `src/dags/forecast-stock.py`
- [Market ingestion](https://github.com/keetasin/us-utilities-forecast/blob/main/src/spark/applications/spark_jobs/pull_yf.py): `src/spark/applications/spark_jobs/pull_yf.py`

### Persisted data

- [Data models](https://github.com/keetasin/us-utilities-forecast/blob/main/src/web/models.py): `src/web/models.py`
- **PostgreSQL**
- **Parquet output**

### Other components

- **Investor**
- **Yahoo Finance**
- **NewsAPI**

## Connections

- Investor → Flask app: uses
- Flask app → Web views: registers routes
- Web views → Data models: queries
- Web views → Forecast engine: requests forecasts
- Web views → Yahoo Finance: fetches analytics
- Web views → Investor: renders views
- Data models → PostgreSQL: reads and writes
- Job scheduler → Stock data: schedules refresh
- Job scheduler → News fetch: schedules refresh
- Stock data → Yahoo Finance: fetches prices
- Stock data → Data models: updates stock records
- News fetch → NewsAPI: fetches articles
- News fetch → Data models: updates news records
- Forecast engine → Yahoo Finance: fetches price history
- Forecast engine → Data models: stores forecasts
- Forecast DAG → Market ingestion
- Market ingestion → Yahoo Finance: downloads market data
- Market ingestion → Parquet output: writes parquet
