Files
brk/website/scripts/options/cointime.js
2026-01-23 22:03:01 +01:00

516 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Unit } from "../utils/units.js";
import { priceLine, priceLines } from "./constants.js";
import { line, baseline } from "./series.js";
import {
satsBtcUsd,
percentileUsdMap,
percentileMap,
sdPatterns,
sdBands,
} from "./shared.js";
/**
* Create price with ratio options for cointime prices
* @param {PartialContext} ctx
* @param {Object} args
* @param {string} args.title
* @param {string} args.legend
* @param {AnyMetricPattern} args.price
* @param {ActivePriceRatioPattern} args.ratio
* @param {Color} [args.color]
* @returns {PartialOptionsTree}
*/
function createCointimePriceWithRatioOptions(
ctx,
{ title, legend, price, ratio, color },
) {
const { colors } = ctx;
const pctUsdMap = percentileUsdMap(colors, ratio);
const pctMap = percentileMap(colors, ratio);
const sdPats = sdPatterns(ratio);
return [
{
name: "price",
title,
top: [line({ metric: price, name: legend, color, unit: Unit.usd })],
},
{
name: "Ratio",
title: `${title} Ratio`,
top: [
line({ metric: price, name: legend, color, unit: Unit.usd }),
...pctUsdMap.map(({ name: pctName, prop, color: pctColor }) =>
line({
metric: prop,
name: pctName,
color: pctColor,
defaultActive: false,
unit: Unit.usd,
options: { lineStyle: 1 },
}),
),
],
bottom: [
baseline({
metric: ratio.ratio,
name: "Ratio",
color,
unit: Unit.ratio,
}),
line({
metric: ratio.ratio1wSma,
name: "1w SMA",
color: colors.lime,
unit: Unit.ratio,
defaultActive: false,
}),
line({
metric: ratio.ratio1mSma,
name: "1m SMA",
color: colors.teal,
unit: Unit.ratio,
defaultActive: false,
}),
line({
metric: ratio.ratio1ySd.sma,
name: "1y SMA",
color: colors.sky,
unit: Unit.ratio,
defaultActive: false,
}),
line({
metric: ratio.ratio2ySd.sma,
name: "2y SMA",
color: colors.indigo,
unit: Unit.ratio,
defaultActive: false,
}),
line({
metric: ratio.ratio4ySd.sma,
name: "4y SMA",
color: colors.purple,
unit: Unit.ratio,
defaultActive: false,
}),
line({
metric: ratio.ratioSd.sma,
name: "All SMA",
color: colors.rose,
unit: Unit.ratio,
defaultActive: false,
}),
...pctMap.map(({ name: pctName, prop, color: pctColor }) =>
line({
metric: prop,
name: pctName,
color: pctColor,
defaultActive: false,
unit: Unit.ratio,
options: { lineStyle: 1 },
}),
),
priceLine({ ctx, unit: Unit.ratio, number: 1 }),
],
},
{
name: "ZScores",
tree: [
// Compare all Z-Scores
{
name: "Compare",
title: `${title} Z-Scores`,
top: [
line({ metric: price, name: legend, color, unit: Unit.usd }),
line({
metric: ratio.ratio1ySd._0sdUsd,
name: "1y 0σ",
color: colors.orange,
defaultActive: false,
unit: Unit.usd,
}),
line({
metric: ratio.ratio2ySd._0sdUsd,
name: "2y 0σ",
color: colors.yellow,
defaultActive: false,
unit: Unit.usd,
}),
line({
metric: ratio.ratio4ySd._0sdUsd,
name: "4y 0σ",
color: colors.lime,
defaultActive: false,
unit: Unit.usd,
}),
line({
metric: ratio.ratioSd._0sdUsd,
name: "all 0σ",
color: colors.blue,
defaultActive: false,
unit: Unit.usd,
}),
],
bottom: [
line({
metric: ratio.ratioSd.zscore,
name: "all",
color: colors.blue,
unit: Unit.sd,
}),
line({
metric: ratio.ratio4ySd.zscore,
name: "4y",
color: colors.lime,
unit: Unit.sd,
}),
line({
metric: ratio.ratio2ySd.zscore,
name: "2y",
color: colors.yellow,
unit: Unit.sd,
}),
line({
metric: ratio.ratio1ySd.zscore,
name: "1y",
color: colors.orange,
unit: Unit.sd,
}),
...priceLines({
ctx,
unit: Unit.sd,
numbers: [0, 1, -1, 2, -2, 3, -3, 4, -4],
defaultActive: false,
}),
],
},
// Individual Z-Score charts
...sdPats.map(({ nameAddon, titleAddon, sd }) => ({
name: nameAddon,
title: `${title} ${titleAddon} Z-Score`,
top: [
line({ metric: price, name: legend, color, unit: Unit.usd }),
...sdBands(colors, sd).map(
({ name: bandName, prop, color: bandColor }) =>
line({
metric: prop,
name: bandName,
color: bandColor,
unit: Unit.usd,
defaultActive: false,
}),
),
],
bottom: [
line({ metric: sd.zscore, name: "Z-Score", color, unit: Unit.sd }),
...priceLines({
ctx,
unit: Unit.sd,
numbers: [0, 1, -1, 2, -2, 3, -3],
defaultActive: false,
}),
],
})),
],
},
];
}
/**
* Create Cointime section
* @param {PartialContext} ctx
* @returns {PartialOptionsGroup}
*/
export function createCointimeSection(ctx) {
const { colors, brk } = ctx;
const { cointime, distribution, supply } = brk.metrics;
const { pricing, cap, activity, supply: cointimeSupply, adjusted } = cointime;
const { all } = distribution.utxoCohorts;
// Cointime prices data
const cointimePrices = [
{
price: pricing.trueMarketMean,
ratio: pricing.trueMarketMeanRatio,
name: "True market mean",
title: "True Market Mean",
color: colors.blue,
},
{
price: pricing.vaultedPrice,
ratio: pricing.vaultedPriceRatio,
name: "Vaulted",
title: "Vaulted Price",
color: colors.lime,
},
{
price: pricing.activePrice,
ratio: pricing.activePriceRatio,
name: "Active",
title: "Active Price",
color: colors.rose,
},
{
price: pricing.cointimePrice,
ratio: pricing.cointimePriceRatio,
name: "cointime",
title: "Cointime Price",
color: colors.yellow,
},
];
// Cointime capitalizations data
const cointimeCapitalizations = [
{
metric: cap.vaultedCap,
name: "vaulted",
title: "Vaulted Cap",
color: colors.lime,
},
{
metric: cap.activeCap,
name: "active",
title: "Active Cap",
color: colors.rose,
},
{
metric: cap.cointimeCap,
name: "cointime",
title: "Cointime Cap",
color: colors.yellow,
},
{
metric: cap.investorCap,
name: "investor",
title: "Investor Cap",
color: colors.fuchsia,
},
{
metric: cap.thermoCap,
name: "thermo",
title: "Thermo Cap",
color: colors.emerald,
},
];
return {
name: "Cointime",
tree: [
// Prices
{
name: "Prices",
tree: [
{
name: "Compare",
title: "Cointime Prices",
top: cointimePrices.map(({ price, name, color }) =>
line({ metric: price, name, color, unit: Unit.usd }),
),
},
...cointimePrices.map(({ price, ratio, name, color, title }) => ({
name,
tree: createCointimePriceWithRatioOptions(ctx, {
price,
ratio,
legend: name,
color,
title,
}),
})),
],
},
// Capitalization
{
name: "Capitalization",
tree: [
{
name: "Compare",
title: "Cointime Caps",
bottom: [
line({
metric: supply.marketCap,
name: "Market",
color: colors.default,
unit: Unit.usd,
}),
line({
metric: all.realized.realizedCap,
name: "Realized",
color: colors.orange,
unit: Unit.usd,
}),
...cointimeCapitalizations.map(({ metric, name, color }) =>
line({ metric, name, color, unit: Unit.usd }),
),
],
},
...cointimeCapitalizations.map(({ metric, name, color, title }) => ({
name,
title,
bottom: [
line({ metric, name, color, unit: Unit.usd }),
line({
metric: supply.marketCap,
name: "Market",
color: colors.default,
unit: Unit.usd,
}),
line({
metric: all.realized.realizedCap,
name: "Realized",
color: colors.orange,
unit: Unit.usd,
}),
],
})),
],
},
// Supply
{
name: "Supply",
title: "Cointime Supply",
bottom: [
...satsBtcUsd(all.supply.total, "All", colors.orange),
...satsBtcUsd(cointimeSupply.vaultedSupply, "Vaulted", colors.lime),
...satsBtcUsd(cointimeSupply.activeSupply, "Active", colors.rose),
],
},
// Liveliness & Vaultedness
{
name: "Liveliness & Vaultedness",
title: "Liveliness & Vaultedness",
bottom: [
line({
metric: activity.liveliness,
name: "Liveliness",
color: colors.rose,
unit: Unit.ratio,
}),
line({
metric: activity.vaultedness,
name: "Vaultedness",
color: colors.lime,
unit: Unit.ratio,
}),
line({
metric: activity.activityToVaultednessRatio,
name: "Liveliness / Vaultedness",
color: colors.purple,
unit: Unit.ratio,
}),
],
},
// Coinblocks
{
name: "Coinblocks",
title: "Coinblocks",
bottom: [
// Destroyed comes from the all cohort's activity
line({
metric: all.activity.coinblocksDestroyed.sum,
name: "Destroyed",
color: colors.red,
unit: Unit.coinblocks,
}),
line({
metric: all.activity.coinblocksDestroyed.cumulative,
name: "Cumulative Destroyed",
color: colors.red,
defaultActive: false,
unit: Unit.coinblocks,
}),
// Created and stored from cointime
line({
metric: activity.coinblocksCreated.sum,
name: "Created",
color: colors.orange,
unit: Unit.coinblocks,
}),
line({
metric: activity.coinblocksCreated.cumulative,
name: "Cumulative Created",
color: colors.orange,
defaultActive: false,
unit: Unit.coinblocks,
}),
line({
metric: activity.coinblocksStored.sum,
name: "Stored",
color: colors.green,
unit: Unit.coinblocks,
}),
line({
metric: activity.coinblocksStored.cumulative,
name: "Cumulative Stored",
color: colors.green,
defaultActive: false,
unit: Unit.coinblocks,
}),
],
},
// Adjusted metrics
{
name: "Adjusted",
tree: [
// Inflation
{
name: "Inflation",
title: "Adjusted Inflation",
bottom: [
line({
metric: supply.inflation,
name: "Base",
color: colors.orange,
unit: Unit.percentage,
}),
line({
metric: adjusted.cointimeAdjInflationRate,
name: "Adjusted",
color: colors.purple,
unit: Unit.percentage,
}),
],
},
// Velocity
{
name: "Velocity",
title: "Adjusted Velocity",
bottom: [
line({
metric: supply.velocity.btc,
name: "BTC",
color: colors.orange,
unit: Unit.ratio,
}),
line({
metric: adjusted.cointimeAdjTxBtcVelocity,
name: "Adj. BTC",
color: colors.red,
unit: Unit.ratio,
}),
line({
metric: supply.velocity.usd,
name: "USD",
color: colors.emerald,
unit: Unit.ratio,
}),
line({
metric: adjusted.cointimeAdjTxUsdVelocity,
name: "Adj. USD",
color: colors.lime,
unit: Unit.ratio,
}),
],
},
],
},
],
};
}