general: snapshot

This commit is contained in:
k
2024-07-12 08:35:41 +02:00
parent 350c835873
commit 35fd5054aa
51 changed files with 2831 additions and 3251 deletions

View File

@@ -1,10 +1,12 @@
export const xthCohorts = [
{
id: "sth",
key: "sth",
name: "Short Term Holders",
legend: "STH",
},
{
id: "lth",
key: "lth",
name: "Long Term Holders",
legend: "LTH",
@@ -12,75 +14,86 @@ export const xthCohorts = [
] as const;
export const upToCohorts = [
{ key: "up_to_1d", name: "Up To 1 Day", legend: "1D" },
{ key: "up_to_1w", name: "Up To 1 Week", legend: "1W" },
{ key: "up_to_1m", name: "Up To 1 Month", legend: "1M" },
{ key: "up_to_2m", name: "Up To 2 Months", legend: "2M" },
{ key: "up_to_3m", name: "Up To 3 Months", legend: "3M" },
{ key: "up_to_4m", name: "Up To 4 Months", legend: "4M" },
{ key: "up_to_5m", name: "Up To 5 Months", legend: "5M" },
{ key: "up_to_6m", name: "Up To 6 Months", legend: "6M" },
{ key: "up_to_1y", name: "Up To 1 Year", legend: "1Y" },
{ key: "up_to_2y", name: "Up To 2 Years", legend: "2Y" },
{ key: "up_to_3y", name: "Up To 3 Years", legend: "3Y" },
{ key: "up_to_5y", name: "Up To 5 Years", legend: "5Y" },
{ key: "up_to_7y", name: "Up To 7 Years", legend: "7Y" },
{ key: "up_to_10y", name: "Up To 10 Years", legend: "10Y" },
{ key: "up_to_15y", name: "Up To 15 Years", legend: "15Y" },
{ id: "up-to-1d", key: "up_to_1d", name: "Up To 1 Day", legend: "1D" },
{ id: "up-to-1w", key: "up_to_1w", name: "Up To 1 Week", legend: "1W" },
{ id: "up-to-1m", key: "up_to_1m", name: "Up To 1 Month", legend: "1M" },
{ id: "up-to-2m", key: "up_to_2m", name: "Up To 2 Months", legend: "2M" },
{ id: "up-to-3m", key: "up_to_3m", name: "Up To 3 Months", legend: "3M" },
{ id: "up-to-4m", key: "up_to_4m", name: "Up To 4 Months", legend: "4M" },
{ id: "up-to-5m", key: "up_to_5m", name: "Up To 5 Months", legend: "5M" },
{ id: "up-to-6m", key: "up_to_6m", name: "Up To 6 Months", legend: "6M" },
{ id: "up-to-1y", key: "up_to_1y", name: "Up To 1 Year", legend: "1Y" },
{ id: "up-to-2y", key: "up_to_2y", name: "Up To 2 Years", legend: "2Y" },
{ id: "up-to-3y", key: "up_to_3y", name: "Up To 3 Years", legend: "3Y" },
{ id: "up-to-5y", key: "up_to_5y", name: "Up To 5 Years", legend: "5Y" },
{ id: "up-to-7y", key: "up_to_7y", name: "Up To 7 Years", legend: "7Y" },
{ id: "up-to-10y", key: "up_to_10y", name: "Up To 10 Years", legend: "10Y" },
{ id: "up-to-15y", key: "up_to_15y", name: "Up To 15 Years", legend: "15Y" },
] as const;
export const fromXToYCohorts = [
{
id: "from-1d-to-1w",
key: "from_1d_to_1w",
name: "From 1 Day To 1 Week",
legend: "1D - 1W",
},
{
id: "from-1w-to-1m",
key: "from_1w_to_1m",
name: "From 1 Week To 1 Month",
legend: "1W - 1M",
},
{
id: "from-1m-to-3m",
key: "from_1m_to_3m",
name: "From 1 Month To 3 Months",
legend: "1M - 3M",
},
{
id: "from-3m-to-6m",
key: "from_3m_to_6m",
name: "From 3 Months To 6 Months",
legend: "3M - 6M",
},
{
id: "from-6m-to-1y",
key: "from_6m_to_1y",
name: "From 6 Months To 1 Year",
legend: "6M - 1Y",
},
{
id: "from-1y-to-2y",
key: "from_1y_to_2y",
name: "From 1 Year To 2 Years",
legend: "1Y - 2Y",
},
{
id: "from-2y-to-3y",
key: "from_2y_to_3y",
name: "From 2 Years To 3 Years",
legend: "2Y - 3Y",
},
{
id: "from-3y-to-5y",
key: "from_3y_to_5y",
name: "From 3 Years To 5 Years",
legend: "3Y - 5Y",
},
{
id: "from-5y-to-7y",
key: "from_5y_to_7y",
name: "From 5 Years To 7 Years",
legend: "5Y - 7Y",
},
{
id: "from-7y-to-10y",
key: "from_7y_to_10y",
name: "From 7 Years To 10 Years",
legend: "7Y - 10Y",
},
{
id: "from-10y-to-15y",
key: "from_10y_to_15y",
name: "From 10 Years To 15 Years",
legend: "10Y - 15Y",
@@ -89,26 +102,31 @@ export const fromXToYCohorts = [
export const fromXCohorts = [
{
id: "from-1y",
key: "from_1y",
name: "From 1 Year",
legend: "1Y+",
},
{
id: "from-2y",
key: "from_2y",
name: "From 2 Years",
legend: "2Y+",
},
{
id: "from-4y",
key: "from_4y",
name: "From 4 Years",
legend: "4Y+",
},
{
id: "from-10y",
key: "from_10y",
name: "From 10 Years",
legend: "10Y+",
},
{
id: "from-15y",
key: "from_15y",
name: "From 15 Years",
legend: "15Y+",
@@ -116,27 +134,28 @@ export const fromXCohorts = [
] as const;
export const yearCohorts = [
{ key: "year_2009", name: "2009" },
{ key: "year_2010", name: "2010" },
{ key: "year_2011", name: "2011" },
{ key: "year_2012", name: "2012" },
{ key: "year_2013", name: "2013" },
{ key: "year_2014", name: "2014" },
{ key: "year_2015", name: "2015" },
{ key: "year_2016", name: "2016" },
{ key: "year_2017", name: "2017" },
{ key: "year_2018", name: "2018" },
{ key: "year_2019", name: "2019" },
{ key: "year_2020", name: "2020" },
{ key: "year_2021", name: "2021" },
{ key: "year_2022", name: "2022" },
{ key: "year_2023", name: "2023" },
{ key: "year_2024", name: "2024" },
{ id: "year-2009", key: "year_2009", name: "2009" },
{ id: "year-2010", key: "year_2010", name: "2010" },
{ id: "year-2011", key: "year_2011", name: "2011" },
{ id: "year-2012", key: "year_2012", name: "2012" },
{ id: "year-2013", key: "year_2013", name: "2013" },
{ id: "year-2014", key: "year_2014", name: "2014" },
{ id: "year-2015", key: "year_2015", name: "2015" },
{ id: "year-2016", key: "year_2016", name: "2016" },
{ id: "year-2017", key: "year_2017", name: "2017" },
{ id: "year-2018", key: "year_2018", name: "2018" },
{ id: "year-2019", key: "year_2019", name: "2019" },
{ id: "year-2020", key: "year_2020", name: "2020" },
{ id: "year-2021", key: "year_2021", name: "2021" },
{ id: "year-2022", key: "year_2022", name: "2022" },
{ id: "year-2023", key: "year_2023", name: "2023" },
{ id: "year-2024", key: "year_2024", name: "2024" },
] as const;
export const ageCohorts = [
{
key: "",
id: "",
name: "",
},
...xthCohorts,

View File

@@ -1,11 +1,13 @@
export const liquidities = [
{
key: "illiquid",
id: "illiquid",
name: "Illiquid",
},
{ key: "liquid", name: "Liquid" },
{ key: "liquid", id: "liquid", name: "Liquid" },
{
key: "highly_liquid",
id: "highly-liquid",
name: "Highly Liquid",
},
] as const;

View File

@@ -1,114 +1,133 @@
export const percentiles = [
{
key: "median_price_paid",
id: "median-price-paid",
name: "Median",
title: "Median Paid",
value: 50,
},
{
key: "95p_price_paid",
id: "95p-price-paid",
name: `95%`,
title: `95th Percentile Paid`,
value: 95,
},
{
key: "90p_price_paid",
id: "90p-price-paid",
name: `90%`,
title: `90th Percentile Paid`,
value: 90,
},
{
key: "85p_price_paid",
id: "85p-price-paid",
name: `85%`,
title: `85th Percentile Paid`,
value: 85,
},
{
key: "80p_price_paid",
id: "80p-price-paid",
name: `80%`,
title: `80th Percentile Paid`,
value: 80,
},
{
key: "75p_price_paid",
id: "75p-price-paid",
name: `75%`,
title: `75th Percentile Paid`,
value: 75,
},
{
key: "70p_price_paid",
id: "70p-price-paid",
name: `70%`,
title: `70th Percentile Paid`,
value: 70,
},
{
key: "65p_price_paid",
id: "65p-price-paid",
name: `65%`,
title: `65th Percentile Paid`,
value: 65,
},
{
key: "60p_price_paid",
id: "60p-price-paid",
name: `60%`,
title: `60th Percentile Paid`,
value: 60,
},
{
key: "55p_price_paid",
id: "55p-price-paid",
name: `55%`,
title: `55th Percentile Paid`,
value: 55,
},
{
key: "45p_price_paid",
id: "45p-price-paid",
name: `45%`,
title: `45th Percentile Paid`,
value: 45,
},
{
key: "40p_price_paid",
id: "40p-price-paid",
name: `40%`,
title: `40th Percentile Paid`,
value: 40,
},
{
key: "35p_price_paid",
id: "35p-price-paid",
name: `35%`,
title: `35th Percentile Paid`,
value: 35,
},
{
key: "30p_price_paid",
id: "30p-price-paid",
name: `30%`,
title: `30th Percentile Paid`,
value: 30,
},
{
key: "25p_price_paid",
id: "25p-price-paid",
name: `25%`,
title: `25th Percentile Paid`,
value: 25,
},
{
key: "20p_price_paid",
id: "20p-price-paid",
name: `20%`,
title: `20th Percentile Paid`,
value: 20,
},
{
key: "15p_price_paid",
id: "15p-price-paid",
name: `15%`,
title: `15th Percentile Paid`,
value: 15,
},
{
key: "10p_price_paid",
id: "10p-price-paid",
name: `10%`,
title: `10th Percentile Paid`,
value: 10,
},
{
key: "05p_price_paid",
id: "05p-price-paid",
name: `5%`,
title: `5th Percentile Paid`,
value: 5,

View File

@@ -1,18 +1,24 @@
type AgeCohortKey = (typeof import("./age").ageCohorts)[number]["key"];
type AgeCohortId = (typeof import("./age").ageCohorts)[number]["id"];
type AddressCohortKey =
type AgeCohortIdSub = Exclude<AgeCohortId, "">;
type AddressCohortId =
(typeof import("./address").addressCohorts)[number]["key"];
type LiquidityKey = (typeof import("./liquidities").liquidities)[number]["key"];
type LiquidityId = (typeof import("./liquidities").liquidities)[number]["id"];
type AddressCohortKeySplitByLiquidity = `${LiquidityKey}_${AddressCohortKey}`;
type AddressCohortIdSplitByLiquidity = `${LiquidityId}-${AddressCohortId}`;
type AnyCohortKey = AgeCohortKey | AddressCohortKey;
type AnyCohortId = AgeCohortId | AddressCohortId;
type AnyPossibleCohortKey =
| AnyCohortKey
| AddressCohortKeySplitByLiquidity
| LiquidityKey;
type AnyPossibleCohortId =
| AnyCohortId
| AddressCohortIdSplitByLiquidity
| LiquidityId;
type AnyDatasetPrefix =
| ""
| `${AgeCohortIdSub | AddressCohortId | AddressCohortIdSplitByLiquidity | LiquidityId}-`;
type AverageName = (typeof import("./averages").averages)[number]["key"];
@@ -20,3 +26,5 @@ type TotalReturnKey = (typeof import("./returns").totalReturns)[number]["key"];
type CompoundReturnKey =
(typeof import("./returns").compoundReturns)[number]["key"];
type PercentileId = (typeof import("./percentiles").percentiles)[number]["id"];

View File

@@ -1,23 +1,49 @@
import groupedKeysToURLPath from "/src/../../datasets/grouped_keys_to_url_path.json";
import { createDateDatasets } from "./date";
import { createHeightDatasets } from "./height";
import { createResourceDataset } from "./resource";
export const scales = ["date" as const, "height" as const];
export const HEIGHT_CHUNK_SIZE = 10_000;
export function createDatasets() {
const date = createDateDatasets({
groupedKeysToURLPath: groupedKeysToURLPath.date,
});
const date = new Map<DateDatasetPath, ResourceDataset<"date">>();
const height = new Map<HeightDatasetPath, ResourceDataset<"height">>();
const height = createHeightDatasets({
groupedKeysToURLPath: groupedKeysToURLPath.height,
});
function getOrImport<Scale extends ResourceScale>(
scale: Scale,
path: DatasetPath<Scale>,
): ResourceDataset<Scale> {
if (scale === "date") {
const found = date.get(path as any);
if (found) return found as ResourceDataset<Scale>;
} else {
const found = height.get(path as any);
if (found) return found as ResourceDataset<Scale>;
}
let dataset: ResourceDataset<Scale, any>;
if (path === `/${scale}-to-ohlc`) {
dataset = createResourceDataset<Scale, OHLC>({
scale,
path,
});
} else {
dataset = createResourceDataset<Scale>({
scale,
path,
});
}
if (scale === "date") {
date.set(path as any, dataset as any);
} else {
height.set(path as any, dataset as any);
}
return dataset;
}
return {
date,
height,
} satisfies Record<ResourceScale, any>;
getOrImport,
};
}

View File

@@ -30,224 +30,239 @@ export function createResourceDataset<
"https://api-bkp.satonomics.xyz"
}${path}`;
const fetchedJSONs = new Array(
(new Date().getFullYear() - new Date("2009-01-01").getFullYear() + 2) *
(scale === "date" ? 1 : 6),
)
.fill(null)
.map((): FetchedResult<Scale, Type> => {
const json = createRWS<FetchedJSON<Scale, Type, Dataset> | null>(null);
return createRoot((dispose) => {
const fetchedJSONs = new Array(
(new Date().getFullYear() - new Date("2009-01-01").getFullYear() + 2) *
(scale === "date" ? 1 : 6),
)
.fill(null)
.map((): FetchedResult<Scale, Type> => {
const json = createRWS<FetchedJSON<Scale, Type, Dataset> | null>(null);
return {
at: null,
json,
loading: false,
vec: createMemo(() => {
const map = json()?.dataset.map || null;
return {
at: null,
json,
loading: false,
vec: createMemo(() => {
const map = json()?.dataset.map || null;
if (!map) {
return null;
}
const chunkId = json()?.chunk.id!;
if (Array.isArray(map)) {
const values = new Array(map.length);
for (let i = 0; i < map.length; i++) {
const value = map[i];
values[i] = {
time: (chunkId + i) as Time,
...(typeof value !== "number" && value !== null
? { ...(value as OHLC), value: value.close }
: { value: value === null ? NaN : (value as number) }),
} as any as Value;
if (!map) {
return null;
}
return values;
} else {
return Object.entries(map).map(
([date, value]) =>
({
time: date,
const chunkId = json()?.chunk.id!;
if (Array.isArray(map)) {
const values = new Array(map.length);
for (let i = 0; i < map.length; i++) {
const value = map[i];
values[i] = {
time: (chunkId + i) as Time,
...(typeof value !== "number" && value !== null
? { ...(value as OHLC), value: value.close }
: { value: value === null ? NaN : (value as number) }),
}) as any as Value,
);
}
}),
};
}) as FetchedResult<Scale, Type>[];
} as any as Value;
}
const _fetch = async (id: number) => {
const index = chunkIdToIndex(scale, id);
return values;
} else {
return Object.entries(map).map(
([date, value]) =>
({
time: date,
...(typeof value !== "number" && value !== null
? { ...(value as OHLC), value: value.close }
: { value: value === null ? NaN : (value as number) }),
}) as any as Value,
);
}
}),
};
}) as FetchedResult<Scale, Type>[];
if (
index < 0 ||
(scale === "date" && id > new Date().getUTCFullYear()) ||
(scale === "height" &&
id > 165 * 365 * (new Date().getUTCFullYear() - 2009))
) {
return;
}
const fetched = fetchedJSONs.at(index);
if (scale === "height" && index > 0) {
const length = fetchedJSONs.at(index - 1)?.vec()?.length;
if (length !== undefined && length < HEIGHT_CHUNK_SIZE) {
return;
}
}
if (!fetched || fetched.loading) {
return;
} else if (fetched.at) {
const diff = new Date().getTime() - fetched.at.getTime();
const _fetch = async (id: number) => {
const index = chunkIdToIndex(scale, id);
if (
diff < ONE_MINUTE_IN_MS ||
(index < fetchedJSONs.findLastIndex((json) => json.at) &&
diff < ONE_HOUR_IN_MS)
index < 0 ||
(scale === "date" && id > new Date().getUTCFullYear()) ||
(scale === "height" &&
id > 165 * 365 * (new Date().getUTCFullYear() - 2009))
) {
return;
}
}
fetched.loading = true;
const fetched = fetchedJSONs.at(index);
let cache: Cache | undefined;
if (scale === "height" && index > 0) {
const length = fetchedJSONs.at(index - 1)?.vec()?.length;
const urlWithQuery = `${baseURL}?chunk=${id}`;
const backupUrlWithQuery = `${backupURL}?chunk=${id}`;
if (!fetched.json()) {
try {
cache = await caches.open("resources");
const cachedResponse = await cache.match(urlWithQuery);
if (cachedResponse) {
const json = await convertResponseToJSON<Scale, Type>(cachedResponse);
if (json) {
console.log(`cache: ${path}?chunk=${id}`);
fetched.json.set(() => json);
}
}
} catch {}
}
if (!navigator.onLine) {
fetched.loading = false;
return;
}
let fetchedResponse: Response | undefined;
try {
fetchedResponse = await fetch(urlWithQuery);
if (!fetchedResponse.ok) {
throw Error;
}
} catch {
try {
fetchedResponse = await fetch(backupUrlWithQuery);
} catch {
fetched.loading = false;
return;
}
if (!fetchedResponse || !fetchedResponse.ok) {
fetched.loading = false;
return;
}
}
const clonedResponse = fetchedResponse.clone();
const json = await convertResponseToJSON<Scale, Type>(fetchedResponse);
if (!json) {
fetched.loading = false;
return;
}
console.log(`fetch: ${path}?chunk=${id}`);
const previousMap = fetched.json()?.dataset.map;
const newMap = json.dataset.map;
const previousLength = Object.keys(previousMap || []).length;
const newLength = Object.keys(newMap).length;
if (!newLength) {
fetched.loading = false;
return;
}
if (previousLength && previousLength === newLength) {
const previousLastValue = Object.values(previousMap || []).at(-1);
const newLastValue = Object.values(newMap).at(-1);
if (typeof newLastValue === "number") {
if (previousLastValue === newLastValue) {
fetched.at = new Date();
fetched.loading = false;
if (length !== undefined && length < HEIGHT_CHUNK_SIZE) {
return;
}
} else {
const previousLastOHLC = previousLastValue as OHLC;
const newLastOHLC = newLastValue as OHLC;
}
if (!fetched || fetched.loading) {
return;
} else if (fetched.at) {
const diff = new Date().getTime() - fetched.at.getTime();
if (
previousLastOHLC.open === newLastOHLC.open &&
previousLastOHLC.high === newLastOHLC.high &&
previousLastOHLC.low === newLastOHLC.low &&
previousLastOHLC.close === newLastOHLC.close
diff < ONE_MINUTE_IN_MS ||
(index < fetchedJSONs.findLastIndex((json) => json.at) &&
diff < ONE_HOUR_IN_MS)
) {
fetched.loading = false;
fetched.at = new Date();
return;
}
}
}
fetched.json.set(() => json);
fetched.loading = true;
function saveToCache() {
cache?.put(urlWithQuery, clonedResponse);
}
let cache: Cache | undefined;
if (requestIdleCallbackPossible) {
requestIdleCallback(saveToCache);
} else {
setTimeout(saveToCache, 1);
}
const urlWithQuery = `${baseURL}?chunk=${id}`;
const backupUrlWithQuery = `${backupURL}?chunk=${id}`;
fetched.at = new Date();
fetched.loading = false;
};
if (!fetched.json()) {
try {
cache = await caches.open("resources");
const resource: ResourceDataset<Scale, Type> = {
scale,
url: baseURL,
fetch: _fetch,
fetchedJSONs,
drop() {
fetchedJSONs.forEach((fetched) => {
fetched.at = null;
fetched.json.set(null);
});
},
};
const cachedResponse = await cache.match(urlWithQuery);
return resource;
if (cachedResponse) {
const json = await convertResponseToJSON<Scale, Type>(
cachedResponse,
);
if (json) {
console.log(`cache: ${path}?chunk=${id}`);
fetched.json.set(() => json);
}
}
} catch {}
}
if (!navigator.onLine) {
fetched.loading = false;
return;
}
let fetchedResponse: Response | undefined;
const fetchConfig: RequestInit = {
signal: AbortSignal.timeout(5000),
};
try {
fetchedResponse = await fetch(urlWithQuery, fetchConfig);
if (!fetchedResponse.ok) {
throw Error;
}
} catch {
try {
fetchedResponse = await fetch(backupUrlWithQuery, fetchConfig);
} catch {
fetched.loading = false;
return;
}
if (!fetchedResponse || !fetchedResponse.ok) {
fetched.loading = false;
return;
}
}
const clonedResponse = fetchedResponse.clone();
const json = await convertResponseToJSON<Scale, Type>(fetchedResponse);
if (!json) {
fetched.loading = false;
return;
}
console.log(`fetch: ${path}?chunk=${id}`);
const previousMap = fetched.json()?.dataset.map;
const newMap = json.dataset.map;
const previousLength = Object.keys(previousMap || []).length;
const newLength = Object.keys(newMap).length;
if (!newLength) {
fetched.loading = false;
return;
}
if (previousLength && previousLength === newLength) {
const previousLastValue = Object.values(previousMap || []).at(-1);
const newLastValue = Object.values(newMap).at(-1);
if (newLastValue === null && previousLastValue === null) {
fetched.at = new Date();
fetched.loading = false;
return;
} else if (typeof newLastValue === "number") {
if (previousLastValue === newLastValue) {
fetched.at = new Date();
fetched.loading = false;
return;
}
} else {
const previousLastOHLC = previousLastValue as OHLC;
const newLastOHLC = newLastValue as OHLC;
if (
previousLastOHLC.open === newLastOHLC.open &&
previousLastOHLC.high === newLastOHLC.high &&
previousLastOHLC.low === newLastOHLC.low &&
previousLastOHLC.close === newLastOHLC.close
) {
fetched.loading = false;
fetched.at = new Date();
return;
}
}
}
fetched.json.set(() => json);
async function saveToCache() {
try {
await cache?.put(urlWithQuery, clonedResponse);
} catch (_) {}
}
if (requestIdleCallbackPossible) {
requestIdleCallback(saveToCache);
} else {
setTimeout(saveToCache, 1);
}
fetched.at = new Date();
fetched.loading = false;
};
const resource: ResourceDataset<Scale, Type> = {
scale,
url: baseURL,
fetch: _fetch,
fetchedJSONs,
drop() {
dispose();
fetchedJSONs.forEach((fetched) => {
fetched.at = null;
fetched.json.set(null);
});
},
};
return resource;
});
}
async function convertResponseToJSON<

View File

@@ -1,9 +1,5 @@
type Datasets = ReturnType<typeof import("./index").createDatasets>;
type DateDatasets = Datasets["date"];
type HeightDatasets = Datasets["height"];
type AnyDatasets = DateDatasets | HeightDatasets;
type ResourceScale = (typeof import("./index").scales)[index];
type DatasetValue<T> = T & Valued;
@@ -92,3 +88,15 @@ interface OHLC {
type GroupedKeysToURLPath =
typeof import("/src/../../datasets/grouped_keys_to_url_path.json");
type DateDatasetPath = import("/src/../../datasets/paths").DatePath;
type HeightDatasetPath = import("/src/../../datasets/paths").HeightPath;
type LastDataPath = import("/src/../../datasets/paths").LastPath;
type DatasetPath<Scale extends ResourceScale> = Scale extends "date"
? DateDatasetPath
: HeightDatasetPath;
type AnyDatasetPath = DateDatasetPath | HeightDatasetPath;

View File

@@ -16,7 +16,7 @@ export function createChart(
priceScaleOptions,
}: {
dark: Accessor<boolean>;
priceScaleOptions: DeepPartialPriceScaleOptions;
priceScaleOptions?: DeepPartialPriceScaleOptions;
},
) {
console.log(`chart: create (scale: ${scale})`);

View File

@@ -2,7 +2,7 @@
// https://github.com/tradingview/lightweight-charts/blob/master/tests/e2e/graphics/test-cases/horizontal-price-scale.js
import { type IHorzScaleBehavior } from "lightweight-charts";
import type { IHorzScaleBehavior } from "lightweight-charts";
export class HorzScaleBehaviorHeight implements IHorzScaleBehavior<number> {
options() {}

View File

@@ -19,6 +19,7 @@ export function createSeriesLegend<Scale extends ResourceScale>({
visible: _visible,
dataset,
}: {
scale: Scale;
id: string;
presetId: string;
title: string;

View File

@@ -1,6 +1,7 @@
import { colors } from "/src/scripts/utils/colors";
import { chunkIdToIndex } from "../datasets/resource";
import { dateFromTime } from "../utils/date";
import { valueToString } from "../utils/locale";
export function setMinMaxMarkers({
@@ -55,11 +56,7 @@ export function setMinMaxMarkers({
let number;
if (scale === "date") {
const date =
typeof data.time === "string"
? new Date(data.time)
: // @ts-ignore
new Date(data.time.year, data.time.month, data.time.day);
const date = dateFromTime(data.time);
number = date.getTime();

View File

@@ -64,35 +64,22 @@ export function initTimeScale({
scale,
activeIds,
exactRange,
charts,
chart,
}: {
scale: ResourceScale;
activeIds: RWS<number[]>;
exactRange: RWS<TimeRange>;
charts: ChartObject[];
chart: IChartApi;
}) {
const firstChart = charts.at(0)?.chart;
if (!firstChart) return;
firstChart.timeScale().subscribeVisibleTimeRangeChange((range) => {
chart.timeScale().subscribeVisibleTimeRangeChange((range) => {
if (!range) return;
exactRange.set(range);
debouncedsetActiveIds({ exactRange: range, activeIds: activeIds });
debouncedSetActiveIds({ exactRange: range, activeIds: activeIds });
debouncedSaveTimeRange({ scale, range });
});
const range = exactRange();
run(async () => {
if (range) {
await tick();
firstChart.timeScale().setVisibleRange(range);
}
});
}
function getLocalStorageKey(scale: ResourceScale) {
@@ -142,7 +129,7 @@ export function setActiveIds({
}
}
const debouncedsetActiveIds = debounce(setActiveIds, 100);
const debouncedSetActiveIds = debounce(setActiveIds, 100);
function saveTimeRange({
scale,

View File

@@ -4,14 +4,9 @@ import {
} from "../../datasets/consts/address";
import { liquidities } from "../../datasets/consts/liquidities";
import { colors } from "../../utils/colors";
import { applySeriesList, SeriesType } from "../apply";
import { createCohortPresetList } from "../templates/cohort";
export function createPresets({
scale,
}: {
scale: ResourceScale;
}): PartialPresetFolder {
export function createPresets(scale: ResourceScale): PartialPresetFolder {
return {
name: "Addresses",
tree: [
@@ -21,18 +16,13 @@ export function createPresets({
title: `Total Non Empty Address`,
description: "",
icon: IconTablerWallet,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: `Total Non Empty Address`,
color: colors.bitcoin,
dataset: params.datasets[scale].address_count,
},
],
});
},
bottom: [
{
title: `Total Non Empty Address`,
color: colors.bitcoin,
datasetPath: `/${scale}-to-address-count`,
},
],
},
{
scale,
@@ -40,18 +30,13 @@ export function createPresets({
title: `New Addresses`,
description: "",
icon: IconTablerSparkles,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: `New Addresses`,
color: colors.white,
dataset: params.datasets[scale].created_addresses,
},
],
});
},
bottom: [
{
title: `New Addresses`,
color: colors.white,
datasetPath: `/${scale}-to-created-addresses`,
},
],
},
{
scale,
@@ -59,18 +44,13 @@ export function createPresets({
title: `Total Addresses Created`,
description: "",
icon: IconTablerArchive,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: `Total Addresses Created`,
color: colors.bitcoin,
dataset: params.datasets[scale].created_addresses,
},
],
});
},
bottom: [
{
title: `Total Addresses Created`,
color: colors.bitcoin,
datasetPath: `/${scale}-to-created-addresses`,
},
],
},
{
scale,
@@ -78,18 +58,13 @@ export function createPresets({
title: `Total Empty Addresses`,
description: "",
icon: IconTablerTrash,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: `Total Empty Addresses`,
color: colors.darkWhite,
dataset: params.datasets[scale].empty_addresses,
},
],
});
},
bottom: [
{
title: `Total Empty Addresses`,
color: colors.darkWhite,
datasetPath: `/${scale}-to-empty-addresses`,
},
],
},
{
name: "By Size",
@@ -98,7 +73,7 @@ export function createPresets({
scale,
color: colors[key],
name,
datasetKey: key,
datasetId: key,
}),
),
},
@@ -110,7 +85,7 @@ export function createPresets({
scale,
color: colors[key],
name,
datasetKey: key,
datasetId: key,
}),
),
},
@@ -118,47 +93,47 @@ export function createPresets({
} satisfies PartialPresetFolder;
}
function createAddressPresetFolder<Scale extends ResourceScale>({
function createAddressPresetFolder({
scale,
color,
name,
datasetKey,
datasetId,
}: {
scale: Scale;
scale: ResourceScale;
name: string;
datasetKey: AddressCohortKey;
datasetId: AddressCohortId;
color: Color;
}): PartialPresetFolder {
return {
name,
tree: [
createAddressCountPreset({ scale, name, datasetKey, color }),
createAddressCountPreset({ scale, name, datasetId, color }),
...createCohortPresetList({
title: name,
scale,
name,
color,
datasetKey,
datasetId,
}),
createLiquidityFolder({
scale,
name,
datasetKey,
datasetId,
color,
}),
],
};
}
export function createLiquidityFolder<Scale extends ResourceScale>({
export function createLiquidityFolder({
scale,
color,
name,
datasetKey,
datasetId,
}: {
scale: Scale;
scale: ResourceScale;
name: string;
datasetKey: AddressCohortKey | "";
datasetId: AddressCohortId | "";
color: Color;
}): PartialPresetFolder {
return {
@@ -171,43 +146,36 @@ export function createLiquidityFolder<Scale extends ResourceScale>({
name: `${liquidity.name} ${name}`,
scale,
color,
datasetKey: !datasetKey
? liquidity.key
: `${liquidity.key}_${datasetKey}`,
datasetId: !datasetId ? liquidity.id : `${liquidity.id}-${datasetId}`,
}),
}),
),
};
}
export function createAddressCountPreset<Scale extends ResourceScale>({
export function createAddressCountPreset({
scale,
color,
name,
datasetKey,
datasetId,
}: {
scale: Scale;
scale: ResourceScale;
name: string;
datasetKey: AddressCohortKey;
datasetId: AddressCohortId;
color: Color;
}): PartialPreset {
const addressCount: SeriesConfig = {
title: "Address Count",
color,
datasetPath: `/${scale}-to-${datasetId}-address-count`,
};
return {
scale,
name: `Address Count`,
title: `${name} Address Count`,
icon: IconTablerAddressBook,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Address Count",
color,
dataset: params.datasets[scale][`${datasetKey}_address_count`],
},
],
});
},
description: "",
bottom: [addressCount],
};
}

View File

@@ -19,62 +19,13 @@ import {
} from "../lightweightCharts/time";
import { setWhitespace } from "../lightweightCharts/whitespace";
import { colors } from "../utils/colors";
import { dateFromTime, getNumberOfDaysBetweenTwoDates } from "../utils/date";
import { debounce } from "../utils/debounce";
import { stringToId } from "../utils/id";
import { webSockets } from "../ws";
import { SeriesType } from "./enums";
export enum SeriesType {
Line,
Based,
Histogram,
Candlestick,
}
type SeriesConfig<Scale extends ResourceScale> =
| {
dataset: ResourceDataset<Scale>;
color?: Color;
topColor?: Color;
bottomColor?: Color;
colors?: undefined;
seriesType: SeriesType.Based;
title: string;
options?: BaselineSeriesOptions;
priceScaleOptions?: DeepPartialPriceScaleOptions;
defaultVisible?: boolean;
}
| {
dataset: ResourceDataset<Scale>;
color?: Color;
colors?: Color[];
seriesType: SeriesType.Histogram;
title: string;
options?: DeepPartialHistogramOptions;
priceScaleOptions?: DeepPartialPriceScaleOptions;
defaultVisible?: boolean;
}
| {
dataset: ResourceDataset<Scale>;
seriesType: SeriesType.Candlestick;
priceScaleOptions?: DeepPartialPriceScaleOptions;
colors?: undefined;
color?: undefined;
options?: DeepPartialLineOptions;
defaultVisible?: boolean;
title: string;
}
| {
dataset: ResourceDataset<Scale>;
color: Color;
colors?: undefined;
seriesType?: SeriesType.Line;
title: string;
options?: DeepPartialLineOptions;
priceScaleOptions?: DeepPartialPriceScaleOptions;
defaultVisible?: boolean;
};
export function applySeriesList<Scale extends ResourceScale>({
export function applySeriesList({
parentDiv,
charts: reactiveChartList,
top,
@@ -92,15 +43,15 @@ export function applySeriesList<Scale extends ResourceScale>({
parentDiv: HTMLDivElement;
preset: Preset;
legendSetter: Setter<SeriesLegend[]>;
priceDataset?: ResourceDataset<Scale>;
priceDataset?: AnyDatasetPath;
priceOptions?: PriceSeriesOptions;
priceScaleOptions?: DeepPartialPriceScaleOptions;
top?: SeriesConfig<Scale>[];
bottom?: SeriesConfig<Scale>[];
// priceScaleOptions?: DeepPartialPriceScaleOptions;
// top?: SeriesConfig<Scale>[];
// bottom?: SeriesConfig<Scale>[];
datasets: Datasets;
dark: Accessor<boolean>;
activeIds: RWS<number[]>;
}) {
} & PresetParams) {
// ---
// Reset states
// ---
@@ -145,22 +96,20 @@ export function applySeriesList<Scale extends ResourceScale>({
const charts = [top || [], bottom]
.flatMap((list) => (list ? [list] : []))
.flatMap((seriesConfigList, index) => {
if (index !== 0 && seriesConfigList.length === 0) {
.flatMap((seriesConfigList, chartIndex) => {
if (chartIndex !== 0 && seriesConfigList.length === 0) {
return [];
}
const div = document.createElement("div");
div.className = "w-full cursor-crosshair min-h-0 border-lighter";
div.className = "w-full cursor-crosshair min-h-0 border-lighter h-full";
parentDiv.appendChild(div);
const chart = createChart(scale, div, {
dark,
priceScaleOptions: {
...priceScaleOptions,
},
priceScaleOptions,
});
if (!chart) {
@@ -170,8 +119,28 @@ export function applySeriesList<Scale extends ResourceScale>({
const whitespace = setWhitespace(chart, scale);
if (exactRange()) {
chart.timeScale().setVisibleRange(exactRange());
const range = exactRange();
if (range) {
chart.timeScale().setVisibleRange(range);
}
if (chartIndex === 0) {
initTimeScale({
scale,
chart,
activeIds: activeIds,
exactRange,
});
if (range) {
updateVisiblePriceSeriesType({
scale,
chart,
priceSeriesType,
timeRange: range,
});
}
}
// const whitespace = new Array<ISeriesApi<"Line"> | undefined>(
@@ -223,6 +192,10 @@ export function applySeriesList<Scale extends ResourceScale>({
const chartLegend: SeriesLegend[] = [];
onCleanup(() => {
chartLegend.length = 0;
});
const markerCallback = () =>
setMinMaxMarkers({
scale,
@@ -241,12 +214,11 @@ export function applySeriesList<Scale extends ResourceScale>({
createEffect(on([exactRange, dark], debouncedSetMinMaxMarkers));
if (index === 0) {
const dataset =
priceDataset ||
(datasets[preset.scale as Scale].price as unknown as NonNullable<
typeof priceDataset
>);
if (chartIndex === 0) {
const datasetPath =
priceDataset || (`/${scale}-to-ohlc` satisfies AnyDatasetPath);
const dataset = datasets.getOrImport(scale, datasetPath);
activeDatasets.push(dataset);
@@ -258,11 +230,12 @@ export function applySeriesList<Scale extends ResourceScale>({
};
function createPriceSeries(seriesType: PriceSeriesType) {
let seriesConfig: SeriesConfig<Scale>;
let seriesConfig: SeriesConfig;
if (seriesType === "Candlestick") {
seriesConfig = {
dataset,
// @ts-ignore
datasetPath,
title,
seriesType: SeriesType.Candlestick,
options: priceOptions,
@@ -270,7 +243,8 @@ export function applySeriesList<Scale extends ResourceScale>({
};
} else {
seriesConfig = {
dataset,
// @ts-ignore
datasetPath,
title,
color: colors.white,
options: priceOptions?.seriesOptions,
@@ -279,6 +253,8 @@ export function applySeriesList<Scale extends ResourceScale>({
}
const priceSeries = createSeriesGroup({
scale,
datasets,
index: -1,
activeIds,
seriesConfig,
@@ -319,9 +295,13 @@ export function applySeriesList<Scale extends ResourceScale>({
}
seriesConfigList.reverse().forEach((seriesConfig, index) => {
activeDatasets.push(seriesConfig.dataset);
const dataset = datasets.getOrImport(scale, seriesConfig.datasetPath);
activeDatasets.push(dataset);
createSeriesGroup({
scale,
datasets,
activeIds: activeIds,
index,
seriesConfig,
@@ -358,10 +338,11 @@ export function applySeriesList<Scale extends ResourceScale>({
charts.forEach((chart) => {
if (chart.legendList.some((legend) => legend.drawn())) {
chart.div.style.border = "";
chart.div.style.maxHeight = "100%";
visibleCharts.push(chart);
} else {
chart.div.style.height = "100%";
// chart.div.style.height = "0px";
// chart.div.style.height = "100%";
chart.div.style.maxHeight = "0px";
chart.div.style.border = "none";
}
});
@@ -384,13 +365,6 @@ export function applySeriesList<Scale extends ResourceScale>({
50,
);
initTimeScale({
scale,
charts,
activeIds: activeIds,
exactRange,
});
const activeDatasetsLength = activeDatasets.length;
createEffect(() => {
const range = activeIds();
@@ -410,21 +384,22 @@ export function applySeriesList<Scale extends ResourceScale>({
for (let i = 0; i < charts.length; i++) {
const chart = charts[i].chart;
chart.timeScale().subscribeVisibleLogicalRangeChange((timeRange) => {
if (!timeRange) return;
chart.timeScale().subscribeVisibleLogicalRangeChange((logicalRange) => {
if (!logicalRange) return;
// Must be the chart with the visible timeScale
if (i === lastChartIndex) {
debouncedUpdateVisiblePriceSeriesType(
debouncedUpdateVisiblePriceSeriesType({
scale,
chart,
timeRange,
logicalRange,
priceSeriesType,
);
});
}
for (let j = 0; j <= lastChartIndex; j++) {
if (i !== j) {
charts[j].chart.timeScale().setVisibleLogicalRange(timeRange);
charts[j].chart.timeScale().setVisibleLogicalRange(logicalRange);
}
}
});
@@ -454,15 +429,38 @@ export function applySeriesList<Scale extends ResourceScale>({
reactiveChartList.set(() => charts.map(({ chart }) => chart));
}
function updateVisiblePriceSeriesType(
chart: IChartApi,
range: LogicalRange,
priceSeriesType: RWS<PriceSeriesType>,
) {
export function updateVisiblePriceSeriesType({
scale,
chart,
logicalRange,
timeRange,
priceSeriesType,
}: {
scale: ResourceScale;
chart: IChartApi;
logicalRange?: LogicalRange;
timeRange?: TimeRange;
priceSeriesType: RWS<PriceSeriesType>;
}) {
try {
const width = chart.timeScale().width();
const ratio = (range.to - range.from) / width;
let ratio: number;
if (logicalRange) {
ratio = (logicalRange.to - logicalRange.from) / width;
} else if (timeRange) {
if (scale === "date") {
ratio = getNumberOfDaysBetweenTwoDates(
dateFromTime(timeRange.from),
dateFromTime(timeRange.to),
);
} else {
ratio = ((timeRange.to as number) - (timeRange.from as number)) / width;
}
} else {
throw Error();
}
if (ratio <= 0.5) {
priceSeriesType.set("Candlestick");
@@ -473,6 +471,8 @@ function updateVisiblePriceSeriesType(
}
function createSeriesGroup<Scale extends ResourceScale>({
scale,
datasets,
activeIds,
seriesConfig,
preset,
@@ -484,8 +484,10 @@ function createSeriesGroup<Scale extends ResourceScale>({
debouncedSetMinMaxMarkers,
dark,
}: {
scale: Scale;
datasets: Datasets;
activeIds: Accessor<number[]>;
seriesConfig: SeriesConfig<Scale>;
seriesConfig: SeriesConfig;
preset: Preset;
chart: IChartApi;
index: number;
@@ -496,7 +498,7 @@ function createSeriesGroup<Scale extends ResourceScale>({
dark: Accessor<boolean>;
}) {
const {
dataset,
datasetPath,
title,
colors,
color,
@@ -506,13 +508,17 @@ function createSeriesGroup<Scale extends ResourceScale>({
priceScaleOptions,
} = seriesConfig;
const scale = preset.scale;
const dataset = datasets.getOrImport(
scale,
datasetPath as DatasetPath<Scale>,
);
const seriesList: RWS<
ISeriesApi<"Baseline" | "Line" | "Histogram" | "Candlestick"> | undefined
>[] = new Array(dataset.fetchedJSONs.length);
const legend = createSeriesLegend({
scale,
id: stringToId(title),
presetId: preset.id,
title,
@@ -532,12 +538,15 @@ function createSeriesGroup<Scale extends ResourceScale>({
createEffect(() => {
const values = json.vec();
if (!values) return;
if (seriesIndex > 0) {
let previous = chartLegend.at(seriesIndex - 1)?.seriesList[index];
if (!previous?.()) return;
if (!previous?.()) {
return;
}
}
untrack(() => {

View File

@@ -1,5 +1,4 @@
import { colors } from "../../utils/colors";
import { applySeriesList, SeriesType } from "../apply";
export function createPresets() {
const scale: ResourceScale = "date";
@@ -13,18 +12,13 @@ export function createPresets() {
name: "Height",
title: "Block Height",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Height",
color: colors.bitcoin,
dataset: params.datasets.date.last_height,
},
],
});
},
bottom: [
{
title: "Height",
color: colors.bitcoin,
datasetPath: `/date-to-last-height`,
},
],
},
{
scale,
@@ -36,37 +30,32 @@ export function createPresets() {
name: "Daily Sum",
title: "Daily Sum Of Blocks Mined",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Target",
color: colors.white,
dataset: params.datasets.date.blocks_mined_1d_target,
options: {
lineStyle: 3,
},
},
{
title: "1W Avg.",
color: colors.momentumYellow,
dataset: params.datasets.date.blocks_mined_1w_sma,
defaultVisible: false,
},
{
title: "1M Avg.",
color: colors.bitcoin,
dataset: params.datasets.date.blocks_mined_1m_sma,
},
{
title: "Mined",
color: colors.darkBitcoin,
dataset: params.datasets.date.blocks_mined,
},
],
});
},
bottom: [
{
title: "Target",
color: colors.white,
datasetPath: `/date-to-blocks-mined-1d-target`,
options: {
lineStyle: 3,
},
},
{
title: "1W Avg.",
color: colors.momentumYellow,
datasetPath: `/date-to-blocks-mined-1w-sma`,
defaultVisible: false,
},
{
title: "1M Avg.",
color: colors.bitcoin,
datasetPath: `/date-to-blocks-mined-1m-sma`,
},
{
title: "Mined",
color: colors.darkBitcoin,
datasetPath: `/date-to-blocks-mined`,
},
],
},
{
scale,
@@ -74,26 +63,21 @@ export function createPresets() {
name: "Weekly Sum",
title: "Weekly Sum Of Blocks Mined",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Target",
color: colors.white,
dataset: params.datasets.date.blocks_mined_1w_target,
options: {
lineStyle: 3,
},
},
{
title: "Sum Mined",
color: colors.bitcoin,
dataset: params.datasets.date.blocks_mined_1w_sum,
},
],
});
},
bottom: [
{
title: "Target",
color: colors.white,
datasetPath: `/date-to-blocks-mined-1w-target`,
options: {
lineStyle: 3,
},
},
{
title: "Sum Mined",
color: colors.bitcoin,
datasetPath: `/date-to-blocks-mined-1w-sum`,
},
],
},
{
scale,
@@ -101,26 +85,21 @@ export function createPresets() {
name: "Monthly Sum",
title: "Monthly Sum Of Blocks Mined",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Target",
color: colors.white,
dataset: params.datasets.date.blocks_mined_1m_target,
options: {
lineStyle: 3,
},
},
{
title: "Sum Mined",
color: colors.bitcoin,
dataset: params.datasets.date.blocks_mined_1m_sum,
},
],
});
},
bottom: [
{
title: "Target",
color: colors.white,
datasetPath: `/date-to-blocks-mined-1m-target`,
options: {
lineStyle: 3,
},
},
{
title: "Sum Mined",
color: colors.bitcoin,
datasetPath: `/date-to-blocks-mined-1m-sum`,
},
],
},
{
scale,
@@ -128,26 +107,21 @@ export function createPresets() {
name: "Yearly Sum",
title: "Yearly Sum Of Blocks Mined",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Target",
color: colors.white,
dataset: params.datasets.date.blocks_mined_1y_target,
options: {
lineStyle: 3,
},
},
{
title: "Sum Mined",
color: colors.bitcoin,
dataset: params.datasets.date.blocks_mined_1y_sum,
},
],
});
},
bottom: [
{
title: "Target",
color: colors.white,
datasetPath: `/date-to-blocks-mined-1y-target`,
options: {
lineStyle: 3,
},
},
{
title: "Sum Mined",
color: colors.bitcoin,
datasetPath: `/date-to-blocks-mined-1y-sum`,
},
],
},
{
scale,
@@ -155,18 +129,13 @@ export function createPresets() {
name: "Total",
title: "Total Blocks Mined",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Mined",
color: colors.bitcoin,
dataset: params.datasets.date.total_blocks_mined,
},
],
});
},
bottom: [
{
title: "Mined",
color: colors.bitcoin,
datasetPath: `/date-to-total-blocks-mined`,
},
],
},
],
},
@@ -176,18 +145,13 @@ export function createPresets() {
name: "Cumulative Size",
title: "Cumulative Block Size",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Size (MB)",
color: colors.darkWhite,
dataset: params.datasets.date.cumulative_block_size,
},
],
});
},
bottom: [
{
title: "Size (MB)",
color: colors.darkWhite,
datasetPath: `/date-to-cumulative-block-size`,
},
],
},
],
} satisfies PartialPresetFolder;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
export const enum SeriesType {
Line,
Based,
Histogram,
Candlestick,
}

View File

@@ -6,10 +6,9 @@ import {
yearCohorts,
} from "../../datasets/consts/age";
import { colors } from "../../utils/colors";
import { applySeriesList } from "../apply";
import { createCohortPresetFolder } from "../templates/cohort";
export function createPresets({ scale }: { scale: ResourceScale }) {
export function createPresets(scale: ResourceScale) {
return {
name: "Hodlers",
tree: [
@@ -19,91 +18,80 @@ export function createPresets({ scale }: { scale: ResourceScale }) {
title: `Hodl Supply`,
description: "",
icon: IconTablerRipple,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: `24h`,
color: colors.up_to_1d,
dataset:
params.datasets.date
.up_to_1d_supply_to_circulating_supply_ratio,
},
bottom: [
{
title: `24h`,
color: colors.up_to_1d,
datasetPath: `/date-to-up-to-1d-supply-to-circulating-supply-ratio`,
},
...fromXToYCohorts.map(({ key, name, legend }) => ({
title: legend,
color: colors[key],
dataset:
params.datasets.date[
`${key}_supply_to_circulating_supply_ratio`
],
})),
...fromXToYCohorts.map(({ key, id, name, legend }) => ({
title: legend,
color: colors[key],
datasetPath:
`/date-to-${id}-supply-to-circulating-supply-ratio` as const,
})),
{
title: `15y+`,
color: colors.from_15y,
dataset:
params.datasets.date
.from_15y_supply_to_circulating_supply_ratio,
},
],
});
},
{
title: `15y+`,
color: colors.from_15y,
datasetPath: `/date-to-from-15y-supply-to-circulating-supply-ratio`,
},
],
},
...xthCohorts.map(({ key, name, legend }) =>
...xthCohorts.map(({ key, id, name, legend }) =>
createCohortPresetFolder({
scale,
color: colors[key],
name: legend,
datasetKey: key,
datasetId: id,
title: name,
}),
),
{
name: "Up To X",
tree: upToCohorts.map(({ key, name }) =>
tree: upToCohorts.map(({ key, id, name }) =>
createCohortPresetFolder({
scale,
color: colors[key],
name,
datasetKey: key,
datasetId: id,
title: name,
}),
),
},
{
name: "From X To Y",
tree: fromXToYCohorts.map(({ key, name }) =>
tree: fromXToYCohorts.map(({ key, id, name }) =>
createCohortPresetFolder({
scale,
color: colors[key],
name,
datasetKey: key,
datasetId: id,
title: name,
}),
),
},
{
name: "From X",
tree: fromXCohorts.map(({ key, name }) =>
tree: fromXCohorts.map(({ key, id, name }) =>
createCohortPresetFolder({
scale,
color: colors[key],
name,
datasetKey: key,
datasetId: id,
title: name,
}),
),
},
{
name: "Years",
tree: yearCohorts.map(({ key, name }) =>
tree: yearCohorts.map(({ key, id, name }) =>
createCohortPresetFolder({
scale,
color: colors[key],
name,
datasetKey: key,
datasetId: id,
title: name,
}),
),

View File

@@ -42,19 +42,19 @@ export function createPresets(): Presets {
...createCohortPresetList({
scale: "date",
color: colors.bitcoin,
datasetKey: "",
datasetId: "",
name: "",
title: "",
}),
createLiquidityFolder({
scale: "date",
color: colors.bitcoin,
datasetKey: "",
datasetId: "",
name: "",
}),
createHodlersPresets({ scale: "date" }),
createAddressesPresets({ scale: "date" }),
createCoinblocksPresets({ scale: "date" }),
createHodlersPresets("date"),
createAddressesPresets("date"),
createCoinblocksPresets("date"),
],
} satisfies PartialPresetFolder,
{
@@ -68,18 +68,18 @@ export function createPresets(): Presets {
scale: "height",
color: colors.bitcoin,
name: "",
datasetKey: "",
datasetId: "",
title: "",
}),
createLiquidityFolder({
scale: "height",
color: colors.bitcoin,
datasetKey: "",
datasetId: "",
name: "",
}),
createHodlersPresets({ scale: "height" }),
createAddressesPresets({ scale: "height" }),
createCoinblocksPresets({ scale: "height" }),
createHodlersPresets("height"),
createAddressesPresets("height"),
createCoinblocksPresets("height"),
]
: [],
} satisfies PartialPresetFolder,

View File

@@ -1,8 +1,6 @@
import { averages } from "/src/scripts/datasets/date";
import { colors } from "/src/scripts/utils/colors";
import { applySeriesList } from "../../apply";
export function createPresets(): PartialPresetFolder {
const scale: ResourceScale = "date";
@@ -14,17 +12,12 @@ export function createPresets(): PartialPresetFolder {
icon: IconTablerMathAvg,
name: "All",
title: "All Averages",
applyPreset(params) {
return applySeriesList({
...params,
top: averages.map((average) => ({
title: average.key.toUpperCase(),
color: colors[`_${average.key}`],
dataset: params.datasets.date[`price_${average.key}_sma`],
})),
});
},
description: "",
top: averages.map((average) => ({
title: average.key.toUpperCase(),
color: colors[`_${average.key}`],
datasetPath: `/date-to-price-${average.key}-sma`,
})),
},
...averages.map(({ name, key }) =>
createPresetFolder({
@@ -55,17 +48,12 @@ function createPresetFolder({
description: "",
icon: IconTablerMathAvg,
title: `${name} Moving Average`,
applyPreset(params) {
return applySeriesList({
...params,
top: [
{
title: `SMA`,
color,
dataset: params.datasets.date[`price_${key}_sma`],
},
],
});
},
top: [
{
title: `SMA`,
color,
datasetPath: `/date-to-price-${key}-sma`,
},
],
} satisfies PartialPreset;
}

View File

@@ -1,5 +1,4 @@
import { colors } from "../../utils/colors";
import { applySeriesList } from "../apply";
import { createPresets as createAveragesPresets } from "./averages";
import { createPresets as createIndicatorsPresets } from "./indicators";
import { createPresets as createReturnsPresets } from "./returns";
@@ -13,9 +12,6 @@ export function createPresets(scale: ResourceScale) {
icon: IconTablerCurrencyDollar,
name: "Price",
title: "Market Price",
applyPreset(params) {
return applySeriesList(params);
},
description: "",
},
{
@@ -23,19 +19,14 @@ export function createPresets(scale: ResourceScale) {
icon: IconTablerInfinity,
name: "Capitalization",
title: "Market Capitalization",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Market Cap.",
dataset: params.datasets[scale].market_cap,
color: colors.bitcoin,
},
],
});
},
description: "",
bottom: [
{
title: "Market Cap.",
datasetPath: `/${scale}-to-market-cap`,
color: colors.bitcoin,
},
],
},
...(scale === "date"
? ([

View File

@@ -3,7 +3,7 @@ import {
totalReturns,
} from "/src/scripts/datasets/consts/returns";
import { applySeriesList, SeriesType } from "../../apply";
import { SeriesType } from "../../enums";
export function createPresets() {
return {
@@ -17,7 +17,7 @@ export function createPresets() {
scale: "date",
name,
title: `${name} Total`,
key: `${key}_total`,
key: `${key}-total`,
}),
),
],
@@ -30,7 +30,7 @@ export function createPresets() {
scale: "date",
name,
title: `${name} Compound`,
key: `${key}_compound`,
key: `${key}-compound`,
}),
),
],
@@ -48,7 +48,7 @@ function createPreset({
scale: ResourceScale;
name: string;
title: string;
key: `${TotalReturnKey}_total` | `${CompoundReturnKey}_compound`;
key: `${TotalReturnKey}-total` | `${CompoundReturnKey}-compound`;
}): PartialPreset {
return {
scale,
@@ -56,17 +56,12 @@ function createPreset({
description: "",
icon: IconTablerReceiptTax,
title: `${title} Return`,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: `Return (%)`,
seriesType: SeriesType.Based,
dataset: params.datasets.date[`price_${key}_return`],
},
],
});
},
bottom: [
{
title: `Return (%)`,
seriesType: SeriesType.Based,
datasetPath: `/date-to-price-${key}-return`,
},
],
};
}

View File

@@ -1,5 +1,5 @@
import { colors } from "../../utils/colors";
import { applySeriesList, SeriesType } from "../apply";
import { SeriesType } from "../enums";
export function createPresets(scale: ResourceScale) {
return {
@@ -19,18 +19,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Bitcoin",
title: "Last Coinbase (In Bitcoin)",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Last",
color: colors.bitcoin,
dataset: params.datasets[scale].last_coinbase,
},
],
});
},
bottom: [
{
title: "Last",
color: colors.bitcoin,
datasetPath: `/${scale}-to-last-coinbase`,
},
],
},
{
scale,
@@ -38,19 +33,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Dollars",
title: "Last Coinbase (In Dollars)",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Last",
color: colors.dollars,
dataset:
params.datasets[scale].last_coinbase_in_dollars,
},
],
});
},
bottom: [
{
title: "Last",
color: colors.dollars,
datasetPath: `/${scale}-to-last-coinbase-in-dollars`,
},
],
},
],
},
@@ -64,18 +53,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Bitcoin",
title: "Daily Sum Of Bitcoin Coinbases",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Coinbases (Bitcoin)",
color: colors.bitcoin,
dataset: params.datasets[scale].coinbase,
},
],
});
},
bottom: [
{
title: "Coinbases (Bitcoin)",
color: colors.bitcoin,
datasetPath: `/${scale}-to-coinbase`,
},
],
},
{
scale,
@@ -83,19 +67,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Dollars",
title: "Daily Sum Of Dollar Coinbases",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Coinbases (Dollars)",
color: colors.dollars,
dataset:
params.datasets[scale].coinbase_in_dollars,
},
],
});
},
bottom: [
{
title: "Coinbases (Dollars)",
color: colors.dollars,
datasetPath: `/${scale}-to-coinbase-in-dollars`,
},
],
},
],
},
@@ -109,18 +87,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Bitcoin",
title: "Yearly Sum Of Bitcoin Coinbases",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Coinbases (Bitcoin)",
color: colors.bitcoin,
dataset: params.datasets[scale].coinbase_1y_sum,
},
],
});
},
bottom: [
{
title: "Coinbases (Bitcoin)",
color: colors.bitcoin,
datasetPath: `/${scale}-to-coinbase-1y-sum`,
},
],
},
{
scale,
@@ -128,20 +101,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Dollars",
title: "Yearly Sum Of Dollar Coinbases",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Coinbases (Dollars)",
color: colors.dollars,
dataset:
params.datasets[scale]
.coinbase_in_dollars_1y_sum,
},
],
});
},
bottom: [
{
title: "Coinbases (Dollars)",
color: colors.dollars,
datasetPath: `/${scale}-to-coinbase-in-dollars-1y-sum`,
},
],
},
],
},
@@ -155,19 +121,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Bitcoin",
title: "Cumulative Bitcoin Coinbases",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Coinbases (Bitcoin)",
color: colors.bitcoin,
dataset:
params.datasets[scale].cumulative_coinbase,
},
],
});
},
bottom: [
{
title: "Coinbases (Bitcoin)",
color: colors.bitcoin,
datasetPath: `/${scale}-to-cumulative-coinbase`,
},
],
},
{
scale,
@@ -175,20 +135,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Dollars",
title: "Cumulative Dollar Coinbases",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Coinbases (Dollars)",
color: colors.dollars,
dataset:
params.datasets[scale]
.cumulative_coinbase_in_dollars,
},
],
});
},
bottom: [
{
title: "Coinbases (Dollars)",
color: colors.dollars,
datasetPath: `/${scale}-to-cumulative-coinbase-in-dollars`,
},
],
},
],
},
@@ -211,19 +164,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Bitcoin",
title: "Last Subsidy (In Bitcoin)",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Last",
color: colors.bitcoin,
dataset: params.datasets[scale].last_subsidy,
},
],
});
},
bottom: [
{
title: "Last",
color: colors.bitcoin,
datasetPath: `/${scale}-to-last-subsidy`,
},
],
},
{
scale,
@@ -231,19 +178,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Dollars",
title: "Last Subsidy (In Dollars)",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Last",
color: colors.dollars,
dataset:
params.datasets[scale].last_subsidy_in_dollars,
},
],
});
},
bottom: [
{
title: "Last",
color: colors.dollars,
datasetPath: `/${scale}-to-last-subsidy-in-dollars`,
},
],
},
],
},
@@ -257,18 +198,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Bitcoin",
title: "Daily Sum Of Bitcoin Subsidies",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Subsidies (Bitcoin)",
color: colors.bitcoin,
dataset: params.datasets[scale].subsidy,
},
],
});
},
bottom: [
{
title: "Subsidies (Bitcoin)",
color: colors.bitcoin,
datasetPath: `/${scale}-to-subsidy`,
},
],
},
{
scale,
@@ -276,19 +212,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Dollars",
title: "Daily Sum Of Dollar Subsidies",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Subsidies (Dollars)",
color: colors.dollars,
dataset:
params.datasets[scale].subsidy_in_dollars,
},
],
});
},
bottom: [
{
title: "Subsidies (Dollars)",
color: colors.dollars,
datasetPath: `/${scale}-to-subsidy-in-dollars`,
},
],
},
],
},
@@ -302,18 +232,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Bitcoin",
title: "Yearly Sum Of Bitcoin Subsidies",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Subsidies (Bitcoin)",
color: colors.bitcoin,
dataset: params.datasets[scale].subsidy_1y_sum,
},
],
});
},
bottom: [
{
title: "Subsidies (Bitcoin)",
color: colors.bitcoin,
datasetPath: `/${scale}-to-subsidy-1y-sum`,
},
],
},
{
scale,
@@ -321,20 +246,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Dollars",
title: "Yearly Sum Of Dollar Subsidies",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Subsidies (Dollars)",
color: colors.dollars,
dataset:
params.datasets[scale]
.subsidy_in_dollars_1y_sum,
},
],
});
},
bottom: [
{
title: "Subsidies (Dollars)",
color: colors.dollars,
datasetPath: `/${scale}-to-subsidy-in-dollars-1y-sum`,
},
],
},
],
},
@@ -348,19 +266,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Bitcoin",
title: "Cumulative Bitcoin Subsidies",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Subsidies (Bitcoin)",
color: colors.bitcoin,
dataset:
params.datasets[scale].cumulative_subsidy,
},
],
});
},
bottom: [
{
title: "Subsidies (Bitcoin)",
color: colors.bitcoin,
datasetPath: `/${scale}-to-cumulative-subsidy`,
},
],
},
{
scale,
@@ -368,20 +280,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Dollars",
title: "Cumulative Dollar Subsidies",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Subsidies (Dollars)",
color: colors.dollars,
dataset:
params.datasets[scale]
.cumulative_subsidy_in_dollars,
},
],
});
},
bottom: [
{
title: "Subsidies (Dollars)",
color: colors.dollars,
datasetPath: `/${scale}-to-cumulative-subsidy-in-dollars`,
},
],
},
],
},
@@ -404,18 +309,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Bitcoin",
title: "Last Fees (In Bitcoin)",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Last",
color: colors.bitcoin,
dataset: params.datasets[scale].last_fees,
},
],
});
},
bottom: [
{
title: "Last",
color: colors.bitcoin,
datasetPath: `/${scale}-to-last-fees`,
},
],
},
{
scale,
@@ -423,19 +323,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Dollars",
title: "Last Fees (In Dollars)",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Last",
color: colors.dollars,
dataset:
params.datasets[scale].last_fees_in_dollars,
},
],
});
},
bottom: [
{
title: "Last",
color: colors.dollars,
datasetPath: `/${scale}-to-last-fees-in-dollars`,
},
],
},
],
},
@@ -449,18 +343,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Bitcoin",
title: "Daily Sum Of Bitcoin Fees",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Fees (Bitcoin)",
color: colors.bitcoin,
dataset: params.datasets[scale].fees,
},
],
});
},
bottom: [
{
title: "Fees (Bitcoin)",
color: colors.bitcoin,
datasetPath: `/${scale}-to-fees`,
},
],
},
{
scale,
@@ -468,18 +357,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Dollars",
title: "Daily Sum Of Dollar Fees",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Fees (Dollars)",
color: colors.dollars,
dataset: params.datasets[scale].fees_in_dollars,
},
],
});
},
bottom: [
{
title: "Fees (Dollars)",
color: colors.dollars,
datasetPath: `/${scale}-to-fees-in-dollars`,
},
],
},
],
},
@@ -493,18 +377,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Bitcoin",
title: "Yearly Sum Of Bitcoin Fees",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Fees (Bitcoin)",
color: colors.bitcoin,
dataset: params.datasets[scale].fees_1y_sum,
},
],
});
},
bottom: [
{
title: "Fees (Bitcoin)",
color: colors.bitcoin,
datasetPath: `/${scale}-to-fees-1y-sum`,
},
],
},
{
scale,
@@ -512,19 +391,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Dollars",
title: "Yearly Sum Of Dollar Fees",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Fees (Dollars)",
color: colors.dollars,
dataset:
params.datasets[scale].fees_in_dollars_1y_sum,
},
],
});
},
bottom: [
{
title: "Fees (Dollars)",
color: colors.dollars,
datasetPath: `/${scale}-to-fees-in-dollars-1y-sum`,
},
],
},
],
},
@@ -538,18 +411,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Bitcoin",
title: "Cumulative Bitcoin Fees",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Fees (Bitcoin)",
color: colors.bitcoin,
dataset: params.datasets[scale].cumulative_fees,
},
],
});
},
bottom: [
{
title: "Fees (Bitcoin)",
color: colors.bitcoin,
datasetPath: `/${scale}-to-cumulative-fees`,
},
],
},
{
scale,
@@ -557,20 +425,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Dollars",
title: "Cumulative Dollar Fees",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Fees (Dollars)",
color: colors.dollars,
dataset:
params.datasets[scale]
.cumulative_fees_in_dollars,
},
],
});
},
bottom: [
{
title: "Fees (Dollars)",
color: colors.dollars,
datasetPath: `/${scale}-to-cumulative-fees-in-dollars`,
},
],
},
],
},
@@ -585,23 +446,18 @@ export function createPresets(scale: ResourceScale) {
name: "Subsidy V. Fees",
title: "Subsidy V. Fees",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Subsidy (%)",
color: colors.bitcoin,
dataset: params.datasets[scale].subsidy_to_coinbase_ratio,
},
{
title: "Fees (%)",
color: colors.darkBitcoin,
dataset: params.datasets[scale].fees_to_coinbase_ratio,
},
],
});
},
bottom: [
{
title: "Subsidy (%)",
color: colors.bitcoin,
datasetPath: `/${scale}-to-subsidy-to-coinbase-ratio`,
},
{
title: "Fees (%)",
color: colors.darkBitcoin,
datasetPath: `/${scale}-to-fees-to-coinbase-ratio`,
},
],
},
...(scale === "date"
@@ -612,21 +468,16 @@ export function createPresets(scale: ResourceScale) {
name: "Puell Multiple",
title: "Puell Multiple",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
priceScaleOptions: {
mode: 1,
},
bottom: [
{
title: "Multiple",
color: colors.bitcoin,
dataset: params.datasets.date.puell_multiple,
},
],
});
priceScaleOptions: {
mode: 1,
},
bottom: [
{
title: "Multiple",
color: colors.bitcoin,
datasetPath: `/date-to-puell-multiple`,
},
],
},
{
@@ -635,79 +486,62 @@ export function createPresets(scale: ResourceScale) {
name: "Hash Rate",
title: "Hash Rate (EH/s)",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
priceScaleOptions: {
mode: 1,
},
bottom: [
{
title: "1M SMA",
color: colors.momentumYellow,
dataset: params.datasets.date.hash_rate_1m_sma,
},
{
title: "1W SMA",
color: colors.bitcoin,
dataset: params.datasets.date.hash_rate_1w_sma,
},
{
title: "Rate",
color: colors.darkBitcoin,
dataset: params.datasets.date.hash_rate,
},
],
});
priceScaleOptions: {
mode: 1,
},
bottom: [
{
title: "1M SMA",
color: colors.momentumYellow,
datasetPath: `/date-to-hash-rate-1m-sma`,
},
{
title: "1W SMA",
color: colors.bitcoin,
datasetPath: `/date-to-hash-rate-1w-sma`,
},
{
title: "Rate",
color: colors.darkBitcoin,
datasetPath: `/date-to-hash-rate`,
},
],
},
{
scale,
icon: IconTablerRibbonHealth,
name: "Hash Ribbon",
title: "Hash Ribbon (EH/s)",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
priceScaleOptions: {
mode: 1,
},
bottom: [
{
title: "1M SMA",
color: colors.profit,
dataset: params.datasets.date.hash_rate_1m_sma,
},
{
title: "2M SMA",
color: colors.loss,
dataset: params.datasets.date.hash_rate_2m_sma,
},
],
});
priceScaleOptions: {
mode: 1,
},
bottom: [
{
title: "1M SMA",
color: colors.profit,
datasetPath: `/date-to-hash-rate-1m-sma`,
},
{
title: "2M SMA",
color: colors.loss,
datasetPath: `/date-to-hash-rate-2m-sma`,
},
],
},
{
scale,
icon: IconTablerTag,
name: "Hash Price",
title: "Hash Price",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Price ($/PH/s)",
color: colors.dollars,
dataset: params.datasets.date.hash_price,
},
],
});
},
bottom: [
{
title: "Price ($/PH/s)",
color: colors.dollars,
datasetPath: `/date-to-hash-price`,
},
],
},
] satisfies PartialPreset[])
: []),
@@ -718,21 +552,16 @@ export function createPresets(scale: ResourceScale) {
name: "Difficulty",
title: "Difficulty",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
priceScaleOptions: {
mode: 1,
},
bottom: [
{
title: "Difficulty",
color: colors.bitcoin,
dataset: params.datasets[scale].difficulty,
},
],
});
priceScaleOptions: {
mode: 1,
},
bottom: [
{
title: "Difficulty",
color: colors.bitcoin,
datasetPath: `/${scale}-to-difficulty`,
},
],
},
...(scale === "date"
@@ -743,18 +572,13 @@ export function createPresets(scale: ResourceScale) {
name: "Difficulty Adjustment",
title: "Difficulty Adjustment",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Adjustment (%)",
seriesType: SeriesType.Based,
dataset: params.datasets[scale].difficulty_adjustment,
},
],
});
},
bottom: [
{
title: "Adjustment (%)",
seriesType: SeriesType.Based,
datasetPath: `/${scale}-to-difficulty-adjustment`,
},
],
},
] satisfies PartialPreset[])
: []),
@@ -765,21 +589,16 @@ export function createPresets(scale: ResourceScale) {
name: "Annualized Issuance",
title: "Annualized Issuance",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
priceScaleOptions: {
mode: 1,
},
bottom: [
{
title: "Issuance",
color: colors.bitcoin,
dataset: params.datasets[scale].annualized_issuance,
},
],
});
priceScaleOptions: {
mode: 1,
},
bottom: [
{
title: "Issuance",
color: colors.bitcoin,
datasetPath: `/${scale}-to-annualized-issuance`,
},
],
},
{
@@ -788,21 +607,16 @@ export function createPresets(scale: ResourceScale) {
name: "Yearly Inflation Rate",
title: "Yearly Inflation Rate",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
priceScaleOptions: {
mode: 1,
},
bottom: [
{
title: "Rate (%)",
color: colors.bitcoin,
dataset: params.datasets[scale].yearly_inflation_rate,
},
],
});
priceScaleOptions: {
mode: 1,
},
bottom: [
{
title: "Rate (%)",
color: colors.bitcoin,
datasetPath: `/${scale}-to-yearly-inflation-rate`,
},
],
},
// For scale === "height"

View File

@@ -1,880 +0,0 @@
import { percentiles } from "../../datasets/consts/percentiles";
import { colors } from "../../utils/colors";
import { applySeriesList, SeriesType } from "../apply";
export function createCohortPresetFolder<Scale extends ResourceScale>({
scale,
color,
name,
datasetKey,
title,
}: {
scale: Scale;
name: string;
datasetKey: AnyPossibleCohortKey;
color: Color;
title: string;
}) {
return {
name,
tree: createCohortPresetList({
title,
name,
scale,
color,
datasetKey,
}),
} satisfies PartialPresetFolder;
}
export function createCohortPresetList<Scale extends ResourceScale>({
name,
scale,
color,
datasetKey,
title,
}: {
name: string;
scale: Scale;
datasetKey: AnyPossibleCohortKey;
title: string;
color: Color;
}) {
const datasetPrefix = datasetKey
? (`${datasetKey}_` as const)
: ("" as const);
return [
{
name: "UTXOs",
tree: [
{
scale,
name: `Count`,
title: `${title} Unspent Transaction Outputs Count`,
icon: () => IconTablerTicket,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Count",
color,
dataset: params.datasets[scale][`${datasetPrefix}utxo_count`],
},
],
});
},
description: "",
},
],
},
{
name: "Realized",
tree: [
{
scale,
name: `Price`,
title: `${title} Realized Price`,
description: "",
icon: () => IconTablerTag,
applyPreset(params) {
return applySeriesList({
...params,
top: [
{
title: "Realized Price",
color,
dataset:
params.datasets[scale][`${datasetPrefix}realized_price`],
},
],
});
},
},
{
scale,
name: `Capitalization`,
title: `${title} Realized Capitalization`,
icon: () => IconTablerPigMoney,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: `${name} Realized Cap.`,
color,
dataset:
params.datasets[scale][`${datasetPrefix}realized_cap`],
},
...(datasetKey
? [
{
title: "Realized Cap.",
color: colors.bitcoin,
dataset: params.datasets[scale].realized_cap,
defaultVisible: false,
},
]
: []),
],
});
},
description: "",
},
{
scale,
name: `Capitalization 1M Net Change`,
title: `${title} Realized Capitalization 1 Month Net Change`,
icon: () => IconTablerStatusChange,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: `Net Change`,
seriesType: SeriesType.Based,
dataset:
params.datasets[scale][
`${datasetPrefix}realized_cap_1m_net_change`
],
},
],
});
},
description: "",
},
{
scale,
name: `Profit`,
title: `${title} Realized Profit`,
icon: () => IconTablerCash,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Realized Profit",
dataset:
params.datasets[scale][`${datasetPrefix}realized_profit`],
color: colors.profit,
},
],
});
},
description: "",
},
{
scale,
name: "Loss",
title: `${title} Realized Loss`,
icon: () => IconTablerCoffin,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Realized Loss",
dataset:
params.datasets[scale][`${datasetPrefix}realized_loss`],
color: colors.loss,
},
],
});
},
description: "",
},
{
scale,
name: `PNL`,
title: `${title} Realized Profit And Loss`,
icon: () => IconTablerArrowsVertical,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Profit",
color: colors.profit,
dataset:
params.datasets[scale][`${datasetPrefix}realized_profit`],
seriesType: SeriesType.Based,
},
{
title: "Loss",
color: colors.loss,
dataset:
params.datasets[scale][
`${datasetPrefix}negative_realized_loss`
],
seriesType: SeriesType.Based,
},
],
});
},
description: "",
},
{
scale,
name: `Net PNL`,
title: `${title} Net Realized Profit And Loss`,
icon: () => IconTablerScale,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Net PNL",
seriesType: SeriesType.Based,
dataset:
params.datasets[scale][
`${datasetPrefix}net_realized_profit_and_loss`
],
},
],
});
},
description: "",
},
{
scale,
name: `Net PNL Relative To Market Cap`,
title: `${title} Net Realized Profit And Loss Relative To Market Capitalization`,
icon: () => IconTablerDivide,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Net",
seriesType: SeriesType.Based,
dataset:
params.datasets[scale][
`${datasetPrefix}net_realized_profit_and_loss_to_market_cap_ratio`
],
},
],
});
},
description: "",
},
{
scale,
name: `Cumulative Profit`,
title: `${title} Cumulative Realized Profit`,
icon: () => IconTablerSum,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Cumulative Realized Profit",
color: colors.profit,
dataset:
params.datasets[scale][
`${datasetPrefix}cumulative_realized_profit`
],
},
],
});
},
description: "",
},
{
scale,
name: "Cumulative Loss",
title: `${title} Cumulative Realized Loss`,
icon: () => IconTablerSum,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Cumulative Realized Loss",
color: colors.loss,
dataset:
params.datasets[scale][
`${datasetPrefix}cumulative_realized_loss`
],
},
],
});
},
description: "",
},
{
scale,
name: `Cumulative Net PNL`,
title: `${title} Cumulative Net Realized Profit And Loss`,
icon: () => IconTablerSum,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Cumulative Net Realized PNL",
seriesType: SeriesType.Based,
dataset:
params.datasets[scale][
`${datasetPrefix}cumulative_net_realized_profit_and_loss`
],
},
],
});
},
description: "",
},
{
scale,
name: `Cumulative Net PNL 30 Day Change`,
title: `${title} Cumulative Net Realized Profit And Loss 30 Day Change`,
icon: () => IconTablerTimeDuration30,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Cumulative Net Realized PNL 30d Change",
dataset:
params.datasets[scale][
`${datasetPrefix}cumulative_net_realized_profit_and_loss_1m_net_change`
],
seriesType: SeriesType.Based,
},
],
});
},
description: "",
},
],
},
{
name: "Unrealized",
tree: [
{
scale,
name: `Profit`,
title: `${title} Unrealized Profit`,
icon: () => IconTablerMoodDollar,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Profit",
dataset:
params.datasets[scale][`${datasetPrefix}unrealized_profit`],
color: colors.profit,
},
],
});
},
description: "",
},
{
scale,
name: "Loss",
title: `${title} Unrealized Loss`,
icon: () => IconTablerMoodSadDizzy,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Loss",
dataset:
params.datasets[scale][`${datasetPrefix}unrealized_loss`],
color: colors.loss,
},
],
});
},
description: "",
},
{
scale,
name: `PNL`,
title: `${title} Unrealized Profit And Loss`,
icon: () => IconTablerArrowsVertical,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Profit",
color: colors.profit,
dataset:
params.datasets[scale][`${datasetPrefix}unrealized_profit`],
seriesType: SeriesType.Based,
},
{
title: "Loss",
color: colors.loss,
dataset:
params.datasets[scale][
`${datasetPrefix}negative_unrealized_loss`
],
seriesType: SeriesType.Based,
},
],
});
},
description: "",
},
{
scale,
name: `Net PNL`,
title: `${title} Net Unrealized Profit And Loss`,
icon: () => IconTablerScale,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Net Unrealized PNL",
dataset:
params.datasets[scale][
`${datasetPrefix}net_unrealized_profit_and_loss`
],
seriesType: SeriesType.Based,
},
],
});
},
description: "",
},
{
scale,
name: `Net PNL Relative To Market Cap`,
title: `${title} Net Unrealized Profit And Loss Relative To Total Market Capitalization`,
icon: () => IconTablerDivide,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Relative Net Unrealized PNL",
dataset:
params.datasets[scale][
`${datasetPrefix}net_unrealized_profit_and_loss_to_market_cap_ratio`
],
seriesType: SeriesType.Based,
},
],
});
},
description: "",
},
],
},
{
name: "Supply",
tree: [
{
name: "Absolute",
tree: [
{
scale,
name: "All",
title: `${title} Profit And Loss`,
icon: () => IconTablerArrowsCross,
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "In Profit",
color: colors.profit,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_profit`
],
},
{
title: "In Loss",
color: colors.loss,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_loss`
],
},
{
title: "Total",
color: colors.white,
dataset: params.datasets[scale][`${datasetPrefix}supply`],
},
{
title: "Halved Total",
color: colors.gray,
dataset:
params.datasets[scale][`${datasetPrefix}halved_supply`],
options: {
lineStyle: 4,
},
},
],
});
},
},
{
scale,
name: `Total`,
title: `${title} Total supply`,
icon: () => IconTablerSum,
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Supply",
color,
dataset: params.datasets[scale][`${datasetPrefix}supply`],
},
],
});
},
},
{
scale,
name: "In Profit",
title: `${title} Supply In Profit`,
icon: () => IconTablerTrendingUp,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Supply",
color: colors.profit,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_profit`
],
},
],
});
},
description: "",
},
{
scale,
name: "In Loss",
title: `${title} Supply In Loss`,
icon: () => IconTablerTrendingDown,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Supply",
color: colors.loss,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_loss`
],
},
],
});
},
description: "",
},
],
},
{
name: "Relative To Circulating",
tree: [
{
scale,
name: "All",
title: `${title} Profit And Loss Relative To Circulating Supply`,
icon: () => IconTablerArrowsCross,
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "In Profit",
color: colors.profit,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_profit_to_circulating_supply_ratio`
],
},
{
title: "In Loss",
color: colors.loss,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_loss_to_circulating_supply_ratio`
],
},
{
title: "100%",
color: colors.white,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_to_circulating_supply_ratio`
],
},
{
title: "50%",
color: colors.gray,
dataset:
params.datasets[scale][
`${datasetPrefix}halved_supply_to_circulating_supply_ratio`
],
options: {
lineStyle: 4,
},
},
],
});
},
},
{
scale,
name: `Total`,
title: `${title} Total supply Relative To Circulating Supply`,
icon: () => IconTablerSum,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Supply",
color,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_to_circulating_supply_ratio`
],
},
],
});
},
description: "",
},
{
scale,
name: "In Profit",
title: `${title} Supply In Profit Relative To Circulating Supply`,
icon: () => IconTablerTrendingUp,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Supply",
color: colors.profit,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_profit_to_circulating_supply_ratio`
],
},
],
});
},
description: "",
},
{
scale,
name: "In Loss",
title: `${title} Supply In Loss Relative To Circulating Supply`,
icon: () => IconTablerTrendingDown,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Supply",
color: colors.loss,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_loss_to_circulating_supply_ratio`
],
},
],
});
},
description: "",
},
],
},
{
name: "Relative To Own",
tree: [
{
scale,
name: "All",
title: `${title} Supply In Profit And Loss Relative To Own Supply`,
icon: () => IconTablerArrowsCross,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "In Profit",
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_profit_to_own_supply_ratio`
],
color: colors.profit,
},
{
title: "In Loss",
color: colors.loss,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_loss_to_own_supply_ratio`
],
},
{
title: "100%",
color: colors.white,
dataset: params.datasets[scale][100],
options: {
lastValueVisible: false,
},
},
{
title: "50%",
color: colors.gray,
dataset: params.datasets[scale][50],
options: {
lineStyle: 4,
lastValueVisible: false,
},
},
],
});
},
description: "",
},
{
scale,
name: "In Profit",
title: `${title} Supply In Profit Relative To Own Supply`,
icon: () => IconTablerTrendingUp,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Supply",
color: colors.profit,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_profit_to_own_supply_ratio`
],
},
],
});
},
description: "",
},
{
scale,
name: "In Loss",
title: `${title} Supply In Loss Relative To Own Supply`,
icon: () => IconTablerTrendingDown,
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Supply",
color: colors.loss,
dataset:
params.datasets[scale][
`${datasetPrefix}supply_in_loss_to_own_supply_ratio`
],
},
],
});
},
description: "",
},
],
},
// createMomentumPresetFolder({
// datasets: datasets[scale],
// scale,
// id: `${scale}-${id}-supply-in-profit-and-loss-percentage-self`,
// title: `${title} Supply In Profit And Loss (% Self)`,
// datasetKey: `${datasetKey}SupplyPNL%Self`,
// }),
],
},
{
name: "Prices Paid",
tree: [
{
scale,
name: `Average`,
title: `${title} Average Price Paid - Realized Price`,
icon: () => IconTablerMathAvg,
applyPreset(params) {
return applySeriesList({
...params,
top: [
{
title: "Average",
color,
dataset:
params.datasets[scale][`${datasetPrefix}realized_price`],
},
],
});
},
description: "",
},
{
scale,
name: `Deciles`,
title: `${title} deciles`,
icon: () => IconTablerSquareHalf,
applyPreset(params) {
return applySeriesList({
...params,
top: percentiles
.filter(({ value }) => Number(value) % 10 === 0)
.map(({ name, key }) => ({
dataset: params.datasets[scale][`${datasetPrefix}${key}`],
color,
title: name,
})),
});
},
description: "",
},
...percentiles.map(
(percentile): PartialPreset => ({
scale,
name: percentile.name,
title: `${title} ${percentile.title}`,
icon: () => IconTablerSquareHalf,
applyPreset(params) {
return applySeriesList({
...params,
top: [
{
title: percentile.name,
color,
dataset:
params.datasets[scale][
`${datasetPrefix}${percentile.key}`
],
},
],
});
},
description: "",
}),
),
],
},
] satisfies PartialPresetTree;
}

View File

@@ -0,0 +1,77 @@
import { createCohortPresetPricesPaidFolder } from "./pricesPaid";
import { createCohortPresetRealizedFolder } from "./realized";
import { createCohortPresetSupplyFolder } from "./supply";
import { createCohortPresetUnrealizedFolder } from "./unrealized";
import { createCohortPresetUTXOFolder } from "./utxo";
export function createCohortPresetFolder({
scale,
color,
name,
datasetId,
title,
}: {
scale: ResourceScale;
name: string;
datasetId: AnyPossibleCohortId;
color: Color;
title: string;
}) {
return {
name,
tree: createCohortPresetList({
title,
name,
scale,
color,
datasetId: datasetId,
}),
} satisfies PartialPresetFolder;
}
export function createCohortPresetList({
name,
scale,
color,
datasetId,
title,
}: {
name: string;
scale: ResourceScale;
datasetId: AnyPossibleCohortId;
title: string;
color: Color;
}) {
return [
createCohortPresetUTXOFolder({
color,
datasetId,
scale,
title,
}),
createCohortPresetRealizedFolder({
color,
datasetId,
scale,
title,
}),
createCohortPresetUnrealizedFolder({
color,
datasetId,
scale,
title,
}),
createCohortPresetSupplyFolder({
color,
datasetId,
scale,
title,
}),
createCohortPresetPricesPaidFolder({
color,
datasetId,
scale,
title,
}),
] satisfies PartialPresetTree;
}

