import { brk } from "../../utils/client.js"; import { colors } from "../../utils/colors.js"; import { Unit } from "../../utils/units.js"; import { line, price } from "../series.js"; const FLOOR_PERCENTILES = /** @type {const} */ ([ { key: "pct95", name: "P95" }, { key: "pct98", name: "P98" }, { key: "pct99", name: "P99" }, { key: "pct995", name: "P99.5" }, { key: "pct999", name: "P99.9" }, ]); const LEVEL_PERCENTILES = /** @type {const} */ ([ { key: "pct10", name: "P10" }, { key: "pct20", name: "P20" }, { key: "pct30", name: "P30" }, { key: "pct40", name: "P40" }, { key: "pct50", name: "P50" }, { key: "pct60", name: "P60" }, { key: "pct70", name: "P70" }, { key: "pct80", name: "P80" }, { key: "pct90", name: "P90" }, ]); /** * @typedef {Object} BedrockMode * @property {string} name * @property {AnySeriesPattern} inLoss * @property {{ * floor: Record, * level: Record, * lossThreshold: Record, * }} tree */ /** * @param {BedrockMode} mode * @param {AnyPricePattern} ath * @returns {PartialChartOption} */ function modeChart(mode, ath) { return { name: mode.name, title: `Bitcoin Bedrock Model: ${mode.name}`, top: [ ...FLOOR_PERCENTILES.map((percentile, index) => price({ series: mode.tree.floor[percentile.key], name: percentile.name, color: colors.bedrock.percentiles[index], }), ), ...LEVEL_PERCENTILES.map((percentile, index) => price({ series: mode.tree.level[percentile.key], name: `L${percentile.name.slice(1)}`, color: colors.bedrock.levels[index], style: 1, }), ), price({ series: ath, name: "L100", color: colors.bedrock.levels[9], style: 1, }), ], bottom: [ line({ series: mode.inLoss, name: "Loss", color: colors.default, defaultActive: false, unit: Unit.ratio, }), ...FLOOR_PERCENTILES.map((percentile, index) => line({ series: mode.tree.lossThreshold[percentile.key], name: percentile.name, color: colors.bedrock.percentiles[index], defaultActive: false, unit: Unit.ratio, }), ), ], }; } /** * Create Bedrock model section. * @returns {PartialOptionsGroup} */ export function createBedrockSection() { const { market, cohorts } = brk.series; const { cointime, coinflow } = brk.series.frameworks; const { bedrock } = brk.series.models; const horizonModes = /** @type {const} */ ([ { key: "coinflow8y", horizon: "_8y", name: "Coinflow 8Y" }, { key: "coinflow4y", horizon: "_4y", name: "Coinflow 4Y" }, { key: "coinflow2y", horizon: "_2y", name: "Coinflow 2Y" }, { key: "coinflow1y", horizon: "_1y", name: "Coinflow 1Y" }, { key: "coinflow6m", horizon: "_6m", name: "Coinflow 6M" }, { key: "coinflow3m", horizon: "_3m", name: "Coinflow 3M" }, { key: "coinflow1m", horizon: "_1m", name: "Coinflow 1M" }, ]).map((mode) => ({ name: mode.name, tree: bedrock[mode.key], inLoss: coinflow.horizon[mode.horizon].supply.inLoss.share, })); const modes = /** @type {readonly BedrockMode[]} */ ([ { name: "Raw", tree: bedrock.raw, inLoss: cohorts.utxo.all.supply.inLoss.share.ratio, }, { name: "Cointime", tree: bedrock.cointime, inLoss: cointime.supply.active.inLoss.share, }, { name: "Coinflow", tree: bedrock.coinflow, inLoss: coinflow.supply.mobile.inLoss.share, }, ...horizonModes, ]); return { name: "Bedrock", tree: modes.map((mode) => modeChart(mode, market.ath.high)), }; }