website: snapshot

This commit is contained in:
nym21
2026-01-21 14:00:31 +01:00
parent a9b2da86ff
commit 1456f47fd1
26 changed files with 353 additions and 328 deletions
+2 -4
View File
@@ -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",
+14 -22
View File
@@ -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",
+21 -39
View File
@@ -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 [
+82 -112
View File
@@ -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",
+34 -13
View File
@@ -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,
),
],
},
-11
View File
@@ -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) =>
+24 -11
View File
@@ -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 -1
View File
@@ -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",
+6 -5
View File
@@ -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",
+9 -1
View File
@@ -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,
},
};
}
+5 -5
View File
@@ -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 }),
];
}
-5
View File
@@ -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