Some checks failed
deploy / deploy (push) Failing after 35s
Proof: Dashboard portfolio metrics now include DB-tracked USDC balances valued from live BTC/EUR and BTC/USDC reference prices, with regression coverage for the observed USDC inventory case. Assumptions: USDC is cash-equivalent for valuation when a fresh BTC/USDC reference event is available; live trading safety remains governed by pair config and price route checks. Still fake: Portfolio valuation still does not provide fee-complete realized PnL or generalized valuation for every imported non-stable asset.
274 lines
8.4 KiB
JavaScript
274 lines
8.4 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import {
|
|
buildCashEquivalentValuationAssets,
|
|
buildPortfolioMetricId,
|
|
computePortfolioMetric,
|
|
} from '../src/core/portfolio-metrics.mjs';
|
|
|
|
const btcAsset = {
|
|
assetId: 'nep141:btc.omft.near',
|
|
symbol: 'BTC',
|
|
decimals: 8,
|
|
};
|
|
|
|
const nbtcAsset = {
|
|
assetId: 'nep141:nbtc.bridge.near',
|
|
symbol: 'BTC',
|
|
label: 'BTC / nBTC reserve',
|
|
decimals: 8,
|
|
};
|
|
|
|
const eureAsset = {
|
|
assetId: 'nep141:eure.omft.near',
|
|
symbol: 'EURe',
|
|
decimals: 18,
|
|
};
|
|
|
|
const usdcAsset = {
|
|
assetId: 'nep141:eth-0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48.omft.near',
|
|
symbol: 'USDC',
|
|
decimals: 6,
|
|
};
|
|
|
|
test('portfolio metrics compute portfolio comparison and mark-to-market pnl from baseline funding inventory', () => {
|
|
const metric = computePortfolioMetric({
|
|
baseline: {
|
|
anchor: 'latest_inventory_before_first_command',
|
|
command_at: '2026-04-02T18:10:43.569Z',
|
|
inventory: {
|
|
inventory_id: 'baseline-1',
|
|
synced_at: '2026-04-02T18:10:33.381Z',
|
|
spendable: {
|
|
'nep141:btc.omft.near': '100000',
|
|
'nep141:eure.omft.near': '60000000000000000000',
|
|
},
|
|
},
|
|
price: {
|
|
price_id: 'price-baseline-1',
|
|
observed_at: '2026-04-02T18:10:30.109Z',
|
|
eure_per_btc: '57792.20000000',
|
|
},
|
|
},
|
|
currentInventory: {
|
|
inventory_id: 'current-1',
|
|
synced_at: '2026-04-02T20:46:48.492Z',
|
|
spendable: {
|
|
'nep141:btc.omft.near': '137014',
|
|
'nep141:eure.omft.near': '38999978799978799978',
|
|
},
|
|
},
|
|
currentPrice: {
|
|
price_id: 'price-current-1',
|
|
observed_at: '2026-04-02T20:46:55.305Z',
|
|
eure_per_btc: '58079.20000000',
|
|
},
|
|
btcAsset,
|
|
eureAsset,
|
|
commandCount: 7,
|
|
resultCount: 7,
|
|
});
|
|
|
|
assert.equal(metric.baseline_status, 'active');
|
|
assert.equal(metric.current_portfolio_value_eure, '118.576613887978799978');
|
|
assert.equal(metric.portfolio_vs_simple_hold_eure, '0.497413887978799978');
|
|
assert.equal(metric.trade_pnl_eure, null);
|
|
assert.equal(metric.mark_to_market_pnl_eure, '0.784413887978799978');
|
|
assert.equal(metric.price_move_pnl_eure, '0.287');
|
|
assert.deepEqual(metric.inventory_delta, {
|
|
btc_units: '37014',
|
|
btc: '0.00037014',
|
|
eure_units: '-21000021200021200022',
|
|
eure: '-21.000021200021200022',
|
|
});
|
|
});
|
|
|
|
test('portfolio metrics stay available before the first live execution', () => {
|
|
const metric = computePortfolioMetric({
|
|
baseline: null,
|
|
currentInventory: {
|
|
inventory_id: 'current-2',
|
|
synced_at: '2026-04-02T20:46:48.492Z',
|
|
spendable: {
|
|
'nep141:btc.omft.near': '100000',
|
|
'nep141:eure.omft.near': '60000000000000000000',
|
|
},
|
|
},
|
|
currentPrice: {
|
|
price_id: 'price-current-2',
|
|
observed_at: '2026-04-02T20:46:55.305Z',
|
|
eure_per_btc: '58079.20000000',
|
|
},
|
|
btcAsset,
|
|
eureAsset,
|
|
commandCount: 0,
|
|
resultCount: 0,
|
|
});
|
|
|
|
assert.equal(metric.baseline_status, 'awaiting_first_execution');
|
|
assert.equal(metric.current_portfolio_value_eure, '118.0792');
|
|
assert.equal(metric.portfolio_vs_simple_hold_eure, null);
|
|
assert.equal(metric.trade_pnl_eure, null);
|
|
assert.equal(metric.mark_to_market_pnl_eure, null);
|
|
assert.equal(metric.price_move_pnl_eure, null);
|
|
});
|
|
|
|
test('portfolio metrics value both tracked BTC wrappers as BTC-equivalent inventory', () => {
|
|
const metric = computePortfolioMetric({
|
|
baseline: null,
|
|
currentInventory: {
|
|
inventory_id: 'current-dual-btc',
|
|
synced_at: '2026-05-07T13:45:00.000Z',
|
|
spendable: {
|
|
'nep141:nbtc.bridge.near': '100000',
|
|
'nep141:btc.omft.near': '201051',
|
|
'nep141:eure.omft.near': '0',
|
|
},
|
|
},
|
|
currentPrice: {
|
|
price_id: 'price-dual-btc',
|
|
observed_at: '2026-05-07T13:45:00.000Z',
|
|
eure_per_btc: '50000',
|
|
},
|
|
btcAsset: nbtcAsset,
|
|
btcAssets: [nbtcAsset, btcAsset],
|
|
eureAsset,
|
|
});
|
|
|
|
assert.equal(metric.current_inventory.btc_units, '301051');
|
|
assert.equal(metric.current_inventory.btc, '0.00301051');
|
|
assert.equal(metric.current_portfolio_value_eure, '150.5255');
|
|
assert.deepEqual(metric.current_inventory.btc_assets.map((asset) => asset.asset_id), [
|
|
'nep141:nbtc.bridge.near',
|
|
'nep141:btc.omft.near',
|
|
]);
|
|
});
|
|
|
|
test('portfolio metrics include tracked USDC valued from live BTC/USDC reference', () => {
|
|
const currentPrice = {
|
|
price_id: 'price-usdc-current',
|
|
observed_at: '2026-05-18T15:41:08.837Z',
|
|
eure_per_btc: '65495.20000000',
|
|
usdc_per_btc: '76316.32000000',
|
|
};
|
|
const valuationAssets = buildCashEquivalentValuationAssets({
|
|
trackedAssets: [nbtcAsset, btcAsset, eureAsset, usdcAsset],
|
|
btcAssets: [nbtcAsset, btcAsset],
|
|
eureAsset,
|
|
priceEvents: [currentPrice],
|
|
});
|
|
|
|
const metric = computePortfolioMetric({
|
|
baseline: null,
|
|
currentInventory: {
|
|
inventory_id: 'current-usdc',
|
|
synced_at: '2026-05-18T15:40:38.976Z',
|
|
spendable: {
|
|
'nep141:nbtc.bridge.near': '45186',
|
|
[usdcAsset.assetId]: '366395170',
|
|
[eureAsset.assetId]: '0',
|
|
},
|
|
},
|
|
currentPrice,
|
|
btcAsset: nbtcAsset,
|
|
btcAssets: [nbtcAsset, btcAsset],
|
|
eureAsset,
|
|
valuationAssets,
|
|
});
|
|
|
|
assert.equal(valuationAssets[0].currentUnitValueEure, '0.858206999498927621');
|
|
assert.equal(metric.current_btc_mark_value_eure, '29.594661072');
|
|
assert.equal(metric.current_valued_asset_value_eure, '314.442899476599500513');
|
|
assert.equal(metric.current_portfolio_value_eure, '344.037560548599500513');
|
|
assert.deepEqual(metric.current_inventory.valued_assets.map((asset) => ({
|
|
asset_id: asset.asset_id,
|
|
amount: asset.amount,
|
|
value_eure: asset.value_eure,
|
|
valuation_source: asset.valuation_source,
|
|
})), [
|
|
{
|
|
asset_id: usdcAsset.assetId,
|
|
amount: '366.39517',
|
|
value_eure: '314.442899476599500513',
|
|
valuation_source: 'btc_usdc_reference',
|
|
},
|
|
]);
|
|
});
|
|
|
|
test('portfolio metrics treat later deposits and withdrawals as external cash flows instead of PnL', () => {
|
|
const metric = computePortfolioMetric({
|
|
baseline: {
|
|
anchor: 'latest_inventory_before_first_command',
|
|
command_at: '2026-04-02T18:10:43.569Z',
|
|
inventory: {
|
|
inventory_id: 'baseline-2',
|
|
synced_at: '2026-04-02T18:10:33.381Z',
|
|
spendable: {
|
|
'nep141:btc.omft.near': '100000',
|
|
'nep141:eure.omft.near': '60000000000000000000',
|
|
},
|
|
},
|
|
price: {
|
|
price_id: 'price-baseline-2',
|
|
observed_at: '2026-04-02T18:10:30.109Z',
|
|
eure_per_btc: '57792.20000000',
|
|
},
|
|
},
|
|
currentInventory: {
|
|
inventory_id: 'current-3',
|
|
synced_at: '2026-04-07T15:43:30.463Z',
|
|
spendable: {
|
|
'nep141:btc.omft.near': '137014',
|
|
'nep141:eure.omft.near': '63999978599978799978',
|
|
},
|
|
},
|
|
currentPrice: {
|
|
price_id: 'price-current-3',
|
|
observed_at: '2026-04-07T15:43:29.885Z',
|
|
eure_per_btc: '58845.90000000',
|
|
},
|
|
externalFlows: [
|
|
{
|
|
flow_id: 'withdrawal-1',
|
|
kind: 'withdrawal',
|
|
asset_id: eureAsset.assetId,
|
|
effective_at: '2026-04-02T10:52:27.863Z',
|
|
signed_units: '-1000000000000000000',
|
|
reference_price_eure_per_btc_at_flow_time: null,
|
|
},
|
|
{
|
|
flow_id: 'deposit-1',
|
|
kind: 'deposit',
|
|
asset_id: eureAsset.assetId,
|
|
effective_at: '2026-04-07T15:20:54.757Z',
|
|
signed_units: '24999999800000000000',
|
|
reference_price_eure_per_btc_at_flow_time: null,
|
|
},
|
|
],
|
|
btcAsset,
|
|
eureAsset,
|
|
commandCount: 7,
|
|
resultCount: 7,
|
|
});
|
|
|
|
assert.equal(metric.external_cash_flows.flow_count, 2);
|
|
assert.equal(metric.external_cash_flows.net_eure, '23.9999998');
|
|
assert.equal(metric.external_cash_flows.net_value_eure_at_flow_time, '23.9999998');
|
|
assert.equal(metric.baseline_portfolio_value_eure_at_baseline_price, '141.7921998');
|
|
assert.equal(metric.baseline_portfolio_value_eure_at_current_price, '142.8458998');
|
|
assert.equal(metric.mark_to_market_pnl_eure, '2.834900225978799978');
|
|
assert.equal(metric.price_move_pnl_eure, '1.0537');
|
|
assert.equal(metric.portfolio_vs_simple_hold_eure, '1.781200225978799978');
|
|
assert.equal(metric.trade_pnl_eure, null);
|
|
});
|
|
|
|
test('portfolio metric id keys off the baseline and current snapshots', () => {
|
|
const metricId = buildPortfolioMetricId({
|
|
baselineInventoryId: 'baseline-1',
|
|
currentInventoryId: 'current-1',
|
|
currentPriceId: 'price-current-1',
|
|
});
|
|
|
|
assert.equal(metricId, 'portfolio-metric:baseline-1:current-1:price-current-1');
|
|
});
|