mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-05 04:31:56 -07:00
global: snapshot
This commit is contained in:
@@ -40,17 +40,17 @@
|
||||
* @typedef {AllUtxoPattern | MinAgePattern | UtxoAmountPattern} PatternWithRealizedPrice
|
||||
* @typedef {AllUtxoPattern} PatternWithFullRealized
|
||||
* @typedef {AllUtxoPattern | MinAgePattern | UtxoAmountPattern} PatternWithNupl
|
||||
* @typedef {AllUtxoPattern | MinAgePattern | UtxoAmountPattern} PatternWithPricePaidStats
|
||||
* @typedef {AllUtxoPattern | MinAgePattern | UtxoAmountPattern} PatternWithCostBasis
|
||||
* @typedef {AllUtxoPattern | MinAgePattern | UtxoAmountPattern} PatternWithActivity
|
||||
* @typedef {AllUtxoPattern | MaxAgePattern | MinAgePattern} PatternWithPricePercentiles
|
||||
* @typedef {AllUtxoPattern | MaxAgePattern | MinAgePattern} PatternWithCostBasisPercentiles
|
||||
*
|
||||
* Cohort objects with specific pattern capabilities
|
||||
* @typedef {{ name: string, title: string, color: Color, tree: PatternWithRealizedPrice }} CohortWithRealizedPrice
|
||||
* @typedef {{ name: string, title: string, color: Color, tree: PatternWithFullRealized }} CohortWithFullRealized
|
||||
* @typedef {{ name: string, title: string, color: Color, tree: PatternWithNupl }} CohortWithNupl
|
||||
* @typedef {{ name: string, title: string, color: Color, tree: PatternWithPricePaidStats }} CohortWithPricePaidStats
|
||||
* @typedef {{ name: string, title: string, color: Color, tree: PatternWithCostBasis }} CohortWithCostBasis
|
||||
* @typedef {{ name: string, title: string, color: Color, tree: PatternWithActivity }} CohortWithActivity
|
||||
* @typedef {{ name: string, title: string, color: Color, tree: PatternWithPricePercentiles }} CohortWithPricePercentiles
|
||||
* @typedef {{ name: string, title: string, color: Color, tree: PatternWithCostBasisPercentiles }} CohortWithCostBasisPercentiles
|
||||
*
|
||||
* Tree branch types
|
||||
* @typedef {InstanceType<typeof BrkClient>["tree"]["computed"]["market"]} Market
|
||||
|
||||
@@ -2500,7 +2500,7 @@ export function createPartialOptions({ colors, brk }) {
|
||||
top: list.flatMap(({ color, name, tree }) => {
|
||||
return /** @type {const} */ ([
|
||||
s({
|
||||
metric: tree.pricePaid.minPricePaid,
|
||||
metric: tree.costBasis.minCostBasis,
|
||||
name,
|
||||
color: color,
|
||||
}),
|
||||
@@ -2513,7 +2513,7 @@ export function createPartialOptions({ colors, brk }) {
|
||||
top: list.flatMap(({ color, name, tree }) => {
|
||||
return /** @type {const} */ ([
|
||||
s({
|
||||
metric: tree.pricePaid.maxPricePaid,
|
||||
metric: tree.costBasis.maxCostBasis,
|
||||
name,
|
||||
color: color,
|
||||
}),
|
||||
@@ -2526,7 +2526,7 @@ export function createPartialOptions({ colors, brk }) {
|
||||
: [
|
||||
{
|
||||
name: "Cost Basis",
|
||||
title: `Costs Basis ${title}`,
|
||||
title: `Cost Basis ${title}`,
|
||||
top: [
|
||||
s({
|
||||
metric: args.tree.realizedPrice,
|
||||
@@ -2534,13 +2534,13 @@ export function createPartialOptions({ colors, brk }) {
|
||||
color: args.color,
|
||||
}),
|
||||
s({
|
||||
metric: args.tree.pricePaid.minPricePaid,
|
||||
metric: args.tree.costBasis.minCostBasis,
|
||||
name: "Min",
|
||||
color: colors.green,
|
||||
defaultActive: false,
|
||||
}),
|
||||
s({
|
||||
metric: args.tree.pricePaid.maxPricePaid,
|
||||
metric: args.tree.costBasis.maxCostBasis,
|
||||
name: "Max",
|
||||
color: colors.red,
|
||||
}),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Address cohort folder builder
|
||||
* Creates option trees for address-based cohorts (has addrCount)
|
||||
* Address cohorts use _0satsPattern which has PricePaidPattern (no percentiles)
|
||||
* Address cohorts use _0satsPattern which has CostBasisPattern (no percentiles)
|
||||
*/
|
||||
|
||||
import {
|
||||
@@ -104,8 +104,8 @@ export function createAddressCohortFolder(ctx, args) {
|
||||
// Unrealized section
|
||||
...createUnrealizedSection(ctx, list, useGroupName, title),
|
||||
|
||||
// Price paid section (no percentiles for address cohorts)
|
||||
...createPricePaidSection(ctx, list, useGroupName, title),
|
||||
// Cost basis section (no percentiles for address cohorts)
|
||||
...createCostBasisSection(ctx, list, useGroupName, title),
|
||||
|
||||
// Activity section
|
||||
...createActivitySection(ctx, list, useGroupName, title),
|
||||
@@ -237,32 +237,32 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create price paid section (no percentiles for address cohorts)
|
||||
* Create cost basis section (no percentiles for address cohorts)
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly AddressCohortObject[]} list
|
||||
* @param {boolean} useGroupName
|
||||
* @param {string} title
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createPricePaidSection(ctx, list, useGroupName, title) {
|
||||
function createCostBasisSection(ctx, list, useGroupName, title) {
|
||||
const { s } = ctx;
|
||||
|
||||
return [
|
||||
{
|
||||
name: "Price Paid",
|
||||
name: "Cost Basis",
|
||||
tree: [
|
||||
{
|
||||
name: "min",
|
||||
title: `Min Price Paid ${title}`,
|
||||
title: `Min Cost Basis ${title}`,
|
||||
top: list.map(({ color, name, tree }) =>
|
||||
s({ metric: tree.pricePaid.minPricePaid, name: useGroupName ? name : "Min", color }),
|
||||
s({ metric: tree.costBasis.minCostBasis, name: useGroupName ? name : "Min", color }),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "max",
|
||||
title: `Max Price Paid ${title}`,
|
||||
title: `Max Cost Basis ${title}`,
|
||||
top: list.map(({ color, name, tree }) =>
|
||||
s({ metric: tree.pricePaid.maxPricePaid, name: useGroupName ? name : "Max", color }),
|
||||
s({ metric: tree.costBasis.maxCostBasis, name: useGroupName ? name : "Max", color }),
|
||||
),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -20,6 +20,6 @@ export {
|
||||
createRealizedPriceSeries,
|
||||
createRealizedPriceRatioSeries,
|
||||
createRealizedCapSeries,
|
||||
createPricePaidMinMaxSeries,
|
||||
createPricePercentilesSeries,
|
||||
createCostBasisMinMaxSeries,
|
||||
createCostBasisPercentilesSeries,
|
||||
} from "./shared.js";
|
||||
|
||||
@@ -178,39 +178,39 @@ export function createRealizedCapSeries(ctx, list, useGroupName) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create price paid min/max series (available on all cohorts)
|
||||
* Create cost basis min/max series (available on all cohorts)
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly CohortObject[]} list
|
||||
* @param {boolean} useGroupName
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createPricePaidMinMaxSeries(ctx, list, useGroupName) {
|
||||
export function createCostBasisMinMaxSeries(ctx, list, useGroupName) {
|
||||
const { s } = ctx;
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
s({ metric: tree.pricePaid.minPricePaid, name: useGroupName ? `${name} min` : "Min", color }),
|
||||
s({ metric: tree.pricePaid.maxPricePaid, name: useGroupName ? `${name} max` : "Max", color }),
|
||||
s({ metric: tree.costBasis.minCostBasis, name: useGroupName ? `${name} min` : "Min", color }),
|
||||
s({ metric: tree.costBasis.maxCostBasis, name: useGroupName ? `${name} max` : "Max", color }),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create price percentile series (only for cohorts with PricePaidPattern2)
|
||||
* Create cost basis percentile series (only for cohorts with CostBasisPattern2)
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly CohortWithPricePercentiles[]} list
|
||||
* @param {readonly CohortWithCostBasisPercentiles[]} list
|
||||
* @param {boolean} useGroupName
|
||||
* @returns {AnyFetchedSeriesBlueprint[]}
|
||||
*/
|
||||
export function createPricePercentilesSeries(ctx, list, useGroupName) {
|
||||
export function createCostBasisPercentilesSeries(ctx, list, useGroupName) {
|
||||
const { s, colors } = ctx;
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => {
|
||||
const pp = tree.pricePaid.pricePercentiles;
|
||||
const percentiles = tree.costBasis.percentiles;
|
||||
return [
|
||||
s({ metric: pp.pct10, name: useGroupName ? `${name} p10` : "p10", color, defaultActive: false }),
|
||||
s({ metric: pp.pct25, name: useGroupName ? `${name} p25` : "p25", color, defaultActive: false }),
|
||||
s({ metric: pp.pct50, name: useGroupName ? `${name} p50` : "p50", color }),
|
||||
s({ metric: pp.pct75, name: useGroupName ? `${name} p75` : "p75", color, defaultActive: false }),
|
||||
s({ metric: pp.pct90, name: useGroupName ? `${name} p90` : "p90", color, defaultActive: false }),
|
||||
s({ metric: percentiles.pct10, name: useGroupName ? `${name} p10` : "p10", color, defaultActive: false }),
|
||||
s({ metric: percentiles.pct25, name: useGroupName ? `${name} p25` : "p25", color, defaultActive: false }),
|
||||
s({ metric: percentiles.pct50, name: useGroupName ? `${name} p50` : "p50", color }),
|
||||
s({ metric: percentiles.pct75, name: useGroupName ? `${name} p75` : "p75", color, defaultActive: false }),
|
||||
s({ metric: percentiles.pct90, name: useGroupName ? `${name} p90` : "p90", color, defaultActive: false }),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
* Creates option trees for UTXO-based cohorts (no addrCount)
|
||||
*
|
||||
* Two main builders:
|
||||
* - createAgeCohortFolder: For term, maxAge, minAge, ageRange, epoch (has price percentiles)
|
||||
* - createAmountCohortFolder: For geAmount, ltAmount, amountRange, type (no price percentiles)
|
||||
* - createAgeCohortFolder: For term, maxAge, minAge, ageRange, epoch (has cost basis percentiles)
|
||||
* - createAmountCohortFolder: For geAmount, ltAmount, amountRange, type (no cost basis percentiles)
|
||||
*/
|
||||
|
||||
import {
|
||||
@@ -16,13 +16,13 @@ import {
|
||||
createRealizedPriceSeries,
|
||||
createRealizedPriceRatioSeries,
|
||||
createRealizedCapSeries,
|
||||
createPricePaidMinMaxSeries,
|
||||
createPricePercentilesSeries,
|
||||
createCostBasisMinMaxSeries,
|
||||
createCostBasisPercentilesSeries,
|
||||
} from "./shared.js";
|
||||
|
||||
/**
|
||||
* Create a cohort folder for age-based UTXO cohorts (term, maxAge, minAge, ageRange, epoch)
|
||||
* These cohorts have price percentiles via PricePaidPattern2
|
||||
* These cohorts have cost basis percentiles via CostBasisPattern2
|
||||
* @param {PartialContext} ctx
|
||||
* @param {AgeCohortObject | AgeCohortGroupObject} args
|
||||
* @returns {PartialOptionsGroup}
|
||||
@@ -40,7 +40,7 @@ export function createAgeCohortFolder(ctx, args) {
|
||||
createUtxoCountSection(ctx, list, useGroupName, title),
|
||||
createRealizedSection(ctx, list, args, useGroupName, isSingle, title),
|
||||
...createUnrealizedSection(ctx, list, useGroupName, title),
|
||||
...createPricePaidSectionWithPercentiles(ctx, list, useGroupName, title),
|
||||
...createCostBasisSectionWithPercentiles(ctx, list, useGroupName, title),
|
||||
...createActivitySection(ctx, list, useGroupName, title),
|
||||
],
|
||||
};
|
||||
@@ -48,7 +48,7 @@ export function createAgeCohortFolder(ctx, args) {
|
||||
|
||||
/**
|
||||
* Create a cohort folder for amount-based UTXO cohorts (geAmount, ltAmount, amountRange, type)
|
||||
* These cohorts have only min/max price paid via PricePaidPattern
|
||||
* These cohorts have only min/max cost basis via CostBasisPattern
|
||||
* @param {PartialContext} ctx
|
||||
* @param {AmountCohortObject | AmountCohortGroupObject} args
|
||||
* @returns {PartialOptionsGroup}
|
||||
@@ -66,7 +66,7 @@ export function createAmountCohortFolder(ctx, args) {
|
||||
createUtxoCountSection(ctx, list, useGroupName, title),
|
||||
createRealizedSection(ctx, list, args, useGroupName, isSingle, title),
|
||||
...createUnrealizedSection(ctx, list, useGroupName, title),
|
||||
...createPricePaidSectionBasic(ctx, list, useGroupName, title),
|
||||
...createCostBasisSectionBasic(ctx, list, useGroupName, title),
|
||||
...createActivitySection(ctx, list, useGroupName, title),
|
||||
],
|
||||
};
|
||||
@@ -87,7 +87,7 @@ export function createUtxoCohortFolder(ctx, args) {
|
||||
const title = args.title ? `${useGroupName ? "by" : "of"} ${args.title}` : "";
|
||||
|
||||
// Runtime check for percentiles
|
||||
const hasPercentiles = "pricePercentiles" in list[0].tree.pricePaid;
|
||||
const hasPercentiles = "percentiles" in list[0].tree.costBasis;
|
||||
|
||||
return {
|
||||
name: args.name || "all",
|
||||
@@ -97,8 +97,8 @@ export function createUtxoCohortFolder(ctx, args) {
|
||||
createRealizedSection(ctx, list, args, useGroupName, isSingle, title),
|
||||
...createUnrealizedSection(ctx, list, useGroupName, title),
|
||||
...(hasPercentiles
|
||||
? createPricePaidSectionWithPercentiles(ctx, /** @type {readonly AgeCohortObject[]} */ (list), useGroupName, title)
|
||||
: createPricePaidSectionBasic(ctx, list, useGroupName, title)),
|
||||
? createCostBasisSectionWithPercentiles(ctx, /** @type {readonly AgeCohortObject[]} */ (list), useGroupName, title)
|
||||
: createCostBasisSectionBasic(ctx, list, useGroupName, title)),
|
||||
...createActivitySection(ctx, list, useGroupName, title),
|
||||
],
|
||||
};
|
||||
@@ -372,38 +372,38 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create price paid section for cohorts WITH percentiles (age cohorts)
|
||||
* Create cost basis section for cohorts WITH percentiles (age cohorts)
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly AgeCohortObject[]} list
|
||||
* @param {boolean} useGroupName
|
||||
* @param {string} title
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createPricePaidSectionWithPercentiles(ctx, list, useGroupName, title) {
|
||||
function createCostBasisSectionWithPercentiles(ctx, list, useGroupName, title) {
|
||||
const { s } = ctx;
|
||||
|
||||
return [
|
||||
{
|
||||
name: "Price Paid",
|
||||
name: "Cost Basis",
|
||||
tree: [
|
||||
{
|
||||
name: "min",
|
||||
title: `Min Price Paid ${title}`,
|
||||
title: `Min Cost Basis ${title}`,
|
||||
top: list.map(({ color, name, tree }) =>
|
||||
s({ metric: tree.pricePaid.minPricePaid, name: useGroupName ? name : "Min", color }),
|
||||
s({ metric: tree.costBasis.minCostBasis, name: useGroupName ? name : "Min", color }),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "max",
|
||||
title: `Max Price Paid ${title}`,
|
||||
title: `Max Cost Basis ${title}`,
|
||||
top: list.map(({ color, name, tree }) =>
|
||||
s({ metric: tree.pricePaid.maxPricePaid, name: useGroupName ? name : "Max", color }),
|
||||
s({ metric: tree.costBasis.maxCostBasis, name: useGroupName ? name : "Max", color }),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "percentiles",
|
||||
title: `Price Paid Percentiles ${title}`,
|
||||
top: createPricePercentilesSeries(ctx, list, useGroupName),
|
||||
title: `Cost Basis Percentiles ${title}`,
|
||||
top: createCostBasisPercentilesSeries(ctx, list, useGroupName),
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -411,32 +411,32 @@ function createPricePaidSectionWithPercentiles(ctx, list, useGroupName, title) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create price paid section for cohorts WITHOUT percentiles (amount cohorts)
|
||||
* Create cost basis section for cohorts WITHOUT percentiles (amount cohorts)
|
||||
* @param {PartialContext} ctx
|
||||
* @param {readonly UtxoCohortObject[]} list
|
||||
* @param {boolean} useGroupName
|
||||
* @param {string} title
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function createPricePaidSectionBasic(ctx, list, useGroupName, title) {
|
||||
function createCostBasisSectionBasic(ctx, list, useGroupName, title) {
|
||||
const { s } = ctx;
|
||||
|
||||
return [
|
||||
{
|
||||
name: "Price Paid",
|
||||
name: "Cost Basis",
|
||||
tree: [
|
||||
{
|
||||
name: "min",
|
||||
title: `Min Price Paid ${title}`,
|
||||
title: `Min Cost Basis ${title}`,
|
||||
top: list.map(({ color, name, tree }) =>
|
||||
s({ metric: tree.pricePaid.minPricePaid, name: useGroupName ? name : "Min", color }),
|
||||
s({ metric: tree.costBasis.minCostBasis, name: useGroupName ? name : "Min", color }),
|
||||
),
|
||||
},
|
||||
{
|
||||
name: "max",
|
||||
title: `Max Price Paid ${title}`,
|
||||
title: `Max Cost Basis ${title}`,
|
||||
top: list.map(({ color, name, tree }) =>
|
||||
s({ metric: tree.pricePaid.maxPricePaid, name: useGroupName ? name : "Max", color }),
|
||||
s({ metric: tree.costBasis.maxCostBasis, name: useGroupName ? name : "Max", color }),
|
||||
),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -121,14 +121,14 @@
|
||||
* @property {Color} color
|
||||
* @property {UtxoCohortPattern} tree
|
||||
*
|
||||
* Age cohorts (term, maxAge, minAge, ageRange, epoch) - have price percentiles
|
||||
* Age cohorts (term, maxAge, minAge, ageRange, epoch) - have cost basis percentiles
|
||||
* @typedef {Object} AgeCohortObject
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
* @property {Color} color
|
||||
* @property {PatternWithPricePercentiles} tree
|
||||
* @property {PatternWithCostBasisPercentiles} tree
|
||||
*
|
||||
* Amount cohorts (geAmount, ltAmount, amountRange, type) - no price percentiles
|
||||
* Amount cohorts (geAmount, ltAmount, amountRange, type) - no cost basis percentiles
|
||||
* @typedef {Object} AmountCohortObject
|
||||
* @property {string} name
|
||||
* @property {string} title
|
||||
|
||||
@@ -644,7 +644,7 @@ export function init({ colors, createChartElement, signals, resources }) {
|
||||
equals: false,
|
||||
},
|
||||
);
|
||||
const averagePricePaidData = signals.createSignal(
|
||||
const averageCostBasisData = signals.createSignal(
|
||||
/** @type {LineData[]} */ ([]),
|
||||
{
|
||||
equals: false,
|
||||
@@ -772,7 +772,7 @@ export function init({ colors, createChartElement, signals, resources }) {
|
||||
title: "Average Cost Basis",
|
||||
type: "Line",
|
||||
color: colors.lime,
|
||||
data: averagePricePaidData,
|
||||
data: averageCostBasisData,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -873,7 +873,7 @@ export function init({ colors, createChartElement, signals, resources }) {
|
||||
totalValueData().length = 0;
|
||||
investmentData().length = 0;
|
||||
bitcoinAddedData().length = 0;
|
||||
averagePricePaidData().length = 0;
|
||||
averageCostBasisData().length = 0;
|
||||
bitcoinPriceData().length = 0;
|
||||
buyCountData().length = 0;
|
||||
totalFeesPaidData().length = 0;
|
||||
@@ -887,7 +887,7 @@ export function init({ colors, createChartElement, signals, resources }) {
|
||||
let investedAmount = 0;
|
||||
let postFeesInvestedAmount = 0;
|
||||
let buyCount = 0;
|
||||
let averagePricePaid = 0;
|
||||
let averageCostBasis = 0;
|
||||
let bitcoinValue = 0;
|
||||
let roi = 0;
|
||||
let totalValue = 0;
|
||||
@@ -951,7 +951,7 @@ export function init({ colors, createChartElement, signals, resources }) {
|
||||
|
||||
totalValue = dollars + bitcoinValue;
|
||||
|
||||
averagePricePaid = postFeesInvestedAmount / bitcoin;
|
||||
averageCostBasis = postFeesInvestedAmount / bitcoin;
|
||||
|
||||
roi = (bitcoinValue / postFeesInvestedAmount - 1) * 100;
|
||||
|
||||
@@ -1010,9 +1010,9 @@ export function init({ colors, createChartElement, signals, resources }) {
|
||||
value: bitcoinAdded,
|
||||
});
|
||||
|
||||
averagePricePaidData().push({
|
||||
averageCostBasisData().push({
|
||||
time,
|
||||
value: averagePricePaid,
|
||||
value: averageCostBasis,
|
||||
});
|
||||
|
||||
buyCountData().push({
|
||||
@@ -1057,12 +1057,12 @@ export function init({ colors, createChartElement, signals, resources }) {
|
||||
const serSats = c("orange", f(sats));
|
||||
const serBitcoin = c("orange", `~${f(bitcoin)}`);
|
||||
const serBitcoinValue = c("amber", fd(bitcoinValue));
|
||||
const serAveragePricePaid = c("lime", fd(averagePricePaid));
|
||||
const serAverageCostBasis = c("lime", fd(averageCostBasis));
|
||||
const serRoi = c("yellow", fp(roi / 100));
|
||||
const serDollars = c("emerald", fd(dollars));
|
||||
const serTotalFeesPaid = c("rose", fd(totalFeesPaid));
|
||||
|
||||
p1.innerHTML = `After exchanging ${serInvestedAmount} in the span of ${serDaysCount} days, you would have accumulated ${serSats} Satoshis (${serBitcoin} Bitcoin) worth today ${serBitcoinValue} at an average price of ${serAveragePricePaid} per Bitcoin with a return of investment of ${serRoi}, have ${serDollars} left and paid a total of ${serTotalFeesPaid} in fees.`;
|
||||
p1.innerHTML = `After exchanging ${serInvestedAmount} in the span of ${serDaysCount} days, you would have accumulated ${serSats} Satoshis (${serBitcoin} Bitcoin) worth today ${serBitcoinValue} at an average cost basis of ${serAverageCostBasis} per Bitcoin with a return of investment of ${serRoi}, have ${serDollars} left and paid a total of ${serTotalFeesPaid} in fees.`;
|
||||
|
||||
const dayDiff = Math.floor(
|
||||
differenceBetweenDates(new Date(), lastInvestDay),
|
||||
@@ -1092,7 +1092,7 @@ export function init({ colors, createChartElement, signals, resources }) {
|
||||
totalValueData.set((a) => a);
|
||||
investmentData.set((a) => a);
|
||||
bitcoinAddedData.set((a) => a);
|
||||
averagePricePaidData.set((a) => a);
|
||||
averageCostBasisData.set((a) => a);
|
||||
bitcoinPriceData.set((a) => a);
|
||||
buyCountData.set((a) => a);
|
||||
totalFeesPaidData.set((a) => a);
|
||||
|
||||
@@ -308,7 +308,7 @@ export const serdeUnit = {
|
||||
(v.includes("_usd") && !v.endsWith("velocity")) ||
|
||||
v.includes("cointime_value") ||
|
||||
v.endsWith("_ago") ||
|
||||
v.endsWith("price_paid") ||
|
||||
v.endsWith("cost_basis") ||
|
||||
v.endsWith("_price") ||
|
||||
(v.startsWith("price") && (v.endsWith("min") || v.endsWith("max"))) ||
|
||||
(v.endsWith("_cap") && !v.includes("rel_to")) ||
|
||||
|
||||
Reference in New Issue
Block a user