Skip to content

Latest commit

 

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CatalystLens

An evidence-checked financial catalyst research baseline that connects news to measurable market reactions.

CI GitHub Pages Python FastAPI PEFT

CatalystLens market research workspace

CatalystLens answers a concrete market question: which company-specific events plausibly explain an unusual price move?

The system aligns time-stamped synthetic news with price, benchmark, and volume series; ranks pre-labelled candidate catalysts; computes an event study; produces a citation-checked impact brief; and exposes the processing trace. It runs with a deterministic lexical baseline by default and can optionally serve a Hugging Face model with a PEFT/LoRA adapter.

Implemented scope: the default application path uses a three-asset synthetic fixture and lexical relevance ranking. It does not claim vector retrieval or production RAG. Generated citation IDs are validated against retrieved evidence, and unsupported or irrelevant requests trigger a safe abstention.

All issuers, news, prices, metrics, and claims in this repository are synthetic. They exist to make the engineering workflow reproducible. CatalystLens does not provide investment advice or claim live-market performance.

What the demo does

Choose one of three synthetic assets and ask a market-impact question. CatalystLens returns:

  • ranked, pre-labelled catalysts classified as guidance, contract, credit, rating, regulation, or product news;
  • the initiating and reinforcing sources, including short evidence excerpts;
  • cumulative abnormal return relative to the asset’s benchmark;
  • event-day volume z-score and post-event volatility change;
  • a cited narrative generated by the deterministic baseline or a locally served LoRA adapter;
  • explicit citation-validation and abstention state;
  • processing details for fixture loading, retrieval, event study, and citation-ID validation.

The UI is a market-research workstation rather than a general chat screen: the price response, benchmark, catalyst timing, and evidence are visible at the same time.

System architecture

synthetic news fixture ─> lexical relevance filter ─> evidence selection
price / volume fixture ──────────────────────────────────┐
                                                        ├─> event study
benchmark fixture ───────────────────────────────────────┘
                                                        │
                                                        ├─> grounded impact brief
local base model + optional LoRA adapter ────────────────┘
                                                        │
                         FastAPI <─ typed response ──────┤
                            │                           │
                            ├─ /health                  ├─ evidence register
                            ├─ /metrics                 └─ validation trace
                            └─ structured request logs

The static web demo remains usable without the API. When NEXT_PUBLIC_API_BASE_URL is set, research requests are sent to FastAPI.

Quant methodology

For asset return rᵢ,t, benchmark return rₘ,t, and an estimated beta βᵢ, abnormal return is:

ARᵢ,t = rᵢ,t − βᵢ rₘ,t
CARᵢ,[−1,+3] = Σ ARᵢ,t

The current deterministic fixture stores beta and computes CAR over the configured event window. Volume shock is the event-day volume relative to the pre-event mean and population standard deviation:

volume z-score = (event volume − pre-event mean) / pre-event standard deviation

Volatility change compares the standard deviation of returns in the reaction window with the pre-event sample. These calculations are deliberately small and inspectable; a production implementation would estimate the market model on a longer clean window, test alternative benchmarks, account for overlapping events, and report confidence intervals.

AI and fine-tuning

The default generator is extractive and deterministic. Fixture narratives are stored as claims with explicit evidence IDs. Every non-abstaining sentence must cite an ID present in the retrieved evidence set; otherwise the service replaces it with an abstention. This validates citation presence and referential integrity, not semantic entailment.

The optional model path uses:

  • Qwen2.5-0.5B-Instruct as the laptop-friendly default base model;
  • Hugging Face Transformers for local inference;
  • PEFT LoRA with rank 16, alpha 32, and dropout 0.05;
  • instruction examples for catalyst attribution, quantification, citation, uncertainty, and abstention;
  • a separate validation split and a fixed random seed.

When an adapter exists at artifacts/catalyst-lora and CATALYSTLENS_MODEL_PROVIDER is set to huggingface, the API loads it automatically. If the adapter is absent, it serves the configured base model and identifies that state in the response.

The training samples are intentionally synthetic and small. They demonstrate the complete fine-tuning and serving path; they are not evidence of production alpha or broad market generalisation.

API

Primary endpoints:

Method Endpoint Purpose
GET /health Service, model, and dataset readiness
GET /api/v1/market-assets Available asset and benchmark metadata
POST /api/v1/market-analyze Catalyst attribution and event-study response
GET /metrics Prometheus-format request counters and p95 latency
GET /docs Interactive OpenAPI documentation

Example request:

curl -X POST http://localhost:8000/api/v1/market-analyze \
  -H 'Content-Type: application/json' \
  -d '{
    "asset_id": "astr",
    "question": "Did guidance explain the unusual price and volume move?",
    "event_id": "astr-guidance"
  }'

Abbreviated response:

