Asset Structures
Every asset in Portfolio is either a Private Equity Fund or a Direct investment. This single enum value determines which transactions, metrics, and workflows are available. Get this wrong and everything downstream breaks.
Why Structure Matters
When you create an asset in Portfolio, the very first decision is its structure. This is stored as the AssetStructure enum and it has exactly two values: PRIVATE_EQUITY_FUND and DIRECT. There is no third option, no hybrid, no "other."
This choice acts as a routing switch for the entire system. It determines:
- Which transaction types are available (subscriptions vs investments, capital calls vs none)
- How investors enter the asset (commit-and-draw-down vs invest-and-get-units)
- What distribution mechanics apply (investor-level + fund-level vs investor-level only)
- Which metrics the calculation service computes (DPI/TVPI/XIRR vs Yield/Multiple/ROC)
- Whether fund cash management is available
The structure determines which transaction types the system will accept. Attempting to create a Capital Call on a Direct asset, or an Investment on a PE Fund asset, will fail at the validation layer. The codebase enforces this rigidly through action classes and form requests.
The Two Structures: Side by Side
Pooled Vehicle
Investors commit capital; the fund draws it down over time
- Investors enter via Subscriptions (3 types)
- Capital drawn via Capital Calls (%-based)
- Returns via Distributions (investor + fund level)
- Fund Cash management with cash pots
- Capital Repayments return committed capital
- NAV tracked via Valuations
Direct Stake
Investors invest directly and receive units immediately
- Investors enter via Investments (simpler)
- No capital call cycle
- Returns via Distributions (investor level only)
- No fund cash management
- No commitment tracking
- Value tracked via Valuations
Let's explore each structure in depth, then compare them feature by feature.
Private Equity Fund: The Full Lifecycle
A PE Fund models the traditional private equity lifecycle: raise commitments, call capital over time, deploy it, return profits. This is the more complex of the two structures, with more transaction types and more moving parts.
Step 1: Subscriptions (Investor Entry)
When an LP joins a PE Fund, they create a Subscription that records their commitment. But not all subscriptions work the same way. The subscription type is configured per-asset via AssetData with the key SUBSCRIPTION_TYPE, and it determines how capital flows from commitment to units.
The LP commits capital but no units are assigned yet. The commitment sits as an obligation — actual cash transfers happen later when the fund issues capital calls.
| On subscription | Commitment recorded. No units. No cash moves. |
| On capital call | A percentage of the commitment is called. LP pays. Units are assigned at this point. |
| Typical fund type | CLOSED — fixed fundraise period, then drawdowns |
The LP commits capital and units are assigned immediately at subscription time. An initial valuation is created automatically. Capital calls may still draw down the commitment later.
| On subscription | Commitment recorded AND units assigned. Initial valuation auto-created. |
| On capital call | A percentage of the commitment is called. LP pays. |
| Key difference | Investor appears on the cap table immediately, not after first drawdown. |
The LP pays the full commitment upfront and gets units immediately. This extends the Units Assigned type — it inherits the automatic unit and valuation creation, but there's nothing left to call because the commitment is already fully paid.
| On subscription | Full payment, units assigned, valuation auto-created. Capital is 100% called. |
| Capital calls | Not applicable — nothing left to draw down. |
| Typical fund type | OPEN_ENDED — accepts new subscriptions over time |
The subscription type is set once at the asset level in AssetData using the SUBSCRIPTION_TYPE key. All investors in that fund use the same subscription type. You cannot have one LP on Drawdown and another on Fully Paid Up within the same asset.
Step 2: Capital Calls (Drawing Down Commitments)
Once investors have subscribed with a Drawdown type, the fund issues Capital Calls to request a portion of their committed capital. Capital calls are percentage-based — the fund calls a percentage of each investor's commitment (e.g., "calling 25% of your $1M commitment = $250K").
Capital calls create cash flows, update the paid-in totals, and assign units to investors. They're a core part of what makes PE Funds complex — and they don't exist at all for Direct assets.
Step 3: Distributions (Returning Capital + Profits)
Distributions are how money flows back to investors. PE Funds support distributions at two levels:
Paid directly to specific investors. Each investor gets their own cash flow record.
- Redemption — investor exits, units redeemed
- Dividend — income distribution, units retained
- Other Income — catch-all for non-standard returns
Applied to the fund as a whole, then allocated pro-rata across all investors based on their paid-in capital.
- Fund Redemption — pro-rata across all LPs
- Fund Dividend — pro-rata income split
- Fund Other Income — pro-rata other returns
Step 4: Fund Cash & Capital Repayments
PE Funds have a Fund Cash entity (FundCash) that tracks the cash pool available for deployment. Fund cash can be organized into cash pots (FundCashPots) — separate pools for different purposes (e.g., deployment, expenses, reserves).
Capital Repayments return committed capital to investors, reducing their outstanding commitment. This is different from a distribution — a distribution returns profits or redeemed capital, while a capital repayment reduces the commitment itself.
Direct: The Simpler Path
A Direct asset represents a direct stake in a single investment. There's no commitment-and-drawdown cycle — investors simply invest and receive units.
Step 1: Investments (Investor Entry)
Instead of Subscriptions, Direct assets use Investments. An investment is simpler: the investor puts money in and gets units. There's no commitment tracking, no unfunded obligation, no capital call lifecycle.
Step 2: Distributions (Investor-Level Only)
Direct assets support the same three distribution types (Redemption, Dividend, Other Income) but only at the investor level. There are no fund-level distributions because there's no concept of a pooled vehicle to distribute from pro-rata.
Step 3: Valuations
Both structures track value over time via Valuations, but the metrics differ significantly. Direct assets focus on investment return metrics rather than fund performance metrics.
Interactive Comparison
Use the tabs below to compare the two structures across different dimensions.
| Transaction Type | PE Fund | Direct |
|---|---|---|
| Subscription | ||
| Investment | ||
| Capital Call | ||
| Capital Repayment | ||
| Investor Distribution | ||
| Fund Distribution | ||
| Fund Cash | ||
| Valuation |
| Aspect | PE Fund (Subscription) | Direct (Investment) |
|---|---|---|
| Entry mechanism | Subscription (3 types) | Investment (1 type) |
| Commitment tracking | Yes — committed, called, uncalled | No — just the investment amount |
| Unit assignment timing | Depends on subscription type (immediate or on first capital call) | Immediate on investment |
| Capital call cycle | Yes — fund calls % of commitment over time | No — full amount invested upfront |
| Unfunded obligation | Yes — uncalled capital is a real liability for LPs | No concept of uncalled capital |
| Subscription types | Drawdown, Units Assigned, Fully Paid Up | N/A |
| Aspect | PE Fund | Direct |
|---|---|---|
| Distribution types | Redemption, Dividend, Other Income | Redemption, Dividend, Other Income |
| Investor-level | Yes | Yes |
| Fund-level | Yes — pro-rata allocation based on paid-in | No |
| Fund-level allocation basis | Pro-rata by paid-in capital (uses PaidInPerInvestor calc) | N/A |
| Capital repayment | Yes — reduces commitment | No |
| PE Fund Metrics | Direct Metrics |
|---|---|
| Committed Capital | Investment |
| Called Capital | Valuation |
| Uncalled Capital | Income |
| Paid-In Capital | Yield |
| DPI (Distributions to Paid-In) | Return on Capital |
| TVPI (Total Value to Paid-In) | Multiple |
| RVPI (Residual Value to Paid-In) | Profit |
| XIRR (Internal Rate of Return) | |
| NAV |
PE Fund metrics are computed by FundsOverview, FundsOverviewPerAsset, and FundsOverviewPerInvestor in the Go calc service. Direct metrics use DirectOverview, DirectOverviewPerAsset, and DirectOverviewPerInvestor. The AggregatesOverview endpoint combines both when a portfolio has mixed structures.
Fund Type: Open vs Closed
PE Fund assets have an additional configuration: the fund type. This is stored in the AssetData EAV table (not as a direct column on the assets table) and has two values:
Fixed fundraise period. Once closed, no new subscriptions are accepted. Capital is drawn down over the fund's life via capital calls.
Typical subscription type: DRAWDOWN
Accepts new subscriptions on an ongoing basis. Investors can typically subscribe and redeem at regular intervals (monthly, quarterly).
Typical subscription type: FULLY_PAID_UP
Fund type is stored in the AssetData entity-attribute-value table, not as a direct column on the assets table. This means you won't find it with a simple SELECT * FROM assets — you need to join or query AssetData with the appropriate key. The same is true for SUBSCRIPTION_TYPE.
Knowledge Check 1
A client wants to set up a traditional PE buyout fund where LPs commit capital and the GP draws it down over 5 years. Which configuration is correct?
Asset Hierarchy
Assets in Portfolio aren't always flat — they can be organized into hierarchies. There are two mechanisms for this:
1. Parent-Child Relationship
The assets table has a self-referencing foreign key (parent_asset_id) for simple parent-child relationships. A parent asset can have multiple child assets.
2. Sub-Positions (Many-to-Many)
For more complex structures, assets use the asset_sub_positions pivot table — a many-to-many relationship that allows an asset to appear as a sub-position under multiple parents. Each sub-position has a type:
Represents share classes within a fund. Example: a PE fund with Class A (lower fees, higher minimum) and Class B (higher fees, lower minimum) shares.
Represents underlying investments held by the fund. Example: a PE fund that owns stakes in Company A, Company B, and Company C.
Visual: Asset Hierarchy Example
Sub-Position Toggles
When an asset has sub-positions, the SubPositionToggle enum controls which behaviors are enabled. These toggles determine how transactions, valuations, and visibility work across the hierarchy.
The MANUAL_VALUATION toggle is the key to understanding how NAV flows through the hierarchy. When set to false, the parent asset's NAV is calculated by summing the valuations of its children. When set to true, someone manually enters the NAV for that node. This matters enormously for multi-class funds where each share class may have its own valuation methodology.
Asset Classes
Every asset has an AssetClass that categorizes the type of investment. This is independent of the asset structure — both PE Funds and Direct assets can be any asset class.
| Asset Class | Description |
|---|---|
CASH | Cash and cash equivalents |
DEBT | Debt instruments (bonds, loans, credit facilities) |
EQUITY | Equity holdings (stock, ownership stakes) |
HYBRID | Hybrid instruments combining debt and equity characteristics |
MULTI_ASSET | Diversified across multiple asset classes |
REAL_ASSETS | Physical assets (infrastructure, natural resources) |
REAL_ESTATE | Property and real estate investments |
COLLECTIBLE / COLLECTIBLES | Art, wine, cars, and other collectible assets |
MEZZANINE_FINANCE | Subordinated debt, typically with equity conversion features |
CONVERTIBLE_LOAN | Loans that can convert to equity under specified conditions |
Asset classes drive the allocation charts in the dashboard (allocation by geography, sector, vintage, style) and help categorize the portfolio for reporting purposes. They don't affect transaction availability — that's purely determined by the asset structure.
Putting It All Together
Here's the complete decision tree when setting up a new asset:
- Choose the structure: Is this a pooled fund (PE Fund) or a direct stake (Direct)?
- If PE Fund — choose the subscription type: Drawdown (commit now, pay later), Units Assigned (commit and get units immediately), or Fully Paid Up (pay everything upfront)?
- If PE Fund — choose the fund type: Closed (fixed fundraise) or Open-Ended (ongoing subscriptions)?
- Choose the asset class: Equity, Debt, Real Estate, etc. — categorization for reporting.
- Set up hierarchy (if needed): Does this asset have share classes (CLASS_TYPE) or underlying investments (UNDERLYING_INVESTMENT_TYPE)? Configure sub-position toggles.
- Configure valuation method: Manual NAV entry or calculated from children?
Once an asset has transactions recorded against it, changing the structure from PE Fund to Direct (or vice versa) would invalidate existing data. The subscription/investment records, capital calls, and metrics would all be inconsistent. Get the structure right at setup time.
Knowledge Check 2
A PE Fund has MANUAL_VALUATION set to FALSE on the parent asset, with two share class sub-positions (Class A and Class B). How is the parent fund's NAV determined?
What's Next
You now understand the two fundamental asset structures and how they determine everything downstream — transaction availability, investor entry, distribution mechanics, and metrics. Next, we'll dive into the full transaction taxonomy — all 17+ transaction types, how they create cash flows, and the dependency chain between them.