mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-02 11:13:39 -07:00
global: snapshot
This commit is contained in:
@@ -0,0 +1 @@
|
||||
*/**/*.md
|
||||
+50
-50
@@ -1558,12 +1558,13 @@
|
||||
</script>
|
||||
|
||||
<!-- IMPORTMAP -->
|
||||
<link rel="modulepreload" href="/scripts/chart/index.02f627a6.js">
|
||||
<link rel="modulepreload" href="/scripts/chart/index.891e1546.js">
|
||||
<link rel="modulepreload" href="/scripts/chart/oklch.21450255.js">
|
||||
<link rel="modulepreload" href="/scripts/entry.10db80a8.js">
|
||||
<link rel="modulepreload" href="/scripts/entry.fe229b42.js">
|
||||
<link rel="modulepreload" href="/scripts/lazy.1ae52534.js">
|
||||
<link rel="modulepreload" href="/scripts/main.22a5bd79.js">
|
||||
<link rel="modulepreload" href="/scripts/modules/brk-client/index.922b14c3.js">
|
||||
<link rel="modulepreload" href="/scripts/modules/brk-client/index.d7a5bd12.js">
|
||||
<link rel="modulepreload" href="/scripts/modules/brk-client/test.119c2b6e.js">
|
||||
<link rel="modulepreload" href="/scripts/modules/lean-qr/2.6.1/index.09195c13.mjs">
|
||||
<link rel="modulepreload" href="/scripts/modules/leeoniya-ufuzzy/1.0.19/dist/uFuzzy.803b7fb0.mjs">
|
||||
<link rel="modulepreload" href="/scripts/modules/lightweight-charts/5.0.9/dist/lightweight-charts.standalone.production.1e264451.mjs">
|
||||
@@ -1575,33 +1576,32 @@
|
||||
<link rel="modulepreload" href="/scripts/modules/solidjs-signals/0.6.3/dist/prod.2f80e335.js">
|
||||
<link rel="modulepreload" href="/scripts/modules/solidjs-signals/0.8.5/dist/prod.8ae56250.js">
|
||||
<link rel="modulepreload" href="/scripts/options/_partial_old.62bf3faa.js">
|
||||
<link rel="modulepreload" href="/scripts/options/chain.4fe9edeb.js">
|
||||
<link rel="modulepreload" href="/scripts/options/cohorts/address.446eab82.js">
|
||||
<link rel="modulepreload" href="/scripts/options/cohorts/data.92c2a350.js">
|
||||
<link rel="modulepreload" href="/scripts/options/cohorts/index.47f11280.js">
|
||||
<link rel="modulepreload" href="/scripts/options/cohorts/shared.028a47f5.js">
|
||||
<link rel="modulepreload" href="/scripts/options/cohorts/types.1e23c94d.js">
|
||||
<link rel="modulepreload" href="/scripts/options/cohorts/utxo.90aa2b4f.js">
|
||||
<link rel="modulepreload" href="/scripts/options/cointime.d859b72a.js">
|
||||
<link rel="modulepreload" href="/scripts/options/chain.3d99e062.js">
|
||||
<link rel="modulepreload" href="/scripts/options/cohorts/address.2e8a42cb.js">
|
||||
<link rel="modulepreload" href="/scripts/options/cohorts/data.f7f24b88.js">
|
||||
<link rel="modulepreload" href="/scripts/options/cohorts/index.b0e57c9d.js">
|
||||
<link rel="modulepreload" href="/scripts/options/cohorts/shared.0602caa3.js">
|
||||
<link rel="modulepreload" href="/scripts/options/cohorts/utxo.f0e69857.js">
|
||||
<link rel="modulepreload" href="/scripts/options/cointime.a69ba0e7.js">
|
||||
<link rel="modulepreload" href="/scripts/options/colors/cohorts.262d4551.js">
|
||||
<link rel="modulepreload" href="/scripts/options/colors/index.a54dc83f.js">
|
||||
<link rel="modulepreload" href="/scripts/options/colors/misc.bee7dbee.js">
|
||||
<link rel="modulepreload" href="/scripts/options/constants.190d9d82.js">
|
||||
<link rel="modulepreload" href="/scripts/options/context.bd3985fb.js">
|
||||
<link rel="modulepreload" href="/scripts/options/constants.f5b525fe.js">
|
||||
<link rel="modulepreload" href="/scripts/options/context.85881310.js">
|
||||
<link rel="modulepreload" href="/scripts/options/full.cbb89ca5.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/averages.52ae3c62.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/index.e6011fff.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/indicators/bands.eb583383.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/averages.d95aa3e1.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/index.6896a1b5.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/indicators/bands.81b19b83.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/indicators/index.70e9b3e4.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/indicators/momentum.8f20362c.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/indicators/onchain.d06affed.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/indicators/volatility.a12b9495.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/investing.c00cb6ed.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/performance.f381010b.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/indicators/momentum.48e71442.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/indicators/onchain.f75ddfd9.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/indicators/volatility.08ec92d7.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/investing.57ded805.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/performance.36c7ad40.js">
|
||||
<link rel="modulepreload" href="/scripts/options/market/utils.e3e058d8.js">
|
||||
<link rel="modulepreload" href="/scripts/options/partial.1bfb5914.js">
|
||||
<link rel="modulepreload" href="/scripts/options/series.3702ffc7.js">
|
||||
<link rel="modulepreload" href="/scripts/options/types.19186083.js">
|
||||
<link rel="modulepreload" href="/scripts/options/partial.ab8fdf12.js">
|
||||
<link rel="modulepreload" href="/scripts/options/series.5a2a34ed.js">
|
||||
<link rel="modulepreload" href="/scripts/options/types.64db5149.js">
|
||||
<link rel="modulepreload" href="/scripts/options/unused.24a71427.js">
|
||||
<link rel="modulepreload" href="/scripts/panes/chart/index.3d231714.js">
|
||||
<link rel="modulepreload" href="/scripts/panes/chart/screenshot.adc8da89.js">
|
||||
@@ -1622,18 +1622,19 @@
|
||||
<link rel="modulepreload" href="/scripts/utils/serde.f9c7ed2b.js">
|
||||
<link rel="modulepreload" href="/scripts/utils/storage.cbd2ff9c.js">
|
||||
<link rel="modulepreload" href="/scripts/utils/timing.ae6a47b8.js">
|
||||
<link rel="modulepreload" href="/scripts/utils/units.97b1a45f.js">
|
||||
<link rel="modulepreload" href="/scripts/utils/units.30278ea7.js">
|
||||
<link rel="modulepreload" href="/scripts/utils/url.20469bf9.js">
|
||||
<link rel="modulepreload" href="/scripts/utils/ws.fe3fb4b1.js">
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"/scripts/chart/index.js": "/scripts/chart/index.02f627a6.js",
|
||||
"/scripts/chart/index.js": "/scripts/chart/index.891e1546.js",
|
||||
"/scripts/chart/oklch.js": "/scripts/chart/oklch.21450255.js",
|
||||
"/scripts/entry.js": "/scripts/entry.10db80a8.js",
|
||||
"/scripts/entry.js": "/scripts/entry.fe229b42.js",
|
||||
"/scripts/lazy.js": "/scripts/lazy.1ae52534.js",
|
||||
"/scripts/main.js": "/scripts/main.22a5bd79.js",
|
||||
"/scripts/modules/brk-client/index.js": "/scripts/modules/brk-client/index.922b14c3.js",
|
||||
"/scripts/modules/brk-client/index.js": "/scripts/modules/brk-client/index.d7a5bd12.js",
|
||||
"/scripts/modules/brk-client/test.js": "/scripts/modules/brk-client/test.119c2b6e.js",
|
||||
"/scripts/modules/lean-qr/2.6.1/index.mjs": "/scripts/modules/lean-qr/2.6.1/index.09195c13.mjs",
|
||||
"/scripts/modules/leeoniya-ufuzzy/1.0.19/dist/uFuzzy.mjs": "/scripts/modules/leeoniya-ufuzzy/1.0.19/dist/uFuzzy.803b7fb0.mjs",
|
||||
"/scripts/modules/lightweight-charts/5.0.9/dist/lightweight-charts.standalone.production.mjs": "/scripts/modules/lightweight-charts/5.0.9/dist/lightweight-charts.standalone.production.1e264451.mjs",
|
||||
@@ -1645,33 +1646,32 @@
|
||||
"/scripts/modules/solidjs-signals/0.6.3/dist/prod.js": "/scripts/modules/solidjs-signals/0.6.3/dist/prod.2f80e335.js",
|
||||
"/scripts/modules/solidjs-signals/0.8.5/dist/prod.js": "/scripts/modules/solidjs-signals/0.8.5/dist/prod.8ae56250.js",
|
||||
"/scripts/options/_partial_old.js": "/scripts/options/_partial_old.62bf3faa.js",
|
||||
"/scripts/options/chain.js": "/scripts/options/chain.4fe9edeb.js",
|
||||
"/scripts/options/cohorts/address.js": "/scripts/options/cohorts/address.446eab82.js",
|
||||
"/scripts/options/cohorts/data.js": "/scripts/options/cohorts/data.92c2a350.js",
|
||||
"/scripts/options/cohorts/index.js": "/scripts/options/cohorts/index.47f11280.js",
|
||||
"/scripts/options/cohorts/shared.js": "/scripts/options/cohorts/shared.028a47f5.js",
|
||||
"/scripts/options/cohorts/types.js": "/scripts/options/cohorts/types.1e23c94d.js",
|
||||
"/scripts/options/cohorts/utxo.js": "/scripts/options/cohorts/utxo.90aa2b4f.js",
|
||||
"/scripts/options/cointime.js": "/scripts/options/cointime.d859b72a.js",
|
||||
"/scripts/options/chain.js": "/scripts/options/chain.3d99e062.js",
|
||||
"/scripts/options/cohorts/address.js": "/scripts/options/cohorts/address.2e8a42cb.js",
|
||||
"/scripts/options/cohorts/data.js": "/scripts/options/cohorts/data.f7f24b88.js",
|
||||
"/scripts/options/cohorts/index.js": "/scripts/options/cohorts/index.b0e57c9d.js",
|
||||
"/scripts/options/cohorts/shared.js": "/scripts/options/cohorts/shared.0602caa3.js",
|
||||
"/scripts/options/cohorts/utxo.js": "/scripts/options/cohorts/utxo.f0e69857.js",
|
||||
"/scripts/options/cointime.js": "/scripts/options/cointime.a69ba0e7.js",
|
||||
"/scripts/options/colors/cohorts.js": "/scripts/options/colors/cohorts.262d4551.js",
|
||||
"/scripts/options/colors/index.js": "/scripts/options/colors/index.a54dc83f.js",
|
||||
"/scripts/options/colors/misc.js": "/scripts/options/colors/misc.bee7dbee.js",
|
||||
"/scripts/options/constants.js": "/scripts/options/constants.190d9d82.js",
|
||||
"/scripts/options/context.js": "/scripts/options/context.bd3985fb.js",
|
||||
"/scripts/options/constants.js": "/scripts/options/constants.f5b525fe.js",
|
||||
"/scripts/options/context.js": "/scripts/options/context.85881310.js",
|
||||
"/scripts/options/full.js": "/scripts/options/full.cbb89ca5.js",
|
||||
"/scripts/options/market/averages.js": "/scripts/options/market/averages.52ae3c62.js",
|
||||
"/scripts/options/market/index.js": "/scripts/options/market/index.e6011fff.js",
|
||||
"/scripts/options/market/indicators/bands.js": "/scripts/options/market/indicators/bands.eb583383.js",
|
||||
"/scripts/options/market/averages.js": "/scripts/options/market/averages.d95aa3e1.js",
|
||||
"/scripts/options/market/index.js": "/scripts/options/market/index.6896a1b5.js",
|
||||
"/scripts/options/market/indicators/bands.js": "/scripts/options/market/indicators/bands.81b19b83.js",
|
||||
"/scripts/options/market/indicators/index.js": "/scripts/options/market/indicators/index.70e9b3e4.js",
|
||||
"/scripts/options/market/indicators/momentum.js": "/scripts/options/market/indicators/momentum.8f20362c.js",
|
||||
"/scripts/options/market/indicators/onchain.js": "/scripts/options/market/indicators/onchain.d06affed.js",
|
||||
"/scripts/options/market/indicators/volatility.js": "/scripts/options/market/indicators/volatility.a12b9495.js",
|
||||
"/scripts/options/market/investing.js": "/scripts/options/market/investing.c00cb6ed.js",
|
||||
"/scripts/options/market/performance.js": "/scripts/options/market/performance.f381010b.js",
|
||||
"/scripts/options/market/indicators/momentum.js": "/scripts/options/market/indicators/momentum.48e71442.js",
|
||||
"/scripts/options/market/indicators/onchain.js": "/scripts/options/market/indicators/onchain.f75ddfd9.js",
|
||||
"/scripts/options/market/indicators/volatility.js": "/scripts/options/market/indicators/volatility.08ec92d7.js",
|
||||
"/scripts/options/market/investing.js": "/scripts/options/market/investing.57ded805.js",
|
||||
"/scripts/options/market/performance.js": "/scripts/options/market/performance.36c7ad40.js",
|
||||
"/scripts/options/market/utils.js": "/scripts/options/market/utils.e3e058d8.js",
|
||||
"/scripts/options/partial.js": "/scripts/options/partial.1bfb5914.js",
|
||||
"/scripts/options/series.js": "/scripts/options/series.3702ffc7.js",
|
||||
"/scripts/options/types.js": "/scripts/options/types.19186083.js",
|
||||
"/scripts/options/partial.js": "/scripts/options/partial.ab8fdf12.js",
|
||||
"/scripts/options/series.js": "/scripts/options/series.5a2a34ed.js",
|
||||
"/scripts/options/types.js": "/scripts/options/types.64db5149.js",
|
||||
"/scripts/options/unused.js": "/scripts/options/unused.24a71427.js",
|
||||
"/scripts/panes/chart/index.js": "/scripts/panes/chart/index.3d231714.js",
|
||||
"/scripts/panes/chart/screenshot.js": "/scripts/panes/chart/screenshot.adc8da89.js",
|
||||
@@ -1692,7 +1692,7 @@
|
||||
"/scripts/utils/serde.js": "/scripts/utils/serde.f9c7ed2b.js",
|
||||
"/scripts/utils/storage.js": "/scripts/utils/storage.cbd2ff9c.js",
|
||||
"/scripts/utils/timing.js": "/scripts/utils/timing.ae6a47b8.js",
|
||||
"/scripts/utils/units.js": "/scripts/utils/units.97b1a45f.js",
|
||||
"/scripts/utils/units.js": "/scripts/utils/units.30278ea7.js",
|
||||
"/scripts/utils/url.js": "/scripts/utils/url.20469bf9.js",
|
||||
"/scripts/utils/ws.js": "/scripts/utils/ws.fe3fb4b1.js"
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @import { Signal, Signals, Accessor } from "./signals.js";
|
||||
*
|
||||
* @import { BrkClient, CatalogTree_Distribution_UtxoCohorts as UtxoCohortTree, CatalogTree_Distribution_AddressCohorts as AddressCohortTree, CatalogTree_Distribution_UtxoCohorts_All as AllUtxoPattern, _10yTo12yPattern as MinAgePattern, _0satsPattern2 as UtxoAmountPattern, _0satsPattern as AddressAmountPattern, Ratio1ySdPattern, Dollars, Price111dSmaPattern as EmaRatioPattern, Index, BlockCountPattern, SizePattern, FullnessPattern, FeeRatePattern, CoinbasePattern, ActivePriceRatioPattern, _0satsPattern, UnclaimedRewardsPattern as ValuePattern, Metric, MetricPattern, AnyMetricPattern, MetricEndpoint, MetricData, AnyMetricEndpoint, AnyMetricData, AddrCountPattern, CatalogTree_Blocks_Interval as IntervalPattern } from "./modules/brk-client/index.js"
|
||||
* @import { BrkClient, CatalogTree_Distribution_UtxoCohorts as UtxoCohortTree, CatalogTree_Distribution_AddressCohorts as AddressCohortTree, CatalogTree_Distribution_UtxoCohorts_All as AllUtxoPattern, CatalogTree_Distribution_UtxoCohorts_Term_Short as ShortTermPattern, CatalogTree_Distribution_UtxoCohorts_Term_Long as LongTermPattern, _10yPattern as MaxAgePattern, _10yTo12yPattern as AgeRangePattern, _0satsPattern2 as UtxoAmountPattern, _0satsPattern as AddressAmountPattern, _100btcPattern as BasicUtxoPattern, _0satsPattern2 as EpochPattern, Ratio1ySdPattern, Dollars, Price111dSmaPattern as EmaRatioPattern, Index, BlockCountPattern, SizePattern, FullnessPattern, FeeRatePattern, CoinbasePattern, ActivePriceRatioPattern, _0satsPattern, UnclaimedRewardsPattern as ValuePattern, Metric, MetricPattern, AnyMetricPattern, MetricEndpoint, MetricData, AnyMetricEndpoint, AnyMetricData, AddrCountPattern, CatalogTree_Blocks_Interval as IntervalPattern, _24hCoinbaseSumPattern as SupplyPattern, RelativePattern, RelativePattern2, RelativePattern5, CatalogTree_Distribution_UtxoCohorts_All_Relative as AllRelativePattern } from "./modules/brk-client/index.js"
|
||||
*
|
||||
* @import { Resources, MetricResource } from './resources.js'
|
||||
*
|
||||
@@ -15,7 +15,9 @@
|
||||
*
|
||||
* @import { WebSockets } from "./utils/ws.js"
|
||||
*
|
||||
* @import { Option, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, SimulationOption, AnySeriesBlueprint, SeriesType, AnyFetchedSeriesBlueprint, TableOption, ExplorerOption, UrlOption, PartialOptionsGroup, OptionsGroup, PartialOptionsTree, UtxoCohortObject, AddressCohortObject, CohortObject, UtxoCohortGroupObject, AddressCohortGroupObject, CohortGroupObject, FetchedLineSeriesBlueprint, FetchedHistogramSeriesBlueprint, PartialContext, AgeCohortObject, AmountCohortObject, AgeCohortGroupObject, AmountCohortGroupObject } from "./options/partial.js"
|
||||
* @import { Option, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, SimulationOption, AnySeriesBlueprint, SeriesType, AnyFetchedSeriesBlueprint, TableOption, ExplorerOption, UrlOption, PartialOptionsGroup, OptionsGroup, PartialOptionsTree, UtxoCohortObject, AddressCohortObject, CohortObject, CohortGroupObject, FetchedLineSeriesBlueprint, FetchedBaselineSeriesBlueprint, FetchedHistogramSeriesBlueprint, PartialContext, PatternAll, PatternFull, PatternWithAdjusted, PatternWithPercentiles, PatternBasic, CohortAll, CohortFull, CohortWithAdjusted, CohortWithPercentiles, CohortBasic, CohortGroupFull, CohortGroupWithAdjusted, CohortGroupWithPercentiles, CohortGroupBasic, UtxoCohortGroupObject, AddressCohortGroupObject } from "./options/partial.js"
|
||||
*
|
||||
* @import { line as LineSeriesFn, baseline as BaselineSeriesFn, histogram as HistogramSeriesFn } from "./options/series.js"
|
||||
*
|
||||
* @import { UnitObject as Unit } from "./utils/units.js"
|
||||
*
|
||||
@@ -34,17 +36,22 @@
|
||||
* @typedef {keyof PoolIdToPoolName} PoolId
|
||||
*
|
||||
* Pattern unions by cohort type
|
||||
* @typedef {AllUtxoPattern | MinAgePattern | UtxoAmountPattern} UtxoCohortPattern
|
||||
* @typedef {AllUtxoPattern | AgeRangePattern | UtxoAmountPattern} UtxoCohortPattern
|
||||
* @typedef {AddressAmountPattern} AddressCohortPattern
|
||||
* @typedef {UtxoCohortPattern | AddressCohortPattern} CohortPattern
|
||||
*
|
||||
* Relative pattern capability types
|
||||
* @typedef {RelativePattern | RelativePattern5} RelativeWithMarketCap
|
||||
* @typedef {RelativePattern2 | RelativePattern5} RelativeWithOwnMarketCap
|
||||
* @typedef {RelativePattern2 | RelativePattern5 | AllRelativePattern} RelativeWithOwnPnl
|
||||
*
|
||||
* Capability-based pattern groupings (patterns that have specific properties)
|
||||
* @typedef {AllUtxoPattern | MinAgePattern | UtxoAmountPattern} PatternWithRealizedPrice
|
||||
* @typedef {AllUtxoPattern | AgeRangePattern | UtxoAmountPattern} PatternWithRealizedPrice
|
||||
* @typedef {AllUtxoPattern} PatternWithFullRealized
|
||||
* @typedef {AllUtxoPattern | MinAgePattern | UtxoAmountPattern} PatternWithNupl
|
||||
* @typedef {AllUtxoPattern | MinAgePattern | UtxoAmountPattern} PatternWithCostBasis
|
||||
* @typedef {AllUtxoPattern | MinAgePattern | UtxoAmountPattern} PatternWithActivity
|
||||
* @typedef {AllUtxoPattern | MinAgePattern} PatternWithCostBasisPercentiles
|
||||
* @typedef {AllUtxoPattern | AgeRangePattern | UtxoAmountPattern} PatternWithNupl
|
||||
* @typedef {AllUtxoPattern | AgeRangePattern | UtxoAmountPattern} PatternWithCostBasis
|
||||
* @typedef {AllUtxoPattern | AgeRangePattern | UtxoAmountPattern} PatternWithActivity
|
||||
* @typedef {AllUtxoPattern | AgeRangePattern} PatternWithCostBasisPercentiles
|
||||
*
|
||||
* Cohort objects with specific pattern capabilities
|
||||
* @typedef {{ name: string, title: string, color: Color, tree: PatternWithRealizedPrice }} CohortWithRealizedPrice
|
||||
|
||||
@@ -11,7 +11,7 @@ export function createChainSection(ctx) {
|
||||
const {
|
||||
colors,
|
||||
brk,
|
||||
s,
|
||||
line,
|
||||
createPriceLine,
|
||||
fromSizePattern,
|
||||
fromFullnessPattern,
|
||||
@@ -20,6 +20,7 @@ export function createChainSection(ctx) {
|
||||
fromValuePattern,
|
||||
fromBlockCountWithUnit,
|
||||
fromIntervalPattern,
|
||||
fromSupplyPattern,
|
||||
} = ctx;
|
||||
const {
|
||||
blocks,
|
||||
@@ -46,22 +47,33 @@ export function createChainSection(ctx) {
|
||||
name: "Dominance",
|
||||
title: `Mining Dominance of ${poolName}`,
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: pool._24hDominance,
|
||||
name: "24h",
|
||||
color: colors.orange,
|
||||
unit: Unit.percentage,
|
||||
defaultActive: false,
|
||||
}),
|
||||
line({
|
||||
metric: pool._1wDominance,
|
||||
name: "1w",
|
||||
color: colors.red,
|
||||
unit: Unit.percentage,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({ metric: pool._1mDominance, name: "1m", unit: Unit.percentage }),
|
||||
s({
|
||||
line({
|
||||
metric: pool._1mDominance,
|
||||
name: "1m",
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
line({
|
||||
metric: pool._1yDominance,
|
||||
name: "1y",
|
||||
color: colors.lime,
|
||||
unit: Unit.percentage,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: pool.dominance,
|
||||
name: "all time",
|
||||
color: colors.teal,
|
||||
@@ -74,32 +86,32 @@ export function createChainSection(ctx) {
|
||||
name: "Blocks mined",
|
||||
title: `Blocks mined by ${poolName}`,
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: pool.blocksMined.sum,
|
||||
name: "Sum",
|
||||
unit: Unit.count,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: pool.blocksMined.cumulative,
|
||||
name: "Cumulative",
|
||||
color: colors.blue,
|
||||
unit: Unit.count,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: pool._1wBlocksMined,
|
||||
name: "1w Sum",
|
||||
color: colors.red,
|
||||
unit: Unit.count,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: pool._1mBlocksMined,
|
||||
name: "1m Sum",
|
||||
color: colors.pink,
|
||||
unit: Unit.count,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: pool._1yBlocksMined,
|
||||
name: "1y Sum",
|
||||
color: colors.purple,
|
||||
@@ -112,8 +124,18 @@ export function createChainSection(ctx) {
|
||||
name: "Rewards",
|
||||
title: `Rewards collected by ${poolName}`,
|
||||
bottom: [
|
||||
...fromValuePattern(pool.coinbase, "coinbase", colors.orange, colors.red),
|
||||
...fromValuePattern(pool.subsidy, "subsidy", colors.lime, colors.emerald),
|
||||
...fromValuePattern(
|
||||
pool.coinbase,
|
||||
"coinbase",
|
||||
colors.orange,
|
||||
colors.red,
|
||||
),
|
||||
...fromValuePattern(
|
||||
pool.subsidy,
|
||||
"subsidy",
|
||||
colors.lime,
|
||||
colors.emerald,
|
||||
),
|
||||
...fromValuePattern(pool.fee, "fee", colors.cyan, colors.indigo),
|
||||
],
|
||||
},
|
||||
@@ -121,7 +143,7 @@ export function createChainSection(ctx) {
|
||||
name: "Days since block",
|
||||
title: `Days since ${poolName} mined a block`,
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: pool.daysSinceBlock,
|
||||
name: "Since block",
|
||||
unit: Unit.days,
|
||||
@@ -143,29 +165,33 @@ export function createChainSection(ctx) {
|
||||
name: "Count",
|
||||
title: "Block Count",
|
||||
bottom: [
|
||||
...fromBlockCountWithUnit(blocks.count.blockCount, "Block", Unit.count),
|
||||
s({
|
||||
...fromBlockCountWithUnit(
|
||||
blocks.count.blockCount,
|
||||
"Block",
|
||||
Unit.count,
|
||||
),
|
||||
line({
|
||||
metric: blocks.count.blockCountTarget,
|
||||
name: "Target",
|
||||
color: colors.gray,
|
||||
unit: Unit.count,
|
||||
options: { lineStyle: 4 },
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.count._1wBlockCount,
|
||||
name: "1w sum",
|
||||
color: colors.red,
|
||||
unit: Unit.count,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.count._1mBlockCount,
|
||||
name: "1m sum",
|
||||
color: colors.pink,
|
||||
unit: Unit.count,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.count._1yBlockCount,
|
||||
name: "1y sum",
|
||||
color: colors.purple,
|
||||
@@ -211,36 +237,36 @@ export function createChainSection(ctx) {
|
||||
name: "Volume",
|
||||
title: "Transaction Volume",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: transactions.volume.sentSum.sats,
|
||||
name: "Sent",
|
||||
unit: Unit.sats,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.volume.sentSum.bitcoin,
|
||||
name: "Sent",
|
||||
unit: Unit.btc,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.volume.sentSum.dollars,
|
||||
name: "Sent",
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.volume.annualizedVolume.sats,
|
||||
name: "annualized",
|
||||
color: colors.red,
|
||||
unit: Unit.sats,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.volume.annualizedVolume.bitcoin,
|
||||
name: "annualized",
|
||||
color: colors.red,
|
||||
unit: Unit.btc,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.volume.annualizedVolume.dollars,
|
||||
name: "annualized",
|
||||
color: colors.lime,
|
||||
@@ -253,7 +279,11 @@ export function createChainSection(ctx) {
|
||||
name: "Size",
|
||||
title: "Transaction Size",
|
||||
bottom: [
|
||||
...fromFeeRatePattern(transactions.size.weight, "weight", Unit.wu),
|
||||
...fromFeeRatePattern(
|
||||
transactions.size.weight,
|
||||
"weight",
|
||||
Unit.wu,
|
||||
),
|
||||
...fromFeeRatePattern(transactions.size.vsize, "vsize", Unit.vb),
|
||||
],
|
||||
},
|
||||
@@ -261,21 +291,39 @@ export function createChainSection(ctx) {
|
||||
name: "Versions",
|
||||
title: "Transaction Versions",
|
||||
bottom: [
|
||||
...fromBlockCountWithUnit(transactions.versions.v1, "v1", Unit.count, colors.orange, colors.red),
|
||||
...fromBlockCountWithUnit(transactions.versions.v2, "v2", Unit.count, colors.cyan, colors.blue),
|
||||
...fromBlockCountWithUnit(transactions.versions.v3, "v3", Unit.count, colors.lime, colors.green),
|
||||
...fromBlockCountWithUnit(
|
||||
transactions.versions.v1,
|
||||
"v1",
|
||||
Unit.count,
|
||||
colors.orange,
|
||||
colors.red,
|
||||
),
|
||||
...fromBlockCountWithUnit(
|
||||
transactions.versions.v2,
|
||||
"v2",
|
||||
Unit.count,
|
||||
colors.cyan,
|
||||
colors.blue,
|
||||
),
|
||||
...fromBlockCountWithUnit(
|
||||
transactions.versions.v3,
|
||||
"v3",
|
||||
Unit.count,
|
||||
colors.lime,
|
||||
colors.green,
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Velocity",
|
||||
title: "Transactions Velocity",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: supply.velocity.btc,
|
||||
name: "bitcoin",
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: supply.velocity.usd,
|
||||
name: "dollars",
|
||||
color: colors.emerald,
|
||||
@@ -287,7 +335,7 @@ export function createChainSection(ctx) {
|
||||
name: "Speed",
|
||||
title: "Transactions Per Second",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: transactions.volume.txPerSec,
|
||||
name: "Transactions",
|
||||
unit: Unit.perSec,
|
||||
@@ -310,7 +358,7 @@ export function createChainSection(ctx) {
|
||||
name: "Speed",
|
||||
title: "Inputs Per Second",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: transactions.volume.inputsPerSec,
|
||||
name: "Inputs",
|
||||
unit: Unit.perSec,
|
||||
@@ -339,7 +387,7 @@ export function createChainSection(ctx) {
|
||||
name: "Speed",
|
||||
title: "Outputs Per Second",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: transactions.volume.outputsPerSec,
|
||||
name: "Outputs",
|
||||
unit: Unit.perSec,
|
||||
@@ -355,7 +403,13 @@ export function createChainSection(ctx) {
|
||||
{
|
||||
name: "Count",
|
||||
title: "UTXO Count",
|
||||
bottom: fromFullnessPattern(outputs.count.utxoCount, "Count", Unit.count),
|
||||
bottom: [
|
||||
line({
|
||||
metric: outputs.count.utxoCount,
|
||||
name: "Count",
|
||||
unit: Unit.count,
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -373,7 +427,7 @@ export function createChainSection(ctx) {
|
||||
title: "Block Subsidy",
|
||||
bottom: [
|
||||
...fromCoinbasePattern(blocks.rewards.subsidy, "Subsidy"),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.rewards.subsidyDominance,
|
||||
name: "Dominance",
|
||||
color: colors.purple,
|
||||
@@ -391,43 +445,43 @@ export function createChainSection(ctx) {
|
||||
name: "Total",
|
||||
title: "Transaction Fees",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: transactions.fees.fee.sats.sum,
|
||||
name: "Sum",
|
||||
unit: Unit.sats,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.fees.fee.sats.cumulative,
|
||||
name: "Cumulative",
|
||||
color: colors.blue,
|
||||
unit: Unit.sats,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.fees.fee.bitcoin.sum,
|
||||
name: "Sum",
|
||||
unit: Unit.btc,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.fees.fee.bitcoin.cumulative,
|
||||
name: "Cumulative",
|
||||
color: colors.blue,
|
||||
unit: Unit.btc,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.fees.fee.dollars.sum,
|
||||
name: "Sum",
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.fees.fee.dollars.cumulative,
|
||||
name: "Cumulative",
|
||||
color: colors.blue,
|
||||
unit: Unit.usd,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.rewards.feeDominance,
|
||||
name: "Dominance",
|
||||
color: colors.purple,
|
||||
@@ -440,55 +494,55 @@ export function createChainSection(ctx) {
|
||||
name: "Rate",
|
||||
title: "Fee Rate",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: transactions.fees.feeRate.median,
|
||||
name: "Median",
|
||||
color: colors.purple,
|
||||
unit: Unit.feeRate,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.fees.feeRate.average,
|
||||
name: "Average",
|
||||
color: colors.blue,
|
||||
unit: Unit.feeRate,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.fees.feeRate.min,
|
||||
name: "Min",
|
||||
color: colors.red,
|
||||
unit: Unit.feeRate,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.fees.feeRate.max,
|
||||
name: "Max",
|
||||
color: colors.green,
|
||||
unit: Unit.feeRate,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.fees.feeRate.pct10,
|
||||
name: "pct10",
|
||||
color: colors.rose,
|
||||
unit: Unit.feeRate,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.fees.feeRate.pct25,
|
||||
name: "pct25",
|
||||
color: colors.pink,
|
||||
unit: Unit.feeRate,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.fees.feeRate.pct75,
|
||||
name: "pct75",
|
||||
color: colors.violet,
|
||||
unit: Unit.feeRate,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: transactions.fees.feeRate.pct90,
|
||||
name: "pct90",
|
||||
color: colors.fuchsia,
|
||||
@@ -508,33 +562,33 @@ export function createChainSection(ctx) {
|
||||
name: "Hashrate",
|
||||
title: "Network Hashrate",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashRate,
|
||||
name: "Hashrate",
|
||||
unit: Unit.hashRate,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashRate1wSma,
|
||||
name: "1w SMA",
|
||||
color: colors.red,
|
||||
unit: Unit.hashRate,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashRate1mSma,
|
||||
name: "1m SMA",
|
||||
color: colors.orange,
|
||||
unit: Unit.hashRate,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashRate2mSma,
|
||||
name: "2m SMA",
|
||||
color: colors.yellow,
|
||||
unit: Unit.hashRate,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashRate1ySma,
|
||||
name: "1y SMA",
|
||||
color: colors.lime,
|
||||
@@ -547,19 +601,19 @@ export function createChainSection(ctx) {
|
||||
name: "Difficulty",
|
||||
title: "Network Difficulty",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: blocks.difficulty.raw,
|
||||
name: "Difficulty",
|
||||
unit: Unit.difficulty,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.difficulty.adjustment,
|
||||
name: "Adjustment",
|
||||
color: colors.orange,
|
||||
unit: Unit.percentage,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.difficulty.asHash,
|
||||
name: "As hash",
|
||||
color: colors.default,
|
||||
@@ -567,14 +621,14 @@ export function createChainSection(ctx) {
|
||||
defaultActive: false,
|
||||
options: { lineStyle: 1 },
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.difficulty.blocksBeforeNextAdjustment,
|
||||
name: "Blocks until adj.",
|
||||
color: colors.indigo,
|
||||
unit: Unit.blocks,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.difficulty.daysBeforeNextAdjustment,
|
||||
name: "Days until adj.",
|
||||
color: colors.purple,
|
||||
@@ -587,32 +641,32 @@ export function createChainSection(ctx) {
|
||||
name: "Hash Price",
|
||||
title: "Hash Price",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashPriceThs,
|
||||
name: "TH/s",
|
||||
color: colors.emerald,
|
||||
unit: Unit.usdPerThsPerDay,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashPricePhs,
|
||||
name: "PH/s",
|
||||
color: colors.emerald,
|
||||
unit: Unit.usdPerPhsPerDay,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashPriceRebound,
|
||||
name: "Rebound",
|
||||
color: colors.yellow,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashPriceThsMin,
|
||||
name: "TH/s Min",
|
||||
color: colors.red,
|
||||
unit: Unit.usdPerThsPerDay,
|
||||
options: { lineStyle: 1 },
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashPricePhsMin,
|
||||
name: "PH/s Min",
|
||||
color: colors.red,
|
||||
@@ -625,32 +679,32 @@ export function createChainSection(ctx) {
|
||||
name: "Hash Value",
|
||||
title: "Hash Value",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashValueThs,
|
||||
name: "TH/s",
|
||||
color: colors.orange,
|
||||
unit: Unit.satsPerThsPerDay,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashValuePhs,
|
||||
name: "PH/s",
|
||||
color: colors.orange,
|
||||
unit: Unit.satsPerPhsPerDay,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashValueRebound,
|
||||
name: "Rebound",
|
||||
color: colors.yellow,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashValueThsMin,
|
||||
name: "TH/s Min",
|
||||
color: colors.red,
|
||||
unit: Unit.satsPerThsPerDay,
|
||||
options: { lineStyle: 1 },
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.mining.hashValuePhsMin,
|
||||
name: "PH/s Min",
|
||||
color: colors.red,
|
||||
@@ -663,18 +717,18 @@ export function createChainSection(ctx) {
|
||||
name: "Halving",
|
||||
title: "Halving Info",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: blocks.halving.blocksBeforeNextHalving,
|
||||
name: "Blocks until halving",
|
||||
unit: Unit.blocks,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.halving.daysBeforeNextHalving,
|
||||
name: "Days until halving",
|
||||
color: colors.orange,
|
||||
unit: Unit.days,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: blocks.halving.epoch,
|
||||
name: "Halving epoch",
|
||||
color: colors.purple,
|
||||
@@ -687,7 +741,7 @@ export function createChainSection(ctx) {
|
||||
name: "Puell Multiple",
|
||||
title: "Puell Multiple",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: market.indicators.puellMultiple,
|
||||
name: "Puell Multiple",
|
||||
unit: Unit.ratio,
|
||||
@@ -708,6 +762,11 @@ export function createChainSection(ctx) {
|
||||
{
|
||||
name: "Unspendable",
|
||||
tree: [
|
||||
{
|
||||
name: "Supply",
|
||||
title: "Unspendable Supply",
|
||||
bottom: fromValuePattern(supply.burned.unspendable, "Supply"),
|
||||
},
|
||||
{
|
||||
name: "OP_RETURN",
|
||||
tree: [
|
||||
@@ -720,23 +779,42 @@ export function createChainSection(ctx) {
|
||||
Unit.count,
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "Supply",
|
||||
title: "OP_RETURN Supply",
|
||||
bottom: fromValuePattern(supply.burned.opreturn, "Supply"),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// Supply
|
||||
{
|
||||
name: "Supply",
|
||||
title: "Circulating Supply",
|
||||
bottom: fromSupplyPattern(supply.circulating, "Supply"),
|
||||
},
|
||||
|
||||
// Inflation
|
||||
{
|
||||
name: "Inflation",
|
||||
title: "Inflation Rate",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: supply.inflation,
|
||||
name: "Rate",
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
],
|
||||
},
|
||||
|
||||
// Unclaimed Rewards
|
||||
{
|
||||
name: "Unclaimed Rewards",
|
||||
title: "Unclaimed Block Rewards",
|
||||
bottom: fromValuePattern(blocks.rewards.unclaimedRewards, "Unclaimed"),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ export function createAddressCohortFolder(ctx, args) {
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createRealizedPriceOptions(ctx, args, title) {
|
||||
const { s } = ctx;
|
||||
const { line } = ctx;
|
||||
const { tree, color } = args;
|
||||
|
||||
return [
|
||||
@@ -143,7 +143,7 @@ function createRealizedPriceOptions(ctx, args, title) {
|
||||
name: "price",
|
||||
title: `Realized Price ${title}`,
|
||||
top: [
|
||||
s({
|
||||
line({
|
||||
metric: tree.realized.realizedPrice,
|
||||
name: "Realized",
|
||||
color,
|
||||
@@ -163,11 +163,11 @@ function createRealizedPriceOptions(ctx, args, title) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
function createRealizedCapWithExtras(ctx, list, args, useGroupName) {
|
||||
const { s, createPriceLine } = ctx;
|
||||
const { line, baseline, createPriceLine } = ctx;
|
||||
const isSingle = !("list" in args);
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
s({
|
||||
line({
|
||||
metric: tree.realized.realizedCap,
|
||||
name: useGroupName ? name : "Capitalization",
|
||||
color,
|
||||
@@ -175,10 +175,9 @@ function createRealizedCapWithExtras(ctx, list, args, useGroupName) {
|
||||
}),
|
||||
...(isSingle
|
||||
? [
|
||||
/** @type {AnyFetchedSeriesBlueprint} */ ({
|
||||
type: "Baseline",
|
||||
baseline({
|
||||
metric: tree.realized.realizedCap30dDelta,
|
||||
title: "30d Change",
|
||||
name: "30d Change",
|
||||
unit: Unit.usd,
|
||||
defaultActive: false,
|
||||
}),
|
||||
@@ -197,7 +196,7 @@ function createRealizedCapWithExtras(ctx, list, args, useGroupName) {
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createRealizedPnlSection(ctx, args, title) {
|
||||
const { colors, s } = ctx;
|
||||
const { colors, line } = ctx;
|
||||
const { realized } = args.tree;
|
||||
|
||||
return [
|
||||
@@ -205,13 +204,13 @@ function createRealizedPnlSection(ctx, args, title) {
|
||||
name: "pnl",
|
||||
title: `Realized Profit And Loss ${title}`,
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: realized.realizedProfit.sum,
|
||||
name: "Profit",
|
||||
color: colors.green,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: realized.realizedLoss.sum,
|
||||
name: "Loss",
|
||||
color: colors.red,
|
||||
@@ -219,20 +218,20 @@ function createRealizedPnlSection(ctx, args, title) {
|
||||
defaultActive: false,
|
||||
}),
|
||||
// RealizedPattern (address cohorts) doesn't have realizedProfitToLossRatio
|
||||
s({
|
||||
line({
|
||||
metric: realized.totalRealizedPnl,
|
||||
name: "Total",
|
||||
color: colors.default,
|
||||
defaultActive: false,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: realized.negRealizedLoss.sum,
|
||||
name: "Negative Loss",
|
||||
color: colors.red,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: realized.negRealizedLoss.cumulative,
|
||||
name: "Negative Loss",
|
||||
color: colors.red,
|
||||
@@ -252,7 +251,7 @@ function createRealizedPnlSection(ctx, args, title) {
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createUnrealizedSection(ctx, list, useGroupName, title) {
|
||||
const { colors, s } = ctx;
|
||||
const { colors, line, baseline } = ctx;
|
||||
|
||||
return [
|
||||
{
|
||||
@@ -262,12 +261,10 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
|
||||
name: "nupl",
|
||||
title: `Net Unrealized Profit/Loss ${title}`,
|
||||
bottom: list.flatMap(({ color, name, tree }) => [
|
||||
/** @type {AnyFetchedSeriesBlueprint} */ ({
|
||||
type: "Baseline",
|
||||
baseline({
|
||||
metric: tree.unrealized.netUnrealizedPnl,
|
||||
title: useGroupName ? name : "NUPL",
|
||||
color: useGroupName ? color : undefined,
|
||||
colors: useGroupName ? undefined : [colors.red, colors.green],
|
||||
name: useGroupName ? name : "NUPL",
|
||||
color: useGroupName ? color : [colors.red, colors.green],
|
||||
unit: Unit.ratio,
|
||||
options: { baseValue: { price: 0 } },
|
||||
}),
|
||||
@@ -277,7 +274,7 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
|
||||
name: "profit",
|
||||
title: `Unrealized Profit ${title}`,
|
||||
bottom: list.flatMap(({ color, name, tree }) => [
|
||||
s({
|
||||
line({
|
||||
metric: tree.unrealized.unrealizedProfit,
|
||||
name: useGroupName ? name : "Profit",
|
||||
color,
|
||||
@@ -289,7 +286,7 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
|
||||
name: "loss",
|
||||
title: `Unrealized Loss ${title}`,
|
||||
bottom: list.flatMap(({ color, name, tree }) => [
|
||||
s({
|
||||
line({
|
||||
metric: tree.unrealized.unrealizedLoss,
|
||||
name: useGroupName ? name : "Loss",
|
||||
color,
|
||||
@@ -311,7 +308,7 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createCostBasisSection(ctx, list, useGroupName, title) {
|
||||
const { s } = ctx;
|
||||
const { line } = ctx;
|
||||
|
||||
return [
|
||||
{
|
||||
@@ -321,7 +318,7 @@ function createCostBasisSection(ctx, list, useGroupName, title) {
|
||||
name: "min",
|
||||
title: `Min Cost Basis ${title}`,
|
||||
top: list.map(({ color, name, tree }) =>
|
||||
s({
|
||||
line({
|
||||
metric: tree.costBasis.min,
|
||||
name: useGroupName ? name : "Min",
|
||||
color,
|
||||
@@ -333,7 +330,7 @@ function createCostBasisSection(ctx, list, useGroupName, title) {
|
||||
name: "max",
|
||||
title: `Max Cost Basis ${title}`,
|
||||
top: list.map(({ color, name, tree }) =>
|
||||
s({
|
||||
line({
|
||||
metric: tree.costBasis.max,
|
||||
name: useGroupName ? name : "Max",
|
||||
color,
|
||||
@@ -355,7 +352,7 @@ function createCostBasisSection(ctx, list, useGroupName, title) {
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createActivitySection(ctx, list, useGroupName, title) {
|
||||
const { s } = ctx;
|
||||
const { line } = ctx;
|
||||
|
||||
return [
|
||||
{
|
||||
@@ -365,13 +362,13 @@ function createActivitySection(ctx, list, useGroupName, title) {
|
||||
name: "coinblocks destroyed",
|
||||
title: `Coinblocks Destroyed ${title}`,
|
||||
bottom: list.flatMap(({ color, name, tree }) => [
|
||||
s({
|
||||
line({
|
||||
metric: tree.activity.coinblocksDestroyed.sum,
|
||||
name: useGroupName ? name : "Coinblocks",
|
||||
color,
|
||||
unit: Unit.coinblocks,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.activity.coinblocksDestroyed.cumulative,
|
||||
name: useGroupName ? name : "Coinblocks",
|
||||
color,
|
||||
@@ -383,13 +380,13 @@ function createActivitySection(ctx, list, useGroupName, title) {
|
||||
name: "coindays destroyed",
|
||||
title: `Coindays Destroyed ${title}`,
|
||||
bottom: list.flatMap(({ color, name, tree }) => [
|
||||
s({
|
||||
line({
|
||||
metric: tree.activity.coindaysDestroyed.sum,
|
||||
name: useGroupName ? name : "Coindays",
|
||||
color,
|
||||
unit: Unit.coindays,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.activity.coindaysDestroyed.cumulative,
|
||||
name: useGroupName ? name : "Coindays",
|
||||
color,
|
||||
|
||||
@@ -42,8 +42,8 @@ export function buildCohortData(colors, brk) {
|
||||
SPENDABLE_TYPE_NAMES,
|
||||
} = brk;
|
||||
|
||||
// Base cohort representing "all"
|
||||
/** @type {UtxoCohortObject} */
|
||||
// Base cohort representing "all" - CohortAll (adjustedSopr + percentiles but no RelToMarketCap)
|
||||
/** @type {CohortAll} */
|
||||
const cohortAll = {
|
||||
name: "",
|
||||
title: "",
|
||||
@@ -51,28 +51,27 @@ export function buildCohortData(colors, brk) {
|
||||
tree: utxoCohorts.all,
|
||||
};
|
||||
|
||||
/** @type {UtxoCohortObject} */
|
||||
const cohortAllForComparison = {
|
||||
name: "all",
|
||||
title: "",
|
||||
color: colors.default,
|
||||
tree: utxoCohorts.all,
|
||||
// Term cohorts - split because short is CohortFull, long is CohortWithPercentiles
|
||||
const shortNames = TERM_NAMES.short;
|
||||
/** @type {CohortFull} */
|
||||
const termShort = {
|
||||
name: shortNames.short,
|
||||
title: shortNames.long,
|
||||
color: colors[termColors.short],
|
||||
tree: utxoCohorts.term.short,
|
||||
};
|
||||
|
||||
// Term cohorts (short/long term holders)
|
||||
/** @type {readonly UtxoCohortObject[]} */
|
||||
const terms = entries(utxoCohorts.term).map(([key, tree]) => {
|
||||
const names = TERM_NAMES[key];
|
||||
return {
|
||||
name: names.short,
|
||||
title: names.long,
|
||||
color: colors[termColors[key]],
|
||||
tree,
|
||||
};
|
||||
});
|
||||
const longNames = TERM_NAMES.long;
|
||||
/** @type {CohortWithPercentiles} */
|
||||
const termLong = {
|
||||
name: longNames.short,
|
||||
title: longNames.long,
|
||||
color: colors[termColors.long],
|
||||
tree: utxoCohorts.term.long,
|
||||
};
|
||||
|
||||
// Max age cohorts (up to X time)
|
||||
/** @type {readonly UtxoCohortObject[]} */
|
||||
// Max age cohorts (up to X time) - CohortWithAdjusted (adjustedSopr only)
|
||||
/** @type {readonly CohortWithAdjusted[]} */
|
||||
const upToDate = entries(utxoCohorts.maxAge).map(([key, tree]) => {
|
||||
const names = MAX_AGE_NAMES[key];
|
||||
return {
|
||||
@@ -83,8 +82,8 @@ export function buildCohortData(colors, brk) {
|
||||
};
|
||||
});
|
||||
|
||||
// Min age cohorts (from X time)
|
||||
/** @type {readonly UtxoCohortObject[]} */
|
||||
// Min age cohorts (from X time) - CohortBasic (neither adjustedSopr nor percentiles)
|
||||
/** @type {readonly CohortBasic[]} */
|
||||
const fromDate = entries(utxoCohorts.minAge).map(([key, tree]) => {
|
||||
const names = MIN_AGE_NAMES[key];
|
||||
return {
|
||||
@@ -95,8 +94,8 @@ export function buildCohortData(colors, brk) {
|
||||
};
|
||||
});
|
||||
|
||||
// Age range cohorts
|
||||
/** @type {readonly UtxoCohortObject[]} */
|
||||
// Age range cohorts - CohortWithPercentiles (percentiles only)
|
||||
/** @type {readonly CohortWithPercentiles[]} */
|
||||
const dateRange = entries(utxoCohorts.ageRange).map(([key, tree]) => {
|
||||
const names = AGE_RANGE_NAMES[key];
|
||||
return {
|
||||
@@ -107,8 +106,8 @@ export function buildCohortData(colors, brk) {
|
||||
};
|
||||
});
|
||||
|
||||
// Epoch cohorts
|
||||
/** @type {readonly UtxoCohortObject[]} */
|
||||
// Epoch cohorts - CohortBasic (neither adjustedSopr nor percentiles)
|
||||
/** @type {readonly CohortBasic[]} */
|
||||
const epoch = entries(utxoCohorts.epoch).map(([key, tree]) => {
|
||||
const names = EPOCH_NAMES[key];
|
||||
return {
|
||||
@@ -119,8 +118,8 @@ export function buildCohortData(colors, brk) {
|
||||
};
|
||||
});
|
||||
|
||||
// UTXOs above amount
|
||||
/** @type {readonly UtxoCohortObject[]} */
|
||||
// UTXOs above amount - CohortBasic (neither adjustedSopr nor percentiles)
|
||||
/** @type {readonly CohortBasic[]} */
|
||||
const utxosAboveAmount = entries(utxoCohorts.geAmount).map(([key, tree]) => {
|
||||
const names = GE_AMOUNT_NAMES[key];
|
||||
return {
|
||||
@@ -145,8 +144,8 @@ export function buildCohortData(colors, brk) {
|
||||
},
|
||||
);
|
||||
|
||||
// UTXOs under amount
|
||||
/** @type {readonly UtxoCohortObject[]} */
|
||||
// UTXOs under amount - CohortBasic (neither adjustedSopr nor percentiles)
|
||||
/** @type {readonly CohortBasic[]} */
|
||||
const utxosUnderAmount = entries(utxoCohorts.ltAmount).map(([key, tree]) => {
|
||||
const names = LT_AMOUNT_NAMES[key];
|
||||
return {
|
||||
@@ -171,8 +170,8 @@ export function buildCohortData(colors, brk) {
|
||||
},
|
||||
);
|
||||
|
||||
// UTXOs amount ranges
|
||||
/** @type {readonly UtxoCohortObject[]} */
|
||||
// UTXOs amount ranges - CohortBasic (neither adjustedSopr nor percentiles)
|
||||
/** @type {readonly CohortBasic[]} */
|
||||
const utxosAmountRanges = entries(utxoCohorts.amountRange).map(
|
||||
([key, tree]) => {
|
||||
const names = AMOUNT_RANGE_NAMES[key];
|
||||
@@ -199,8 +198,8 @@ export function buildCohortData(colors, brk) {
|
||||
},
|
||||
);
|
||||
|
||||
// Spendable type cohorts
|
||||
/** @type {readonly UtxoCohortObject[]} */
|
||||
// Spendable type cohorts - CohortBasic (neither adjustedSopr nor percentiles)
|
||||
/** @type {readonly CohortBasic[]} */
|
||||
const type = entries(utxoCohorts.type).map(([key, tree]) => {
|
||||
const names = SPENDABLE_TYPE_NAMES[key];
|
||||
return {
|
||||
@@ -213,8 +212,8 @@ export function buildCohortData(colors, brk) {
|
||||
|
||||
return {
|
||||
cohortAll,
|
||||
cohortAllForComparison,
|
||||
terms,
|
||||
termShort,
|
||||
termLong,
|
||||
upToDate,
|
||||
fromDate,
|
||||
dateRange,
|
||||
|
||||
@@ -6,7 +6,13 @@
|
||||
export { buildCohortData } from "./data.js";
|
||||
|
||||
// Cohort folder builders (type-safe!)
|
||||
export { createUtxoCohortFolder, createAgeCohortFolder, createAmountCohortFolder } from "./utxo.js";
|
||||
export {
|
||||
createCohortFolderAll,
|
||||
createCohortFolderFull,
|
||||
createCohortFolderWithAdjusted,
|
||||
createCohortFolderWithPercentiles,
|
||||
createCohortFolderBasic,
|
||||
} from "./utxo.js";
|
||||
export { createAddressCohortFolder } from "./address.js";
|
||||
|
||||
// Shared helpers
|
||||
|
||||
@@ -9,23 +9,23 @@ import { Unit } from "../../utils/units.js";
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createSingleSupplySeries(ctx, cohort) {
|
||||
const { colors, s, createPriceLine } = ctx;
|
||||
const { colors, line, createPriceLine } = ctx;
|
||||
const { tree } = cohort;
|
||||
|
||||
return [
|
||||
s({
|
||||
line({
|
||||
metric: tree.supply.total.sats,
|
||||
name: "Supply",
|
||||
color: colors.default,
|
||||
unit: Unit.sats,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.supply.total.bitcoin,
|
||||
name: "Supply",
|
||||
color: colors.default,
|
||||
unit: Unit.btc,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.supply.total.dollars,
|
||||
name: "Supply",
|
||||
color: colors.default,
|
||||
@@ -33,7 +33,7 @@ export function createSingleSupplySeries(ctx, cohort) {
|
||||
}),
|
||||
...("supplyRelToCirculatingSupply" in tree.relative
|
||||
? [
|
||||
s({
|
||||
line({
|
||||
metric: tree.relative.supplyRelToCirculatingSupply,
|
||||
name: "Supply",
|
||||
color: colors.default,
|
||||
@@ -41,57 +41,57 @@ export function createSingleSupplySeries(ctx, cohort) {
|
||||
}),
|
||||
]
|
||||
: []),
|
||||
s({
|
||||
line({
|
||||
metric: tree.unrealized.supplyInProfit.sats,
|
||||
name: "In Profit",
|
||||
color: colors.green,
|
||||
unit: Unit.sats,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.unrealized.supplyInProfit.bitcoin,
|
||||
name: "In Profit",
|
||||
color: colors.green,
|
||||
unit: Unit.btc,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.unrealized.supplyInProfit.dollars,
|
||||
name: "In Profit",
|
||||
color: colors.green,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.unrealized.supplyInLoss.sats,
|
||||
name: "In Loss",
|
||||
color: colors.red,
|
||||
unit: Unit.sats,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.unrealized.supplyInLoss.bitcoin,
|
||||
name: "In Loss",
|
||||
color: colors.red,
|
||||
unit: Unit.btc,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.unrealized.supplyInLoss.dollars,
|
||||
name: "In Loss",
|
||||
color: colors.red,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.supply.halved.sats,
|
||||
name: "half",
|
||||
color: colors.gray,
|
||||
unit: Unit.sats,
|
||||
options: { lineStyle: 4 },
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.supply.halved.bitcoin,
|
||||
name: "half",
|
||||
color: colors.gray,
|
||||
unit: Unit.btc,
|
||||
options: { lineStyle: 4 },
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.supply.halved.dollars,
|
||||
name: "half",
|
||||
color: colors.gray,
|
||||
@@ -100,13 +100,13 @@ export function createSingleSupplySeries(ctx, cohort) {
|
||||
}),
|
||||
...("supplyInProfitRelToCirculatingSupply" in tree.relative
|
||||
? [
|
||||
s({
|
||||
line({
|
||||
metric: tree.relative.supplyInProfitRelToCirculatingSupply,
|
||||
name: "In Profit",
|
||||
color: colors.green,
|
||||
unit: Unit.pctSupply,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.relative.supplyInLossRelToCirculatingSupply,
|
||||
name: "In Loss",
|
||||
color: colors.red,
|
||||
@@ -114,13 +114,13 @@ export function createSingleSupplySeries(ctx, cohort) {
|
||||
}),
|
||||
]
|
||||
: []),
|
||||
s({
|
||||
line({
|
||||
metric: tree.relative.supplyInProfitRelToOwnSupply,
|
||||
name: "In Profit",
|
||||
color: colors.green,
|
||||
unit: Unit.pctOwn,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.relative.supplyInLossRelToOwnSupply,
|
||||
name: "In Loss",
|
||||
color: colors.red,
|
||||
@@ -143,21 +143,21 @@ export function createSingleSupplySeries(ctx, cohort) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createGroupedSupplyTotalSeries(ctx, list) {
|
||||
const { s, brk } = ctx;
|
||||
const { line, brk } = ctx;
|
||||
const constant100 = brk.tree.constants.constant100;
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
s({ metric: tree.supply.total.sats, name, color, unit: Unit.sats }),
|
||||
s({ metric: tree.supply.total.bitcoin, name, color, unit: Unit.btc }),
|
||||
s({ metric: tree.supply.total.dollars, name, color, unit: Unit.usd }),
|
||||
line({ metric: tree.supply.total.sats, name, color, unit: Unit.sats }),
|
||||
line({ metric: tree.supply.total.bitcoin, name, color, unit: Unit.btc }),
|
||||
line({ metric: tree.supply.total.dollars, name, color, unit: Unit.usd }),
|
||||
"supplyRelToCirculatingSupply" in tree.relative
|
||||
? s({
|
||||
? line({
|
||||
metric: tree.relative.supplyRelToCirculatingSupply,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.pctSupply,
|
||||
})
|
||||
: s({ metric: constant100, name, color, unit: Unit.pctSupply }),
|
||||
: line({ metric: constant100, name, color, unit: Unit.pctSupply }),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -168,22 +168,22 @@ export function createGroupedSupplyTotalSeries(ctx, list) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createGroupedSupplyInProfitSeries(ctx, list) {
|
||||
const { s } = ctx;
|
||||
const { line } = ctx;
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
s({
|
||||
line({
|
||||
metric: tree.unrealized.supplyInProfit.sats,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.sats,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.unrealized.supplyInProfit.bitcoin,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.btc,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.unrealized.supplyInProfit.dollars,
|
||||
name,
|
||||
color,
|
||||
@@ -191,7 +191,7 @@ export function createGroupedSupplyInProfitSeries(ctx, list) {
|
||||
}),
|
||||
...("supplyInProfitRelToCirculatingSupply" in tree.relative
|
||||
? [
|
||||
s({
|
||||
line({
|
||||
metric: tree.relative.supplyInProfitRelToCirculatingSupply,
|
||||
name,
|
||||
color,
|
||||
@@ -209,22 +209,22 @@ export function createGroupedSupplyInProfitSeries(ctx, list) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createGroupedSupplyInLossSeries(ctx, list) {
|
||||
const { s } = ctx;
|
||||
const { line } = ctx;
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
s({
|
||||
line({
|
||||
metric: tree.unrealized.supplyInLoss.sats,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.sats,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.unrealized.supplyInLoss.bitcoin,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.btc,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.unrealized.supplyInLoss.dollars,
|
||||
name,
|
||||
color,
|
||||
@@ -232,7 +232,7 @@ export function createGroupedSupplyInLossSeries(ctx, list) {
|
||||
}),
|
||||
...("supplyInLossRelToCirculatingSupply" in tree.relative
|
||||
? [
|
||||
s({
|
||||
line({
|
||||
metric: tree.relative.supplyInLossRelToCirculatingSupply,
|
||||
name,
|
||||
color,
|
||||
@@ -251,10 +251,10 @@ export function createGroupedSupplyInLossSeries(ctx, list) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createUtxoCountSeries(ctx, list, useGroupName) {
|
||||
const { s } = ctx;
|
||||
const { line } = ctx;
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
s({
|
||||
line({
|
||||
metric: tree.outputs.utxoCount,
|
||||
name: useGroupName ? name : "Count",
|
||||
color,
|
||||
@@ -271,10 +271,10 @@ export function createUtxoCountSeries(ctx, list, useGroupName) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createAddressCountSeries(ctx, list, useGroupName) {
|
||||
const { s, colors } = ctx;
|
||||
const { line, colors } = ctx;
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
s({
|
||||
line({
|
||||
metric: tree.addrCount,
|
||||
name: useGroupName ? name : "Count",
|
||||
color: useGroupName ? color : colors.orange,
|
||||
@@ -290,10 +290,10 @@ export function createAddressCountSeries(ctx, list, useGroupName) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createRealizedPriceSeries(ctx, list) {
|
||||
const { s } = ctx;
|
||||
const { line } = ctx;
|
||||
|
||||
return list.map(({ color, name, tree }) =>
|
||||
s({ metric: tree.realized.realizedPrice, name, color, unit: Unit.usd }),
|
||||
line({ metric: tree.realized.realizedPrice, name, color, unit: Unit.usd }),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -304,11 +304,11 @@ export function createRealizedPriceSeries(ctx, list) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createRealizedPriceRatioSeries(ctx, list) {
|
||||
const { s, createPriceLine } = ctx;
|
||||
const { line, createPriceLine } = ctx;
|
||||
|
||||
return [
|
||||
...list.map(({ color, name, tree }) =>
|
||||
s({
|
||||
line({
|
||||
metric: tree.realized.realizedPriceExtra.ratio,
|
||||
name,
|
||||
color,
|
||||
@@ -327,10 +327,10 @@ export function createRealizedPriceRatioSeries(ctx, list) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createRealizedCapSeries(ctx, list, useGroupName) {
|
||||
const { s } = ctx;
|
||||
const { line } = ctx;
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
s({
|
||||
line({
|
||||
metric: tree.realized.realizedCap,
|
||||
name: useGroupName ? name : "Capitalization",
|
||||
color,
|
||||
@@ -347,16 +347,16 @@ export function createRealizedCapSeries(ctx, list, useGroupName) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createCostBasisMinMaxSeries(ctx, list, useGroupName) {
|
||||
const { s } = ctx;
|
||||
const { line } = ctx;
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
s({
|
||||
line({
|
||||
metric: tree.costBasis.min,
|
||||
name: useGroupName ? `${name} min` : "Min",
|
||||
color,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: tree.costBasis.max,
|
||||
name: useGroupName ? `${name} max` : "Max",
|
||||
color,
|
||||
@@ -373,39 +373,39 @@ export function createCostBasisMinMaxSeries(ctx, list, useGroupName) {
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createCostBasisPercentilesSeries(ctx, list, useGroupName) {
|
||||
const { s } = ctx;
|
||||
const { line } = ctx;
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => {
|
||||
const percentiles = tree.costBasis.percentiles;
|
||||
return [
|
||||
s({
|
||||
line({
|
||||
metric: percentiles.costBasisPct10,
|
||||
name: useGroupName ? `${name} p10` : "p10",
|
||||
color,
|
||||
unit: Unit.usd,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: percentiles.costBasisPct25,
|
||||
name: useGroupName ? `${name} p25` : "p25",
|
||||
color,
|
||||
unit: Unit.usd,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: percentiles.costBasisPct50,
|
||||
name: useGroupName ? `${name} p50` : "p50",
|
||||
color,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: percentiles.costBasisPct75,
|
||||
name: useGroupName ? `${name} p75` : "p75",
|
||||
color,
|
||||
unit: Unit.usd,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: percentiles.costBasisPct90,
|
||||
name: useGroupName ? `${name} p90` : "p90",
|
||||
color,
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
/**
|
||||
* Cohort-related type definitions
|
||||
* Types are defined in ../types.js, this file exists for documentation
|
||||
*/
|
||||
|
||||
export {};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,7 @@ function createCointimePriceWithRatioOptions(
|
||||
ctx,
|
||||
{ title, legend, price, ratio, color },
|
||||
) {
|
||||
const { s, colors, createPriceLine } = ctx;
|
||||
const { line, colors, createPriceLine } = ctx;
|
||||
|
||||
// Percentile USD mappings
|
||||
const percentileUsdMap = [
|
||||
@@ -68,15 +68,15 @@ function createCointimePriceWithRatioOptions(
|
||||
{
|
||||
name: "price",
|
||||
title,
|
||||
top: [s({ metric: price, name: legend, color, unit: Unit.usd })],
|
||||
top: [line({ metric: price, name: legend, color, unit: Unit.usd })],
|
||||
},
|
||||
{
|
||||
name: "Ratio",
|
||||
title: `${title} Ratio`,
|
||||
top: [
|
||||
s({ metric: price, name: legend, color, unit: Unit.usd }),
|
||||
line({ metric: price, name: legend, color, unit: Unit.usd }),
|
||||
...percentileUsdMap.map(({ name: pctName, prop, color: pctColor }) =>
|
||||
s({
|
||||
line({
|
||||
metric: prop,
|
||||
name: pctName,
|
||||
color: pctColor,
|
||||
@@ -87,45 +87,45 @@ function createCointimePriceWithRatioOptions(
|
||||
),
|
||||
],
|
||||
bottom: [
|
||||
s({ metric: ratio.ratio, name: "Ratio", color, unit: Unit.ratio }),
|
||||
s({
|
||||
line({ metric: ratio.ratio, name: "Ratio", color, unit: Unit.ratio }),
|
||||
line({
|
||||
metric: ratio.ratio1wSma,
|
||||
name: "1w SMA",
|
||||
color: colors.lime,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: ratio.ratio1mSma,
|
||||
name: "1m SMA",
|
||||
color: colors.teal,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: ratio.ratio1ySd.sma,
|
||||
name: "1y SMA",
|
||||
color: colors.sky,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: ratio.ratio2ySd.sma,
|
||||
name: "2y SMA",
|
||||
color: colors.indigo,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: ratio.ratio4ySd.sma,
|
||||
name: "4y SMA",
|
||||
color: colors.purple,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: ratio.ratioSd.sma,
|
||||
name: "All SMA",
|
||||
color: colors.rose,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
...percentileMap.map(({ name: pctName, prop, color: pctColor }) =>
|
||||
s({
|
||||
line({
|
||||
metric: prop,
|
||||
name: pctName,
|
||||
color: pctColor,
|
||||
@@ -143,10 +143,15 @@ function createCointimePriceWithRatioOptions(
|
||||
name: nameAddon,
|
||||
title: `${title} ${titleAddon} Z-Score`,
|
||||
top: getSdBands(sd).map(({ name: bandName, prop, color: bandColor }) =>
|
||||
s({ metric: prop, name: bandName, color: bandColor, unit: Unit.usd }),
|
||||
line({
|
||||
metric: prop,
|
||||
name: bandName,
|
||||
color: bandColor,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
),
|
||||
bottom: [
|
||||
s({ metric: sd.zscore, name: "Z-Score", color, unit: Unit.sd }),
|
||||
line({ metric: sd.zscore, name: "Z-Score", color, unit: Unit.sd }),
|
||||
createPriceLine({ unit: Unit.sd, number: 3 }),
|
||||
createPriceLine({ unit: Unit.sd, number: 2 }),
|
||||
createPriceLine({ unit: Unit.sd, number: 1 }),
|
||||
@@ -166,7 +171,7 @@ function createCointimePriceWithRatioOptions(
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
export function createCointimeSection(ctx) {
|
||||
const { colors, brk, s } = ctx;
|
||||
const { colors, brk, line } = ctx;
|
||||
const { cointime, distribution, supply } = brk.tree;
|
||||
const { pricing, cap, activity, supply: cointimeSupply, adjusted } = cointime;
|
||||
const { all } = distribution.utxoCohorts;
|
||||
@@ -248,7 +253,7 @@ export function createCointimeSection(ctx) {
|
||||
name: "Compare",
|
||||
title: "Compare Cointime Prices",
|
||||
top: cointimePrices.map(({ price, name, color }) =>
|
||||
s({ metric: price, name, color, unit: Unit.usd }),
|
||||
line({ metric: price, name, color, unit: Unit.usd }),
|
||||
),
|
||||
},
|
||||
...cointimePrices.map(({ price, ratio, name, color, title }) => ({
|
||||
@@ -272,20 +277,20 @@ export function createCointimeSection(ctx) {
|
||||
name: "Compare",
|
||||
title: "Compare Cointime Capitalizations",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: supply.marketCap,
|
||||
name: "Market",
|
||||
color: colors.default,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: all.realized.realizedCap,
|
||||
name: "Realized",
|
||||
color: colors.orange,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
...cointimeCapitalizations.map(({ metric, name, color }) =>
|
||||
s({ metric, name, color, unit: Unit.usd }),
|
||||
line({ metric, name, color, unit: Unit.usd }),
|
||||
),
|
||||
],
|
||||
},
|
||||
@@ -293,14 +298,14 @@ export function createCointimeSection(ctx) {
|
||||
name,
|
||||
title,
|
||||
bottom: [
|
||||
s({ metric, name, color, unit: Unit.usd }),
|
||||
s({
|
||||
line({ metric, name, color, unit: Unit.usd }),
|
||||
line({
|
||||
metric: supply.marketCap,
|
||||
name: "Market",
|
||||
color: colors.default,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: all.realized.realizedCap,
|
||||
name: "Realized",
|
||||
color: colors.orange,
|
||||
@@ -317,19 +322,19 @@ export function createCointimeSection(ctx) {
|
||||
title: "Cointime Supply",
|
||||
bottom: [
|
||||
// All supply (different pattern structure)
|
||||
s({
|
||||
line({
|
||||
metric: all.supply.total.sats,
|
||||
name: "All",
|
||||
color: colors.orange,
|
||||
unit: Unit.sats,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: all.supply.total.bitcoin,
|
||||
name: "All",
|
||||
color: colors.orange,
|
||||
unit: Unit.btc,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: all.supply.total.dollars,
|
||||
name: "All",
|
||||
color: colors.orange,
|
||||
@@ -340,9 +345,9 @@ export function createCointimeSection(ctx) {
|
||||
[cointimeSupply.vaultedSupply, "Vaulted", colors.lime],
|
||||
[cointimeSupply.activeSupply, "Active", colors.rose],
|
||||
]).flatMap(([supplyItem, name, color]) => [
|
||||
s({ metric: supplyItem.sats, name, color, unit: Unit.sats }),
|
||||
s({ metric: supplyItem.bitcoin, name, color, unit: Unit.btc }),
|
||||
s({ metric: supplyItem.dollars, name, color, unit: Unit.usd }),
|
||||
line({ metric: supplyItem.sats, name, color, unit: Unit.sats }),
|
||||
line({ metric: supplyItem.bitcoin, name, color, unit: Unit.btc }),
|
||||
line({ metric: supplyItem.dollars, name, color, unit: Unit.usd }),
|
||||
]),
|
||||
],
|
||||
},
|
||||
@@ -352,19 +357,19 @@ export function createCointimeSection(ctx) {
|
||||
name: "Liveliness & Vaultedness",
|
||||
title: "Liveliness & Vaultedness",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: activity.liveliness,
|
||||
name: "Liveliness",
|
||||
color: colors.rose,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: activity.vaultedness,
|
||||
name: "Vaultedness",
|
||||
color: colors.lime,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: activity.activityToVaultednessRatio,
|
||||
name: "Liveliness / Vaultedness",
|
||||
color: colors.purple,
|
||||
@@ -379,13 +384,13 @@ export function createCointimeSection(ctx) {
|
||||
title: "Coinblocks",
|
||||
bottom: [
|
||||
// Destroyed comes from the all cohort's activity
|
||||
s({
|
||||
line({
|
||||
metric: all.activity.coinblocksDestroyed.sum,
|
||||
name: "Destroyed",
|
||||
color: colors.red,
|
||||
unit: Unit.coinblocks,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: all.activity.coinblocksDestroyed.cumulative,
|
||||
name: "Cumulative Destroyed",
|
||||
color: colors.red,
|
||||
@@ -393,26 +398,26 @@ export function createCointimeSection(ctx) {
|
||||
unit: Unit.coinblocks,
|
||||
}),
|
||||
// Created and stored from cointime
|
||||
s({
|
||||
line({
|
||||
metric: activity.coinblocksCreated.sum,
|
||||
name: "Created",
|
||||
color: colors.orange,
|
||||
unit: Unit.coinblocks,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: activity.coinblocksCreated.cumulative,
|
||||
name: "Cumulative Created",
|
||||
color: colors.orange,
|
||||
defaultActive: false,
|
||||
unit: Unit.coinblocks,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: activity.coinblocksStored.sum,
|
||||
name: "Stored",
|
||||
color: colors.green,
|
||||
unit: Unit.coinblocks,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: activity.coinblocksStored.cumulative,
|
||||
name: "Cumulative Stored",
|
||||
color: colors.green,
|
||||
@@ -431,13 +436,13 @@ export function createCointimeSection(ctx) {
|
||||
name: "Inflation",
|
||||
title: "Cointime-Adjusted Inflation Rate",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: supply.inflation,
|
||||
name: "Base",
|
||||
color: colors.orange,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: adjusted.cointimeAdjInflationRate,
|
||||
name: "Adjusted",
|
||||
color: colors.purple,
|
||||
@@ -450,25 +455,25 @@ export function createCointimeSection(ctx) {
|
||||
name: "Velocity",
|
||||
title: "Cointime-Adjusted Transactions Velocity",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: supply.velocity.btc,
|
||||
name: "BTC",
|
||||
color: colors.orange,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: adjusted.cointimeAdjTxBtcVelocity,
|
||||
name: "Adj. BTC",
|
||||
color: colors.red,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: supply.velocity.usd,
|
||||
name: "USD",
|
||||
color: colors.emerald,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: adjusted.cointimeAdjTxUsdVelocity,
|
||||
name: "Adj. USD",
|
||||
color: colors.lime,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/** Constant helpers for creating price lines and reference lines */
|
||||
|
||||
import { line } from "./series.js";
|
||||
|
||||
/**
|
||||
* Get constant pattern by number dynamically from tree
|
||||
* Examples: 0 → constant0, 38.2 → constant382, -1 → constantMinus1
|
||||
@@ -92,7 +94,7 @@ export function createPriceLines({ constants, colors, numbers, unit }) {
|
||||
* @param {boolean} [args.defaultActive]
|
||||
* @returns {FetchedLineSeriesBlueprint}
|
||||
*/
|
||||
export function line({
|
||||
export function constantLine({
|
||||
colors,
|
||||
constant,
|
||||
name,
|
||||
@@ -101,9 +103,9 @@ export function line({
|
||||
lineStyle,
|
||||
defaultActive,
|
||||
}) {
|
||||
return {
|
||||
return line({
|
||||
metric: constant,
|
||||
title: name,
|
||||
name,
|
||||
unit,
|
||||
defaultActive,
|
||||
color: color ?? colors.gray,
|
||||
@@ -112,5 +114,5 @@ export function line({
|
||||
lastValueVisible: false,
|
||||
crosshairMarkerVisible: false,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import {
|
||||
s,
|
||||
line,
|
||||
baseline,
|
||||
histogram,
|
||||
fromBlockCount,
|
||||
fromBitcoin,
|
||||
fromBlockSize,
|
||||
@@ -8,10 +10,12 @@ import {
|
||||
fromFeeRatePattern,
|
||||
fromCoinbasePattern,
|
||||
fromValuePattern,
|
||||
fromBitcoinPatternWithUnit,
|
||||
fromBlockCountWithUnit,
|
||||
fromIntervalPattern,
|
||||
fromSupplyPattern,
|
||||
} from "./series.js";
|
||||
import { createPriceLine, createPriceLines, line } from "./constants.js";
|
||||
import { createPriceLine, createPriceLines, constantLine } from "./constants.js";
|
||||
|
||||
/**
|
||||
* Create a context object with all dependencies for building partial options
|
||||
@@ -28,7 +32,9 @@ export function createContext({ colors, brk }) {
|
||||
brk,
|
||||
|
||||
// Series helpers
|
||||
s,
|
||||
line,
|
||||
baseline,
|
||||
histogram,
|
||||
fromBlockCount: (pattern, title, color) =>
|
||||
fromBlockCount(colors, pattern, title, color),
|
||||
fromBitcoin: (pattern, title, color) =>
|
||||
@@ -45,14 +51,38 @@ export function createContext({ colors, brk }) {
|
||||
fromCoinbasePattern(colors, pattern, title),
|
||||
fromValuePattern: (pattern, title, sumColor, cumulativeColor) =>
|
||||
fromValuePattern(colors, pattern, title, sumColor, cumulativeColor),
|
||||
fromBitcoinPatternWithUnit: (
|
||||
pattern,
|
||||
title,
|
||||
unit,
|
||||
sumColor,
|
||||
cumulativeColor,
|
||||
) =>
|
||||
fromBitcoinPatternWithUnit(
|
||||
colors,
|
||||
pattern,
|
||||
title,
|
||||
unit,
|
||||
sumColor,
|
||||
cumulativeColor,
|
||||
),
|
||||
fromBlockCountWithUnit: (pattern, title, unit, sumColor, cumulativeColor) =>
|
||||
fromBlockCountWithUnit(colors, pattern, title, unit, sumColor, cumulativeColor),
|
||||
fromBlockCountWithUnit(
|
||||
colors,
|
||||
pattern,
|
||||
title,
|
||||
unit,
|
||||
sumColor,
|
||||
cumulativeColor,
|
||||
),
|
||||
fromIntervalPattern: (pattern, title, unit, color) =>
|
||||
fromIntervalPattern(colors, pattern, title, unit, color),
|
||||
fromSupplyPattern: (pattern, title, color) =>
|
||||
fromSupplyPattern(colors, pattern, title, color),
|
||||
|
||||
createPriceLine: (args) => createPriceLine({ constants, colors, ...args }),
|
||||
createPriceLines: (args) =>
|
||||
createPriceLines({ constants, colors, ...args }),
|
||||
line: (args) => line({ colors, ...args }),
|
||||
constantLine: (args) => constantLine({ colors, ...args }),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -44,8 +44,11 @@ export function buildAverages(colors, ma) {
|
||||
* @param {Color} [args.color]
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
export function createPriceWithRatioOptions(ctx, { title, legend, ratio, color }) {
|
||||
const { s, colors, createPriceLine } = ctx;
|
||||
export function createPriceWithRatioOptions(
|
||||
ctx,
|
||||
{ title, legend, ratio, color },
|
||||
) {
|
||||
const { line, colors, createPriceLine } = ctx;
|
||||
const priceMetric = ratio.price;
|
||||
|
||||
const percentileUsdMap = [
|
||||
@@ -94,27 +97,71 @@ export function createPriceWithRatioOptions(ctx, { title, legend, ratio, color }
|
||||
{
|
||||
name: "price",
|
||||
title,
|
||||
top: [s({ metric: priceMetric, name: legend, color, unit: Unit.usd })],
|
||||
top: [line({ metric: priceMetric, name: legend, color, unit: Unit.usd })],
|
||||
},
|
||||
{
|
||||
name: "Ratio",
|
||||
title: `${title} Ratio`,
|
||||
top: [
|
||||
s({ metric: priceMetric, name: legend, color, unit: Unit.usd }),
|
||||
line({ metric: priceMetric, name: legend, color, unit: Unit.usd }),
|
||||
...percentileUsdMap.map(({ name: pctName, prop, color: pctColor }) =>
|
||||
s({ metric: prop, name: pctName, color: pctColor, defaultActive: false, unit: Unit.usd, options: { lineStyle: 1 } }),
|
||||
line({
|
||||
metric: prop,
|
||||
name: pctName,
|
||||
color: pctColor,
|
||||
defaultActive: false,
|
||||
unit: Unit.usd,
|
||||
options: { lineStyle: 1 },
|
||||
}),
|
||||
),
|
||||
],
|
||||
bottom: [
|
||||
s({ metric: ratio.ratio, name: "Ratio", color, unit: Unit.ratio }),
|
||||
s({ metric: ratio.ratio1wSma, name: "1w SMA", color: colors.lime, unit: Unit.ratio }),
|
||||
s({ metric: ratio.ratio1mSma, name: "1m SMA", color: colors.teal, unit: Unit.ratio }),
|
||||
s({ metric: ratio.ratio1ySd.sma, name: "1y SMA", color: colors.sky, unit: Unit.ratio }),
|
||||
s({ metric: ratio.ratio2ySd.sma, name: "2y SMA", color: colors.indigo, unit: Unit.ratio }),
|
||||
s({ metric: ratio.ratio4ySd.sma, name: "4y SMA", color: colors.purple, unit: Unit.ratio }),
|
||||
s({ metric: ratio.ratioSd.sma, name: "All SMA", color: colors.rose, unit: Unit.ratio }),
|
||||
line({ metric: ratio.ratio, name: "Ratio", color, unit: Unit.ratio }),
|
||||
line({
|
||||
metric: ratio.ratio1wSma,
|
||||
name: "1w SMA",
|
||||
color: colors.lime,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
line({
|
||||
metric: ratio.ratio1mSma,
|
||||
name: "1m SMA",
|
||||
color: colors.teal,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
line({
|
||||
metric: ratio.ratio1ySd.sma,
|
||||
name: "1y SMA",
|
||||
color: colors.sky,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
line({
|
||||
metric: ratio.ratio2ySd.sma,
|
||||
name: "2y SMA",
|
||||
color: colors.indigo,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
line({
|
||||
metric: ratio.ratio4ySd.sma,
|
||||
name: "4y SMA",
|
||||
color: colors.purple,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
line({
|
||||
metric: ratio.ratioSd.sma,
|
||||
name: "All SMA",
|
||||
color: colors.rose,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
...percentileMap.map(({ name: pctName, prop, color: pctColor }) =>
|
||||
s({ metric: prop, name: pctName, color: pctColor, defaultActive: false, unit: Unit.ratio, options: { lineStyle: 1 } }),
|
||||
line({
|
||||
metric: prop,
|
||||
name: pctName,
|
||||
color: pctColor,
|
||||
defaultActive: false,
|
||||
unit: Unit.ratio,
|
||||
options: { lineStyle: 1 },
|
||||
}),
|
||||
),
|
||||
createPriceLine({ unit: Unit.ratio, number: 1 }),
|
||||
],
|
||||
@@ -125,10 +172,15 @@ export function createPriceWithRatioOptions(ctx, { title, legend, ratio, color }
|
||||
name: nameAddon,
|
||||
title: `${title} ${titleAddon} Z-Score`,
|
||||
top: getSdBands(sd).map(({ name: bandName, prop, color: bandColor }) =>
|
||||
s({ metric: prop, name: bandName, color: bandColor, unit: Unit.usd }),
|
||||
line({
|
||||
metric: prop,
|
||||
name: bandName,
|
||||
color: bandColor,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
),
|
||||
bottom: [
|
||||
s({ metric: sd.zscore, name: "Z-Score", color, unit: Unit.sd }),
|
||||
line({ metric: sd.zscore, name: "Z-Score", color, unit: Unit.sd }),
|
||||
createPriceLine({ unit: Unit.sd, number: 3 }),
|
||||
createPriceLine({ unit: Unit.sd, number: 2 }),
|
||||
createPriceLine({ unit: Unit.sd, number: 1 }),
|
||||
@@ -148,7 +200,7 @@ export function createPriceWithRatioOptions(ctx, { title, legend, ratio, color }
|
||||
* @param {ReturnType<typeof buildAverages>} averages
|
||||
*/
|
||||
export function createAveragesSection(ctx, averages) {
|
||||
const { s } = ctx;
|
||||
const { line } = ctx;
|
||||
|
||||
return {
|
||||
name: "Averages",
|
||||
@@ -162,7 +214,12 @@ export function createAveragesSection(ctx, averages) {
|
||||
name: "Compare",
|
||||
title: `Market Price ${nameAddon} Moving Averages`,
|
||||
top: averages.map(({ id, color, sma, ema }) =>
|
||||
s({ metric: (metricAddon === "sma" ? sma : ema).price, name: id, color, unit: Unit.usd }),
|
||||
line({
|
||||
metric: (metricAddon === "sma" ? sma : ema).price,
|
||||
name: id,
|
||||
color,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
),
|
||||
},
|
||||
...averages.map(({ name, color, sma, ema }) => ({
|
||||
|
||||
@@ -12,7 +12,7 @@ import { createInvestingSection } from "./investing.js";
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
export function createMarketSection(ctx) {
|
||||
const { colors, brk, s } = ctx;
|
||||
const { colors, brk, line } = ctx;
|
||||
const { market, supply } = brk.tree;
|
||||
const {
|
||||
movingAverage,
|
||||
@@ -41,7 +41,7 @@ export function createMarketSection(ctx) {
|
||||
name: "Capitalization",
|
||||
title: "Market Capitalization",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: supply.marketCap,
|
||||
name: "Capitalization",
|
||||
unit: Unit.usd,
|
||||
@@ -53,27 +53,31 @@ export function createMarketSection(ctx) {
|
||||
{
|
||||
name: "All Time High",
|
||||
title: "All Time High",
|
||||
top: [s({ metric: ath.priceAth, name: "ATH", unit: Unit.usd })],
|
||||
top: [line({ metric: ath.priceAth, name: "ATH", unit: Unit.usd })],
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: ath.priceDrawdown,
|
||||
name: "Drawdown",
|
||||
color: colors.red,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
s({ metric: ath.daysSincePriceAth, name: "Since", unit: Unit.days }),
|
||||
s({
|
||||
line({
|
||||
metric: ath.daysSincePriceAth,
|
||||
name: "Since",
|
||||
unit: Unit.days,
|
||||
}),
|
||||
line({
|
||||
metric: ath.yearsSincePriceAth,
|
||||
name: "Since",
|
||||
unit: Unit.years,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: ath.maxDaysBetweenPriceAths,
|
||||
name: "Max",
|
||||
color: colors.red,
|
||||
unit: Unit.days,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: ath.maxYearsBetweenPriceAths,
|
||||
name: "Max",
|
||||
color: colors.red,
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Unit } from "../../../utils/units.js";
|
||||
* @param {Market["movingAverage"]} args.movingAverage
|
||||
*/
|
||||
export function createBandsSection(ctx, { range, movingAverage }) {
|
||||
const { s, colors } = ctx;
|
||||
const { line, colors } = ctx;
|
||||
|
||||
return {
|
||||
name: "Bands",
|
||||
@@ -46,8 +46,13 @@ export function createBandsSection(ctx, { range, movingAverage }) {
|
||||
name: id,
|
||||
title: `Bitcoin Price ${title} MinMax Bands`,
|
||||
top: [
|
||||
s({ metric: min, name: "Min", color: colors.red, unit: Unit.usd }),
|
||||
s({
|
||||
line({
|
||||
metric: min,
|
||||
name: "Min",
|
||||
color: colors.red,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
line({
|
||||
metric: max,
|
||||
name: "Max",
|
||||
color: colors.green,
|
||||
@@ -60,19 +65,19 @@ export function createBandsSection(ctx, { range, movingAverage }) {
|
||||
name: "Mayer Multiple",
|
||||
title: "Mayer Multiple",
|
||||
top: [
|
||||
s({
|
||||
line({
|
||||
metric: movingAverage.price200dSma.price,
|
||||
name: "200d SMA",
|
||||
color: colors.yellow,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: movingAverage.price200dSmaX24,
|
||||
name: "200d SMA x2.4",
|
||||
color: colors.green,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: movingAverage.price200dSmaX08,
|
||||
name: "200d SMA x0.8",
|
||||
color: colors.red,
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Unit } from "../../../utils/units.js";
|
||||
* @param {Market["indicators"]} indicators
|
||||
*/
|
||||
export function createMomentumSection(ctx, indicators) {
|
||||
const { s, colors, createPriceLine } = ctx;
|
||||
const { line, histogram, colors, createPriceLine } = ctx;
|
||||
|
||||
return {
|
||||
name: "Momentum",
|
||||
@@ -17,20 +17,20 @@ export function createMomentumSection(ctx, indicators) {
|
||||
name: "RSI",
|
||||
title: "Relative Strength Index (14d)",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: indicators.rsi14d,
|
||||
name: "RSI",
|
||||
color: colors.indigo,
|
||||
unit: Unit.index,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: indicators.rsi14dMin,
|
||||
name: "Min",
|
||||
color: colors.red,
|
||||
defaultActive: false,
|
||||
unit: Unit.index,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: indicators.rsi14dMax,
|
||||
name: "Max",
|
||||
color: colors.green,
|
||||
@@ -38,7 +38,11 @@ export function createMomentumSection(ctx, indicators) {
|
||||
unit: Unit.index,
|
||||
}),
|
||||
createPriceLine({ unit: Unit.index, number: 70 }),
|
||||
createPriceLine({ unit: Unit.index, number: 50, defaultActive: false }),
|
||||
createPriceLine({
|
||||
unit: Unit.index,
|
||||
number: 50,
|
||||
defaultActive: false,
|
||||
}),
|
||||
createPriceLine({ unit: Unit.index, number: 30 }),
|
||||
],
|
||||
},
|
||||
@@ -46,19 +50,19 @@ export function createMomentumSection(ctx, indicators) {
|
||||
name: "StochRSI",
|
||||
title: "Stochastic RSI",
|
||||
bottom: [
|
||||
// s({
|
||||
// line({
|
||||
// metric: indicators.stochRsi,
|
||||
// name: "Stoch RSI",
|
||||
// color: colors.purple,
|
||||
// unit: Unit.index,
|
||||
// }),
|
||||
s({
|
||||
line({
|
||||
metric: indicators.stochRsiK,
|
||||
name: "K",
|
||||
color: colors.blue,
|
||||
unit: Unit.index,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: indicators.stochRsiD,
|
||||
name: "D",
|
||||
color: colors.orange,
|
||||
@@ -72,8 +76,8 @@ export function createMomentumSection(ctx, indicators) {
|
||||
// name: "Stochastic",
|
||||
// title: "Stochastic Oscillator",
|
||||
// bottom: [
|
||||
// s({ metric: indicators.stochK, name: "K", color: colors.blue, unit: Unit.index }),
|
||||
// s({ metric: indicators.stochD, name: "D", color: colors.orange, unit: Unit.index }),
|
||||
// line({ metric: indicators.stochK, name: "K", color: colors.blue, unit: Unit.index }),
|
||||
// line({ metric: indicators.stochD, name: "D", color: colors.orange, unit: Unit.index }),
|
||||
// createPriceLine({ unit: Unit.index, number: 80 }),
|
||||
// createPriceLine({ unit: Unit.index, number: 20 }),
|
||||
// ],
|
||||
@@ -82,22 +86,21 @@ export function createMomentumSection(ctx, indicators) {
|
||||
name: "MACD",
|
||||
title: "Moving Average Convergence Divergence",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: indicators.macdLine,
|
||||
name: "MACD",
|
||||
color: colors.blue,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: indicators.macdSignal,
|
||||
name: "Signal",
|
||||
color: colors.orange,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
/** @type {FetchedHistogramSeriesBlueprint} */ ({
|
||||
histogram({
|
||||
metric: indicators.macdHistogram,
|
||||
title: "Histogram",
|
||||
type: "Histogram",
|
||||
name: "Histogram",
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
createPriceLine({ unit: Unit.usd }),
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Unit } from "../../../utils/units.js";
|
||||
* @param {Market["movingAverage"]} args.movingAverage
|
||||
*/
|
||||
export function createOnchainSection(ctx, { indicators, movingAverage }) {
|
||||
const { s, colors, createPriceLine } = ctx;
|
||||
const { line, colors, createPriceLine } = ctx;
|
||||
|
||||
return {
|
||||
name: "On-chain",
|
||||
@@ -19,13 +19,13 @@ export function createOnchainSection(ctx, { indicators, movingAverage }) {
|
||||
name: "Pi Cycle",
|
||||
title: "Pi Cycle Top Indicator",
|
||||
top: [
|
||||
s({
|
||||
line({
|
||||
metric: movingAverage.price111dSma.price,
|
||||
name: "111d SMA",
|
||||
color: colors.green,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: movingAverage.price350dSmaX2,
|
||||
name: "350d SMA x2",
|
||||
color: colors.red,
|
||||
@@ -33,7 +33,7 @@ export function createOnchainSection(ctx, { indicators, movingAverage }) {
|
||||
}),
|
||||
],
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: indicators.piCycle,
|
||||
name: "Pi Cycle",
|
||||
color: colors.purple,
|
||||
@@ -46,7 +46,7 @@ export function createOnchainSection(ctx, { indicators, movingAverage }) {
|
||||
name: "Puell Multiple",
|
||||
title: "Puell Multiple",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: indicators.puellMultiple,
|
||||
name: "Puell",
|
||||
color: colors.green,
|
||||
@@ -58,7 +58,7 @@ export function createOnchainSection(ctx, { indicators, movingAverage }) {
|
||||
name: "NVT",
|
||||
title: "Network Value to Transactions Ratio",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: indicators.nvt,
|
||||
name: "NVT",
|
||||
color: colors.orange,
|
||||
@@ -70,7 +70,7 @@ export function createOnchainSection(ctx, { indicators, movingAverage }) {
|
||||
name: "Gini",
|
||||
title: "Gini Coefficient",
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: indicators.gini,
|
||||
name: "Gini",
|
||||
color: colors.red,
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Unit } from "../../../utils/units.js";
|
||||
* @param {Market["range"]} args.range
|
||||
*/
|
||||
export function createVolatilitySection(ctx, { volatility, range }) {
|
||||
const { s, colors, createPriceLine } = ctx;
|
||||
const { line, colors, createPriceLine } = ctx;
|
||||
|
||||
return {
|
||||
name: "Volatility",
|
||||
@@ -19,21 +19,48 @@ export function createVolatilitySection(ctx, { volatility, range }) {
|
||||
name: "Index",
|
||||
title: "Bitcoin Price Volatility Index",
|
||||
bottom: [
|
||||
s({ metric: volatility.price1wVolatility, name: "1w", color: colors.red, unit: Unit.percentage }),
|
||||
s({ metric: volatility.price1mVolatility, name: "1m", color: colors.orange, unit: Unit.percentage }),
|
||||
s({ metric: volatility.price1yVolatility, name: "1y", color: colors.lime, unit: Unit.percentage }),
|
||||
line({
|
||||
metric: volatility.price1wVolatility,
|
||||
name: "1w",
|
||||
color: colors.red,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
line({
|
||||
metric: volatility.price1mVolatility,
|
||||
name: "1m",
|
||||
color: colors.orange,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
line({
|
||||
metric: volatility.price1yVolatility,
|
||||
name: "1y",
|
||||
color: colors.lime,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "True Range",
|
||||
title: "Bitcoin Price True Range",
|
||||
bottom: [s({ metric: range.priceTrueRange, name: "Value", color: colors.yellow, unit: Unit.usd })],
|
||||
bottom: [
|
||||
line({
|
||||
metric: range.priceTrueRange,
|
||||
name: "Value",
|
||||
color: colors.yellow,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Choppiness",
|
||||
title: "Bitcoin Price Choppiness Index",
|
||||
bottom: [
|
||||
s({ metric: range.price2wChoppinessIndex, name: "2w", color: colors.red, unit: Unit.index }),
|
||||
line({
|
||||
metric: range.price2wChoppinessIndex,
|
||||
name: "2w",
|
||||
color: colors.red,
|
||||
unit: Unit.index,
|
||||
}),
|
||||
createPriceLine({ unit: Unit.index, number: 61.8 }),
|
||||
createPriceLine({ unit: Unit.index, number: 38.2 }),
|
||||
],
|
||||
@@ -42,9 +69,24 @@ export function createVolatilitySection(ctx, { volatility, range }) {
|
||||
name: "Sharpe Ratio",
|
||||
title: "Sharpe Ratio",
|
||||
bottom: [
|
||||
s({ metric: volatility.sharpe1w, name: "1w", color: colors.red, unit: Unit.ratio }),
|
||||
s({ metric: volatility.sharpe1m, name: "1m", color: colors.orange, unit: Unit.ratio }),
|
||||
s({ metric: volatility.sharpe1y, name: "1y", color: colors.lime, unit: Unit.ratio }),
|
||||
line({
|
||||
metric: volatility.sharpe1w,
|
||||
name: "1w",
|
||||
color: colors.red,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
line({
|
||||
metric: volatility.sharpe1m,
|
||||
name: "1m",
|
||||
color: colors.orange,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
line({
|
||||
metric: volatility.sharpe1y,
|
||||
name: "1y",
|
||||
color: colors.lime,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
createPriceLine({ unit: Unit.ratio }),
|
||||
],
|
||||
},
|
||||
@@ -52,9 +94,24 @@ export function createVolatilitySection(ctx, { volatility, range }) {
|
||||
name: "Sortino Ratio",
|
||||
title: "Sortino Ratio",
|
||||
bottom: [
|
||||
s({ metric: volatility.sortino1w, name: "1w", color: colors.red, unit: Unit.ratio }),
|
||||
s({ metric: volatility.sortino1m, name: "1m", color: colors.orange, unit: Unit.ratio }),
|
||||
s({ metric: volatility.sortino1y, name: "1y", color: colors.lime, unit: Unit.ratio }),
|
||||
line({
|
||||
metric: volatility.sortino1w,
|
||||
name: "1w",
|
||||
color: colors.red,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
line({
|
||||
metric: volatility.sortino1m,
|
||||
name: "1m",
|
||||
color: colors.orange,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
line({
|
||||
metric: volatility.sortino1y,
|
||||
name: "1y",
|
||||
color: colors.lime,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
createPriceLine({ unit: Unit.ratio }),
|
||||
],
|
||||
},
|
||||
|
||||
@@ -40,7 +40,7 @@ export function buildDcaClasses(colors, dca) {
|
||||
* @param {Market["returns"]} args.returns
|
||||
*/
|
||||
export function createInvestingSection(ctx, { dca, lookback, returns }) {
|
||||
const { s, colors, createPriceLine } = ctx;
|
||||
const { line, baseline, colors, createPriceLine } = ctx;
|
||||
const dcaClasses = buildDcaClasses(colors, dca);
|
||||
|
||||
return {
|
||||
@@ -77,13 +77,13 @@ export function createInvestingSection(ctx, { dca, lookback, returns }) {
|
||||
name: "Cost basis",
|
||||
title: `${name} DCA vs Lump Sum (Cost Basis)`,
|
||||
top: [
|
||||
s({
|
||||
line({
|
||||
metric: dcaCostBasis,
|
||||
name: "DCA",
|
||||
color: colors.green,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: priceAgo,
|
||||
name: "Lump sum",
|
||||
color: colors.orange,
|
||||
@@ -95,17 +95,15 @@ export function createInvestingSection(ctx, { dca, lookback, returns }) {
|
||||
name: "Returns",
|
||||
title: `${name} DCA vs Lump Sum (Returns)`,
|
||||
bottom: [
|
||||
/** @type {AnyFetchedSeriesBlueprint} */ ({
|
||||
baseline({
|
||||
metric: dcaReturns,
|
||||
title: "DCA",
|
||||
type: "Baseline",
|
||||
name: "DCA",
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
/** @type {AnyFetchedSeriesBlueprint} */ ({
|
||||
baseline({
|
||||
metric: priceReturns,
|
||||
title: "Lump sum",
|
||||
type: "Baseline",
|
||||
colors: [colors.lime, colors.red],
|
||||
name: "Lump sum",
|
||||
color: [colors.lime, colors.red],
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
createPriceLine({ unit: Unit.percentage }),
|
||||
@@ -115,37 +113,37 @@ export function createInvestingSection(ctx, { dca, lookback, returns }) {
|
||||
name: "Stack",
|
||||
title: `${name} DCA vs Lump Sum Stack ($100/day)`,
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: dcaStack.sats,
|
||||
name: "DCA",
|
||||
color: colors.green,
|
||||
unit: Unit.sats,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: dcaStack.bitcoin,
|
||||
name: "DCA",
|
||||
color: colors.green,
|
||||
unit: Unit.btc,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: dcaStack.dollars,
|
||||
name: "DCA",
|
||||
color: colors.green,
|
||||
unit: Unit.usd,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: lumpSumStack.sats,
|
||||
name: "Lump sum",
|
||||
color: colors.orange,
|
||||
unit: Unit.sats,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: lumpSumStack.bitcoin,
|
||||
name: "Lump sum",
|
||||
color: colors.orange,
|
||||
unit: Unit.btc,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: lumpSumStack.dollars,
|
||||
name: "Lump sum",
|
||||
color: colors.orange,
|
||||
@@ -171,7 +169,7 @@ export function createInvestingSection(ctx, { dca, lookback, returns }) {
|
||||
title: "DCA Cost Basis by Year",
|
||||
top: dcaClasses.map(
|
||||
({ year, color, defaultActive, costBasis }) =>
|
||||
s({
|
||||
line({
|
||||
metric: costBasis,
|
||||
name: `${year}`,
|
||||
color,
|
||||
@@ -183,16 +181,14 @@ export function createInvestingSection(ctx, { dca, lookback, returns }) {
|
||||
{
|
||||
name: "Returns",
|
||||
title: "DCA Returns by Year",
|
||||
bottom: dcaClasses.map(
|
||||
({ year, color, defaultActive, returns }) =>
|
||||
/** @type {AnyFetchedSeriesBlueprint} */ ({
|
||||
metric: returns,
|
||||
title: `${year}`,
|
||||
type: "Baseline",
|
||||
color,
|
||||
defaultActive,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
bottom: dcaClasses.map(({ year, color, defaultActive, returns }) =>
|
||||
baseline({
|
||||
metric: returns,
|
||||
name: `${year}`,
|
||||
color,
|
||||
defaultActive,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
),
|
||||
},
|
||||
{
|
||||
@@ -200,21 +196,21 @@ export function createInvestingSection(ctx, { dca, lookback, returns }) {
|
||||
title: "DCA Stack by Year ($100/day)",
|
||||
bottom: dcaClasses.flatMap(
|
||||
({ year, color, defaultActive, stack }) => [
|
||||
s({
|
||||
line({
|
||||
metric: stack.sats,
|
||||
name: `${year}`,
|
||||
color,
|
||||
defaultActive,
|
||||
unit: Unit.sats,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: stack.bitcoin,
|
||||
name: `${year}`,
|
||||
color,
|
||||
defaultActive,
|
||||
unit: Unit.btc,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: stack.dollars,
|
||||
name: `${year}`,
|
||||
color,
|
||||
@@ -234,7 +230,7 @@ export function createInvestingSection(ctx, { dca, lookback, returns }) {
|
||||
name: "Cost basis",
|
||||
title: `DCA Class ${year} Cost Basis`,
|
||||
top: [
|
||||
s({
|
||||
line({
|
||||
metric: costBasis,
|
||||
name: "Cost basis",
|
||||
color,
|
||||
@@ -246,10 +242,9 @@ export function createInvestingSection(ctx, { dca, lookback, returns }) {
|
||||
name: "Returns",
|
||||
title: `DCA Class ${year} Returns`,
|
||||
bottom: [
|
||||
/** @type {AnyFetchedSeriesBlueprint} */ ({
|
||||
baseline({
|
||||
metric: returns,
|
||||
title: "Returns",
|
||||
type: "Baseline",
|
||||
name: "Returns",
|
||||
color,
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
@@ -259,19 +254,19 @@ export function createInvestingSection(ctx, { dca, lookback, returns }) {
|
||||
name: "Stack",
|
||||
title: `DCA Class ${year} Stack ($100/day)`,
|
||||
bottom: [
|
||||
s({
|
||||
line({
|
||||
metric: stack.sats,
|
||||
name: "Stack",
|
||||
color,
|
||||
unit: Unit.sats,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: stack.bitcoin,
|
||||
name: "Stack",
|
||||
color,
|
||||
unit: Unit.btc,
|
||||
}),
|
||||
s({
|
||||
line({
|
||||
metric: stack.dollars,
|
||||
name: "Stack",
|
||||
color,
|
||||
|
||||
@@ -9,7 +9,7 @@ import { periodIdToName } from "./utils.js";
|
||||
* @param {Market["returns"]} returns
|
||||
*/
|
||||
export function createPerformanceSection(ctx, returns) {
|
||||
const { colors, createPriceLine } = ctx;
|
||||
const { colors, baseline, createPriceLine } = ctx;
|
||||
|
||||
return {
|
||||
name: "Performance",
|
||||
@@ -35,19 +35,17 @@ export function createPerformanceSection(ctx, returns) {
|
||||
name,
|
||||
title: `${name} Performance`,
|
||||
bottom: [
|
||||
/** @type {AnyFetchedSeriesBlueprint} */ ({
|
||||
baseline({
|
||||
metric: priceReturns,
|
||||
title: "Total",
|
||||
type: "Baseline",
|
||||
name: "Total",
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
...(cagr
|
||||
? [
|
||||
/** @type {AnyFetchedSeriesBlueprint} */ ({
|
||||
baseline({
|
||||
metric: cagr,
|
||||
title: "CAGR",
|
||||
type: "Baseline",
|
||||
colors: [colors.lime, colors.pink],
|
||||
name: "CAGR",
|
||||
color: [colors.lime, colors.pink],
|
||||
unit: Unit.percentage,
|
||||
}),
|
||||
]
|
||||
|
||||
@@ -4,7 +4,11 @@ import { localhost } from "../utils/env.js";
|
||||
import { createContext } from "./context.js";
|
||||
import {
|
||||
buildCohortData,
|
||||
createUtxoCohortFolder,
|
||||
createCohortFolderAll,
|
||||
createCohortFolderFull,
|
||||
createCohortFolderWithAdjusted,
|
||||
createCohortFolderWithPercentiles,
|
||||
createCohortFolderBasic,
|
||||
createAddressCohortFolder,
|
||||
} from "./cohorts/index.js";
|
||||
import { createMarketSection } from "./market/index.js";
|
||||
@@ -28,8 +32,8 @@ export function createPartialOptions({ colors, brk }) {
|
||||
// Build cohort data
|
||||
const {
|
||||
cohortAll,
|
||||
cohortAllForComparison,
|
||||
terms,
|
||||
termShort,
|
||||
termLong,
|
||||
upToDate,
|
||||
fromDate,
|
||||
dateRange,
|
||||
@@ -43,11 +47,15 @@ export function createPartialOptions({ colors, brk }) {
|
||||
type,
|
||||
} = buildCohortData(colors, brk);
|
||||
|
||||
// Helper to map UTXO cohorts
|
||||
const mapUtxoCohorts = (/** @type {any} */ cohort) => createUtxoCohortFolder(ctx, cohort);
|
||||
|
||||
// Helper to map Address cohorts
|
||||
const mapAddressCohorts = (/** @type {any} */ cohort) => createAddressCohortFolder(ctx, cohort);
|
||||
// Helpers to map cohorts by capability type
|
||||
/** @param {CohortWithAdjusted} cohort */
|
||||
const mapWithAdjusted = (cohort) => createCohortFolderWithAdjusted(ctx, cohort);
|
||||
/** @param {CohortWithPercentiles} cohort */
|
||||
const mapWithPercentiles = (cohort) => createCohortFolderWithPercentiles(ctx, cohort);
|
||||
/** @param {CohortBasic} cohort */
|
||||
const mapBasic = (cohort) => createCohortFolderBasic(ctx, cohort);
|
||||
/** @param {AddressCohortObject} cohort */
|
||||
const mapAddressCohorts = (cohort) => createAddressCohortFolder(ctx, cohort);
|
||||
|
||||
return [
|
||||
// Debug explorer (localhost only)
|
||||
@@ -75,123 +83,120 @@ export function createPartialOptions({ colors, brk }) {
|
||||
{
|
||||
name: "Cohorts",
|
||||
tree: [
|
||||
// All UTXOs
|
||||
createUtxoCohortFolder(ctx, cohortAll),
|
||||
// All UTXOs - CohortAll (adjustedSopr + percentiles but no RelToMarketCap)
|
||||
createCohortFolderAll(ctx, cohortAll),
|
||||
|
||||
// Terms (STH/LTH)
|
||||
// Terms (STH/LTH) - Short is Full, Long is WithPercentiles
|
||||
{
|
||||
name: "terms",
|
||||
tree: [
|
||||
createUtxoCohortFolder(ctx, {
|
||||
name: "Compare",
|
||||
title: "UTXOs Term",
|
||||
list: [...terms, cohortAllForComparison],
|
||||
}),
|
||||
...terms.map(mapUtxoCohorts),
|
||||
// Individual cohorts with their specific capabilities
|
||||
createCohortFolderFull(ctx, termShort),
|
||||
createCohortFolderWithPercentiles(ctx, termLong),
|
||||
],
|
||||
},
|
||||
|
||||
// Epochs
|
||||
// Epochs - CohortBasic (neither adjustedSopr nor percentiles)
|
||||
{
|
||||
name: "Epochs",
|
||||
tree: [
|
||||
createUtxoCohortFolder(ctx, {
|
||||
createCohortFolderBasic(ctx, {
|
||||
name: "Compare",
|
||||
title: "Epoch",
|
||||
list: [...epoch, cohortAllForComparison],
|
||||
list: epoch,
|
||||
}),
|
||||
...epoch.map(mapUtxoCohorts),
|
||||
...epoch.map(mapBasic),
|
||||
],
|
||||
},
|
||||
|
||||
// Types
|
||||
// Types - CohortBasic
|
||||
{
|
||||
name: "types",
|
||||
tree: [
|
||||
createUtxoCohortFolder(ctx, {
|
||||
createCohortFolderBasic(ctx, {
|
||||
name: "Compare",
|
||||
title: "Type",
|
||||
list: [...type, cohortAllForComparison],
|
||||
list: type,
|
||||
}),
|
||||
...type.map(mapUtxoCohorts),
|
||||
...type.map(mapBasic),
|
||||
],
|
||||
},
|
||||
|
||||
// UTXOs Up to age
|
||||
// UTXOs Up to age - CohortWithAdjusted (adjustedSopr only)
|
||||
{
|
||||
name: "UTXOs Up to age",
|
||||
tree: [
|
||||
createUtxoCohortFolder(ctx, {
|
||||
createCohortFolderWithAdjusted(ctx, {
|
||||
name: "Compare",
|
||||
title: "UTXOs Up To Age",
|
||||
list: [...upToDate, cohortAllForComparison],
|
||||
list: upToDate,
|
||||
}),
|
||||
...upToDate.map(mapUtxoCohorts),
|
||||
...upToDate.map(mapWithAdjusted),
|
||||
],
|
||||
},
|
||||
|
||||
// UTXOs from age
|
||||
// UTXOs from age - CohortBasic
|
||||
{
|
||||
name: "UTXOs from age",
|
||||
tree: [
|
||||
createUtxoCohortFolder(ctx, {
|
||||
createCohortFolderBasic(ctx, {
|
||||
name: "Compare",
|
||||
title: "UTXOs from age",
|
||||
list: [...fromDate, cohortAllForComparison],
|
||||
list: fromDate,
|
||||
}),
|
||||
...fromDate.map(mapUtxoCohorts),
|
||||
...fromDate.map(mapBasic),
|
||||
],
|
||||
},
|
||||
|
||||
// UTXOs age ranges
|
||||
// UTXOs age ranges - CohortWithPercentiles (percentiles only)
|
||||
{
|
||||
name: "UTXOs age Ranges",
|
||||
tree: [
|
||||
createUtxoCohortFolder(ctx, {
|
||||
createCohortFolderWithPercentiles(ctx, {
|
||||
name: "Compare",
|
||||
title: "UTXOs Age Range",
|
||||
list: [...dateRange, cohortAllForComparison],
|
||||
list: dateRange,
|
||||
}),
|
||||
...dateRange.map(mapUtxoCohorts),
|
||||
...dateRange.map(mapWithPercentiles),
|
||||
],
|
||||
},
|
||||
|
||||
// UTXOs under amounts
|
||||
// UTXOs under amounts - CohortBasic
|
||||
{
|
||||
name: "UTXOs under amounts",
|
||||
tree: [
|
||||
createUtxoCohortFolder(ctx, {
|
||||
createCohortFolderBasic(ctx, {
|
||||
name: "Compare",
|
||||
title: "UTXOs under amount",
|
||||
list: [...utxosUnderAmount, cohortAllForComparison],
|
||||
list: utxosUnderAmount,
|
||||
}),
|
||||
...utxosUnderAmount.map(mapUtxoCohorts),
|
||||
...utxosUnderAmount.map(mapBasic),
|
||||
],
|
||||
},
|
||||
|
||||
// UTXOs above amounts
|
||||
// UTXOs above amounts - CohortBasic
|
||||
{
|
||||
name: "UTXOs Above Amounts",
|
||||
tree: [
|
||||
createUtxoCohortFolder(ctx, {
|
||||
createCohortFolderBasic(ctx, {
|
||||
name: "Compare",
|
||||
title: "UTXOs Above Amount",
|
||||
list: [...utxosAboveAmount, cohortAllForComparison],
|
||||
list: utxosAboveAmount,
|
||||
}),
|
||||
...utxosAboveAmount.map(mapUtxoCohorts),
|
||||
...utxosAboveAmount.map(mapBasic),
|
||||
],
|
||||
},
|
||||
|
||||
// UTXOs between amounts
|
||||
// UTXOs between amounts - CohortBasic
|
||||
{
|
||||
name: "UTXOs between amounts",
|
||||
tree: [
|
||||
createUtxoCohortFolder(ctx, {
|
||||
createCohortFolderBasic(ctx, {
|
||||
name: "Compare",
|
||||
title: "UTXOs between amounts",
|
||||
list: [...utxosAmountRanges, cohortAllForComparison],
|
||||
list: utxosAmountRanges,
|
||||
}),
|
||||
...utxosAmountRanges.map(mapUtxoCohorts),
|
||||
...utxosAmountRanges.map(mapBasic),
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
import { Unit } from "../utils/units.js";
|
||||
|
||||
/**
|
||||
* Create a single series from a tree accessor
|
||||
* Create a Line series
|
||||
* @param {Object} args
|
||||
* @param {AnyMetricPattern} args.metric - Tree accessor with .by property
|
||||
* @param {string} args.name - Display name for the series
|
||||
* @param {AnyMetricPattern} args.metric
|
||||
* @param {string} args.name
|
||||
* @param {Unit} args.unit
|
||||
* @param {Color} [args.color]
|
||||
* @param {Unit} [args.unit]
|
||||
* @param {boolean} [args.defaultActive]
|
||||
* @param {LineSeriesPartialOptions} [args.options]
|
||||
* @returns {AnyFetchedSeriesBlueprint}
|
||||
* @returns {FetchedLineSeriesBlueprint}
|
||||
*/
|
||||
export function s({ metric, name, color, defaultActive, unit, options }) {
|
||||
export function line({ metric, name, color, defaultActive, unit, options }) {
|
||||
return {
|
||||
metric,
|
||||
title: name,
|
||||
@@ -24,6 +24,68 @@ export function s({ metric, name, color, defaultActive, unit, options }) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Baseline series
|
||||
* @param {Object} args
|
||||
* @param {AnyMetricPattern} args.metric
|
||||
* @param {string} args.name
|
||||
* @param {Unit} args.unit
|
||||
* @param {Color | [Color, Color]} [args.color]
|
||||
* @param {boolean} [args.defaultActive]
|
||||
* @param {BaselineSeriesPartialOptions} [args.options]
|
||||
* @returns {FetchedBaselineSeriesBlueprint}
|
||||
*/
|
||||
export function baseline({
|
||||
metric,
|
||||
name,
|
||||
color,
|
||||
defaultActive,
|
||||
unit,
|
||||
options,
|
||||
}) {
|
||||
const isTuple = Array.isArray(color);
|
||||
return {
|
||||
type: /** @type {const} */ ("Baseline"),
|
||||
metric,
|
||||
title: name,
|
||||
color: isTuple ? undefined : color,
|
||||
colors: isTuple ? color : undefined,
|
||||
unit,
|
||||
defaultActive,
|
||||
options,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Histogram series
|
||||
* @param {Object} args
|
||||
* @param {AnyMetricPattern} args.metric
|
||||
* @param {string} args.name
|
||||
* @param {Unit} args.unit
|
||||
* @param {Color | [Color, Color]} [args.color]
|
||||
* @param {boolean} [args.defaultActive]
|
||||
* @param {HistogramSeriesPartialOptions} [args.options]
|
||||
* @returns {FetchedHistogramSeriesBlueprint}
|
||||
*/
|
||||
export function histogram({
|
||||
metric,
|
||||
name,
|
||||
color,
|
||||
defaultActive,
|
||||
unit,
|
||||
options,
|
||||
}) {
|
||||
return {
|
||||
type: /** @type {const} */ ("Histogram"),
|
||||
metric,
|
||||
title: name,
|
||||
color,
|
||||
unit,
|
||||
defaultActive,
|
||||
options,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create series from a BlockCountPattern ({ base, sum, cumulative })
|
||||
* @param {Colors} colors
|
||||
@@ -424,7 +486,13 @@ export function fromCoinbasePattern(colors, pattern, title) {
|
||||
* @param {Color} [cumulativeColor]
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function fromValuePattern(colors, pattern, title, sumColor, cumulativeColor) {
|
||||
export function fromValuePattern(
|
||||
colors,
|
||||
pattern,
|
||||
title,
|
||||
sumColor,
|
||||
cumulativeColor,
|
||||
) {
|
||||
return [
|
||||
{
|
||||
metric: pattern.sats.sum,
|
||||
@@ -468,6 +536,41 @@ export function fromValuePattern(colors, pattern, title, sumColor, cumulativeCol
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create sum/cumulative series from a BitcoinPattern ({ sum, cumulative }) with explicit unit and colors
|
||||
* @param {Colors} colors
|
||||
* @param {{ sum: AnyMetricPattern, cumulative: AnyMetricPattern }} pattern
|
||||
* @param {string} title
|
||||
* @param {Unit} unit
|
||||
* @param {Color} [sumColor]
|
||||
* @param {Color} [cumulativeColor]
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function fromBitcoinPatternWithUnit(
|
||||
colors,
|
||||
pattern,
|
||||
title,
|
||||
unit,
|
||||
sumColor,
|
||||
cumulativeColor,
|
||||
) {
|
||||
return [
|
||||
{
|
||||
metric: pattern.sum,
|
||||
title: `${title} sum`,
|
||||
color: sumColor,
|
||||
unit,
|
||||
},
|
||||
{
|
||||
metric: pattern.cumulative,
|
||||
title: `${title} cumulative`,
|
||||
color: cumulativeColor ?? colors.blue,
|
||||
unit,
|
||||
defaultActive: false,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create sum/cumulative series from a BlockCountPattern with explicit unit and colors
|
||||
* @param {Colors} colors
|
||||
@@ -478,7 +581,14 @@ export function fromValuePattern(colors, pattern, title, sumColor, cumulativeCol
|
||||
* @param {Color} [cumulativeColor]
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function fromBlockCountWithUnit(colors, pattern, title, unit, sumColor, cumulativeColor) {
|
||||
export function fromBlockCountWithUnit(
|
||||
colors,
|
||||
pattern,
|
||||
title,
|
||||
unit,
|
||||
sumColor,
|
||||
cumulativeColor,
|
||||
) {
|
||||
return [
|
||||
{
|
||||
metric: pattern.sum,
|
||||
@@ -508,13 +618,92 @@ export function fromBlockCountWithUnit(colors, pattern, title, unit, sumColor, c
|
||||
export function fromIntervalPattern(colors, pattern, title, unit, color) {
|
||||
return [
|
||||
{ metric: pattern.base, title, color, unit },
|
||||
{ metric: pattern.average, title: `${title} avg`, color: colors.purple, unit, defaultActive: false },
|
||||
{ metric: pattern.min, title: `${title} min`, color: colors.red, unit, defaultActive: false },
|
||||
{ metric: pattern.max, title: `${title} max`, color: colors.green, unit, defaultActive: false },
|
||||
{ metric: pattern.median, title: `${title} median`, color: colors.violet, unit, defaultActive: false },
|
||||
{ metric: pattern.pct10, title: `${title} pct10`, color: colors.rose, unit, defaultActive: false },
|
||||
{ metric: pattern.pct25, title: `${title} pct25`, color: colors.pink, unit, defaultActive: false },
|
||||
{ metric: pattern.pct75, title: `${title} pct75`, color: colors.fuchsia, unit, defaultActive: false },
|
||||
{ metric: pattern.pct90, title: `${title} pct90`, color: colors.amber, unit, defaultActive: false },
|
||||
{
|
||||
metric: pattern.average,
|
||||
title: `${title} avg`,
|
||||
color: colors.purple,
|
||||
unit,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
metric: pattern.min,
|
||||
title: `${title} min`,
|
||||
color: colors.red,
|
||||
unit,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
metric: pattern.max,
|
||||
title: `${title} max`,
|
||||
color: colors.green,
|
||||
unit,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
metric: pattern.median,
|
||||
title: `${title} median`,
|
||||
color: colors.violet,
|
||||
unit,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
metric: pattern.pct10,
|
||||
title: `${title} pct10`,
|
||||
color: colors.rose,
|
||||
unit,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
metric: pattern.pct25,
|
||||
title: `${title} pct25`,
|
||||
color: colors.pink,
|
||||
unit,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
metric: pattern.pct75,
|
||||
title: `${title} pct75`,
|
||||
color: colors.fuchsia,
|
||||
unit,
|
||||
defaultActive: false,
|
||||
},
|
||||
{
|
||||
metric: pattern.pct90,
|
||||
title: `${title} pct90`,
|
||||
color: colors.amber,
|
||||
unit,
|
||||
defaultActive: false,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create series from a SupplyPattern (sats/bitcoin/dollars, no sum/cumulative)
|
||||
* @param {Colors} colors
|
||||
* @param {SupplyPattern} pattern
|
||||
* @param {string} title
|
||||
* @param {Color} [color]
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function fromSupplyPattern(colors, pattern, title, color) {
|
||||
return [
|
||||
{
|
||||
metric: pattern.sats,
|
||||
title,
|
||||
color: color ?? colors.default,
|
||||
unit: Unit.sats,
|
||||
},
|
||||
{
|
||||
metric: pattern.bitcoin,
|
||||
title,
|
||||
color: color ?? colors.default,
|
||||
unit: Unit.btc,
|
||||
},
|
||||
{
|
||||
metric: pattern.dollars,
|
||||
title,
|
||||
color: color ?? colors.default,
|
||||
unit: Unit.usd,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@@ -121,19 +121,98 @@
|
||||
* @property {Color} color
|
||||
* @property {UtxoCohortPattern} tree
|
||||
*
|
||||
* Age cohorts (term, maxAge, minAge, ageRange, epoch) - have cost basis percentiles
|
||||
* @typedef {Object} AgeCohortObject
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {Color} color
|
||||
* @property {PatternWithCostBasisPercentiles} tree
|
||||
* ============================================================================
|
||||
* UTXO Cohort Pattern Types (based on brk client patterns)
|
||||
* ============================================================================
|
||||
*
|
||||
* Amount cohorts (geAmount, ltAmount, amountRange, type) - no cost basis percentiles
|
||||
* @typedef {Object} AmountCohortObject
|
||||
* Patterns with adjustedSopr + percentiles + RelToMarketCap:
|
||||
* - ShortTermPattern (term.short)
|
||||
* @typedef {ShortTermPattern} PatternFull
|
||||
*
|
||||
* The "All" pattern is special - has adjustedSopr + percentiles but NO RelToMarketCap
|
||||
* @typedef {AllUtxoPattern} PatternAll
|
||||
*
|
||||
* Patterns with adjustedSopr only (RealizedPattern4, CostBasisPattern):
|
||||
* - MaxAgePattern (maxAge.*)
|
||||
* @typedef {MaxAgePattern} PatternWithAdjusted
|
||||
*
|
||||
* Patterns with percentiles only (RealizedPattern2, CostBasisPattern2):
|
||||
* - LongTermPattern (term.long)
|
||||
* - AgeRangePattern (ageRange.*)
|
||||
* @typedef {LongTermPattern | AgeRangePattern} PatternWithPercentiles
|
||||
*
|
||||
* Patterns with neither (RealizedPattern/2, CostBasisPattern):
|
||||
* - BasicUtxoPattern (minAge.*, geAmount.*, ltAmount.*)
|
||||
* - EpochPattern (epoch.*)
|
||||
* @typedef {BasicUtxoPattern | EpochPattern} PatternBasic
|
||||
*
|
||||
* ============================================================================
|
||||
* Cohort Object Types (by capability)
|
||||
* ============================================================================
|
||||
*
|
||||
* All cohort: adjustedSopr + percentiles but NO RelToMarketCap (special)
|
||||
* @typedef {Object} CohortAll
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {Color} color
|
||||
* @property {UtxoAmountPattern} tree
|
||||
* @property {PatternAll} tree
|
||||
*
|
||||
* Full cohort: adjustedSopr + percentiles + RelToMarketCap (term.short)
|
||||
* @typedef {Object} CohortFull
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {Color} color
|
||||
* @property {PatternFull} tree
|
||||
*
|
||||
* Cohort with adjustedSopr only (maxAge.*)
|
||||
* @typedef {Object} CohortWithAdjusted
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {Color} color
|
||||
* @property {PatternWithAdjusted} tree
|
||||
*
|
||||
* Cohort with percentiles only (term.long, ageRange.*)
|
||||
* @typedef {Object} CohortWithPercentiles
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {Color} color
|
||||
* @property {PatternWithPercentiles} tree
|
||||
*
|
||||
* Basic cohort: neither (minAge.*, epoch.*, amount cohorts)
|
||||
* @typedef {Object} CohortBasic
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {Color} color
|
||||
* @property {PatternBasic} tree
|
||||
*
|
||||
* ============================================================================
|
||||
* Cohort Group Types (by capability)
|
||||
* ============================================================================
|
||||
*
|
||||
* @typedef {Object} CohortGroupFull
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {readonly CohortFull[]} list
|
||||
*
|
||||
* @typedef {Object} CohortGroupWithAdjusted
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {readonly CohortWithAdjusted[]} list
|
||||
*
|
||||
* @typedef {Object} CohortGroupWithPercentiles
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {readonly CohortWithPercentiles[]} list
|
||||
*
|
||||
* @typedef {Object} CohortGroupBasic
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {readonly CohortBasic[]} list
|
||||
*
|
||||
* @typedef {Object} UtxoCohortGroupObject
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {readonly UtxoCohortObject[]} list
|
||||
*
|
||||
* @typedef {Object} AddressCohortObject
|
||||
* @property {string} name
|
||||
@@ -143,20 +222,6 @@
|
||||
*
|
||||
* @typedef {UtxoCohortObject | AddressCohortObject} CohortObject
|
||||
*
|
||||
* @typedef {Object} UtxoCohortGroupObject
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {readonly UtxoCohortObject[]} list
|
||||
*
|
||||
* @typedef {Object} AgeCohortGroupObject
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {readonly AgeCohortObject[]} list
|
||||
*
|
||||
* @typedef {Object} AmountCohortGroupObject
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {readonly AmountCohortObject[]} list
|
||||
*
|
||||
* @typedef {Object} AddressCohortGroupObject
|
||||
* @property {string} name
|
||||
@@ -168,7 +233,9 @@
|
||||
* @typedef {Object} PartialContext
|
||||
* @property {Colors} colors
|
||||
* @property {BrkClient} brk
|
||||
* @property {(args: { metric: AnyMetricPattern, name: string, unit: Unit, color?: Color, defaultActive?: boolean, options?: LineSeriesPartialOptions }) => AnyFetchedSeriesBlueprint} s
|
||||
* @property {LineSeriesFn} line
|
||||
* @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: SizePattern<any>, title: string, color?: Color) => AnyFetchedSeriesBlueprint[]} fromBlockSize
|
||||
@@ -177,11 +244,13 @@
|
||||
* @property {(pattern: FeeRatePattern<any>, title: string, unit: Unit) => AnyFetchedSeriesBlueprint[]} fromFeeRatePattern
|
||||
* @property {(pattern: CoinbasePattern, title: string) => AnyFetchedSeriesBlueprint[]} fromCoinbasePattern
|
||||
* @property {(pattern: ValuePattern, title: string, sumColor?: Color, cumulativeColor?: Color) => AnyFetchedSeriesBlueprint[]} fromValuePattern
|
||||
* @property {(pattern: { sum: AnyMetricPattern, cumulative: AnyMetricPattern }, title: string, unit: Unit, sumColor?: Color, cumulativeColor?: Color) => AnyFetchedSeriesBlueprint[]} fromBitcoinPatternWithUnit
|
||||
* @property {(pattern: BlockCountPattern<any>, title: string, unit: Unit, sumColor?: Color, cumulativeColor?: Color) => AnyFetchedSeriesBlueprint[]} fromBlockCountWithUnit
|
||||
* @property {(pattern: IntervalPattern, title: string, unit: Unit, color?: Color) => AnyFetchedSeriesBlueprint[]} fromIntervalPattern
|
||||
* @property {(pattern: SupplyPattern, title: string, color?: Color) => AnyFetchedSeriesBlueprint[]} fromSupplyPattern
|
||||
* @property {(args: { number?: number, name?: string, defaultActive?: boolean, lineStyle?: LineStyle, color?: Color, unit: Unit }) => FetchedLineSeriesBlueprint} createPriceLine
|
||||
* @property {(args: { numbers: number[], unit: Unit }) => FetchedLineSeriesBlueprint[]} createPriceLines
|
||||
* @property {(args: { constant: AnyMetricPattern, name: string, unit: Unit, color?: Color, lineStyle?: number, defaultActive?: boolean }) => FetchedLineSeriesBlueprint} line
|
||||
* @property {(args: { constant: AnyMetricPattern, name: string, unit: Unit, color?: Color, lineStyle?: number, defaultActive?: boolean }) => FetchedLineSeriesBlueprint} constantLine
|
||||
*/
|
||||
|
||||
// Re-export for type consumers
|
||||
|
||||
@@ -21,6 +21,7 @@ export const Unit = /** @type {const} */ ({
|
||||
pctMcap: { id: "pct-mcap", name: "% of Market Cap" },
|
||||
pctRcap: { id: "pct-rcap", name: "% of Realized Cap" },
|
||||
pctOwnMcap: { id: "pct-own-mcap", name: "% of Own Market Cap" },
|
||||
pctOwnPnl: { id: "pct-own-pnl", name: "% of Own P&L" },
|
||||
|
||||
// Time
|
||||
days: { id: "days", name: "Days" },
|
||||
|
||||
Reference in New Issue
Block a user