View File

@@ -0,0 +1,79 @@
import { percentiles } from "/src/scripts/datasets/consts/percentiles";
import { datasetIdToPrefix } from "./utils";
export function createCohortPresetPricesPaidFolder({
scale,
color,
datasetId,
title,
}: {
scale: ResourceScale;
datasetId: AnyPossibleCohortId;
title: string;
color: Color;
}): PartialPresetFolder {
return {
name: "Prices Paid",
tree: [
{
scale,
name: `Average`,
title: `${title} Average Price Paid - Realized Price`,
description: "",
icon: () => IconTablerMathAvg,
top: [
{
title: "Average",
color,
datasetPath: `/${scale as ResourceScale}-to-${datasetIdToPrefix(datasetId)}realized-price`,
},
],
},
{
scale,
name: `Deciles`,
title: `${title} deciles`,
icon: () => IconTablerSquareHalf,
description: "",
top: percentiles
.filter(({ value }) => Number(value) % 10 === 0)
.map(({ name, id }) => {
const datasetPath = generatePath(scale, datasetId, id);
return {
datasetPath,
color,
title: name,
};
}),
},
...percentiles.map(
(percentile): PartialPreset => ({
scale,
name: percentile.name,
title: `${title} ${percentile.title}`,
description: "",
icon: () => IconTablerSquareHalf,
top: [
{
title: percentile.name,
color,
datasetPath: generatePath(scale, datasetId, percentile.id),
},
],
}),
),
],
};
}
function generatePath(
scale: ResourceScale,
cohortId: AnyPossibleCohortId,
id: PercentileId,
): AnyDatasetPath {
const datasetPrefix = datasetIdToPrefix(cohortId);
return `/${scale}-to-${datasetPrefix}${id}` as const;
}

