Skip to main content

InvestDayTip

InvestDayTip Logo

A multi-factor scoring and analysis tool for long-term stock & ETF research in US, European, Asian, and Superinvestor-consensus markets, computed live from public market data — a decision-support tool, not investment advice.

License: MIT Python 3.10+ PyPI version CI GitHub stars Last commit Website

🌐 See it live — investdaytip.com

The site runs on this project's scoring engine — the pure-Python core behind the CLI tool — and publishes quantitative ratings for the top 100 US stocks, refreshed daily: per-ticker deep-dive (Piotroski, Altman, risk signals), a time machine that diffs any past run against the one before it, and a methodology page whose full model documentation links right here.

The site is a separate project (proprietary code, third-party market data under its own terms) built on this engine; the engine itself stays MIT.


Features

  • 📈 Multi-factor scoring — composite 0-100 score per asset
  • 🔗 Multiple data sources — yfinance (default), yahooquery (batch), Financial Modeling Prep (FMP) or StockFit (US stocks, Starter plan), with automatic fallback
  • 🏦 Stocks & ETFs — auto-detected and scored with dedicated models
  • 🌍 US, European, Asian & Superinvestor markets — S&P 500, DAX, CAC 40, FTSE 100, Nikkei 225, Hang Seng, NSE, and superinvestor consensus picks from DataRoma 13F filings
  • 💱 Currency filter — narrow by native currency (USD, EUR, JPY, …)
  • ⚡ Concurrent fetching — analyzes ~300 tickers in seconds
  • 📊 Rich CLI output — price, 1M/1Y change, score breakdown and rationale
  • 🧾 Self-contained HTML export — interactive report with filters and sortable columns
  • 🧪 Pure scoring functions — testable without network
  • 🧠 Interactive advisor — market pulse, portfolio review, and model-scored pick lists via the advisor subcommand (decision support, not personal recommendations)
  • 🤖 AI-powered assistant — chat in natural language to analyze markets, review portfolios, and explore the model's top picks — powered by OpenCode agents
  • 📊 Backtest validation — historical backtesting with automated before/after comparison script
  • 🧾 StockFit integration (optional) — point-in-time SEC filing dates for backtests (--pit-source stockfit, works offline from a local snapshot), a fundamentals insights section in the HTML report (--fundamental-insights), per-ticker deep-dive reports and a keyless devil's advocate layer (risk signals). Works on every StockFit plan — and without a key at all (stockfit-status shows what yours unlocks)

Installation

pip install investdaytip

Upgrade

pip install --upgrade investdaytip

Force reinstall if the version doesn't update (e.g. cached old wheel):

pip install --upgrade --no-cache-dir investdaytip

From source (for development)

git clone https://github.com/dfdezdom/investdaytip.git
cd investdaytip
python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install -e ".[dev]"

Quick start

investdaytip

That's it. You'll see the top 5 highest-scoring candidates across 300+ stocks & ETFs.

InvestDayTip CLI output


Usage

CLI

Subcommands:

Command What it does Section
investdaytip [flags] Top-scoring candidates from the curated universes below
investdaytip advisor Interactive market pulse, portfolio review, model picks Advisor
investdaytip deep-dive Per-ticker deep report (score + research + diagnostics) Deep-dive
investdaytip backtest Historical validation of the scoring model Backtest
investdaytip stockfit-status Your StockFit plan + which features unlock Tiers
investdaytip                         # Top 5 from full universe (US + EU + Asia, stocks + ETFs)
investdaytip -n 10                   # Top 10
investdaytip -a stocks               # Only stocks
investdaytip -a etfs                 # Only ETFs
investdaytip -r us                   # Only US
investdaytip -r eu                   # Only Europe
investdaytip -r asia                 # Only Asia
investdaytip -r superinvestor        # Only superinvestor consensus tickers
investdaytip -r us eu                # US + Europe
investdaytip -r eu -a stocks         # Only European stocks
investdaytip -r asia -a etfs         # Only Asian ETFs
investdaytip -c USD                  # Only USD-denominated assets
investdaytip -c EUR                  # Only EUR-denominated assets
investdaytip -c USD EUR              # USD + EUR assets
investdaytip -c JPY                  # Only JPY-denominated assets
investdaytip -r eu -c USD            # EU region + USD post-filter
investdaytip -r us eu -c USD EUR     # US + EU, USD + EUR assets
investdaytip -t AAPL MSFT VOO        # Custom ticker list

investdaytip --tickers-file tickers.txt # Custom ticker file (lines, spaces, commas)
investdaytip --tickers-file tickers-files-examples/semiconductors_relevant_tickers.txt
investdaytip --export-html report.html # Export report with interactive filters
investdaytip --export-html             # Uses investDayTip-aaaammdd-hhmm.html
                                       # or investDayTip-<tag>-aaaammdd-hhmm.html
                                       # when --tickers-file is set

investdaytip --superinvestor         # Fetch DataRoma superinvestor data and display column
investdaytip --no-include-technical  # Disable RSI + MACD (enabled by default for quant)
investdaytip --scoring-model classic # Use the classic Graham/Buffett model instead of quant
investdaytip --min-market-cap 1B     # Raise min market cap to $1B
investdaytip --min-market-cap 0      # Disable market-cap filter

investdaytip --data-source yahooquery  # Use yahooquery (batch-friendly yfinance backend)
                                       # Falls back to yfinance automatically per ticker
