Welcome

This is the start of my technical portfolio. Explore the Chart Studio to interact with the platform, or read on to learn how it works.


How It Works

The platform follows a containerised microservice architecture. A reverse proxy handles TLS termination and request routing, forwarding traffic to the application server. Persistent state is managed by a relational database, while an in-memory store provides low-latency caching and rate-limit enforcement. Background workers handle scheduled data ingestion tasks independently of the request cycle.

Container Environment Reverse Proxy Application Server Relational Database persistence + search index In-Memory Cache rate limits + sessions Object Storage static assets Background Workers
Environment-driven configuration — The application loads a different configuration profile depending on the deployment target. Each profile inherits shared defaults (database, cache, logging conventions) and overrides only the settings relevant to its context. The portfolio deployment disables authentication, payment processing, and scheduled task orchestration, yielding a reduced attack surface and faster cold-start times.
Multi-stage container builds — The production container image is produced via a two-stage build process. The first stage resolves dependencies and compiles the frontend bundle; the second stage copies only the runtime artifacts into a minimal base image. Health-check endpoints enable the orchestrator to verify both process liveness and downstream connectivity.
Rate limiting and resource budgets — All public-facing endpoints are subject to IP-based rate limiting, enforced via the in-memory cache. Upstream data provider calls are tracked against configurable daily budgets. When a budget is exhausted, the system falls back to cached data rather than issuing additional external requests.

The charting engine is a custom Canvas-based rendering system. It employs a layered architecture in which each visual concern — axes, data series, annotations, and user interaction — occupies its own rendering pass. Mathematical transformations (temporal and linear scaling, domain computation, coordinate projection) are delegated to a dedicated scale library, while the rendering itself uses hardware-accelerated 2D canvas operations to maintain responsive frame rates across large datasets.

Axis Layer (grid, tick labels, date formatting) Series Layer (line / area / bar rendering) Overlay Layer (annotations, measurements, shaded regions) Interaction Layer (crosshair, pan, zoom, drawing tools) render order ↑
Dual-axis scale construction — Each render pass constructs temporal (x-axis) and linear (dual y-axis) scales from the current data domain. Pan and zoom interactions override the computed domain boundaries, and these overrides persist across frames and are serialised with saved chart configurations to preserve the user's viewport.
Logarithmic crosshair snapping — With datasets exceeding 50,000 observations, the crosshair must locate the nearest data point on every pointer movement. The system uses binary search over the sorted date index to achieve O(log n) lookup time, ensuring smooth interaction even at high data densities.
Typed annotation model — Text labels, horizontal and vertical reference lines, rectangular regions, freeform drawn lines, and distance measurements are each represented as typed objects in a centralised state store. Each annotation type encapsulates its own rendering logic, and all date-valued properties are stored as native temporal objects to guarantee correct scale mapping after serialisation.

The platform ingests time series data from multiple upstream providers and normalises it into a uniform representation for the chart engine. A multi-tier caching strategy balances response latency against upstream API constraints. The integrated search engine indexes over 100,000 financial instruments and supports full-text queries with faceted filtering.

Equity Providers FRED World Bank Provider Router fallback + retry Cache Layer hot + persistent tiers Chart API normalise + transform Frontend
Provider fallback chain — For equity data, the system attempts a primary provider first and falls back to a secondary source when the primary is unavailable or the requested ticker is not found. Macro-economic data is sourced from FRED (Federal Reserve Economic Data) and the World Bank Open Data API. All fetch operations employ exponential-backoff retry for transient network failures.
Multi-tier caching — Recently accessed data resides in the in-memory cache with short time-to-live values for responsiveness. Historical time series are persisted to the relational database, ensuring continuity across cache eviction events and reducing redundant upstream requests. Budget counters enforce per-provider daily call limits.
Full-text search with faceted filtering — The search index spans over 100,000 instruments across equities, macro indicators, and international datasets. Queries are scored by relevance across ticker symbol, instrument name, and topic tags. Results support faceted narrowing by data source, exchange, reporting frequency, and subject area, with typical response times under 50 milliseconds.

