mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-16 21:48:10 -07:00
global: sats version of all prices
This commit is contained in:
@@ -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),
|
||||
],
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
],
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
],
|
||||
},
|
||||
|
||||
@@ -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: [
|
||||
|
||||
Reference in New Issue
Block a user