{
  "asset_id": "astr",
  "ticker": "ASTR",
  "summary": "The move is most consistent with a guidance-led re-rating [astr-guidance].",
  "metrics": {
    "cumulative_abnormal_return": 6.5,
    "volume_z_score": 4.29,
    "volatility_change_pct": 405.1,
    "beta": 1.18,
    "event_window": "[-1, +3]"
  },
  "evidence": [
    {
      "id": "astr-guidance",
      "category": "Guidance",
      "source": "Asteron investor update",
      "confidence": 94
    }
  ],
  "model_provider": "extractive",
  "citation_validation": {
    "valid": true,
    "cited_ids": ["astr-guidance"],
    "unsupported_ids": [],
    "uncited_claim_count": 0,
    "abstained": false
  }
}

Exact calculated values are returned by the current fixture and may change when the synthetic series is revised.

Run locally

Requirements:

  • Node.js 22.13 or newer
  • Python 3.11–3.14
  • Docker Desktop only if using the full stack

Install:

npm ci
python3 -m venv .venv
.venv/bin/python -m pip install -e './api[dev]'
cp .env.example .env

Start the API:

.venv/bin/uvicorn app.main:app --app-dir api --reload --port 8000

Start the web app in another terminal:

npm run dev

Open http://localhost:3000 and the API documentation at http://localhost:8000/docs.

One-command local stack

docker compose up --build

This starts the web app on http://localhost:8080 and FastAPI on http://localhost:8000. The default stack deliberately contains no unused vector database: retrieval is the documented deterministic lexical baseline.

Train and serve the adapter

Install the training dependencies:

.venv/bin/python -m pip install -e './api[training]'
cd api
../.venv/bin/python training/train_lora.py

Then set:

CATALYSTLENS_MODEL_PROVIDER=huggingface
CATALYSTLENS_ADAPTER_PATH=artifacts/catalyst-lora

Restart the API. The health and analysis responses expose whether the loaded generator is extractive, huggingface-base, or huggingface-lora.

For a quick qualitative check:

cd api
../.venv/bin/python training/infer_adapter.py

Evaluation and tests

Run the complete local checks:

npm run lint
npm run build
.venv/bin/ruff check api
cd api
../.venv/bin/python -m pytest tests
../.venv/bin/python -m evaluation.evaluate

The current synthetic regression suite contains 12 answerable paraphrases and six deliberately irrelevant questions. It reports:

Metric Result
Event recall at 2 1.000
Mean reciprocal rank 1.000
Evidence precision 0.750
Impact-direction accuracy 1.000
Citation-ID validity 1.000
Safe-abstention accuracy 1.000

These are regression checks on 18 controlled fixture cases, not performance estimates for real news or prices. CI treats retrieval, citation validity and safe abstention as release gates.

CI runs frontend lint/build, Python lint/tests/evaluation, and three container builds on each push and pull request. The Pages workflow deploys the static demonstration from main.

Reliability and safety

  • Unknown asset IDs return 404 rather than silently broadening the search.
  • Pydantic validates identifiers, questions, and response bounds.
  • Every request receives an X-Request-ID.
  • Logs are structured JSON and include route, status, and duration.
  • Prometheus-format metrics expose request count, failure count, and rolling p95 latency.
  • Every generated sentence must cite an evidence ID returned for that request.
  • Unsupported citations, uncited sentences and irrelevant questions return a safe abstention.
  • The interface labels its dataset synthetic and does not emit buy, sell, target-price, or portfolio-allocation advice.

For real feeds, add source licensing, exchange-calendar alignment, corporate-action adjustment, duplicate-story clustering, delayed-data controls, and secrets management before deployment.

Repository map

app/                         React market-research interface
components/                  reusable UI primitives
api/app/main.py              FastAPI routes and operational middleware
api/app/market.py            event-study calculations and catalyst ranking
api/app/generation.py        deterministic and local LoRA generators
api/data/market_events.json  synthetic news, price, benchmark, and volume data
api/app/grounding.py         citation-ID validation and fail-closed abstention
api/evaluation/              retrieval, citation, direction, and abstention gates
api/training/                PEFT/LoRA training and inference scripts
api/tests/                   API, market-metric, and compatibility tests
.github/workflows/           CI and GitHub Pages deployment
compose.yaml                 local web and API stack
Dockerfile*                  lightweight API, full ML API, and web images

Public disclosure boundary

This showcase contains source code, synthetic fixtures, tests, documentation, and generated interface assets only. It contains no credentials, customer or employer data, licensed market data, trained model weights, private endpoints, or production configuration. .env.example documents variable names with non-sensitive local defaults; real environment files remain untracked.

Scope

CatalystLens demonstrates research engineering and model operations, not a trading strategy or a production RAG system. It does not backtest a portfolio, model transaction costs, or claim that news causally determines returns. Its event attribution is a transparent fixture baseline: evidence and benchmark-relative reaction are shown together so a human can challenge the conclusion.

A production roadmap would add licensed live news and adjusted prices, point-in-time ticker mapping, multi-event deconfliction, learned relevance scoring, confidence calibration, persistent research sessions, and monitoring by catalyst class.

About

Evidence-checked financial catalyst research baseline with FastAPI, event studies, safe abstention, and optional local LoRA

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages