@the-situation/indexer 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -4
- package/dist/aggregator/cohort.d.ts +30 -0
- package/dist/aggregator/cohort.d.ts.map +1 -0
- package/dist/aggregator/cohort.js +153 -0
- package/dist/aggregator/cohort.js.map +1 -0
- package/dist/aggregator/daily.d.ts +71 -0
- package/dist/aggregator/daily.d.ts.map +1 -0
- package/dist/aggregator/daily.js +249 -0
- package/dist/aggregator/daily.js.map +1 -0
- package/dist/aggregator/domains.d.ts +20 -0
- package/dist/aggregator/domains.d.ts.map +1 -0
- package/dist/aggregator/domains.js +38 -0
- package/dist/aggregator/domains.js.map +1 -0
- package/dist/aggregator/index.d.ts +31 -0
- package/dist/aggregator/index.d.ts.map +1 -0
- package/dist/aggregator/index.js +100 -0
- package/dist/aggregator/index.js.map +1 -0
- package/dist/aggregator/lifetime.d.ts +52 -0
- package/dist/aggregator/lifetime.d.ts.map +1 -0
- package/dist/aggregator/lifetime.js +222 -0
- package/dist/aggregator/lifetime.js.map +1 -0
- package/dist/aggregator/roi.d.ts +42 -0
- package/dist/aggregator/roi.d.ts.map +1 -0
- package/dist/aggregator/roi.js +153 -0
- package/dist/aggregator/roi.js.map +1 -0
- package/dist/aggregator/sources.d.ts +59 -0
- package/dist/aggregator/sources.d.ts.map +1 -0
- package/dist/aggregator/sources.js +53 -0
- package/dist/aggregator/sources.js.map +1 -0
- package/dist/aggregator/writers.d.ts +22 -0
- package/dist/aggregator/writers.d.ts.map +1 -0
- package/dist/aggregator/writers.js +147 -0
- package/dist/aggregator/writers.js.map +1 -0
- package/dist/api/app.d.ts +177 -13
- package/dist/api/app.d.ts.map +1 -1
- package/dist/api/app.js +4 -3
- package/dist/api/app.js.map +1 -1
- package/dist/api/routes/admin-subscriptions.d.ts +11 -11
- package/dist/api/routes/analytics.d.ts +205 -0
- package/dist/api/routes/analytics.d.ts.map +1 -0
- package/dist/api/routes/analytics.js +122 -0
- package/dist/api/routes/analytics.js.map +1 -0
- package/dist/api/routes/health.d.ts.map +1 -1
- package/dist/api/routes/health.js +2 -0
- package/dist/api/routes/health.js.map +1 -1
- package/dist/api/routes/index.d.ts +1 -0
- package/dist/api/routes/index.d.ts.map +1 -1
- package/dist/api/routes/index.js +1 -0
- package/dist/api/routes/index.js.map +1 -1
- package/dist/api/routes/rankings.d.ts +17 -3
- package/dist/api/routes/rankings.d.ts.map +1 -1
- package/dist/api/routes/rankings.js +44 -5
- package/dist/api/routes/rankings.js.map +1 -1
- package/dist/api/routes/trader-stats.d.ts +11 -2
- package/dist/api/routes/trader-stats.d.ts.map +1 -1
- package/dist/api/routes/trader-stats.js +72 -2
- package/dist/api/routes/trader-stats.js.map +1 -1
- package/dist/client/IndexerClient.d.ts +30 -1
- package/dist/client/IndexerClient.d.ts.map +1 -1
- package/dist/client/IndexerClient.js.map +1 -1
- package/dist/client/IndexerClientLive.d.ts.map +1 -1
- package/dist/client/IndexerClientLive.js +50 -1
- package/dist/client/IndexerClientLive.js.map +1 -1
- package/dist/client/convenience.d.ts +9 -2
- package/dist/client/convenience.d.ts.map +1 -1
- package/dist/client/convenience.js +9 -1
- package/dist/client/convenience.js.map +1 -1
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/config.d.ts +17 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +39 -3
- package/dist/config.js.map +1 -1
- package/dist/etl/event-indexer.d.ts +1 -1
- package/dist/etl/lp-position-refresher.d.ts +2 -1
- package/dist/etl/lp-position-refresher.d.ts.map +1 -1
- package/dist/etl/lp-position-refresher.js +24 -11
- package/dist/etl/lp-position-refresher.js.map +1 -1
- package/dist/index.js +64 -8
- package/dist/index.js.map +1 -1
- package/dist/layers/ChainReaderLive.d.ts.map +1 -1
- package/dist/layers/ChainReaderLive.js +15 -0
- package/dist/layers/ChainReaderLive.js.map +1 -1
- package/dist/layers/VoyagerClientLive.d.ts +2 -1
- package/dist/layers/VoyagerClientLive.d.ts.map +1 -1
- package/dist/layers/VoyagerClientLive.js +89 -55
- package/dist/layers/VoyagerClientLive.js.map +1 -1
- package/dist/services/ChainReader.d.ts +10 -0
- package/dist/services/ChainReader.d.ts.map +1 -1
- package/dist/services/ChainReader.js.map +1 -1
- package/dist/services/VoyagerRateLimit.d.ts +11 -8
- package/dist/services/VoyagerRateLimit.d.ts.map +1 -1
- package/dist/services/VoyagerRateLimit.js +51 -26
- package/dist/services/VoyagerRateLimit.js.map +1 -1
- package/dist/types/analytics.d.ts +194 -0
- package/dist/types/analytics.d.ts.map +1 -0
- package/dist/types/analytics.js +10 -0
- package/dist/types/analytics.js.map +1 -0
- package/dist/types/api.d.ts +2 -0
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/warehouse/analytics-helpers.d.ts +36 -0
- package/dist/warehouse/analytics-helpers.d.ts.map +1 -0
- package/dist/warehouse/analytics-helpers.js +142 -0
- package/dist/warehouse/analytics-helpers.js.map +1 -0
- package/dist/warehouse/backfill.d.ts +26 -0
- package/dist/warehouse/backfill.d.ts.map +1 -0
- package/dist/warehouse/backfill.js +77 -0
- package/dist/warehouse/backfill.js.map +1 -0
- package/dist/warehouse/connection.d.ts +18 -0
- package/dist/warehouse/connection.d.ts.map +1 -0
- package/dist/warehouse/connection.js +24 -0
- package/dist/warehouse/connection.js.map +1 -0
- package/dist/warehouse/index.d.ts +14 -0
- package/dist/warehouse/index.d.ts.map +1 -0
- package/dist/warehouse/index.js +14 -0
- package/dist/warehouse/index.js.map +1 -0
- package/dist/warehouse/repositories/analytics.d.ts +61 -0
- package/dist/warehouse/repositories/analytics.d.ts.map +1 -0
- package/dist/warehouse/repositories/analytics.js +418 -0
- package/dist/warehouse/repositories/analytics.js.map +1 -0
- package/dist/warehouse/schema.d.ts +9 -0
- package/dist/warehouse/schema.d.ts.map +1 -0
- package/dist/warehouse/schema.js +219 -0
- package/dist/warehouse/schema.js.map +1 -0
- package/dist/warehouse/seed-domains.d.ts +29 -0
- package/dist/warehouse/seed-domains.d.ts.map +1 -0
- package/dist/warehouse/seed-domains.js +223 -0
- package/dist/warehouse/seed-domains.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** All primary-domain rows. */
|
|
2
|
+
export async function loadMarketPrimaryDomains(pg) {
|
|
3
|
+
const rows = (await pg `
|
|
4
|
+
SELECT market_address, domain_slug
|
|
5
|
+
FROM market_domains
|
|
6
|
+
WHERE is_primary
|
|
7
|
+
`);
|
|
8
|
+
const map = new Map();
|
|
9
|
+
for (const row of rows) {
|
|
10
|
+
map.set(row.market_address, row.domain_slug);
|
|
11
|
+
}
|
|
12
|
+
return map;
|
|
13
|
+
}
|
|
14
|
+
/** Lookup with `'other'` fallback. */
|
|
15
|
+
export function primaryDomainOf(map, marketAddress) {
|
|
16
|
+
return map.get(marketAddress) ?? 'other';
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns all (market, slug) pairs — useful for "user touched N domains"
|
|
20
|
+
* style metrics. A market may be tagged with multiple domains; this returns
|
|
21
|
+
* every assignment.
|
|
22
|
+
*/
|
|
23
|
+
export async function loadAllMarketDomains(pg) {
|
|
24
|
+
const rows = (await pg `
|
|
25
|
+
SELECT market_address, domain_slug FROM market_domains
|
|
26
|
+
`);
|
|
27
|
+
const map = new Map();
|
|
28
|
+
for (const row of rows) {
|
|
29
|
+
let set = map.get(row.market_address);
|
|
30
|
+
if (!set) {
|
|
31
|
+
set = new Set();
|
|
32
|
+
map.set(row.market_address, set);
|
|
33
|
+
}
|
|
34
|
+
set.add(row.domain_slug);
|
|
35
|
+
}
|
|
36
|
+
return map;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=domains.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domains.js","sourceRoot":"","sources":["../../src/aggregator/domains.ts"],"names":[],"mappings":"AAWA,+BAA+B;AAC/B,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,EAAO;IACpD,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAA;;;;GAIrB,CAA2D,CAAC;IAE7D,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,eAAe,CAAC,GAAoB,EAAE,aAAqB;IACzE,OAAO,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,EAAO;IAEP,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAA;;GAErB,CAA2D,CAAC;IAE7D,MAAM,GAAG,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC3C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACtC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;YACxB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QACnC,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,GAA+C,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aggregator orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* Reads OLTP rows from SQLite, computes derived analytics in memory, and bulk-
|
|
5
|
+
* writes them into the Postgres warehouse. Intended to run on a non-overlapping
|
|
6
|
+
* loop (default 5 min) alongside the existing event/state/position refreshers.
|
|
7
|
+
*
|
|
8
|
+
* Strategy: full recompute per cycle. Cheap at current scale (~100k events).
|
|
9
|
+
* Switch to incremental once event volume justifies it.
|
|
10
|
+
*/
|
|
11
|
+
import type { SQL } from 'bun';
|
|
12
|
+
import type { Database as SqliteDatabase } from 'bun:sqlite';
|
|
13
|
+
export interface AggregatorRunSummary {
|
|
14
|
+
readonly events: number;
|
|
15
|
+
readonly traders: number;
|
|
16
|
+
readonly lps: number;
|
|
17
|
+
readonly dailyRows: number;
|
|
18
|
+
readonly cohortRows: number;
|
|
19
|
+
readonly roiRows: number;
|
|
20
|
+
readonly durationMs: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function runAggregatorOnce(sqlite: SqliteDatabase, pg: SQL): Promise<AggregatorRunSummary>;
|
|
23
|
+
export interface AggregatorHandles {
|
|
24
|
+
readonly stop: () => void;
|
|
25
|
+
readonly runNow: () => Promise<AggregatorRunSummary>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Start a non-overlapping aggregator loop. Returns handles for shutdown.
|
|
29
|
+
*/
|
|
30
|
+
export declare function startAggregator(sqlite: SqliteDatabase, pg: SQL, intervalMs: number): AggregatorHandles;
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/aggregator/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,KAAK,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,YAAY,CAAC;AA+B7D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,cAAc,EACtB,EAAE,EAAE,GAAG,GACN,OAAO,CAAC,oBAAoB,CAAC,CA6C/B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,cAAc,EACtB,EAAE,EAAE,GAAG,EACP,UAAU,EAAE,MAAM,GACjB,iBAAiB,CA+CnB"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { log } from '../logger';
|
|
2
|
+
import { buildDailyAggregates, } from './daily';
|
|
3
|
+
import { loadMarketPrimaryDomains } from './domains';
|
|
4
|
+
import { buildLPLifetime, buildTraderLifetime, } from './lifetime';
|
|
5
|
+
import { buildCohortRetention, writeCohortRetention } from './cohort';
|
|
6
|
+
import { buildRoi, writeRoi } from './roi';
|
|
7
|
+
import { readAllEvents, readAllLPPositions, readAllPositions, } from './sources';
|
|
8
|
+
import { recordAggregatorRun, writeDailyDomainStats, writeDailyLPStats, writeDailyMarketStats, writeDailyPlatformStats, writeDailyTraderStats, writeLPLifetime, writeTraderLifetime, } from './writers';
|
|
9
|
+
export async function runAggregatorOnce(sqlite, pg) {
|
|
10
|
+
const start = performance.now();
|
|
11
|
+
const [events, positions, lpPositions, marketDomains] = await Promise.all([
|
|
12
|
+
Promise.resolve(readAllEvents(sqlite)),
|
|
13
|
+
Promise.resolve(readAllPositions(sqlite)),
|
|
14
|
+
Promise.resolve(readAllLPPositions(sqlite)),
|
|
15
|
+
loadMarketPrimaryDomains(pg),
|
|
16
|
+
]);
|
|
17
|
+
const daily = buildDailyAggregates(events, marketDomains);
|
|
18
|
+
const traderLifetime = buildTraderLifetime(events, positions, marketDomains);
|
|
19
|
+
const lpLifetime = buildLPLifetime(lpPositions, marketDomains);
|
|
20
|
+
const cohort = buildCohortRetention(events, traderLifetime, lpLifetime, marketDomains);
|
|
21
|
+
const roi = buildRoi(traderLifetime, lpLifetime);
|
|
22
|
+
await writeDailyTraderStats(pg, daily.trader);
|
|
23
|
+
await writeDailyLPStats(pg, daily.lp);
|
|
24
|
+
await writeDailyMarketStats(pg, daily.market);
|
|
25
|
+
await writeDailyDomainStats(pg, daily.domain);
|
|
26
|
+
await writeDailyPlatformStats(pg, daily.platform);
|
|
27
|
+
await writeTraderLifetime(pg, traderLifetime);
|
|
28
|
+
await writeLPLifetime(pg, lpLifetime);
|
|
29
|
+
await writeCohortRetention(pg, cohort);
|
|
30
|
+
await writeRoi(pg, roi);
|
|
31
|
+
const durationMs = Math.round(performance.now() - start);
|
|
32
|
+
return {
|
|
33
|
+
events: events.length,
|
|
34
|
+
traders: traderLifetime.length,
|
|
35
|
+
lps: lpLifetime.length,
|
|
36
|
+
dailyRows: daily.trader.length +
|
|
37
|
+
daily.lp.length +
|
|
38
|
+
daily.market.length +
|
|
39
|
+
daily.domain.length +
|
|
40
|
+
daily.platform.length,
|
|
41
|
+
cohortRows: cohort.length,
|
|
42
|
+
roiRows: roi.distribution.length + roi.summary.length,
|
|
43
|
+
durationMs,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Start a non-overlapping aggregator loop. Returns handles for shutdown.
|
|
48
|
+
*/
|
|
49
|
+
export function startAggregator(sqlite, pg, intervalMs) {
|
|
50
|
+
let stopped = false;
|
|
51
|
+
let timer = null;
|
|
52
|
+
let inFlight = null;
|
|
53
|
+
async function runOnce() {
|
|
54
|
+
try {
|
|
55
|
+
const summary = await runAggregatorOnce(sqlite, pg);
|
|
56
|
+
await recordAggregatorRun(pg, 'main', true, null);
|
|
57
|
+
log.info('aggregator cycle', { ...summary });
|
|
58
|
+
return summary;
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
62
|
+
log.error('aggregator cycle failed', { error: message });
|
|
63
|
+
try {
|
|
64
|
+
await recordAggregatorRun(pg, 'main', false, message);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// ignore — bookkeeping is best-effort
|
|
68
|
+
}
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function loop() {
|
|
73
|
+
if (stopped)
|
|
74
|
+
return;
|
|
75
|
+
inFlight = runOnce();
|
|
76
|
+
try {
|
|
77
|
+
await inFlight;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// already logged
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
inFlight = null;
|
|
84
|
+
}
|
|
85
|
+
if (stopped)
|
|
86
|
+
return;
|
|
87
|
+
timer = setTimeout(loop, intervalMs);
|
|
88
|
+
}
|
|
89
|
+
// Kick off after one interval so the OLTP boot sync gets a head start.
|
|
90
|
+
timer = setTimeout(loop, intervalMs);
|
|
91
|
+
return {
|
|
92
|
+
stop: () => {
|
|
93
|
+
stopped = true;
|
|
94
|
+
if (timer != null)
|
|
95
|
+
clearTimeout(timer);
|
|
96
|
+
},
|
|
97
|
+
runNow: () => inFlight ?? runOnce(),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/aggregator/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-entity lifetime aggregates (CLTV inputs).
|
|
3
|
+
*
|
|
4
|
+
* `trader_lifetime` is built from market_events (for activity) + user_positions
|
|
5
|
+
* (for P&L). `lp_lifetime` rolls up lp_positions across markets per provider.
|
|
6
|
+
*
|
|
7
|
+
* ROI percentage is total_pnl / total_collateral_at_risk * 100. It is NULL
|
|
8
|
+
* when the denominator is zero (no capital ever deployed).
|
|
9
|
+
*/
|
|
10
|
+
import { type AggEventRow, type AggLPPositionRow, type AggPositionRow } from './sources';
|
|
11
|
+
import { type MarketDomainMap } from './domains';
|
|
12
|
+
export interface TraderLifetimeRow {
|
|
13
|
+
readonly trader: string;
|
|
14
|
+
readonly first_trade_at: number | null;
|
|
15
|
+
readonly last_trade_at: number | null;
|
|
16
|
+
readonly cohort_week: string | null;
|
|
17
|
+
readonly total_trades: number;
|
|
18
|
+
readonly buy_count: number;
|
|
19
|
+
readonly sell_count: number;
|
|
20
|
+
readonly markets_traded: number;
|
|
21
|
+
readonly domains_traded: number;
|
|
22
|
+
readonly domains_json: readonly string[];
|
|
23
|
+
readonly total_volume: number;
|
|
24
|
+
readonly total_collateral_at_risk: number;
|
|
25
|
+
readonly realized_pnl: number;
|
|
26
|
+
readonly unrealized_pnl: number;
|
|
27
|
+
readonly total_pnl: number;
|
|
28
|
+
readonly roi_pct: number | null;
|
|
29
|
+
readonly active_days: number;
|
|
30
|
+
}
|
|
31
|
+
export interface LPLifetimeRow {
|
|
32
|
+
readonly provider: string;
|
|
33
|
+
readonly first_deposit_at: number | null;
|
|
34
|
+
readonly last_activity_at: number | null;
|
|
35
|
+
readonly cohort_week: string | null;
|
|
36
|
+
readonly deposit_count: number;
|
|
37
|
+
readonly withdraw_count: number;
|
|
38
|
+
readonly total_deposited: number;
|
|
39
|
+
readonly total_withdrawn: number;
|
|
40
|
+
readonly net_position: number;
|
|
41
|
+
readonly current_value: number | null;
|
|
42
|
+
readonly unrealized_pnl: number | null;
|
|
43
|
+
readonly realized_pnl: number;
|
|
44
|
+
readonly markets_provided: number;
|
|
45
|
+
readonly domains_provided: number;
|
|
46
|
+
readonly domains_json: readonly string[];
|
|
47
|
+
readonly active_days: number;
|
|
48
|
+
readonly roi_pct: number | null;
|
|
49
|
+
}
|
|
50
|
+
export declare function buildTraderLifetime(events: readonly AggEventRow[], positions: readonly AggPositionRow[], marketDomains: MarketDomainMap): readonly TraderLifetimeRow[];
|
|
51
|
+
export declare function buildLPLifetime(lpPositions: readonly AggLPPositionRow[], marketDomains: MarketDomainMap): readonly LPLifetimeRow[];
|
|
52
|
+
//# sourceMappingURL=lifetime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifetime.d.ts","sourceRoot":"","sources":["../../src/aggregator/lifetime.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EAGpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,eAAe,EAAmB,MAAM,WAAW,CAAC;AAElE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;IAC1C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAiDD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,SAAS,EAAE,SAAS,cAAc,EAAE,EACpC,aAAa,EAAE,eAAe,GAC7B,SAAS,iBAAiB,EAAE,CAiH9B;AAED,wBAAgB,eAAe,CAC7B,WAAW,EAAE,SAAS,gBAAgB,EAAE,EACxC,aAAa,EAAE,eAAe,GAC7B,SAAS,aAAa,EAAE,CAuF1B"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-entity lifetime aggregates (CLTV inputs).
|
|
3
|
+
*
|
|
4
|
+
* `trader_lifetime` is built from market_events (for activity) + user_positions
|
|
5
|
+
* (for P&L). `lp_lifetime` rolls up lp_positions across markets per provider.
|
|
6
|
+
*
|
|
7
|
+
* ROI percentage is total_pnl / total_collateral_at_risk * 100. It is NULL
|
|
8
|
+
* when the denominator is zero (no capital ever deployed).
|
|
9
|
+
*/
|
|
10
|
+
import { TRADE_EVENT_TYPES, parseCollateralAmount, } from './sources';
|
|
11
|
+
import { primaryDomainOf } from './domains';
|
|
12
|
+
function dateOfUTC(ts) {
|
|
13
|
+
const d = new Date(ts * 1000);
|
|
14
|
+
const yyyy = d.getUTCFullYear();
|
|
15
|
+
const mm = String(d.getUTCMonth() + 1).padStart(2, '0');
|
|
16
|
+
const dd = String(d.getUTCDate()).padStart(2, '0');
|
|
17
|
+
return `${yyyy}-${mm}-${dd}`;
|
|
18
|
+
}
|
|
19
|
+
/** ISO Monday (UTC) of the week containing the given unix-seconds timestamp. */
|
|
20
|
+
function isoWeekStart(ts) {
|
|
21
|
+
const d = new Date(ts * 1000);
|
|
22
|
+
const day = d.getUTCDay(); // 0 Sun .. 6 Sat
|
|
23
|
+
const diff = day === 0 ? -6 : 1 - day;
|
|
24
|
+
const monday = new Date(d.getTime());
|
|
25
|
+
monday.setUTCDate(d.getUTCDate() + diff);
|
|
26
|
+
return dateOfUTC(Math.floor(monday.getTime() / 1000));
|
|
27
|
+
}
|
|
28
|
+
export function buildTraderLifetime(events, positions, marketDomains) {
|
|
29
|
+
const states = new Map();
|
|
30
|
+
for (const event of events) {
|
|
31
|
+
if (!event.trader)
|
|
32
|
+
continue;
|
|
33
|
+
if (!TRADE_EVENT_TYPES.has(event.event_type))
|
|
34
|
+
continue;
|
|
35
|
+
const trader = event.trader;
|
|
36
|
+
const collateral = parseCollateralAmount(event.collateral_posted);
|
|
37
|
+
const isSell = (event.is_position_sell ?? 0) === 1;
|
|
38
|
+
const domain = primaryDomainOf(marketDomains, event.market_address);
|
|
39
|
+
let s = states.get(trader);
|
|
40
|
+
if (!s) {
|
|
41
|
+
s = {
|
|
42
|
+
first_trade_at: event.timestamp,
|
|
43
|
+
last_trade_at: event.timestamp,
|
|
44
|
+
total_trades: 0,
|
|
45
|
+
buy_count: 0,
|
|
46
|
+
sell_count: 0,
|
|
47
|
+
markets: new Set(),
|
|
48
|
+
domains: new Set(),
|
|
49
|
+
total_volume: 0,
|
|
50
|
+
active_days: new Set(),
|
|
51
|
+
};
|
|
52
|
+
states.set(trader, s);
|
|
53
|
+
}
|
|
54
|
+
s.first_trade_at = Math.min(s.first_trade_at, event.timestamp);
|
|
55
|
+
s.last_trade_at = Math.max(s.last_trade_at, event.timestamp);
|
|
56
|
+
s.total_trades += 1;
|
|
57
|
+
if (isSell)
|
|
58
|
+
s.sell_count += 1;
|
|
59
|
+
else
|
|
60
|
+
s.buy_count += 1;
|
|
61
|
+
s.markets.add(event.market_address);
|
|
62
|
+
s.domains.add(domain);
|
|
63
|
+
s.total_volume += collateral;
|
|
64
|
+
s.active_days.add(dateOfUTC(event.timestamp));
|
|
65
|
+
}
|
|
66
|
+
// P&L from user_positions
|
|
67
|
+
const pnlByTrader = new Map();
|
|
68
|
+
for (const pos of positions) {
|
|
69
|
+
if (!pos.trader)
|
|
70
|
+
continue;
|
|
71
|
+
const realized = pos.realized_pnl ?? 0;
|
|
72
|
+
const unrealized = pos.has_position === 1 ? (pos.unrealized_pnl ?? 0) : 0;
|
|
73
|
+
const ev = pos.expected_value ?? 0;
|
|
74
|
+
const entry = pnlByTrader.get(pos.trader) ?? {
|
|
75
|
+
realized: 0,
|
|
76
|
+
unrealized: 0,
|
|
77
|
+
collateralAtRisk: 0,
|
|
78
|
+
};
|
|
79
|
+
entry.realized += realized;
|
|
80
|
+
entry.unrealized += unrealized;
|
|
81
|
+
entry.collateralAtRisk += Math.max(0, ev);
|
|
82
|
+
pnlByTrader.set(pos.trader, entry);
|
|
83
|
+
}
|
|
84
|
+
const out = [];
|
|
85
|
+
for (const [trader, s] of states) {
|
|
86
|
+
const pnl = pnlByTrader.get(trader) ?? { realized: 0, unrealized: 0, collateralAtRisk: 0 };
|
|
87
|
+
const denom = pnl.collateralAtRisk > 0 ? pnl.collateralAtRisk : s.total_volume;
|
|
88
|
+
const total_pnl = pnl.realized + pnl.unrealized;
|
|
89
|
+
const roi_pct = denom > 0 ? (total_pnl / denom) * 100 : null;
|
|
90
|
+
out.push({
|
|
91
|
+
trader,
|
|
92
|
+
first_trade_at: s.first_trade_at,
|
|
93
|
+
last_trade_at: s.last_trade_at,
|
|
94
|
+
cohort_week: isoWeekStart(s.first_trade_at),
|
|
95
|
+
total_trades: s.total_trades,
|
|
96
|
+
buy_count: s.buy_count,
|
|
97
|
+
sell_count: s.sell_count,
|
|
98
|
+
markets_traded: s.markets.size,
|
|
99
|
+
domains_traded: s.domains.size,
|
|
100
|
+
domains_json: Array.from(s.domains).sort(),
|
|
101
|
+
total_volume: s.total_volume,
|
|
102
|
+
total_collateral_at_risk: denom,
|
|
103
|
+
realized_pnl: pnl.realized,
|
|
104
|
+
unrealized_pnl: pnl.unrealized,
|
|
105
|
+
total_pnl,
|
|
106
|
+
roi_pct,
|
|
107
|
+
active_days: s.active_days.size,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// Traders that have positions but somehow no trade events still get a row.
|
|
111
|
+
for (const [trader, pnl] of pnlByTrader) {
|
|
112
|
+
if (states.has(trader))
|
|
113
|
+
continue;
|
|
114
|
+
const denom = pnl.collateralAtRisk;
|
|
115
|
+
const total_pnl = pnl.realized + pnl.unrealized;
|
|
116
|
+
const roi_pct = denom > 0 ? (total_pnl / denom) * 100 : null;
|
|
117
|
+
out.push({
|
|
118
|
+
trader,
|
|
119
|
+
first_trade_at: null,
|
|
120
|
+
last_trade_at: null,
|
|
121
|
+
cohort_week: null,
|
|
122
|
+
total_trades: 0,
|
|
123
|
+
buy_count: 0,
|
|
124
|
+
sell_count: 0,
|
|
125
|
+
markets_traded: 0,
|
|
126
|
+
domains_traded: 0,
|
|
127
|
+
domains_json: [],
|
|
128
|
+
total_volume: 0,
|
|
129
|
+
total_collateral_at_risk: denom,
|
|
130
|
+
realized_pnl: pnl.realized,
|
|
131
|
+
unrealized_pnl: pnl.unrealized,
|
|
132
|
+
total_pnl,
|
|
133
|
+
roi_pct,
|
|
134
|
+
active_days: 0,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
return out;
|
|
138
|
+
}
|
|
139
|
+
export function buildLPLifetime(lpPositions, marketDomains) {
|
|
140
|
+
const states = new Map();
|
|
141
|
+
for (const lp of lpPositions) {
|
|
142
|
+
const domain = primaryDomainOf(marketDomains, lp.market_address);
|
|
143
|
+
let s = states.get(lp.provider);
|
|
144
|
+
if (!s) {
|
|
145
|
+
s = {
|
|
146
|
+
first_deposit_at: Number.POSITIVE_INFINITY,
|
|
147
|
+
last_activity_at: 0,
|
|
148
|
+
deposit_count: 0,
|
|
149
|
+
withdraw_count: 0,
|
|
150
|
+
total_deposited: 0,
|
|
151
|
+
total_withdrawn: 0,
|
|
152
|
+
current_value: 0,
|
|
153
|
+
current_value_known: false,
|
|
154
|
+
unrealized_pnl: 0,
|
|
155
|
+
unrealized_pnl_known: false,
|
|
156
|
+
realized_pnl: 0,
|
|
157
|
+
markets: new Set(),
|
|
158
|
+
domains: new Set(),
|
|
159
|
+
active_days: new Set(),
|
|
160
|
+
};
|
|
161
|
+
states.set(lp.provider, s);
|
|
162
|
+
}
|
|
163
|
+
if (lp.first_deposit_at != null) {
|
|
164
|
+
s.first_deposit_at = Math.min(s.first_deposit_at, lp.first_deposit_at);
|
|
165
|
+
s.active_days.add(dateOfUTC(lp.first_deposit_at));
|
|
166
|
+
}
|
|
167
|
+
if (lp.last_activity_at != null) {
|
|
168
|
+
s.last_activity_at = Math.max(s.last_activity_at, lp.last_activity_at);
|
|
169
|
+
s.active_days.add(dateOfUTC(lp.last_activity_at));
|
|
170
|
+
}
|
|
171
|
+
s.deposit_count += lp.deposit_count;
|
|
172
|
+
s.withdraw_count += lp.withdrawal_count;
|
|
173
|
+
s.total_deposited += lp.total_deposited;
|
|
174
|
+
s.total_withdrawn += lp.total_withdrawn;
|
|
175
|
+
if (lp.current_value != null) {
|
|
176
|
+
s.current_value += lp.current_value;
|
|
177
|
+
s.current_value_known = true;
|
|
178
|
+
}
|
|
179
|
+
if (lp.unrealized_pnl != null) {
|
|
180
|
+
s.unrealized_pnl += lp.unrealized_pnl;
|
|
181
|
+
s.unrealized_pnl_known = true;
|
|
182
|
+
}
|
|
183
|
+
if (lp.claim_payout != null && lp.claimed_at != null) {
|
|
184
|
+
// Claim payout - net deposited is realized P&L for this market.
|
|
185
|
+
const net = lp.total_deposited - lp.total_withdrawn;
|
|
186
|
+
s.realized_pnl += lp.claim_payout - Math.max(0, net);
|
|
187
|
+
s.active_days.add(dateOfUTC(lp.claimed_at));
|
|
188
|
+
}
|
|
189
|
+
s.markets.add(lp.market_address);
|
|
190
|
+
s.domains.add(domain);
|
|
191
|
+
}
|
|
192
|
+
const out = [];
|
|
193
|
+
for (const [provider, s] of states) {
|
|
194
|
+
const first = s.first_deposit_at === Number.POSITIVE_INFINITY ? null : s.first_deposit_at;
|
|
195
|
+
const last = s.last_activity_at === 0 ? null : s.last_activity_at;
|
|
196
|
+
const net_position = s.total_deposited - s.total_withdrawn;
|
|
197
|
+
const denom = s.total_deposited > 0 ? s.total_deposited : 0;
|
|
198
|
+
const totalReturn = s.realized_pnl + (s.unrealized_pnl_known ? s.unrealized_pnl : 0);
|
|
199
|
+
const roi_pct = denom > 0 ? (totalReturn / denom) * 100 : null;
|
|
200
|
+
out.push({
|
|
201
|
+
provider,
|
|
202
|
+
first_deposit_at: first,
|
|
203
|
+
last_activity_at: last,
|
|
204
|
+
cohort_week: first != null ? isoWeekStart(first) : null,
|
|
205
|
+
deposit_count: s.deposit_count,
|
|
206
|
+
withdraw_count: s.withdraw_count,
|
|
207
|
+
total_deposited: s.total_deposited,
|
|
208
|
+
total_withdrawn: s.total_withdrawn,
|
|
209
|
+
net_position,
|
|
210
|
+
current_value: s.current_value_known ? s.current_value : null,
|
|
211
|
+
unrealized_pnl: s.unrealized_pnl_known ? s.unrealized_pnl : null,
|
|
212
|
+
realized_pnl: s.realized_pnl,
|
|
213
|
+
markets_provided: s.markets.size,
|
|
214
|
+
domains_provided: s.domains.size,
|
|
215
|
+
domains_json: Array.from(s.domains).sort(),
|
|
216
|
+
active_days: s.active_days.size,
|
|
217
|
+
roi_pct,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
return out;
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=lifetime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifetime.js","sourceRoot":"","sources":["../../src/aggregator/lifetime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ROI distribution + summary builder.
|
|
3
|
+
*
|
|
4
|
+
* Builds two outputs per (domain_slug, entity_type):
|
|
5
|
+
* - roi_distribution: bucketed histogram (e.g. -100..-50, -50..-20, ..., 100..200, 200+)
|
|
6
|
+
* - roi_summary: count of users with positive ROI, percentiles (p25/p50/p75/p90), mean
|
|
7
|
+
*
|
|
8
|
+
* "Positive ROI" = roi_pct > 0. Users with NULL roi_pct (no capital ever
|
|
9
|
+
* deployed) are excluded from both the distribution and the summary.
|
|
10
|
+
*
|
|
11
|
+
* Per-domain rows are emitted by attributing each user to every domain they
|
|
12
|
+
* touched (not just primary). The 'all' bucket is the un-segmented total.
|
|
13
|
+
*/
|
|
14
|
+
import type { LPLifetimeRow, TraderLifetimeRow } from './lifetime';
|
|
15
|
+
export interface RoiDistRow {
|
|
16
|
+
readonly domain_slug: string;
|
|
17
|
+
readonly entity_type: 'trader' | 'lp';
|
|
18
|
+
readonly bucket_index: number;
|
|
19
|
+
readonly bucket_lower_pct: number;
|
|
20
|
+
readonly bucket_upper_pct: number;
|
|
21
|
+
readonly user_count: number;
|
|
22
|
+
}
|
|
23
|
+
export interface RoiSummaryRow {
|
|
24
|
+
readonly domain_slug: string;
|
|
25
|
+
readonly entity_type: 'trader' | 'lp';
|
|
26
|
+
readonly total_users: number;
|
|
27
|
+
readonly positive_roi_users: number;
|
|
28
|
+
readonly positive_roi_pct: number;
|
|
29
|
+
readonly median_roi_pct: number | null;
|
|
30
|
+
readonly p25_roi_pct: number | null;
|
|
31
|
+
readonly p75_roi_pct: number | null;
|
|
32
|
+
readonly p90_roi_pct: number | null;
|
|
33
|
+
readonly mean_roi_pct: number | null;
|
|
34
|
+
}
|
|
35
|
+
interface BuildOutput {
|
|
36
|
+
readonly distribution: readonly RoiDistRow[];
|
|
37
|
+
readonly summary: readonly RoiSummaryRow[];
|
|
38
|
+
}
|
|
39
|
+
export declare function buildRoi(traderLifetime: readonly TraderLifetimeRow[], lpLifetime: readonly LPLifetimeRow[]): BuildOutput;
|
|
40
|
+
export declare function writeRoi(pg: import('bun').SQL, out: BuildOutput): Promise<void>;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=roi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roi.d.ts","sourceRoot":"","sources":["../../src/aggregator/roi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AA4CD,UAAU,WAAW;IACnB,QAAQ,CAAC,YAAY,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;CAC5C;AAED,wBAAgB,QAAQ,CACtB,cAAc,EAAE,SAAS,iBAAiB,EAAE,EAC5C,UAAU,EAAE,SAAS,aAAa,EAAE,GACnC,WAAW,CAqFb;AAED,wBAAsB,QAAQ,CAC5B,EAAE,EAAE,OAAO,KAAK,EAAE,GAAG,EACrB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,IAAI,CAAC,CAgCf"}
|