mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-13 03:58:12 -07:00
website: snapshot
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/** Chain section builder - typed tree-based patterns */
|
||||
|
||||
import { Unit } from "../utils/units.js";
|
||||
import { line, baseline, dots } from "./series.js";
|
||||
import { satsBtcUsd } from "./shared.js";
|
||||
|
||||
/**
|
||||
@@ -12,9 +13,6 @@ export function createChainSection(ctx) {
|
||||
const {
|
||||
colors,
|
||||
brk,
|
||||
line,
|
||||
baseline,
|
||||
dots,
|
||||
createPriceLine,
|
||||
fromSizePattern,
|
||||
fromFullnessPattern,
|
||||
@@ -240,7 +238,7 @@ export function createChainSection(ctx) {
|
||||
name: "Volume",
|
||||
title: "Transaction Volume",
|
||||
bottom: [
|
||||
...satsBtcUsd(ctx, transactions.volume.sentSum, "Sent"),
|
||||
...satsBtcUsd( transactions.volume.sentSum, "Sent"),
|
||||
line({
|
||||
metric: transactions.volume.annualizedVolume.sats,
|
||||
name: "annualized",
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
import { Unit } from "../../utils/units.js";
|
||||
import { line, baseline } from "../series.js";
|
||||
import {
|
||||
createSingleSupplySeries,
|
||||
createGroupedSupplyTotalSeries,
|
||||
@@ -54,12 +55,12 @@ export function createAddressCohortFolder(ctx, args) {
|
||||
{
|
||||
name: "in profit",
|
||||
title: `Supply In Profit ${title}`,
|
||||
bottom: createGroupedSupplyInProfitSeries(ctx, list),
|
||||
bottom: createGroupedSupplyInProfitSeries(list),
|
||||
},
|
||||
{
|
||||
name: "in loss",
|
||||
title: `Supply In Loss ${title}`,
|
||||
bottom: createGroupedSupplyInLossSeries(ctx, list),
|
||||
bottom: createGroupedSupplyInLossSeries(list),
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -68,7 +69,7 @@ export function createAddressCohortFolder(ctx, args) {
|
||||
{
|
||||
name: "utxo count",
|
||||
title: `UTXO Count ${title}`,
|
||||
bottom: createUtxoCountSeries(ctx, list, useGroupName),
|
||||
bottom: createUtxoCountSeries(list, useGroupName),
|
||||
},
|
||||
|
||||
// Address count (ADDRESS COHORTS ONLY - fully type safe!)
|
||||
@@ -87,7 +88,7 @@ export function createAddressCohortFolder(ctx, args) {
|
||||
{
|
||||
name: "Price",
|
||||
title: `Realized Price ${title}`,
|
||||
top: createRealizedPriceSeries(ctx, list),
|
||||
top: createRealizedPriceSeries(list),
|
||||
},
|
||||
{
|
||||
name: "Ratio",
|
||||
@@ -96,7 +97,6 @@ export function createAddressCohortFolder(ctx, args) {
|
||||
},
|
||||
]
|
||||
: createRealizedPriceOptions(
|
||||
ctx,
|
||||
/** @type {AddressCohortObject} */ (args),
|
||||
title,
|
||||
)),
|
||||
@@ -119,24 +119,22 @@ export function createAddressCohortFolder(ctx, args) {
|
||||
...createUnrealizedSection(ctx, list, useGroupName, title),
|
||||
|
||||
// Cost basis section (no percentiles for address cohorts)
|
||||
...createCostBasisSection(ctx, list, useGroupName, title),
|
||||
...createCostBasisSection(list, useGroupName, title),
|
||||
|
||||
// Activity section
|
||||
...createActivitySection(ctx, list, useGroupName, title),
|
||||
...createActivitySection(list, useGroupName, title),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create realized price options for single cohort
|
||||
* @param {PartialContext} ctx
|
||||
* @param {AddressCohortObject} args
|
||||
* @param {string} title
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createRealizedPriceOptions(ctx, args, title) {
|
||||
const { line } = ctx;
|
||||
const { tree, color } = args;
|
||||
function createRealizedPriceOptions(args, title) {
|
||||
const { tree, color } = args;
|
||||
|
||||
return [
|
||||
{
|
||||
@@ -163,7 +161,7 @@ function createRealizedPriceOptions(ctx, args, title) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
function createRealizedCapWithExtras(ctx, list, args, useGroupName) {
|
||||
const { line, baseline, createPriceLine } = ctx;
|
||||
const { createPriceLine } = ctx;
|
||||
const isSingle = !("list" in args);
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
@@ -196,7 +194,7 @@ function createRealizedCapWithExtras(ctx, list, args, useGroupName) {
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createRealizedPnlSection(ctx, args, title) {
|
||||
const { colors, line } = ctx;
|
||||
const { colors } = ctx;
|
||||
const { realized } = args.tree;
|
||||
|
||||
return [
|
||||
@@ -251,7 +249,7 @@ function createRealizedPnlSection(ctx, args, title) {
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createUnrealizedSection(ctx, list, useGroupName, title) {
|
||||
const { colors, line, baseline } = ctx;
|
||||
const { colors } = ctx;
|
||||
|
||||
return [
|
||||
{
|
||||
@@ -301,15 +299,12 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
|
||||
|
||||
/**
|
||||
* Create cost basis section (no percentiles for address cohorts)
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly AddressCohortObject[]} list
|
||||
* @param {boolean} useGroupName
|
||||
* @param {string} title
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createCostBasisSection(ctx, list, useGroupName, title) {
|
||||
const { line } = ctx;
|
||||
|
||||
function createCostBasisSection(list, useGroupName, title) {
|
||||
return [
|
||||
{
|
||||
name: "Cost Basis",
|
||||
@@ -345,15 +340,12 @@ function createCostBasisSection(ctx, list, useGroupName, title) {
|
||||
|
||||
/**
|
||||
* Create activity section
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly AddressCohortObject[]} list
|
||||
* @param {boolean} useGroupName
|
||||
* @param {string} title
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createActivitySection(ctx, list, useGroupName, title) {
|
||||
const { line } = ctx;
|
||||
|
||||
function createActivitySection(list, useGroupName, title) {
|
||||
return [
|
||||
{
|
||||
name: "Activity",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** Shared cohort chart section builders */
|
||||
|
||||
import { Unit } from "../../utils/units.js";
|
||||
import { line } from "../series.js";
|
||||
import { satsBtcUsd } from "../shared.js";
|
||||
|
||||
/**
|
||||
@@ -10,11 +11,11 @@ import { satsBtcUsd } from "../shared.js";
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createSingleSupplySeries(ctx, cohort) {
|
||||
const { colors, line, createPriceLine } = ctx;
|
||||
const { colors, createPriceLine } = ctx;
|
||||
const { tree } = cohort;
|
||||
|
||||
return [
|
||||
...satsBtcUsd(ctx, tree.supply.total, "Supply", colors.default),
|
||||
...satsBtcUsd( tree.supply.total, "Supply", colors.default),
|
||||
...("supplyRelToCirculatingSupply" in tree.relative
|
||||
? [
|
||||
line({
|
||||
@@ -25,9 +26,9 @@ export function createSingleSupplySeries(ctx, cohort) {
|
||||
}),
|
||||
]
|
||||
: []),
|
||||
...satsBtcUsd(ctx, tree.unrealized.supplyInProfit, "In Profit", colors.green),
|
||||
...satsBtcUsd(ctx, tree.unrealized.supplyInLoss, "In Loss", colors.red),
|
||||
...satsBtcUsd(ctx, tree.supply.halved, "half", colors.gray).map((s) => ({
|
||||
...satsBtcUsd( tree.unrealized.supplyInProfit, "In Profit", colors.green),
|
||||
...satsBtcUsd( tree.unrealized.supplyInLoss, "In Loss", colors.red),
|
||||
...satsBtcUsd( tree.supply.halved, "half", colors.gray).map((s) => ({
|
||||
...s,
|
||||
options: { lineStyle: 4 },
|
||||
})),
|
||||
@@ -76,11 +77,11 @@ export function createSingleSupplySeries(ctx, cohort) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createGroupedSupplyTotalSeries(ctx, list) {
|
||||
const { line, brk } = ctx;
|
||||
const { brk } = ctx;
|
||||
const constant100 = brk.metrics.constants.constant100;
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
...satsBtcUsd(ctx, tree.supply.total, name, color),
|
||||
...satsBtcUsd( tree.supply.total, name, color),
|
||||
line({
|
||||
metric:
|
||||
"supplyRelToCirculatingSupply" in tree.relative
|
||||
@@ -95,15 +96,13 @@ export function createGroupedSupplyTotalSeries(ctx, list) {
|
||||
|
||||
/**
|
||||
* Create supply in profit series for grouped cohorts
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly CohortObject[]} list
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createGroupedSupplyInProfitSeries(ctx, list) {
|
||||
const { line } = ctx;
|
||||
|
||||
export function createGroupedSupplyInProfitSeries(list) {
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
...satsBtcUsd(ctx, tree.unrealized.supplyInProfit, name, color),
|
||||
...satsBtcUsd( tree.unrealized.supplyInProfit, name, color),
|
||||
...("supplyInProfitRelToCirculatingSupply" in tree.relative
|
||||
? [
|
||||
line({
|
||||
@@ -119,15 +118,13 @@ export function createGroupedSupplyInProfitSeries(ctx, list) {
|
||||
|
||||
/**
|
||||
* Create supply in loss series for grouped cohorts
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly CohortObject[]} list
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createGroupedSupplyInLossSeries(ctx, list) {
|
||||
const { line } = ctx;
|
||||
|
||||
export function createGroupedSupplyInLossSeries(list) {
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
...satsBtcUsd(ctx, tree.unrealized.supplyInLoss, name, color),
|
||||
...satsBtcUsd( tree.unrealized.supplyInLoss, name, color),
|
||||
...("supplyInLossRelToCirculatingSupply" in tree.relative
|
||||
? [
|
||||
line({
|
||||
@@ -143,14 +140,11 @@ export function createGroupedSupplyInLossSeries(ctx, list) {
|
||||
|
||||
/**
|
||||
* Create UTXO count series
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly CohortObject[]} list
|
||||
* @param {boolean} useGroupName
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createUtxoCountSeries(ctx, list, useGroupName) {
|
||||
const { line } = ctx;
|
||||
|
||||
export function createUtxoCountSeries(list, useGroupName) {
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
line({
|
||||
metric: tree.outputs.utxoCount,
|
||||
@@ -169,7 +163,7 @@ export function createUtxoCountSeries(ctx, list, useGroupName) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createAddressCountSeries(ctx, list, useGroupName) {
|
||||
const { line, colors } = ctx;
|
||||
const { colors } = ctx;
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
line({
|
||||
@@ -183,13 +177,10 @@ export function createAddressCountSeries(ctx, list, useGroupName) {
|
||||
|
||||
/**
|
||||
* Create realized price series for grouped cohorts
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly CohortObject[]} list
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createRealizedPriceSeries(ctx, list) {
|
||||
const { line } = ctx;
|
||||
|
||||
export function createRealizedPriceSeries(list) {
|
||||
return list.map(({ color, name, tree }) =>
|
||||
line({ metric: tree.realized.realizedPrice, name, color, unit: Unit.usd }),
|
||||
);
|
||||
@@ -202,7 +193,7 @@ export function createRealizedPriceSeries(ctx, list) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createRealizedPriceRatioSeries(ctx, list) {
|
||||
const { line, createPriceLine } = ctx;
|
||||
const { createPriceLine } = ctx;
|
||||
|
||||
return [
|
||||
...list.map(({ color, name, tree }) =>
|
||||
@@ -219,14 +210,11 @@ export function createRealizedPriceRatioSeries(ctx, list) {
|
||||
|
||||
/**
|
||||
* Create realized capitalization series
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly CohortObject[]} list
|
||||
* @param {boolean} useGroupName
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createRealizedCapSeries(ctx, list, useGroupName) {
|
||||
const { line } = ctx;
|
||||
|
||||
export function createRealizedCapSeries(list, useGroupName) {
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
line({
|
||||
metric: tree.realized.realizedCap,
|
||||
@@ -239,14 +227,11 @@ export function createRealizedCapSeries(ctx, list, useGroupName) {
|
||||
|
||||
/**
|
||||
* Create cost basis min/max series (available on all cohorts)
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly CohortObject[]} list
|
||||
* @param {boolean} useGroupName
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createCostBasisMinMaxSeries(ctx, list, useGroupName) {
|
||||
const { line } = ctx;
|
||||
|
||||
export function createCostBasisMinMaxSeries(list, useGroupName) {
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
line({
|
||||
metric: tree.costBasis.min,
|
||||
@@ -265,14 +250,11 @@ export function createCostBasisMinMaxSeries(ctx, list, useGroupName) {
|
||||
|
||||
/**
|
||||
* Create cost basis percentile series (only for cohorts with CostBasisPattern2)
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly CohortWithCostBasisPercentiles[]} list
|
||||
* @param {boolean} useGroupName
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createCostBasisPercentilesSeries(ctx, list, useGroupName) {
|
||||
const { line } = ctx;
|
||||
|
||||
export function createCostBasisPercentilesSeries(list, useGroupName) {
|
||||
return list.flatMap(({ color, name, tree }) => {
|
||||
const percentiles = tree.costBasis.percentiles;
|
||||
return [
|
||||
|
||||
@@ -34,6 +34,7 @@ import {
|
||||
createCostBasisPercentilesSeries,
|
||||
} from "./shared.js";
|
||||
import { Unit } from "../../utils/units.js";
|
||||
import { line, baseline } from "../series.js";
|
||||
|
||||
// ============================================================================
|
||||
// Folder Builders (4 variants based on pattern capabilities)
|
||||
@@ -51,10 +52,10 @@ export function createCohortFolderAll(ctx, args) {
|
||||
name: args.name || "all",
|
||||
tree: [
|
||||
createSingleSupplyChart(ctx, args, title),
|
||||
createSingleUtxoCountChart(ctx, args, title),
|
||||
createSingleUtxoCountChart(args, title),
|
||||
createSingleRealizedSectionWithAdjusted(ctx, args, title),
|
||||
createSingleUnrealizedSectionAll(ctx, args, title),
|
||||
createSingleCostBasisSectionWithPercentiles(ctx, args, title),
|
||||
createSingleCostBasisSectionWithPercentiles(args, title),
|
||||
...createSingleActivitySectionWithAdjusted(ctx, args, title),
|
||||
],
|
||||
};
|
||||
@@ -74,11 +75,11 @@ export function createCohortFolderFull(ctx, args) {
|
||||
name: args.name || "all",
|
||||
tree: [
|
||||
createGroupedSupplySection(ctx, list, title),
|
||||
createGroupedUtxoCountChart(ctx, list, title),
|
||||
createGroupedUtxoCountChart(list, title),
|
||||
createGroupedRealizedSectionWithAdjusted(ctx, list, title),
|
||||
createGroupedUnrealizedSectionFull(ctx, list, title),
|
||||
createGroupedCostBasisSectionWithPercentiles(ctx, list, title),
|
||||
...createGroupedActivitySectionWithAdjusted(ctx, list, title),
|
||||
createGroupedCostBasisSectionWithPercentiles(list, title),
|
||||
...createGroupedActivitySectionWithAdjusted(list, title),
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -87,10 +88,10 @@ export function createCohortFolderFull(ctx, args) {
|
||||
name: args.name || "all",
|
||||
tree: [
|
||||
createSingleSupplyChart(ctx, args, title),
|
||||
createSingleUtxoCountChart(ctx, args, title),
|
||||
createSingleUtxoCountChart(args, title),
|
||||
createSingleRealizedSectionWithAdjusted(ctx, args, title),
|
||||
createSingleUnrealizedSectionFull(ctx, args, title),
|
||||
createSingleCostBasisSectionWithPercentiles(ctx, args, title),
|
||||
createSingleCostBasisSectionWithPercentiles(args, title),
|
||||
...createSingleActivitySectionWithAdjusted(ctx, args, title),
|
||||
],
|
||||
};
|
||||
@@ -110,11 +111,11 @@ export function createCohortFolderWithAdjusted(ctx, args) {
|
||||
name: args.name || "all",
|
||||
tree: [
|
||||
createGroupedSupplySection(ctx, list, title),
|
||||
createGroupedUtxoCountChart(ctx, list, title),
|
||||
createGroupedUtxoCountChart(list, title),
|
||||
createGroupedRealizedSectionWithAdjusted(ctx, list, title),
|
||||
createGroupedUnrealizedSectionWithMarketCap(ctx, list, title),
|
||||
createGroupedCostBasisSection(ctx, list, title),
|
||||
...createGroupedActivitySectionWithAdjusted(ctx, list, title),
|
||||
createGroupedCostBasisSection(list, title),
|
||||
...createGroupedActivitySectionWithAdjusted(list, title),
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -123,10 +124,10 @@ export function createCohortFolderWithAdjusted(ctx, args) {
|
||||
name: args.name || "all",
|
||||
tree: [
|
||||
createSingleSupplyChart(ctx, args, title),
|
||||
createSingleUtxoCountChart(ctx, args, title),
|
||||
createSingleUtxoCountChart(args, title),
|
||||
createSingleRealizedSectionWithAdjusted(ctx, args, title),
|
||||
createSingleUnrealizedSectionWithMarketCap(ctx, args, title),
|
||||
createSingleCostBasisSection(ctx, args, title),
|
||||
createSingleCostBasisSection(args, title),
|
||||
...createSingleActivitySectionWithAdjusted(ctx, args, title),
|
||||
],
|
||||
};
|
||||
@@ -146,11 +147,11 @@ export function createCohortFolderWithPercentiles(ctx, args) {
|
||||
name: args.name || "all",
|
||||
tree: [
|
||||
createGroupedSupplySection(ctx, list, title),
|
||||
createGroupedUtxoCountChart(ctx, list, title),
|
||||
createGroupedUtxoCountChart(list, title),
|
||||
createGroupedRealizedSectionBasic(ctx, list, title),
|
||||
createGroupedUnrealizedSectionWithOwnCaps(ctx, list, title),
|
||||
createGroupedCostBasisSectionWithPercentiles(ctx, list, title),
|
||||
...createGroupedActivitySectionBasic(ctx, list, title),
|
||||
createGroupedCostBasisSectionWithPercentiles(list, title),
|
||||
...createGroupedActivitySectionBasic(list, title),
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -159,10 +160,10 @@ export function createCohortFolderWithPercentiles(ctx, args) {
|
||||
name: args.name || "all",
|
||||
tree: [
|
||||
createSingleSupplyChart(ctx, args, title),
|
||||
createSingleUtxoCountChart(ctx, args, title),
|
||||
createSingleUtxoCountChart(args, title),
|
||||
createSingleRealizedSectionBasic(ctx, args, title),
|
||||
createSingleUnrealizedSectionWithOwnCaps(ctx, args, title),
|
||||
createSingleCostBasisSectionWithPercentiles(ctx, args, title),
|
||||
createSingleCostBasisSectionWithPercentiles(args, title),
|
||||
...createSingleActivitySectionBasic(ctx, args, title),
|
||||
],
|
||||
};
|
||||
@@ -182,11 +183,11 @@ export function createCohortFolderBasic(ctx, args) {
|
||||
name: args.name || "all",
|
||||
tree: [
|
||||
createGroupedSupplySection(ctx, list, title),
|
||||
createGroupedUtxoCountChart(ctx, list, title),
|
||||
createGroupedUtxoCountChart(list, title),
|
||||
createGroupedRealizedSectionBasic(ctx, list, title),
|
||||
createGroupedUnrealizedSectionBase(ctx, list, title),
|
||||
createGroupedCostBasisSection(ctx, list, title),
|
||||
...createGroupedActivitySectionBasic(ctx, list, title),
|
||||
createGroupedCostBasisSection(list, title),
|
||||
...createGroupedActivitySectionBasic(list, title),
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -195,10 +196,10 @@ export function createCohortFolderBasic(ctx, args) {
|
||||
name: args.name || "all",
|
||||
tree: [
|
||||
createSingleSupplyChart(ctx, args, title),
|
||||
createSingleUtxoCountChart(ctx, args, title),
|
||||
createSingleUtxoCountChart(args, title),
|
||||
createSingleRealizedSectionBasic(ctx, args, title),
|
||||
createSingleUnrealizedSectionBase(ctx, args, title),
|
||||
createSingleCostBasisSection(ctx, args, title),
|
||||
createSingleCostBasisSection(args, title),
|
||||
...createSingleActivitySectionBasic(ctx, args, title),
|
||||
],
|
||||
};
|
||||
@@ -238,12 +239,12 @@ function createGroupedSupplySection(ctx, list, title) {
|
||||
{
|
||||
name: "in profit",
|
||||
title: `Supply In Profit ${title}`,
|
||||
bottom: createGroupedSupplyInProfitSeries(ctx, list),
|
||||
bottom: createGroupedSupplyInProfitSeries(list),
|
||||
},
|
||||
{
|
||||
name: "in loss",
|
||||
title: `Supply In Loss ${title}`,
|
||||
bottom: createGroupedSupplyInLossSeries(ctx, list),
|
||||
bottom: createGroupedSupplyInLossSeries(list),
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -251,31 +252,29 @@ function createGroupedSupplySection(ctx, list, title) {
|
||||
|
||||
/**
|
||||
* Create UTXO count chart for single cohort
|
||||
* @param {PartialContext} ctx
|
||||
* @param {UtxoCohortObject} cohort
|
||||
* @param {string} title
|
||||
* @returns {PartialChartOption}
|
||||
*/
|
||||
function createSingleUtxoCountChart(ctx, cohort, title) {
|
||||
function createSingleUtxoCountChart(cohort, title) {
|
||||
return {
|
||||
name: "utxo count",
|
||||
title: `UTXO Count ${title}`,
|
||||
bottom: createUtxoCountSeries(ctx, [cohort], false),
|
||||
bottom: createUtxoCountSeries( [cohort], false),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create UTXO count chart for grouped cohorts
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly UtxoCohortObject[]} list
|
||||
* @param {string} title
|
||||
* @returns {PartialChartOption}
|
||||
*/
|
||||
function createGroupedUtxoCountChart(ctx, list, title) {
|
||||
function createGroupedUtxoCountChart(list, title) {
|
||||
return {
|
||||
name: "utxo count",
|
||||
title: `UTXO Count ${title}`,
|
||||
bottom: createUtxoCountSeries(ctx, list, true),
|
||||
bottom: createUtxoCountSeries( list, true),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -290,7 +289,7 @@ function createSingleRealizedSectionWithAdjusted(ctx, cohort, title) {
|
||||
return {
|
||||
name: "Realized",
|
||||
tree: [
|
||||
createSingleRealizedPriceChart(ctx, cohort, title),
|
||||
createSingleRealizedPriceChart(cohort, title),
|
||||
{
|
||||
name: "capitalization",
|
||||
title: `Realized Capitalization ${title}`,
|
||||
@@ -316,7 +315,7 @@ function createGroupedRealizedSectionWithAdjusted(ctx, list, title) {
|
||||
{
|
||||
name: "Price",
|
||||
title: `Realized Price ${title}`,
|
||||
top: createRealizedPriceSeries(ctx, list),
|
||||
top: createRealizedPriceSeries(list),
|
||||
},
|
||||
{
|
||||
name: "Ratio",
|
||||
@@ -326,7 +325,7 @@ function createGroupedRealizedSectionWithAdjusted(ctx, list, title) {
|
||||
{
|
||||
name: "capitalization",
|
||||
title: `Realized Capitalization ${title}`,
|
||||
bottom: createGroupedRealizedCapSeries(ctx, list),
|
||||
bottom: createGroupedRealizedCapSeries(list),
|
||||
},
|
||||
...createGroupedRealizedPnlSections(ctx, list, title),
|
||||
createGroupedSoprSectionWithAdjusted(ctx, list, title),
|
||||
@@ -345,7 +344,7 @@ function createSingleRealizedSectionBasic(ctx, cohort, title) {
|
||||
return {
|
||||
name: "Realized",
|
||||
tree: [
|
||||
createSingleRealizedPriceChart(ctx, cohort, title),
|
||||
createSingleRealizedPriceChart(cohort, title),
|
||||
{
|
||||
name: "capitalization",
|
||||
title: `Realized Capitalization ${title}`,
|
||||
@@ -371,7 +370,7 @@ function createGroupedRealizedSectionBasic(ctx, list, title) {
|
||||
{
|
||||
name: "Price",
|
||||
title: `Realized Price ${title}`,
|
||||
top: createRealizedPriceSeries(ctx, list),
|
||||
top: createRealizedPriceSeries(list),
|
||||
},
|
||||
{
|
||||
name: "Ratio",
|
||||
@@ -381,7 +380,7 @@ function createGroupedRealizedSectionBasic(ctx, list, title) {
|
||||
{
|
||||
name: "capitalization",
|
||||
title: `Realized Capitalization ${title}`,
|
||||
bottom: createGroupedRealizedCapSeries(ctx, list),
|
||||
bottom: createGroupedRealizedCapSeries(list),
|
||||
},
|
||||
...createGroupedRealizedPnlSections(ctx, list, title),
|
||||
createGroupedSoprSectionBasic(ctx, list, title),
|
||||
@@ -391,14 +390,12 @@ function createGroupedRealizedSectionBasic(ctx, list, title) {
|
||||
|
||||
/**
|
||||
* Create realized price chart for single cohort
|
||||
* @param {PartialContext} ctx
|
||||
* @param {UtxoCohortObject} cohort
|
||||
* @param {string} title
|
||||
* @returns {PartialChartOption}
|
||||
*/
|
||||
function createSingleRealizedPriceChart(ctx, cohort, title) {
|
||||
const { line } = ctx;
|
||||
const { tree, color } = cohort;
|
||||
function createSingleRealizedPriceChart(cohort, title) {
|
||||
const { tree, color } = cohort;
|
||||
|
||||
return {
|
||||
name: "price",
|
||||
@@ -421,7 +418,7 @@ function createSingleRealizedPriceChart(ctx, cohort, title) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
function createSingleRealizedCapSeries(ctx, cohort) {
|
||||
const { colors, line, baseline, createPriceLine } = ctx;
|
||||
const { colors, createPriceLine } = ctx;
|
||||
const { color, tree } = cohort;
|
||||
|
||||
return [
|
||||
@@ -459,13 +456,10 @@ function createSingleRealizedCapSeries(ctx, cohort) {
|
||||
|
||||
/**
|
||||
* Create realized cap series for grouped cohorts
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly UtxoCohortObject[]} list
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
function createGroupedRealizedCapSeries(ctx, list) {
|
||||
const { line } = ctx;
|
||||
|
||||
function createGroupedRealizedCapSeries(list) {
|
||||
return list.map(({ color, name, tree }) =>
|
||||
line({
|
||||
metric: tree.realized.realizedCap,
|
||||
@@ -486,8 +480,6 @@ function createGroupedRealizedCapSeries(ctx, list) {
|
||||
function createSingleRealizedPnlSection(ctx, cohort, title) {
|
||||
const {
|
||||
colors,
|
||||
line,
|
||||
baseline,
|
||||
createPriceLine,
|
||||
fromBlockCountWithUnit,
|
||||
fromBitcoinPatternWithUnit,
|
||||
@@ -598,7 +590,7 @@ function createSingleRealizedPnlSection(ctx, cohort, title) {
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createGroupedRealizedPnlSections(ctx, list, title) {
|
||||
const { line, baseline, createPriceLine } = ctx;
|
||||
const { createPriceLine } = ctx;
|
||||
|
||||
return [
|
||||
{
|
||||
@@ -795,7 +787,7 @@ function createGroupedRealizedPnlSections(ctx, list, title) {
|
||||
* @returns {PartialChartOption}
|
||||
*/
|
||||
function createSingleBaseSoprChart(ctx, cohort, title) {
|
||||
const { colors, baseline, createPriceLine } = ctx;
|
||||
const { colors, createPriceLine } = ctx;
|
||||
const { tree } = cohort;
|
||||
|
||||
return {
|
||||
@@ -837,7 +829,7 @@ function createSingleBaseSoprChart(ctx, cohort, title) {
|
||||
* @returns {PartialChartOption}
|
||||
*/
|
||||
function createSingleAdjustedSoprChart(ctx, cohort, title) {
|
||||
const { colors, baseline, createPriceLine } = ctx;
|
||||
const { colors, createPriceLine } = ctx;
|
||||
const { tree } = cohort;
|
||||
|
||||
return {
|
||||
@@ -880,7 +872,7 @@ function createSingleAdjustedSoprChart(ctx, cohort, title) {
|
||||
* @returns {PartialChartOption}
|
||||
*/
|
||||
function createGroupedBaseSoprChart(ctx, list, title) {
|
||||
const { baseline, createPriceLine } = ctx;
|
||||
const { createPriceLine } = ctx;
|
||||
|
||||
return {
|
||||
name: "Normal",
|
||||
@@ -924,7 +916,7 @@ function createGroupedBaseSoprChart(ctx, list, title) {
|
||||
* @returns {PartialChartOption}
|
||||
*/
|
||||
function createGroupedAdjustedSoprChart(ctx, list, title) {
|
||||
const { baseline, createPriceLine } = ctx;
|
||||
const { createPriceLine } = ctx;
|
||||
|
||||
return {
|
||||
name: "Adjusted",
|
||||
@@ -1035,7 +1027,7 @@ function createGroupedSoprSectionBasic(ctx, list, title) {
|
||||
* @param {RelativeWithMarketCap} rel
|
||||
*/
|
||||
function createUnrealizedPnlRelToMarketCapMetrics(ctx, rel) {
|
||||
const { colors, line } = ctx;
|
||||
const { colors } = ctx;
|
||||
return [
|
||||
line({
|
||||
metric: rel.unrealizedProfitRelToMarketCap,
|
||||
@@ -1064,7 +1056,7 @@ function createUnrealizedPnlRelToMarketCapMetrics(ctx, rel) {
|
||||
* @param {RelativeWithOwnMarketCap} rel
|
||||
*/
|
||||
function createUnrealizedPnlRelToOwnMarketCapMetrics(ctx, rel) {
|
||||
const { colors, line, createPriceLine } = ctx;
|
||||
const { colors, createPriceLine } = ctx;
|
||||
return [
|
||||
line({
|
||||
metric: rel.unrealizedProfitRelToOwnMarketCap,
|
||||
@@ -1095,7 +1087,7 @@ function createUnrealizedPnlRelToOwnMarketCapMetrics(ctx, rel) {
|
||||
* @param {RelativeWithOwnPnl} rel
|
||||
*/
|
||||
function createUnrealizedPnlRelToOwnPnlMetrics(ctx, rel) {
|
||||
const { colors, line, createPriceLine } = ctx;
|
||||
const { colors, createPriceLine } = ctx;
|
||||
return [
|
||||
line({
|
||||
metric: rel.unrealizedProfitRelToOwnTotalUnrealizedPnl,
|
||||
@@ -1122,12 +1114,10 @@ function createUnrealizedPnlRelToOwnPnlMetrics(ctx, rel) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PartialContext} ctx
|
||||
* @param {RelativeWithMarketCap} rel
|
||||
*/
|
||||
function createNetUnrealizedPnlRelToMarketCapMetrics(ctx, rel) {
|
||||
const { baseline } = ctx;
|
||||
return [
|
||||
function createNetUnrealizedPnlRelToMarketCapMetrics(rel) {
|
||||
return [
|
||||
baseline({
|
||||
metric: rel.netUnrealizedPnlRelToMarketCap,
|
||||
name: "Net",
|
||||
@@ -1141,7 +1131,7 @@ function createNetUnrealizedPnlRelToMarketCapMetrics(ctx, rel) {
|
||||
* @param {RelativeWithOwnMarketCap} rel
|
||||
*/
|
||||
function createNetUnrealizedPnlRelToOwnMarketCapMetrics(ctx, rel) {
|
||||
const { baseline, createPriceLine } = ctx;
|
||||
const { createPriceLine } = ctx;
|
||||
return [
|
||||
baseline({
|
||||
metric: rel.netUnrealizedPnlRelToOwnMarketCap,
|
||||
@@ -1157,7 +1147,7 @@ function createNetUnrealizedPnlRelToOwnMarketCapMetrics(ctx, rel) {
|
||||
* @param {RelativeWithOwnPnl} rel
|
||||
*/
|
||||
function createNetUnrealizedPnlRelToOwnPnlMetrics(ctx, rel) {
|
||||
const { baseline, createPriceLine } = ctx;
|
||||
const { createPriceLine } = ctx;
|
||||
return [
|
||||
baseline({
|
||||
metric: rel.netUnrealizedPnlRelToOwnTotalUnrealizedPnl,
|
||||
@@ -1174,7 +1164,7 @@ function createNetUnrealizedPnlRelToOwnPnlMetrics(ctx, rel) {
|
||||
* @param {{ unrealized: { totalUnrealizedPnl: AnyMetricPattern, unrealizedProfit: AnyMetricPattern, unrealizedLoss: AnyMetricPattern, negUnrealizedLoss: AnyMetricPattern } }} tree
|
||||
*/
|
||||
function createUnrealizedPnlBaseMetrics(ctx, tree) {
|
||||
const { colors, line } = ctx;
|
||||
const { colors } = ctx;
|
||||
return [
|
||||
line({
|
||||
metric: tree.unrealized.totalUnrealizedPnl,
|
||||
@@ -1206,12 +1196,10 @@ function createUnrealizedPnlBaseMetrics(ctx, tree) {
|
||||
|
||||
/**
|
||||
* Base net unrealized metric (always present)
|
||||
* @param {PartialContext} ctx
|
||||
* @param {{ unrealized: { netUnrealizedPnl: AnyMetricPattern } }} tree
|
||||
*/
|
||||
function createNetUnrealizedPnlBaseMetric(ctx, tree) {
|
||||
const { baseline } = ctx;
|
||||
return baseline({
|
||||
function createNetUnrealizedPnlBaseMetric(tree) {
|
||||
return baseline({
|
||||
metric: tree.unrealized.netUnrealizedPnl,
|
||||
name: "Net",
|
||||
unit: Unit.ratio,
|
||||
@@ -1249,7 +1237,7 @@ function createSingleUnrealizedSectionAll(ctx, cohort, title) {
|
||||
name: "Net pnl",
|
||||
title: `Net Unrealized Profit And Loss ${title}`,
|
||||
bottom: [
|
||||
createNetUnrealizedPnlBaseMetric(ctx, tree),
|
||||
createNetUnrealizedPnlBaseMetric(tree),
|
||||
...createNetUnrealizedPnlRelToOwnPnlMetrics(ctx, tree.relative),
|
||||
createPriceLine({ unit: Unit.usd }),
|
||||
],
|
||||
@@ -1287,8 +1275,8 @@ function createSingleUnrealizedSectionFull(ctx, cohort, title) {
|
||||
name: "Net pnl",
|
||||
title: `Net Unrealized Profit And Loss ${title}`,
|
||||
bottom: [
|
||||
createNetUnrealizedPnlBaseMetric(ctx, tree),
|
||||
...createNetUnrealizedPnlRelToMarketCapMetrics(ctx, tree.relative),
|
||||
createNetUnrealizedPnlBaseMetric(tree),
|
||||
...createNetUnrealizedPnlRelToMarketCapMetrics(tree.relative),
|
||||
...createNetUnrealizedPnlRelToOwnMarketCapMetrics(ctx, tree.relative),
|
||||
...createNetUnrealizedPnlRelToOwnPnlMetrics(ctx, tree.relative),
|
||||
createPriceLine({ unit: Unit.usd }),
|
||||
@@ -1326,8 +1314,8 @@ function createSingleUnrealizedSectionWithMarketCap(ctx, cohort, title) {
|
||||
name: "Net pnl",
|
||||
title: `Net Unrealized Profit And Loss ${title}`,
|
||||
bottom: [
|
||||
createNetUnrealizedPnlBaseMetric(ctx, tree),
|
||||
...createNetUnrealizedPnlRelToMarketCapMetrics(ctx, tree.relative),
|
||||
createNetUnrealizedPnlBaseMetric(tree),
|
||||
...createNetUnrealizedPnlRelToMarketCapMetrics(tree.relative),
|
||||
createPriceLine({ unit: Unit.usd }),
|
||||
createPriceLine({ unit: Unit.pctMcap }),
|
||||
],
|
||||
@@ -1364,7 +1352,7 @@ function createSingleUnrealizedSectionWithOwnCaps(ctx, cohort, title) {
|
||||
name: "Net pnl",
|
||||
title: `Net Unrealized Profit And Loss ${title}`,
|
||||
bottom: [
|
||||
createNetUnrealizedPnlBaseMetric(ctx, tree),
|
||||
createNetUnrealizedPnlBaseMetric(tree),
|
||||
...createNetUnrealizedPnlRelToOwnMarketCapMetrics(ctx, tree.relative),
|
||||
...createNetUnrealizedPnlRelToOwnPnlMetrics(ctx, tree.relative),
|
||||
createPriceLine({ unit: Unit.usd }),
|
||||
@@ -1400,7 +1388,7 @@ function createSingleUnrealizedSectionBase(ctx, cohort, title) {
|
||||
name: "Net pnl",
|
||||
title: `Net Unrealized Profit And Loss ${title}`,
|
||||
bottom: [
|
||||
createNetUnrealizedPnlBaseMetric(ctx, tree),
|
||||
createNetUnrealizedPnlBaseMetric(tree),
|
||||
createPriceLine({ unit: Unit.usd }),
|
||||
],
|
||||
},
|
||||
@@ -1410,13 +1398,11 @@ function createSingleUnrealizedSectionBase(ctx, cohort, title) {
|
||||
|
||||
/**
|
||||
* Grouped unrealized base charts (profit, loss, total pnl)
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly { color: Color, name: string, tree: { unrealized: PatternAll["unrealized"] } }[]} list
|
||||
* @param {string} title
|
||||
*/
|
||||
function createGroupedUnrealizedBaseCharts(ctx, list, title) {
|
||||
const { line } = ctx;
|
||||
return [
|
||||
function createGroupedUnrealizedBaseCharts(list, title) {
|
||||
return [
|
||||
{
|
||||
name: "profit",
|
||||
title: `Unrealized Profit ${title}`,
|
||||
@@ -1464,11 +1450,11 @@ function createGroupedUnrealizedBaseCharts(ctx, list, title) {
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
function createGroupedUnrealizedSectionFull(ctx, list, title) {
|
||||
const { baseline, createPriceLine } = ctx;
|
||||
const { createPriceLine } = ctx;
|
||||
return {
|
||||
name: "Unrealized",
|
||||
tree: [
|
||||
...createGroupedUnrealizedBaseCharts(ctx, list, title),
|
||||
...createGroupedUnrealizedBaseCharts(list, title),
|
||||
{
|
||||
name: "Net pnl",
|
||||
title: `Net Unrealized Profit And Loss ${title}`,
|
||||
@@ -1517,11 +1503,11 @@ function createGroupedUnrealizedSectionFull(ctx, list, title) {
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
function createGroupedUnrealizedSectionWithMarketCap(ctx, list, title) {
|
||||
const { baseline, createPriceLine } = ctx;
|
||||
const { createPriceLine } = ctx;
|
||||
return {
|
||||
name: "Unrealized",
|
||||
tree: [
|
||||
...createGroupedUnrealizedBaseCharts(ctx, list, title),
|
||||
...createGroupedUnrealizedBaseCharts(list, title),
|
||||
{
|
||||
name: "Net pnl",
|
||||
title: `Net Unrealized Profit And Loss ${title}`,
|
||||
@@ -1556,11 +1542,11 @@ function createGroupedUnrealizedSectionWithMarketCap(ctx, list, title) {
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
function createGroupedUnrealizedSectionWithOwnCaps(ctx, list, title) {
|
||||
const { baseline, createPriceLine } = ctx;
|
||||
const { createPriceLine } = ctx;
|
||||
return {
|
||||
name: "Unrealized",
|
||||
tree: [
|
||||
...createGroupedUnrealizedBaseCharts(ctx, list, title),
|
||||
...createGroupedUnrealizedBaseCharts(list, title),
|
||||
{
|
||||
name: "Net pnl",
|
||||
title: `Net Unrealized Profit And Loss ${title}`,
|
||||
@@ -1602,11 +1588,11 @@ function createGroupedUnrealizedSectionWithOwnCaps(ctx, list, title) {
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
function createGroupedUnrealizedSectionBase(ctx, list, title) {
|
||||
const { baseline, createPriceLine } = ctx;
|
||||
const { createPriceLine } = ctx;
|
||||
return {
|
||||
name: "Unrealized",
|
||||
tree: [
|
||||
...createGroupedUnrealizedBaseCharts(ctx, list, title),
|
||||
...createGroupedUnrealizedBaseCharts(list, title),
|
||||
{
|
||||
name: "Net pnl",
|
||||
title: `Net Unrealized Profit And Loss ${title}`,
|
||||
@@ -1628,14 +1614,12 @@ function createGroupedUnrealizedSectionBase(ctx, list, title) {
|
||||
|
||||
/**
|
||||
* Create cost basis section for single cohort WITH percentiles
|
||||
* @param {PartialContext} ctx
|
||||
* @param {CohortAll | CohortFull | CohortWithPercentiles} cohort
|
||||
* @param {string} title
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
function createSingleCostBasisSectionWithPercentiles(ctx, cohort, title) {
|
||||
const { line } = ctx;
|
||||
const { color, tree } = cohort;
|
||||
function createSingleCostBasisSectionWithPercentiles(cohort, title) {
|
||||
const { color, tree } = cohort;
|
||||
|
||||
return {
|
||||
name: "Cost Basis",
|
||||
@@ -1668,7 +1652,7 @@ function createSingleCostBasisSectionWithPercentiles(ctx, cohort, title) {
|
||||
{
|
||||
name: "percentiles",
|
||||
title: `Cost Basis Percentiles ${title}`,
|
||||
top: createCostBasisPercentilesSeries(ctx, [cohort], false),
|
||||
top: createCostBasisPercentilesSeries( [cohort], false),
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1676,14 +1660,11 @@ function createSingleCostBasisSectionWithPercentiles(ctx, cohort, title) {
|
||||
|
||||
/**
|
||||
* Create cost basis section for grouped cohorts WITH percentiles
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly (CohortFull | CohortWithPercentiles)[]} list
|
||||
* @param {string} title
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
function createGroupedCostBasisSectionWithPercentiles(ctx, list, title) {
|
||||
const { line } = ctx;
|
||||
|
||||
function createGroupedCostBasisSectionWithPercentiles(list, title) {
|
||||
return {
|
||||
name: "Cost Basis",
|
||||
tree: [
|
||||
@@ -1719,14 +1700,12 @@ function createGroupedCostBasisSectionWithPercentiles(ctx, list, title) {
|
||||
|
||||
/**
|
||||
* Create cost basis section for single cohort (no percentiles)
|
||||
* @param {PartialContext} ctx
|
||||
* @param {CohortWithAdjusted | CohortBasic} cohort
|
||||
* @param {string} title
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
function createSingleCostBasisSection(ctx, cohort, title) {
|
||||
const { line } = ctx;
|
||||
const { color, tree } = cohort;
|
||||
function createSingleCostBasisSection(cohort, title) {
|
||||
const { color, tree } = cohort;
|
||||
|
||||
return {
|
||||
name: "Cost Basis",
|
||||
@@ -1762,14 +1741,11 @@ function createSingleCostBasisSection(ctx, cohort, title) {
|
||||
|
||||
/**
|
||||
* Create cost basis section for grouped cohorts (no percentiles)
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly (CohortWithAdjusted | CohortBasic)[]} list
|
||||
* @param {string} title
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
function createGroupedCostBasisSection(ctx, list, title) {
|
||||
const { line } = ctx;
|
||||
|
||||
function createGroupedCostBasisSection(list, title) {
|
||||
return {
|
||||
name: "Cost Basis",
|
||||
tree: [
|
||||
@@ -1811,7 +1787,7 @@ function createGroupedCostBasisSection(ctx, list, title) {
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createSingleActivitySectionWithAdjusted(ctx, cohort, title) {
|
||||
const { colors, line } = ctx;
|
||||
const { colors } = ctx;
|
||||
const { tree, color } = cohort;
|
||||
|
||||
return [
|
||||
@@ -1925,7 +1901,7 @@ function createSingleActivitySectionWithAdjusted(ctx, cohort, title) {
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createSingleActivitySectionBasic(ctx, cohort, title) {
|
||||
const { colors, line } = ctx;
|
||||
const { colors } = ctx;
|
||||
const { tree, color } = cohort;
|
||||
|
||||
return [
|
||||
@@ -2021,14 +1997,11 @@ function createSingleActivitySectionBasic(ctx, cohort, title) {
|
||||
|
||||
/**
|
||||
* Create activity section for grouped cohorts with adjusted values (for cohorts with RealizedPattern3/4)
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly (CohortFull | CohortWithAdjusted)[]} list
|
||||
* @param {string} title
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createGroupedActivitySectionWithAdjusted(ctx, list, title) {
|
||||
const { line } = ctx;
|
||||
|
||||
function createGroupedActivitySectionWithAdjusted(list, title) {
|
||||
return [
|
||||
{
|
||||
name: "Sell Side Risk",
|
||||
@@ -2151,14 +2124,11 @@ function createGroupedActivitySectionWithAdjusted(ctx, list, title) {
|
||||
|
||||
/**
|
||||
* Create activity section for grouped cohorts without adjusted values (for cohorts with RealizedPattern/2)
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly (CohortWithPercentiles | CohortBasic)[]} list
|
||||
* @param {string} title
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createGroupedActivitySectionBasic(ctx, list, title) {
|
||||
const { line } = ctx;
|
||||
|
||||
function createGroupedActivitySectionBasic(list, title) {
|
||||
return [
|
||||
{
|
||||
name: "Sell Side Risk",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** Cointime section builder - typed tree-based patterns */
|
||||
|
||||
import { Unit } from "../utils/units.js";
|
||||
import { line, baseline } from "./series.js";
|
||||
import {
|
||||
satsBtcUsd,
|
||||
priceLines,
|
||||
@@ -25,7 +26,7 @@ function createCointimePriceWithRatioOptions(
|
||||
ctx,
|
||||
{ title, legend, price, ratio, color },
|
||||
) {
|
||||
const { line, colors, createPriceLine } = ctx;
|
||||
const { colors, createPriceLine } = ctx;
|
||||
|
||||
const pctUsdMap = percentileUsdMap(colors, ratio);
|
||||
const pctMap = percentileMap(colors, ratio);
|
||||
@@ -54,42 +55,53 @@ function createCointimePriceWithRatioOptions(
|
||||
),
|
||||
],
|
||||
bottom: [
|
||||
line({ metric: ratio.ratio, name: "Ratio", color, unit: Unit.ratio }),
|
||||
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({
|
||||
@@ -174,13 +186,14 @@ function createCointimePriceWithRatioOptions(
|
||||
...sdPats.map(({ nameAddon, titleAddon, sd }) => ({
|
||||
name: nameAddon,
|
||||
title: `${title} ${titleAddon} Z-Score`,
|
||||
top: sdBands(colors, sd).map(({ name: bandName, prop, color: bandColor }) =>
|
||||
line({
|
||||
metric: prop,
|
||||
name: bandName,
|
||||
color: bandColor,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
top: sdBands(colors, sd).map(
|
||||
({ name: bandName, prop, color: bandColor }) =>
|
||||
line({
|
||||
metric: prop,
|
||||
name: bandName,
|
||||
color: bandColor,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
),
|
||||
bottom: [
|
||||
line({ metric: sd.zscore, name: "Z-Score", color, unit: Unit.sd }),
|
||||
@@ -198,7 +211,7 @@ function createCointimePriceWithRatioOptions(
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
export function createCointimeSection(ctx) {
|
||||
const { colors, brk, line } = ctx;
|
||||
const { colors, brk } = ctx;
|
||||
const { cointime, distribution, supply } = brk.metrics;
|
||||
const { pricing, cap, activity, supply: cointimeSupply, adjusted } = cointime;
|
||||
const { all } = distribution.utxoCohorts;
|
||||
@@ -348,9 +361,17 @@ export function createCointimeSection(ctx) {
|
||||
name: "Supply",
|
||||
title: "Cointime Supply",
|
||||
bottom: [
|
||||
...satsBtcUsd(ctx, all.supply.total, "All", colors.orange),
|
||||
...satsBtcUsd(ctx, cointimeSupply.vaultedSupply, "Vaulted", colors.lime),
|
||||
...satsBtcUsd(ctx, cointimeSupply.activeSupply, "Active", colors.rose),
|
||||
...satsBtcUsd( all.supply.total, "All", colors.orange),
|
||||
...satsBtcUsd(
|
||||
cointimeSupply.vaultedSupply,
|
||||
"Vaulted",
|
||||
colors.lime,
|
||||
),
|
||||
...satsBtcUsd(
|
||||
cointimeSupply.activeSupply,
|
||||
"Active",
|
||||
colors.rose,
|
||||
),
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
import {
|
||||
line,
|
||||
dots,
|
||||
candlestick,
|
||||
baseline,
|
||||
histogram,
|
||||
fromBlockCount,
|
||||
fromBitcoin,
|
||||
fromBlockSize,
|
||||
@@ -37,12 +32,6 @@ export function createContext({ colors, brk }) {
|
||||
colors,
|
||||
brk,
|
||||
|
||||
// Series helpers
|
||||
line,
|
||||
dots,
|
||||
candlestick,
|
||||
baseline,
|
||||
histogram,
|
||||
fromBlockCount: (pattern, title, color) =>
|
||||
fromBlockCount(colors, pattern, title, color),
|
||||
fromBitcoin: (pattern, title, color) =>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** Moving averages section */
|
||||
|
||||
import { Unit } from "../../utils/units.js";
|
||||
import { line, baseline } from "../series.js";
|
||||
import {
|
||||
priceLines,
|
||||
percentileUsdMap,
|
||||
@@ -55,7 +56,7 @@ export function createPriceWithRatioOptions(
|
||||
ctx,
|
||||
{ title, legend, ratio, color },
|
||||
) {
|
||||
const { line, colors, createPriceLine } = ctx;
|
||||
const { colors, createPriceLine } = ctx;
|
||||
const priceMetric = ratio.price;
|
||||
|
||||
const pctUsdMap = percentileUsdMap(colors, ratio);
|
||||
@@ -85,42 +86,54 @@ export function createPriceWithRatioOptions(
|
||||
),
|
||||
],
|
||||
bottom: [
|
||||
line({ metric: ratio.ratio, name: "Ratio", color, unit: Unit.ratio }),
|
||||
baseline({
|
||||
metric: ratio.ratio,
|
||||
name: "Ratio",
|
||||
base: 1,
|
||||
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({
|
||||
@@ -140,13 +153,14 @@ export function createPriceWithRatioOptions(
|
||||
tree: sdPats.map(({ nameAddon, titleAddon, sd }) => ({
|
||||
name: nameAddon,
|
||||
title: `${title} ${titleAddon} Z-Score`,
|
||||
top: sdBands(colors, sd).map(({ name: bandName, prop, color: bandColor }) =>
|
||||
line({
|
||||
metric: prop,
|
||||
name: bandName,
|
||||
color: bandColor,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
top: sdBands(colors, sd).map(
|
||||
({ name: bandName, prop, color: bandColor }) =>
|
||||
line({
|
||||
metric: prop,
|
||||
name: bandName,
|
||||
color: bandColor,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
),
|
||||
bottom: [
|
||||
line({ metric: sd.zscore, name: "Z-Score", color, unit: Unit.sd }),
|
||||
@@ -163,8 +177,7 @@ export function createPriceWithRatioOptions(
|
||||
* @param {ReturnType<typeof buildAverages>} averages
|
||||
*/
|
||||
export function createAveragesSection(ctx, averages) {
|
||||
const { line } = ctx;
|
||||
|
||||
|
||||
return {
|
||||
name: "Averages",
|
||||
tree: [
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { localhost } from "../../utils/env.js";
|
||||
import { Unit } from "../../utils/units.js";
|
||||
import { line } from "../series.js";
|
||||
import { buildAverages, createAveragesSection } from "./averages.js";
|
||||
import { createPerformanceSection } from "./performance.js";
|
||||
import { createIndicatorsSection } from "./indicators/index.js";
|
||||
@@ -13,7 +14,7 @@ import { createInvestingSection } from "./investing.js";
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
export function createMarketSection(ctx) {
|
||||
const { colors, brk, line } = ctx;
|
||||
const { colors, brk } = ctx;
|
||||
const { market, supply, price } = brk.metrics;
|
||||
const {
|
||||
movingAverage,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** Bands indicators (MinMax, Mayer Multiple) */
|
||||
|
||||
import { Unit } from "../../../utils/units.js";
|
||||
import { line } from "../../series.js";
|
||||
|
||||
/**
|
||||
* Create Bands section
|
||||
@@ -10,7 +11,7 @@ import { Unit } from "../../../utils/units.js";
|
||||
* @param {Market["movingAverage"]} args.movingAverage
|
||||
*/
|
||||
export function createBandsSection(ctx, { range, movingAverage }) {
|
||||
const { line, colors } = ctx;
|
||||
const { colors } = ctx;
|
||||
|
||||
return {
|
||||
name: "Bands",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** Momentum indicators (RSI, StochRSI, Stochastic, MACD) */
|
||||
|
||||
import { Unit } from "../../../utils/units.js";
|
||||
import { line, histogram } from "../../series.js";
|
||||
|
||||
/**
|
||||
* Create Momentum section
|
||||
@@ -8,7 +9,7 @@ import { Unit } from "../../../utils/units.js";
|
||||
* @param {Market["indicators"]} indicators
|
||||
*/
|
||||
export function createMomentumSection(ctx, indicators) {
|
||||
const { line, histogram, colors, createPriceLine } = ctx;
|
||||
const { colors, createPriceLine } = ctx;
|
||||
|
||||
return {
|
||||
name: "Momentum",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** On-chain indicators (Pi Cycle, Puell, NVT, Gini) */
|
||||
|
||||
import { Unit } from "../../../utils/units.js";
|
||||
import { line } from "../../series.js";
|
||||
|
||||
/**
|
||||
* Create On-chain section
|
||||
@@ -10,7 +11,7 @@ import { Unit } from "../../../utils/units.js";
|
||||
* @param {Market["movingAverage"]} args.movingAverage
|
||||
*/
|
||||
export function createOnchainSection(ctx, { indicators, movingAverage }) {
|
||||
const { line, colors, createPriceLine } = ctx;
|
||||
const { colors, createPriceLine } = ctx;
|
||||
|
||||
return {
|
||||
name: "On-chain",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** Volatility indicators (Index, True Range, Choppiness, Sharpe, Sortino) */
|
||||
|
||||
import { Unit } from "../../../utils/units.js";
|
||||
import { line } from "../../series.js";
|
||||
|
||||
/**
|
||||
* Create Volatility section
|
||||
@@ -10,7 +11,7 @@ import { Unit } from "../../../utils/units.js";
|
||||
* @param {Market["range"]} args.range
|
||||
*/
|
||||
export function createVolatilitySection(ctx, { volatility, range }) {
|
||||
const { line, colors, createPriceLine } = ctx;
|
||||
const { colors, createPriceLine } = ctx;
|
||||
|
||||
return {
|
||||
name: "Volatility",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** Investing section (DCA) */
|
||||
|
||||
import { Unit } from "../../utils/units.js";
|
||||
import { line, baseline } from "../series.js";
|
||||
import { satsBtcUsd } from "../shared.js";
|
||||
import { periodIdToName } from "./utils.js";
|
||||
|
||||
@@ -41,7 +42,7 @@ export function buildDcaClasses(colors, dca) {
|
||||
* @param {Market["returns"]} args.returns
|
||||
*/
|
||||
export function createInvestingSection(ctx, { dca, lookback, returns }) {
|
||||
const { line, baseline, colors, createPriceLine } = ctx;
|
||||
const { colors, createPriceLine } = ctx;
|
||||
const dcaClasses = buildDcaClasses(colors, dca);
|
||||
|
||||
return {
|
||||
@@ -114,8 +115,8 @@ export function createInvestingSection(ctx, { dca, lookback, returns }) {
|
||||
name: "Stack",
|
||||
title: `${name} DCA vs Lump Sum Stack ($100/day)`,
|
||||
bottom: [
|
||||
...satsBtcUsd(ctx, dcaStack, "DCA", colors.green),
|
||||
...satsBtcUsd(ctx, lumpSumStack, "Lump sum", colors.orange),
|
||||
...satsBtcUsd( dcaStack, "DCA", colors.green),
|
||||
...satsBtcUsd( lumpSumStack, "Lump sum", colors.orange),
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -164,7 +165,7 @@ export function createInvestingSection(ctx, { dca, lookback, returns }) {
|
||||
title: "DCA Stack by Year ($100/day)",
|
||||
bottom: dcaClasses.flatMap(
|
||||
({ year, color, defaultActive, stack }) =>
|
||||
satsBtcUsd(ctx, stack, `${year}`, color, { defaultActive }),
|
||||
satsBtcUsd( stack, `${year}`, color, { defaultActive }),
|
||||
),
|
||||
},
|
||||
],
|
||||
@@ -200,7 +201,7 @@ export function createInvestingSection(ctx, { dca, lookback, returns }) {
|
||||
{
|
||||
name: "Stack",
|
||||
title: `DCA Class ${year} Stack ($100/day)`,
|
||||
bottom: satsBtcUsd(ctx, stack, "Stack", color),
|
||||
bottom: satsBtcUsd( stack, "Stack", color),
|
||||
},
|
||||
],
|
||||
})),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** Performance section */
|
||||
|
||||
import { Unit } from "../../utils/units.js";
|
||||
import { baseline } from "../series.js";
|
||||
import { periodIdToName } from "./utils.js";
|
||||
|
||||
/**
|
||||
@@ -9,7 +10,7 @@ import { periodIdToName } from "./utils.js";
|
||||
* @param {Market["returns"]} returns
|
||||
*/
|
||||
export function createPerformanceSection(ctx, returns) {
|
||||
const { colors, baseline, createPriceLine } = ctx;
|
||||
const { colors, createPriceLine } = ctx;
|
||||
|
||||
return {
|
||||
name: "Performance",
|
||||
|
||||
@@ -85,6 +85,8 @@ export function candlestick({
|
||||
* @param {Unit} args.unit
|
||||
* @param {Color | [Color, Color]} [args.color]
|
||||
* @param {boolean} [args.defaultActive]
|
||||
* @param {boolean} [args.defaultActive]
|
||||
* @param {number | undefined} [args.base]
|
||||
* @param {BaselineSeriesPartialOptions} [args.options]
|
||||
* @returns {FetchedBaselineSeriesBlueprint}
|
||||
*/
|
||||
@@ -94,6 +96,7 @@ export function baseline({
|
||||
color,
|
||||
defaultActive,
|
||||
unit,
|
||||
base,
|
||||
options,
|
||||
}) {
|
||||
const isTuple = Array.isArray(color);
|
||||
@@ -105,7 +108,12 @@ export function baseline({
|
||||
colors: isTuple ? color : undefined,
|
||||
unit,
|
||||
defaultActive,
|
||||
options,
|
||||
options: {
|
||||
baseValue: {
|
||||
price: base,
|
||||
},
|
||||
...options,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
/** Shared helpers for options */
|
||||
|
||||
import { Unit } from "../utils/units.js";
|
||||
import { line } from "./series.js";
|
||||
|
||||
/**
|
||||
* Create sats/btc/usd line series from a pattern with .sats/.bitcoin/.dollars
|
||||
* @param {PartialContext} ctx
|
||||
* @param {{ sats: AnyMetricPattern, bitcoin: AnyMetricPattern, dollars: AnyMetricPattern }} pattern
|
||||
* @param {string} name
|
||||
* @param {Color} [color]
|
||||
* @param {{ defaultActive?: boolean }} [options]
|
||||
* @returns {FetchedLineSeriesBlueprint[]}
|
||||
*/
|
||||
export function satsBtcUsd(ctx, pattern, name, color, options) {
|
||||
export function satsBtcUsd(pattern, name, color, options) {
|
||||
const { defaultActive } = options || {};
|
||||
return [
|
||||
ctx.line({ metric: pattern.sats, name, color, unit: Unit.sats, defaultActive }),
|
||||
ctx.line({ metric: pattern.bitcoin, name, color, unit: Unit.btc, defaultActive }),
|
||||
ctx.line({ metric: pattern.dollars, name, color, unit: Unit.usd, defaultActive }),
|
||||
line({ metric: pattern.sats, name, color, unit: Unit.sats, defaultActive }),
|
||||
line({ metric: pattern.bitcoin, name, color, unit: Unit.btc, defaultActive }),
|
||||
line({ metric: pattern.dollars, name, color, unit: Unit.usd, defaultActive }),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -241,11 +241,6 @@
|
||||
* @typedef {Object} PartialContext
|
||||
* @property {Colors} colors
|
||||
* @property {BrkClient} brk
|
||||
* @property {LineSeriesFn} line
|
||||
* @property {DotsSeriesFn} dots
|
||||
* @property {CandlestickSeriesFn} candlestick
|
||||
* @property {BaselineSeriesFn} baseline
|
||||
* @property {HistogramSeriesFn} histogram
|
||||
* @property {(pattern: BlockCountPattern<any>, title: string, color?: Color) => AnyFetchedSeriesBlueprint[]} fromBlockCount
|
||||
* @property {(pattern: FullnessPattern<any>, title: string, color?: Color) => AnyFetchedSeriesBlueprint[]} fromBitcoin
|
||||
* @property {(pattern: AnyStatsPattern, title: string, color?: Color) => AnyFetchedSeriesBlueprint[]} fromBlockSize
|
||||
|
||||
Reference in New Issue
Block a user