mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-08-05 23:23:05 -07:00
next: ai part 11
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
import { brk } from "../../utils/client.js";
|
||||
import { colors } from "../../utils/colors.js";
|
||||
import { Unit } from "../../utils/units.js";
|
||||
import { ageRanges } from "../age-ranges.js";
|
||||
import { line, price } from "../series.js";
|
||||
import { satsBtcUsd } from "../shared.js";
|
||||
|
||||
/**
|
||||
* @typedef {Object} CoinflowAgeRange
|
||||
* @property {string} name
|
||||
* @property {Color} color
|
||||
* @property {{
|
||||
* mobility: AnySeriesPattern,
|
||||
* spendingRate: AnySeriesPattern,
|
||||
* spendingExposure: AnySeriesPattern,
|
||||
* supply: { mobile: AnyValuePattern, immobile: AnyValuePattern },
|
||||
* }} tree
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {readonly CoinflowAgeRange[]} ranges
|
||||
* @param {"mobility" | "spendingRate" | "spendingExposure"} key
|
||||
* @param {string} name
|
||||
* @returns {PartialChartOption}
|
||||
*/
|
||||
function ageRangeRatioChart(ranges, key, name) {
|
||||
return {
|
||||
name,
|
||||
title: `${name} by UTXO Age`,
|
||||
bottom: ranges.map((range) =>
|
||||
line({
|
||||
series: range.tree[key],
|
||||
name: range.name,
|
||||
color: range.color,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {readonly CoinflowAgeRange[]} ranges
|
||||
* @param {"mobile" | "immobile"} key
|
||||
* @param {string} name
|
||||
* @returns {PartialChartOption}
|
||||
*/
|
||||
function ageRangeSupplyChart(ranges, key, name) {
|
||||
return {
|
||||
name,
|
||||
title: `${name} Supply by UTXO Age`,
|
||||
bottom: ranges.flatMap((range) =>
|
||||
satsBtcUsd({
|
||||
pattern: range.tree.supply[key],
|
||||
name: range.name,
|
||||
color: range.color,
|
||||
}),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Coinflow section.
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
export function createCoinflowSection() {
|
||||
const { coinflow } = brk.series;
|
||||
const ranges = ageRanges.map(({ key, ...range }) => ({
|
||||
...range,
|
||||
tree: coinflow.ageRange[key],
|
||||
}));
|
||||
|
||||
const horizons = /** @type {const} */ ([
|
||||
{ key: "_8y", name: "8Y" },
|
||||
{ key: "_4y", name: "4Y" },
|
||||
{ key: "_2y", name: "2Y" },
|
||||
{ key: "_1y", name: "1Y" },
|
||||
{ key: "_6m", name: "6M" },
|
||||
{ key: "_3m", name: "3M" },
|
||||
{ key: "_1m", name: "1M" },
|
||||
]).map((horizon, index, all) => ({
|
||||
...horizon,
|
||||
color: colors.at(index, all.length),
|
||||
}));
|
||||
|
||||
return {
|
||||
name: "Coinflow",
|
||||
tree: [
|
||||
{
|
||||
name: "Supply",
|
||||
tree: [
|
||||
{
|
||||
name: "Breakdown",
|
||||
title: "Mobile vs Immobile Supply",
|
||||
bottom: [
|
||||
...satsBtcUsd({
|
||||
pattern: coinflow.supply.mobile,
|
||||
name: "Mobile",
|
||||
color: colors.mobile,
|
||||
}),
|
||||
...satsBtcUsd({
|
||||
pattern: coinflow.supply.immobile,
|
||||
name: "Immobile",
|
||||
color: colors.immobile,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Mobile in Loss",
|
||||
title: "Mobile Supply in Loss",
|
||||
bottom: [
|
||||
line({
|
||||
series: coinflow.supply.mobile.inLoss.share,
|
||||
name: "Lifetime",
|
||||
color: colors.loss,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "In Loss by Horizon",
|
||||
title: "Mobile Supply in Loss by Horizon",
|
||||
bottom: horizons.map((horizon) =>
|
||||
line({
|
||||
series:
|
||||
coinflow.horizon[horizon.key].supply.inLoss.share,
|
||||
name: horizon.name,
|
||||
color: horizon.color,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Cap",
|
||||
title: "Coinflow Cap",
|
||||
bottom: [
|
||||
line({
|
||||
series: coinflow.cap.usd,
|
||||
name: "Coinflow",
|
||||
color: colors.coinflow,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Price",
|
||||
title: "Coinflow Price",
|
||||
top: [
|
||||
price({
|
||||
series: coinflow.price,
|
||||
name: "Coinflow",
|
||||
color: colors.coinflow,
|
||||
}),
|
||||
],
|
||||
bottom: [
|
||||
line({
|
||||
series: coinflow.price.ratio,
|
||||
name: "Spot / Coinflow",
|
||||
color: colors.coinflow,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Age Range",
|
||||
tree: [
|
||||
ageRangeRatioChart(ranges, "mobility", "Mobility"),
|
||||
ageRangeRatioChart(ranges, "spendingRate", "Spending Rate"),
|
||||
ageRangeRatioChart(
|
||||
ranges,
|
||||
"spendingExposure",
|
||||
"Spending Exposure",
|
||||
),
|
||||
{
|
||||
name: "Supply",
|
||||
tree: [
|
||||
ageRangeSupplyChart(ranges, "mobile", "Mobile"),
|
||||
ageRangeSupplyChart(ranges, "immobile", "Immobile"),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
import { Unit } from "../../../utils/units.js";
|
||||
import { line, ROLLING_WINDOWS } from "../../series.js";
|
||||
import { satsBtcUsd } from "../../shared.js";
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* average: Record<"_24h" | "_1w" | "_1m" | "_1y", AnySeriesPattern>,
|
||||
* sum: Record<"_24h" | "_1w" | "_1m" | "_1y", AnySeriesPattern>,
|
||||
* cumulative: AnySeriesPattern,
|
||||
* }} CointimeAgeRangeCoindays
|
||||
*
|
||||
* @typedef {Object} CointimeAgeRange
|
||||
* @property {string} name
|
||||
* @property {Color} color
|
||||
* @property {{
|
||||
* coindaysCreated: CointimeAgeRangeCoindays,
|
||||
* coindaysConsumed: CointimeAgeRangeCoindays,
|
||||
* coindaysStored: CointimeAgeRangeCoindays,
|
||||
* liveliness: AnySeriesPattern,
|
||||
* vaultedness: AnySeriesPattern,
|
||||
* ratio: AnySeriesPattern,
|
||||
* supply: { active: AnyValuePattern, vaulted: AnyValuePattern },
|
||||
* }} tree
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {readonly CointimeAgeRange[]} ranges
|
||||
* @param {"liveliness" | "vaultedness" | "ratio"} key
|
||||
* @param {string} name
|
||||
* @param {string} legend
|
||||
* @returns {PartialChartOption}
|
||||
*/
|
||||
function activityChart(ranges, key, name, legend) {
|
||||
return {
|
||||
name,
|
||||
title: `${legend} by UTXO Age`,
|
||||
bottom: ranges.map((range) =>
|
||||
line({
|
||||
series: range.tree[key],
|
||||
name: range.name,
|
||||
color: range.color,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {readonly CointimeAgeRange[]} ranges
|
||||
* @param {"active" | "vaulted"} key
|
||||
* @param {string} name
|
||||
* @returns {PartialChartOption}
|
||||
*/
|
||||
function supplyChart(ranges, key, name) {
|
||||
return {
|
||||
name,
|
||||
title: `${name} Supply by UTXO Age`,
|
||||
bottom: ranges.flatMap((range) =>
|
||||
satsBtcUsd({
|
||||
pattern: range.tree.supply[key],
|
||||
name: range.name,
|
||||
color: range.color,
|
||||
}),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {readonly CointimeAgeRange[]} ranges
|
||||
* @param {"coindaysCreated" | "coindaysConsumed" | "coindaysStored"} key
|
||||
* @param {string} name
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
function coindaysTree(ranges, key, name) {
|
||||
return {
|
||||
name,
|
||||
tree: [
|
||||
{
|
||||
name: "Average",
|
||||
tree: ROLLING_WINDOWS.map((window) => ({
|
||||
name: window.name,
|
||||
title: `${window.title} Average ${name} by UTXO Age`,
|
||||
bottom: ranges.map((range) =>
|
||||
line({
|
||||
series: range.tree[key].average[window.key],
|
||||
name: range.name,
|
||||
color: range.color,
|
||||
unit: Unit.coindays,
|
||||
}),
|
||||
),
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: "Sum",
|
||||
tree: ROLLING_WINDOWS.map((window) => ({
|
||||
name: window.name,
|
||||
title: `${window.title} ${name} by UTXO Age`,
|
||||
bottom: ranges.map((range) =>
|
||||
line({
|
||||
series: range.tree[key].sum[window.key],
|
||||
name: range.name,
|
||||
color: range.color,
|
||||
unit: Unit.coindays,
|
||||
}),
|
||||
),
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: "Cumulative",
|
||||
title: `Cumulative ${name} by UTXO Age`,
|
||||
bottom: ranges.map((range) =>
|
||||
line({
|
||||
series: range.tree[key].cumulative,
|
||||
name: range.name,
|
||||
color: range.color,
|
||||
unit: Unit.coindays,
|
||||
}),
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {readonly CointimeAgeRange[]} ranges
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
export function createCointimeAgeRangeSection(ranges) {
|
||||
return {
|
||||
name: "Age Range",
|
||||
tree: [
|
||||
{
|
||||
name: "Supply",
|
||||
tree: [
|
||||
supplyChart(ranges, "active", "Active"),
|
||||
supplyChart(ranges, "vaulted", "Vaulted"),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Activity",
|
||||
tree: [
|
||||
activityChart(ranges, "liveliness", "Liveliness", "Liveliness"),
|
||||
activityChart(ranges, "vaultedness", "Vaultedness", "Vaultedness"),
|
||||
activityChart(
|
||||
ranges,
|
||||
"ratio",
|
||||
"Activity Ratio",
|
||||
"Liveliness / Vaultedness",
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Coindays",
|
||||
tree: [
|
||||
coindaysTree(ranges, "coindaysCreated", "Coindays Created"),
|
||||
coindaysTree(ranges, "coindaysConsumed", "Coindays Consumed"),
|
||||
coindaysTree(ranges, "coindaysStored", "Coindays Stored"),
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,472 @@
|
||||
import { colors } from "../../../utils/colors.js";
|
||||
import { brk } from "../../../utils/client.js";
|
||||
import { Unit } from "../../../utils/units.js";
|
||||
import {
|
||||
dots,
|
||||
line,
|
||||
price,
|
||||
multiSeriesTree,
|
||||
percentRatioDots,
|
||||
sumsAndAveragesCumulative,
|
||||
} from "../../series.js";
|
||||
import { ageRanges } from "../../age-ranges.js";
|
||||
import { satsBtcUsd, priceRatioPercentilesTree } from "../../shared.js";
|
||||
import { createCointimeAgeRangeSection } from "./age-range.js";
|
||||
|
||||
/**
|
||||
* Create Cointime section
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
export function createCointimeSection() {
|
||||
const { cointime, cohorts, supply } = brk.series;
|
||||
const {
|
||||
prices: cointimePrices,
|
||||
cap,
|
||||
activity,
|
||||
supply: cointimeSupply,
|
||||
adjusted,
|
||||
reserveRisk,
|
||||
value,
|
||||
} = cointime;
|
||||
const { all } = cohorts.utxo;
|
||||
const cointimeAgeRanges = ageRanges.map(({ key, ...range }) => ({
|
||||
...range,
|
||||
tree: cointime.ageRange[key],
|
||||
}));
|
||||
|
||||
// Reference lines for cap comparisons
|
||||
const capReferenceLines = /** @type {const} */ ([
|
||||
{ series: supply.marketCap.usd, name: "Market", color: colors.default },
|
||||
{
|
||||
series: all.realized.cap.usd,
|
||||
name: "Realized",
|
||||
color: colors.realized,
|
||||
},
|
||||
]);
|
||||
|
||||
/** @type {readonly { pattern: PriceRatioPercentilesPattern, name: string, title: (name: string) => string, color: Color, defaultActive: boolean }[]} */
|
||||
const prices = [
|
||||
{
|
||||
pattern: cointimePrices.trueMarketMean,
|
||||
name: "True Market Mean",
|
||||
title: (name) => name,
|
||||
color: colors.trueMarketMean,
|
||||
defaultActive: true,
|
||||
},
|
||||
{
|
||||
pattern: cointimePrices.vaulted,
|
||||
name: "Vaulted",
|
||||
title: (name) => `${name} Price`,
|
||||
color: colors.vaulted,
|
||||
defaultActive: true,
|
||||
},
|
||||
{
|
||||
pattern: cointimePrices.active,
|
||||
name: "Active",
|
||||
title: (name) => `${name} Price`,
|
||||
color: colors.active,
|
||||
defaultActive: true,
|
||||
},
|
||||
{
|
||||
pattern: cointimePrices.cointime,
|
||||
name: "Cointime",
|
||||
title: (name) => `${name} Price`,
|
||||
color: colors.cointime,
|
||||
defaultActive: true,
|
||||
},
|
||||
];
|
||||
|
||||
const caps = /** @type {const} */ ([
|
||||
{
|
||||
series: cap.vaulted.usd,
|
||||
name: "Vaulted",
|
||||
color: colors.vaulted,
|
||||
defaultActive: true,
|
||||
},
|
||||
{
|
||||
series: cap.active.usd,
|
||||
name: "Active",
|
||||
color: colors.active,
|
||||
defaultActive: true,
|
||||
},
|
||||
{
|
||||
series: cap.cointime.usd,
|
||||
name: "Cointime",
|
||||
color: colors.cointime,
|
||||
defaultActive: true,
|
||||
},
|
||||
{
|
||||
series: cap.investor.usd,
|
||||
name: "Investor",
|
||||
color: colors.investor,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
series: cap.thermo.usd,
|
||||
name: "Thermo",
|
||||
color: colors.thermo,
|
||||
defaultActive: false,
|
||||
},
|
||||
]);
|
||||
|
||||
const supplyBreakdown = /** @type {const} */ ([
|
||||
{ pattern: all.supply.total, name: "Total", color: colors.bitcoin },
|
||||
{
|
||||
pattern: cointimeSupply.vaulted,
|
||||
name: "Vaulted",
|
||||
color: colors.vaulted,
|
||||
},
|
||||
{
|
||||
pattern: cointimeSupply.active,
|
||||
name: "Active",
|
||||
color: colors.active,
|
||||
},
|
||||
]);
|
||||
|
||||
const coinblocks = /** @type {const} */ ([
|
||||
{
|
||||
pattern: activity.coinblocksDestroyed,
|
||||
name: "Destroyed",
|
||||
title: "Coinblocks Destroyed",
|
||||
color: colors.destroyed,
|
||||
},
|
||||
{
|
||||
pattern: activity.coinblocksCreated,
|
||||
name: "Created",
|
||||
title: "Coinblocks Created",
|
||||
color: colors.created,
|
||||
},
|
||||
{
|
||||
pattern: activity.coinblocksStored,
|
||||
name: "Stored",
|
||||
title: "Coinblocks Stored",
|
||||
color: colors.stored,
|
||||
},
|
||||
]);
|
||||
|
||||
// Colors aligned with coinblocks: Destroyed=red, Created=orange, Stored=green
|
||||
const cointimeValues = /** @type {const} */ ([
|
||||
{
|
||||
pattern: value.created,
|
||||
name: "Created",
|
||||
title: "Cointime Value Created",
|
||||
color: colors.created,
|
||||
},
|
||||
{
|
||||
pattern: value.destroyed,
|
||||
name: "Destroyed",
|
||||
title: "Cointime Value Destroyed",
|
||||
color: colors.destroyed,
|
||||
},
|
||||
{
|
||||
pattern: value.stored,
|
||||
name: "Stored",
|
||||
title: "Cointime Value Stored",
|
||||
color: colors.stored,
|
||||
},
|
||||
]);
|
||||
|
||||
const vocdd = /** @type {const} */ ({
|
||||
pattern: value.vocdd,
|
||||
name: "VOCDD",
|
||||
title: "Value of Coin Days Destroyed",
|
||||
color: colors.vocdd,
|
||||
});
|
||||
|
||||
return {
|
||||
name: "Cointime",
|
||||
tree: [
|
||||
{
|
||||
name: "Prices",
|
||||
tree: [
|
||||
{
|
||||
name: "Compare",
|
||||
title: "Cointime Prices",
|
||||
top: [
|
||||
price({
|
||||
series: all.realized.price,
|
||||
name: "Realized",
|
||||
color: colors.realized,
|
||||
}),
|
||||
price({
|
||||
series: all.realized.capitalized.price,
|
||||
name: "Capitalized",
|
||||
color: colors.capitalized,
|
||||
}),
|
||||
...prices.map(({ pattern, name, color, defaultActive }) =>
|
||||
price({ series: pattern, name, color, defaultActive }),
|
||||
),
|
||||
],
|
||||
},
|
||||
...prices.map(({ pattern, name, title, color }) => ({
|
||||
name,
|
||||
tree: priceRatioPercentilesTree({
|
||||
pattern,
|
||||
title: title(name),
|
||||
legend: name,
|
||||
color,
|
||||
priceReferences: [
|
||||
price({
|
||||
series: all.realized.price,
|
||||
name: "Realized",
|
||||
color: colors.realized,
|
||||
defaultActive: false,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
})),
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: "Caps",
|
||||
tree: [
|
||||
{
|
||||
name: "Compare",
|
||||
title: "Cointime Caps",
|
||||
bottom: [
|
||||
...capReferenceLines.map(({ series, name, color }) =>
|
||||
line({ series, name, color, unit: Unit.usd }),
|
||||
),
|
||||
...caps.map(({ series, name, color, defaultActive }) =>
|
||||
line({ series, name, color, defaultActive, unit: Unit.usd }),
|
||||
),
|
||||
],
|
||||
},
|
||||
...caps.map(({ series, name, color }) => ({
|
||||
name,
|
||||
title: `${name} Cap`,
|
||||
bottom: [
|
||||
line({ series, name, color, unit: Unit.usd }),
|
||||
...capReferenceLines.map((ref) =>
|
||||
line({
|
||||
series: ref.series,
|
||||
name: ref.name,
|
||||
color: ref.color,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
),
|
||||
],
|
||||
})),
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: "Supply",
|
||||
tree: [
|
||||
{
|
||||
name: "Breakdown",
|
||||
title: "Active vs Vaulted Supply",
|
||||
bottom: supplyBreakdown.flatMap(({ pattern, name, color }) =>
|
||||
satsBtcUsd({ pattern, name, color }),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "Active in Loss",
|
||||
title: "Active Supply in Loss",
|
||||
bottom: [
|
||||
line({
|
||||
series: cointimeSupply.active.inLoss.share,
|
||||
name: "Share",
|
||||
color: colors.loss,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
createCointimeAgeRangeSection(cointimeAgeRanges),
|
||||
|
||||
{
|
||||
name: "Activity",
|
||||
title: "Liveliness & Vaultedness",
|
||||
bottom: [
|
||||
line({
|
||||
series: activity.liveliness,
|
||||
name: "Liveliness",
|
||||
color: colors.liveliness,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
line({
|
||||
series: activity.vaultedness,
|
||||
name: "Vaultedness",
|
||||
color: colors.vaulted,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
line({
|
||||
series: activity.ratio,
|
||||
name: "Liveliness / Vaultedness",
|
||||
color: colors.activity,
|
||||
unit: Unit.ratio,
|
||||
defaultActive: false,
|
||||
}),
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: "Coinblocks",
|
||||
tree: [
|
||||
...multiSeriesTree({
|
||||
entries: coinblocks.map(({ pattern, name, color }) => ({
|
||||
name,
|
||||
color,
|
||||
average: pattern.average,
|
||||
sum: pattern.sum,
|
||||
cumulative: pattern.cumulative,
|
||||
})),
|
||||
metric: "Coinblocks",
|
||||
unit: Unit.coinblocks,
|
||||
}),
|
||||
...coinblocks.map(({ pattern, name, title: metric, color }) => ({
|
||||
name,
|
||||
tree: sumsAndAveragesCumulative({
|
||||
sum: pattern.sum,
|
||||
average: pattern.average,
|
||||
cumulative: pattern.cumulative,
|
||||
metric,
|
||||
unit: Unit.coinblocks,
|
||||
color,
|
||||
}),
|
||||
})),
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: "Value",
|
||||
tree: [
|
||||
...multiSeriesTree({
|
||||
entries: [
|
||||
...cointimeValues.map(({ pattern, name, color }) => ({
|
||||
name,
|
||||
color,
|
||||
average: pattern.average,
|
||||
sum: pattern.sum,
|
||||
cumulative: pattern.cumulative,
|
||||
})),
|
||||
{
|
||||
name: vocdd.name,
|
||||
color: vocdd.color,
|
||||
average: vocdd.pattern.average,
|
||||
sum: vocdd.pattern.sum,
|
||||
cumulative: vocdd.pattern.cumulative,
|
||||
},
|
||||
],
|
||||
metric: "Cointime Value",
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
...cointimeValues.map(({ pattern, name, title: metric, color }) => ({
|
||||
name,
|
||||
tree: sumsAndAveragesCumulative({
|
||||
sum: pattern.sum,
|
||||
average: pattern.average,
|
||||
cumulative: pattern.cumulative,
|
||||
metric,
|
||||
unit: Unit.usd,
|
||||
color,
|
||||
}),
|
||||
})),
|
||||
{
|
||||
name: vocdd.name,
|
||||
tree: sumsAndAveragesCumulative({
|
||||
sum: vocdd.pattern.sum,
|
||||
average: vocdd.pattern.average,
|
||||
cumulative: vocdd.pattern.cumulative,
|
||||
metric: vocdd.title,
|
||||
unit: Unit.usd,
|
||||
color: vocdd.color,
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: "Indicators",
|
||||
tree: [
|
||||
{
|
||||
name: "AVIV",
|
||||
title: "AVIV Ratio",
|
||||
bottom: [
|
||||
line({
|
||||
series: cap.aviv.ratio,
|
||||
name: "AVIV",
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Reserve Risk",
|
||||
title: "Reserve Risk",
|
||||
bottom: [
|
||||
line({
|
||||
series: reserveRisk.value,
|
||||
name: "Ratio",
|
||||
color: colors.reserveRisk,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
name: "Adjusted",
|
||||
tree: [
|
||||
{
|
||||
name: "Inflation",
|
||||
title: "Cointime-Adjusted Inflation",
|
||||
bottom: [
|
||||
dots({
|
||||
series: supply.inflationRate.percent,
|
||||
name: "Base",
|
||||
color: colors.base,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
...percentRatioDots({
|
||||
pattern: adjusted.inflationRate,
|
||||
name: "Cointime-Adjusted",
|
||||
color: colors.adjusted,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "BTC Velocity",
|
||||
title: "Cointime-Adjusted BTC Velocity",
|
||||
bottom: [
|
||||
line({
|
||||
series: supply.velocity.native,
|
||||
name: "Base",
|
||||
color: colors.base,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
line({
|
||||
series: adjusted.txVelocityNative,
|
||||
name: "Cointime-Adjusted",
|
||||
color: colors.adjusted,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "USD Velocity",
|
||||
title: "Cointime-Adjusted USD Velocity",
|
||||
bottom: [
|
||||
line({
|
||||
series: supply.velocity.fiat,
|
||||
name: "Base",
|
||||
color: colors.thermo,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
line({
|
||||
series: adjusted.txVelocityFiat,
|
||||
name: "Cointime-Adjusted",
|
||||
color: colors.vaulted,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user