๐ finvader
Finance-aware sentiment analysis for Rust
VADER, re-tuned for the market โ financial lexicon, phrase rules, and catalyst detection for news headlines and market text instead of tweets.
๐ฏ Why finvader?
Generic VADER was calibrated for social media. On financial text it misfires in two directions:
| โ Generic VADER problem | ๐ฅ Example | finvader fix |
|---|---|---|
| Misses finance sentiment | "beats expectations", "cuts guidance", "going concern" โ score โ 0 | ๐ Financial lexicon + phrase rules |
| Misfires on neutral finance words | "gross margin", "cancer drug", "debt refinancing" โ scored negative | ๐ญ Neutral-override masking |
And it adds something VADER never had: ๐จ catalyst detection โ single events (FDA approval, buyout offer, index inclusion, bankruptcy) that permanently re-rate a stock and deserve to be surfaced on their own.
๐ Accuracy
On a hand-labeled set of 60 financial headlines:
| Analyzer | Correct signal | Accuracy | |
|---|---|---|---|
| generic VADER | 31 / 60 | 51.7% | ๐ฅ๐ฅ๐ฅ๐ฅ๐ฅโฌโฌโฌโฌโฌ |
| finvader | 60 / 60 | 100% | ๐ฉ๐ฉ๐ฉ๐ฉ๐ฉ๐ฉ๐ฉ๐ฉ๐ฉ๐ฉ |
๐ Quick start
[]
= "0.1"
use ;
let fv = new;
let s = fv.analyze;
assert!;
assert_eq!;
// Which terms drove the score:
for t in &s.triggers
๐ก Construct one
FinVaderand reuse it across calls โ it loads the lexicons once and isSend + Sync.
โ๏ธ How it works
Each input runs two parallel passes โ a masked base-VADER pass and a financial layer (phrases, gap-phrases, single words) โ then the two are blended, nudged by any catalyst, and clamped:
| Stage | What it does |
|---|---|
| ๐ก normalize | Lowercase, strip punctuation, keep market-text characters (-, %, $, ') |
| ๐ญ mask_for_base | Replace finance-neutral words (gross, cancer, debt, crude, vice, shareโฆ) with a placeholder before base VADER, so everyday valences never pollute the score |
| ๐งฉ phrase / gap / word passes | Match multi-word phrases (beats expectations), gap-tolerant pairs (beats โฆ expectations, up to 2 tokens apart), and single words โ consumed so nothing double-counts. up 45% / down 30% become magnitude-scaled moves |
| ๐ negation & boosters | failed to beat expectations flips ยท sharply missed amplifies ยท slightly missed softens ยท beat by 40% scales on magnitude |
| โ๏ธ blend | With financial terms present: 0.35 ร base + 0.65 ร financial; otherwise base VADER passes through untouched |
| ๐จ catalyst bonus | A detected event shifts the compound by ยฑ0.25 |
๐ Signals
compound maps to a discrete Signal:
| compound | Signal | |
|---|---|---|
>= 0.5 |
StronglyBullish |
๐ข๐ข |
>= 0.15 |
Bullish |
๐ข |
-0.15 .. 0.15 |
Neutral |
โช |
<= -0.15 |
Bearish |
๐ด |
<= -0.5 |
StronglyBearish |
๐ด๐ด |
๐จ Catalyst detection
Beyond the smooth sentiment score, finvader flags episodic-pivot events
and returns them as Option<Catalyst>:
| ๐ Bullish catalysts | ๐ Bearish catalysts |
|---|---|
| FDA approval / clearance | FDA rejection |
| Breakthrough therapy | Missed / failed endpoint |
| Met primary endpoint | Chapter 11 / Chapter 7 |
| Buyout / takeover / merger | Going concern |
| S&P 500 inclusion | SEC charges |
| Contract awards | Accounting fraud |
| Record quarter, beat-and-raise | Auditor resignation |
๐ Where it fits
finvader is the scoring core of a news-driven momentum alert pipeline:
โก Performance
Single-threaded, release build, cargo run --release --example bench
(Apple Silicon):
| Analyzer | Per headline | Throughput |
|---|---|---|
| generic VADER | 1.8 ยตs | ~570,000 / sec |
| finvader | 22.3 ยตs | ~45,000 / sec |
finvader does more work per call (masking + three match passes + catalyst detection) and still clears tens of thousands of headlines per second per core.
๐ Lexicon
Single-word and phrase valences are calibrated for market news, informed by
the Loughran-McDonald
financial sentiment research. Valences are on VADER's -4.0 ..= 4.0 scale.
๐งช Examples
๐ License
MIT ยฉ albyte-ai