{
  "id": 15159969,
  "title": "Three silent bugs in a portfolio tracker's math (and how we stopped them coming back)",
  "url": "https://urgent.news/2026/10/17/three-silent-bugs-in-a-portfolio-trackers-math-and-how-we-stopped",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-10-17T08:42:57.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/alinaderlou/three-silent-bugs-in-a-portfolio-trackers-math-and-how-we-stopped-them-coming-back-112g"
  },
  "original_language": "en",
  "account": "The most insidious software bugs are the ones that appear as if nothing is wrong on the surface, but subtly skew calculations. We learned this the hard way while developing a portfolio tracker for the Iranian market, dealing with currencies, gold, stocks and cryptocurrencies all denominated in Toman.\n\nOur first major insight came when we realized deposits and withdrawals were being counted as profits, not as losses. The initial formula (valueEnd - valueStart) / valueStart worked well for untouched values, but broke down when transactions were added or removed. The solution was to reconstruct cash flows from the user's transaction journal instead of using the current transaction values. This approach accounted for any changes made to transactions, such as editing or back-dating them.\n\nNext, we encountered a bug related to daily snapshots and historical data. While the journal shows the user's current holdings, a historical record only reflects the past. Deleting, editing, or recording off-market prices in a transaction silently altered history. The fix was to strictly use the facts stored in each daily snapshot, including the total value and the day's market-driven change (price movement times quantity held). By simplifying the calculation to\nconst bookChange = v [ t ] - v [ t - 1 ] - dayChange [ t ];\nconst base = v [ t - 1 ] + Math.max(0, bookChange );\nconst r = dayChange [ t ] / base;\nwe ensured the growth was based solely on market movements, not changes in value.\n\nThe third bug was related to the display of statistics when there was insufficient historical data. Simply not displaying a figure could be misleading, so we adopted a rule: every code path that stayed silent should return a human-readable explanation, which then appeared in the user interface. This way, the UI would clearly indicate when a reason existed for the lack of a displayed number.\n\nOur tests caught all these bugs by breaking the functionality they were guarding. Several tests had never experienced a failure, so we compared their inputs against the real product to ensure accuracy. Additionally, we created equivalence tests for duplicated logic across different parts of the codebase. By asking \"if this introduces a bug, who will notice?\" and adding guards where necessary, we ensured that any potential regressions would be caught before they made it into production.\n\nIn conclusion, these lessons are applicable to any application that transforms stored numbers into percentages or other calculated values. By focusing on these key areas—correct mathematical formulations, handling historical data accurately, and ensuring robust error handling—we can prevent subtle but critical bugs from slipping through the cracks.",
  "summary": "The worst bugs in a finance app are not the ones that crash. They are the ones where the console stays clean, the page renders, the tests are green, and a number on the screen is simply wrong. We build a portfolio tracker for the Iranian market (gold, crypto, stocks, currencies, all in Toman), and these three bugs taught us the most. 1. Deposits that look like profit The obvious way to compute a…",
  "key_points": [
    "Deposits and withdrawals counted as profits, not losses",
    "Daily snapshots used to correct historical data alterations",
    "UI displayed human-readable explanations for insufficient data"
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}