mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-25 23:29:58 -07:00
website: snapshot
This commit is contained in:
@@ -16,14 +16,89 @@
|
||||
import { Unit } from "../../utils/units.js";
|
||||
import { line, baseline } from "../series.js";
|
||||
import { satsBtcUsd, satsBtcUsdBaseline } from "../shared.js";
|
||||
import { colors } from "../../utils/colors.js";
|
||||
import { priceLines } from "../constants.js";
|
||||
|
||||
/**
|
||||
* @param {UtxoCohortObject | CohortWithoutRelative} cohort
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
function createSingleSupplySeries(cohort) {
|
||||
const { color, tree } = cohort;
|
||||
return [...satsBtcUsd({ pattern: tree.supply.total, name: "Supply", color })];
|
||||
const { tree } = cohort;
|
||||
return [
|
||||
...satsBtcUsd({
|
||||
pattern: tree.supply.total,
|
||||
name: "Total",
|
||||
color: colors.default,
|
||||
}),
|
||||
...satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInProfit,
|
||||
name: "In Profit",
|
||||
color: colors.profit,
|
||||
}),
|
||||
...satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInLoss,
|
||||
name: "In Loss",
|
||||
color: colors.loss,
|
||||
}),
|
||||
// Halved supply (sparse line)
|
||||
...satsBtcUsd({
|
||||
pattern: tree.supply.halved,
|
||||
name: "Halved",
|
||||
color: colors.gray,
|
||||
style: 4,
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Supply series for CohortAll (has % of Own Supply but not % of Circulating)
|
||||
* @param {CohortAll} cohort
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
function createSingleSupplySeriesAll(cohort) {
|
||||
const { tree } = cohort;
|
||||
return [
|
||||
...satsBtcUsd({
|
||||
pattern: tree.supply.total,
|
||||
name: "Total",
|
||||
color: colors.default,
|
||||
}),
|
||||
...satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInProfit,
|
||||
name: "In Profit",
|
||||
color: colors.profit,
|
||||
}),
|
||||
...satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInLoss,
|
||||
name: "In Loss",
|
||||
color: colors.loss,
|
||||
}),
|
||||
// Halved supply (sparse line)
|
||||
...satsBtcUsd({
|
||||
pattern: tree.supply.halved,
|
||||
name: "Halved",
|
||||
color: colors.gray,
|
||||
style: 4,
|
||||
}),
|
||||
// % of Own Supply
|
||||
line({
|
||||
metric: tree.relative.supplyInProfitRelToOwnSupply,
|
||||
name: "In Profit",
|
||||
color: colors.profit,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
line({
|
||||
metric: tree.relative.supplyInLossRelToOwnSupply,
|
||||
name: "In Loss",
|
||||
color: colors.loss,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
...priceLines({
|
||||
numbers: [100, 50, 0],
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,7 +106,10 @@ function createSingleSupplySeries(cohort) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
function createSingle30dChangeSeries(cohort) {
|
||||
return satsBtcUsdBaseline({ pattern: cohort.tree.supply._30dChange, name: "30d Change" });
|
||||
return satsBtcUsdBaseline({
|
||||
pattern: cohort.tree.supply._30dChange,
|
||||
name: "30d Change",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,18 +157,121 @@ function createSingleAddrCount30dChangeSeries(cohort) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create supply series with % of Circulating (for cohorts with relative data)
|
||||
* @param {CohortFull | CohortWithAdjusted | CohortBasicWithMarketCap | CohortMinAge} cohort
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
function createSingleRelativeSeries(cohort) {
|
||||
const { color, tree } = cohort;
|
||||
function createSingleSupplySeriesWithRelative(cohort) {
|
||||
const { tree } = cohort;
|
||||
return [
|
||||
...satsBtcUsd({
|
||||
pattern: tree.supply.total,
|
||||
name: "Total",
|
||||
color: colors.default,
|
||||
}),
|
||||
...satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInProfit,
|
||||
name: "In Profit",
|
||||
color: colors.profit,
|
||||
}),
|
||||
...satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInLoss,
|
||||
name: "In Loss",
|
||||
color: colors.loss,
|
||||
}),
|
||||
// Halved supply (sparse line)
|
||||
...satsBtcUsd({
|
||||
pattern: tree.supply.halved,
|
||||
name: "Halved",
|
||||
color: colors.gray,
|
||||
style: 4,
|
||||
}),
|
||||
// % of Circulating Supply
|
||||
line({
|
||||
metric: tree.relative.supplyRelToCirculatingSupply,
|
||||
name: "% of Circulating",
|
||||
color,
|
||||
name: "Total",
|
||||
color: colors.default,
|
||||
unit: Unit.pctSupply,
|
||||
}),
|
||||
line({
|
||||
metric: tree.relative.supplyInProfitRelToCirculatingSupply,
|
||||
name: "In Profit",
|
||||
color: colors.profit,
|
||||
unit: Unit.pctSupply,
|
||||
}),
|
||||
line({
|
||||
metric: tree.relative.supplyInLossRelToCirculatingSupply,
|
||||
name: "In Loss",
|
||||
color: colors.loss,
|
||||
unit: Unit.pctSupply,
|
||||
}),
|
||||
// % of Own Supply
|
||||
line({
|
||||
metric: tree.relative.supplyInProfitRelToOwnSupply,
|
||||
name: "In Profit",
|
||||
color: colors.profit,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
line({
|
||||
metric: tree.relative.supplyInLossRelToOwnSupply,
|
||||
name: "In Loss",
|
||||
color: colors.loss,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
...priceLines({
|
||||
numbers: [100, 50, 0],
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Supply series with % of Own Supply only (for cohorts without % of Circulating)
|
||||
* @param {CohortAgeRange | CohortBasicWithoutMarketCap} cohort
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
function createSingleSupplySeriesWithOwnSupply(cohort) {
|
||||
const { tree } = cohort;
|
||||
return [
|
||||
...satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInProfit,
|
||||
name: "In Profit",
|
||||
color: colors.profit,
|
||||
}),
|
||||
...satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInLoss,
|
||||
name: "In Loss",
|
||||
color: colors.loss,
|
||||
}),
|
||||
...satsBtcUsd({
|
||||
pattern: tree.supply.total,
|
||||
name: "Total",
|
||||
color: colors.default,
|
||||
}),
|
||||
// Halved supply (sparse line)
|
||||
...satsBtcUsd({
|
||||
pattern: tree.supply.halved,
|
||||
name: "Halved",
|
||||
color: colors.gray,
|
||||
style: 4,
|
||||
}),
|
||||
// % of Own Supply
|
||||
line({
|
||||
metric: tree.relative.supplyInProfitRelToOwnSupply,
|
||||
name: "In Profit",
|
||||
color: colors.profit,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
line({
|
||||
metric: tree.relative.supplyInLossRelToOwnSupply,
|
||||
name: "In Loss",
|
||||
color: colors.loss,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
...priceLines({
|
||||
numbers: [100, 50, 0],
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -132,17 +313,18 @@ export function createHoldingsSection({ cohort, title }) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ cohort: CohortFull | CohortWithAdjusted | CohortBasicWithMarketCap | CohortMinAge, title: (metric: string) => string }} args
|
||||
* Holdings section with % of Own Supply only (for cohorts without % of Circulating)
|
||||
* @param {{ cohort: CohortAgeRange | CohortBasicWithoutMarketCap, title: (metric: string) => string }} args
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
export function createHoldingsSectionWithRelative({ cohort, title }) {
|
||||
export function createHoldingsSectionWithOwnSupply({ cohort, title }) {
|
||||
return {
|
||||
name: "Holdings",
|
||||
tree: [
|
||||
{
|
||||
name: "Supply",
|
||||
title: title("Supply"),
|
||||
bottom: createSingleSupplySeries(cohort),
|
||||
bottom: createSingleSupplySeriesWithOwnSupply(cohort),
|
||||
},
|
||||
{
|
||||
name: "UTXO Count",
|
||||
@@ -164,10 +346,42 @@ export function createHoldingsSectionWithRelative({ cohort, title }) {
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ cohort: CohortFull | CohortWithAdjusted | CohortBasicWithMarketCap | CohortMinAge, title: (metric: string) => string }} args
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
export function createHoldingsSectionWithRelative({ cohort, title }) {
|
||||
return {
|
||||
name: "Holdings",
|
||||
tree: [
|
||||
{
|
||||
name: "Relative",
|
||||
title: title("Relative to Circulating Supply"),
|
||||
bottom: createSingleRelativeSeries(cohort),
|
||||
name: "Supply",
|
||||
title: title("Supply"),
|
||||
bottom: createSingleSupplySeriesWithRelative(cohort),
|
||||
},
|
||||
{
|
||||
name: "UTXO Count",
|
||||
title: title("UTXO Count"),
|
||||
bottom: createSingleUtxoCountSeries(cohort),
|
||||
},
|
||||
{
|
||||
name: "30d Changes",
|
||||
tree: [
|
||||
{
|
||||
name: "Supply",
|
||||
title: title("Supply 30d Change"),
|
||||
bottom: createSingle30dChangeSeries(cohort),
|
||||
},
|
||||
{
|
||||
name: "UTXO Count",
|
||||
title: title("UTXO Count 30d Change"),
|
||||
bottom: createSingleUtxoCount30dChangeSeries(cohort),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -184,7 +398,7 @@ export function createHoldingsSectionAll({ cohort, title }) {
|
||||
{
|
||||
name: "Supply",
|
||||
title: title("Supply"),
|
||||
bottom: createSingleSupplySeries(cohort),
|
||||
bottom: createSingleSupplySeriesAll(cohort),
|
||||
},
|
||||
{
|
||||
name: "UTXO Count",
|
||||
@@ -238,7 +452,62 @@ export function createHoldingsSectionAddress({ cohort, title }) {
|
||||
{
|
||||
name: "Supply",
|
||||
title: title("Supply"),
|
||||
bottom: createSingleSupplySeries(cohort),
|
||||
bottom: createSingleSupplySeriesWithOwnSupply(cohort),
|
||||
},
|
||||
{
|
||||
name: "UTXO Count",
|
||||
title: title("UTXO Count"),
|
||||
bottom: createSingleUtxoCountSeries(cohort),
|
||||
},
|
||||
{
|
||||
name: "Address Count",
|
||||
title: title("Address Count"),
|
||||
bottom: [
|
||||
line({
|
||||
metric: cohort.addrCount.count,
|
||||
name: "Address Count",
|
||||
color: cohort.color,
|
||||
unit: Unit.count,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "30d Changes",
|
||||
tree: [
|
||||
{
|
||||
name: "Supply",
|
||||
title: title("Supply 30d Change"),
|
||||
bottom: createSingle30dChangeSeries(cohort),
|
||||
},
|
||||
{
|
||||
name: "UTXO Count",
|
||||
title: title("UTXO Count 30d Change"),
|
||||
bottom: createSingleUtxoCount30dChangeSeries(cohort),
|
||||
},
|
||||
{
|
||||
name: "Address Count",
|
||||
title: title("Address Count 30d Change"),
|
||||
bottom: createSingleAddrCount30dChangeSeries(cohort),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Holdings section for address amount cohorts (has relative supply + address count)
|
||||
* @param {{ cohort: AddressCohortObject, title: (metric: string) => string }} args
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
export function createHoldingsSectionAddressAmount({ cohort, title }) {
|
||||
return {
|
||||
name: "Holdings",
|
||||
tree: [
|
||||
{
|
||||
name: "Supply",
|
||||
title: title("Supply"),
|
||||
bottom: createSingleSupplySeriesWithRelative(cohort),
|
||||
},
|
||||
{
|
||||
name: "UTXO Count",
|
||||
@@ -291,10 +560,67 @@ export function createGroupedHoldingsSectionAddress({ list, title }) {
|
||||
tree: [
|
||||
{
|
||||
name: "Supply",
|
||||
title: title("Supply"),
|
||||
bottom: list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({ pattern: tree.supply.total, name, color }),
|
||||
),
|
||||
tree: [
|
||||
{
|
||||
name: "Total",
|
||||
title: title("Supply"),
|
||||
bottom: list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({ pattern: tree.supply.total, name, color }),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "In Profit",
|
||||
title: title("Supply In Profit"),
|
||||
bottom: [
|
||||
...list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInProfit,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
// % of Own Supply
|
||||
...list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyInProfitRelToOwnSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
),
|
||||
...priceLines({
|
||||
numbers: [100, 50, 0],
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "In Loss",
|
||||
title: title("Supply In Loss"),
|
||||
bottom: [
|
||||
...list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInLoss,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
// % of Own Supply
|
||||
...list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyInLossRelToOwnSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
),
|
||||
...priceLines({
|
||||
numbers: [100, 50, 0],
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "UTXO Count",
|
||||
@@ -322,7 +648,176 @@ export function createGroupedHoldingsSectionAddress({ list, title }) {
|
||||
name: "Supply",
|
||||
title: title("Supply 30d Change"),
|
||||
bottom: list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsdBaseline({ pattern: tree.supply._30dChange, name, color }),
|
||||
satsBtcUsdBaseline({
|
||||
pattern: tree.supply._30dChange,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "UTXO Count",
|
||||
title: title("UTXO Count 30d Change"),
|
||||
bottom: list.map(({ name, color, tree }) =>
|
||||
baseline({
|
||||
metric: tree.outputs.utxoCount30dChange,
|
||||
name,
|
||||
unit: Unit.count,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "Address Count",
|
||||
title: title("Address Count 30d Change"),
|
||||
bottom: list.map(({ name, color, addrCount }) =>
|
||||
baseline({
|
||||
metric: addrCount._30dChange,
|
||||
name,
|
||||
unit: Unit.count,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Grouped holdings section for address amount cohorts (has relative supply + address count)
|
||||
* @param {{ list: readonly AddressCohortObject[], title: (metric: string) => string }} args
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
export function createGroupedHoldingsSectionAddressAmount({ list, title }) {
|
||||
return {
|
||||
name: "Holdings",
|
||||
tree: [
|
||||
{
|
||||
name: "Supply",
|
||||
tree: [
|
||||
{
|
||||
name: "Total",
|
||||
title: title("Supply"),
|
||||
bottom: [
|
||||
...list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({ pattern: tree.supply.total, name, color }),
|
||||
),
|
||||
// % of Circulating
|
||||
...list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyRelToCirculatingSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctSupply,
|
||||
}),
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "In Profit",
|
||||
title: title("Supply In Profit"),
|
||||
bottom: [
|
||||
...list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInProfit,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
// % of Circulating
|
||||
...list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyInProfitRelToCirculatingSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctSupply,
|
||||
}),
|
||||
),
|
||||
// % of Own Supply
|
||||
...list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyInProfitRelToOwnSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
),
|
||||
...priceLines({
|
||||
numbers: [100, 50, 0],
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "In Loss",
|
||||
title: title("Supply In Loss"),
|
||||
bottom: [
|
||||
...list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInLoss,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
// % of Circulating
|
||||
...list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyInLossRelToCirculatingSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctSupply,
|
||||
}),
|
||||
),
|
||||
// % of Own Supply
|
||||
...list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyInLossRelToOwnSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
),
|
||||
...priceLines({
|
||||
numbers: [100, 50, 0],
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "UTXO Count",
|
||||
title: title("UTXO Count"),
|
||||
bottom: list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.outputs.utxoCount,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.count,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "Address Count",
|
||||
title: title("Address Count"),
|
||||
bottom: list.map(({ name, color, addrCount }) =>
|
||||
line({ metric: addrCount.count, name, color, unit: Unit.count }),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "30d Changes",
|
||||
tree: [
|
||||
{
|
||||
name: "Supply",
|
||||
title: title("Supply 30d Change"),
|
||||
bottom: list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsdBaseline({
|
||||
pattern: tree.supply._30dChange,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
@@ -366,10 +861,37 @@ export function createGroupedHoldingsSection({ list, title }) {
|
||||
tree: [
|
||||
{
|
||||
name: "Supply",
|
||||
title: title("Supply"),
|
||||
bottom: list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({ pattern: tree.supply.total, name, color }),
|
||||
),
|
||||
tree: [
|
||||
{
|
||||
name: "Total",
|
||||
title: title("Supply"),
|
||||
bottom: list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({ pattern: tree.supply.total, name, color }),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "In Profit",
|
||||
title: title("Supply In Profit"),
|
||||
bottom: list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInProfit,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "In Loss",
|
||||
title: title("Supply In Loss"),
|
||||
bottom: list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInLoss,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "UTXO Count",
|
||||
@@ -390,7 +912,128 @@ export function createGroupedHoldingsSection({ list, title }) {
|
||||
name: "Supply",
|
||||
title: title("Supply 30d Change"),
|
||||
bottom: list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsdBaseline({ pattern: tree.supply._30dChange, name, color }),
|
||||
satsBtcUsdBaseline({
|
||||
pattern: tree.supply._30dChange,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "UTXO Count",
|
||||
title: title("UTXO Count 30d Change"),
|
||||
bottom: list.map(({ name, color, tree }) =>
|
||||
baseline({
|
||||
metric: tree.outputs.utxoCount30dChange,
|
||||
name,
|
||||
unit: Unit.count,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Grouped holdings section with % of Own Supply only (for cohorts without % of Circulating)
|
||||
* @param {{ list: readonly (CohortAgeRange | CohortBasicWithoutMarketCap)[], title: (metric: string) => string }} args
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
export function createGroupedHoldingsSectionWithOwnSupply({ list, title }) {
|
||||
return {
|
||||
name: "Holdings",
|
||||
tree: [
|
||||
{
|
||||
name: "Supply",
|
||||
tree: [
|
||||
{
|
||||
name: "In Profit",
|
||||
title: title("Supply In Profit"),
|
||||
bottom: [
|
||||
...list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInProfit,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
// % of Own Supply
|
||||
...list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyInProfitRelToOwnSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
),
|
||||
...priceLines({
|
||||
numbers: [100, 50, 0],
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "In Loss",
|
||||
title: title("Supply In Loss"),
|
||||
bottom: [
|
||||
...list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInLoss,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
// % of Own Supply
|
||||
...list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyInLossRelToOwnSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
),
|
||||
...priceLines({
|
||||
numbers: [100, 50, 0],
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Total",
|
||||
title: title("Supply"),
|
||||
bottom: list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({ pattern: tree.supply.total, name, color }),
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "UTXO Count",
|
||||
title: title("UTXO Count"),
|
||||
bottom: list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.outputs.utxoCount,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.count,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "30d Changes",
|
||||
tree: [
|
||||
{
|
||||
name: "Supply",
|
||||
title: title("Supply 30d Change"),
|
||||
bottom: list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsdBaseline({
|
||||
pattern: tree.supply._30dChange,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
@@ -421,10 +1064,96 @@ export function createGroupedHoldingsSectionWithRelative({ list, title }) {
|
||||
tree: [
|
||||
{
|
||||
name: "Supply",
|
||||
title: title("Supply"),
|
||||
bottom: list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({ pattern: tree.supply.total, name, color }),
|
||||
),
|
||||
tree: [
|
||||
{
|
||||
name: "Total",
|
||||
title: title("Supply"),
|
||||
bottom: [
|
||||
...list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({ pattern: tree.supply.total, name, color }),
|
||||
),
|
||||
// % of Circulating
|
||||
...list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyRelToCirculatingSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctSupply,
|
||||
}),
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "In Profit",
|
||||
title: title("Supply In Profit"),
|
||||
bottom: [
|
||||
...list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInProfit,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
// % of Circulating
|
||||
...list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyInProfitRelToCirculatingSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctSupply,
|
||||
}),
|
||||
),
|
||||
// % of Own Supply
|
||||
...list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyInProfitRelToOwnSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
),
|
||||
...priceLines({
|
||||
numbers: [100, 50, 0],
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "In Loss",
|
||||
title: title("Supply In Loss"),
|
||||
bottom: [
|
||||
...list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsd({
|
||||
pattern: tree.unrealized.supplyInLoss,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
// % of Circulating
|
||||
...list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyInLossRelToCirculatingSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctSupply,
|
||||
}),
|
||||
),
|
||||
// % of Own Supply
|
||||
...list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyInLossRelToOwnSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
),
|
||||
...priceLines({
|
||||
numbers: [100, 50, 0],
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "UTXO Count",
|
||||
@@ -445,7 +1174,11 @@ export function createGroupedHoldingsSectionWithRelative({ list, title }) {
|
||||
name: "Supply",
|
||||
title: title("Supply 30d Change"),
|
||||
bottom: list.flatMap(({ name, color, tree }) =>
|
||||
satsBtcUsdBaseline({ pattern: tree.supply._30dChange, name, color }),
|
||||
satsBtcUsdBaseline({
|
||||
pattern: tree.supply._30dChange,
|
||||
name,
|
||||
color,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
@@ -462,18 +1195,6 @@ export function createGroupedHoldingsSectionWithRelative({ list, title }) {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Relative",
|
||||
title: title("Relative to Circulating Supply"),
|
||||
bottom: list.map(({ name, color, tree }) =>
|
||||
line({
|
||||
metric: tree.relative.supplyRelToCirculatingSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctSupply,
|
||||
}),
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user