investdaytip --data-source fmp         # Use Financial Modeling Prep (requires FMP_API_KEY env var)
                                       # Get a free key at https://financialmodelingprep.com/
investdaytip --no-cache                # Bypass SQLite cache, fetch fresh data
investdaytip --cache-clear           # Purge all cached data before running
investdaytip --workers 20            # More parallelism

investdaytip advisor                    # Interactive mode (asks for risk, region, etc.)

investdaytip deep-dive -t AAPL          # Deep report: score + research + risk signals
investdaytip deep-dive -t NVDA --export-html nvda.html

investdaytip backtest -n 10 -r us       # Backtest stock scoring on US market (stocks only)
investdaytip backtest -t AAPL MSFT VOO  # Backtest on custom ticker list
investdaytip backtest --export-html     # Export backtest results to HTML
investdaytip backtest --no-cache        # Bypass cache in backtest
investdaytip backtest --cache-clear     # Purge cache before backtest

investdaytip stockfit-status            # Your StockFit plan and unlocked features

investdaytip --help
./preview.sh                         # Serve generated HTML files on localhost:8000

Options

Flag Description Default
-n, --top N Number of picks to show (defaults to ticker count when -t is used) 5
-t, --tickers ... Custom ticker list (overrides universe; quoted space-separated ok) curated universe
--tickers-file PATH Text file with custom tickers (merged with --tickers if both are used) disabled
-a, --asset-class {all,stocks,etfs} Asset class filter all
-r, --region {all,us,eu,asia,superinvestor} nargs="+" Region filter(s) — e.g. -r us eu all
-c, --currency {all,USD,EUR,GBP,…} nargs="+" Currency filter(s); narrows universe to matching regions when no -r is given all
-s, --sector TEXT Sector/category prefix filter, case-insensitive (e.g. Financial matches Financial Services) disabled
--export-html [PATH] Export the scoring results to self-contained HTML (investDayTip-aaaammdd-hhmm.html if omitted) disabled
--superinvestor Include superinvestor ownership data from DataRoma (adds ~80 HTTP requests, shows column in HTML and CLI) disabled
--fundamental-insights Add a StockFit fundamentals section to the HTML report (margin trends, FCF/NI quality, balance-sheet health; US stocks only). Uses STOCKFIT_API_KEY when set and is omitted gracefully without it disabled
--include-technical Include RSI + MACD technical indicators in the scoring. Default is True for quant and False for classic. Use --no-include-technical to force-disable. model-dependent
--no-include-technical Force-disable RSI + MACD technical indicators disabled
--scoring-model {classic,quant} Stock/ETF scoring model quant
--data-source {yfinance,yahooquery,fmp,stockfit} Data source. stockfit = US stocks only, requires STOCKFIT_API_KEY + Starter plan (rankings differ from yfinance — as-filed FY semantics) yfinance
--min-market-cap VALUE Minimum market cap (1B, 500M, 0 to disable; see Market Cap Classification) 0 with tickers, 2B otherwise
--no-cache Skip SQLite cache, fetch all data live from Yahoo Finance disabled
--cache-clear Purge the SQLite cache before running disabled
--workers N Parallel fetch threads 10
--version Show the installed version and exit n/a
-h, --help Print the usage help and exit n/a

🤖 OpenCode AI Agent

InvestDayTip includes an AI-powered analysis assistant that lets you explore markets and the model's output from your terminal — no memorizing CLI flags. Its answers are decision support built on the scoring model, not personal investment advice.

Prerequisites

# Install via the official installer (macOS / Linux)
curl -fsSL https://opencode.ai/install | bash

# Also available via npm, brew, bun, and more — see https://opencode.ai

What it can do

  1. Market pulse — Full macro analysis (VIX + yield curve + bond volatility + DXY) in ~30 seconds
  2. Portfolio review — Score your holdings, spot weaknesses, and see the model's risk signals
  3. Model picks — Highest-scoring candidates filtered by region, asset class, and risk profile
  4. Devil's advocate — Bear case + risk signals for specific tickers (see below)
  5. Full analysis — All of the above combined into a single comprehensive report

Quick example

@advisor what's the market pulse?

Expected output:

📊 Market Pulse

Macro Score: 58/100 (Neutral)
- VIX: 14.2 (calm)
- 10Y-2Y Spread: +0.85% (healthy)
- MOVE: 78 (normal)
- DXY: 102.3 (strong)
- Fear & Greed: 67/Greed

Signal: 🟡 HOLD — selective buying

🩺 Devil's advocate — bear cases from SEC footnotes

Every portfolio review and model pick now ends with a bear case for the analyzed tickers, in two layers:

Layer Source Needs
1 — risk signals investdaytip deep-dive (risk bullets, Piotroski checks, Altman zone) + StockFit footnotes bullets (Pro plan) nothing — works keyless
2 — SEC footnotes StockFit MCP tools: customer/supplier concentration trends, debt maturity walls, stock-comp dilution, insider summaries (0 buys vs N sells), governance flags StockFit MCP connected
@advisor devil's advocate on NVDA

Expected output: severity bullets (🔴/🟡/🔵) mixing both layers — e.g. "Customer One went from 14% → 25% of receivables in two years" next to "0 insider buys vs 318 sells ($2.18B) in 12 months" — plus the balanced view of what does not support the bear case (clean balance sheet, no hidden leverage). Never fabricated: every bullet comes from a tool call.

