From e0bdf06a96ec0af54dedc526edc70d58f4924d08 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 13 Aug 2026 17:23:48 +0200 Subject: [PATCH 1/5] Task/extend personal finance tools (20260813) (#7615) Extend personal finance tools --- libs/common/src/lib/personal-finance-tools.ts | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/libs/common/src/lib/personal-finance-tools.ts b/libs/common/src/lib/personal-finance-tools.ts index b3aae6a02..4fd866236 100644 --- a/libs/common/src/lib/personal-finance-tools.ts +++ b/libs/common/src/lib/personal-finance-tools.ts @@ -1252,6 +1252,19 @@ export const personalFinanceTools: Product[] = [ slogan: 'Know where your money is going', url: 'https://www.pocketsmith.com' }, + { + categories: ['FINANCIAL_PLANNING', 'NET_WORTH_TRACKING'], + hasFreePlan: true, + hasSelfHostingAbility: false, + key: 'portfolio-coach', + languages: ['English'], + name: 'Portfolio Coach', + origin: 'GB', + platforms: ['WEB'], + pricingPerYear: '£120', + slogan: 'Know your wealth. Ask it anything.', + url: 'https://portfoliocoach.co.uk' + }, { categories: ['DIVIDEND_TRACKING', 'STOCK_TRACKING'], hasFreePlan: false, @@ -1276,6 +1289,18 @@ export const personalFinanceTools: Product[] = [ slogan: 'Tools for Better Investors', url: 'https://www.portfoliovisualizer.com' }, + { + categories: ['DIVIDEND_TRACKING', 'ETF_TRACKING', 'STOCK_TRACKING'], + hasFreePlan: true, + hasSelfHostingAbility: false, + key: 'portfolioglance', + languages: ['English', 'Polski'], + name: 'PortfolioGlance', + origin: 'PL', + platforms: ['WEB'], + slogan: 'One look. Clear picture of your portfolio.', + url: 'https://www.portfolioglance.com' + }, { categories: ['STOCK_TRACKING'], hasFreePlan: true, @@ -1551,6 +1576,19 @@ export const personalFinanceTools: Product[] = [ 'Your financial life in a spreadsheet, automatically updated each day', url: 'https://tiller.com' }, + { + categories: ['CRYPTOCURRENCY', 'DIVIDEND_TRACKING', 'STOCK_TRACKING'], + hasFreePlan: true, + hasSelfHostingAbility: false, + key: 'tinywallet', + languages: ['Deutsch', 'English'], + name: 'TinyWallet', + origin: 'DE', + platforms: ['WEB'], + pricingPerYear: '€35', + slogan: 'Your key to empowered wealth management', + url: 'https://www.tinywallet.de' + }, { founded: 2011, hasFreePlan: false, From c9a45e9f538ee934e2e45b765a18c1443722b04f Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 13 Aug 2026 17:24:12 +0200 Subject: [PATCH 2/5] Task/refresh cryptocurrencies list (20260813) (#7613) * Update cryptocurrencies.json * Update changelog --- CHANGELOG.md | 6 + .../cryptocurrencies/cryptocurrencies.json | 127 +++++++++--------- 2 files changed, 71 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f55eb8e7e..2dd4c0cb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Refreshed the cryptocurrencies list + ## 3.49.0 - 2026-08-12 ### Changed diff --git a/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json b/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json index 9eac78aa4..69d455264 100644 --- a/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json +++ b/apps/api/src/assets/cryptocurrencies/cryptocurrencies.json @@ -113,7 +113,7 @@ "2OMB": "2omb Finance", "2SHARES": "2SHARE", "2TF": "2TF", - "2Z": "DoubleZero USD Price", + "2Z": "DoubleZero", "300F": "300FIT", "314DAO": "Tonken 314 DAO", "32BIT": "32Bitcoin", @@ -212,7 +212,7 @@ "AAVEGOTCHIFOMO": "Aavegotchi FOMO", "AAX": "Academic Labs", "AAZ": "ATLAZ", - "AB": "Arma The Battle Ground USD Price", + "AB": "Arma The Battle Ground", "AB1INCH": "1inch (Avalanche Bride)", "ABA": "EcoBall", "ABAT": "Aave BAT", @@ -806,7 +806,7 @@ "AMY": "Amygws", "AMZE": "The Amaze World", "AMZNON": "Amazon (Ondo Tokenized)", - "AMZNX": "Amazon tokenized stock (xStock) USD Price", + "AMZNX": "Amazon tokenized stock (xStock)", "ANA": "Nirvana ANA", "ANAL": "AnalCoin", "ANALOS": "analoS", @@ -845,7 +845,7 @@ "ANIM": "Animalia", "ANIMA": "Realm Anima", "ANIME": "Animecoin", - "ANIME35319": "Animecoin USD Price", + "ANIME35319": "Animecoin", "ANIMECOIN": "Animecoin", "ANIMEONBASE": "Anime", "ANIMETOKEN": "Anime Token (animetoken.in)", @@ -1016,7 +1016,7 @@ "ARBUZ": "ARBUZ", "ARBYS": "Arbys Token", "ARC": "AI Rig Complex", - "ARC23486": "Arcadeum USD Price", + "ARC23486": "Arcadeum", "ARCA": "Legend of Arcadia", "ARCAD": "Arcadeum", "ARCADE": "ARCADE", @@ -1367,7 +1367,7 @@ "AVGOX": "Broadcom tokenized stock (xStock)", "AVH": "Animation Vision Cash", "AVI": "Aviator", - "AVICI": "Avici USD Price", + "AVICI": "Avici", "AVINOC": "AVINOC", "AVIVE": "Avive World", "AVL": "Aston Villa Fan Token", @@ -1390,7 +1390,7 @@ "AWAX": "AWAX", "AWBTC": "Aave interest bearing WBTC", "AWC": "Atomic Wallet Coin", - "AWE": "AWE Network USD Price", + "AWE": "AWE Network", "AWK": "Awkward Monkey Base", "AWM": "Another World", "AWNEX": "AWNEX token", @@ -1452,7 +1452,7 @@ "AZUR": "Azuro Protocol", "AZURE": "Azure Wallet", "AZY": "Amazy", - "B": "BUILDon USD Price", + "B": "BUILDon", "B01": "b0rder1ess", "B1P": "B ONE PAYMENT", "B2": "B² Network", @@ -1974,7 +1974,7 @@ "BEPE": "Blast Pepe", "BEPR": "Blockchain Euro Project", "BEPRO": "BEPRO Network", - "BERA": "Berachain USD Price", + "BERA": "Berachain", "BERAETH": "Berachain Staked ETH", "BERASTONE": "StakeStone Berachain Vault Token", "BERC": "Fair BERC20", @@ -2129,6 +2129,7 @@ "BIKE": "White Bike", "BIKI": "BIKI", "BILL": "TillBilly", + "BILL39545": "Billions Network", "BILLI": "Billi", "BILLICAT": "BilliCat", "BILLY": "Billy", @@ -2614,7 +2615,7 @@ "BONDLYV1": "Bondly Finance", "BONDX": "BondX", "BONE": "Shibarium Wrapped BONE", - "BONE11865": "Bone ShibaSwap USD Price", + "BONE11865": "Bone ShibaSwap", "BONEBONE": "Bone", "BONES": "Moonshots Farm", "BONESCOIN": "BonesCoin", @@ -3715,7 +3716,7 @@ "CHILL": "ChillPill", "CHILLAX": "Chillax", "CHILLCAT": "Chillchat", - "CHILLGUY": "Just a chill guy USD Price", + "CHILLGUY": "Just a chill guy", "CHILLHOUSE": "Chill House", "CHIM": "Chimera", "CHINA": "China Coin", @@ -3965,7 +3966,7 @@ "CO2": "CO2 Token", "COA": "Alliance Games", "COAI": "ChainOpera AI", - "COAI38489": "ChainOpera AI USD Price", + "COAI38489": "ChainOpera AI", "COAL": "BitCoal", "COB": "Cobinhood", "COBE": "Castle of Blackwater", @@ -5260,7 +5261,7 @@ "DOFI": "Doge Floki Coin", "DOG": "Dog (Runes)", "DOG11557": "The Doge NFT", - "DOG30933": "Dog (Runes) USD Price", + "DOG30933": "Dog (Runes)", "DOGA": "DOGAMÍ", "DOGACOIN": "DogaCoin", "DOGAI": "Dogai", @@ -5527,7 +5528,7 @@ "DRT": "DomRaider", "DRUGS": "Big Pharmai", "DRV": "Derive", - "DRV35014": "Derive USD Price", + "DRV35014": "Derive", "DRX": "DRX Token", "DRXNE": "Droxne", "DRZ": "Droidz", @@ -6077,7 +6078,7 @@ "ENRON": "Enron", "ENRX": "Enrex", "ENS": "Ethereum Name Service", - "ENSO": "Enso USD Price", + "ENSO": "Enso", "ENT": "Eternity", "ENTC": "ENTERBUTTON", "ENTER": "EnterCoin", @@ -6629,7 +6630,7 @@ "FEY": "Feyorra", "FF": "Forefront", "FF1": "Two Prime FF1 Token", - "FF38482": "Falcon Finance USD Price", + "FF38482": "Falcon Finance", "FFA": "Cryptofifa", "FFC": "FireflyCoin", "FFCT": "FortFC", @@ -6678,7 +6679,7 @@ "FIGHTPEPE": "FIGHT PEPE", "FIGHTRUMP": "FIGHT TRUMP", "FIGMA": "Figments Club", - "FIGRHELOC": "Figure HELOC USD Price", + "FIGRHELOC": "Figure HELOC", "FIH": "Fidelity House", "FIII": "Fiii", "FIL": "Filecoin", @@ -6955,7 +6956,7 @@ "FORGE": "Forge Finance", "FORK": "Gastro Advisor Token", "FORM": "Formation Fi", - "FORM23635": "Four USD Price", + "FORM23635": "Four", "FORMATION": "Formation FI", "FORMNET": "Form", "FORS": "Foresight", @@ -7555,7 +7556,7 @@ "GIFT": "GiftNet", "GIG": "GigaCoin", "GIGA": "Gigachad", - "GIGA30063": "Gigachad USD Price", + "GIGA30063": "Gigachad", "GIGABRAIN": "Gigabrain by virtuals", "GIGACAT": "GIGACAT", "GIGACHAD": "GigaChad", @@ -7911,7 +7912,7 @@ "GRID": "Grid+", "GRIDCOIN": "GridCoin", "GRIDZ": "GridZone.io", - "GRIFFAIN": "GRIFFAIN USD Price", + "GRIFFAIN": "GRIFFAIN", "GRIFT": "ORBIT", "GRIM": "GrimToken", "GRIMACE": "GrimaceCoin", @@ -8108,7 +8109,7 @@ "GZT": "Golden Zen Token", "GZX": "GreenZoneX", "Glo Dollar": "USDGLO", - "H": "Humanity Protocol USD Price", + "H": "Humanity Protocol", "H1": "Haven1", "H1DR4": "H1DR4 by Virtuals", "H2O": "H2O DAO", @@ -8545,7 +8546,7 @@ "HOSTAI": "Host AI", "HOT": "Holo", "HOT1": "Holo", - "HOT2682": "Holo USD Price", + "HOT2682": "Holo", "HOTCROSS": "Hot Cross", "HOTDOGE": "Hot Doge", "HOTKEY": "HotKeySwap", @@ -8952,7 +8953,7 @@ "INFX": "Influxcoin", "ING": "Infinity Games", "INI": "InitVerse", - "INIT": "Initia USD Price", + "INIT": "Initia", "INJ": "Injective", "INK": "Ink", "INN": "Innova", @@ -9293,7 +9294,7 @@ "JINDO": "JINDOGE", "JINDOGE": "Jindoge", "JIO": "JIO Token", - "JITOSOL": "Jito Staked SOL USD Price", + "JITOSOL": "Jito Staked SOL", "JIZZ": "JizzRocket", "JIZZLORD": "JizzLord", "JIZZUS": "JIZZUS CHRIST", @@ -9301,7 +9302,7 @@ "JK": "JK Coin", "JKC": "JunkCoin", "JKL": "Jackal Protocol", - "JLP": "Jupiter Perps LP USD Price", + "JLP": "Jupiter Perps LP", "JLY": "Jellyverse", "JM": "JustMoney", "JMC": "Junson Ming Chan Coin", @@ -9457,7 +9458,7 @@ "KAIM": "Kai Meme", "KAINET": "KAINET", "KAIRO": "Kairo", - "KAITO": "KAITO USD Price", + "KAITO": "KAITO", "KAKA": "KAKA NFT World", "KAKAXA": "KAKAXA", "KAKI": "Doge KaKi", @@ -9694,7 +9695,7 @@ "KISHU": "Kishu Inu", "KIT": "DexKit", "KITA": "KITA INU", - "KITE": "Kite USD Price", + "KITE": "Kite", "KITEAI": "KITEAI", "KITEHAI": "Kite", "KITKAT": "Remember KitKat", @@ -10274,7 +10275,7 @@ "LISUSD": "lisUSD", "LIT": "Lition", "LIT1": "Litentry", - "LIT39125": "Lighter USD Price", + "LIT39125": "Lighter", "LITCOIN": "Litcoin", "LITE": "Lite USD", "LITEBTC": "LiteBitcoin", @@ -10362,7 +10363,7 @@ "LOCG": "LOCGame", "LOCI": "LociCoin", "LOCK": "Meridian Network", - "LOCKIN": "LOCK IN USD Price", + "LOCKIN": "LOCK IN", "LOCO": "Loco", "LOCOM": "Locomotir", "LOCUS": "Locus Chain", @@ -10370,7 +10371,7 @@ "LOE": "Legends of Elysium", "LOF": "Land of Fantasy", "LOFI": "LOFI", - "LOFI34187": "LOFI USD Price", + "LOFI34187": "LOFI", "LOFIBUZZ": "LOFI", "LOG": "Wood Coin", "LOGO": "LOGOS", @@ -10640,7 +10641,7 @@ "M0": "M by M^0", "M1": "SupplyShock", "M2O": "M2O Token", - "M35491": "MemeCore USD Price", + "M35491": "MemeCore", "M3H": "MehVerseCoin", "M3M3": "M3M3", "M87": "MESSIER", @@ -11011,7 +11012,7 @@ "MEFAI": "META FINANCIAL AI", "MEFI": "Meo Finance", "MEGA": "MegaCryptoPolis", - "MEGA38770": "MegaETH USD Price", + "MEGA38770": "MegaETH", "MEGABOT": "Megabot", "MEGAD": "Mega Dice Casino", "MEGAHERO": "MEGAHERO", @@ -11026,7 +11027,7 @@ "MEL": "MELX", "MELAN": "Melania Meme", "MELANIA": "Melania Meme", - "MELANIA35347": "Official Melania Meme USD Price", + "MELANIA35347": "Official Melania Meme", "MELANIATRUMP": "Melania Trump", "MELB": "Minelab", "MELD": "MELD", @@ -11106,7 +11107,7 @@ "MESSI": "MESSI COIN", "MESSU": "Loinel Messu", "MET": "Metronome", - "MET38353": "Meteora USD Price", + "MET38353": "Meteora", "META": "Metadium", "METAA": "META ARENA", "METABOT": "Robot Warriors", @@ -11513,7 +11514,7 @@ "MOBYONBASEV1": "Moby v1", "MOC": "Moss Coin", "MOCA": "Moca Network", - "MOCA31526": "Moca Network USD Price", + "MOCA31526": "Moca Network", "MOCHI": "Mochiswap", "MOCHI14315": "Mochi", "MOCHICAT": "MochiCat", @@ -11576,7 +11577,7 @@ "MOMO2": "MOMO 2.0", "MOMO2025": "momo", "MON": "PocMon", - "MON30495": "Monad USD Price", + "MON30495": "Monad", "MON30950": "MON", "MONA": "MonaCoin", "MONAI": "MONAI", @@ -11631,7 +11632,7 @@ "MOOBIFI": "Staked BIFI", "MOOCAT": "MooCat", "MOODENG": "Moo Deng (moodengsol.com)", - "MOODENG33093": "Moo Deng USD Price", + "MOODENG33093": "Moo Deng", "MOODENGBNB": "MOODENG (moodengbnb.com)", "MOODENGSBS": "Moo Deng (moodeng.sbs)", "MOODENGSPACE": "MOO DENG", @@ -12352,7 +12353,7 @@ "NIK": "NIKPLACE", "NIKO": "NikolAI", "NIL": "Nillion", - "NIL35702": "Nillion USD Price", + "NIL35702": "Nillion", "NILA": "MindWave", "NILE": "Nile", "NIM": "Nimiq", @@ -13672,7 +13673,7 @@ "PIPL": "PiplCoin", "PIPO": "Pipo", "PIPONHL": "PiP", - "PIPPIN": "pippin USD Price", + "PIPPIN": "pippin", "PIPPKIN": "Pippkin The Horse", "PIPT": "Power Index Pool Token", "PIRATE": "PirateCash", @@ -14094,7 +14095,7 @@ "PROLIFIC": "Prolific Game Studio", "PROM": "Prom", "PROME": "Prometheus Trading", - "PROMPT": "Wayfinder USD Price", + "PROMPT": "Wayfinder", "PRON": "Rise Of Nebula", "PROOF": "PROVER", "PROP": "Propeller", @@ -14250,7 +14251,7 @@ "PURPE": "Purple Pepe", "PURPLEBTC": "Purple Bitcoin", "PURR": "Purr", - "PURR34332": "Purr USD Price", + "PURR34332": "Purr", "PURRC": "Purrcoin", "PURSE": "Pundi X PURSE", "PUS": "Pussy Cat", @@ -14357,6 +14358,7 @@ "QGOLD": "Quorium", "QGOV": "Q Protocol", "QI": "QiSwap", + "QI9288": "BENQI", "QIE": "QI Blockchain", "QINGWA": "ShangXin QingWa", "QISWAP": "QiSwap", @@ -14546,7 +14548,7 @@ "RATWIF": "RatWifHat", "RAV": "Ravelin Finance", "RAVE": "Ravendex", - "RAVE38967": "RaveDAO USD Price", + "RAVE38967": "RaveDAO", "RAVELOUS": "Ravelous", "RAVEN": "Raven Protocol", "RAVENCOINC": "Ravencoin Classic", @@ -14620,6 +14622,7 @@ "RDT": "Ridotto", "RDWON": "Redwire (Ondo Tokenized)", "RDX": "Redux Protocol", + "RE": "Re", "REA": "Realisto", "REACH": "/Reach", "REACT": "Reactive Network", @@ -14706,7 +14709,7 @@ "REINDEER": "Reindeer", "REK": "Rekt", "REKT": "Rekt", - "REKT34434": "Rekt USD Price", + "REKT34434": "Rekt", "REKTV1": "REKT", "REKTV2": "REKT 2.0", "REKTV3": "REKT v3 (rekt.game)", @@ -15053,7 +15056,7 @@ "RRT": "Recovery Right Tokens", "RS": "ReadySwap", "RSC": "ResearchCoin", - "RSC27054": "ResearchCoin USD Price", + "RSC27054": "ResearchCoin", "RSETH": "Kelp DAO Restaked ETH", "RSF": "Royal Sting", "RSG": "RSG TOKEN", @@ -15202,7 +15205,7 @@ "SAD": "SadCat", "SAF": "Safcoin", "SAFE": "SafeCoin", - "SAFE21585": "Safe USD Price", + "SAFE21585": "Safe", "SAFEBTC": "SafeBTC", "SAFEBULL": "SafeBull", "SAFECOIN": "SafeCoin", @@ -15289,7 +15292,7 @@ "SAO": "Sator", "SAP": "SwapAll", "SAPE": "SolanaApe", - "SAPIEN": "Sapien USD Price", + "SAPIEN": "Sapien", "SAPP": "Sapphire", "SAPPC": "SappChat", "SAR": "Saren", @@ -15315,7 +15318,7 @@ "SATOX": "Satoxcoin", "SATOZ": "Satozhi", "SATS": "SATS (Ordinals)", - "SATS28194": "SATS (Ordinals) USD Price", + "SATS28194": "SATS (Ordinals)", "SATSALL": "ALL BEST ICO SATOSHI", "SATT": "SaTT", "SATX": "SATX", @@ -15514,7 +15517,7 @@ "SENATE": "SENATE", "SENC": "Sentinel Chain", "SEND": "Social Send", - "SEND34611": "Suilend USD Price", + "SEND34611": "Suilend", "SENDCOIN": "Sendcoin", "SENDOR": "Sendor", "SENK": "Senk", @@ -16125,7 +16128,7 @@ "SNRG": "Synergy", "SNRK": "Snark Launch", "SNS": "Synesis One", - "SNS36468": "Solana Name Service USD Price", + "SNS36468": "Solana Name Service", "SNST": "Smooth Network Solutions Token", "SNSY": "Sensay", "SNT": "Status", @@ -16283,7 +16286,7 @@ "SONOF": "Son of Solana", "SONOR": "SonorusToken", "SOON": "SoonVerse", - "SOON36542": "SOON USD Price", + "SOON36542": "SOON", "SOONAVERSE": "Soonaverse", "SOONCOIN": "SoonCoin", "SOONTOKEN": "SOON", @@ -17340,7 +17343,7 @@ "THOR": "THORSwap", "THOREUM": "Thoreum V3", "THP": "TurboHigh Performance", - "THQ": "Theoriq Token", + "THQ": "Theoriq", "THR": "Thorecoin", "THREE": "Three Protocol Token", "THRT": "ThriveToken", @@ -17751,7 +17754,7 @@ "TRUMP2024": "Donald Trump", "TRUMP27872": "MAGA", "TRUMP3": "Trump MP3", - "TRUMP35336": "OFFICIAL TRUMP USD Price", + "TRUMP35336": "OFFICIAL TRUMP", "TRUMP47": "47th President of the United States", "TRUMPA": "TRUMP AI", "TRUMPAI": "Trump Maga AI", @@ -17890,7 +17893,7 @@ "TURT": "TurtSat", "TURT28826": "TurtSat", "TURTLE": "Turtle", - "TURTLE38671": "Turtle USD Price", + "TURTLE38671": "Turtle", "TUS": "Treasure Under Sea", "TUSD": "TrueUSD", "TUSDV1": "True USD v1", @@ -18065,7 +18068,7 @@ "UMAMI": "Umami Finance", "UMB": "Umbrella Network", "UMBR": "Umbria Network", - "UMBRA": "Umbra USD Price", + "UMBRA": "Umbra", "UMC": "Umbrella Coin", "UMI": "UMI", "UMID": "Umi Digital", @@ -18216,7 +18219,7 @@ "USCR": "United States Crypto Reserve", "USD0": "Usual USD", "USD1": "World Liberty Financial USD", - "USD136148": "World Liberty Financial USD USD Price", + "USD136148": "World Liberty Financial USD", "USD3": "Web 3 Dollar", "USDA": "USDA", "USDACC": "USDA", @@ -18296,7 +18299,7 @@ "USE": "Usechain Token", "USEDCAR": "A Gently Used 2001 Honda", "USELESS": "USELESS COIN", - "USELESS36828": "Useless Coin USD Price", + "USELESS36828": "Useless Coin", "USETH": "USETH", "USF": "Unslashed Finance", "USG": "USGold", @@ -18363,7 +18366,7 @@ "UWULEND": "UwU Lend", "UX": "UX Chain", "UXD": "UXD Stablecoin", - "UXLINK": "UXLINK USD Price", + "UXLINK": "UXLINK", "UXLINKV1": "UXLINK v1", "UXOS": "UXOS", "UXP": "UXD Protocol", @@ -19177,7 +19180,7 @@ "WLSC": "WESTLAND SMART CITY", "WLTH": "Common Wealth", "WLUNA": "Wrapped LUNA Token", - "WLUNC": "Wrapped LUNA Classic USD Price", + "WLUNC": "Wrapped LUNA Classic", "WLXT": "Wallex Token", "WM": "WrappedM by M^0", "WMATIC": "Wrapped Matic", @@ -19509,7 +19512,7 @@ "XCXT": "CoinonatX", "XD": "Data Transaction Token", "XDAG": "XDAG", - "XDAI": "xDAI", + "XDAI": "XDAI", "XDAO": "XDAO", "XDATA": "Streamr XDATA", "XDB": "DigitalBits", @@ -19587,7 +19590,7 @@ "XIDR": "XIDR", "XIL": "Project X", "XIN": "Mixin", - "XIN2349": "Mixin USD Price", + "XIN2349": "Mixin", "XING": "Xing Xing", "XINGXING": "星星", "XINU": "XINU", @@ -19848,7 +19851,7 @@ "YAXIS": "yAxis", "YAY": "YAY Games", "YAYCOIN": "YAYcoin", - "YB": "YieldBasis USD Price", + "YB": "YieldBasis", "YBC": "YbCoin", "YBDBD": "YBDBD", "YBNB": "Yellow BNB 4", @@ -20034,7 +20037,7 @@ "ZBCN": "Zebec Network", "ZBIT": "zbit", "ZBT": "ZB Token", - "ZBT38427": "ZEROBASE USD Price", + "ZBT38427": "ZEROBASE", "ZBU": "Zeebu", "ZBUV1": "ZEEBU v1", "ZCC": "ZCC Coin", From f474f319bfccc8b3e53669f247b673134524750c Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 13 Aug 2026 18:20:52 +0200 Subject: [PATCH 3/5] Bugfix/resolve error when fetching dividends from Yahoo Finance for date ranges without events (#7612) * Resolve error when fetching dividends for date ranges without events * Update changelog --- CHANGELOG.md | 4 ++ .../data-provider/data-provider.service.ts | 8 ++- .../yahoo-finance/yahoo-finance.service.ts | 63 ++++++++++++------- 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dd4c0cb0..bb5353dcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Refreshed the cryptocurrencies list +### Fixed + +- Resolved an error when fetching dividends from _Yahoo Finance_ for date ranges without events + ## 3.49.0 - 2026-08-12 ### Changed diff --git a/apps/api/src/services/data-provider/data-provider.service.ts b/apps/api/src/services/data-provider/data-provider.service.ts index c5de3e4e5..adb12f5f0 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -340,7 +340,13 @@ export class DataProviderService implements OnModuleInit { from: Date; granularity: Granularity; to: Date; - } & AssetProfileIdentifier) { + } & AssetProfileIdentifier): Promise<{ + [date: string]: DataProviderHistoricalResponse; + }> { + if (!isValid(from) || !isValid(to)) { + return {}; + } + return this.getDataProvider(DataSource[dataSource]).getDividends({ from, granularity, diff --git a/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts b/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts index 364354f6b..f59e91db4 100644 --- a/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts +++ b/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts @@ -22,6 +22,7 @@ import { import { Injectable, Logger } from '@nestjs/common'; import { DataSource, SymbolProfile } from '@prisma/client'; import { addDays, format, isSameDay } from 'date-fns'; +import { ReasonPhrases, StatusCodes } from 'http-status-codes'; import { uniqBy } from 'lodash'; import YahooFinance from 'yahoo-finance2'; import { ChartResultArray } from 'yahoo-finance2/esm/src/modules/chart'; @@ -41,6 +42,12 @@ import { SearchQuoteNonYahoo } from 'yahoo-finance2/esm/src/modules/search'; @Injectable() export class YahooFinanceService implements DataProviderInterface { + private static readonly DELISTED_ERROR_MESSAGE = + 'No data found, symbol may be delisted'; + + private static readonly RATE_LIMIT_ERROR_MESSAGE = + ReasonPhrases.TOO_MANY_REQUESTS; + private readonly logger = new Logger(YahooFinanceService.name); private readonly yahooFinance = new YahooFinance({ @@ -77,10 +84,6 @@ export class YahooFinanceService implements DataProviderInterface { symbol, to }: GetDividendsParams) { - if (isSameDay(from, to)) { - to = addDays(to, 1); - } - try { const historicalResult = this.convertToDividendResult( await this.yahooFinance.chart( @@ -91,7 +94,10 @@ export class YahooFinanceService implements DataProviderInterface { events: 'dividends', interval: granularity === 'month' ? '1mo' : '1d', period1: format(from, DATE_FORMAT), - period2: format(to, DATE_FORMAT) + period2: format( + isSameDay(from, to) ? addDays(to, 1) : to, + DATE_FORMAT + ) } ) ); @@ -107,12 +113,26 @@ export class YahooFinanceService implements DataProviderInterface { return response; } catch (error) { - this.logger.error( - `Could not get dividends for ${symbol} (${this.getName()}) from ${format( - from, - DATE_FORMAT - )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}` - ); + const message = `Could not get dividends for ${symbol} (${this.getName()}) from ${format( + from, + DATE_FORMAT + )} to ${format(to, DATE_FORMAT)}`; + + if (error?.message === YahooFinanceService.DELISTED_ERROR_MESSAGE) { + this.logger.warn( + `${message}: ${YahooFinanceService.DELISTED_ERROR_MESSAGE}` + ); + } else if ( + (error?.name === 'HTTPError' && + error?.code === StatusCodes.TOO_MANY_REQUESTS) || + error?.message?.startsWith(YahooFinanceService.RATE_LIMIT_ERROR_MESSAGE) + ) { + this.logger.warn( + `${message}: ${YahooFinanceService.RATE_LIMIT_ERROR_MESSAGE}` + ); + } else { + this.logger.error(`${message}: [${error?.name}] ${error?.message}`); + } return {}; } @@ -125,10 +145,6 @@ export class YahooFinanceService implements DataProviderInterface { }: GetHistoricalParams): Promise<{ [date: string]: DataProviderHistoricalResponse; }> { - if (isSameDay(from, to)) { - to = addDays(to, 1); - } - try { const historicalResult = this.convertToHistoricalResult( await this.yahooFinance.chart( @@ -138,7 +154,10 @@ export class YahooFinanceService implements DataProviderInterface { { interval: '1d', period1: format(from, DATE_FORMAT), - period2: format(to, DATE_FORMAT) + period2: format( + isSameDay(from, to) ? addDays(to, 1) : to, + DATE_FORMAT + ) } ) ); @@ -155,7 +174,7 @@ export class YahooFinanceService implements DataProviderInterface { return response; } catch (error) { - if (error.message === 'No data found, symbol may be delisted') { + if (error?.message === YahooFinanceService.DELISTED_ERROR_MESSAGE) { throw new AssetProfileDelistedError( `No data found, ${symbol} (${this.getName()}) may be delisted` ); @@ -164,7 +183,7 @@ export class YahooFinanceService implements DataProviderInterface { `Could not get historical market data for ${symbol} (${this.getName()}) from ${format( from, DATE_FORMAT - )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}` + )} to ${format(to, DATE_FORMAT)}: [${error?.name}] ${error?.message}` ); } } @@ -343,9 +362,11 @@ export class YahooFinanceService implements DataProviderInterface { private convertToDividendResult( result: ChartResultArray ): HistoricalDividendsResult { - return result.events.dividends.map(({ amount: dividends, date }) => { - return { date, dividends }; - }); + return (result.events?.dividends ?? []).map( + ({ amount: dividends, date }) => { + return { date, dividends }; + } + ); } private convertToHistoricalResult( From 1af196f193a82a1081053c99a4e212eac1bd6516 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 13 Aug 2026 20:12:01 +0200 Subject: [PATCH 4/5] Task/upgrade countries-list to version 3.4.1 (#7614) * Update countries-list to version 3.4.1 * Update changelog --- CHANGELOG.md | 1 + package-lock.json | 8 ++++---- package.json | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb5353dcc..c805c2586 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Refreshed the cryptocurrencies list +- Upgraded `countries-list` from version `3.4.0` to `3.4.1` ### Fixed diff --git a/package-lock.json b/package-lock.json index 270171969..e01b10215 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,7 +63,7 @@ "color": "5.0.3", "cookie-parser": "1.4.7", "countries-and-timezones": "3.9.0", - "countries-list": "3.4.0", + "countries-list": "3.4.1", "countup.js": "2.10.1", "date-fns": "4.4.0", "dotenv": "17.4.2", @@ -16600,9 +16600,9 @@ } }, "node_modules/countries-list": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/countries-list/-/countries-list-3.4.0.tgz", - "integrity": "sha512-SonKkjlEGUNz/Ugj6akOMUl8/F6EBVbLq/nQbDKhZo60EFyNgsVIgDP521J9pGhywikV514Ct4BueIqiOnvBBA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/countries-list/-/countries-list-3.4.1.tgz", + "integrity": "sha512-sKLGAZD5EAdzQwQ19vOp/9u33MTjmZ0CkdXPYtp/An6cyIlJ/E8TwGf2FcPe1AnzHO+h7nbTfoHyXIi58Hpa+Q==", "license": "MIT" }, "node_modules/countup.js": { diff --git a/package.json b/package.json index a6c09c1d0..49e87f202 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "color": "5.0.3", "cookie-parser": "1.4.7", "countries-and-timezones": "3.9.0", - "countries-list": "3.4.0", + "countries-list": "3.4.1", "countup.js": "2.10.1", "date-fns": "4.4.0", "dotenv": "17.4.2", From b764faff9e418879a33eb41bba87b433856c9509 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 13 Aug 2026 20:13:01 +0200 Subject: [PATCH 5/5] Bugfix/add missing country mapping for Czech Republic and Turkey (#7611) * Add missing country mapping for Czech Republic and Turkey * Update changelog --- CHANGELOG.md | 5 +++++ apps/api/src/helper/country.helper.ts | 2 +- .../yahoo-finance/yahoo-finance.service.ts | 22 +++++++++++-------- .../financial-modeling-prep.service.ts | 3 ++- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c805c2586..53235aaf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Resolved an error when fetching dividends from _Yahoo Finance_ for date ranges without events +### Fixed + +- Fixed the missing mapping for Turkey in the country weightings of the _Financial Modeling Prep_ service +- Fixed the missing mapping for Czech Republic and Turkey in the data enhancer for asset profile data via _Yahoo Finance_ + ## 3.49.0 - 2026-08-12 ### Changed diff --git a/apps/api/src/helper/country.helper.ts b/apps/api/src/helper/country.helper.ts index ecb28b8d3..2e6da5340 100644 --- a/apps/api/src/helper/country.helper.ts +++ b/apps/api/src/helper/country.helper.ts @@ -18,7 +18,7 @@ export function getCountryCodeByName({ } } - if (name) { + if (name && name.toLowerCase() !== 'other') { const logger = new Logger('getCountryCodeByName'); logger.warn(`Could not map the country "${name}" to a code`); 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 749f10c12..f2cbcf8ea 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 @@ -1,3 +1,4 @@ +import { getCountryCodeByName } from '@ghostfolio/api/helper/country.helper'; import { getSectorName } from '@ghostfolio/api/helper/sector.helper'; import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service'; import { AssetProfileDelistedError } from '@ghostfolio/api/services/data-provider/errors/asset-profile-delisted.error'; @@ -18,12 +19,16 @@ import { SymbolProfile } from '@prisma/client'; import { isISIN } from 'class-validator'; -import { countries } from 'countries-list'; import YahooFinance from 'yahoo-finance2'; import type { Price } from 'yahoo-finance2/esm/src/modules/quoteSummary-iface'; @Injectable() export class YahooFinanceDataEnhancerService implements DataEnhancerInterface { + private static countriesMapping = { + 'Czech Republic': 'CZ', + Turkey: 'TR' + }; + private static sectorsMapping: Record = { basic_materials: 'Basic Materials', communication_services: 'Communication Services', @@ -246,15 +251,14 @@ export class YahooFinanceDataEnhancerService implements DataEnhancerInterface { ) { // Add country if asset is stock and country available - try { - const [code] = Object.entries(countries).find(([, country]) => { - return country.name === assetProfile.summaryProfile?.country; - }); + const code = getCountryCodeByName({ + aliases: YahooFinanceDataEnhancerService.countriesMapping, + name: assetProfile.summaryProfile.country + }); - if (code) { - response.countries = [{ code, weight: 1 }]; - } - } catch {} + if (code) { + response.countries = [{ code, weight: 1 }]; + } if (assetProfile.summaryProfile?.sector) { response.sectors = [ diff --git a/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts b/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts index f4c36d256..913214b41 100644 --- a/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts +++ b/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts @@ -56,7 +56,8 @@ export class FinancialModelingPrepService private static countriesMapping = { 'Korea (the Republic of)': 'KR', 'Russian Federation': 'RU', - 'Taiwan (Province of China)': 'TW' + 'Taiwan (Province of China)': 'TW', + Turkey: 'TR' }; private readonly logger = new Logger(FinancialModelingPrepService.name);