Analyzing Financial Market Sentiment from RSS Feeds Using Gemini and Seaborn
Gemini plus Pydantic turns financial RSS into structured sentiment, visualized with Seaborn; results show only 40% agreement with keyword scoring.
Key Takeaways
- The article tests Gemini 3.5 Flash-Lite for financial news sentiment analysis from RSS feeds and compares it with a keyword-based baseline.
- The LLM and keyword methods agreed only 40% of the time, suggesting the model interprets market headlines more contextually than rule-based scoring.
- Strict Pydantic schemas were essential for reliable model output, enforcing valid sentiment scores, labels, tickers, sectors, and confidence ratings.
- The pipeline included practical safeguards such as cached RSS ingestion, centralized configuration, and a hard cap on API calls to control cost and rate-limit risk.
- The model produced nuanced sentiment records, such as neutral scores with detailed key drivers, showing value beyond simple keyword matching.
Meta description: A hands-on test of Gemini 3.5 Flash-Lite for financial news sentiment, using Pydantic schemas, RSS feeds, and Seaborn charts against a keyword baseline.
Tags: Gemini API, financial sentiment analysis, Pydantic, RSS feeds, Seaborn
Featured image: an abstract, friendly illustration of news headlines flowing into a glowing chart, no people, no logos, no text.
Anyone who tracks markets knows the feeling: a headline crosses the wire, and you have seconds to decide whether it is noise or signal. Keyword lexicons, the old standby for automated sentiment scoring, are cheap and fast, but they struggle with context. A mention of falling bond yields can read as panic or as relief, and a bag-of-words model cannot tell the difference.
That gap is what prompted an experiment testing whether a modern generative language model, wrapped in strict Pydantic typing, could pull accurate structured sentiment out of live RSS feeds without blowing through an API budget. The test targeted a snapshot date of 2026-09-29 and compared model output against a legacy keyword baseline.
What the pipeline actually did
The setup was an end-to-end system: ingest live articles from financial RSS endpoints, submit structured evaluation payloads to Gemini 3.5 Flash-Lite, aggregate rolling market indicators, and render dashboards with Seaborn. Rather than trusting fragile regular expressions or unconstrained string output, the architecture enforced schema compliance at the API boundary and capped API calls to prevent surprise billing.
After processing the ingestion window, the audit logs showed:
- total_articles_analyzed: 15
- average_market_sentiment: 0.15
- top_bullish_ticker: BTC
- baseline_agreement_rate: 0.4
- dominant_theme: Macro interest rate trajectory, corporate earnings resilience, and semiconductor demand
That 0.4 agreement rate is the headline number for anyone weighing LLM extraction against rule-based scoring. The model and the keyword baseline agreed less than half the time, which suggests the two approaches are reading the same headlines very differently.
Building the ingestion layer
The first instinct was to write custom XML parsing loops with standard library tools. That failed quickly. Publishers like Yahoo Finance, CNBC, and Reuters format timestamps, author tags, and summary HTML inconsistently, which introduced high variance and parsing errors.
The pivot was to feedparser, which normalizes RSS and Atom formats into a unified dictionary structure. A centralized configuration class handled logging, environment settings, and execution parameters. The `NewsFeedIngester` class iterated through target endpoints, extracted headline text, and cached raw payloads locally before any model interaction. Caching matters here: it prevents redundant network calls during iterative testing and leaves an immutable audit trail of the exact news state at ingestion time.
Running the ingester across three configured endpoints pulled 24 raw articles, a batch ready for sentiment analysis.
Why Pydantic mattered more than the prompt
The harder problem was getting Gemini to return something parseable. Prompting for generic JSON produced severe variance: the model would wrap output in markdown code fences or add conversational preamble, triggering parsing exceptions. The fix was defining strict data contracts with Pydantic v2 combined with Google's modern GenAI SDK.
The `ArticleSentimentRecord` schema bound every field to a constraint. `sentiment_score` was bounded between -1.0 and 1.0, `confidence_rating` between 0.0 and 1.0, and `sentiment_label` restricted to a `Literal` of "bullish", "bearish", or "neutral". A field validator rounded sentiment scores to four decimal places. The schema also captured `asset_ticker`, `sector`, and a list of `key_drivers`.
Binding that schema directly to the model request meant every returned payload conformed to expected numerical bounds, ticker formats, and categorical labels. The model name was pinned to `gemini-3.5-flash-lite`, and the configuration capped `MAX_API_CALLS` at 15.
Cost control as a design constraint
Live news feeds plus LLM calls equals rate-limit and billing risk. The `GeminiSentimentAnalyzer` class carried an explicit API call counter. Once the evaluation budget hit the configured limit, the analyzer halted further calls and logged its status, protecting against runaway spend while preserving a representative sample.
The run hit that ceiling exactly: a warning logged that the API call limit of 15 had been reached, and the checkpoint recorded 15 API calls made, 15 records generated. No calls were wasted, and no budget was exceeded.
The prompt itself asked the model to extract the primary impacted ticker or macro category (examples given included AAPL, TSLA, SPY, BTC, FED, MSFT, NVDA), the market sector, a sentiment score, a confidence rating, a categorical label, and key drivers. The system instruction cast the model as a senior quantitative financial analyst.
What the records looked like
The generated audit records show granular structure. One example: a Yahoo Finance article titled "Ennis (EBF) Grows Sales but Earns Less. Are Legal Items Hiding a Better Business?" was scored with an `asset_ticker` of EBF, sector Finance, `sentiment_score` of 0.0, `confidence_rating` of 0.75, and a neutral label. Its key drivers captured sales growth, lower earnings from legal items, and the possibility that underlying business strength was obscured by one-off expenses.
That is a genuinely nuanced read. A keyword system seeing "Grows Sales" and "Earns Less" in the same headline would likely land somewhere arbitrary. The model split the difference and explained why.
A second record involved a Strive CEO comment on Bitcoin, which was tagged with BTC as the top bullish ticker, consistent with the aggregate finding that BTC led bullish sentiment across the batch.
What this means if you are building something similar
Three practical takeaways stand out.
First, schema enforcement is not optional. If you are feeding LLM output into a downstream system, Pydantic-style validation at the API boundary removes an entire class of runtime failures. The experiment's early attempts with regex parsing are a useful cautionary tale.
Second, hard API caps belong in the class design, not in a comment. The counter here stopped execution cleanly at 15 calls and logged the halt. That is the difference between a controlled experiment and a surprise invoice.
Third, a low baseline agreement rate is not automatically a win for the LLM. It means the two methods diverge, and divergence cuts both ways. The model may be capturing context the lexicon misses, or it may be introducing its own biases. The right next step is manual review of the disagreeing cases, not assuming the newer tool is correct.
The open question
The experiment establishes that a constrained Gemini pipeline can produce structured, bounded sentiment records from live RSS feeds at a fixed call budget. What it does not yet establish is whether those records are more accurate than keyword scoring, only that they are different.
For anyone weighing this approach, that is the work still ahead: labeling a ground-truth set, measuring precision on the bullish and bearish calls, and tracking whether the model's confidence ratings correlate with actual correctness. The pipeline is built. The validation is the next experiment.

Comments (0)