From a01060ba62885c5fe6c0d45bb2da4ecd61b1261e Mon Sep 17 00:00:00 2001 From: wireless_purple Date: Fri, 13 Sep 2024 20:55:38 +0000 Subject: [PATCH] implement /markets --- bun.lockb | Bin 50698 -> 61842 bytes package.json | 12 +- src/routes/+page.svelte | 122 +++++++++++---------- src/routes/market/[market]/+page.svelte | 62 ++++++----- src/routes/markets/+page.server.js | 6 + src/routes/markets/+page.svelte | 140 +++++++++++++++++++++++- src/routes/trades/+page.svelte | 1 - 7 files changed, 248 insertions(+), 95 deletions(-) create mode 100644 src/routes/markets/+page.server.js delete mode 100644 src/routes/trades/+page.svelte diff --git a/bun.lockb b/bun.lockb index 53fc12bb9c9f39cf2ba4b7ff5ab9cf061fe2a3d8..503c6a17e6ba3430192269294edef85e7ece54f1 100755 GIT binary patch delta 14838 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 CWt0*C delta 9418 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 currency); let interval = $state("86400000"); let key = $state("USD"); -let trades = $derived((() => { - let trades = grouped[key] - .map((e) => { - return { - time: new Date(e.date), - value: getPrice(e.price, e.currency), - }; - }) - .toSorted((a, b) => (a.time - b.time)); - - trades = Object.groupBy( - trades, - ({ time }) => new Date(time - (time % interval)) / 1000, - ); - - for (const intervalDate in trades) { - trades[intervalDate] = trades[intervalDate].reduce((a, c) => { - return { - open: a.open ?? c.value, - close: c.value, - high: (c.value > a.high ? c.value : a.high) ?? c.value, - low: (c.value < a.low ? c.value : a.low) ?? c.value, - }; - }, {}); - trades[intervalDate].time = Number.parseInt(intervalDate, 10); - } - return Object.values(trades); -})()); -let [volume, swaps] = $derived((() => { - let volume = Object.groupBy( - data.trades +let trades = $derived( + (() => { + let trades = grouped[key] .map((e) => { return { - volume: e.xmrAmount, - time: e.date, + time: new Date(e.date), + value: getPrice(e.price, e.currency), }; }) - .toSorted((a, b) => (a.time - b.time)), - ({ time }) => new Date(time - (time % interval)) / 1000, - ); - let swaps = {}; - for (const intervalDate in volume) { - swaps[intervalDate] = volume[intervalDate].reduce( - (a) => { - return { - value: a.value + 1, - }; - }, - { value: 0 }, + .toSorted((a, b) => a.time - b.time); + + trades = Object.groupBy( + trades, + ({ time }) => new Date(time - (time % interval)) / 1000, ); - volume[intervalDate] = volume[intervalDate].reduce( - (a, c) => { + for (const intervalDate in trades) { + trades[intervalDate] = trades[intervalDate].reduce((a, c) => { return { - value: a.value + c.volume / 10 ** 12, + open: a.open ?? c.value, + close: c.value, + high: (c.value > a.high ? c.value : a.high) ?? c.value, + low: (c.value < a.low ? c.value : a.low) ?? c.value, }; - }, - { value: 0 }, + }, {}); + trades[intervalDate].time = Number.parseInt(intervalDate, 10); + } + return Object.values(trades); + })(), +); +let [volume, swaps] = $derived( + (() => { + let volume = Object.groupBy( + data.trades + .map((e) => { + return { + volume: e.xmrAmount, + time: e.date, + }; + }) + .toSorted((a, b) => a.time - b.time), + ({ time }) => new Date(time - (time % interval)) / 1000, ); + let swaps = {}; + for (const intervalDate in volume) { + swaps[intervalDate] = volume[intervalDate].reduce( + (a) => { + return { + value: a.value + 1, + }; + }, + { value: 0 }, + ); - volume[intervalDate].time = Number.parseInt(intervalDate, 10); - swaps[intervalDate].time = Number.parseInt(intervalDate, 10); - } - return [Object.values(volume), Object.values(swaps)]; -})()); -let precision = $derived(getSignificantDigits(trades.flatMap((e) => [e.open, e.close]))); + volume[intervalDate] = volume[intervalDate].reduce( + (a, c) => { + return { + value: a.value + c.volume / 10 ** 12, + }; + }, + { value: 0 }, + ); + + volume[intervalDate].time = Number.parseInt(intervalDate, 10); + swaps[intervalDate].time = Number.parseInt(intervalDate, 10); + } + return [Object.values(volume), Object.values(swaps)]; + })(), +); +let precision = $derived( + getSignificantDigits(trades.flatMap((e) => [e.open, e.close])), +); const chartLayout = { background: { @@ -188,6 +194,6 @@ let w = $state(); {/each} -

View more »

+

View more »

\ No newline at end of file diff --git a/src/routes/market/[market]/+page.svelte b/src/routes/market/[market]/+page.svelte index 003f00c..e67aeb1 100644 --- a/src/routes/market/[market]/+page.svelte +++ b/src/routes/market/[market]/+page.svelte @@ -10,38 +10,42 @@ import { import { CandlestickSeries, Chart, TimeScale } from "svelte-lightweight-charts"; const market = $page.params.market; -let {data} = $props(); +let { data } = $props(); const interval = 86400000; -let trades = $derived((() => { - let trades = data.trades - .map((e) => { - return { - time: new Date(e.date), - value: getPrice(e.price, e.currency, false, false), - }; - }) - .toSorted((a, b) => (a.time - b.time)); +let trades = $derived( + (() => { + let trades = data.trades + .map((e) => { + return { + time: new Date(e.date), + value: getPrice(e.price, e.currency, false, false), + }; + }) + .toSorted((a, b) => a.time - b.time); - trades = Object.groupBy( - trades, - ({ time }) => new Date(time - (time % interval)) / 1000, - ); + trades = Object.groupBy( + trades, + ({ time }) => new Date(time - (time % interval)) / 1000, + ); - for (const intervalDate in trades) { - trades[intervalDate] = trades[intervalDate].reduce((a, c) => { - return { - open: a.open ?? c.value, - close: c.value, - high: (c.value > a.high ? c.value : a.high) ?? c.value, - low: (c.value < a.low ? c.value : a.low) ?? c.value, - }; - }, {}); - trades[intervalDate].time = Number.parseInt(intervalDate, 10); - } - return Object.values(trades); -})()); + for (const intervalDate in trades) { + trades[intervalDate] = trades[intervalDate].reduce((a, c) => { + return { + open: a.open ?? c.value, + close: c.value, + high: (c.value > a.high ? c.value : a.high) ?? c.value, + low: (c.value < a.low ? c.value : a.low) ?? c.value, + }; + }, {}); + trades[intervalDate].time = Number.parseInt(intervalDate, 10); + } + return Object.values(trades); + })(), +); -let precision = $derived(getSignificantDigits(trades.flatMap((e) => [e.open, e.close]))); +let precision = $derived( + getSignificantDigits(trades.flatMap((e) => [e.open, e.close])), +); let w = $state(); const chartLayout = { @@ -117,7 +121,7 @@ const BUY_SELL = isMoneroQuote(market) ? ["SELL", "BUY"] : ["BUY", "SELL"];
-

Last Trades

+

Latest Trades

diff --git a/src/routes/markets/+page.server.js b/src/routes/markets/+page.server.js new file mode 100644 index 0000000..a86a2b6 --- /dev/null +++ b/src/routes/markets/+page.server.js @@ -0,0 +1,6 @@ +import { trades } from "$lib/server/context"; +import { get } from "svelte/store"; + +export function load() { + return { trades: get(trades) }; +} diff --git a/src/routes/markets/+page.svelte b/src/routes/markets/+page.svelte index b9c4d8d..15f077a 100644 --- a/src/routes/markets/+page.svelte +++ b/src/routes/markets/+page.svelte @@ -1 +1,139 @@ -Under construction \ No newline at end of file + + + + + Markets - Haveno Markets + + +
+
+

+ Volume

+ + + + + + + + + +
+
+
+
+

Markets

+
+ + + + + + + + {#each Object.values(Object.groupBy(data.trades, ({currency}) => currency)).toSorted((a,b) => b.length - a.length || (b[0].currency < a[0].currency ? 1 : -1)).slice(0, 16) as market} + + + + + + + {/each} + +
CurrencyPriceVolume (XMR)Trades
{getAsset(market[0].currency).name} ({market[0].currency}){formatPrice(market[0].price, market[0].currency, true, false)}{formatPrice(market.reduce((a,b) => a + b.xmrAmount, 0), "XMR", false, false)}{market.length}
+
+
+
+
+

Latest Trades

+ + + + + + + + + {#each data.trades.slice(0, 64) as trade} + + + + + + + {/each} + +
DatePriceAmount (XMR)Amount
{new Date(trade.date).toISOString().replace("T", " ").replace(/\.\d*Z/, "")}{formatPrice(trade.price, trade.currency, true, false)}{formatPrice(trade.xmrAmount, "XMR", false, false)}{formatPrice(trade.amount, trade.currency, false, false)} {trade.currency}
+
+
\ No newline at end of file diff --git a/src/routes/trades/+page.svelte b/src/routes/trades/+page.svelte deleted file mode 100644 index b9c4d8d..0000000 --- a/src/routes/trades/+page.svelte +++ /dev/null @@ -1 +0,0 @@ -Under construction \ No newline at end of file