Connecting the StockFit MCP (layer 2): the server is registered in opencode.json (OAuth 2.1 — no API key in config):

opencode mcp add stockfit --url https://api.stockfit.io/mcp   # already registered

Then sign in once from the OpenCode TUI: run /mcps, select stockfit and complete the browser flow. Tools appear as tools.stockfit.* (125 of them — footnotes, governance, insider/ownership summaries, sector-aware metrics). Without the MCP — or on lower plans — the advisor degrades to layer 1 and says so explicitly.

AI Agent vs CLI advisor

OpenCode AI Agent investdaytip advisor CLI
Interface Natural language chat Interactive menu prompts
Flexibility Ad-hoc questions, follow-ups Predefined flow
Speed ~30s for market pulse ~1–2 min for full analysis
Output Clean markdown tables Rich colored tables (terminal)
Best for Quick questions, exploration Deep structured analysis

Full documentation

See .opencode/agents/advisor.md for:

  • VIX / macro regime interpretation rules
  • Fear & Greed Index signals
  • Bubble burst historical indicators (dot-com 2000, railroads 1845)
  • Portfolio scoring thresholds and presentation format
  • Devil's advocate rules (bear-case layers, StockFit tool map, never-fabricate)
  • Execution methods (market pulse, portfolio review, devil's advocate, full analysis)

Advisor subcommand

Interactive market analysis with multi-indicator macro pulse (VIX, 10Y-2Y yield curve, MOVE bond volatility, DXY dollar strength), portfolio review, and model-generated pick lists:

investdaytip advisor                          # Interactive mode (asks for risk, region, etc.)
investdaytip advisor --risk moderate          # Non-interactive with risk preset
investdaytip advisor --risk aggressive -r us -a stocks    # US stocks, aggressive, non-interactive
investdaytip advisor --risk moderate --portfolio portfolios/portfolio.txt  # Custom portfolio

The advisor now displays a composite macro health score (0-100):

  • 🟢 ≥70 — Macro healthy
  • 🟡 ≥45 — Mixed signals
  • 🟠 ≥25 — Macro warning
  • 🔴 <25 — Macro danger

See investdaytip advisor --help for all options.

Market Indicators

The advisor fetches six live indicators to compute the composite macro health score (0-100):

Indicator Ticker What it measures Reference ranges Score impact
VIX ^VIX Expected S&P 500 volatility over the next 30 days ≤15 calm, ≤25 neutral, ≤35 fear, >35 panic ±20
VXN ^VXN Expected Nasdaq 100 volatility (tech-heavy complement to VIX) (informational only) —
10Y-2Y Spread ^TNX + 2YY=F US Treasury yield curve slope — inverted curve signals recession risk >1% healthy, 0–1% neutral, <0% inverted −20 / +5
MOVE ^MOVE Bond market volatility (Merrill Lynch Option Volatility Estimate) <60 calm, 60–100 normal, 100–120 elevated, >120 panic −15 / +5
DXY DX-Y.NYB US Dollar Index — strength against EUR, JPY, GBP, CAD, SEK, CHF <95 weak, 95–100 neutral, 100–105 strong, >105 very strong −10 / +5
Fear & Greed CNN API Composite market sentiment from 7 sub-indicators (momentum, breadth, put/call, volatility, junk bonds, safe havens) 0–100; <25 extreme fear, >75 extreme greed ±10 (contrarian)

The score starts at a neutral 50 and each indicator adjusts it up or down based on current readings. The final score determines the macro regime signal — a model output for decision support, not an instruction to trade:

  • 🟢 ≥70 — Macro healthy → buy
  • 🟡 ≥45 — Mixed signals → hold
  • 🟠 ≥25 — Macro warning → hold
  • 🔴 <25 — Macro danger → sell

All indicators are shown live in the 📈 Market Analysis table when running investdaytip advisor.

Deep-dive subcommand

Per-ticker deep report — this is where the detail lives: the InvestDayTip score, StockFit's research summary and keyless health diagnostics.

investdaytip deep-dive -t AAPL                      # Rich terminal report
investdaytip deep-dive -t "AAPL MSFT" --export-html # Self-contained HTML page
Section Source Needs STOCKFIT_API_KEY?
Score + factor breakdown live data + the scoring model no
Earnings snapshot (margins, ROE/ROIC, FCF, growth, next dates) StockFit company/research-summary yes (omitted gracefully otherwise)
Piotroski F-Score (9 checks) + Altman Z + zone local computation from the ticker's own statements no
Devil's advocate — risk signals local heuristics (Altman zone, Piotroski failures, leverage, payout, losses) + StockFit footnotes/* bullets (concentration, debt maturities, pensions…) no — footnotes layer needs a Pro plan (omitted with a note otherwise)

Piotroski/Altman are informative diagnostics — never scored (they were validated and rejected as scoring factors). The Altman Z-Score follows StockFit's variant of the 1968 model: X4 = book value of equity attributable to the parent ÷ total liabilities (not the 1968 market-value term), so the keyless diagnostic matches StockFit's precomputed value exactly.

Flag Description Default
-t, --tickers ... Ticker(s) to analyse (required) —
--export-html [PATH] Export the report to a self-contained HTML page disabled
--scoring-model {classic,quant} Scoring model for the displayed score quant
--no-cache Skip SQLite cache for the underlying fetches disabled

StockFit integration & tiers

InvestDayTip works on every StockFit plan — and without a key at all: features unlock more as the tier rises and degrade gracefully below it (omitted with the reason, never fabricated). See what your setup unlocks:

investdaytip stockfit-status
Feature Needs
PIT backtests + snapshot (--pit-source stockfit) keyless (local snapshot)
HTML fundamental insights (--fundamental-insights) any key (Free)
deep-dive earnings snapshot Starter
Rich devil's advocate footnotes (roadmap) Pro

Backtest subcommand

Historical validation of the stock scoring model:

investdaytip backtest                          # Backtest US stocks (default)
investdaytip backtest -n 10                    # Top 10 picks per snapshot
investdaytip backtest -r us                    # US stocks
investdaytip backtest -r eu                    # European stocks
investdaytip backtest -r asia                  # Asian stocks
investdaytip backtest -r superinvestor         # Superinvestor consensus stocks
investdaytip backtest -t AAPL MSFT             # Custom ticker list
investdaytip backtest --benchmark SPY          # Custom benchmark
investdaytip backtest --interval-months 6      # Semi-annual snapshots
investdaytip backtest --lag-days 90            # Reporting lag (default: 60)
investdaytip backtest --period 3y              # Shorter price history
investdaytip backtest --export-html            # Export to HTML
investdaytip backtest --pit-source stockfit    # Point-in-time SEC filing dates (StockFit)
investdaytip backtest --no-cache               # Bypass SQLite cache
investdaytip backtest --cache-clear            # Purge cache before run

Backtest options

Flag Description Default
-n, --top N Top N picks per snapshot 10
-t, --tickers ... Custom ticker list curated US universe
-r, --region ... Region filter(s) us
-c, --currency ... Currency filter(s) all
--period PERIOD yfinance lookback period 5y
--interval-months N Months between snapshots 3
--lag-days N Reporting lag in days 60
--min-market-cap CAP Minimum market cap (0, 1B, …) 0 with tickers, 2B otherwise
--benchmark TICKER Benchmark for alpha/returns SPY (per region)
--export-html [PATH] Export results to HTML disabled
--scoring-model {classic,quant} Scoring model to validate quant
--pit-source {none,stockfit} Point-in-time fundamentals (exact SEC filing dates; needs key or local snapshot) none
--include-technical / --no-include-technical Force RSI/MACD in/out model-dependent
--max-workers N Parallel fetch threads 10
--no-cache / --cache-clear Bypass / purge the SQLite cache disabled

Note: Backtest only supports stocks (no ETFs). It simulates quarterly snapshots with a configurable reporting lag, scores each stock, and measures forward returns against a benchmark.

Point-in-time fundamentals (StockFit, opt-in)

--pit-source stockfit replaces the fixed reporting-lag assumption with each filing's actual SEC acceptance date (dateFiled) — every snapshot only sees data that was public that day, so slow filers can't leak results back in time. US stocks only. Validated on the full US universe: Sharpe 0.74→0.85, max drawdown 24%→11%, 12M win rate 50%→56% (hypothetical backtests over historical data — past performance is not indicative of future results).

It works without an API key when a local snapshot exists (~/.investdaytip/pit/) — build one while your StockFit key is valid:

python scripts/pit_snapshot.py          # full US stock universe (196 tickers)
python scripts/pit_snapshot.py --status # inspect saved files (offline)

Resolution order, per ticker: live StockFit (when STOCKFIT_API_KEY is set) → local snapshot → the classic fixed-lag path.

Backtest-Driven Scoring Validation

Use the included scripts/scoring_baseline.py to validate scoring changes objectively:

# Save baseline BEFORE your change
python scripts/scoring_baseline.py run \
  --tag "before" -r us -n 10 \
  -t "AAPL MSFT GOOGL META NVDA" \
  --period 2y --interval-months 3 \
  --min-market-cap 0

# Save baseline AFTER your change
python scripts/scoring_baseline.py run \
  --tag "after" -r us -n 10 \
  -t "AAPL MSFT GOOGL META NVDA" \
  --period 2y --interval-months 3 \
  --min-market-cap 0

# Compare two different scoring models on the same universe
python scripts/scoring_baseline.py run --tag classic -r us -n 10 \
  -t "AAPL MSFT GOOGL META NVDA" --period 2y --interval-months 3 \
  --min-market-cap 0 --scoring-model classic

python scripts/scoring_baseline.py run --tag quant -r us -n 10 \
  -t "AAPL MSFT GOOGL META NVDA" --period 2y --interval-months 3 \
  --min-market-cap 0 --scoring-model quant

python scripts/scoring_baseline.py compare baseline-classic.json baseline-quant.json

# Compare side-by-side with decision rules
python scripts/scoring_baseline.py compare baseline-before.json baseline-after.json

Decision rules:

  • Ship it: Alpha ↑ AND Sharpe ↑ AND 12M win rate ↑
  • Consider: Alpha ↑ OR Sharpe ↑ (mixed, review drawdown)
  • Reject / iterate: Alpha ↓ AND Sharpe ↓

When to use technical indicators

The --include-technical flag adds RSI-14 and MACD histogram to the Momentum factor (15% weight, blended at 30%). Under the quant model this is now enabled by default; under classic it remains opt-in.

Backtest validation across four scenarios under the quant model shows the flag is generally additive for US screens but mixed for concentrated mega-caps and EU:

Scenario Without --include-technical With --include-technical Verdict
US ($2B+) (134 tickers, -n 10) Alpha 21.94%, Sharpe 1.49 Alpha 25.00%, Sharpe 1.68 ✅ Improved — higher alpha (+3pp), Sharpe (+0.19), and lower drawdown (6.76% → 5.63%)
US (no cap filter) (134 tickers, -n 10) Alpha 5.47%, Sharpe 0.54 Alpha 11.53%, Sharpe 0.85 ✅ Improved — alpha doubles, drawdown halves (34.3% → 16.2%), 12M win rate climbs (53% → 73%)
US mega-caps ($200B+) (134 tickers, -n 2) Alpha 44.33%, Sharpe 1.31 Alpha 42.35%, Sharpe 1.18 ⚠️ Mixed — slightly lower alpha (−2pp) and Sharpe, but drawdown improves sharply (18.8% → 10.4%)
EU ($2B+) (66 tickers, -n 10) Alpha 7.11%, Sharpe 1.71 Alpha 3.93%, Sharpe 0.93 ⚠️ Neutral/Mixed — lower alpha and Sharpe with tech, but 12M win rate climbs (42% → 60%)

The backtest figures above are hypothetical simulations over historical data, under the assumptions modeled; past performance is not indicative of future results.

Guidelines:

  • ✅ Default behavior — quant enables technical indicators automatically; classic keeps them opt-in
  • ✅ Broad US screens benefit the most — higher alpha, Sharpe, and lower drawdown
  • ⚠️ Concentrated mega-cap lists — mixed results; alpha and Sharpe may dip but drawdown improves
  • ⚠️ EU screens — fundamental-only (no-tech) shows stronger risk-adjusted returns; verify on your specific ticker list
  • ❌ Use --no-include-technical if you rely on the classic model or want a pure fundamental signal

Market Cap Classification

The --min-market-cap filter controls the size of companies included in the analysis. Standard classification for reference:

Category Market Cap Typical characteristics
Mega-cap > $200B Largest global companies (Apple, Microsoft, Google). Highest liquidity, most followed by analysts, technical indicators most reliable.
Large-cap $10B – $200B Established companies with stable fundamentals. Good balance of growth and stability.
Mid-cap $2B – $10B Growing companies, regional leaders. More volatile than large-caps but higher growth potential.
Small-cap $300M – $2B Niche players or regional companies. Higher volatility, less analyst coverage, fundamentals less reliable.
Micro-cap < $300M Early-stage or distressed companies. Very high risk, low liquidity.

Why the default is $2B (mid-cap threshold):

The model is designed for long-term fundamental investing. Below $2B (small/micro-caps), companies tend to have:

  • Incomplete or unreliable financial data in yfinance
  • Higher volatility that overwhelms fundamental signals
  • Lower liquidity, making technical indicators less meaningful

The $2B threshold strikes a balance: it includes mid-caps and above (where fundamentals are reliable) while filtering out the noisiest small/micro-caps. Use --min-market-cap 0 to include all tickers, or raise it to 10B/50B for a pure large/mega-cap focus.

Note: when explicit tickers are provided via -t or --tickers-file, the filter defaults to 0 (disabled) — the assumption is that you curated your own list.

HTML export

Generate an interactive report that works offline (single file with inline CSS/JS):

investdaytip -n 25 -a all -r all --export-html investdaytip-report.html

The generated report includes filters for:

  • Text search (ticker/name/sector)
  • Asset class (stock / etf)
  • Region (us / eu / asia)
  • Minimum score
  • Minimum 1M return (%)
  • Minimum 1Y return (%)

When --superinvestor is enabled, an additional "Superinvestors" sortable column appears between 1Y and Score showing the number of tracked managers holding each ticker. When --include-technical is enabled, "RSI" and "MACD" columns appear between 1Y (or Superinvestors) and Score.

It also includes:

  • Click-to-sort columns (ascending/descending)
  • Full-width responsive layout (uses available browser width)
  • Pre-rendered rows + client-side interactivity (works even if JS is restricted)
  • Direct platform links in table columns: Ticker (Google Finance), T (TradingView), Y (Yahoo Finance)

Direct platform links (Ticker → Google Finance, T → TradingView, Y → Yahoo Finance) use exchange suffix mapping. See _normalize_exchange_hint() and _exchange_mapping() in src/investdaytip/html_export.py for the full list of ~20 supported exchanges.

Programmatic API

from investdaytip import get_recommendations

# Get top 5 Asian stocks
picks = get_recommendations(top_n=5, region="asia", asset_class="stocks")
for s in picks:
    print(f"{s.data.ticker} ({s.asset_type}) — score={s.total:.1f}")
    print(f"  Price: {s.data.current_price} {s.data.currency}")
    print(f"  1M: {s.data.return_1m:.2%}  1Y: {s.data.return_12m:.2%}")
    print(f"  Why: {'; '.join(s.rationale[:3])}")

# Or filter by sector (prefix match, case-insensitive)
picks = get_recommendations(top_n=5, sector="Financial")  # Financial + Financial Services

# Or mix regions and asset classes
picks = get_recommendations(top_n=10, region="all")  # US + EU + Asia stocks & ETFs

# Choose the scoring model explicitly (quant is the default)
picks = get_recommendations(top_n=5, region="us", scoring_model="classic")

# Use FMP data source (requires FMP_API_KEY env var)
picks = get_recommendations(top_n=5, region="us", data_source="fmp")

Output

Each row includes:

Column Meaning
Type STOCK or ETF
Ticker / Name / Sector Identification
Ticker link Opens Google Finance in a new tab
T / Y Opens TradingView / Yahoo Finance in a new tab
Price Current price in native currency
% Today Daily change vs previous close
P/E Trailing price-to-earnings ratio (stocks; - when unavailable)
Yield Dividend yield for stocks (TTM from raw dividends, fallback to dividendYield) or ETFs (yield_) — - when unavailable
1M Δ % change vs ~22 trading days ago
1Y Δ % change vs ~252 trading days ago
RSI RSI-14 (when --include-technical is enabled)
MACD MACD histogram % vs price (when --include-technical is enabled)
Superinvestors Number of managers holding the stock (HTML only; - if not in DataRoma universe)
Score Composite 0-100 weighted score
Breakdown Four sub-scores (shown in a compact single line)
Why Top 3 rationale notes

Scoring Model

InvestDayTip supports two stock-scoring models, selectable via --scoring-model {classic,quant}. The default is quant, a five-factor model inspired by Seeking Alpha Quant Ratings (a trademark of its owner; this project is not affiliated with, endorsed by, or connected to Seeking Alpha). The original classic model (Graham/Buffett + momentum) remains available for backwards compatibility.

Each metric is normalized to 0-100 via piecewise-linear functions over empirically reasonable ranges. Missing data contributes a neutral 50 so a ticker isn't penalized for lacking a metric.

Stocks — quant (default)

Factor Weight Metrics
Value 25% trailing P/E, P/B, PEG (derived = P/E ÷ growth %, positive growth only), FCF yield
Growth 20% earnings growth, revenue growth
Profitability 25% ROE, ROA, profit margin + a YoY-improvement sub-score (Δgross margin + ΔROA vs last fiscal year; neutral when statements are unavailable)
Momentum 15% price vs SMA200, 12-month return, SMA200 slope (plus RSI-14 + MACD histogram by default; disable with --no-include-technical)
EPS Revisions 15% average EPS surprise (Reported EPS vs analyst Estimate) over the last four quarters

The quant model uses disqualifying grades: if any high-impact factor falls into red-flag territory, the total score is capped at neutral (50). This prevents a strong showing in one area from masking a serious weakness elsewhere.

Stocks — classic

Pillar Weight Metrics
Quality 35% ROE, profit margin, earnings & revenue growth
Value 25% trailing P/E, P/B, PEG
Health 20% Debt/Equity, current ratio, free cash flow
Trend 20% price vs SMA200, 12-month return, SMA200 slope (plus RSI-14 + MACD histogram when --include-technical is explicitly enabled)

ETFs

ETF scoring also switches between two models via --scoring-model {classic,quant}. The default is quant, a momentum-first model.

quant (default for ETFs when --scoring-model quant):

Factor Weight Metrics
Momentum 65% 1m (15%), 3m (25%), 6m (30%), 12m (30%) returns
Risk 15% volatility + beta (lower is better)
Cost 12% expense ratio (lower is better)
Liquidity 8% AUM (log scale)

classic (used when --scoring-model classic):

Pillar Weight Metrics
Returns 40% 3y avg, 5y avg, 12m return
RiskAdj 25% Sharpe proxy (r12 - rf) / σ, annualized volatility
Size 15% AUM (log scale)
Cost/Yield 20% expense ratio (lower=better), dividend yield

Universes

When no -t is given, InvestDayTip uses curated universes:

  • US stocks — 121 large-caps across all S&P sectors (src/investdaytip/universe.py)
  • US ETFs — 41 broad-market, factor, sector and bond ETFs (etf_universe.py)
  • EU stocks — 99 large-caps from DAX, CAC, FTSE 100, IBEX, AEX, SMI, FTSE MIB, Nordics (eu_universe.py)
  • EU UCITS ETFs — 35 broad, sector and bond UCITS ETFs (eu_etf_universe.py)
  • Asia stocks — 110 large-caps from Japan, Hong Kong, Singapore, India, South Korea, Taiwan, and Australia (asia_universe.py)
  • Asia ETFs — 17 broad-market, country-specific, and sector ETFs with significant Asian exposure (asia_etf_universe.py)
  • Superinvestor stocks — 101 consensus picks held by ≥2 of ~82 top investors tracked by DataRoma 13F filings (superinvestor_universe.py)

Tickers use Yahoo Finance suffixes:

  • US: no suffix (AAPL, MSFT)
  • EU: .DE Xetra · .PA Paris · .AS Amsterdam · .L London · .MC Madrid · .MI Milan · .SW Swiss
  • Asia: .T Tokyo · .HK Hong Kong · .SI Singapore · .NS NSE India · .KS Korea · .TW Taiwan · .AX Australia

Ticker File Examples

The repository includes ready-to-use ticker sets in tickers-files-examples/ for thematic analyses:

  • artificial_intelligence_relevant_tickers.txt
  • biotech_relevant_tickers.txt
  • energy_relevant_tickers.txt
  • eu_etfs_relevant_tickers.txt
  • financial_relevant_tickers.txt
  • health_relevant_tickers.txt
  • pharma_relevant_tickers.txt
  • quantum_computing_relevant_tickers.txt
  • semiconductors_relevant_tickers.txt
  • space_relevant_tickers.txt
  • spain_relevant_tickers.txt
  • technology_relevant_tickers.txt

Example:

investdaytip -n 15 --tickers-file tickers-files-examples/artificial_intelligence_relevant_tickers.txt --export-html

After export, preview the generated file in a browser by running:

./preview.sh

Then open the generated report from:

http://localhost:8000/<generated-file-name>.html

Shell tab completion

Requires the argcomplete package (installed automatically with pip install investdaytip):

# Enable for the current session:
eval "$(register-python-argcomplete investdaytip)"

# Make it permanent (add to ~/.zshrc or ~/.bashrc):
echo 'eval "$(register-python-argcomplete investdaytip)"' >> ~/.zshrc

Once enabled, try investdaytip -<TAB> or investdaytip --region <TAB>.


Data Source

All market data is fetched live from Yahoo Finance via the yfinance library. Fundamentals come from Ticker.info, prices and trend metrics from Ticker.history(period="2y").

These libraries and endpoints are third-party services and remain subject to those providers' terms of use; generated reports therefore contain third-party data and are not covered by this repository's MIT license.

Dividend yield normalization: yfinance reports dividendYield inconsistently — most US tickers return a decimal (e.g. 0.054 = 5.4%) while some European tickers return an already-multiplied percentage (e.g. 4.05 = 4.05%). InvestDayTip normalizes any value greater than 1.0 by dividing by 100.

Reliable stock dividend yield: For stocks, the Yield column is computed directly from Ticker.dividends over the trailing twelve months divided by the current price, because yfinance's dividendYield field can be wildly wrong for some tickers (e.g. AAPL and V). When raw dividend history is unavailable, InvestDayTip falls back to the normalized dividendYield from Ticker.info.

Superinvestor data comes from DataRoma (https://www.dataroma.com), which aggregates publicly filed SEC Form 13F holdings for ~82 well-known investors. The data is fetched once and cached for 7 days. Use --superinvestor to enable this data and display the "Superinvestors" column in both the HTML report and the CLI table (disabled by default to avoid the extra requests).

Ticker normalization: When a company has multiple share classes (e.g., Alphabet's GOOGL and GOOG), DataRoma holdings are normalized to a single ticker (GOOGL) to avoid duplicate counting. This ensures the "Superinvestors" column reflects unique manager positions, not duplicated entries.

Local Cache

InvestDayTip includes an SQLite cache (~/.investdaytip/cache.db) created automatically on first fetch:

Data TTL
Prices & history 15 minutes
Fundamentals (info dict) 1 day
Financial statements (balance sheet, income, cash flow) 7 days
Dividends 7 days
Fear & Greed Index 1 hour
Superinvestor holdings 7 days

The cache uses per-thread SQLite connections with a write lock to support concurrent fetches safely. Use --no-cache to bypass the cache for a single run, or --cache-clear to purge all entries. Both flags work on the main and backtest subcommands. Caching is automatically disabled when running tests.


Project Structure

preview.sh                # Local static server for generated HTML reports
scripts/
├── scoring_baseline.py    # Backtest before/after comparison tool
├── factor_ic.py           # Factor IC analysis (which metrics predict returns)
├── pit_snapshot.py        # StockFit PIT statement snapshot builder
└── compare_data_sources.py # yfinance vs yahooquery vs FMP field comparison
src/investdaytip/
├── __init__.py            # Public API: get_recommendations
├── main.py                # CLI entry point + rich table rendering
├── advisor.py             # Interactive advisor: market pulse (VIX + macro), portfolio review, buy recs
├── backtest.py            # Historical stock scoring validation (stocks only)
├── dataroma.py            # DataRoma superinvestor holdings client (13F aggregation)
├── html_export.py         # Self-contained HTML report exporter
├── recommender.py         # Concurrent orchestration
├── cache.py               # SQLite caching layer (per-thread connections, WAL mode)
├── data_source.py         # yfinance wrapper + dataclasses (StockData / EtfData)
├── data_source_fmp.py     # FMP wrapper (alternative data source, 6 endpoints/ticker)
├── data_source_yahooquery.py # Yahooquery batch data source
├── data_source_stockfit.py # StockFit client: PIT statements, insights, plan detection, live source
├── financial_health.py    # Piotroski F-Score, Altman Z, YoY-improvement flags
├── deep_dive.py           # Per-ticker deep report (score + research + diagnostics)
├── risk_signals.py        # Keyless devil's advocate layer (bear-case bullets)
├── scoring.py             # Pure scoring functions (score_stock, score_etf)
├── sentiment.py           # CNN Fear & Greed Index fetch
├── universe.py            # US stock universe
├── etf_universe.py        # US ETF universe
├── superinvestor_universe.py  # Superinvestor consensus universe (DataRoma 13F)
├── eu_universe.py         # EU stock universe
├── eu_etf_universe.py     # EU UCITS ETF universe
├── asia_universe.py       # Asia stock universe
└── asia_etf_universe.py   # Asia ETF universe
portfolios/               # Portfolio ticker files
advisor_recommendations/   # Advisor-generated HTML reports (git-ignored)
tests/
├── conftest.py            # Global fixtures (cache off, network guard, temp snapshot dir)
├── test_integration.py    # End-to-end integration tests (sorting, filters, CLI, export)
├── test_advisor.py        # Advisor tests (VIX, macro regime, bubble risk)
├── test_backtest.py       # Backtest engine tests (fetch, snapshots, scoring, cache, interpret)
├── test_recommender.py    # Recommendation orchestration tests
├── test_main.py           # CLI helper tests
├── test_html_export.py    # HTML export tests
├── test_scoring.py        # Stock scoring tests
├── test_scoring_quant.py  # Quant model tests (five factors, improvement sub-score)
├── test_etf_scoring.py    # ETF scoring tests
├── test_financial_health.py # Piotroski / Altman / improvement-flag tests
├── test_sentiment.py      # Fear & Greed sentiment tests
├── test_cache.py          # SQLite cache tests
├── test_universes.py      # Universe integrity tests
├── test_data_source.py    # yfinance data fetching tests
├── test_data_source_fmp.py # FMP data fetching tests
├── test_data_source_yahooquery.py # Yahooquery data source tests
├── test_data_source_stockfit_pit.py # StockFit PIT layer tests (mocked HTTP)
├── test_data_source_stockfit_live.py # StockFit live data source tests (mocked HTTP)
├── test_fundamental_insights.py # StockFit insights section tests
├── test_pit_snapshot.py   # PIT snapshot layer tests
├── test_deep_dive.py      # Deep-dive report tests
├── test_stockfit_plan.py  # StockFit tier detection & capability gating tests
└── test_dataroma.py       # DataRoma client tests
tickers-files-examples/
├── semiconductors_relevant_tickers.txt
├── artificial_intelligence_relevant_tickers.txt
├── quantum_computing_relevant_tickers.txt
├── energy_relevant_tickers.txt
├── space_relevant_tickers.txt
├── technology_relevant_tickers.txt
├── spanish_relevant_tickers.txt
├── pharma_relevant_tickers.txt
├── biotech_relevant_tickers.txt
├── health_relevant_tickers.txt
└── financial_relevant_tickers.txt

Limitations & Caveats

  • No currency normalization — prices, market caps and AUM stay in native currency
  • Currency filter (-c) compares against yfinance's reported currency field; tickers with a missing/unknown currency are always kept (a missing field shouldn't silently drop a candidate)
  • min_market_cap filter (--min-market-cap) is applied against raw native-currency figures; when active, tickers with a missing market cap are excluded
  • Some European tickers change Yahoo symbols over time; if a ticker is delisted in Yahoo it's silently skipped
  • ETF expense ratios are sometimes missing in yfinance — the scorer falls back to a slightly optimistic default (60) in that case
  • Long-term, fundamental-driven model: not suitable for short-term/day trading signals

Testing

pip install -e ".[dev]"   # pytest, ruff, mypy
pytest -q                 # run the suite
ruff check src tests      # lint
mypy                      # type-check

335 tests across 16 test files. The scoring engine is purely functional and tested without network calls; an autouse guard in tests/conftest.py fails fast if a test reaches yfinance unmocked. Integration tests mock the full recommend() → main() → export pipeline.


Contributing

Contributions are welcome! See CONTRIBUTING.md.


Disclaimer

This is not financial advice. InvestDayTip is a research and decision-support tool that applies a deterministic scoring model to publicly available data. Scores, buy/hold/sell labels and any AI-generated commentary are model outputs, not personal recommendations to buy or sell any security. Backtests are hypothetical simulations over historical data — past performance is not indicative of future results. Always do your own research and consult a licensed advisor before making investment decisions.

Third-party names (Yahoo Finance, DataRoma, Financial Modeling Prep, StockFit, Seeking Alpha, OpenCode, …) are used for identification only and imply no affiliation or endorsement.


License

MIT

The software is MIT-licensed. Generated output is not: reports and datasets produced by the tool contain third-party market data (Yahoo Finance via yfinance/yahooquery, DataRoma 13F aggregations, and FMP or StockFit when configured) and remain subject to those providers' terms of use.

Metadata

Release files for investdaytip 0.17.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for investdaytip 0.17.5
File Size Uploaded
investdaytip-0.17.5.tar.gz 729.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for investdaytip 0.17.5
File Interpreter ABI Platform
investdaytip-0.17.5-py3-none-any.whl Python 3 none any Details

Total release size: 889.5 kB

Release files / investdaytip-0.17.5.tar.gz

Download URL investdaytip-0.17.5.tar.gz
Size 729.9 kB
Tags Source
SHA-256 checksum
How to use checksums
72249adf115baa2f52bb2a7f63fb4b80c6422d936069b077ff7ae2e100a23e08
BLAKE2b-256 checksum
How to use checksums
5fd2fa322f1da7c0cb44431493a9102da690afde381c99def1379423ff5552a5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Release files / investdaytip-0.17.5-py3-none-any.whl

Download URL investdaytip-0.17.5-py3-none-any.whl
Size 159.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
54f554e3527a7579832b1c4805836f2cc8a6e1a23550ef65642b713370b3b0e4
BLAKE2b-256 checksum
How to use checksums
398e187eb76fcf78c2900319b8a23fccc49cd84bd6225884bdea8bdd54c19037
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page