Skip to content

Blackl1stV35/PortfolioOptimizer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

104 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

PortfolioOptimizer

Private family income portfolio management system.
Thai retail investor focus Β· USD income assets Β· KAsset THB mutual fund Β· Multi-account Β· AI-assisted


What this is

A multi-page Streamlit application that tracks, analyses, and optimises a generational income portfolio across three brokerage accounts. It is not a general-purpose tool β€” it is built around the specific needs of a Thai investor holding USD income assets (BKLN, ARCC, PDI) and a Thai fixed-income mutual fund (K-FIXED-A), with a 30-year wealth-building mandate.


Accounts managed

ID Account Currency Contents
397543-7 K CYBER TRADE (Kasikorn Securities) USD BKLN 192sh Β· ARCC 133sh Β· PDI 105sh
722379-7 K CYBER TRADE (Kasikorn Securities) THB Cash only β€” Thai domestic account
005-8-95518-3 KAsset Wisdom (Finnomena) THB K-FIXED-A ΰΈΏ1,396,284.70

Project structure

PortfolioOptimizer/
β”œβ”€β”€ app.py                        Entry point β€” 85 lines of pure routing
β”œβ”€β”€ core.py                       Shared runtime: accounts, YAML I/O, cache, sidebar
β”œβ”€β”€ requirements.txt
β”‚
β”œβ”€β”€ pages/
β”‚   β”œβ”€β”€ p1_dashboard.py           Dashboard: overview, prices, dividend calendar, WHT, transactions
β”‚   β”œβ”€β”€ p2_intelligence.py        Intelligence Hub: macro, SEC EDGAR, FX timing
β”‚   β”œβ”€β”€ p3_analytics.py           Analytics: risk, backtest, Monte Carlo, generational plan, charts
β”‚   β”œβ”€β”€ p4_sandbox.py             Sandbox: What-If, 3D frontier (Plotly + Three.js), exit simulator
β”‚   β”œβ”€β”€ p5_accounts.py            Account manager: consolidated view, settings, cash transfers
β”‚   β”œβ”€β”€ p6_research.py            AI research agent (Groq streaming)
β”‚   └── p7_family.py              Family overview (shown when 2+ accounts)
β”‚
β”œβ”€β”€ engine/
β”‚   β”œβ”€β”€ julia_engine.jl           Julia worker: LW covariance, MC, gen plan, max-Sharpe, HRP
β”‚   β”œβ”€β”€ julia_bridge.py           Python↔Julia bridge (juliacall, Python fallback)
β”‚   β”œβ”€β”€ charts.py                 Advanced charts via pandas_ta (SMA/EMA/BB/RSI/MACD)
β”‚   β”œβ”€β”€ exit_simulator.py         Exit position impact: P&L, tax, income loss, 30yr generational
β”‚   β”œβ”€β”€ scenario_analyzer.py      What-If multi-asset optimizer
β”‚   β”œβ”€β”€ wht_reconciliation.py     WHT reconciliation with treaty band 12–22%
β”‚   β”œβ”€β”€ edgar_monitor.py          SEC EDGAR: ARCC 8-K, XBRL NAV/NII, BDC screener
β”‚   β”œβ”€β”€ analytics.py              Portfolio risk metrics
β”‚   β”œβ”€β”€ backtest.py               Walk-forward backtest
β”‚   β”œβ”€β”€ black_litterman.py        Black-Litterman model
β”‚   β”œβ”€β”€ dividend_calendar.py      Upcoming dividend event builder
β”‚   β”œβ”€β”€ fx_timing.py              USD/THB z-score signal
β”‚   β”œβ”€β”€ generational_planner.py   30-year generational plan
β”‚   β”œβ”€β”€ macro_monitor.py          VIX, yield curve, oil, FX macro indicators
β”‚   └── report_builder.py        (Legacy β€” kept for reference, Excel export removed)
β”‚
β”œβ”€β”€ utils/
β”‚   β”œβ”€β”€ i18n.py                   EN/TH language switching β€” t() helper
β”‚   β”œβ”€β”€ finnomena.py              KAsset/Finnomena NAV fetcher + YAML fallback
β”‚   β”œβ”€β”€ research_agent.py         Groq llama-3.3-70b-versatile streaming agent
β”‚   β”œβ”€β”€ llm_summarizer.py         Post-analysis AI summaries with session-state cache
β”‚   └── github_commit.py          GitHub PAT auto-commit after data mutations
β”‚
└── config/
    β”œβ”€β”€ accounts.yaml             Account registry (IDs, colours, YAML filenames)
    β”œβ”€β”€ portfolio_397543-7.yaml   USD income account (BKLN/ARCC/PDI)
    β”œβ”€β”€ portfolio_722379-7.yaml   THB cash account
    └── portfolio_005895518-3.yaml KAsset Wisdom mutual fund account