The platform incorporates a large language model as a streaming analysis engine. Given the user's charted data and a selected analytical question, the system constructs a context-aware prompt, streams the model's response in real time, and extracts structured annotations that are rendered directly on the chart. The model is augmented with web search grounding to reference named economic events and geopolitical developments.

User Input question type + date range Prompt Builder contextual assembly + series data LLM streaming response + web grounding Extractor structured annotations from response Chart Overlay events + regions snapped to data
Modular question taxonomy — Each analysis category (trend summarisation, divergence assessment, regime identification, driver decomposition) is represented as a self-contained entry in a question registry. Each entry specifies its minimum data requirements, the types of annotations it may produce, and whether follow-up selection (e.g., driver category filtering) is applicable.
Structured annotation extraction — The model's output includes both human-readable narrative and a machine-readable annotation block. Annotations are typed as either point events (rendered as vertical markers at a specific date) or regions (rendered as shaded rectangles between two dates), each carrying a category label, colour assignment, and descriptive blurb. These annotations are automatically applied to the chart upon generation.
Server-Sent Event streaming — The analysis response is streamed token-by-token to the frontend via an SSE connection. The interface progressively renders formatted text as it arrives, providing immediate visual feedback while the full response is still being generated. Annotation extraction occurs once the stream completes.

A step-by-step walkthrough of how to use the Chart Studio, from loading data through to AI-powered analysis.

Loading & Configuring Data
1
Search for a series

Use the search bar in the left sidebar or the navbar to find equities (e.g. "AAPL"), macro indicators (e.g. "GDP", "CPI"), or international data. Results show the instrument name, data source, and frequency.

2
Add series to the chart

Click on a search result to add it. Each series appears in the sidebar with a colour swatch, its ticker, and a human-readable name. You can add up to 6 series simultaneously.

3
Configure each series

For each series, select a transform (raw value, percentage change, log scale, z-score, cumulative return, etc.) and assign it to the left or right axis. Change the series colour by clicking the colour swatch.

4
Set the date range

Use the date pickers in the sidebar to narrow the analysis window. Press Update Chart to reload data within the selected range.


Navigation & Annotation Tools
5
Pan & Zoom

Use the scroll wheel to zoom in and out. Click and drag on the chart to pan. The Reset View button (compress icon in the toolbar) restores the original viewport.

6
Measure tool

Select the Measure tool (ruler icon) or press M. Click two points on the chart to see the absolute change, percentage change, and number of days between them.

7
Drawing tools

The toolbar provides Line, Horizontal Line, Vertical Line, and Rectangle Shade tools for manual annotation. Use the colour picker to change the drawing colour. The Text tool places editable labels directly on the chart.

8
Eraser & Clear All

Select the Eraser tool then click on any annotation to remove it. The Clear All button (trash icon) removes all measurements and drawings at once.


AI Analysis
9
Open the AI panel

Click the Analyze button on the far right of the toolbar. The analysis panel opens showing available question types and a daily usage quota.

10
Set the analysis range

The analysis panel has its own date range that defaults to the chart's range. You can narrow it further using the date pickers or the crosshair picker (target icon) to click start and end dates directly on the chart.

11
Select series and detail level

When multiple series are loaded, use the series toggles to include or exclude specific instruments from the analysis. Choose between Bullet (concise points) and Paragraph (detailed narrative) output formats.

12
Ask a question

Click on one of the available question types (e.g., "Trend Summary", "Divergence", "Market Regimes", "Key Drivers"). Some questions require a minimum number of series. The AI streams its response in real time, and any identified annotations — event markers or shaded regions — are automatically applied to the chart.

13
Review annotations

Expand each annotation card in the panel to read its descriptive blurb and category. Individual annotations can also be toggled or applied manually. Previous analyses are preserved in the History dropdown for quick reference.


Saving & Loading Charts
14
Save a chart configuration

In the sidebar under "Saved Charts", click + New Chart, enter a name, and press save. This stores all loaded series, date range, annotations, drawing objects, AI analysis history, and the current zoom/pan viewport.

15
Load and update

Click the load button next to a saved chart to restore its full state. After making changes, click the save button on the same row to overwrite it with the current state. Use the pencil icon to rename, or the delete button to remove it.