From 7dbacdbf0fa835f0093bd70907dbdc75b7132522 Mon Sep 17 00:00:00 2001 From: Kenrick Tandrian <60643640+KenTandrian@users.noreply.github.com> Date: Sat, 31 Jan 2026 14:43:04 +0700 Subject: [PATCH] Feature/extract top holdings from Yahoo Finance for ETF and mutual funds (#6254) * Extract top holdings from Yahoo Finance for ETF and mutual funds * Update changelog --- CHANGELOG.md | 4 ++++ .../yahoo-finance/yahoo-finance.service.ts | 17 +++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1092b049..a3fb00a66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Added the ability to fetch top holdings for ETF and mutual fund assets from _Yahoo Finance_ + ### Changed - Removed the deprecated `firstBuyDate` in the portfolio calculator diff --git a/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts b/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts index 65bcd6c06..97c875360 100644 --- a/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts +++ b/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts @@ -135,10 +135,10 @@ export class YahooFinanceDataEnhancerService implements DataEnhancerInterface { shortName, symbol }: { - longName: Price['longName']; - quoteType: Price['quoteType']; - shortName: Price['shortName']; - symbol: Price['symbol']; + longName?: Price['longName']; + quoteType?: Price['quoteType']; + shortName?: Price['shortName']; + symbol?: Price['symbol']; }) { let name = longName; @@ -217,6 +217,15 @@ export class YahooFinanceDataEnhancerService implements DataEnhancerInterface { }); } } + + response.holdings = assetProfile.topHoldings.holdings.map( + ({ holdingName, holdingPercent }) => { + return { + name: this.formatName({ longName: holdingName }), + weight: holdingPercent + }; + } + ); } else if ( assetSubClass === 'STOCK' && assetProfile.summaryProfile?.country