global: sats version of all prices

This commit is contained in:
nym21
2026-01-26 15:04:45 +01:00
parent f066fcda32
commit 3d01822d27
53 changed files with 2843 additions and 1688 deletions
+47 -8
View File
@@ -1,7 +1,6 @@
/** Moving averages section */
import { Unit } from "../../utils/units.js";
import { line } from "../series.js";
import { price } from "../series.js";
import { createRatioChart, createZScoresFolder, formatCohortTitle } from "../shared.js";
import { periodIdToName } from "./utils.js";
@@ -81,19 +80,19 @@ export function createPriceWithRatioOptions(
ctx,
{ title, legend, ratio, color },
) {
const priceMetric = ratio.price;
const pricePattern = ratio.price;
return [
{
name: "Price",
title,
top: [line({ metric: priceMetric, name: legend, color, unit: Unit.usd })],
top: [price({ metric: pricePattern, name: legend, color })],
},
createRatioChart(ctx, { title: formatCohortTitle(title), price: priceMetric, ratio, color }),
createRatioChart(ctx, { title: formatCohortTitle(title), pricePattern, ratio, color }),
createZScoresFolder(ctx, {
title,
legend,
price: priceMetric,
pricePattern,
ratio,
color,
}),
@@ -103,6 +102,46 @@ export function createPriceWithRatioOptions(
/** Common period IDs to show at top level */
const COMMON_PERIODS = ["1w", "1m", "200d", "1y", "200w", "4y"];
/** Periods to compare SMA vs EMA */
const COMPARISON_PERIODS = ["1w", "1m", "200d", "1y", "200w", "4y"];
/**
* Create SMA vs EMA comparison section
* @param {ReturnType<typeof buildSmaAverages>} smaAverages
* @param {ReturnType<typeof buildEmaAverages>} emaAverages
*/
function createCompareSection(smaAverages, emaAverages) {
// Find matching SMA/EMA pairs
const pairs = COMPARISON_PERIODS.map(id => {
const sma = smaAverages.find(a => a.id === id);
const ema = emaAverages.find(a => a.id === id);
if (!sma || !ema) return null;
return { id, sma, ema };
}).filter(/** @type {(p: any) => p is { id: string, sma: ReturnType<typeof buildSmaAverages>[number], ema: ReturnType<typeof buildEmaAverages>[number] }} */ (p) => p !== null);
return {
name: "Compare",
tree: [
{
name: "All Periods",
title: "SMA vs EMA Comparison",
top: pairs.flatMap(({ sma, ema }) => [
price({ metric: sma.ratio.price, name: `${sma.id} SMA`, color: sma.color }),
price({ metric: ema.ratio.price, name: `${ema.id} EMA`, color: ema.color, options: { lineStyle: 1 } }),
]),
},
...pairs.map(({ id, sma, ema }) => ({
name: periodIdToName(id, true),
title: `${periodIdToName(id, true)} SMA vs EMA`,
top: [
price({ metric: sma.ratio.price, name: "SMA", color: sma.color }),
price({ metric: ema.ratio.price, name: "EMA", color: ema.color, options: { lineStyle: 1 } }),
],
})),
],
};
}
/**
* @param {PartialContext} ctx
* @param {MarketMovingAverage} movingAverage
@@ -127,11 +166,10 @@ export function createAveragesSection(ctx, movingAverage) {
name: "Compare",
title: `Price ${label}s`,
top: averages.map(({ id, color, ratio }) =>
line({
price({
metric: ratio.price,
name: id,
color,
unit: Unit.usd,
}),
),
},
@@ -165,6 +203,7 @@ export function createAveragesSection(ctx, movingAverage) {
return {
name: "Moving Averages",
tree: [
createCompareSection(smaAverages, emaAverages),
createSubSection("SMA", smaAverages),
createSubSection("EMA", emaAverages),
],
+6 -14
View File
@@ -1,7 +1,4 @@
/** Bands indicators (MinMax, Mayer Multiple) */
import { Unit } from "../../utils/units.js";
import { line } from "../series.js";
import { price } from "../series.js";
/**
* Create Bands section
@@ -47,19 +44,17 @@ export function createBandsSection(ctx, { range, movingAverage }) {
name: id,
title: `${title} MinMax`,
top: [
line({
price({
metric: min,
name: "Min",
key: `price-min`,
color: colors.red,
unit: Unit.usd,
}),
line({
price({
metric: max,
name: "Max",
key: `price-max`,
color: colors.green,
unit: Unit.usd,
}),
],
})),
@@ -68,23 +63,20 @@ export function createBandsSection(ctx, { range, movingAverage }) {
name: "Mayer Multiple",
title: "Mayer Multiple",
top: [
line({
price({
metric: movingAverage.price200dSma.price,
name: "200d SMA",
color: colors.yellow,
unit: Unit.usd,
}),
line({
price({
metric: movingAverage.price200dSmaX24,
name: "200d SMA x2.4",
color: colors.green,
unit: Unit.usd,
}),
line({
price({
metric: movingAverage.price200dSmaX08,
name: "200d SMA x0.8",
color: colors.red,
unit: Unit.usd,
}),
],
},
+21 -20
View File
@@ -2,7 +2,7 @@
import { localhost } from "../../utils/env.js";
import { Unit } from "../../utils/units.js";
import { candlestick, line } from "../series.js";
import { candlestick, line, price } from "../series.js";
import { createAveragesSection } from "./averages.js";
import { createReturnsSection } from "./performance.js";
import { createMomentumSection } from "./momentum.js";
@@ -18,7 +18,7 @@ import { createDcaVsLumpSumSection, createDcaByYearSection } from "./investing.j
*/
export function createMarketSection(ctx) {
const { colors, brk } = ctx;
const { market, supply, price } = brk.metrics;
const { market, supply, price: priceMetrics } = brk.metrics;
const {
movingAverage,
ath,
@@ -39,79 +39,80 @@ export function createMarketSection(ctx) {
name: "Price",
title: "Bitcoin Price",
},
// Oracle section is localhost-only debug - uses non-price-pattern metrics
...(localhost
? [
? /** @type {PartialOptionsTree} */ ([
{
name: "Oracle",
title: "Oracle Price",
top: [
top: /** @type {any} */ ([
candlestick({
metric: price.oracle.closeOhlcDollars,
name: "close",
metric: priceMetrics.oracle.closeOhlcDollars,
name: "Close",
unit: Unit.usd,
}),
candlestick({
metric: price.oracle.midOhlcDollars,
name: "mid",
metric: priceMetrics.oracle.midOhlcDollars,
name: "Mid",
unit: Unit.usd,
}),
line({
metric: price.oracle.phaseDailyDollars.median,
metric: priceMetrics.oracle.phaseDailyDollars.median,
name: "o. p50",
unit: Unit.usd,
color: colors.yellow,
}),
line({
metric: price.oracle.phaseV2DailyDollars.median,
metric: priceMetrics.oracle.phaseV2DailyDollars.median,
name: "o2. p50",
unit: Unit.usd,
color: colors.orange,
}),
line({
metric: price.oracle.phaseV2PeakDailyDollars.median,
metric: priceMetrics.oracle.phaseV2PeakDailyDollars.median,
name: "o2.2 p50",
unit: Unit.usd,
color: colors.orange,
}),
line({
metric: price.oracle.phaseV3DailyDollars.median,
metric: priceMetrics.oracle.phaseV3DailyDollars.median,
name: "o3. p50",
unit: Unit.usd,
color: colors.red,
}),
line({
metric: price.oracle.phaseV3PeakDailyDollars.median,
metric: priceMetrics.oracle.phaseV3PeakDailyDollars.median,
name: "o3.2 p50",
unit: Unit.usd,
color: colors.red,
}),
line({
metric: price.oracle.phaseDailyDollars.max,
metric: priceMetrics.oracle.phaseDailyDollars.max,
name: "o. max",
unit: Unit.usd,
color: colors.lime,
}),
line({
metric: price.oracle.phaseV2DailyDollars.max,
metric: priceMetrics.oracle.phaseV2DailyDollars.max,
name: "o.2 max",
unit: Unit.usd,
color: colors.emerald,
}),
line({
metric: price.oracle.phaseDailyDollars.min,
metric: priceMetrics.oracle.phaseDailyDollars.min,
name: "o. min",
unit: Unit.usd,
color: colors.rose,
}),
line({
metric: price.oracle.phaseV2DailyDollars.min,
metric: priceMetrics.oracle.phaseV2DailyDollars.min,
name: "o.2 min",
unit: Unit.usd,
color: colors.purple,
}),
],
]),
},
]
])
: []),
// Capitalization
@@ -131,7 +132,7 @@ export function createMarketSection(ctx) {
{
name: "All Time High",
title: "All Time High",
top: [line({ metric: ath.priceAth, name: "ATH", unit: Unit.usd })],
top: [price({ metric: ath.priceAth, name: "ATH" })],
bottom: [
line({
metric: ath.priceDrawdown,
+13 -17
View File
@@ -2,7 +2,7 @@
import { Unit } from "../../utils/units.js";
import { priceLine } from "../constants.js";
import { line, baseline } from "../series.js";
import { line, baseline, price } from "../series.js";
import { satsBtcUsd } from "../shared.js";
import { periodIdToName } from "./utils.js";
@@ -58,17 +58,15 @@ export function createDcaVsLumpSumSection(ctx, { dca, lookback, returns }) {
name: "Cost Basis",
title: `${name} Cost Basis`,
top: [
line({
price({
metric: dca.periodAveragePrice[key],
name: "DCA",
color: colors.green,
unit: Unit.usd,
}),
line({
price({
metric: lookback[key],
name: "Lump sum",
color: colors.orange,
unit: Unit.usd,
}),
],
});
@@ -78,8 +76,8 @@ export function createDcaVsLumpSumSection(ctx, { dca, lookback, returns }) {
name: "Days in Profit",
title: `${name} Days in Profit`,
top: [
line({ metric: dca.periodAveragePrice[key], name: "DCA", color: colors.green, unit: Unit.usd }),
line({ metric: lookback[key], name: "Lump sum", color: colors.orange, unit: Unit.usd }),
price({ metric: dca.periodAveragePrice[key], name: "DCA", color: colors.green }),
price({ metric: lookback[key], name: "Lump sum", color: colors.orange }),
],
bottom: [
line({ metric: dca.periodDaysInProfit[key], name: "DCA", color: colors.green, unit: Unit.days }),
@@ -92,8 +90,8 @@ export function createDcaVsLumpSumSection(ctx, { dca, lookback, returns }) {
name: "Days in Loss",
title: `${name} Days in Loss`,
top: [
line({ metric: dca.periodAveragePrice[key], name: "DCA", color: colors.green, unit: Unit.usd }),
line({ metric: lookback[key], name: "Lump sum", color: colors.orange, unit: Unit.usd }),
price({ metric: dca.periodAveragePrice[key], name: "DCA", color: colors.green }),
price({ metric: lookback[key], name: "Lump sum", color: colors.orange }),
],
bottom: [
line({ metric: dca.periodDaysInLoss[key], name: "DCA", color: colors.red, unit: Unit.days }),
@@ -106,8 +104,8 @@ export function createDcaVsLumpSumSection(ctx, { dca, lookback, returns }) {
name: "Max Drawdown",
title: `${name} Max Drawdown`,
top: [
line({ metric: dca.periodAveragePrice[key], name: "DCA", color: colors.green, unit: Unit.usd }),
line({ metric: lookback[key], name: "Lump sum", color: colors.orange, unit: Unit.usd }),
price({ metric: dca.periodAveragePrice[key], name: "DCA", color: colors.green }),
price({ metric: lookback[key], name: "Lump sum", color: colors.orange }),
],
bottom: [
line({ metric: dca.periodMaxDrawdown[key], name: "DCA", color: colors.green, unit: Unit.percentage }),
@@ -120,8 +118,8 @@ export function createDcaVsLumpSumSection(ctx, { dca, lookback, returns }) {
name: "Max Return",
title: `${name} Max Return`,
top: [
line({ metric: dca.periodAveragePrice[key], name: "DCA", color: colors.green, unit: Unit.usd }),
line({ metric: lookback[key], name: "Lump sum", color: colors.orange, unit: Unit.usd }),
price({ metric: dca.periodAveragePrice[key], name: "DCA", color: colors.green }),
price({ metric: lookback[key], name: "Lump sum", color: colors.orange }),
],
bottom: [
line({ metric: dca.periodMaxReturn[key], name: "DCA", color: colors.green, unit: Unit.percentage }),
@@ -279,12 +277,11 @@ export function createDcaByYearSection(ctx, { dca }) {
name: "Cost basis",
title: "DCA Cost Basis",
top: dcaClasses.map(({ year, color, defaultActive, costBasis }) =>
line({
price({
metric: costBasis,
name: `${year}`,
color,
defaultActive,
unit: Unit.usd,
}),
),
},
@@ -353,11 +350,10 @@ export function createDcaByYearSection(ctx, { dca }) {
name: "Cost Basis",
title: `${year} Cost Basis`,
top: [
line({
price({
metric: costBasis,
name: "Cost Basis",
color,
unit: Unit.usd,
}),
],
},
+3 -5
View File
@@ -1,7 +1,7 @@
/** On-chain indicators (Pi Cycle, Puell, NVT, Gini) */
import { Unit } from "../../utils/units.js";
import { baseline, line } from "../series.js";
import { baseline, line, price } from "../series.js";
/**
* Create Valuation section
@@ -20,17 +20,15 @@ export function createValuationSection(ctx, { indicators, movingAverage }) {
name: "Pi Cycle",
title: "Pi Cycle",
top: [
line({
price({
metric: movingAverage.price111dSma.price,
name: "111d SMA",
color: colors.green,
unit: Unit.usd,
}),
line({
price({
metric: movingAverage.price350dSmaX2,
name: "350d SMA x2",
color: colors.red,
unit: Unit.usd,
}),
],
bottom: [