If you’ve read the Agile Complexification Inverter blog, you know the core idea: start by deleting. Strip away the noise, the “just in case” features, and the over‑engineered layers, and you’re often left with a system that’s simpler to maintain and easier to extend.
For Swift developers, PortfolioEC is a case study in that mindset:
We delete the “dashboard‑soup” UI.
We delete manual‑sync and spreadsheet‑driven workflows.
We delete generic “investor persona” abstractions.
Then we rebuild around one canonical artifact — the equity curve — and anchor almost everything else to it.
Most portfolio apps start with a “god‑dashboard”:
Pie charts, watchlists, news feeds, and “AI‑score” widgets all fighting for attention.
A sprawling view hierarchy with multiple top‑level screens, each with its own state machine and background‑sync logic.
PortfolioEC deletes that pattern and starts instead with:
A single entry point: the equity‑curve chart (1D, 1W, 1M, 3M, 1Y, 5Y, 10Y).
A transaction‑overlay layer that anchors buys and sells onto that curve.
From a Swift‑code perspective, that looks like:
A lightweight main view whose core responsibility is “render the curve + transactions + drill‑down triggers.”
A small set of view‑models (e.g., PortfolioCurveViewModel, TransactionOverlayViewModel) that feed into SwiftUI views.
A single source of truth for the timeline, so you don’t need to reconcile multiple dashboards or sync them in parallel.
In other words: delete the dashboard, keep the curve, and let almost everything else be a drill‑down sheet or a detail panel that re‑uses the same models.
Traditional portfolio tracking pushes complexity onto the user:
Copy‑pasting trades into spreadsheets.
Manually adjusting lot‑basis after splits.
Cross‑referencing tax‑lot data between broker and app.
PortfolioEC deletes those manual steps by pushing the complexity into the data layer instead of the UI:
FIFO cost‑basis and split‑adjustment logic live in the model layer, with tests that cover re‑splits, reverse‑splits, and corporate actions.
Lot‑matching and trade‑attribution overlays are computed from the transaction history, not entered by the user.
For your Swift codebase, that means:
A rich, testable Transaction and Lot model (buy/sell, splits, dividends, fees, transfers).
A few well‑defined services (e.g., LotCalculator, SplitAdjuster) that produce split‑adjusted curves and cost‑basis.
A leaner UI layer that mostly queries pre‑computed view‑models, reducing the surface area for race conditions and UI bugs.
The complexity is still there, but it’s encapsulated in composable, testable types rather than spread across user‑driven spreadsheet‑mimicking UIs.
Many portfolio apps start with abstractions like “retail investor,” “day trader,” or “buy‑and‑hold,” and then try to build one UI that serves all of them. The result is a feature‑sprawl that makes the codebase hard to reason about and hard to refactor.
PortfolioEC instead assumes:
An investor who cares about their own equity curve, not someone else’s benchmark.
A developer who wants to expose investor‑specific timelines and trade‑attribution rather than generic “market news + a chart.”
For your Swift architecture, this translates into:
Time‑based aggregates at the domain level:
EquityCurve(account: Account, range: TimeRange)
EquityCurve(assetClass: AssetClass, range: TimeRange)
Trade‑attribution view‑models that connect your transaction history to price data and events (earnings, dividends, splits).
UI that’s built around “what‑happened‑when” stories, not “what’s trending now in the market.”
This makes the architecture feel more like an event‑sourced, timeline‑oriented system than a generic “feed + chart” app built on top of a JSON blob.
A core idea in the Agile Complexification Inverter is that you should never optimize early. First clarify the model, delete the noise, and then think about performance, caching, and AI‑assisted features.
For PortfolioEC’s Swift backlog, that suggests a clear ordering:
Model and persistence first
Transaction, Lot, Split, Dividend, Fee, Transfer types.
Well‑tested LotCalculator and SplitAdjuster logic.
Sync and reliability
Account‑level sync (broker + user‑entered).
Conflict resolution and data‑recovery paths.
Visualization and analytics
Equity‑curve SwiftUI views (PortfolioCurveView, TransactionOverlayView).
Trade‑attribution overlays and drill‑down panels.
Then optimization and “smart” features
Prefetching and caching of historical curves.
Background pre‑calculation of trade‑impact metrics.
Eventually, AI‑assisted trade‑review or anomaly‑detection workflows (Swift‑native, with optional ML models).
If you invert that order — start with “smart recommendations” before you have a solid, testable model — you end up with a brittle, entangled system where every feature is coupled to marketing hype and fragile data pipelines.
From a Swift developer’s backlog, the Agile Complexification Inverter litmus test is:
“If we deleted this feature, would the core equity‑story still be clear and usable?”
Using that lens, PortfolioEC can obviously drop:
General‑market news feeds that don’t connect to your trades.
“Magic score” widgets that don’t reflect your actual cost‑basis or timing.
Over‑complicated watchlists that duplicate your existing portfolio data.
What you keep:
The equity curve + transaction overlays in SwiftUI.
The event‑rich timeline (earnings, dividends, splits) tied to your trades.
The accurate, split‑adjusted cost‑basis that underpins every metric.
Everything else becomes a candidate for deletion — either now, or when it hasn’t demonstrably improved the investor’s understanding of their own equity story.
If you were to summarize PortfolioEC’s developer backlog in Swift Dojo terms:
Delete:
Cross‑tool spreadsheet gymnastics.
Generic “investor persona” features.
Early‑stage AI‑hype features built on shaky data models.
Refactor:
The transaction and lot model into a well‑tested, split‑aware core (SwiftData/Core Data‑backed).
The view‑model layer around “curve + events + drill‑downs” using SwiftUI view‑models.
Add (only after clarity):
Fast, incremental sync and caching.
Trade‑attribution analytics and “what‑if” scenarios.
Optional, opt‑in AI‑assisted review of your own trade history (with Swift‑native ML or remote APIs).
The result is an app that doesn’t just ship faster — it’s simpler to reason about, easier to test, and more aligned with how real investors think about performance, while also feeling natural and idiomatic to Swift developers building on iOS 18+ and SwiftUI.