oak-domain-investments
The investments domain for the OakQuant platform — a complete, goal-linked investing product delivered as a single discoverable plugin, spanning all four OakQuant layers with zero edits to any core library.
What it is
Investing is a discoverable plugin. The package advertises itself through
entry points and registers into the host's shared registries — Timber's
model/service registries, grove's FastAPI app, grove's Celery worker + beat,
grove's config store, and acorn's Oracle tool registry — never by editing the
core libraries. Install it and a full investing capability appears across the
platform; leave it out and nothing breaks. See the oak-domain-plugins skill
for the wider plugin shape.
This is OakQuant's largest and most mature domain. It began as a single watchlist migration and is now the whole B2C investing product: financial-goal creation with AI vision and personalized inspiration imagery, brokerage linkage via Plaid, portfolio and goal dashboards, a self-learning single-stock research flow, an index×sector sentiment heatmap, a behavioral Financial DNA assessment, an advisor review queue with SLAs, and a continually-learning prediction engine. Grove core owns zero investing code or config — everything investing lives here. The bulk of this program is in production.
The four-layer shape
A single installed package plugs into four OakQuant layers, one entry point per group. Each host discovers only its own entry-point group and imports only that entry point's module, so the timber layer never pulls in grove/FastAPI or acorn, and the acorn layer never pulls in the SQLAlchemy model stack.
| Layer | Entry-point group | Object | Contributes |
|---|---|---|---|
| timber | timber.domains |
oak_domain_investments:InvestmentsDomain |
ORM models (Python + bundled YAML built by the ModelFactory at Step 8.5) and ~40 registered services (watchlist, goals, portfolio, Plaid, stock/market data, forecasting, prediction brain, research, Financial DNA, advisor review, …) |
| grove (web) | grove.domains |
oak_domain_investments.grove_plugin:InvestmentsGroveDomain |
Ten FastAPI routers (watchlist, goals, portfolio, Plaid, advisor, prediction track-record, semantic search, stock lookup, calendar-generate) + UI options-helpers |
| grove (worker) | grove.workers |
oak_domain_investments.worker_plugin:InvestmentsWorkerDomain |
The adaptive-prediction Celery tasks + their beat schedule (predict / predict-universe / observe / mature) |
| grove (config) | grove.feature_packages |
oak_domain_investments:feature_packages_dir |
Nine bundled Tier-1 config packages (workflows, tasks, HITL screens, pages, nav, home widgets, schedulers) seeded into the grove DB |
| grove (secrets) | grove.secret_specs |
oak_domain_investments:secret_specs |
The market-data provider + Plaid secret specs grove fetches from ranger at boot (all optional; a missing key degrades a feature, never blocks startup) |
| acorn | acorn.domains |
oak_domain_investments.acorn_plugin:InvestmentsAcornDomain |
The Oracle "investments" assistant profile (financial persona) + ~20 gated agent tools |
| sky | (host widget registry) | sky-investments |
The goal/portfolio/watchlist/heatmap/oak-tree widgets (registered into sky's widget registry; lives in the sky repo) |
Grove and acorn delegate to the same services the timber layer registers
(reached through service_registry.domain("investments")), so there is one
implementation behind every surface. The grove routers mount outside grove's
auth middleware and so re-assert the X-Grove-API-Key service boundary; caller
identity and enterprise scope arrive as canopy-forwarded X-User-* headers.
Every investing surface is capability-gated: only an investments-provisioned
tenant can reach it.
Capabilities
Goals & vision (in production)
Config-driven financial-goal creation on the shared HITL engine: goal + timeline
intake → deterministic budget/feasibility → AI-written vision → a generated
inspiration-image gallery → a persisted InvestmentGoal with calendar
milestones. GoalService owns the lifecycle (create/update/progress/soft-delete,
assisted rewrite, in-screen budget/vision/image recalculation). The premium
goal dashboard adds time-adjusted progress and a summary roll-up.
Personalized goal imagery (in production)
GoalImageService composes grove's generic image service with cambium to
generate inspiration imagery for a goal. When a user has uploaded a self photo
(a consent-gated PersonReference), goal images preserve their likeness via
gemini-2.5-flash-image. Image regeneration is generative (token cost), so it
runs only on explicit user confirmation.
Portfolio & holdings (in production)
Manual holdings CRUD, buy/sell transactions, and brokerage→goal allocation
(PortfolioService + InvestmentService). The portfolio dashboard (premium)
returns holdings, per-lot positions, watchlist, and a value timeline backed by a
daily PortfolioValueSnapshot scheduler. Brokerage truth (a PortfolioHolding)
and goal allocation (a goal-linked Position carrying portfolio_holding_id)
are kept strictly distinct — allocating never mutates the holding.
Brokerage linkage via Plaid (in production, Plaid PRODUCTION)
PlaidBridge owns link-token creation, public-token exchange, linked-account
listing, idempotent holdings sync, and unlink — composing the configured Plaid
singleton with timber's DB and grove's generic tier guard. The
onboard_investments HITL flow lets a user connect a brokerage (auto-syncing
real holdings) or add a position manually, launchable from home or from chat.
Watchlist & accumulation (in production)
The rich, goal-linked WatchlistItem (AI + advisor recommendations, price
snapshots, buy/sell/stop targets, and an accumulation plan). Items may be
goal-linked or unlinked (a personal watchlist, goal_id nullable). The home
watchlist gadget aggregates every tracked symbol across all goals plus the
unlinked list. GrowthService runs a forward paper-accrual of accumulation
plans and rolls the latest per-item value into goal attainment; projection.py
builds the value-vs-contributed projection (profit = the gap) and can re-fit from
actual snapshots.
Single-stock research (the oak tree) (in production)
stock_research_service runs a config-driven, cost-disciplined flow —
explore → fundamentals → technicals → growth → news sentiment → forecast →
summarize — rendered as an interactive oak tree with category drill-down. Five of
six steps are deterministic/statistical; only the summary may touch an LLM, on a
cambium-distilled payload. The price forecast uses an ensemble whose signal
weights are learned from realized outcomes and records each forecast into a
feedback ledger so accuracy improves over time.
Index & sector research (the heatmap) (in production)
SectorResearchService explores indices across geographies/types, scores
sentiment + volatility across the ~11 GICS sectors, surfaces top companies and
movers/shakers, and renders an index×sector sentiment heatmap with per-cell
drill-down into single-stock research. Sentiment is batched-LLM per index with a
lexical fallback.
Adaptive prediction engine (in production)
A shared meta-learning "brain" (adapt/: estimate, cascade, cluster, ledger,
backtest, track-record) that predicts short-horizon moves for a resolved
universe (watchlist ∪ default), observes realized outcomes, and matures/scores
them — closing an autonomous continual-learning loop on grove's beat. The
cascade blends multiple strategies (reversal → news-cluster → deep) over one
shared model. A premium+ track-record endpoint exposes the honest,
outcome-scored accuracy.
Financial DNA (in production)
FdnaService computes a behavioral investor profile — persona (e.g.
architect / pragmatist / guardian / explorer / delegator), risk score, key
dimensions, and deterministic allocation / strategy / guardrail recommendations —
from a 16-screen / 6-phase HITL assessment scored on both answers and answer
timing. Reachable as a launchable flow and via the acorn assistant.
Advisor portfolio review (built, enterprise + admin)
AdvisorReviewService detects holdings drift from the Financial DNA target
allocation, drafts an AI rebalancing recommendation, and routes it to the
advisor_review work queue with a real SLA; an advisor claims / reviews /
approves or rejects it. Includes SLA-monitor and drift-scan schedulers and an
admin SLA override.
Market data & analytics (in production)
A self-contained market-data stack migrated out of timber core: multi-provider
fetchers (yfinance keyless default, with Alpha Vantage / Finnhub / Polygon when
keyed) behind a read-through cache; data_processor (returns, risk, technical
indicators, portfolio metrics); analytics (fundamental ratios, growth,
valuation); sentiment (lexical + optional LLM); forecasting
(signal→model→ensemble); and stock_search over a bundled symbol catalog that
powers the type-ahead and HITL stock pickers.
Cross-cutting integrations
The domain also contributes, via the registry, its own calendar event
generators (earnings / ex-dividend from holdings, goal target-dates +
milestones) and calendar taxonomy; hydration handlers for the home
goals/portfolio widgets; Rustle context-access rules for its
context-conversations; monitor session specs so grove's stuck-workflow
monitor can name investing session tables generically; usage queries so the
billing guard can count investing tier limits (max_goals, max_holdings,
max_watchlist, max_goal_workflow_runs, max_index_research_runs) without
grove naming any investing model; and the nav items + home widgets grove
composes into its generic shell.
Grove HTTP surface
InvestmentsGroveDomain mounts ten routers on grove's app (each behind the
X-Grove-API-Key boundary and the investments capability gate):
| Prefix | Purpose |
|---|---|
/api/v3/watchlist |
goal + unlinked watchlist, add/update, projection, advisor review |
/api/v3/goals |
goal list/detail, dashboard, assisted rewrite, in-screen recalc (budget/vision/images), reopen-save, soft-delete |
/api/v3/portfolio |
home snapshot, premium dashboard, manual holdings CRUD, transactions, brokerage→goal allocation, market data |
/api/v3/external/plaid |
link-token, token-exchange, linked accounts, holdings sync, unlink, health |
/api/v3/advisor |
advisor inbox, review detail, claim/approve/reject, admin SLA override |
/api/v3/adapt |
premium+ prediction track-record |
/api/v3/investments |
semantic + hybrid vector search over cached financial data |
/api/v3/ui · /api/human-tasks |
stock symbol search / by-symbol lookup (type-ahead + HITL pickers) |
/api/v3/calendar |
on-demand single-user calendar-event generation |
Acorn agent surface
InvestmentsAcornDomain registers the "investments" assistant profile (the
Oracle financial persona, greeting, suggestions, and investments-tagged tool
resolution) plus ~20 gated tools, each user-scoped through the forwarded
principal and returning markdown. They cover the user's own data
(get_user_goals, get_portfolio_holdings, get_goal_investments,
get_watchlist, get_financial_dna_profile), watchlist writes
(add_to_watchlist), analysis (analyze_stock_info, analyze_stock_news,
analyze_stock_price, analyze_portfolio, market_outlook, advice_on_topic,
explain_concept, investment_philosophy, quote_of_the_day), semantic search
(vector_search, search_stocks, search_indices, hybrid_search), and
research_stock, which drives the grove oak-tree flow and hands back the
interactive A2UI screen. All financial knowledge lives in this package — acorn
core keeps only the generic @tool / grove-passthrough / profile mechanisms.
Feature packages (bundled grove config)
The grove.feature_packages entry point points grove at
feature_packages/, nine portable, self-describing config bundles that
grove's sync_configs discovers and seeds into the grove DB — so the domain's
workflows/tasks/HITL screens/pages/nav travel with the package:
goal_workflow · onboard_investments · financial_dna · stock_research ·
index_research · portfolio · advisor_portfolio_review ·
investment_growth · investments (base decisioning tables).
Models
Two Python models (WatchlistItem, WatchlistValueSnapshot) plus ~30 tables
built from bundled YAML by the timber ModelFactory at Step 8.5 — byte-identical
to grove's prior definitions, so the live tables map field-for-field and
create_all is a no-op for them. Notable tables: investment_goals,
goal_images, goal_milestones, positions, portfolio_holdings,
portfolio_transactions, portfolio_value_snapshots, plaid_item,
financial_account, the read-through cache tables (cached_stock_data,
cached_market_indices, stock_data_snapshots, …), the workflow-session tables
(stock_research_sessions, index_research_sessions, financial_dna_sessions,
create_financial_goal_sessions, onboard_investments_sessions,
advisor_review_sessions), and the prediction feedback tables (predictions,
prediction_outcomes, prediction_scores, news_clusters).
How it plugs in
Each host loads only its own entry-point group; discovery is automatic once the package is installed:
[project.entry-points."timber.domains"]
investments = "oak_domain_investments:InvestmentsDomain"
[project.entry-points."grove.domains"]
investments = "oak_domain_investments.grove_plugin:InvestmentsGroveDomain"
[project.entry-points."grove.workers"]
investments = "oak_domain_investments.worker_plugin:InvestmentsWorkerDomain"
[project.entry-points."grove.feature_packages"]
investments = "oak_domain_investments:feature_packages_dir"
[project.entry-points."grove.secret_specs"]
investments = "oak_domain_investments:secret_specs"
[project.entry-points."acorn.domains"]
investments = "oak_domain_investments.acorn_plugin:InvestmentsAcornDomain"
For local development against checkouts, each host also honors an env-var
fallback (e.g. TIMBER_DOMAIN_PLUGINS=oak_domain_investments:InvestmentsDomain)
so the plugin loads without a reinstall.
Install
pip install oak-domain-investments
Requires Python 3.11+. Depends on timber-common>=0.6.16, plaid-python, and
cambium-ai. The import package is oak_domain_investments.
Develop / test against a sibling timber checkout:
# from the repo root, with ../timber on the path
PYTHONPATH=../timber:. TIMBER_DOMAIN_PLUGINS=oak_domain_investments:InvestmentsDomain \
python3 -m pytest tests/ -q
Secrets & configuration
All provider secrets are optional and fetched from ranger by grove's
bootstrap via the grove.secret_specs entry point — a missing key degrades a
feature rather than blocking startup:
- Market data —
ALPHA_VANTAGE_API_KEY,FINNHUB_API_KEY,POLYGON_API_KEY(absent → the fetchers fall back to the keyless yfinance provider). - Plaid —
PLAID_CLIENT_ID,PLAID_SECRET,PLAID_SECRET_PRODUCTION,PLAID_ENVIRONMENT,PLAID_RECOVERY(absent → brokerage linking is simply unavailable).
License
Apache-2.0. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file oak_domain_investments-0.42.3.tar.gz.
File metadata
- Download URL: oak_domain_investments-0.42.3.tar.gz
- Upload date:
- Size: 456.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d467418748af92c3f9fef86a381890d763ff5d8f76f47cbb40fe8b8c6fa8bef
|
|
| MD5 |
a369071472fdf9d7e9e3717827240c21
|
|
| BLAKE2b-256 |
92925bcd466a7802b9dfee7e5b6e35d8e4061325e55f8604c75d944fc6418f46
|
Provenance
The following attestation bundles were made for oak_domain_investments-0.42.3.tar.gz:
Publisher:
release.yml on oakquant-ai/oak-domain-investments
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oak_domain_investments-0.42.3.tar.gz -
Subject digest:
2d467418748af92c3f9fef86a381890d763ff5d8f76f47cbb40fe8b8c6fa8bef - Sigstore transparency entry: 2281545763
- Sigstore integration time:
-
Permalink:
oakquant-ai/oak-domain-investments@8bcb07010d07e1894c0d0e47b04b173d3d2e0b32 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/oakquant-ai
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8bcb07010d07e1894c0d0e47b04b173d3d2e0b32 -
Trigger Event:
push
-
Statement type:
File details
Details for the file oak_domain_investments-0.42.3-py3-none-any.whl.
File metadata
- Download URL: oak_domain_investments-0.42.3-py3-none-any.whl
- Upload date:
- Size: 534.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0eb8393880307768eedc7b3aa85e5da5a8a78a0aac8b63ca70954327b33484b2
|
|
| MD5 |
93916d8f32087d6e7c1d2cf88468ff75
|
|
| BLAKE2b-256 |
b5aa44b54c5936bffa18cd2407968452de6f705be926b4054401243bb6635dc9
|
Provenance
The following attestation bundles were made for oak_domain_investments-0.42.3-py3-none-any.whl:
Publisher:
release.yml on oakquant-ai/oak-domain-investments
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oak_domain_investments-0.42.3-py3-none-any.whl -
Subject digest:
0eb8393880307768eedc7b3aa85e5da5a8a78a0aac8b63ca70954327b33484b2 - Sigstore transparency entry: 2281545771
- Sigstore integration time:
-
Permalink:
oakquant-ai/oak-domain-investments@8bcb07010d07e1894c0d0e47b04b173d3d2e0b32 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/oakquant-ai
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8bcb07010d07e1894c0d0e47b04b173d3d2e0b32 -
Trigger Event:
push
-
Statement type: