mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-25 15:19:58 -07:00
website: simulation: small changes
This commit is contained in:
@@ -1527,6 +1527,7 @@ const utils = {
|
||||
}),
|
||||
},
|
||||
date: {
|
||||
ONE_DAY_IN_MS: 1000 * 60 * 60 * 24,
|
||||
todayUTC() {
|
||||
const today = new Date();
|
||||
return new Date(
|
||||
@@ -1575,6 +1576,14 @@ const utils = {
|
||||
}
|
||||
return dates;
|
||||
},
|
||||
/**
|
||||
* @param {Date} date1
|
||||
* @param {Date} date2
|
||||
* @returns
|
||||
*/
|
||||
differenceBetween(date1, date2) {
|
||||
return Math.abs(date1.valueOf() - date2.valueOf()) / this.ONE_DAY_IN_MS;
|
||||
},
|
||||
},
|
||||
color: {
|
||||
/**
|
||||
@@ -2046,9 +2055,14 @@ function createColors(dark) {
|
||||
sky,
|
||||
blue,
|
||||
rose,
|
||||
pink,
|
||||
green,
|
||||
amber,
|
||||
avocado,
|
||||
cyan,
|
||||
violet,
|
||||
purple,
|
||||
fuchsia,
|
||||
pink,
|
||||
|
||||
_1d: pink,
|
||||
_1w: red,
|
||||
|
||||
@@ -285,10 +285,9 @@ export function init({
|
||||
title: createColoredTypeHTML({
|
||||
color: "red",
|
||||
type: "Fees",
|
||||
text: "Percentage",
|
||||
text: "Exchange",
|
||||
}),
|
||||
description:
|
||||
"The amount of fees (in %) from where you'll be exchanging your dollars.",
|
||||
description: "The amount of trading fees (in %) at the exchange.",
|
||||
input: utils.dom.createInputNumberElement({
|
||||
id: "",
|
||||
title: "",
|
||||
@@ -340,6 +339,7 @@ export function init({
|
||||
resultsElement.append(p1);
|
||||
resultsElement.append(p2);
|
||||
resultsElement.append(p3);
|
||||
resultsElement.append(p4);
|
||||
|
||||
if (!start || !end || start > end) return;
|
||||
|
||||
@@ -377,8 +377,10 @@ export function init({
|
||||
const unprofitableDaysRatioData = [];
|
||||
|
||||
let bitcoin = 0;
|
||||
let sats = 0;
|
||||
let dollars = initialDollarAmount;
|
||||
let investedAmount = 0;
|
||||
let postFeesInvestedAmount = 0;
|
||||
let buyCount = 0;
|
||||
let averagePricePaid = 0;
|
||||
let bitcoinValue = 0;
|
||||
@@ -390,6 +392,10 @@ export function init({
|
||||
let unprofitableDays = 0;
|
||||
let profitableDaysRatio = 0;
|
||||
let unprofitableDaysRatio = 0;
|
||||
let lastInvestDay = range[0];
|
||||
let dailyInvestment = 0;
|
||||
let bitcoinAdded = 0;
|
||||
let satsAdded = 0;
|
||||
|
||||
range.forEach((date, index) => {
|
||||
const year = date.getUTCFullYear();
|
||||
@@ -405,13 +411,14 @@ export function init({
|
||||
|
||||
if (!close) return;
|
||||
|
||||
let dailyInvestment = 0;
|
||||
dailyInvestment = 0;
|
||||
/** @param {number} value */
|
||||
function invest(value) {
|
||||
value = Math.min(dollars, value);
|
||||
dailyInvestment += value;
|
||||
dollars -= value;
|
||||
buyCount += 1;
|
||||
lastInvestDay = date;
|
||||
}
|
||||
if (!index) {
|
||||
invest(initialSwap);
|
||||
@@ -420,27 +427,31 @@ export function init({
|
||||
invest(recurrentSwap);
|
||||
}
|
||||
|
||||
investedAmount += dailyInvestment;
|
||||
|
||||
let dailyInvestmentPostFees =
|
||||
dailyInvestment * (1 - (fees || 0) / 100);
|
||||
|
||||
totalFeesPaid += dailyInvestment - dailyInvestmentPostFees;
|
||||
|
||||
const bitcoinAdded = dailyInvestmentPostFees / close;
|
||||
bitcoinAdded = dailyInvestmentPostFees / close;
|
||||
bitcoin += bitcoinAdded;
|
||||
satsAdded = Math.floor(bitcoinAdded * 100_000_000);
|
||||
sats += satsAdded;
|
||||
|
||||
investedAmount += dailyInvestmentPostFees;
|
||||
postFeesInvestedAmount += dailyInvestmentPostFees;
|
||||
|
||||
bitcoinValue = close * bitcoin;
|
||||
|
||||
totalValue = dollars + bitcoinValue;
|
||||
|
||||
averagePricePaid = investedAmount / bitcoin;
|
||||
averagePricePaid = postFeesInvestedAmount / bitcoin;
|
||||
|
||||
roi = (bitcoinValue / investedAmount - 1) * 100;
|
||||
roi = (bitcoinValue / postFeesInvestedAmount - 1) * 100;
|
||||
|
||||
const daysCount = index + 1;
|
||||
profitableDaysRatio = (profitableDays / daysCount) * 100;
|
||||
unprofitableDaysRatio = (unprofitableDays / daysCount) * 100;
|
||||
profitableDaysRatio = profitableDays / daysCount;
|
||||
unprofitableDaysRatio = unprofitableDays / daysCount;
|
||||
|
||||
if (roi >= 0) {
|
||||
profitableDays += 1;
|
||||
@@ -515,52 +526,59 @@ export function init({
|
||||
|
||||
profitableDaysRatioData.push({
|
||||
time,
|
||||
value: profitableDaysRatio,
|
||||
value: profitableDaysRatio * 100,
|
||||
});
|
||||
|
||||
unprofitableDaysRatioData.push({
|
||||
time,
|
||||
value: unprofitableDaysRatio,
|
||||
value: unprofitableDaysRatio * 100,
|
||||
});
|
||||
});
|
||||
|
||||
const f = utils.locale.numberToUSFormat;
|
||||
/** @param {number} v */
|
||||
const fd = (v) => utils.formatters.dollars.format(v);
|
||||
/** @param {number} v */
|
||||
const fp = (v) => utils.formatters.percentage.format(v);
|
||||
/**
|
||||
* @param {ColorName} c
|
||||
* @param {string} t
|
||||
*/
|
||||
const c = (c, t) => createColoredSpan({ color: c, text: t });
|
||||
|
||||
const serInvestedAmount = c("dollars", `$${f(investedAmount)}`);
|
||||
const serInvestedAmount = c("dollars", fd(investedAmount));
|
||||
const serDaysCount = c("sky", f(daysCount));
|
||||
const serBitcoin = c("orange", f(bitcoin));
|
||||
const serBitcoinValue = c("dollars", `$${f(bitcoinValue)}`);
|
||||
const serAveragePricePaid = c("dollars", `$${f(averagePricePaid)}`);
|
||||
const serRoi = c("yellow", `${f(roi)}%`);
|
||||
const serSats = c("orange", f(sats));
|
||||
const serBitcoin = c("orange", `~${f(bitcoin)}`);
|
||||
const serBitcoinValue = c("amber", fd(bitcoinValue));
|
||||
const serAveragePricePaid = c("lightDollars", fd(averagePricePaid));
|
||||
const serRoi = c("yellow", fp(roi / 100));
|
||||
const serDollars = c("offDollars", fd(dollars));
|
||||
const serTotalFeesPaid = c("rose", fd(totalFeesPaid));
|
||||
|
||||
p1.innerHTML = `After exchanging ${serInvestedAmount} in the span of ${serDaysCount} days, you would've accumulated ${serBitcoin} Bitcoin worth ${serBitcoinValue} at an average price of ${serAveragePricePaid} per Bitcoin with a return of investment of ${serRoi}.`;
|
||||
p1.innerHTML = `After exchanging ${serInvestedAmount} in the span of ${serDaysCount} days, you would have accumulated ${serSats} Satoshis (${serBitcoin} Bitcoin) worth ${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.`;
|
||||
|
||||
const serProfitableDaysRatio = c(
|
||||
"green",
|
||||
`${f(profitableDaysRatio)}%`,
|
||||
);
|
||||
const serUnprofitableDaysRatio = c(
|
||||
"red",
|
||||
`${f(unprofitableDaysRatio)}%`,
|
||||
const dayDiff = Math.floor(
|
||||
utils.date.differenceBetween(new Date(), lastInvestDay),
|
||||
);
|
||||
const serDailyInvestment = c("offDollars", fd(dailyInvestment));
|
||||
const setSatsAdded = c("bitcoin", f(satsAdded));
|
||||
p2.innerHTML = `Your last buy would've happened ${c("blue", dayDiff ? f(dayDiff) : "today")} where you would have exchanged ${serDailyInvestment} for ${setSatsAdded} Satoshis`;
|
||||
|
||||
p2.innerHTML = `You would've been ${serProfitableDaysRatio} of the time profitable and ${serUnprofitableDaysRatio} of the time unprofitable.`;
|
||||
const serProfitableDaysRatio = c("green", fp(profitableDaysRatio));
|
||||
const serUnprofitableDaysRatio = c("red", fp(unprofitableDaysRatio));
|
||||
|
||||
p3.innerHTML = `You would've been ${serProfitableDaysRatio} of the time profitable and ${serUnprofitableDaysRatio} of the time unprofitable.`;
|
||||
|
||||
signals.createEffect(lastValues, (lastValues) => {
|
||||
const lowestAnnual4YReturn = 23.68;
|
||||
const lowestAnnual4YReturn = 0.2368;
|
||||
// const lowestAnnual4YReturn = lastValues?.["price-4y-compound-return"] || 0
|
||||
const serLowestAnnual4YReturn = c(
|
||||
"yellow",
|
||||
`${f(lowestAnnual4YReturn)}%`,
|
||||
"cyan",
|
||||
`${fp(lowestAnnual4YReturn)}`,
|
||||
);
|
||||
|
||||
const lowestAnnual4YReturnPercentage =
|
||||
1 + lowestAnnual4YReturn / 100;
|
||||
const lowestAnnual4YReturnPercentage = 1 + lowestAnnual4YReturn;
|
||||
/**
|
||||
* @param {number} power
|
||||
*/
|
||||
@@ -570,22 +588,17 @@ export function init({
|
||||
);
|
||||
}
|
||||
const bitcoinValueAfter4y = bitcoinValueReturn(4);
|
||||
const serBitcoinValueAfter4y = c(
|
||||
"rose",
|
||||
`$${f(bitcoinValueAfter4y)}`,
|
||||
);
|
||||
const serBitcoinValueAfter4y = c("purple", fd(bitcoinValueAfter4y));
|
||||
const bitcoinValueAfter10y = bitcoinValueReturn(10);
|
||||
const serBitcoinValueAfter10y = c(
|
||||
"pink",
|
||||
`$${f(bitcoinValueAfter10y)}`,
|
||||
);
|
||||
const bitcoinValueAfter20y = bitcoinValueReturn(20);
|
||||
const serBitcoinValueAfter20y = c(
|
||||
"purple",
|
||||
`$${f(bitcoinValueAfter20y)}`,
|
||||
"fuchsia",
|
||||
fd(bitcoinValueAfter10y),
|
||||
);
|
||||
const bitcoinValueAfter21y = bitcoinValueReturn(21);
|
||||
const serBitcoinValueAfter21y = c("pink", fd(bitcoinValueAfter21y));
|
||||
|
||||
p3.innerHTML = `Historically, the lowest annual return after 4 years has been ${serLowestAnnual4YReturn}.<br/>Using this as our baseline and assuming you don't swap any more US Dollars, your Bitcoin would be worth ${serBitcoinValueAfter4y} after 4 years, ${serBitcoinValueAfter10y} after 10 years and ${serBitcoinValueAfter20y} after 20 years.`;
|
||||
/** @param {number} v */
|
||||
p4.innerHTML = `The lowest annual return after 4 years has historically been ${serLowestAnnual4YReturn}.<br/>Using it as the baseline, your Bitcoin would be worth ${serBitcoinValueAfter4y} after 4 years, ${serBitcoinValueAfter10y} after 10 years and ${serBitcoinValueAfter21y} after 21 years.`;
|
||||
});
|
||||
|
||||
lightweightCharts.createChart({
|
||||
@@ -601,22 +614,16 @@ export function init({
|
||||
config: [
|
||||
{
|
||||
kind: "line",
|
||||
color: colors.bitcoin,
|
||||
color: colors.amber,
|
||||
owner,
|
||||
data: bitcoinValueData,
|
||||
},
|
||||
{
|
||||
kind: "line",
|
||||
color: colors.lime,
|
||||
color: colors.offDollars,
|
||||
owner,
|
||||
data: dollarsLeftData,
|
||||
},
|
||||
{
|
||||
kind: "line",
|
||||
color: colors.default,
|
||||
owner,
|
||||
data: totalValueData,
|
||||
},
|
||||
{
|
||||
kind: "line",
|
||||
color: colors.dollars,
|
||||
@@ -625,7 +632,7 @@ export function init({
|
||||
},
|
||||
{
|
||||
kind: "line",
|
||||
color: colors.red,
|
||||
color: colors.rose,
|
||||
owner,
|
||||
data: totalFeesPaidData,
|
||||
},
|
||||
@@ -670,13 +677,13 @@ export function init({
|
||||
{
|
||||
kind: "line",
|
||||
owner,
|
||||
color: colors.bitcoin,
|
||||
color: colors.default,
|
||||
data: bitcoinPriceData,
|
||||
},
|
||||
{
|
||||
kind: "line",
|
||||
owner,
|
||||
color: colors.default,
|
||||
color: colors.lightDollars,
|
||||
data: averagePricePaidData,
|
||||
},
|
||||
],
|
||||
@@ -729,47 +736,19 @@ export function init({
|
||||
{
|
||||
kind: "line",
|
||||
owner,
|
||||
color: colors.pink,
|
||||
color: colors.red,
|
||||
data: unprofitableDaysRatioData,
|
||||
},
|
||||
{
|
||||
kind: "line",
|
||||
owner,
|
||||
color: colors.lime,
|
||||
color: colors.green,
|
||||
data: profitableDaysRatioData,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
lightweightCharts.createChart({
|
||||
parent: resultsElement,
|
||||
signals,
|
||||
colors,
|
||||
id: `simulation-counts`,
|
||||
kind: "static",
|
||||
config: [
|
||||
{
|
||||
unit: "US Dollars",
|
||||
scale: "date",
|
||||
config: [
|
||||
{
|
||||
kind: "line",
|
||||
owner,
|
||||
color: colors.blue,
|
||||
data: buyCountData,
|
||||
},
|
||||
{
|
||||
kind: "line",
|
||||
owner,
|
||||
color: colors.sky,
|
||||
data: daysCountData,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user