Skip to content

Releases: furic/richfolio

v1.7.0 — Multi-AI Mode (Gemini + Claude) & 3 More Languages

05 Jun 02:20

Choose a tag to compare

What's New

Multi-AI Mode — Gemini + Claude Side by Side

Richfolio is no longer Gemini-only. The analysis layer was refactored into a pluggable provider architecture, and Anthropic Claude is now a first-class second provider.

  • Set one key (GEMINI_API_KEY or ANTHROPIC_API_KEY) → identical behaviour to v1.6, single-AI rendering, no surprises.
  • Set both keys → multi-AI mode auto-engages: providers run concurrently, scores aggregate per ticker, every email and Telegram message shows a per-AI breakdown beneath each consensus recommendation.

How aggregation works

  • Consensus action via mode-of-votes with confidence-sum tiebreaker (see src/aiAggregation.ts)
  • STRONG BUY requires unanimous agreement — if any provider dissents, the consensus caps at BUY. Preserves STRONG BUY's "rare, high-conviction" semantics.
  • Averaged confidence drives within-tier sort, displayed prominently with an avg tag
  • Agreement badge (unanimous / majority / split) shown next to the action
  • Suggested buy value / limit price inherited from the highest-confidence provider that voted consensus — deterministic, no muddled averages

Graceful degradation

  • If a provider throws mid-run (rate-limited, network blip, quota hit), surviving providers continue.
  • If exactly one provider survives, that run renders as single-AI mode.
  • If all providers fail, falls back to gap-based recommendations (today's behaviour with no AI key).

Reasoning history is now per-provider

Each AI sees only its own past convictions in the "HISTORICAL CONTEXT" prompt section. Storage schema bumped v1 → v2; existing history is dropped on first load (7 days isn't precious data).

Pluggable detailed analysis (STRONG BUY page)

The dedicated "More Details" analysis page for STRONG BUY tickers can now be generated by either provider. Default: first available. Override:

Env var Effect
AI_DETAILED_PROVIDER=gemini Force Gemini
AI_DETAILED_PROVIDER=claude Force Claude
CLAUDE_MODEL=claude-haiku-4-5-20251001 Use Haiku for cheaper Claude calls

New Architecture (Extensible)

Adding a third provider (OpenAI, Mistral, whatever) is now ~50 lines: implement the AIProvider interface in src/providers/, register it in src/providers/index.ts, done. The orchestrator, guard pipeline, aggregation, reasoning history, and renderers all flow through automatically — no consumer changes needed.

src/providers/
├── types.ts        # AIProvider interface + canonical AIBuyRecommendation
├── prompts.ts      # SDK-agnostic prompt builders
├── gemini.ts       # GeminiProvider (Google @google/genai)
├── claude.ts       # ClaudeProvider (Anthropic @anthropic-ai/sdk, tool-use)
└── index.ts        # Provider registry — buildActiveProviders()

src/aiOrchestrator.ts  # Runs active providers, applies guards, sorts
src/aiAggregation.ts   # Consensus action, average, unanimity rule

3 More Languages: Japanese, Korean, Spanish

The docs site now ships in 6 languages total:

  • English (default)
  • 简体中文 (Simplified Chinese)
  • 繁體中文 (Traditional Chinese)
  • 日本語 (Japanese) — new
  • 한국어 (Korean) — new
  • Español (Spanish, neutral / Latin-American) — new

Language picker in the docs header was converted from inline links to a compact dropdown <select> to scale cleanly as more locales are added.

Bug Fixes

  • fix(docs): removed // comments from the language switcher inline script — Jekyll's HTML compression collapsed the script onto a single line, turning // into a runaway comment that broke the parser with "Unexpected end of input". Dropdown navigation now works in production.

Docs

  • docs/api-keys.md restructured around the multi-AI mode (single/multi comparison table at top, dedicated Anthropic Claude section, removed obsolete "Using a different AI model" sub-section)
  • docs/deployment.md "Add Secrets & Variables" table now lists ANTHROPIC_API_KEY, CLAUDE_MODEL, AI_DETAILED_PROVIDER
  • docs/troubleshooting.md Gemini quota fix now notes Claude continues alone when both keys are set; "empty email" bullet expanded into 4 combinations
  • All of the above translated to the 5 non-English locales

Upgrading

If you already had GEMINI_API_KEY set: nothing breaks, nothing changes. v1.7 is fully backward compatible with single-AI configurations.

To opt into multi-AI mode:

  1. Sign up at console.anthropic.com and create an API key
  2. Add ANTHROPIC_API_KEY as a GitHub Secret (and to your local .env)
  3. Optionally set CLAUDE_MODEL=claude-haiku-4-5-20251001 as a GitHub Variable for cheaper Claude calls
  4. Optionally set AI_DETAILED_PROVIDER=gemini or claude to pin who generates the STRONG BUY analysis page
  5. Next scheduled run picks up the new env automatically — no code deploy needed

Full Changelog: v1.6.0...v1.7.0

v1.6.0 — Bond ETF Timing Signals & i18n Docs

22 May 03:07

Choose a tag to compare

What's New

Bond ETF Timing Signals — No More Flatline 75% BUY for BSV

The short-duration bond ETF framework (BSV, SHY, VGSH, SCHO, BIL, SHV, SGOV, ...) was previously gap-capped: any meaningful allocation gap returned a fixed 75% BUY every single day, regardless of whether today was actually a good entry. This release replaces that with a base + timing-modifiers scoring system so BSV's daily conviction reflects real entry-quality signals.

  • 90-day price percentile (new on TechnicalData.pricePercentile90d) — where today's price sits in its rolling 90-day window. Bottom 20% gets +12pts (cheap entry), top 20% gets −15pts (poor entry).
  • 10-year treasury 20-day change (new on MacroIndicators.treasury10yChange20d) — bonds get cheaper when rates rise. Rising fast (>+0.15%) adds +6pts; falling fast (<−0.15%) subtracts 12pts to discourage chasing rallies.
  • Distribution yield (new on QuoteData.distributionYield, from Yahoo summaryDetail.yield) — high SEC yield (>4.5%) adds +3pts, low yield (<3%) subtracts 2pts.
  • Per-tier confidence ceilings: gap≥5% can reach 95, gap 3-5% reaches 85, gap 1-3% reaches 72. Gap<1% stays HOLD.
  • No more limit-price clutter: short-duration bonds never get a suggestedLimitPrice — the daily range is too tight for the suggestion to mean anything.
  • AI reason field now frames bond recommendations around percentile + rate direction, never RSI/MACD (which are noise for rate-driven instruments).

Net effect: BSV will swing from ~35% (poor entry day) up to 90%+ (great entry day — near 90-day low, rates spiking, high yield, big gap) instead of flatlining at 75% every day.

Action-Tier Sort

AI recommendations are now sorted STRONG BUY → BUY → HOLD → WAIT (with confidence descending within each tier), applied as a final pass in aiAnalyze after the guard pipeline. Previously the email/Telegram render order was confidence-only, which meant a high-confidence bond BUY could rank above a genuine equity STRONG BUY. Now equity STRONG BUYs always appear at the top.

Documentation: i18n Site

  • Jekyll polyglot scaffolding for the docs site, supporting English (default), Simplified Chinese, and Traditional Chinese
  • Full translations of how-it-works.md, features.md, and references.md for both Chinese variants
  • hreflang and canonical <link> tags emitted for each language to improve SEO
  • Language switcher in the header (vertically centered fix)

References

  • OpenAlice promoted to #2 in the inspiration credits
  • hvkshetry Medium article added

Guards

  • Absolute confidence ceiling for short-duration bond ETFs raised 88 → 95 to match the equity confidence cap (guardConfidenceSanity). The action-tier sort prevents visual displacement of equity STRONG BUYs.
  • Bond-cap guard now strips suggestedLimitPrice/limitPriceReason for short-duration bonds (safety net in case the AI suggests one anyway).
  • Gap-based confidence ceiling for bonds removed — driven by the new timing modifiers instead.

Chore

  • Claude Code project settings added (.claude/settings.json) with Playwright MCP and python3 permissions

Full Changelog: v1.5.0...v1.6.0

v1.5.0 — International Currency Support

28 Apr 10:24
ddffe32

Choose a tag to compare

What's New

International Currency Support

  • Portfolio now supports non-USD tickers (LSE, Frankfurt, and other exchanges) — configure defaultCurrency in config.json and holdings are automatically converted
  • FX rates fetched live from Yahoo Finance (GBPUSD=X convention) in a single batch per run — no extra API key needed
  • Sub-unit fix for exchanges quoting in fractional units: GBp/GBX (LSE pence → GBP), ILA (TASE agorot), ZAc (JSE cents) automatically divided by 100
  • All prices, limit orders, dividends, suggested buy values, and portfolio stats displayed in your default currency
  • Multi-currency caveat shown in emails and Telegram when the portfolio spans currencies
  • totalPortfolioValueUSD deprecated in favour of totalPortfolioValue + defaultCurrency in config

Ticker Name Tooltips

  • Company full names shown as hover tooltips on ticker symbols in all emails (daily, intraday, weekly, refresh)
  • Names sourced from Yahoo Finance longName field

CI & Code Quality

  • GitHub Actions CI now runs on all pull requests — catches type errors and formatting drift before merge
  • Prettier formatting enforced across src/ and test/
  • Unit tests (63 tests via node:test, zero dependencies) covering formatMoney, applyFxRate, and SUB_UNIT_FIX
  • npm test — unit tests; npm run smoke — live API smoke tests (manual)

Bug Fixes & Improvements

  • Two-stage AI analysis (Observe → Decide) improves STRONG BUY consistency by separating data parsing from decision-making
  • Earnings calendar guard: hard HOLD if earnings ≤3 days, cap at BUY if ≤7 days
  • Guard pipeline (guards.ts) programmatically enforces STRONG BUY criteria as a post-AI safety net
  • ATR (Average True Range), Stochastic %K/%D, and OBV trend added to technical indicators
  • News sentiment scoring: each headline rated bullish/bearish/neutral + impact with overall per-ticker sentiment fed to AI
  • Reasoning persistence: 7-day rolling history of AI conviction trends shown to Gemini each run
  • Fixed STRONG BUY over-strictness and bond ETF confidence constant

Full Changelog: v1.4.0...v1.5.0

v1.4.0 — Macro Indicators & Smarter STRONG BUY

05 Apr 12:52

Choose a tag to compare

What's New

Macro Environment Context

  • AI now receives real-time macro indicators (VIX, 10Y Treasury yield, S&P 500, Oil/WTI, USD/DXY) from Yahoo Finance — no extra API key needed
  • Gemini writes macro-aware risk assessments instead of generic boilerplate (e.g. "elevated VIX + high yields suggest caution")
  • Fed to both daily analysis and detailed STRONG BUY analysis prompts

Smarter STRONG BUY Criteria

  • Price below 200-day MA added as a price-level signal — ETFs (which lack P/E data) now have a viable path to STRONG BUY without requiring near-52w-low
  • Entry signals now require at least 1 price-level signal (P/E below avg, 52w position <30%, or below 200MA) — momentum signals alone no longer sufficient
  • Golden cross correctly ignored when price is below 200MA (lagging artifact, not bullish)

Bond ETF Framework

  • Two-tier framework: short-duration (BSV, SHY, etc.) hard-capped at BUY ≤65%; long-duration (TLT, BND, etc.) eligible for STRONG BUY at rate cycle peaks
  • RSI/MACD/momentum explicitly excluded as buy signals for all bond ETFs

Bug Fixes

  • Fixed 52-week position misinterpretation in detailed analysis — Gemini no longer confuses "% of annual range" with "% of 52w high"
  • Fixed golden cross framing in detailed analysis when price is below both MAs
  • Three-layer news filtering (financial phrases → language filter → Gemini relevance) reduces false positive headlines

Technical Indicators

  • MACD (12/26/9) with bullish/bearish crossover detection
  • Bollinger Bands with %B, bandwidth, and squeeze detection
  • Explicit conflict resolution hierarchy (MACD for trending, Bollinger for range-bound)
  • Bottom-fishing model: stricter threshold for stocks/ETFs (3+ indicators) vs crypto (2+)

Other

  • Intraday alerts refocused on STRONG BUY signals only
  • Baseline updated after intraday alert to prevent duplicate notifications
  • Auto-generated news search terms from Yahoo Finance company names
  • Docs rewritten as GitHub-first for non-technical users

Full Changelog: v1.3.0...v1.4.0

v1.3.0 — Refresh Analysis & Smarter Intraday Alerts

09 Mar 08:19

Choose a tag to compare

What's New

Refresh Analysis Mode

Re-analyze a single ticker with the latest price (including after-hours/pre-market) to get an updated limit order and analysis URL.

npm run refresh -- SMH

Also available via GitHub Actions: Run workflow → mode: refresh → ticker: SMH

  • Uses Yahoo Finance postMarketPrice / preMarketPrice (zero extra API calls)
  • Sends email + Telegram with updated analysis URL
  • Useful when you see a STRONG BUY alert after market close and the price has moved

Smarter Intraday Alerts

Intraday alerts now focus exclusively on STRONG BUY signals:

  1. Upgraded to STRONG BUY — any action → STRONG BUY
  2. Downgraded from STRONG BUY — STRONG BUY → any other action
  3. Confidence changed ≥10 — while staying at STRONG BUY

Other Changes

  • Fix: TradingView chart now renders correctly on the analysis page
  • Fix: Detailed analysis uses Gemini Flash instead of Pro (avoids quota issues)
  • Docs: Added "Who Should Use This" section to README
  • Docs: Gemini free-tier quota gotcha and model swap guide
  • UI: Repo icon and Google Gemini badge

Full Changelog: v1.2.0...v1.3.0

v1.2.0 — STRONG BUY Analysis Page

05 Mar 10:45

Choose a tag to compare

What's New

STRONG BUY Analysis Page

STRONG BUY tickers now include a "More Details" link in emails and Telegram messages. Clicking it opens a dedicated analysis page on GitHub Pages featuring:

  • Interactive TradingView chart — 6-month candlestick with SMA50, SMA200, and RSI overlays
  • Detailed buy thesis — 3-4 paragraph analysis generated by Gemini 2.5 Pro
  • Risk analysis — specific risk factors to watch
  • Key metrics grid — price, P/E, 52-week position, RSI, moving averages, momentum
  • Fundamentals — ROE, debt/equity, margins, growth, analyst target
  • Action summary — suggested investment amount, limit order price with reasoning

All data is compressed and embedded in the URL hash — no server-side logic needed. The page works offline once loaded.

STRONG BUY Analysis

Other Changes

  • Fix intraday baseline — use age check instead of date string comparison
  • CONFIG_JSON moved from Actions Secret to Variable for easier editing
  • RECIPIENT_EMAIL moved from Actions Secret to Variable
  • Cleaned up duplicate setup.md (content already split across doc pages)
  • Updated screenshots, mockups, and documentation

New Files

  • src/detailedAnalysis.ts — Gemini 2.5 Pro call for detailed buy thesis + risk analysis
  • src/analysisUrl.ts — zlib compression + base64url encoding into URL hash
  • docs/analysis/index.html — Static analysis page (decodes URL hash client-side)

Full Changelog: v1.1.0...v1.2.0

v1.1.0 — Value Investing & Crypto Bottom-Fishing

26 Feb 07:48

Choose a tag to compare

What's New in v1.1.0

Two new AI analytical frameworks embedded into the Gemini prompt — zero additional API calls, stays within free tier. Inspired by @xingpt's AI agent skills article on BlockTempo.

New Features

  • Value Investing Framework — AI rates individual stocks A–D based on five fundamental criteria: ROE > 15%, debt/equity < 50%, FCF/operating CF > 80%, positive earnings growth, and price below analyst target. Displayed as colored badges in email and Telegram
  • Crypto Bottom-Fishing Model — AI detects BTC/ETH accumulation zones using four indicators: RSI < 30, volume contraction > 20%, price below 200-day MA, and death cross. 2+ triggers a bottom signal, 3+ strongly considers STRONG BUY with DCA recommendation

How It Works

Both features are prompt-only enhancements — structured analytical frameworks injected into the single Gemini call:

  • Fundamental data (ROE, debt/equity, FCF, margins, growth, analyst targets) comes from Yahoo Finance's financialData module, added to the existing quoteSummary call — zero extra API overhead
  • Volume change (7-day avg vs prior 30-day avg) computed from existing chart data for selling exhaustion detection
  • Value ratings adjust AI confidence: A boosts ~10 points, D reduces ~10 points
  • Bottom signals shown in daily email, intraday alerts, and Telegram messages

Screenshots

Daily Brief Intraday Alert Weekly Rebalance
Daily Intraday Weekly

Files Changed

File Change
src/fetchPrices.ts Added financialData module + 9 new QuoteData fields
src/fetchTechnicals.ts Added volumeChange7d computation
src/aiAnalysis.ts Extended schema, prompt with 2 frameworks
src/email.ts Value rating badges + bottom signal rendering
src/telegram.ts Value rating + bottom signal inline
src/intradayCompare.ts Propagated new fields
src/intradayEmail.ts Rendered new fields in alerts

Upgrading

No config changes needed. Just pull the latest code — the new features activate automatically when Gemini is configured. Existing config.json and .env files work as-is.

Full Changelog: v1.0.0...v1.1.0

v1.0.0 — Technical Momentum & Limit Orders

25 Feb 14:16

Choose a tag to compare

What's New

Richfolio v1.0.0 — a zero-maintenance portfolio monitoring system with AI-powered buy signals, delivered daily via email and Telegram.

Features

  • AI Buy Recommendations — Gemini 2.5 Flash analyzes valuation, allocation gaps, news sentiment, technicals, and risk
  • Technical Momentum Signals — SMA50, SMA200, RSI(14), golden/death cross, momentum classification for every ticker
  • Limit Order Prices — AI-suggested limit prices based on nearby support (moving averages, recent lows, round numbers)
  • Allocation Gap Analysis — current vs target %, with suggested buy amounts
  • Dynamic P/E Signals — trailing P/E compared against historical averages from Yahoo Finance
  • ETF Overlap Detection — reduces buy priority when you hold overlapping stocks
  • 52-Week Range Signals — highlights tickers near their 52w low or high
  • News Digest — top headlines per ticker from NewsAPI
  • Portfolio Health — weighted beta, estimated annual dividend income
  • Intraday Alerts — periodic checks that alert only when buy signals strengthen vs morning brief
  • Weekly Rebalancing Report — drift analysis with BUY/TRIM/OK actions
  • Dual Delivery — dark-themed HTML email + condensed Telegram message

Stack

All free-tier services — $0/month to run:

Component Service
Prices & Fundamentals Yahoo Finance (yahoo-finance2)
News NewsAPI.org (100 req/day)
AI Analysis Google Gemini 2.5 Flash (250 req/day)
Email Resend.com (3,000/month)
Telegram Telegram Bot API
Scheduler GitHub Actions (cron)

Getting Started

  1. Fork this repo
  2. Add secrets (CONFIG_JSON, RESEND_API_KEY, RECIPIENT_EMAIL)
  3. Run manually or wait for the daily cron (8am AEST)

See the full documentation for setup details.