View File

@@ -0,0 +1,209 @@
import { colors } from "/src/scripts/utils/colors";
import { SeriesType } from "../../enums";
import { datasetIdToPrefix } from "./utils";
export function createCohortPresetRealizedFolder({
scale,
color,
datasetId,
title,
}: {
scale: ResourceScale;
datasetId: AnyPossibleCohortId;
title: string;
color: Color;
}): PartialPresetFolder {
const datasetPrefix = datasetIdToPrefix(datasetId);
return {
name: "Realized",
tree: [
{
scale,
name: `Price`,
title: `${title} Realized Price`,
description: "",
icon: () => IconTablerTag,
top: [
{
title: "Realized Price",
color,
datasetPath: `/${scale}-to-${datasetPrefix}realized-price`,
},
],
},
{
scale,
name: `Capitalization`,
title: `${title} Realized Capitalization`,
description: "",
icon: () => IconTablerPigMoney,
bottom: [
{
title: `${name} Realized Cap.`,
color,
datasetPath: `/${scale}-to-${datasetPrefix}realized-cap`,
},
...(datasetId
? ([
{
title: "Realized Cap.",
color: colors.bitcoin,
datasetPath: `/${scale}-to-realized-cap`,
defaultVisible: false,
},
] as const)
: []),
],
},
{
scale,
name: `Capitalization 1M Net Change`,
title: `${title} Realized Capitalization 1 Month Net Change`,
description: "",
icon: () => IconTablerStatusChange,
bottom: [
{
title: `Net Change`,
seriesType: SeriesType.Based,
datasetPath: `/${scale}-to-${datasetPrefix}realized-cap-1m-net-change`,
},
],
},
{
scale,
name: `Profit`,
title: `${title} Realized Profit`,
description: "",
icon: () => IconTablerCash,
bottom: [
{
title: "Realized Profit",
datasetPath: `/${scale}-to-${datasetPrefix}realized-profit`,
color: colors.profit,
},
],
},
{
scale,
name: "Loss",
title: `${title} Realized Loss`,
description: "",
icon: () => IconTablerCoffin,
bottom: [
{
title: "Realized Loss",
datasetPath: `/${scale}-to-${datasetPrefix}realized-loss`,
color: colors.loss,
},
],
},
{
scale,
name: `PNL`,
title: `${title} Realized Profit And Loss`,
description: "",
icon: () => IconTablerArrowsVertical,
bottom: [
{
title: "Profit",
color: colors.profit,
datasetPath: `/${scale}-to-${datasetPrefix}realized-profit`,
seriesType: SeriesType.Based,
},
{
title: "Loss",
color: colors.loss,
datasetPath: `/${scale}-to-${datasetPrefix}negative-realized-loss`,
seriesType: SeriesType.Based,
},
],
},
{
scale,
name: `Net PNL`,
title: `${title} Net Realized Profit And Loss`,
description: "",
icon: () => IconTablerScale,
bottom: [
{
title: "Net PNL",
seriesType: SeriesType.Based,
datasetPath: `/${scale}-to-${datasetPrefix}net-realized-profit-and-loss`,
},
],
},
{
scale,
name: `Net PNL Relative To Market Cap`,
title: `${title} Net Realized Profit And Loss Relative To Market Capitalization`,
description: "",
icon: () => IconTablerDivide,
bottom: [
{
title: "Net",
seriesType: SeriesType.Based,
datasetPath: `/${scale}-to-${datasetPrefix}net-realized-profit-and-loss-to-market-cap-ratio`,
},
],
},
{
scale,
name: `Cumulative Profit`,
title: `${title} Cumulative Realized Profit`,
description: "",
icon: () => IconTablerSum,
bottom: [
{
title: "Cumulative Realized Profit",
color: colors.profit,
datasetPath: `/${scale}-to-${datasetPrefix}cumulative-realized-profit`,
},
],
},
{
scale,
name: "Cumulative Loss",
title: `${title} Cumulative Realized Loss`,
description: "",
icon: () => IconTablerSum,
bottom: [
{
title: "Cumulative Realized Loss",
color: colors.loss,
datasetPath: `/${scale}-to-${datasetPrefix}cumulative-realized-loss`,
},
],
},
{
scale,
name: `Cumulative Net PNL`,
title: `${title} Cumulative Net Realized Profit And Loss`,
description: "",
icon: () => IconTablerSum,
bottom: [
{
title: "Cumulative Net Realized PNL",
seriesType: SeriesType.Based,
datasetPath: `/${scale}-to-${datasetPrefix}cumulative-net-realized-profit-and-loss`,
},
],
},
{
scale,
name: `Cumulative Net PNL 30 Day Change`,
title: `${title} Cumulative Net Realized Profit And Loss 30 Day Change`,
description: "",
icon: () => IconTablerTimeDuration30,
bottom: [
{
title: "Cumulative Net Realized PNL 30d Change",
datasetPath: `/${scale}-to-${datasetPrefix}cumulative-net-realized-profit-and-loss-1m-net-change`,
seriesType: SeriesType.Based,
},
],
},
],
};
}

