mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: snapshot
This commit is contained in:
@@ -2,8 +2,7 @@
|
||||
|
||||
import { colors } from "../utils/colors.js";
|
||||
import { brk } from "../client.js";
|
||||
import { Unit } from "../utils/units.js";
|
||||
import { baseline, price } from "./series.js";
|
||||
import { percentRatioBaseline, price } from "./series.js";
|
||||
import { satsBtcUsd } from "./shared.js";
|
||||
import { periodIdToName } from "./utils.js";
|
||||
|
||||
@@ -31,7 +30,7 @@ const LONG_PERIODS = /** @type {const} */ ([
|
||||
/**
|
||||
* Add CAGR to a base entry item
|
||||
* @param {BaseEntryItem} entry
|
||||
* @param {AnyMetricPattern} cagr
|
||||
* @param {PercentRatioPattern} cagr
|
||||
* @returns {LongEntryItem}
|
||||
*/
|
||||
const withCagr = (entry, cagr) => ({ ...entry, cagr });
|
||||
@@ -47,19 +46,23 @@ const YEARS_2010S = /** @type {const} */ ([2019, 2018, 2017, 2016, 2015]);
|
||||
/** @param {AllPeriodKey} key */
|
||||
const periodName = (key) => periodIdToName(key.slice(1), true);
|
||||
|
||||
/**
|
||||
* @typedef {{ percent: AnyMetricPattern, ratio: AnyMetricPattern }} PercentRatioPattern
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base entry item for compare and single-entry charts
|
||||
* @typedef {Object} BaseEntryItem
|
||||
* @property {string} name - Display name
|
||||
* @property {Color} color - Item color
|
||||
* @property {AnyPricePattern} costBasis - Cost basis metric
|
||||
* @property {AnyMetricPattern} returns - Returns metric
|
||||
* @property {PercentRatioPattern} returns - Returns metric
|
||||
* @property {AnyValuePattern} stack - Stack pattern
|
||||
*/
|
||||
|
||||
/**
|
||||
* Long-term entry item with CAGR
|
||||
* @typedef {BaseEntryItem & { cagr: AnyMetricPattern }} LongEntryItem
|
||||
* @typedef {BaseEntryItem & { cagr: PercentRatioPattern }} LongEntryItem
|
||||
*/
|
||||
|
||||
const ALL_YEARS = /** @type {const} */ ([...YEARS_2020S, ...YEARS_2010S]);
|
||||
@@ -77,7 +80,7 @@ function buildYearEntry(dca, year, i) {
|
||||
name: `${year}`,
|
||||
color: colors.at(i, ALL_YEARS.length),
|
||||
costBasis: dca.class.costBasis[key],
|
||||
returns: dca.class.return[key].ratio,
|
||||
returns: dca.class.return[key],
|
||||
stack: dca.class.stack[key],
|
||||
};
|
||||
}
|
||||
@@ -122,12 +125,11 @@ function createCompareFolder(context, items) {
|
||||
name: "Returns",
|
||||
title: `Returns: ${context}`,
|
||||
top: topPane,
|
||||
bottom: items.map(({ name, color, returns }) =>
|
||||
baseline({
|
||||
metric: returns,
|
||||
bottom: items.flatMap(({ name, color, returns }) =>
|
||||
percentRatioBaseline({
|
||||
pattern: returns,
|
||||
name,
|
||||
color: [color, color],
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
),
|
||||
},
|
||||
@@ -176,9 +178,7 @@ function createSingleEntryTree(item, returnsBottom) {
|
||||
* @param {BaseEntryItem & { titlePrefix?: string }} item
|
||||
*/
|
||||
function createShortSingleEntry(item) {
|
||||
return createSingleEntryTree(item, [
|
||||
baseline({ metric: item.returns, name: "Current", unit: Unit.percentage }),
|
||||
]);
|
||||
return createSingleEntryTree(item, percentRatioBaseline({ pattern: item.returns, name: "Current" }));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,8 +187,8 @@ function createShortSingleEntry(item) {
|
||||
*/
|
||||
function createLongSingleEntry(item) {
|
||||
return createSingleEntryTree(item, [
|
||||
baseline({ metric: item.returns, name: "Current", unit: Unit.percentage }),
|
||||
baseline({ metric: item.cagr, name: "CAGR", unit: Unit.cagr }),
|
||||
...percentRatioBaseline({ pattern: item.returns, name: "Current" }),
|
||||
...percentRatioBaseline({ pattern: item.cagr, name: "CAGR" }),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -223,16 +223,14 @@ export function createDcaVsLumpSumSection({ dca, lookback, returns }) {
|
||||
title: `Returns: ${name} DCA vs Lump Sum`,
|
||||
top: topPane(key),
|
||||
bottom: [
|
||||
baseline({
|
||||
metric: dca.period.return[key].ratio,
|
||||
...percentRatioBaseline({
|
||||
pattern: dca.period.return[key],
|
||||
name: "DCA",
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
baseline({
|
||||
metric: dca.period.lumpSumReturn[key].ratio,
|
||||
...percentRatioBaseline({
|
||||
pattern: dca.period.lumpSumReturn[key],
|
||||
name: "Lump Sum",
|
||||
color: colors.bi.p2,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
],
|
||||
});
|
||||
@@ -243,27 +241,23 @@ export function createDcaVsLumpSumSection({ dca, lookback, returns }) {
|
||||
title: `Returns: ${name} DCA vs Lump Sum`,
|
||||
top: topPane(key),
|
||||
bottom: [
|
||||
baseline({
|
||||
metric: dca.period.return[key].ratio,
|
||||
...percentRatioBaseline({
|
||||
pattern: dca.period.return[key],
|
||||
name: "DCA",
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
baseline({
|
||||
metric: dca.period.lumpSumReturn[key].ratio,
|
||||
...percentRatioBaseline({
|
||||
pattern: dca.period.lumpSumReturn[key],
|
||||
name: "Lump Sum",
|
||||
color: colors.bi.p2,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
baseline({
|
||||
metric: dca.period.cagr[key].ratio,
|
||||
...percentRatioBaseline({
|
||||
pattern: dca.period.cagr[key],
|
||||
name: "DCA CAGR",
|
||||
unit: Unit.cagr,
|
||||
}),
|
||||
baseline({
|
||||
metric: returns.cagr[key].ratio,
|
||||
...percentRatioBaseline({
|
||||
pattern: returns.cagr[key],
|
||||
name: "Lump Sum CAGR",
|
||||
color: colors.bi.p2,
|
||||
unit: Unit.cagr,
|
||||
}),
|
||||
],
|
||||
});
|
||||
@@ -350,8 +344,8 @@ function createPeriodSection({ dca, lookback, returns }) {
|
||||
color: colors.at(i, allPeriods.length),
|
||||
costBasis: isLumpSum ? lookback[key] : dca.period.costBasis[key],
|
||||
returns: isLumpSum
|
||||
? dca.period.lumpSumReturn[key].ratio
|
||||
: dca.period.return[key].ratio,
|
||||
? dca.period.lumpSumReturn[key]
|
||||
: dca.period.return[key],
|
||||
stack: isLumpSum
|
||||
? dca.period.lumpSumStack[key]
|
||||
: dca.period.stack[key],
|
||||
@@ -361,7 +355,7 @@ function createPeriodSection({ dca, lookback, returns }) {
|
||||
const buildLongEntry = (key, i) =>
|
||||
withCagr(
|
||||
buildBaseEntry(key, i),
|
||||
isLumpSum ? returns.cagr[key].ratio : dca.period.cagr[key].ratio,
|
||||
isLumpSum ? returns.cagr[key] : dca.period.cagr[key],
|
||||
);
|
||||
|
||||
/** @param {BaseEntryItem} entry */
|
||||
|
||||
@@ -122,21 +122,18 @@ function returnsSubSection(name, periods) {
|
||||
{
|
||||
name: "Compare",
|
||||
title: `${name} Returns`,
|
||||
bottom: periods.map((p) =>
|
||||
baseline({
|
||||
metric: p.returns,
|
||||
bottom: periods.flatMap((p) =>
|
||||
percentRatioBaseline({
|
||||
pattern: p.returns,
|
||||
name: p.id,
|
||||
color: p.color,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
),
|
||||
},
|
||||
...periods.map((p) => ({
|
||||
name: periodIdToName(p.id, true),
|
||||
title: `${periodIdToName(p.id, true)} Returns`,
|
||||
bottom: [
|
||||
baseline({ metric: p.returns, name: "Total", unit: Unit.percentage }),
|
||||
],
|
||||
bottom: percentRatioBaseline({ pattern: p.returns, name: "Total" }),
|
||||
})),
|
||||
],
|
||||
};
|
||||
@@ -153,12 +150,11 @@ function returnsSubSectionWithCagr(name, periods) {
|
||||
{
|
||||
name: "Compare",
|
||||
title: `${name} Returns`,
|
||||
bottom: periods.map((p) =>
|
||||
baseline({
|
||||
metric: p.returns,
|
||||
bottom: periods.flatMap((p) =>
|
||||
percentRatioBaseline({
|
||||
pattern: p.returns,
|
||||
name: p.id,
|
||||
color: p.color,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
),
|
||||
},
|
||||
@@ -166,8 +162,8 @@ function returnsSubSectionWithCagr(name, periods) {
|
||||
name: periodIdToName(p.id, true),
|
||||
title: `${periodIdToName(p.id, true)} Returns`,
|
||||
bottom: [
|
||||
baseline({ metric: p.returns, name: "Total", unit: Unit.percentage }),
|
||||
baseline({ metric: p.cagr, name: "annual", unit: Unit.cagr }),
|
||||
...percentRatioBaseline({ pattern: p.returns, name: "Total" }),
|
||||
...percentRatioBaseline({ pattern: p.cagr, name: "annual" }),
|
||||
],
|
||||
})),
|
||||
],
|
||||
@@ -216,70 +212,70 @@ export function createMarketSection() {
|
||||
} = market;
|
||||
|
||||
const shortPeriodsBase = [
|
||||
{ id: "24h", returns: returns.periods._24h.ratio, lookback: lookback._24h },
|
||||
{ id: "1w", returns: returns.periods._1w.ratio, lookback: lookback._1w },
|
||||
{ id: "1m", returns: returns.periods._1m.ratio, lookback: lookback._1m },
|
||||
{ id: "24h", returns: returns.periods._24h, lookback: lookback._24h },
|
||||
{ id: "1w", returns: returns.periods._1w, lookback: lookback._1w },
|
||||
{ id: "1m", returns: returns.periods._1m, lookback: lookback._1m },
|
||||
{
|
||||
id: "3m",
|
||||
returns: returns.periods._3m.ratio,
|
||||
returns: returns.periods._3m,
|
||||
lookback: lookback._3m,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
id: "6m",
|
||||
returns: returns.periods._6m.ratio,
|
||||
returns: returns.periods._6m,
|
||||
lookback: lookback._6m,
|
||||
defaultActive: false,
|
||||
},
|
||||
{ id: "1y", returns: returns.periods._1y.ratio, lookback: lookback._1y },
|
||||
{ id: "1y", returns: returns.periods._1y, lookback: lookback._1y },
|
||||
];
|
||||
|
||||
const longPeriodsBase = [
|
||||
{
|
||||
id: "2y",
|
||||
returns: returns.periods._2y.ratio,
|
||||
cagr: returns.cagr._2y.ratio,
|
||||
returns: returns.periods._2y,
|
||||
cagr: returns.cagr._2y,
|
||||
lookback: lookback._2y,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
id: "3y",
|
||||
returns: returns.periods._3y.ratio,
|
||||
cagr: returns.cagr._3y.ratio,
|
||||
returns: returns.periods._3y,
|
||||
cagr: returns.cagr._3y,
|
||||
lookback: lookback._3y,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
id: "4y",
|
||||
returns: returns.periods._4y.ratio,
|
||||
cagr: returns.cagr._4y.ratio,
|
||||
returns: returns.periods._4y,
|
||||
cagr: returns.cagr._4y,
|
||||
lookback: lookback._4y,
|
||||
},
|
||||
{
|
||||
id: "5y",
|
||||
returns: returns.periods._5y.ratio,
|
||||
cagr: returns.cagr._5y.ratio,
|
||||
returns: returns.periods._5y,
|
||||
cagr: returns.cagr._5y,
|
||||
lookback: lookback._5y,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
id: "6y",
|
||||
returns: returns.periods._6y.ratio,
|
||||
cagr: returns.cagr._6y.ratio,
|
||||
returns: returns.periods._6y,
|
||||
cagr: returns.cagr._6y,
|
||||
lookback: lookback._6y,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
id: "8y",
|
||||
returns: returns.periods._8y.ratio,
|
||||
cagr: returns.cagr._8y.ratio,
|
||||
returns: returns.periods._8y,
|
||||
cagr: returns.cagr._8y,
|
||||
lookback: lookback._8y,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
id: "10y",
|
||||
returns: returns.periods._10y.ratio,
|
||||
cagr: returns.cagr._10y.ratio,
|
||||
returns: returns.periods._10y,
|
||||
cagr: returns.cagr._10y,
|
||||
lookback: lookback._10y,
|
||||
defaultActive: false,
|
||||
},
|
||||
@@ -426,11 +422,10 @@ export function createMarketSection() {
|
||||
name: "Growth Rate",
|
||||
title: "Capitalization Growth Rate",
|
||||
bottom: [
|
||||
line({
|
||||
metric: supply.marketCap.delta.rate._24h.percent,
|
||||
...percentRatio({
|
||||
pattern: supply.marketCap.delta.rate._24h,
|
||||
name: "Market Cap (24h)",
|
||||
color: colors.bitcoin,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
baseline({
|
||||
metric: supply.marketMinusRealizedCapGrowthRate._24h,
|
||||
@@ -493,12 +488,11 @@ export function createMarketSection() {
|
||||
{
|
||||
name: "Compare",
|
||||
title: "Returns Comparison",
|
||||
bottom: [...shortPeriods, ...longPeriods].map((p) =>
|
||||
baseline({
|
||||
metric: p.returns,
|
||||
bottom: [...shortPeriods, ...longPeriods].flatMap((p) =>
|
||||
percentRatioBaseline({
|
||||
pattern: p.returns,
|
||||
name: p.id,
|
||||
color: p.color,
|
||||
unit: Unit.percentage,
|
||||
defaultActive: p.defaultActive,
|
||||
}),
|
||||
),
|
||||
|
||||
@@ -320,7 +320,7 @@ export function createMiningSection() {
|
||||
title: "Mining Difficulty",
|
||||
bottom: [
|
||||
line({
|
||||
metric: blocks.difficulty.raw,
|
||||
metric: blocks.difficulty.value,
|
||||
name: "Difficulty",
|
||||
unit: Unit.difficulty,
|
||||
}),
|
||||
|
||||
@@ -58,9 +58,9 @@ export function createNetworkSection() {
|
||||
const nonAddressableTypes = /** @type {const} */ ([
|
||||
{ key: "p2ms", name: "P2MS", color: st.p2ms, defaultActive: false },
|
||||
{
|
||||
key: "opreturn",
|
||||
key: "opReturn",
|
||||
name: "OP_RETURN",
|
||||
color: st.opreturn,
|
||||
color: st.opReturn,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
@@ -568,7 +568,7 @@ export function createNetworkSection() {
|
||||
name: "Base",
|
||||
title: "OP_RETURN Burned",
|
||||
bottom: satsBtcUsd({
|
||||
pattern: supply.burned.opreturn.base,
|
||||
pattern: supply.burned.opReturn.base,
|
||||
name: "sum",
|
||||
}),
|
||||
},
|
||||
@@ -580,7 +580,7 @@ export function createNetworkSection() {
|
||||
title: "OP_RETURN Burned Rolling",
|
||||
bottom: ROLLING_WINDOWS.flatMap((w) =>
|
||||
satsBtcUsd({
|
||||
pattern: supply.burned.opreturn.sum[w.key],
|
||||
pattern: supply.burned.opReturn.sum[w.key],
|
||||
name: w.name,
|
||||
color: w.color,
|
||||
}),
|
||||
@@ -590,7 +590,7 @@ export function createNetworkSection() {
|
||||
name: w.name,
|
||||
title: `OP_RETURN Burned ${w.name}`,
|
||||
bottom: satsBtcUsd({
|
||||
pattern: supply.burned.opreturn.sum[w.key],
|
||||
pattern: supply.burned.opReturn.sum[w.key],
|
||||
name: w.name,
|
||||
color: w.color,
|
||||
}),
|
||||
@@ -601,7 +601,7 @@ export function createNetworkSection() {
|
||||
name: "Cumulative",
|
||||
title: "OP_RETURN Burned (Total)",
|
||||
bottom: satsBtcUsd({
|
||||
pattern: supply.burned.opreturn.cumulative,
|
||||
pattern: supply.burned.opReturn.cumulative,
|
||||
name: "all-time",
|
||||
}),
|
||||
},
|
||||
@@ -1035,7 +1035,7 @@ export function createNetworkSection() {
|
||||
title: "Mining Difficulty",
|
||||
bottom: [
|
||||
line({
|
||||
metric: blocks.difficulty.base,
|
||||
metric: blocks.difficulty.value,
|
||||
name: "Difficulty",
|
||||
unit: Unit.count,
|
||||
}),
|
||||
|
||||
@@ -640,7 +640,7 @@ export function percentRatioDots({ pattern, name, color, defaultActive }) {
|
||||
* @param {Object} args
|
||||
* @param {{ percent: AnyMetricPattern, ratio: AnyMetricPattern }} args.pattern
|
||||
* @param {string} args.name
|
||||
* @param {Color} [args.color]
|
||||
* @param {Color | [Color, Color]} [args.color]
|
||||
* @param {boolean} [args.defaultActive]
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
|
||||
@@ -254,7 +254,7 @@ export const colors = {
|
||||
p2wsh: palette.yellow,
|
||||
p2tr: palette.cyan,
|
||||
p2a: palette.indigo,
|
||||
opreturn: palette.purple,
|
||||
opReturn: palette.purple,
|
||||
unknown: palette.violet,
|
||||
empty: palette.fuchsia,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user