Setup

1. Install dependencies

python -m venv venv
source venv/bin/activate        # Windows: venv\Scripts\activate
pip install -r requirements.txt

2. Configure secrets

Copy .streamlit/secrets.toml.template β†’ .streamlit/secrets.toml and fill in:

[github]
pat      = "ghp_..."            # GitHub Personal Access Token (for auto-commit)
repo_url = "https://github.com/Blackl1stV35/PortfolioOptimizer"

[groq]
api_key = "gsk_..."             # From console.groq.com β€” free tier

[account_pins]
# Not required β€” PIN gate removed. Accounts switch by button click.

Never commit secrets.toml. It is already in .gitignore.

3. Run

streamlit run app.py

Julia acceleration (optional)

Julia provides sub-3-second Monte Carlo (5,000 Γ— 360 months), Ledoit-Wolf covariance, Max-Sharpe, Min-CVaR, and HRP optimisation. Without Julia, Python/NumPy fallbacks are used automatically.

# Install Julia (https://julialang.org/downloads/)
# Then:
pip install juliacall
# On first run, Julia initialises once via @st.cache_resource

Julia is not required for the app to function.


Pages

πŸ“Š Dashboard

  • Overview β€” live market values in USD and THB, unrealised P&L per holding (live prices via yfinance)
  • Price & History β€” 6-timeframe interactive price chart (1M β†’ MAX) with monthly return bars
  • Dividend Calendar β€” smart checklist for upcoming dividends with βœ… confirm flow; auto-updates portfolio YAML; ICS export for Google/Apple/Outlook Calendar
  • Tax & Reconciliation β€” WHT implied rate back-calculation; treaty band 12–22% (W-8BEN validated); auto-detects 15% treaty vs 30% default
  • Transactions β€” editable st.data_editor ledger + step-by-step add-transaction wizard with live price autofill, impact preview, and optional GitHub push

πŸ” Intelligence Hub

  • Macro Pulse β€” Thai policy rate, US Fed rate, VIX, oil, yield curve, recession probability, macro regime (Aggressive / Neutral / Defensive) with cash deployment recommendation
  • SEC EDGAR β€” ARCC 8-K dividend declarations, XBRL NAV/NII fundamentals, insider Form 4 trades, BDC candidate screener
  • FX Timing β€” USD/THB 90-day z-score signal with deployment recommendation

πŸ§ͺ Analytics Engine

  • Risk & Optimisation β€” per-asset risk metrics (Sharpe, CVaR, Max Drawdown) via Julia; Max-Sharpe, Min-Variance, Min-CVaR weight tables; Groq AI summary
  • Backtest β€” walk-forward backtest across multiple strategies; Groq AI summary
  • Monte Carlo β€” 1,000–10,000 path simulation (Julia-accelerated); p10/p50/p90 fan chart; target income probability; Groq AI summary
  • Generational Plan β€” 30-year, 5,000-path plan; milestone table (Year 5/10/15/20/25/30); median time-to-target; Groq AI summary
  • Advanced Charts β€” pandas_ta technical indicators: SMA20/50, EMA20, Bollinger Bands, RSI(14), MACD(12,26,9); multi-asset overlay with benchmark comparison; 8 timeframes

πŸ”¬ What-If & 3D Sandbox

  • What-If Simulator β€” add up to 3 tickers simultaneously; Β±5% entry price sensitivity sub-scenarios; Ξ”Sharpe / Ξ”CVaR / Ξ”income KPIs; before/after weight table; 5-year MC fan chart; sandbox checkbox (never writes to YAML until explicitly confirmed)
  • 3D Frontier β€” Plotly WebGL 3D scatter: X=volatility, Y=return, Z=monthly income; coloured by Sharpe ratio; 2,000 random portfolios
  • Three.js Bubble Chart β€” interactive WebGL asset bubbles; drag to rotate, scroll to zoom, hover for details; size=weight, colour=yield
  • Exit Simulator β€” full exit impact: capital gain/loss, Thai CGT exemption note, lost monthly income, 30-year compounded income loss, portfolio concentration after exit