View File

@@ -0,0 +1,258 @@
import { colors } from "/src/scripts/utils/colors";
import { datasetIdToPrefix } from "./utils";
export function createCohortPresetSupplyFolder({
scale,
color,
datasetId,
title,
}: {
scale: ResourceScale;
datasetId: AnyPossibleCohortId;
title: string;
color: Color;
}): PartialPresetFolder {
const datasetPrefix = datasetIdToPrefix(datasetId);
return {
name: "Supply",
tree: [
{
name: "Absolute",
tree: [
{
scale,
name: "All",
title: `${title} Profit And Loss`,
icon: () => IconTablerArrowsCross,
description: "",
bottom: [
{
title: "In Profit",
color: colors.profit,
datasetPath: `/${scale}-to-${datasetPrefix}supply-in-profit`,
},
{
title: "In Loss",
color: colors.loss,
datasetPath: `/${scale}-to-${datasetPrefix}supply-in-loss`,
},
{
title: "Total",
color: colors.white,
datasetPath: `/${scale}-to-${datasetPrefix}supply`,
},
{
title: "Halved Total",
color: colors.gray,
datasetPath: `/${scale}-to-${datasetPrefix}halved-supply`,
options: {
lineStyle: 4,
},
},
],
},
{
scale,
name: `Total`,
title: `${title} Total supply`,
icon: () => IconTablerSum,
description: "",
bottom: [
{
title: "Supply",
color,
datasetPath: `/${scale}-to-${datasetPrefix}supply`,
},
],
},
{
scale,
name: "In Profit",
title: `${title} Supply In Profit`,
description: "",
icon: () => IconTablerTrendingUp,
bottom: [
{
title: "Supply",
color: colors.profit,
datasetPath: `/${scale}-to-${datasetPrefix}supply-in-profit`,
},
],
},
{
scale,
name: "In Loss",
title: `${title} Supply In Loss`,
description: "",
icon: () => IconTablerTrendingDown,
bottom: [
{
title: "Supply",
color: colors.loss,
datasetPath: `/${scale}-to-${datasetPrefix}supply-in-loss`,
},
],
},
],
},
{
name: "Relative To Circulating",
tree: [
{
scale,
name: "All",
title: `${title} Profit And Loss Relative To Circulating Supply`,
description: "",
icon: () => IconTablerArrowsCross,
bottom: [
{
title: "In Profit",
color: colors.profit,
datasetPath: `/${scale}-to-${datasetPrefix}supply-in-profit-to-circulating-supply-ratio`,
},
{
title: "In Loss",
color: colors.loss,
datasetPath: `/${scale}-to-${datasetPrefix}supply-in-loss-to-circulating-supply-ratio`,
},
{
title: "100%",
color: colors.white,
datasetPath: `/${scale}-to-${datasetPrefix}supply-to-circulating-supply-ratio`,
},
{
title: "50%",
color: colors.gray,
datasetPath: `/${scale}-to-${datasetPrefix}halved-supply-to-circulating-supply-ratio`,
options: {
lineStyle: 4,
},
},
],
},
{
scale,
name: `Total`,
title: `${title} Total supply Relative To Circulating Supply`,
description: "",
icon: () => IconTablerSum,
bottom: [
{
title: "Supply",
color,
datasetPath: `/${scale}-to-${datasetPrefix}supply-to-circulating-supply-ratio`,
},
],
},
{
scale,
name: "In Profit",
title: `${title} Supply In Profit Relative To Circulating Supply`,
description: "",
icon: () => IconTablerTrendingUp,
bottom: [
{
title: "Supply",
color: colors.profit,
datasetPath: `/${scale}-to-${datasetPrefix}supply-in-profit-to-circulating-supply-ratio`,
},
],
},
{
scale,
name: "In Loss",
title: `${title} Supply In Loss Relative To Circulating Supply`,
description: "",
icon: () => IconTablerTrendingDown,
bottom: [
{
title: "Supply",
color: colors.loss,
datasetPath: `/${scale}-to-${datasetPrefix}supply-in-loss-to-circulating-supply-ratio`,
},
],
},
],
},
{
name: "Relative To Own",
tree: [
{
scale,
name: "All",
title: `${title} Supply In Profit And Loss Relative To Own Supply`,
description: "",
icon: () => IconTablerArrowsCross,
bottom: [
{
title: "In Profit",
color: colors.profit,
datasetPath: `/${scale}-to-${datasetPrefix}supply-in-profit-to-own-supply-ratio`,
},
{
title: "In Loss",
color: colors.loss,
datasetPath: `/${scale}-to-${datasetPrefix}supply-in-loss-to-own-supply-ratio`,
},
{
title: "100%",
color: colors.white,
datasetPath: `/${scale}-to-100`,
options: {
lastValueVisible: false,
},
},
{
title: "50%",
color: colors.gray,
datasetPath: `/${scale}-to-50`,
options: {
lineStyle: 4,
lastValueVisible: false,
},
},
],
},
{
scale,
name: "In Profit",
title: `${title} Supply In Profit Relative To Own Supply`,
description: "",
icon: () => IconTablerTrendingUp,
bottom: [
{
title: "Supply",
color: colors.profit,
datasetPath: `/${scale}-to-${datasetPrefix}supply-in-profit-to-own-supply-ratio`,
},
],
},
{
scale,
name: "In Loss",
title: `${title} Supply In Loss Relative To Own Supply`,
description: "",
icon: () => IconTablerTrendingDown,
bottom: [
{
title: "Supply",
color: colors.loss,
datasetPath: `/${scale}-to-${datasetPrefix}supply-in-loss-to-own-supply-ratio`,
},
],
},
],
},
// createMomentumPresetFolder({
// datasets: datasets[scale],
// scale,
// id: `${scale}-${id}-supply-in-profit-and-loss-percentage-self`,
// title: `${title} Supply In Profit And Loss (% Self)`,
// datasetId: `${datasetId}SupplyPNL%Self`,
// }),
],
};
}

