Inspiration
Retail investors get their signal from headlines. But headlines and share prices don't always agree, and the gap between them is where beginners lose money.
A stock can generate a fortnight of media coverage but still barely move. Another can quietly slide while the commentary stays upbeat.
Everyone else is reading headlines and guessing. I wanted to make that gap visible in ten seconds, in plain English, to be used from experts all the way to someone who has never bought a share.
What it does
Pick from 15 stocks. For each one, Rumour vs Reality:
- Pulls live price data and calculates the 24-hour and 7-day movement
- Collects every headline published about that company in the last 7 days, from 5+ major outlets
- Sends those headlines to Claude, which returns a directional classification, a confidence score, a "hype score" measuring how excitable the coverage is and finally a two-sentence summary written for a beginner
- Compares the two - positive coverage against a flat price is hype exceeding reality; negative coverage against a rising price is the reverse
The output is one clear verdict per stock.
How I built it
| Part | Tool |
|---|---|
| Price data | yfinance |
| News collection | feedparser over RSS |
| Analysis | Anthropic Claude API |
| Interface | Streamlit |
Four modules, each with a single responsibility:
prices.py— takes a ticker, returns current price and percentage change over both windowsnews.py— merges 5+ RSS sources, including a Google News search feed constructed per company, then filters to a rolling 7-day window and to headlines actually mentioning that companyai.py— formats the headlines, prompts Claude for structured JSON, and parses the responseapp.py— the Streamlit interface that orchestrates the three and computes the verdict
Each module was built and verified in isolation before anything was wired together. That paid for itself repeatedly: when something broke, the failing layer was never in question.
Challenges I ran into
Real-world data is messy. One RSS feed seemed healthy but it returned entries. Another threw no errors, but its newest article was over a year old. A third turned out to serve exchange operational notices rather than company news. Response codes tell you nothing about whether the content is usable.
Third-party responses don't match their documentation. A missing summary field on a single Yahoo article killed the entire run. A ThinkingBlock in the Claude response meant content[0].text didn't exist. Both taught me to never assume a shape you haven't verified. Every field access is now defensive, so a broken source degrades one stock rather than the whole application.
Getting structured output from a language model. Claude's prose analysis was excellent and unusable, the verdict logic needs a value to compare against a number, not a paragraph. Switching to a JSON response with an explicit example in the prompt solved it, wrapped in exception handling that returns a schema-valid default so a malformed reply never reaches the interface.
Generic feeds don't cover single companies. The first five business feeds returned zero Nvidia headlines on a day Nvidia was the biggest story in tech. The fix was a Google News search feed built dynamically from the company name, which reaches across hundreds of publishers in one request and now supplies most of the coverage.
My key takeaways
The interesting problems in this build weren't the API calls but moreover everything surrounding them: how to make a system that depends on six external sources behave predictably when any of them can fail, and how to get deterministic, machine-readable output from a model designed to produce prose.
Two things I'll carry forward in my future in programming:
- Test the connection before the logic. A trivial API call surfaced a billing problem in 30 seconds that would otherwise have been buried under a complex prompt and a broken parser.
- Constrain the model, then handle it failing anyway. An explicit output example does most of the work; the exception handler covers the rest. Neither alone is sufficient.
Built With
- anthropic
- api
- claude
- claude-api
- data-visualization
- dotenv
- feedparser
- financial-data
- fintech
- generative-ai
- github
- json
- llm
- natural-language-processing
- pandas
- python
- rss
- sentiment-analysis
- stock-market
- streamlit
- vs-code
- web-scraping
- yfinance
Log in or sign up for Devpost to join the conversation.