mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-05-21 07:14:47 -07:00
website: update
This commit is contained in:
@@ -252,7 +252,6 @@
|
||||
--fuchsia: oklch(0.629 0.294 322.523);
|
||||
--pink: oklch(0.624 0.245 357.444);
|
||||
--rose: oklch(0.6155 0.2495 17.012);
|
||||
--dollar: var(--green);
|
||||
--background-color: light-dark(var(--white), var(--black));
|
||||
--color: light-dark(var(--black), var(--white));
|
||||
--off-color: light-dark(var(--light-gray), var(--dark-gray));
|
||||
@@ -654,11 +653,11 @@
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
background: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M7 10l5 5 5-5z" fill="gray"/><path d="M0 0h24v24H0z" fill="none"/></svg>')
|
||||
background: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="gray"><path fill-rule="evenodd" d="M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" /></svg>')
|
||||
100% 50% no-repeat transparent;
|
||||
|
||||
&:focus-visible {
|
||||
border: none;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* @import { Option, ResourceDataset, TimeScale, TimeRange, Unit, Marker, Weighted, DatasetPath, OHLC, FetchedJSON, DatasetValue, FetchedResult, AnyDatasetPath, SeriesBlueprint, BaselineSpecificSeriesBlueprint, CandlestickSpecificSeriesBlueprint, LineSpecificSeriesBlueprint, SpecificSeriesBlueprintWithChart, Signal, Color, DatasetCandlestickData, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, AnyPath, SimulationOption, Frequency, CreatePaneParameters, CreateBaselineSeriesParams, CreateCandlestickSeriesParams, CreateLineSeriesParams } from "./types/self"
|
||||
* @import { Option, ResourceDataset, TimeScale, TimeRange, Unit, Marker, Weighted, DatasetPath, OHLC, FetchedJSON, DatasetValue, FetchedResult, AnyDatasetPath, SeriesBlueprint, BaselineSpecificSeriesBlueprint, CandlestickSpecificSeriesBlueprint, LineSpecificSeriesBlueprint, SpecificSeriesBlueprintWithChart, Signal, Color, DatasetCandlestickData, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, AnyPath, SimulationOption, Frequency, CreatePaneParameters, CreateBaselineSeriesParams, CreateCandlestickSeriesParams, CreateLineSeriesParams, LastValues } from "./types/self"
|
||||
* @import {createChart as CreateClassicChart, createChartEx as CreateCustomChart, LineStyleOptions} from "../packages/lightweight-charts/v4.2.0/types";
|
||||
* @import * as _ from "../packages/ufuzzy/v1.0.14/types"
|
||||
* @import { DeepPartial, ChartOptions, IChartApi, IHorzScaleBehavior, WhitespaceData, SingleValueData, ISeriesApi, Time, LineData, LogicalRange, SeriesMarker, CandlestickData, SeriesType, BaselineStyleOptions, SeriesOptionsCommon } from "../packages/lightweight-charts/v4.2.0/types"
|
||||
@@ -665,8 +665,7 @@ function initPackages() {
|
||||
const chartModes = /** @type {const} */ (["Linear", "Log"]);
|
||||
const chartMode = signals.createSignal(
|
||||
/** @type {Lowercase<typeof chartModes[number]>} */ (
|
||||
localStorage.getItem(id) ||
|
||||
chartModes[chartIndex ? 0 : 1].toLowerCase()
|
||||
localStorage.getItem(id) || "linear"
|
||||
),
|
||||
);
|
||||
|
||||
@@ -2048,6 +2047,8 @@ function createColors(dark) {
|
||||
blue,
|
||||
rose,
|
||||
pink,
|
||||
green,
|
||||
purple,
|
||||
|
||||
_1d: pink,
|
||||
_1w: red,
|
||||
@@ -2138,7 +2139,6 @@ function createColors(dark) {
|
||||
coinblocksCreated: purple,
|
||||
coinblocksDestroyed: red,
|
||||
coinblocksStored: green,
|
||||
momentum: [green, yellow, red],
|
||||
momentumGreen: green,
|
||||
momentumYellow: yellow,
|
||||
momentumRed: red,
|
||||
@@ -2703,9 +2703,8 @@ packages.signals().then((signals) =>
|
||||
}
|
||||
const lastHeight = createLastHeightResource();
|
||||
|
||||
const lastValues = signals.createSignal(
|
||||
/** @type {Record<LastPath, number> | null} */ (null),
|
||||
);
|
||||
const lastValues = signals.createSignal(/** @type {LastValues} */ (null));
|
||||
|
||||
function createFetchLastValuesWhenNeededEffect() {
|
||||
let previousHeight = -1;
|
||||
signals.createEffect(lastHeight, (lastHeight) => {
|
||||
@@ -2831,17 +2830,12 @@ packages.signals().then((signals) =>
|
||||
signals.runWithOwner(owner, () =>
|
||||
init({
|
||||
colors,
|
||||
consts,
|
||||
dark,
|
||||
datasets,
|
||||
elements,
|
||||
ids,
|
||||
lightweightCharts,
|
||||
options,
|
||||
selected: option,
|
||||
signals,
|
||||
utils,
|
||||
webSockets,
|
||||
lastValues,
|
||||
}),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,35 +1,26 @@
|
||||
/**
|
||||
* @import { Options } from './options';
|
||||
* @import { ColorName } from './types/self';
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Object} args
|
||||
* @param {Colors} args.colors
|
||||
* @param {Consts} args.consts
|
||||
* @param {LightweightCharts} args.lightweightCharts
|
||||
* @param {SimulationOption} args.selected
|
||||
* @param {Signals} args.signals
|
||||
* @param {Utilities} args.utils
|
||||
* @param {Options} args.options
|
||||
* @param {Datasets} args.datasets
|
||||
* @param {WebSockets} args.webSockets
|
||||
* @param {Elements} args.elements
|
||||
* @param {Ids} args.ids
|
||||
* @param {Accessor<boolean>} args.dark
|
||||
* @param {Signal<LastValues>} args.lastValues
|
||||
*/
|
||||
export function init({
|
||||
colors,
|
||||
consts,
|
||||
dark,
|
||||
datasets,
|
||||
elements,
|
||||
ids,
|
||||
lightweightCharts,
|
||||
options,
|
||||
selected,
|
||||
signals,
|
||||
utils,
|
||||
webSockets,
|
||||
lastValues,
|
||||
}) {
|
||||
const simulationElement = elements.simulation;
|
||||
|
||||
@@ -137,6 +128,25 @@ export function init({
|
||||
}).headerElement,
|
||||
);
|
||||
|
||||
/**
|
||||
* @param {Object} param0
|
||||
* @param {ColorName} param0.color
|
||||
* @param {string} param0.type
|
||||
* @param {string} param0.text
|
||||
*/
|
||||
function createColoredTypeHTML({ color, type, text }) {
|
||||
return `${createColoredSpan({ color, text: `${type}:` })} ${text}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} param0
|
||||
* @param {ColorName} param0.color
|
||||
* @param {string} param0.text
|
||||
*/
|
||||
function createColoredSpan({ color, text }) {
|
||||
return `<span style="color: ${colors[color]()}; font-weight: var(--font-weight-bold)">${text}</span>`;
|
||||
}
|
||||
|
||||
parametersElement.append(
|
||||
createFieldElement({
|
||||
title: createColoredTypeHTML({
|
||||
@@ -291,9 +301,10 @@ export function init({
|
||||
}),
|
||||
);
|
||||
|
||||
const firstParagraph = window.document.createElement("p");
|
||||
|
||||
const secondParagraph = window.document.createElement("p");
|
||||
const p1 = window.document.createElement("p");
|
||||
const p2 = window.document.createElement("p");
|
||||
const p3 = window.document.createElement("p");
|
||||
const p4 = window.document.createElement("p");
|
||||
|
||||
const owner = signals.getOwner();
|
||||
|
||||
@@ -326,8 +337,9 @@ export function init({
|
||||
console.log({ start, end });
|
||||
|
||||
resultsElement.innerHTML = "";
|
||||
resultsElement.append(firstParagraph);
|
||||
resultsElement.append(secondParagraph);
|
||||
resultsElement.append(p1);
|
||||
resultsElement.append(p2);
|
||||
resultsElement.append(p3);
|
||||
|
||||
if (!start || !end || start > end) return;
|
||||
|
||||
@@ -361,6 +373,8 @@ export function init({
|
||||
const daysCountData = [];
|
||||
/** @type {LineData<Time>[]} */
|
||||
const profitableDaysRatioData = [];
|
||||
/** @type {LineData<Time>[]} */
|
||||
const unprofitableDaysRatioData = [];
|
||||
|
||||
let bitcoin = 0;
|
||||
let dollars = initialDollarAmount;
|
||||
@@ -374,6 +388,8 @@ export function init({
|
||||
let daysCount = range.length;
|
||||
let profitableDays = 0;
|
||||
let unprofitableDays = 0;
|
||||
let profitableDaysRatio = 0;
|
||||
let unprofitableDaysRatio = 0;
|
||||
|
||||
range.forEach((date, index) => {
|
||||
const year = date.getUTCFullYear();
|
||||
@@ -423,6 +439,8 @@ export function init({
|
||||
roi = (bitcoinValue / investedAmount - 1) * 100;
|
||||
|
||||
const daysCount = index + 1;
|
||||
profitableDaysRatio = (profitableDays / daysCount) * 100;
|
||||
unprofitableDaysRatio = (unprofitableDays / daysCount) * 100;
|
||||
|
||||
if (roi >= 0) {
|
||||
profitableDays += 1;
|
||||
@@ -497,20 +515,78 @@ export function init({
|
||||
|
||||
profitableDaysRatioData.push({
|
||||
time,
|
||||
value: profitableDays / daysCount,
|
||||
value: profitableDaysRatio,
|
||||
});
|
||||
|
||||
unprofitableDaysRatioData.push({
|
||||
time,
|
||||
value: unprofitableDaysRatio,
|
||||
});
|
||||
});
|
||||
|
||||
const f = utils.locale.numberToUSFormat;
|
||||
/**
|
||||
* @param {string} c
|
||||
* @param {ColorName} c
|
||||
* @param {string} t
|
||||
*/
|
||||
const c = (c, t) => createColoredSpan({ color: c, text: t });
|
||||
|
||||
firstParagraph.innerHTML = `After exchanging ${c("dollar", `$${f(investedAmount)}`)} in the span of ${c("sky", f(daysCount))} days, you would've accumulated ${c("orange", f(bitcoin))} Bitcoin worth ${c("dollar", `$${f(bitcoinValue)}`)} at an average price of ${c("dollar", `$${f(averagePricePaid)}`)} per Bitcoin with a return of investment of ${c("yellow", `${f(roi)}%`)}.`;
|
||||
const serInvestedAmount = c("dollars", `$${f(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)}%`);
|
||||
|
||||
secondParagraph.innerHTML = `Work in progress`;
|
||||
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}.`;
|
||||
|
||||
const serProfitableDaysRatio = c(
|
||||
"green",
|
||||
`${f(profitableDaysRatio)}%`,
|
||||
);
|
||||
const serUnprofitableDaysRatio = c(
|
||||
"red",
|
||||
`${f(unprofitableDaysRatio)}%`,
|
||||
);
|
||||
|
||||
p2.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 = lastValues?.["price-4y-compound-return"] || 0
|
||||
const serLowestAnnual4YReturn = c(
|
||||
"yellow",
|
||||
`${f(lowestAnnual4YReturn)}%`,
|
||||
);
|
||||
|
||||
const lowestAnnual4YReturnPercentage =
|
||||
1 + lowestAnnual4YReturn / 100;
|
||||
/**
|
||||
* @param {number} power
|
||||
*/
|
||||
function bitcoinValueReturn(power) {
|
||||
return (
|
||||
bitcoinValue * Math.pow(lowestAnnual4YReturnPercentage, power)
|
||||
);
|
||||
}
|
||||
const bitcoinValueAfter4y = bitcoinValueReturn(4);
|
||||
const serBitcoinValueAfter4y = c(
|
||||
"rose",
|
||||
`$${f(bitcoinValueAfter4y)}`,
|
||||
);
|
||||
const bitcoinValueAfter10y = bitcoinValueReturn(10);
|
||||
const serBitcoinValueAfter10y = c(
|
||||
"pink",
|
||||
`$${f(bitcoinValueAfter10y)}`,
|
||||
);
|
||||
const bitcoinValueAfter20y = bitcoinValueReturn(20);
|
||||
const serBitcoinValueAfter20y = c(
|
||||
"purple",
|
||||
`$${f(bitcoinValueAfter20y)}`,
|
||||
);
|
||||
|
||||
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.`;
|
||||
});
|
||||
|
||||
lightweightCharts.createChart({
|
||||
parent: resultsElement,
|
||||
@@ -523,12 +599,6 @@ export function init({
|
||||
unit: "US Dollars",
|
||||
scale: "date",
|
||||
config: [
|
||||
{
|
||||
kind: "line",
|
||||
color: colors.dollars,
|
||||
owner,
|
||||
data: totalInvestedAmountData,
|
||||
},
|
||||
{
|
||||
kind: "line",
|
||||
color: colors.bitcoin,
|
||||
@@ -549,9 +619,9 @@ export function init({
|
||||
},
|
||||
{
|
||||
kind: "line",
|
||||
color: colors.yellow,
|
||||
color: colors.dollars,
|
||||
owner,
|
||||
data: investmentData,
|
||||
data: totalInvestedAmountData,
|
||||
},
|
||||
{
|
||||
kind: "line",
|
||||
@@ -564,6 +634,28 @@ export function init({
|
||||
],
|
||||
});
|
||||
|
||||
// lightweightCharts.createChart({
|
||||
// parent: resultsElement,
|
||||
// signals,
|
||||
// colors,
|
||||
// id: `simulation-0`,
|
||||
// kind: "static",
|
||||
// config: [
|
||||
// {
|
||||
// unit: "US Dollars",
|
||||
// scale: "date",
|
||||
// config: [
|
||||
// {
|
||||
// kind: "line",
|
||||
// color: colors.yellow,
|
||||
// owner,
|
||||
// data: investmentData,
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// });
|
||||
|
||||
lightweightCharts.createChart({
|
||||
parent: resultsElement,
|
||||
signals,
|
||||
@@ -581,43 +673,38 @@ export function init({
|
||||
owner,
|
||||
data: bitcoinData,
|
||||
},
|
||||
{
|
||||
kind: "line",
|
||||
color: colors.lightBitcoin,
|
||||
owner,
|
||||
data: bitcoinAddedData,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
lightweightCharts.createChart({
|
||||
parent: resultsElement,
|
||||
signals,
|
||||
colors,
|
||||
id: `simulation-2`,
|
||||
kind: "static",
|
||||
config: [
|
||||
{
|
||||
unit: "US Dollars",
|
||||
scale: "date",
|
||||
config: [
|
||||
{
|
||||
kind: "baseline",
|
||||
owner,
|
||||
data: resultData,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
// lightweightCharts.createChart({
|
||||
// parent: resultsElement,
|
||||
// signals,
|
||||
// colors,
|
||||
// id: `simulation-1`,
|
||||
// kind: "static",
|
||||
// config: [
|
||||
// {
|
||||
// unit: "US Dollars",
|
||||
// scale: "date",
|
||||
// config: [
|
||||
// {
|
||||
// kind: "line",
|
||||
// color: colors.lightBitcoin,
|
||||
// owner,
|
||||
// data: bitcoinAddedData,
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// });
|
||||
|
||||
lightweightCharts.createChart({
|
||||
parent: resultsElement,
|
||||
signals,
|
||||
colors,
|
||||
id: `simulation-3`,
|
||||
id: `simulation-average-price`,
|
||||
kind: "static",
|
||||
config: [
|
||||
{
|
||||
@@ -645,7 +732,66 @@ export function init({
|
||||
parent: resultsElement,
|
||||
signals,
|
||||
colors,
|
||||
id: `simulation-4`,
|
||||
id: `simulation-return-ratio`,
|
||||
kind: "static",
|
||||
config: [
|
||||
{
|
||||
unit: "US Dollars",
|
||||
scale: "date",
|
||||
config: [
|
||||
{
|
||||
kind: "baseline",
|
||||
owner,
|
||||
data: resultData,
|
||||
// TODO: Doesn't work for some reason
|
||||
// options: {
|
||||
// baseLineColor: "#888",
|
||||
// baseLineVisible: true,
|
||||
// baseLineWidth: 1,
|
||||
// baseValue: {
|
||||
// price: 0,
|
||||
// type: "price",
|
||||
// },
|
||||
// },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
lightweightCharts.createChart({
|
||||
parent: resultsElement,
|
||||
signals,
|
||||
colors,
|
||||
id: `simulation-profitability-ratios`,
|
||||
kind: "static",
|
||||
config: [
|
||||
{
|
||||
unit: "Percentage",
|
||||
scale: "date",
|
||||
config: [
|
||||
{
|
||||
kind: "line",
|
||||
owner,
|
||||
color: colors.pink,
|
||||
data: unprofitableDaysRatioData,
|
||||
},
|
||||
{
|
||||
kind: "line",
|
||||
owner,
|
||||
color: colors.lime,
|
||||
data: profitableDaysRatioData,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
lightweightCharts.createChart({
|
||||
parent: resultsElement,
|
||||
signals,
|
||||
colors,
|
||||
id: `simulation-counts`,
|
||||
kind: "static",
|
||||
config: [
|
||||
{
|
||||
@@ -668,28 +814,6 @@ export function init({
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
lightweightCharts.createChart({
|
||||
parent: resultsElement,
|
||||
signals,
|
||||
colors,
|
||||
id: `simulation-5`,
|
||||
kind: "static",
|
||||
config: [
|
||||
{
|
||||
unit: "Percentage",
|
||||
scale: "date",
|
||||
config: [
|
||||
{
|
||||
kind: "line",
|
||||
owner,
|
||||
color: colors.pink,
|
||||
data: profitableDaysRatioData,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -804,25 +928,6 @@ function getOrdinalDay(day) {
|
||||
}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} param0
|
||||
* @param {string} param0.color
|
||||
* @param {string} param0.type
|
||||
* @param {string} param0.text
|
||||
*/
|
||||
function createColoredTypeHTML({ color, type, text }) {
|
||||
return `${createColoredSpan({ color, text: `${type}:` })} ${text}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} param0
|
||||
* @param {string} param0.color
|
||||
* @param {string} param0.text
|
||||
*/
|
||||
function createColoredSpan({ color, text }) {
|
||||
return `<span style="color: var(--${color}); font-weight: var(--font-weight-bold)">${text}</span>`;
|
||||
}
|
||||
|
||||
function computeFrequencies() {
|
||||
const weekDays = [
|
||||
"Monday",
|
||||
|
||||
3
website/scripts/types/self.d.ts
vendored
3
website/scripts/types/self.d.ts
vendored
@@ -42,6 +42,7 @@ type AnyDatasetPath = import("./paths").DatePath | import("./paths").HeightPath;
|
||||
type AnyPath = AnyDatasetPath | LastPath;
|
||||
|
||||
type Color = () => string;
|
||||
type ColorName = keyof Colors;
|
||||
|
||||
interface BaselineSpecificSeriesBlueprint {
|
||||
type: "Baseline";
|
||||
@@ -399,3 +400,5 @@ interface CreatePaneParameters {
|
||||
| ({ kind: "baseline" } & CreateBaselineSeriesParams)
|
||||
)[];
|
||||
}
|
||||
|
||||
type LastValues = Record<LastPath, number> | null;
|
||||
|
||||
Reference in New Issue
Block a user