Track • Allocate • Visualize • Project Returns
An opinionated, lightweight personal portfolio allocation dashboard built with Angular 20, PrimeNG, AnyChart and a Firebase backend.
Features • Quick Start • Screenshots • Usage • Architecture • Contributing
Ani Portfolio Allocation helps you understand how your investments are distributed, what each category contributes, and what your weighted expected returns look like over time. It combines allocation management, categorization, expectation modeling, and net worth trend visualization into a single clean UI.
| Core Value | Description |
|---|---|
| Allocation Transparency | See how capital is split across asset categories. |
| Expectations Engine | Weighted expected return calculation with per‑category assumptions. |
| Change Tracking | Synthetic or real historical snapshots displayed as a net worth curve. |
| Mock-Friendly | Develop fully offline without Firebase by flipping one flag. |
- 📊 Interactive allocation charts (category drill-downs)
- 🗂️ Category management with editable expected returns
- 📈 Net worth trend visualization with generated or real change history
- 🔁 Weighted expected annual return & absolute return projection
- 💾 In‑memory mock mode (no backend required) for instant onboarding
- 🔐 Firebase integration for auth + persistence (flag controlled)
- 🎨 Theming with PrimeNG + custom dark preset (
preset-lara-dark-blue) - ⚡ Modern Angular 20 standalone component architecture style readiness
The UI below represents mock data. Images are in
docs/.
Order: Dashboard → Manage → Allocation → Categories → Expectations.
| Dashboard | Manage | Allocation |
|---|---|---|
![]() |
![]() |
![]() |
| Categories | Expectations | Net Worth Trend |
|---|---|---|
![]() |
![]() |
![]() |
| Manage (Edit) |
|---|
![]() |
For full resolution open the images directly in the
docsdirectory.
| Layer | Tooling |
|---|---|
| Framework | Angular 20 (CLI) |
| UI | PrimeNG, PrimeFlex, Prime Icons |
| Charts | AnyChart |
| State / Rx | Built-in services + RxJS |
| Backend | Firebase (Auth, Firestore) |
| Mocking | In-memory service implementations |
| Tooling | ESLint, TypeScript 5, Angular ESLint |
src/
app/
components/ # Feature components (allocation, expectations, charts, tables)
services/ # Auth + portfolio + mocks
models/ # Portfolio / category interfaces
utils/ # Pipes & nav items
theme/ # Custom theme preset
assets/ # Images & static assets
environments/ # Environment flags (mocks, production)
docs/ # Screenshots
Mock mode is controlled via environment.useMocks and is intended solely for local/offline development when Firebase credentials or connectivity are unavailable.
// src/environments/environment.ts
export const environment = { production: false, useMocks: true };Set useMocks: false (default for production builds) to enable real Firebase initialization (you must configure Firebase separately – credentials are intentionally not stored here).
- Skips Firebase initialization
- Provides
AuthService&PortfolioServicevia mock implementations - Seeds allocation, categories and generated historical change points (
mock-portfolio.service.ts)
The expectations engine computes per‑category weightage and aggregates weighted expected returns.
flowchart LR
A[Portfolio Items] -->|group by category| B[Category Buckets]
B --> C[Sum Values]
C --> D[Compute Category Weightage %]
D --> E[Expected Return per Category]
E --> F[Weighted Exp Return Σ]
F --> G[Overall Expected Annual Return]
Formula snippet:
weightage(category) = value(category) / total_portfolio_value * 100
weighted_expected(category) = weightage(category) * expected_return(category) / 100
overall_weighted_expected = Σ weighted_expected(category)
The application expects a Firebase project for production runtime (auth + data persistence).
- Visit https://console.firebase.google.com/
- Create a new project (skip Google Analytics if not needed)
- Enable Authentication (e.g., Google Login) as user auth is required
- Create Firestore database in Production mode
Add a Web App in Project Settings → General → Your Apps → Web.
Copy the generated config:
export const firebaseConfig = {
apiKey: "...",
authDomain: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "...",
};Integrate via AngularFire in an initialization module or main.ts once real services are implemented.
Minimal example (already in firestore.rules):
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId}/{documents=**} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}
Deploy rules:
firebase deploy --only firestore:rulesfirebase emulators:start --only firestore,authnpm run build
firebase deploySet useMocks: false and ensure Firebase modules + real services are wired.
git clone <your-fork-url> ani-portfolio-allocation
cd ani-portfolio-allocationnpm installnpm startVisit: http://localhost:4200
npm run build
npm run previewnpm run build
npm run deploy| Action | How |
|---|---|
| Add / Edit Allocation Item | Use Manage / Allocation view (mock data stored in-memory) |
| Change Expected Returns | Edit category expected % in Categories view |
| View Weighted Return | Open Expectations page (shows per‑category + total) |
| Inspect Net Worth Trend | Net Worth Graph page (generated series in mock mode) |
| Switch to Real Backend | Set useMocks: false (already the prod expectation) and configure Firebase modules |
- Disable mocks (
useMocks: false). - Provide Firebase config & initialize AngularFire modules.
- Implement real
PortfolioServiceCRUD using Firestore. - Map Firestore docs to existing model interfaces.
npm run lintESLint is configured via eslint.config.js (flat config). Adjust rules as needed.
npm run buildOutputs production bundle to dist/ani-portfolio-allocation/ (Angular CLI default). Deployed by Firebase Hosting script.
- Fork the repository
- Create a feature branch:
git checkout -b feat/awesome-thing - Commit changes:
git commit -m "feat: add awesome thing" - Push branch:
git push origin feat/awesome-thing - Open a Pull Request
Follow conventional commits (feat:, fix:, chore:, docs: etc.) to keep history clean.
- Prefer strongly typed interfaces in
models/ - Keep services lean and observable-based
- Avoid premature abstraction until a pattern repeats ≥3 times
Licensed under the MIT License. See LICENSE for details.
Open an issue for feature requests or questions. PRs welcome!
| Category | Value |
|---|---|
| Stack | Angular + PrimeNG + AnyChart |
| Mode | Mock by default (flip flag for backend) |
| Focus | Allocation insight & expected returns |
| Deploy | Firebase Hosting |
Made with ❤️ to simplify personal portfolio clarity by Aniruddha Sadhukhan.