View File

@@ -0,0 +1,101 @@
import { colors } from "/src/scripts/utils/colors";
import { SeriesType } from "../../enums";
import { datasetIdToPrefix } from "./utils";
export function createCohortPresetUnrealizedFolder({
scale,
color,
datasetId,
title,
}: {
scale: ResourceScale;
datasetId: AnyPossibleCohortId;
title: string;
color: Color;
}): PartialPresetFolder {
const datasetPrefix = datasetIdToPrefix(datasetId);
return {
name: "Unrealized",
tree: [
{
scale,
name: `Profit`,
title: `${title} Unrealized Profit`,
description: "",
icon: () => IconTablerMoodDollar,
bottom: [
{
title: "Profit",
datasetPath: `/${scale}-to-${datasetPrefix}unrealized-profit`,
color: colors.profit,
},
],
},
{
scale,
name: "Loss",
title: `${title} Unrealized Loss`,
description: "",
icon: () => IconTablerMoodSadDizzy,
bottom: [
{
title: "Loss",
datasetPath: `/${scale}-to-${datasetPrefix}unrealized-loss`,
color: colors.loss,
},
],
},
{
scale,
name: `PNL`,
title: `${title} Unrealized Profit And Loss`,
description: "",
icon: () => IconTablerArrowsVertical,
bottom: [
{
title: "Profit",
color: colors.profit,
datasetPath: `/${scale}-to-${datasetPrefix}unrealized-profit`,
seriesType: SeriesType.Based,
},
{
title: "Loss",
color: colors.loss,
datasetPath: `/${scale}-to-${datasetPrefix}negative-unrealized-loss`,
seriesType: SeriesType.Based,
},
],
},
{
scale,
name: `Net PNL`,
title: `${title} Net Unrealized Profit And Loss`,
description: "",
icon: () => IconTablerScale,
bottom: [
{
title: "Net Unrealized PNL",
datasetPath: `/${scale}-to-${datasetPrefix}net-unrealized-profit-and-loss`,
seriesType: SeriesType.Based,
},
],
},
{
scale,
name: `Net PNL Relative To Market Cap`,
title: `${title} Net Unrealized Profit And Loss Relative To Total Market Capitalization`,
description: "",
icon: () => IconTablerDivide,
bottom: [
{
title: "Relative Net Unrealized PNL",
datasetPath: `/${scale}-to-${datasetPrefix}net-unrealized-profit-and-loss-to-market-cap-ratio`,
seriesType: SeriesType.Based,
},
],
},
],
};
}

View File

@@ -0,0 +1,5 @@
export function datasetIdToPrefix(
datasetId: AnyPossibleCohortId,
): AnyDatasetPrefix {
return datasetId ? (`${datasetId}-` as const) : ("" as const);
}

View File

@@ -0,0 +1,35 @@
import { datasetIdToPrefix } from "./utils";
export function createCohortPresetUTXOFolder({
scale,
color,
datasetId,
title,
}: {
scale: ResourceScale;
datasetId: AnyPossibleCohortId;
title: string;
color: Color;
}): PartialPresetFolder {
const datasetPrefix = datasetIdToPrefix(datasetId);
return {
name: "UTXOs",
tree: [
{
scale,
name: `Count`,
title: `${title} Unspent Transaction Outputs Count`,
description: "",
icon: () => IconTablerTicket,
bottom: [
{
title: "Count",
color,
datasetPath: `/${scale}-to-${datasetPrefix}utxo-count`,
},
],
},
],
};
}

View File

@@ -24,13 +24,13 @@
// scale,
// id,
// title,
// datasetKey,
// datasetId,
// }: {
// datasets: Record<`${Key}${MomentumKey}`, Dataset<ResourceScale>>;
// scale: Scale;
// id: string;
// title: string;
// datasetKey: Key;
// datasetId: Key;
// }): PartialPresetFolder {
// return {
// id: `${scale}-${id}-momentum`,
@@ -50,7 +50,7 @@
// title: "Momentum",
// colors: colors.momentum,
// seriesType: SeriesType.Histogram,
// dataset: datasets[`${datasetKey}Momentum`],
// dataset: datasets[`${datasetId}Momentum`],
// options: {
// priceScaleId: PRICE_SCALE_MOMENTUM_ID,
// lastValueVisible: false,
@@ -82,7 +82,7 @@
// {
// title: "Bitcoin Returns",
// dataset:
// datasets[`${datasetKey}MomentumBLSHBitcoinReturns`],
// datasets[`${datasetId}MomentumBLSHBitcoinReturns`],
// color: colors.bitcoin,
// },
// ],
@@ -106,7 +106,7 @@
// list: [
// {
// title: "Dollar Returns",
// dataset: datasets[`${datasetKey}MomentumBLSHDollarReturns`],
// dataset: datasets[`${datasetId}MomentumBLSHDollarReturns`],
// color: colors.dollars,
// },
// ],

View File

