From b0bc5f261c9be74057df567a6f7975c5ebdf049c Mon Sep 17 00:00:00 2001 From: MuslemRahimi Date: Fri, 21 Jun 2024 21:15:51 +0200 Subject: [PATCH] Add market maker component --- src/lib/components/MarketMaker.svelte | 155 ++++++++++++++++++++------ 1 file changed, 122 insertions(+), 33 deletions(-) diff --git a/src/lib/components/MarketMaker.svelte b/src/lib/components/MarketMaker.svelte index d9826f68..aff8d78b 100644 --- a/src/lib/components/MarketMaker.svelte +++ b/src/lib/components/MarketMaker.svelte @@ -2,7 +2,7 @@ import { marketMakerComponent, displayCompanyName, stockTicker, assetType, etfTicker, screenWidth, userRegion, getCache, setCache} from '$lib/store'; import InfoModal from '$lib/components/InfoModal.svelte'; import { Chart } from 'svelte-echarts' - import { abbreviateNumber } from "$lib/utils"; + import { abbreviateNumber, formatString } from "$lib/utils"; import Lazy from 'svelte-lazy'; export let data; @@ -27,8 +27,25 @@ let historyData = []; let topMarketMakers = []; let optionsData; - let avgVolume; - let avgShortVolume; + let avgTradeCount; + let avgShareQuantity; + let avgNotionalSum; + let showFullStats = false; + +function formatDateRange(lastDateStr) { + // Convert lastDateStr to Date object + const lastDate = new Date(lastDateStr); + + // Get today's date for the first date (assuming today is the last date in your original logic) + const firstDate = new Date(lastDate.getTime() - 7 * 24 * 60 * 60 * 1000); + + // Format first and last dates + const firstDateFormatted = firstDate.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', day: '2-digit' }); + const lastDateFormatted = lastDate.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', day: '2-digit' }); + + // Construct and return the formatted date range string + return `${firstDateFormatted} - ${lastDateFormatted}`; +} function normalizer(value) { if (Math?.abs(value) >= 1e18) { @@ -61,8 +78,20 @@ function getPlotOptions() { notionalSumList?.push(item?.totalNotionalSum) }); - console.log(tradeCountList) + + // Compute the average of item?.traded + const totalTraded = tradeCountList?.reduce((acc, traded) => acc + traded, 0); + avgTradeCount = totalTraded / tradeCountList?.length; + + const totalShare = shareQuantityList?.reduce((acc, item) => acc + item, 0); + avgShareQuantity = totalShare / shareQuantityList?.length; + + const totalSum = notionalSumList?.reduce((acc, sentiment) => acc + sentiment, 0); + avgNotionalSum = totalSum / notionalSumList?.length; + + const {unit, denominator } = normalizer(Math.max(...notionalSumList) ?? 0) + const { unit: shareUnit, denominator: shareDenominator } = normalizer(Math.max(...shareQuantityList) ?? 0); const option = { silent: true, @@ -74,11 +103,11 @@ function getPlotOptions() { top: '5%', containLabel: true }, - xAxis: { + xAxis: + { type: 'category', boundaryGap: false, data: dates, - }, yAxis: [ { @@ -92,7 +121,7 @@ function getPlotOptions() { // Display every second tick if (index % 2 === 0) { value = Math.max(value, 0); - return (value / denominator)?.toFixed(1) + unit; // Format value in millions + return '$'+(value / denominator)?.toFixed(1) + unit; // Format value in millions } else { return ''; // Hide this tick } @@ -104,12 +133,11 @@ function getPlotOptions() { splitLine: { show: false, // Disable x-axis grid lines }, - name: 'Sentiment', position: 'right', axisLabel: { formatter: function (value, index) { if (index % 2 === 0) { - return value.toFixed(2); // Format the sentiment value + return (value / shareDenominator)?.toFixed(1) + shareUnit; // Format value in millions } else { return ''; // Hide this tick } @@ -127,22 +155,13 @@ function getPlotOptions() { showSymbol: false }, { - data: tradeCountList, - type: 'bar', - yAxisIndex: 1, - itemStyle: { - color: '#9DED1E' // Change bar color to white - }, - showSymbol: false - }, - { - data: shareQuantityList, type: 'bar', yAxisIndex: 1, itemStyle: { color: '#536FC5' // Change bar color to white }, + barWidth: "40%", showSymbol: false }, ] @@ -185,6 +204,7 @@ const getMarketMaker = async (ticker) => { $: { if($assetType === 'stock' ? $stockTicker :$etfTicker && typeof window !== 'undefined') { isLoaded=false; + showFullStats = false; const ticker = $assetType === 'stock' ? $stockTicker :$etfTicker const asyncFunctions = [ getMarketMaker(ticker) @@ -203,6 +223,20 @@ $: { } } +let charNumber = 20; + +$: { + if($screenWidth < 640) + { + charNumber = 20; + } + else { + charNumber =40; + } +} + + + @@ -229,10 +263,11 @@ $: {
- Over the past 12 months, {$displayCompanyName} has experienced an average dark pool trading volume of - 12 shares. - Out of this total, an average of 12 shares, - constituting approximately 12%, were short volume. + Over the past year, {$displayCompanyName} has seen a weekly average of + {abbreviateNumber(avgTradeCount)} trades, involving an average of + {abbreviateNumber(avgShareQuantity)} shares bought and sold. + This activity sums up to an average total notional value of + {abbreviateNumber(avgNotionalSum,true)}.
@@ -252,26 +287,25 @@ $: { - Total Volume + Notional Sum
- Short Volume + Share Quantity
-

Latest Information

- + + +

+ Top 10 Market Makers Activity +

+ These market makers represent the highest average trading activity for {$displayCompanyName} over the past 12 months, calculated on a weekly basis. + +
+ + + + + + + + + + + {#each (showFullStats ? topMarketMakers?.slice(0,10) : topMarketMakers?.slice(0,3)) as item,index} + + + + + + + + + + + {/each} + +
NameTrade CountShare QuantityNotional Sum
+ {item?.name?.length > charNumber ? formatString(item?.name?.slice(0,charNumber)) + "..." : formatString(item?.name)} + + {abbreviateNumber(item?.avgWeeklyTradeCount)} + + {abbreviateNumber(item?.avgWeeklyShareQuantity)} + + {abbreviateNumber(item?.avgNotionalSum, true)} +
+ + +
+ + + {/if}