πŸ‘₯ Account Manager

  • Consolidated NAV, income, and cash across all 3 accounts
  • Income bar chart by account
  • Per-account settings editor (FX rate, WHT rate, risk-free rate, income target)
  • Cash transfer recorder (bookkeeping only β€” no broker API)

πŸ€– AI Research

  • Groq llama-3.3-70b-versatile streaming agent
  • Full portfolio context injected into system prompt (holdings, WHT, FX, strategy)
  • Responds in English or Thai based on language setting
  • 7 curated starter questions in both languages

KAsset / Finnomena NAV

The Finnomena API is Cloudflare-blocked from server environments. NAV is managed manually:

  1. Open Dashboard β†’ KAsset Wisdom account β†’ Overview
  2. Expand "Update NAV manually"
  3. Enter NAV per unit + total market value β†’ Update NAV
  4. The app stores the entry in portfolio_005895518-3.yaml β†’ nav_history
  5. A ⚠️ stale warning appears if data is more than 3 days old

Language switching

Click the 🌐 ΰΈ ΰΈ²ΰΈ©ΰΈ²ΰΉ„ΰΈ—ΰΈ’ / English button at the bottom of the sidebar. All UI labels, navigation items, and metric names switch. AI Research responses also switch language based on this setting.


Data flow

YAML files (primary) ──→ core.load_cfg()
                              β”‚
                              β”œβ”€β”€ render_sidebar()   (once per re-run)
                              β”‚
                              └── pages/pN.render()  (only active page re-runs)
                                        β”‚
                                        β”œβ”€β”€ yfinance  (prices, FX β€” cached 5 min)
                                        β”œβ”€β”€ Julia     (heavy compute β€” cached resource)
                                        β”œβ”€β”€ Groq      (summaries β€” session-state cache)
                                        └── Finnomena (NAV β€” YAML fallback)
                                        β”‚
                                    save_cfg()
                                        β”‚
                                        β”œβ”€β”€ YAML write
                                        β”œβ”€β”€ Supabase dual-write (Phase 2 hook, optional)
                                        └── GitHub auto-commit (if PAT configured)

WHT reconciliation logic

Implied WHT Verdict Meaning
< 5% no_data KS data missing or zero
12–22% treaty_15 βœ… W-8BEN applied (18% band accounts for KS FX rounding)
27–33% default_30 ⚠️ Standard US withholding β€” file W-8BEN with KS
> 35% overpaid ❌ Contact KS
Other partial Unusual β€” verify KS statement

W-8BEN treaty rate (15%) validated on account 397543-7 as of 2026-04-14.


Dividend calendar β€” upcoming (as of 2026-04-14)

Ticker Ex-date Pay-date Eligible shares Est. gross Est. net (15% WHT)
PDI 2026-04-13 2026-05-01 105 $23.15 $19.68
BKLN 2026-04-23 2026-04-27 192 $19.20 $16.32
PDI 2026-05-11 2026-06-01 105 $23.15 $19.68
BKLN 2026-05-28 2026-06-01 192 $19.20 $16.32
ARCC 2026-06-12 2026-06-30 133 $63.84 $54.26
BKLN 2026-06-25 2026-06-27 192 $19.20 $16.32
PDI 2026-06-12 2026-07-01 105 $23.15 $19.68

⚠️ ARCC Q1 2026 dividend missed β€” shares purchased 2026-03-25, ex-date was 2026-03-12.


Hosting

Current: Streamlit Community Cloud

Free, 1 app, ~1 GB RAM. Julia not available (Python fallback active). Suitable for current portfolio size.

Recommended upgrade: Hugging Face Spaces

Free, always-on, 16 GB RAM, Julia installable via Dockerfile. Zero cold starts.

FROM python:3.11-slim
RUN apt-get update && apt-get install -y curl
RUN curl -fsSL https://install.julialang.org | sh
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
RUN echo 'juliacall>=0.9.0' >> requirements.txt && pip install juliacall
CMD ["streamlit", "run", "app.py", "--server.port=7860"]

Git commit convention

Auto-commits are triggered after: dividend confirmation, trade logging, What-If apply, NAV update.

feat: multi-account + Groq LLM + Julia + 3D sandbox
fix: WHT treaty band 12-22%, snapshot key resolver, PyArrow KS THB
data: portfolio_397543-7 β€” WHT 15% validated, mkt value $8,201.80
data: KAsset Wisdom account 005-8-95518-3 β€” K-FIXED-A ΰΈΏ1,396,284.70

Licence

MIT

About

A quantitative decision-support platform for dynamic portfolio optimization, risk management, and automated fundamental analysis.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors