mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 22:59:58 -07:00
178 lines
6.7 KiB
JavaScript
178 lines
6.7 KiB
JavaScript
/**
|
|
* Capitalization section builders
|
|
*/
|
|
|
|
import { Unit } from "../../utils/units.js";
|
|
import { colors } from "../../utils/colors.js";
|
|
import { ROLLING_WINDOWS, line, baseline, mapWindows, sumsTreeBaseline, rollingPercentRatioTree, percentRatio, percentRatioBaseline } from "../series.js";
|
|
import { ratioBottomSeries, mapCohortsWithAll, flatMapCohortsWithAll } from "../shared.js";
|
|
|
|
// ============================================================================
|
|
// Shared building blocks
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Single cohort: Change + Growth Rate items (flat)
|
|
* @param {UtxoCohortObject["tree"]} tree
|
|
* @param {(name: string) => string} title
|
|
* @returns {PartialOptionsTree}
|
|
*/
|
|
function singleDeltaItems(tree, title) {
|
|
return [
|
|
{ ...sumsTreeBaseline({ windows: mapWindows(tree.realized.cap.delta.absolute, (c) => c.usd), title, metric: "Realized Cap Change", unit: Unit.usd, legend: "Change" }), name: "Change" },
|
|
{ ...rollingPercentRatioTree({ windows: tree.realized.cap.delta.rate, title, metric: "Realized Cap Growth Rate" }), name: "Growth Rate" },
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Grouped: Change + Growth Rate + MVRV items (flat)
|
|
* @param {readonly (UtxoCohortObject | CohortWithoutRelative)[]} list
|
|
* @param {CohortAll} all
|
|
* @param {(name: string) => string} title
|
|
* @returns {PartialOptionsTree}
|
|
*/
|
|
function groupedDeltaAndMvrv(list, all, title) {
|
|
return [
|
|
{
|
|
name: "MVRV",
|
|
title: title("MVRV"),
|
|
bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) =>
|
|
baseline({ series: tree.realized.mvrv, name, color, unit: Unit.ratio, base: 1 }),
|
|
),
|
|
},
|
|
{
|
|
name: "Change",
|
|
tree: ROLLING_WINDOWS.map((w) => ({
|
|
name: w.name,
|
|
title: title(`${w.title} Realized Cap Change`),
|
|
bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) =>
|
|
baseline({ series: tree.realized.cap.delta.absolute[w.key].usd, name, color, unit: Unit.usd }),
|
|
),
|
|
})),
|
|
},
|
|
{
|
|
name: "Growth Rate",
|
|
tree: ROLLING_WINDOWS.map((w) => ({
|
|
name: w.name,
|
|
title: title(`${w.title} Realized Cap Growth Rate`),
|
|
bottom: flatMapCohortsWithAll(list, all, ({ name, color, tree }) =>
|
|
percentRatioBaseline({ pattern: tree.realized.cap.delta.rate[w.key], name, color }),
|
|
),
|
|
})),
|
|
},
|
|
];
|
|
}
|
|
|
|
// ============================================================================
|
|
// Single Cohort Sections
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Full capitalization (has invested capital, own market cap ratio, full MVRV)
|
|
* @param {{ cohort: CohortAll | CohortFull | CohortLongTerm, title: (name: string) => string }} args
|
|
* @returns {PartialOptionsGroup}
|
|
*/
|
|
export function createValuationSectionFull({ cohort, title }) {
|
|
const { tree, color } = cohort;
|
|
return {
|
|
name: "Capitalization",
|
|
tree: [
|
|
{ name: "Total", title: title("Realized Cap"), bottom: [line({ series: tree.realized.cap.usd, name: "Realized Cap", color, unit: Unit.usd })] },
|
|
{
|
|
name: "Profitability",
|
|
title: title("Invested Capital"),
|
|
bottom: [
|
|
line({ series: tree.realized.cap.usd, name: "Total", color: colors.default, unit: Unit.usd }),
|
|
line({ series: tree.unrealized.investedCapital.inProfit.usd, name: "In Profit", color: colors.profit, unit: Unit.usd }),
|
|
line({ series: tree.unrealized.investedCapital.inLoss.usd, name: "In Loss", color: colors.loss, unit: Unit.usd }),
|
|
],
|
|
},
|
|
{ name: "MVRV", title: title("MVRV"), bottom: ratioBottomSeries(tree.realized.price) },
|
|
...singleDeltaItems(tree, title),
|
|
{ name: "% of Own Market Cap", title: title("Realized Cap (% of Own Market Cap)"), bottom: percentRatioBaseline({ pattern: tree.realized.cap.toOwnMcap, name: "% of Own Market Cap", color }) },
|
|
],
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Basic capitalization (no invested capital, simple MVRV)
|
|
* @param {{ cohort: CohortWithAdjusted | CohortBasic | CohortAddr | CohortWithoutRelative, title: (name: string) => string }} args
|
|
* @returns {PartialOptionsGroup}
|
|
*/
|
|
export function createValuationSection({ cohort, title }) {
|
|
const { tree } = cohort;
|
|
return {
|
|
name: "Capitalization",
|
|
tree: [
|
|
{ name: "Total", title: title("Realized Cap"), bottom: [line({ series: tree.realized.cap.usd, name: "Realized Cap", color: cohort.color, unit: Unit.usd })] },
|
|
...singleDeltaItems(tree, title),
|
|
{ name: "MVRV", title: title("MVRV"), bottom: [baseline({ series: tree.realized.mvrv, name: "MVRV", unit: Unit.ratio, base: 1 })] },
|
|
],
|
|
};
|
|
}
|
|
|
|
// ============================================================================
|
|
// Grouped Cohort Sections
|
|
// ============================================================================
|
|
|
|
/**
|
|
* @param {{ list: readonly (UtxoCohortObject | CohortWithoutRelative)[], all: CohortAll, title: (name: string) => string }} args
|
|
* @returns {PartialOptionsGroup}
|
|
*/
|
|
export function createGroupedValuationSection({ list, all, title }) {
|
|
return {
|
|
name: "Capitalization",
|
|
tree: [
|
|
{
|
|
name: "Total",
|
|
title: title("Realized Cap"),
|
|
bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) =>
|
|
line({ series: tree.realized.cap.usd, name, color, unit: Unit.usd }),
|
|
),
|
|
},
|
|
...groupedDeltaAndMvrv(list, all, title),
|
|
],
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @param {{ list: readonly (CohortAll | CohortFull | CohortLongTerm)[], all: CohortAll, title: (name: string) => string }} args
|
|
* @returns {PartialOptionsGroup}
|
|
*/
|
|
export function createGroupedValuationSectionWithOwnMarketCap({ list, all, title }) {
|
|
return {
|
|
name: "Capitalization",
|
|
tree: [
|
|
{
|
|
name: "Total",
|
|
title: title("Realized Cap"),
|
|
bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) =>
|
|
line({ series: tree.realized.cap.usd, name, color, unit: Unit.usd }),
|
|
),
|
|
},
|
|
{
|
|
name: "In Profit",
|
|
title: title("Invested Capital In Profit"),
|
|
bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) =>
|
|
line({ series: tree.unrealized.investedCapital.inProfit.usd, name, color, unit: Unit.usd }),
|
|
),
|
|
},
|
|
{
|
|
name: "In Loss",
|
|
title: title("Invested Capital In Loss"),
|
|
bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) =>
|
|
line({ series: tree.unrealized.investedCapital.inLoss.usd, name, color, unit: Unit.usd }),
|
|
),
|
|
},
|
|
...groupedDeltaAndMvrv(list, all, title),
|
|
{
|
|
name: "% of Own Market Cap",
|
|
title: title("Realized Cap (% of Own Market Cap)"),
|
|
bottom: flatMapCohortsWithAll(list, all, ({ name, color, tree }) =>
|
|
percentRatio({ pattern: tree.realized.cap.toOwnMcap, name, color }),
|
|
),
|
|
},
|
|
],
|
|
};
|
|
}
|