Portfolio Construction
Build a portfolio view from existing Dark Matter inventory.
Overview
This cookbook explains how to build a portfolio view from existing Dark Matter inventory. The workflow: pull positions via the API with filters, aggregate by issuer, vehicle class, or strategy, and render a portfolio dashboard. The pattern supports internal tools, reporting, and customer-facing portfolio UIs. You can run this as a batch job, a real-time dashboard, or a hybrid with cached data and webhook-driven updates.
Step 1: Pull inventory
Use the positions API to list positions with filters for participant, status, vehicle class, and other criteria. Paginate through results for large inventories. Cache results as appropriate for your freshness requirements.
const positions = await dmtr.positions.list({
participant_id: "part-allocator-001",
status: "active",
limit: 100
});
for (const pos of positions.data) {
console.log(pos.entity_id, pos.asset?.issuer, pos.valuation?.current_mark);
}{
"data": [
{
"entity_id": "meg-2026-047",
"asset": {
"vehicle_class": "spv_llc",
"issuer": "Acme Growth Fund III"
},
"units": 100,
"valuation": {
"current_mark": 2500000
},
"status": {
"current": "active"
}
},
{
"entity_id": "meg-2026-112",
"asset": {
"vehicle_class": "fund_lp",
"issuer": "Sequoia Capital Fund XVIII"
},
"units": 50,
"valuation": {
"current_mark": 1250000
},
"status": {
"current": "active"
}
},
{
"entity_id": "meg-2026-089",
"asset": {
"vehicle_class": "spv_llc",
"issuer": "Venture Co SPV II"
},
"units": 200,
"valuation": {
"current_mark": 800000
},
"status": {
"current": "active"
}
}
],
"has_more": true,
"next_cursor": "eyJpZCI6Im1lZy0yMDI2LTA5MCJ9"
}Step 2: Aggregate by dimension
Aggregate positions by vehicle class, issuer, vintage, or strategy. Compute totals for valuation, units, and exposure. Use the aggregated data to power summary tables, charts, or drill-down views.
const positions = await dmtr.positions.list({
participant_id: "part-allocator-001",
status: "active",
limit: 100
});
const byVehicle = {};
for (const p of positions.data) {
const vc = p.asset?.vehicle_class ?? "unknown";
if (!byVehicle[vc]) byVehicle[vc] = { count: 0, totalValuation: 0 };
byVehicle[vc].count += 1;
byVehicle[vc].totalValuation += p.valuation?.current_mark ?? 0;
}
console.log(byVehicle);Step 3: Render portfolio
Display the aggregated portfolio in your chosen format: table, chart, or dashboard. A typical summary table might show:
| Vehicle class | Count | Total valuation |
|---|---|---|
| spv_llc | 12 | $4,200,000 |
| fund_lp | 8 | $2,100,000 |
| direct | 3 | $850,000 |
Support drill-down to position detail. Link to the DMTR console for full context. For a complete guide with UI patterns and real-time updates, see Build a Portfolio View.
Use webhooks for live portfolio updates. Subscribe to position lifecycle events (registration, transfer, valuation change) and refresh your view incrementally instead of polling. See the webhooks documentation for setup.
Related docs
- Build a Portfolio View — Full guide with aggregation patterns and UI examples
- Pagination — Cursor-based pagination for large inventories
- Pull Inventory — Quickstart for listing and filtering positions