@@ -22,7 +22,7 @@
// scale,
// id,
// title,
// datasetKey,
// datasetId,
// color,
// }: {
// datasets: Record<`${Key}${RatioKey}`, Dataset<ResourceScale>>;
@@ -30,7 +30,7 @@
// id: string;
// title: string;
// color: string;
// datasetKey: Key;
// datasetId: Key;
// }): PartialPresetFolder {
// return {
// id: `${scale}-${id}-ratio`,
@@ -52,7 +52,7 @@
// {
// title: "Ratio",
// seriesType: SeriesType.Based,
// dataset: datasets[`${datasetKey}Ratio`],
// dataset: datasets[`${datasetId}Ratio`],
// options: {
// base: 1,
// },
@@ -83,7 +83,7 @@
// title: "Ratio",
// seriesType: SeriesType.Based,
// color: colors.gray,
// dataset: datasets[`${datasetKey}Ratio`],
// dataset: datasets[`${datasetId}Ratio`],
// options: {
// base: 1,
// },
@@ -91,12 +91,12 @@
// {
// title: "7 Day Moving Average",
// color: colors.closes7DMA,
// dataset: datasets[`${datasetKey}Ratio7DayMovingAverage`],
// dataset: datasets[`${datasetId}Ratio7DayMovingAverage`],
// },
// {
// title: "1 Year Moving Average",
// color: colors.closes1YMA,
// dataset: datasets[`${datasetKey}Ratio1YearMovingAverage`],
// dataset: datasets[`${datasetId}Ratio1YearMovingAverage`],
// },
// ],
// });
@@ -108,7 +108,7 @@
// scale,
// id: `${scale}-${id}-ratio-averages`,
// title: `${title} Ratio Moving Averages`,
// datasetKey: `${datasetKey}Ratio`,
// datasetId: `${datasetId}Ratio`,
// }),
// ],
// },
@@ -135,7 +135,7 @@
// title: "Ratio",
// color: colors.white,
// seriesType: SeriesType.Based,
// dataset: datasets[`${datasetKey}Ratio`],
// dataset: datasets[`${datasetId}Ratio`],
// options: {
// base: 1,
// options: {
@@ -147,20 +147,20 @@
// {
// id: "99.9-percentile",
// title: "99.9th Percentile",
// dataset: datasets[`${datasetKey}Ratio99.9Percentile`],
// dataset: datasets[`${datasetId}Ratio99.9Percentile`],
// color: colors.extremeMax,
// },
// {
// id: "99.5-percentile",
// title: "99.5th Percentile",
// color: colors.extremeMiddle,
// dataset: datasets[`${datasetKey}Ratio99.5Percentile`],
// dataset: datasets[`${datasetId}Ratio99.5Percentile`],
// },
// {
// id: "99-percentile",
// title: "99th Percentile",
// color: colors.extremeMin,
// dataset: datasets[`${datasetKey}Ratio99Percentile`],
// dataset: datasets[`${datasetId}Ratio99Percentile`],
// },
// ],
// });
@@ -185,7 +185,7 @@
// title: "Ratio",
// color: colors.white,
// seriesType: SeriesType.Based,
// dataset: datasets[`${datasetKey}Ratio`],
// dataset: datasets[`${datasetId}Ratio`],
// options: {
// base: 1,
// options: {
@@ -198,19 +198,19 @@
// id: "1-percentile",
// title: "1st Percentile",
// color: colors.extremeMin,
// dataset: datasets[`${datasetKey}Ratio1Percentile`],
// dataset: datasets[`${datasetId}Ratio1Percentile`],
// },
// {
// id: "0.5-percentile",
// title: "0.5th Percentile",
// color: colors.extremeMiddle,
// dataset: datasets[`${datasetKey}Ratio0.5Percentile`],
// dataset: datasets[`${datasetId}Ratio0.5Percentile`],
// },
// {
// id: "0.1-percentile",
// title: "0.1th Percentile",
// color: colors.extremeMax,
// dataset: datasets[`${datasetKey}Ratio0.1Percentile`],
// dataset: datasets[`${datasetId}Ratio0.1Percentile`],
// },
// ],
// });
@@ -231,19 +231,19 @@
// id: "99.9-percentile",
// title: "99.9th Percentile",
// color: colors.extremeMax,
// dataset: datasets[`${datasetKey}Ratio99.9Price`],
// dataset: datasets[`${datasetId}Ratio99.9Price`],
// },
// {
// id: "99.5-percentile",
// title: "99.5th Percentile",
// color: colors.extremeMiddle,
// dataset: datasets[`${datasetKey}Ratio99.5Price`],
// dataset: datasets[`${datasetId}Ratio99.5Price`],
// },
// {
// id: "99-percentile",
// title: "99th Percentile",
// color: colors.extremeMin,
// dataset: datasets[`${datasetKey}Ratio99Price`],
// dataset: datasets[`${datasetId}Ratio99Price`],
// },
// ],
// });
@@ -264,19 +264,19 @@
// id: "1-percentile",
// title: "1st Percentile",
// color: colors.extremeMin,
// dataset: datasets[`${datasetKey}Ratio1Price`],
// dataset: datasets[`${datasetId}Ratio1Price`],
// },
// {
// id: "0.5-percentile",
// title: "0.5th Percentile",
// color: colors.extremeMiddle,
// dataset: datasets[`${datasetKey}Ratio0.5Price`],
// dataset: datasets[`${datasetId}Ratio0.5Price`],
// },
// {
// id: "0.1-percentile",
// title: "0.1th Percentile",
// color: colors.extremeMax,
// dataset: datasets[`${datasetKey}Ratio0.1Price`],
// dataset: datasets[`${datasetId}Ratio0.1Price`],
// },
// ],
// });

View File

@@ -1,5 +1,4 @@
import { colors } from "../../utils/colors";
import { applySeriesList } from "../apply";
export function createPresets(scale: ResourceScale) {
return {
@@ -11,28 +10,23 @@ export function createPresets(scale: ResourceScale) {
name: "Count",
title: "Transaction Count",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "1M SMA",
color: colors.momentumYellow,
dataset: params.datasets[scale].transaction_count_1m_sma,
},
{
title: "1W SMA",
color: colors.bitcoin,
dataset: params.datasets[scale].transaction_count_1w_sma,
},
{
title: "Raw",
color: colors.darkBitcoin,
dataset: params.datasets[scale].transaction_count,
},
],
});
},
bottom: [
{
title: "1M SMA",
color: colors.momentumYellow,
datasetPath: `/${scale}-to-transaction-count-1m-sma`,
},
{
title: "1W SMA",
color: colors.bitcoin,
datasetPath: `/${scale}-to-transaction-count-1w-sma`,
},
{
title: "Raw",
color: colors.darkBitcoin,
datasetPath: `/${scale}-to-transaction-count`,
},
],
},
{
@@ -44,28 +38,23 @@ export function createPresets(scale: ResourceScale) {
name: "In Bitcoin",
title: "Transaction Volume",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "1M SMA",
color: colors.momentumYellow,
dataset: params.datasets[scale].transaction_volume_1m_sma,
},
{
title: "1W SMA",
color: colors.bitcoin,
dataset: params.datasets[scale].transaction_volume_1w_sma,
},
{
title: "Raw",
color: colors.darkBitcoin,
dataset: params.datasets[scale].transaction_volume,
},
],
});
},
bottom: [
{
title: "1M SMA",
color: colors.momentumYellow,
datasetPath: `/${scale}-to-transaction-volume-1m-sma`,
},
{
title: "1W SMA",
color: colors.bitcoin,
datasetPath: `/${scale}-to-transaction-volume-1w-sma`,
},
{
title: "Raw",
color: colors.darkBitcoin,
datasetPath: `/${scale}-to-transaction-volume`,
},
],
},
{
scale,
@@ -73,36 +62,26 @@ export function createPresets(scale: ResourceScale) {
name: "In Dollars",
title: "Transaction Volume In Dollars",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
priceScaleOptions: {
mode: 1,
},
bottom: [
{
title: "1M SMA",
color: colors.lightDollars,
dataset:
params.datasets[scale]
.transaction_volume_in_dollars_1m_sma,
},
{
title: "1W SMA",
color: colors.dollars,
dataset:
params.datasets[scale]
.transaction_volume_in_dollars_1w_sma,
},
{
title: "Raw",
color: colors.darkDollars,
dataset:
params.datasets[scale].transaction_volume_in_dollars,
},
],
});
priceScaleOptions: {
mode: 1,
},
bottom: [
{
title: "1M SMA",
color: colors.lightDollars,
datasetPath: `/${scale}-to-transaction-volume-in-dollars-1m-sma`,
},
{
title: "1W SMA",
color: colors.dollars,
datasetPath: `/${scale}-to-transaction-volume-in-dollars-1w-sma`,
},
{
title: "Raw",
color: colors.darkDollars,
datasetPath: `/${scale}-to-transaction-volume-in-dollars`,
},
],
},
],
},
@@ -116,19 +95,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Bitcoin",
title: "Annualized Transaction Volume",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Volume",
color: colors.bitcoin,
dataset:
params.datasets[scale].annualized_transaction_volume,
},
],
});
},
bottom: [
{
title: "Volume",
color: colors.bitcoin,
datasetPath: `/${scale}-to-annualized-transaction-volume`,
},
],
},
{
scale,
@@ -136,20 +109,13 @@ export function createPresets(scale: ResourceScale) {
name: "In Dollars",
title: "Annualized Transaction Volume In Dollars",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Volume",
color: colors.dollars,
dataset:
params.datasets[scale]
.annualized_transaction_volume_in_dollars,
},
],
});
},
bottom: [
{
title: "Volume",
color: colors.dollars,
datasetPath: `/${scale}-to-annualized-transaction-volume-in-dollars`,
},
],
},
],
},
@@ -159,18 +125,13 @@ export function createPresets(scale: ResourceScale) {
name: "Velocity",
title: "Transactions Velocity",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "Transactions Velocity",
color: colors.bitcoin,
dataset: params.datasets[scale].transaction_velocity,
},
],
});
},
bottom: [
{
title: "Transactions Velocity",
color: colors.bitcoin,
datasetPath: `/${scale}-to-transaction-velocity`,
},
],
},
{
scale,
@@ -178,28 +139,23 @@ export function createPresets(scale: ResourceScale) {
name: "Per Second",
title: "Transactions Per Second",
description: "",
applyPreset(params) {
return applySeriesList({
...params,
bottom: [
{
title: "1M SMA",
color: colors.lightBitcoin,
dataset: params.datasets[scale].transactions_per_second_1m_sma,
},
{
title: "1W SMA",
color: colors.bitcoin,
dataset: params.datasets[scale].transactions_per_second_1w_sma,
},
{
title: "Raw",
color: colors.darkBitcoin,
dataset: params.datasets[scale].transactions_per_second,
},
],
});
},
bottom: [
{
title: "1M SMA",
color: colors.lightBitcoin,
datasetPath: `/${scale}-to-transactions-per-second-1m-sma`,
},
{
title: "1W SMA",
color: colors.bitcoin,
datasetPath: `/${scale}-to-transactions-per-second-1w-sma`,
},
{
title: "Raw",
color: colors.darkBitcoin,
datasetPath: `/${scale}-to-transactions-per-second`,
},
],
},
],
} satisfies PartialPresetFolder;

View File

@@ -1,11 +1,16 @@
interface PartialPreset {
interface PresetParams {
priceScaleOptions?: DeepPartialPriceScaleOptions;
top?: SeriesConfig[];
bottom?: SeriesConfig[];
}
type PartialPreset = {
scale: ResourceScale;
icon?: () => JSXElement;
name: string;
title: string;
applyPreset: ApplyPreset;
description: string;
}
} & PresetParams;
interface Preset extends PartialPreset {
id: string;
@@ -19,15 +24,15 @@ type FilePath = {
name: string;
}[];
type ApplyPreset = (params: {
charts: RWS<IChartApi[]>;
parentDiv: HTMLDivElement;
datasets: Datasets;
preset: Preset;
legendSetter: Setter<SeriesLegend[]>;
dark: Accessor<boolean>;
activeIds: RWS<number[]>;
}) => void;
// type ApplyPreset = (params: {
// charts: RWS<IChartApi[]>;
// parentDiv: HTMLDivElement;
// datasets: Datasets;
// preset: Preset;
// legendSetter: Setter<SeriesLegend[]>;
// dark: Accessor<boolean>;
// activeIds: RWS<number[]>;
// }) => void;
interface PartialPresetFolder {
name: string;
@@ -41,8 +46,6 @@ interface PresetFolder extends PartialPresetFolder {
type PartialPresetTree = (PartialPreset | PartialPresetFolder)[];
type PresetTree = (Preset | PresetFolder)[];
// type PresetList = Preset[];
// type FavoritePresets = Accessor<Preset[]>;
type PresetsHistory = { date: Date; preset: Preset }[];
type PresetsHistorySignal = RWS<PresetsHistory>;
@@ -70,3 +73,53 @@ interface ChartObject {
legendList: SeriesLegend[];
debouncedSetMinMaxMarkers: VoidFunction;
}
type EnumSeriesType = typeof import("./enums").SeriesType;
type SeriesConfig =
| {
// datasetPath: DatasetPath<Scale>;
datasetPath: AnyDatasetPath;
color?: Color;
topColor?: Color;
bottomColor?: Color;
colors?: undefined;
seriesType: EnumSeriesType["Based"];
title: string;
options?: BaselineSeriesOptions;
priceScaleOptions?: DeepPartialPriceScaleOptions;
defaultVisible?: boolean;
}
| {
// datasetPath: DatasetPath<Scale>;
datasetPath: AnyDatasetPath;
color?: Color;
colors?: Color[];
seriesType: EnumSeriesType["Histogram"];
title: string;
options?: DeepPartialHistogramOptions;
priceScaleOptions?: DeepPartialPriceScaleOptions;
defaultVisible?: boolean;
}
| {
// datasetPath: DatasetPath<Scale>;
datasetPath: AnyDatasetPath;
seriesType: EnumSeriesType["Candlestick"];
priceScaleOptions?: DeepPartialPriceScaleOptions;
colors?: undefined;
color?: undefined;
options?: DeepPartialLineOptions;
defaultVisible?: boolean;
title: string;
}
| {
// datasetPath: DatasetPath<Scale>;
datasetPath: AnyDatasetPath;
color: Color;
colors?: undefined;
seriesType?: EnumSeriesType["Line"];
title: string;
options?: DeepPartialLineOptions;
priceScaleOptions?: DeepPartialPriceScaleOptions;
defaultVisible?: boolean;
};

View File

@@ -4,3 +4,10 @@ export const dateToString = (date: Date) => date.toJSON().split("T")[0];
export const getNumberOfDaysBetweenTwoDates = (oldest: Date, youngest: Date) =>
Math.round(Math.abs((youngest.getTime() - oldest.getTime()) / ONE_DAY_IN_MS));
export function dateFromTime(time: Time) {
return typeof time === "string"
? new Date(time)
: // @ts-ignore
new Date(time.year, time.month, time.day);
}