# Market Screener & Personal Finance Assistant A Node.js CLI tool that screens stocks, ETFs, bonds, and crypto using live Yahoo Finance data. It scores each asset under two lenses — **Market-Adjusted** (what's acceptable in today's inflated market) and **Fundamental** (Graham-style strict value investing) — and gives you an honest signal by comparing both. It also connects to your brokerage accounts via **SimpleFIN** to track net worth, spending, and give hold/sell/add advice on your actual portfolio. --- ## Quick Start ```bash npm install cp .env.example .env # add SIMPLEFIN_SETUP_TOKEN if you have SimpleFIN npm start # screen today's catalyst tickers from Yahoo news ``` --- ## Commands | Command | What it does | |---|---| | `npm start` | Fetches today's market news, extracts catalyst tickers, screens them | | `npm start -- watch` | Screens the default watchlist instead | | `npm start -- AAPL MSFT VOO` | Screens specific tickers | | `npm run finance` | Portfolio advice + SimpleFIN account data → `finance-report.html` | | `npm run import-portfolio -- file.csv` | Imports Robinhood/Vanguard/Fidelity CSV into `portfolio.json` | | `npm test` | Runs all unit tests (51 tests, zero external dependencies) | | `npm run test:watch` | Re-runs tests on file changes during development | | `npm run format` | Formats all source files with Prettier | | `npm run format:check` | Checks formatting without writing (useful in CI) | Both commands generate self-contained HTML reports that open in any browser. --- ## How the Screener Works Every asset is scored twice: **Market-Adjusted** — gates derived from live Yahoo Finance benchmarks: - Stock P/E gate = S&P 500 P/E (via SPY) × 1.5 - Tech P/E gate = XLK sector P/E × 1.3 - REIT min yield = XLRE dividend yield × 0.85 - Bond min spread = LQD − TNX live spread × 0.80 **Fundamental** — strict Graham/value-investing gates from `src/config/ScoringConfig.js`: - Stock P/E < 20x, PEG < 1.5 - Bond spread > 1.0% above risk-free rate The comparison produces a **Signal**: | Signal | Meaning | |---|---| | ✅ Strong Buy | Passes both — genuinely good value | | ⚡ Momentum | Passes market-adjusted, holds fundamentally | | ⚠️ Speculation | Passes market-adjusted, fails fundamental — priced for perfection | | 🔄 Neutral | Hold territory in one or both lenses | | ❌ Avoid | Fails both | --- ## Personal Finance Edit `portfolio.json` with your holdings (or import from a broker CSV): ```json { "holdings": [ { "ticker": "AAPL", "shares": 10, "costBasis": 150.00, "source": "Robinhood", "type": "stock" }, { "ticker": "VOO", "shares": 8, "costBasis": 380.00, "source": "Vanguard", "type": "etf" }, { "ticker": "BTC-USD", "shares": 0.25, "costBasis": 45000, "source": "Coinbase", "type": "crypto" } ] } ``` `npm run finance` screens your holdings, fetches crypto prices, and generates hold/sell/add advice based on the screener signal crossed with your gain/loss position. ### SimpleFIN (optional) Connects to your real bank and brokerage accounts for net worth, balances, and 30-day spending breakdown. 1. Get your setup token from [beta-bridge.simplefin.org](https://beta-bridge.simplefin.org) 2. Add to `.env`: `SIMPLEFIN_SETUP_TOKEN=aHR0cHM6Ly...` 3. Run `npm run finance` — the Access URL is claimed and saved automatically ### Importing broker holdings ```bash npm run import-portfolio -- ~/Downloads/robinhood_holdings.csv npm run import-portfolio -- ~/Downloads/vanguard_holdings.csv ``` Broker is auto-detected from CSV headers. Running multiple imports merges them into `portfolio.json`. --- ## Project Structure ``` ├── bin/ │ ├── screen.js # Market screener entry point │ ├── finance.js # Personal finance entry point │ └── import-portfolio.js # Broker CSV importer │ ├── prompts/ │ └── catalyst-analysis.md # Daily catalyst analysis playbook │ ├── src/ │ ├── config/ │ │ └── ScoringConfig.js # All scoring gates, weights, thresholds │ │ │ ├── market/ # Yahoo Finance data layer │ │ ├── YahooClient.js │ │ ├── BenchmarkProvider.js │ │ └── MarketRegime.js # Derives inflated gate overrides from live data │ │ │ ├── screener/ # Core screening domain │ │ ├── ScreenerEngine.js │ │ ├── DataMapper.js │ │ ├── RuleMerger.js │ │ ├── Chunker.js │ │ ├── assets/ # Stock, Etf, Bond data containers │ │ └── scorers/ # StockScorer, EtfScorer, BondScorer │ │ │ ├── analyst/ │ │ └── CatalystAnalyst.js # Extracts tickers from Yahoo Finance news │ │ │ ├── finance/ │ │ ├── clients/ │ │ │ └── SimpleFINClient.js │ │ ├── PersonalFinanceAnalyzer.js │ │ ├── PortfolioAdvisor.js │ │ └── PortfolioImporter.js │ │ │ └── reporters/ │ ├── HtmlReporter.js # screener-report.html │ └── FinanceReporter.js # finance-report.html │ ├── portfolio.json # Your holdings (edit this) └── .env # SIMPLEFIN_SETUP_TOKEN / SIMPLEFIN_ACCESS_URL ``` --- ## Metrics Scored per Stock | Metric | Source | Why it matters | |---|---|---| | P/E ratio | Yahoo forwardPE / trailingPE | Valuation | | PEG ratio | Yahoo or computed (trailingPE ÷ earningsGrowth) | Valuation vs growth | | Price-to-Book | Yahoo | Graham's primary value metric | | ROE | Yahoo returnOnEquity | Buffett's primary quality metric | | Operating margin | Yahoo operatingMargins | Pricing power | | Net profit margin | Yahoo profitMargins | Bottom-line profitability | | Revenue growth | Yahoo revenueGrowth | Top-line momentum | | FCF yield | Computed (freeCashflow ÷ market cap) | Cash generation quality | | Debt/Equity | Yahoo debtToEquity | Balance sheet risk | | Quick ratio | Yahoo quickRatio (falls back to currentRatio) | Liquidity | | Beta | Yahoo beta | Market sensitivity | | 52-week position | Yahoo fiftyTwoWeekHigh/Low | Momentum / opportunity flag | Sector overrides apply: REIT scores on yield + P/FFO, FINANCIAL on ROE + P/B, TECHNOLOGY with realistic D/E tolerance.