CoolFace
Apppublic

Uris001/equity-research-platform

sourceHugging Facemitupdated 2mo agoView on Hugging Face
0likes
App README

<div align="center">

<br>

<img src="https://readme-typing-svg.demolab.com?font=Fira+Code&weight=700&size=27&pause=1000&color=60A5FA&center=true&vCenter=true&width=760&lines=%E2%9A%A1+AI-Powered+Equity+Research+Platform;Score+any+public+ticker+in+seconds;Live+Quant+%2B+OOS+Stat-Arb+%2B+Volatility+Cones" alt="Typing SVG" />

<br><br>

![Generation](https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.2) ![Embeddings](https://huggingface.co/BAAI/bge-small-en-v1.5) ![Dataset](https://huggingface.co/datasets/Uris001/equity-research-dataset) ![Gradio](https://gradio.app) ![FAISS](https://github.com/facebookresearch/faiss) ![Tests](tests/testlogic.py) [![License](https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge)](LICENSE) [![Space](https://img.shields.io/badge/๐Ÿค—Live_Demo-Running-purple?style=for-the-badge)](https://huggingface.co/spaces/Uris001/equity-research-platform)

<br>

Type any ticker โ€” S&P 500, Nasdaq, or global โ€” and get a full quant deep-dive in seconds: a transparent 0โ€“100 scorecard, an AI-written analyst note, two peer-discovery engines, a look-ahead-free pairs stat-arb backtest, and a 21-day volatility cone โ€” all from live market data.

<br>

Built around one principle: every number on screen is either real, validated, or explicitly labelled as neither.

<br>

</div>


๐ŸŽฏ The Problem & The Solution

A junior equity analyst spends hours per stock pulling prices, computing technical indicators, reading fundamentals, scanning sentiment, writing up a note, and finding comparable companies. That workflow is repetitive, slow, and inconsistent across analysts.

This project automates the entire loop with a data-science pipeline that spans every stage of the course โ€” synthetic data generation, EDA, embedding-based recommendation, LLM text generation, a trained sentiment classifier, and a live application โ€” tied together into one coherent product:

The analyst doesโ€ฆโ€ฆthe platform does it automatically
Pull prices + compute RSI / MACD / Bollinger / ATR / betayfinance live fetch โ†’ vectorised indicator engine
Read fundamentals (ROE, margins, growth, valuation)Pulled live (Yahoo โ†’ Finnhub fallback) โ†’ fundamental sub-score
Judge attractivenessTransparent 0โ€“100 heuristic scorecard โ†’ ๐ŸŸข Attractive / ๐ŸŸก Neutral / ๐Ÿ”ด Weak
Write the research noteMistral-7B-Instruct few-shot generation (deterministic template fallback)
Find comparable companiesFAISS cosine over the winning text embeddings (BGE-small, from winner.json) + a live-profile peer engine
Hunt market-neutral tradesEngleโ€“Granger cointegration screen + out-of-sample stat-arb backtest
Size the near-term risk21-day volatility cone โ€” realized ฯƒ, โˆšt scaling, honest uncertainty
What makes this version different: the platform is engineered to be defensible, not just impressive. The pairs backtest is look-ahead-free by construction and unit-tested for it; the return-prediction experiment that scored negative out-of-sample Rยฒ is disclosed on the card instead of dressed up as a forecast; and every tab carries a data-provenance badge (๐Ÿ“ก LIVE ยท ๐Ÿงช SYNTHETIC ยท ๐Ÿค– MODEL) so no synthetic number can masquerade as a real one.

๐Ÿ“‹ Table of Contents


๐Ÿ—บ End-to-End Workflow

mermaid
flowchart TD
    A["๐Ÿงช PART 1 โ€” Synthetic Data Generation<br/>Qwen2.5-1.5B-Instruct ยท 200 tickers ร— 10 sectors<br/>ร— event/technique mix ยท leakage-controlled = 10,000 notes"] --> B
    B["๐Ÿ“Š PART 2 โ€” Exploratory Data Analysis<br/>Quality audit ยท IQR outliers ยท 7 research questions<br/>feature engineering ยท text-vs-quant separability"] --> C
    C["๐Ÿงน Quality Gate<br/>drop short / low-diversity / failed generations<br/>โ†’ clean modeling corpus"] --> D
    C --> T
    D["๐Ÿง  PART 3 โ€” Embedding Benchmark<br/>MiniLM-L6-v2 ยท MPNet-base-v2 ยท BGE-small-en-v1.5<br/>(+ Tabular-PCA quant baseline) ยท intra-sim / silhouette / Davies-Bouldin"] --> E
    E["๐Ÿ† Winner: BAAI/bge-small-en-v1.5<br/>recorded in winner.json ยท FAISS IndexFlatIP (cosine)<br/>ticker & natural-language recommendation"] --> F
    T["๐Ÿ”ข Quant feature matrix<br/>synthetic fundamentals โ†’ winsorized z-scores<br/>SECTOR-NEUTRAL Value/Quality/Momentum factors"] --> H
    F["โœ๏ธ PART 4 โ€” Analyst-Note Generation<br/>Mistral-7B-Instruct-v0.2 ยท few-shot prompting<br/>ROUGE-L ยท BERTScore ยท Flesch ยท semantic sim ยท hallucination proxy"] --> H
    P["๐Ÿ”ฎ PART 6 โ€” Return-Model Evaluation<br/>real yfinance features ยท temporal split<br/>VERDICT: OOS Rยฒ < 0 โ†’ ship the VOLATILITY CONE instead"] --> H
    Q["๐Ÿ“ˆ Pairs Stat-Arb Engine<br/>formation/trading split ยท Engleโ€“Granger screen<br/>causal rolling z ยท next-bar execution ยท bootstrap CI"] --> H
    H["๐Ÿš€ PART 5 โ€” HuggingFace Space (Gradio 6)<br/>modular architecture ยท 26 unit tests ยท provenance badges<br/>6 tabs ยท zero runtime training ยท dark quant UI"]

    style A fill:#e0e7ff,stroke:#4338ca,color:#1e1b4b
    style B fill:#dcfce7,stroke:#16a34a,color:#052e16
    style C fill:#fef3c7,stroke:#d97706,color:#451a03
    style T fill:#fff7ed,stroke:#ea580c,color:#431407
    style D fill:#e0f2fe,stroke:#0284c7,color:#0c4a6e
    style E fill:#fce7f3,stroke:#db2777,color:#500724
    style F fill:#f3e8ff,stroke:#9333ea,color:#2e1065
    style P fill:#dbeafe,stroke:#2563eb,color:#0c1d57
    style Q fill:#cffafe,stroke:#0891b2,color:#083344
    style H fill:#e0f2fe,stroke:#0369a1,color:#0c4a6e
Two AI engines, one platform. A recommendation engine (embeddings + FAISS) finds similar stocks; a generation engine (Mistral-7B) writes the analyst note. Both are wrapped by a deterministic, finance-aware scorecard, extended by a look-ahead-free stat-arb backtester and an empirical volatility cone โ€” and everything that touches synthetic data says so on screen.

๐Ÿ”— How the Parts Connect

Nothing is an isolated exercise; every part is a dependency of the next.

  1. 1.Part 1 โ†’ Part 2. The synthetic generator produces ~10,000 notes across 200 tickers. Because the generator is a small instruction model, raw outputs need auditing โ€” so Part 2 (EDA) is the gate that measures quality and removes noise before modeling.
  1. 1.Part 2 โ†’ Part 3. The EDA defines the quality filters and engineers the tabular financial features that feed the factor model and the trained sentiment classifier.
  1. 1.Part 3 โ†’ Part 4 โ†’ App. Part 3 benchmarks three text-embedding models (MiniLM, MPNet, BGE-small) against a quant-PCA baseline, crowns BGE-small-en-v1.5 the measured winner โ€” recorded in winner.json, which the app reads at startup so the deployed encoder can never drift from the declared winner โ€” and builds the FAISS index the app reuses for narrative peer discovery. Part 4 validates the few-shot prompting strategy for Mistral-7B that the app reuses to write notes. Parts 3โ€“4 are the R&D; the app is the production deployment of their findings.
  1. 1.Honesty as an architectural rule. Two return-prediction experiments were run โ€” one on synthetic fundamentals (Part 3 ยง11), one on real market data (Part 6). Both scored out-of-sample Rยฒ โ‰ˆ 0 or below, and both are shelved, with the negative results documented in the app itself. The forward-looking views the platform does ship are the ones that survive scrutiny: the factor ranking (transparent methodology), the OOS pairs backtest (look-ahead-free), and the volatility cone (measured uncertainty).
Part 1 (generate) โ”€โ–ถ Part 2 (clean + engineer features)
                          โ”‚                          โ”‚
                          โ–ผ                          โ–ผ
                  text notes (โ‰ˆ10k)         tabular features
                          โ”‚                          โ”‚
                          โ–ผ                โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                 Part 3 (BGE + FAISS)    โ–ผ                          โ–ผ
                          โ”‚       Value/Quality/Momentum     sentiment classifier
                          โ”‚       (sector-neutral z-scores)  (the trained deliverable)
                          โ”‚                โ”‚                          โ”‚
                          โ”‚                โ”‚     ยง11 + Part 6 return predictors
                          โ”‚                โ”‚     โ†’ BOTH SHELVED (OOS Rยฒ โ‰ค 0),
                          โ”‚                โ”‚       disclosed in-app
                          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                   โ–ผ                  โ–ผ
        Part 4 (Mistral few-shot)  +  pairs stat-arb engine  +  volatility cone
                                   โ–ผ
                  Part 5 โ€” Gradio App (this Space, 6 tabs, 26 unit tests)

๐Ÿ“ฆ Upstream โ€” the Dataset (Parts 1 & 2)

This app is built on `Uris001/equity-research-dataset` โ€” ~10,000 analyst notes across 200 tickers and 10 sectors, generated with an instruction-tuned LLM under a leakage-controlled design, then audited and cleaned via a full EDA (quality, outliers, 7 research questions). The generation process and the EDA are documented in the [dataset card](https://huggingface.co/datasets/Uris001/equity-research-dataset).

One rule follows from this everywhere in the app: the corpus fundamentals are synthetic, so any panel built on them carries a ๐Ÿงช SYNTHETIC provenance badge, and no synthetic quantity is ever blended into a live-data number.


๐Ÿง  Part 3 โ€” Recommendation, Embeddings & the Quant Layer

๐Ÿ““ Notebook: 03_embeddings_recommendation.ipynb

The goal: turn each stock into a vector, so "find me similar stocks" becomes a geometry problem โ€” then extend the same feature work into a systematic factor model and a trained classifier.

3.1 โ€” Three-model embedding benchmark

ModelTypeDimHypothesis
all-MiniLM-L6-v2text2vec384Fast baseline โ€” best speed/quality ratio
all-mpnet-base-v2text2vec768Gold standard โ€” larger dim, best semantic quality?
BAAI/bge-small-en-v1.5text2vec384Retrieval-tuned challenger in MiniLM's size class
Tabular PCAquant baseline (not an embedding model)10How much structure do the numbers alone recover?

Full-document coverage via chunk + mean-pool (naรฏve encode() silently truncates at ~250 words), and a composite quality metric (intra-sector cosine + silhouette + inverted Davies-Bouldin):

๐Ÿ† `BAAI/bge-small-en-v1.5` wins the measured composite (intra-sector cosine + silhouette + inverted Davies-Bouldin) and is recorded in winner.json โ€” the app reads that file at startup. Winning vectors are L2-normalised and indexed with FAISS `IndexFlatIP` (inner product = cosine on unit vectors) for sub-millisecond search.

3.1b โ€” Does the recommender actually recommend? (measured, not asserted)

The deployed index was validated two ways โ€” the sector label is never an input (the engine sees only note text), so recovering sector structure is genuine validation, not circularity:

Domain spot checks (pre-stated expectations, then inspected output):

QueryTop narrative peers returnedVerdict
NVDAAMD ยท INTC ยท ORCL ยท INTU (+ RGTI โ€” quantum, pulled in by shared "chips/compute/AI" language)โœ… semis/AI desk
JPMMS ยท GS ยท SQ ยท KKRโœ… financials desk
XOMCVX ยท VLO ยท DVN ยท OXY + the XLE energy ETFโœ… oil majors
LLYPFE ยท AMGN ยท ABBV + the XLV healthcare ETFโœ… pharma

Universe-wide metric โ€” querying every one of the 200 tickers and scoring its top-5 neighbours:

Sector precision@5 = 0.62 vs a โ‰ˆ 0.14 random-sector prior โ€” a same-sector peer is ~4.4ร— more likely than chance. Strongest where the language is distinctive (Energy 0.90, Healthcare 0.72, Technology 0.72); weakest for Materials (0.07) and Communication Services (0.03) โ€” both have only 6 names in the universe (few same-sector candidates exist), and their notes read like adjacent sectors (GOOGL/META are labelled Communication Services but discussed as tech). That failure mode is the embedding faithfully reflecting the notes' language colliding with a rigid sector taxonomy โ€” disclosed here rather than hidden. KMeans + DBSCAN independently recover the sector taxonomy and flag the pre-profit Space/Quantum names as density outliers โ€” an unsupervised confirmation of the EDA.

3.2 โ€” Cross-Sectional Factor Model (the Universe Screener)

Every ticker is scored on three classic factors (Fama-French / AQR lineage) via winsorised (1/99%), sign-adjusted, cross-sectional z-scores:

FactorIntuitionInputs (sign)
Valuecheap stocks outperformNTM P/E (โˆ’), EV/EBITDA (โˆ’)
Qualityprofitable, low-leverage firms compoundgross margin (+), FCF yield (+), analyst consensus (+), debt/equity (โˆ’)
Momentumrecent strength persists52-week position (+), implied upside (+), revenue growth YoY (+)

New in this version โ€” sector-neutral scoring (default). Global z-scores make the Value factor a hidden sector bet (short tech, long energy). The screener now standardizes each input within its sector (with a global fallback for tiny groups), so "cheap" means cheap versus its own sector. The effect is unit-tested: on a synthetic universe with deliberately different sector valuation levels, sector-mean Value spread drops from >0.5ฯƒ to <0.15ฯƒ.

3.3 โ€” Return predictor on synthetic fundamentals (ยง11 โ€” shelved)

Pre-registered ship rule: deploy only if OOS Rยฒ โ‰ฅ 0.05. Verdict: shelved โ€” synthetic fundamentals carry no real forward signal (OOS Rยฒ โ‰ˆ 0 or below). In this version the shelving is complete: no synthetic-data return model is loaded anywhere in the app โ€” no hidden "ML estimate" panels.

3.4 โ€” Sentiment classifier (ยง12 โ€” the trained deliverable)

A multimodal bake-off (TF-IDF + SVD text channel โŠ• engineered features โŠ• standardized fundamentals) across four model families under one shared CV split, scored on macro-F1:

๐Ÿ† Winner: Logistic Regression โ€” test macro-F1 = 0.618 (chance = 0.333), beating the tree ensembles and single-channel baselines. It runs live in the Document Research tab with its provenance disclosed on-screen: it was trained on this project's synthetic corpus, so agreement with FinBERT is a consistency check between models, not independent validation on real market text.

โœ๏ธ Part 4 โ€” Analyst-Note Generation

๐Ÿ““ Notebook: 04_generation.ipynb

Benchmarks the app's runtime generator โ€” `mistralai/Mistral-7B-Instruct-v0.2` โ€” across zero-shot / one-shot / few-shot prompting on a stratified test set, with a five-metric evaluation suite:

MetricMeasures
ROUGE-Llongest-common-subsequence overlap vs reference
BERTScore-F1semantic similarity via contextual embeddings
Flesch Reading Easereadability
Semantic Coherencecosine of generated vs reference (sentence-transformer embeddings)
Hallucination Proxyticker grounded? plausible length? no URLs? sector keywords?

Few-shot wins the composite, and that exact strategy ships in the app. In production the model is served via the HF Inference API (no 7B weights in the Space) behind a two-tier fallback: Mistral-7B โ†’ deterministic template (Mistral is the only LLM) โ€” the note box is never empty, even without an HF_TOKEN, on a rate limit, or during a cold start โ€” and every note is labelled with the tier that actually wrote it, so a template can never masquerade as an LLM.


๐ŸŽฏ The Heuristic Scorecard

Every ticker gets a transparent 0โ€“100 score. It is deliberately presented as what it is โ€” a documented rule-based rubric, not a fitted or validated predictive model โ€” and its bands are named accordingly (no implied trading calls):

Composite = 0.40 ยท Technical  +  0.40 ยท Fundamental  +  0.20 ยท Market Signal

  Technical     = 0.30ยทRSI + 0.30ยทMACD + 0.15ยทBB%B + 0.15ยทMomentum + 0.10ยทVolume
  Fundamental   โ”Œ profitable : 0.30ยทROE + 0.25ยทNetMargin + 0.25ยทRevGrowth + 0.20ยทP/E
                โ”” pre-profit : 0.55ยทRevGrowth + 0.30ยทP/S + 0.15ยทMarketCap
  Market Signal = analyst target-price premium + recommendation mean
                  (3-month momentum ONLY as a disclosed fallback when there is
                   no analyst coverage โ€” it is already inside Technical, so
                   blending it unconditionally would double-count it)
ScoreBand
โ‰ฅ 65๐ŸŸข ATTRACTIVE
40 โ€“ 64๐ŸŸก NEUTRAL
< 40๐Ÿ”ด WEAK
Pre-profit awareness is the key design choice โ€” loss-making Space/Quantum names have structurally NaN profitability metrics, so pushing them through a P/E-based rubric would be nonsense. The platform routes them through a revenue-growth + price-to-sales + market-cap track instead. Both tracks are unit-tested to stay within [0, 100] even on all-NaN input.

๐Ÿ–ฅ Part 5 โ€” The Live Application

๐Ÿ“„ Entry point: app.py โ€” this Hugging Face Space (modular architecture, see Engineering & Tests)

A six-tab Gradio app with a dark quant UI, reading the dataset and models directly from the Hub at runtime. Every tab carries a provenance badge.

TabWhat it doesProvenance
๐Ÿ“Š Analyze Any StockLive deep-dive on any ticker: scorecard gauge, technical + fundamental tables, 1-year chart, AI analyst note, and two peer engines โ€” ๐Ÿ”— live-profile (cosine over 11 standardized live features) and ๐Ÿงฌ research-narrative (FAISS over the winning BGE-small note embeddings).๐Ÿ“ก LIVE
๐ŸŒ Universe & Factor ScreenerInstant, dataset-backed browse of the full 200-ticker universe ranked by Value / Quality / Momentum with live weight sliders, a sector-neutral toggle, corpus sentiment mix, and a one-click live deep-dive of the #1 pick.๐Ÿงช SYNTHETIC inputs, disclosed
๐Ÿ“‘ Analyst TerminalThe single-screen research dossier โ€” ~60 metrics: valuation, margins, health, growth, dividends, analyst targets & consensus, ownership & short interest, risk levels, trailing returns, profile, live news. Layered sources (history โ†’ fast_info โ†’ .info โ†’ Finnhub) keep cards populated when Yahoo rate-limits cloud IPs.๐Ÿ“ก LIVE
๐Ÿง  Document ResearchPaste or upload a .txt/.pdf โ€” FinBERT and our trained classifier score it side-by-side with an agreement read (provenance disclosed), plus summary, key figures & event signals, sentence-level evidence, and an AI research brief.๐Ÿค– MODEL
๐Ÿ“ˆ Pairs TradingCointegration-screened stat-arb with a genuinely out-of-sample backtest โ€” see the next section.๐Ÿ“ก LIVE
๐Ÿ”ฎ Price ScenariosA 21-day empirical volatility cone โ€” with the negative-Rยฒ return-model result disclosed on the card.๐Ÿ“ก LIVE

Each tab ships one-click Quick Starters (e.g. AAPL, TSLA, IONQ).


๐Ÿ“ˆ Pairs Trading โ€” a Look-Ahead-Free Backtest

The single most common flaw in amateur stat-arb backtests is look-ahead bias: computing the z-score from full-sample statistics, so the entry signal at time t "knows" the future mean it will revert to. This platform's backtest is engineered โ€” and unit-tested โ€” to be free of it:

      โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ FORMATION (60%) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”คโ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ TRADING (40%) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
      pair selection (Engleโ€“Granger ADF on spread)     the ONLY window that is reported
      hedge ratio ฮฒ (OLS on log prices)                trailing 60-day z-score, shifted
      OU half-life                                     one bar โ†’ strictly causal
                                                       positions execute NEXT bar
                                                       P&L net of costs (10 bps/side)
  • โ€”Selection without peeking โ€” the hedge leg is chosen among FAISS-suggested peers by formation-window correlation + cointegration only. A test proves that corrupting the trading window cannot change any formation metric.
  • โ€”Causal signals โ€” z_t uses the mean/std of the previous 60 bars (window shifted by one). A test proves that perturbing future prices cannot change past z-scores, and that a signal formed on the final bar earns exactly zero (next-bar execution).
  • โ€”Honest statistics โ€” OOS Sharpe ships with a bootstrap 90% confidence interval; pairs that fail the Engleโ€“Granger 5% critical value (โˆ’3.34) are labelled NO TRADE and their stats greyed out; low trade counts and weak correlations trigger explicit low-confidence banners.
  • โ€”Validated math โ€” the pure-numpy ADF t-statistic matches statsmodels.adfuller to 1e-6 in tests.
Example of the honesty working as designed: on a recent KO/PEP run the formation ADF was โˆ’2.31 (fails the โˆ’3.34 bar) โ†’ the app shows NO TRADE, and the OOS Sharpe's CI of [โˆ’0.68, +3.07] straddles zero โ€” which is exactly what an unvalidated pair should look like.

๐Ÿ”ฎ Part 6 โ€” From Return Model to Volatility Cone

๐Ÿ““ Notebook: price_predictor.ipynb ยท Artifact: price_scenario_model.joblib

Part 6 asks: can a model predict the 21-day forward return from real market data? A 186-ticker, ~27k-row weekly panel of strictly-trailing technical features + fundamentals, a temporal split (train โ‰ค 12 months ago, test = last 12 months, no shuffle), three regressors, and a pre-registered ship rule (deploy if OOS Rยฒ โ‰ฅ 0.05):

ModelOOS RยฒMAERMSEHit rate
Ridge (best)โˆ’0.0260.0990.14553.5%
HistGradientBoostingโˆ’0.0500.0980.14754.4%
GradientBoostingโˆ’0.1510.1000.15453.0%
โš–๏ธ Verdict: no model clears the bar โ€” so no point forecast ships. Publishing bull/bear price targets from a negative-Rยฒ model would be decorative complexity. Instead, the ๐Ÿ”ฎ tab shows the defensible object:

The volatility cone. The ticker's own realized daily volatility (trailing 252d), scaled by โˆšt under a zero-drift lognormal model:

upper_t = Pโ‚€ ยท exp(+1.5ยทฯƒยทโˆšt)        21-day band โ‰ˆ ยฑ11% for a defensive name (KO)
lower_t = Pโ‚€ ยท exp(โˆ’1.5ยทฯƒยทโˆšt)                     โ‰ˆ ยฑ19% for a high-beta name (TSLA)

The card states plainly why there is no expected-return line โ€” "a Ridge regression was evaluated for this horizon and scored OOS Rยฒ = โˆ’0.03" โ€” turning a negative result into demonstrated methodology. Knowing what doesn't predict is part of the analysis.


๐Ÿงช Engineering & Tests

The app is a modular package (one concern per module) rather than a single-file script:

What the tests pin down (tests/test_logic.py):

PropertyHow it's tested
ADF statistic is correctmatches statsmodels.adfuller (lag-0, constant) to 1e-6 on AR(1) fixtures
z-score is causalperturbing future values cannot change past z; current bar excluded from its own stats
No look-ahead in executiona signal formed on the final bar earns exactly 0 (next-bar rule)
Formation/trading isolationcorrupting the OOS window leaves ฮฒ / ADF / corr unchanged
Cone mathโˆšt widening, closed-form terminal width, k-scaling, zero-drift midline
Scorecard safetybounds hold on the all-NaN pre-profit path (IONQ-style names)
Factor signs & neutralitylow P/E โ‡’ higher Value; sector-neutral scoring removes the sector bet
Reproducibilitybootstrap CI deterministic under the project seed (42)

Robustness & degraded modes: no HF_TOKEN โ†’ deterministic template (note box never empty) ยท Yahoo blocked โ†’ Finnhub โ†’ history-derived cards ยท FAISS artifacts missing โ†’ narrative peers disabled gracefully ยท long documents โ†’ token-window chunking + a sentence cap with an on-screen notice ยท the ~40-fetch live peer index builds in a background thread at startup so the first click is fast. Secrets are read from the environment only and never logged. No GPU anywhere โ€” free CPU tier.


๐Ÿš€ How to Use the App

Live Space: **huggingface.co/spaces/Uris001/equity-research-platform**

Tab 1 โ€” ๐Ÿ“Š Analyze Any Stock

Type a ticker (AAPL, NVDA, IONQ, โ€ฆ) โ†’ Analyze โ†’ scorecard + band, technical/fundamental breakdown, price chart, AI note, and the two peer tables.

Tab 2 โ€” ๐ŸŒ Universe & Factor Screener

Drag the Value / Quality / Momentum sliders (updates live), toggle sector-neutral, filter sectors, then ๐Ÿ”ฌ Deep-Dive #1 Pick to pull a full live dossier on the top name.

Tab 3 โ€” ๐Ÿ“‘ Analyst Terminal

Type a ticker โ†’ Pull Full Dossier โ†’ ~60 metrics + chart + live news on one screen.

Tab 4 โ€” ๐Ÿง  Document Research

Paste text or upload a .txt/.pdf โ†’ Analyze Document โ†’ dual-model sentiment with agreement read, summary, key figures & event signals, sentence-level evidence, AI research brief.

Tab 5 โ€” ๐Ÿ“ˆ Pairs Trading

Enter a ticker (optionally a hedge leg) โ†’ Run Stat-Arb โ†’ cointegration screen, causal signal, and the out-of-sample backtest with its bootstrap CI. Try KO/PEP, GS/MS, XOM/CVX.

Tab 6 โ€” ๐Ÿ”ฎ Price Scenarios

Type a ticker โ†’ Project Cone โ†’ the 21-day โˆšt volatility cone, terminal band levels, and the disclosed return-model evaluation.

Tip: generation needs an HF_TOKEN Space secret to call Mistral. Without it the app still runs end-to-end (deterministic template note, clearly labelled).

๐Ÿ›  Tech Stack

ComponentTechnologyRole in the pipeline
Synthetic generationInstruction-tuned LLM (Qwen-class)Part 1 โ€” ~10,000 synthetic notes, 200 tickers
Embedding modelBAAI/bge-small-en-v1.5Part 3 โ€” measured winner of the 3-model benchmark (winner.json)
Generation modelMistral-7B-Instruct-v0.2Part 4 โ€” few-shot notes via HF Inference API
Sentiment classifierLogReg (multimodal), macro-F1 = 0.618Part 3 ยง12 โ€” trained deliverable, provenance disclosed in-app
Document sentiment`ProsusAI/finbert`App โ€” pasted/uploaded text, token-window chunking
Factor modelSector-neutral Value/Quality/Momentum z-scoresUniverse Screener โ€” full 200-ticker ranking, instant
Stat-arb engineEngleโ€“Granger ยท formation/trading split ยท causal z ยท bootstrap CIPairs Trading โ€” look-ahead-free OOS backtest
Risk viewRealized-vol โˆšt cone (zero drift)Price Scenarios โ€” honest uncertainty, negative-Rยฒ model disclosed
Similarity searchFAISS IndexFlatIP + NumPy cosineNarrative + live-profile peers
Market datayfinance (+ Finnhub fallback, curl_cffi session)Live history & fundamentals, cloud-IP resilient
TechnicalsRSI ยท MACD ยท Bollinger ยท ATR ยท BetaComputed from raw OHLCV
Testingpytest (26 tests) + statsmodels cross-validationCorrectness of every pure-math component
UI frameworkGradio 6Dark quant theme, 6 tabs, Quick Starters
PlatformHuggingFace Spaces โ€” CPU BasicReads dataset + models from the Hub

โš ๏ธ Limitations & Disclaimer

  • โ€”Not financial advice. This is an educational data-science project. Do not trade on its output.
  • โ€”The scorecard is a heuristic. Its weights and thresholds are documented rules, not fitted parameters โ€” it is labelled on-screen as "not a validated predictive signal," and its bands deliberately avoid buy/sell language.
  • โ€”The factor screener's inputs are synthetic (the project corpus), disclosed on the tab. The ranking methodology โ€” winsorized, sector-neutral cross-sectional z-scores โ€” is the deliverable; the deep-dive pulls real live data.
  • โ€”The pairs backtest is honest but still simplified โ€” no slippage or borrow costs, IID bootstrap (ignores autocorrelation), single fixed formation split. All stated in the UI caveats.
  • โ€”Near-term return prediction failed our ship rule twice (synthetic ยง11 and real-data Part 6, both OOS Rยฒ โ‰ค 0) โ€” which is why the app shows uncertainty cones, factor ranks and cointegration screens instead of price forecasts.
  • โ€”ETFs & non-equities lack per-company fundamentals โ€” their fundamental sub-score falls back to neutral defaults and is indicative only.

๐Ÿ‘ค Author

<table> <tr> <td> <b>Uri Sivan</b><br> Introduction to Data Science ยท Reichman University<br> Final Project โ€” Synthetic Data ยท EDA ยท Embeddings ยท Generation ยท Classifier ยท Stat-Arb ยท HuggingFace Spaces<br><br> <a href="https://huggingface.co/Uris001">๐Ÿค— HuggingFace</a> &nbsp;ยท&nbsp; <a href="https://huggingface.co/spaces/Uris001/equity-research-platform">๐Ÿš€ Live Space</a> &nbsp;ยท&nbsp; <a href="https://huggingface.co/datasets/Uris001/equity-research-dataset">๐Ÿ“ฆ Dataset</a> </td> </tr> </table>


<div align="center">

<br>

If you found this useful, consider leaving a โญ on the Space!

<br>

Built with โค๏ธ using

๐Ÿค— HuggingFace &nbsp;ยท&nbsp; ๐Ÿ“ˆ yfinance &nbsp;ยท&nbsp; ๐Ÿง  BGE-small &nbsp;ยท&nbsp; ๐Ÿค– Mistral-7B &nbsp;ยท&nbsp; ๐Ÿ”Ž FAISS &nbsp;ยท&nbsp; ๐ŸŸฉ Gradio

<br>

<br>

</div>