All checks were successful
deploy / deploy (push) Successful in 22s
Proof: Persist portfolio value and PnL snapshots from the live inventory and reference-price path so operators can inspect trading performance from repo-controlled data. Assumptions: The last credited inventory snapshot before the first live command is the correct baseline for trade-driven PnL, and EURe remains explicit 1:1 with EUR. Still fake: The new portfolio metrics and watch output are implemented and tested locally but are not live until the updated app image is deployed to k3s.
106 lines
3.1 KiB
JavaScript
106 lines
3.1 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import { buildPortfolioMetricId, computePortfolioMetric } from '../src/core/portfolio-metrics.mjs';
|
|
|
|
const btcAsset = {
|
|
assetId: 'nep141:btc.omft.near',
|
|
symbol: 'BTC',
|
|
decimals: 8,
|
|
};
|
|
|
|
const eureAsset = {
|
|
assetId: 'nep141:eure.omft.near',
|
|
symbol: 'EURe',
|
|
decimals: 18,
|
|
};
|
|
|
|
test('portfolio metrics compute trade pnl 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.trade_pnl_eure, '0.391183707978799978');
|
|
assert.equal(metric.mark_to_market_pnl_eure, '0.497413887978799978');
|
|
assert.equal(metric.price_move_pnl_eure, '0.10623018');
|
|
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.trade_pnl_eure, null);
|
|
assert.equal(metric.mark_to_market_pnl_eure, null);
|
|
assert.equal(metric.price_move_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');
|
|
});
|