From 96887705ea02336c2ba0304e0c20a344d80f58f2 Mon Sep 17 00:00:00 2001 From: MuslemRahimi Date: Mon, 31 Mar 2025 10:47:02 +0200 Subject: [PATCH] ui fixes --- src/lib/components/FailToDeliver.svelte | 56 ++- src/lib/components/ShareHolders.svelte | 6 +- .../stocks/[tickerID]/insider/+page.server.ts | 13 +- .../stocks/[tickerID]/insider/+page.svelte | 369 +----------------- .../insider/congress-trading/+page.svelte | 129 +----- .../[tickerID]/insider/institute/+page.svelte | 2 +- .../statistics/fail-to-deliver/+layout.svelte | 3 +- .../statistics/fail-to-deliver/+page.svelte | 6 +- 8 files changed, 65 insertions(+), 519 deletions(-) diff --git a/src/lib/components/FailToDeliver.svelte b/src/lib/components/FailToDeliver.svelte index d2bf251b..a8be5132 100644 --- a/src/lib/components/FailToDeliver.svelte +++ b/src/lib/components/FailToDeliver.svelte @@ -21,23 +21,24 @@ let activeIdx = 0; const tabs = [ { - title: "Daily", + title: "Monthly", }, { title: "Quarterly", }, ]; - let tableList = rawData?.sort( - (a, b) => new Date(b?.date) - new Date(a?.date), - ); - + let tableList; function changeTimePeriod(i) { activeIdx = i; tableList = rawData?.sort((a, b) => new Date(b?.date) - new Date(a?.date)); if (activeIdx === 1) { + // Quarterly filter as before tableList = filterByPeriod([...tableList]); + } else if (activeIdx === 0) { + // New monthly filter: one result per month at the beginning of each month + tableList = filterByMonth([...tableList]); } } @@ -59,7 +60,25 @@ }); } - function getPlotOptions() { + function filterByMonth(data) { + if (!Array.isArray(data) || data.length === 0) return []; + + // Monthly: one result per month. + const seenMonths = new Set(); + return data.filter((item) => { + const dt = new Date(item.date); + const year = dt.getFullYear(); + const month = dt.getMonth(); // Month as a number (0-11) + const key = `${year}-${month}`; + if (!seenMonths.has(key)) { + seenMonths.add(key); + return true; + } + return false; + }); + } + + function plotData() { let dates = []; let priceList = []; let failToDeliverList = []; @@ -149,7 +168,7 @@ labels: { style: { color: $mode === "light" ? "black" : "white" }, - distance: 20, // Increases space between label and axis + distance: 10, // Increases space between label and axis formatter: function () { return new Date(this.value).toLocaleDateString("en-US", { day: "2-digit", // Include day number @@ -233,7 +252,8 @@ data?.getStockQuote?.avgVolume) * 100 )?.toFixed(2); - config = getPlotOptions(); + config = plotData(); + changeTimePeriod(0); } } } @@ -323,10 +343,18 @@ > - Date - Price - FTD Shares - % Change + Date + Price + FTD Shares + % Change @@ -359,7 +387,7 @@ {#if index === tableList?.length - 1} n/a {:else if item?.failToDeliver > tableList[index + 1]?.failToDeliver} - + +{( ((item?.failToDeliver - tableList[index + 1]?.failToDeliver) / @@ -368,7 +396,7 @@ )?.toFixed(2)}% {:else if item?.failToDeliver < tableList[index + 1]?.failToDeliver} - + -{( Math.abs( (item?.failToDeliver - diff --git a/src/lib/components/ShareHolders.svelte b/src/lib/components/ShareHolders.svelte index b39f1895..fdb1b5c2 100644 --- a/src/lib/components/ShareHolders.svelte +++ b/src/lib/components/ShareHolders.svelte @@ -291,7 +291,7 @@

@@ -558,13 +558,13 @@ class=" text-end text-sm sm:text-[1rem] whitespace-nowrap" > {#if item?.changeInSharesNumberPercentage >= 0} - +{abbreviateNumber( item?.changeInSharesNumberPercentage?.toFixed(2), )}% {:else if item?.changeInSharesNumberPercentage < 0} - {abbreviateNumber( item?.changeInSharesNumberPercentage?.toFixed(2), )}% { if (item.acquistionOrDisposition === "D") { - return "Sold"; + return "Sale"; } else if (item.acquistionOrDisposition === "A") { return "Bought"; } else { @@ -46,15 +46,15 @@ export const load = async ({ locals, params }) => { let output = await response.json(); output = user?.tier !== "Pro" ? output?.slice(0, 6) : output; - + output = output?.reduce((acc, item) => { const newTransactionType = typeof transactionTypeMap[item?.transactionType] === "function" ? transactionTypeMap[item?.transactionType](item) : transactionTypeMap[item?.transactionType]; - // Only include items with 'Bought' or 'Sold' - if (newTransactionType === "Bought" || newTransactionType === "Sold") { + // Only include items with 'Bought' or 'Sale' + if (newTransactionType === "Bought" || newTransactionType === "Sale") { const value = item?.securitiesTransacted * item?.price; if (value > 0) { acc.push({ @@ -67,6 +67,7 @@ export const load = async ({ locals, params }) => { return acc; }, []); + return output; }; diff --git a/src/routes/stocks/[tickerID]/insider/+page.svelte b/src/routes/stocks/[tickerID]/insider/+page.svelte index 94ca9ef5..481024fc 100644 --- a/src/routes/stocks/[tickerID]/insider/+page.svelte +++ b/src/routes/stocks/[tickerID]/insider/+page.svelte @@ -3,8 +3,7 @@ import { formatString, abbreviateNumber } from "$lib/utils"; import UpgradeToPro from "$lib/components/UpgradeToPro.svelte"; import { onMount } from "svelte"; - import * as DropdownMenu from "$lib/components/shadcn/dropdown-menu/index.js"; - import { Button } from "$lib/components/shadcn/button/index.js"; + import TableHeader from "$lib/components/Table/TableHeader.svelte"; import SEO from "$lib/components/SEO.svelte"; import Infobox from "$lib/components/Infobox.svelte"; @@ -23,65 +22,6 @@ }); } - let statistics = {}; - let buySellRatio = 0; - const now = new Date(); - let year = now.getFullYear(); - let quarter = Math.floor(now.getMonth() / 3) + 1; - let yearRange = Array.from( - new Set( - rawData?.map((item) => new Date(item?.transactionDate)?.getFullYear()), - ), - )?.sort((a, b) => b - a); - if (yearRange?.length > 0) { - year = yearRange?.slice(0)?.at(0); - } - - function calculateInsiderTradingStatistics(data, year, quarter) { - // Helper function to check if the transaction date is within the current quarter - const isInCurrentQuarter = (transactionDate) => { - const date = new Date(transactionDate); - return ( - date.getFullYear() === year && - Math.floor(date.getMonth() / 3) + 1 === quarter - ); - }; - - // Initialize statistics object - let statistics = { - soldShares: 0, - buyShares: 0, - buySharesPercentage: 0, - soldSharesPercentage: 0, - quarter: quarter, - year: year, - }; - - // Summing up bought and sold shares efficiently in a single loop - data.forEach( - ({ transactionType, securitiesTransacted, price, transactionDate }) => { - if (price > 0 && isInCurrentQuarter(transactionDate)) { - if (transactionType === "Sold") { - statistics.soldShares += securitiesTransacted; - } else if (transactionType === "Bought") { - statistics.buyShares += securitiesTransacted; - } - } - }, - ); - - const totalShares = statistics.buyShares + statistics.soldShares; - - if (totalShares > 0) { - statistics.buySharesPercentage = Math.floor( - (statistics.buyShares / totalShares) * 100, - ); - statistics.soldSharesPercentage = 100 - statistics.buySharesPercentage; - } - - return statistics; - } - function extractOfficeInfo(inputString) { const indexOfficer = inputString?.toLowerCase()?.indexOf("officer:"); const indexOther = inputString?.toLowerCase()?.indexOf("other:"); @@ -115,14 +55,6 @@ }; }); - const transactionStyles = { - Bought: "P - Purchase", - Grant: "G - Grant", - Sold: "S - Sale", - Exercise: "E - Exercise", - "n/a": { text: "n/a", class: "text-gray-300" }, - }; - let columns = [ { key: "reportingName", label: "Name", align: "left" }, { key: "transactionDate", label: "Date", align: "right" }, @@ -198,16 +130,6 @@ // Sort using the generic comparison function insiderTradingList = [...originalData].sort(compareValues)?.slice(0, 50); }; - - $: { - if ((year || quarter) && typeof window !== "undefined") { - statistics = calculateInsiderTradingStatistics(rawData, year, quarter); - buySellRatio = - statistics?.soldShares !== 0 - ? statistics?.buyShares / statistics?.soldShares - : 0; - } - } -
- - - - - - - Select Year - - - - {#each yearRange as index} - (year = index)} - class="cursor-pointer sm:hover:bg-gray-300 dark:sm:hover:bg-primary" - > - {index} - - {/each} - - - -
-
- - - - - - - Select Quarter - - - - {#each [1, 2, 3, 4] as index} - (quarter = index)} - class="cursor-pointer sm:hover:bg-gray-300 dark:sm:hover:bg-primary" - > - Q{index} - - {/each} - - - -
- - -

- Q{statistics?.quarter} - {statistics?.year} Insider Statistics -

- -
-
- -
-
- Buy/Sell - - {buySellRatio > 0 - ? buySellRatio?.toFixed(1) - : buySellRatio} - -
- -
- - - - - - = 1 - ? 0 - : 100 - (buySellRatio * 100)?.toFixed(2)} - > - - - -
- {(buySellRatio * 100)?.toFixed(0)}% -
-
- -
- - -
-
- Bought Shares - - {new Intl.NumberFormat("en", { - minimumFractionDigits: 0, - maximumFractionDigits: 0, - }).format(statistics?.buyShares)} - -
- -
- - - - - - - - - -
- {statistics?.buySharesPercentage}% -
-
- -
- - -
-
- Sold Shares - - {new Intl.NumberFormat("en", { - minimumFractionDigits: 0, - maximumFractionDigits: 0, - }).format(statistics?.soldShares)} - -
- -
- - - - - - - - - -
- {statistics?.soldSharesPercentage}% -
-
- -
- -
-
- - {/if} -
- {@html abbreviateNumber( - item?.securitiesTransacted, - false, - true, - )} + {item?.securitiesTransacted?.toLocaleString("en-US")} diff --git a/src/routes/stocks/[tickerID]/insider/congress-trading/+page.svelte b/src/routes/stocks/[tickerID]/insider/congress-trading/+page.svelte index 9ea6fbe3..ba538bb2 100644 --- a/src/routes/stocks/[tickerID]/insider/congress-trading/+page.svelte +++ b/src/routes/stocks/[tickerID]/insider/congress-trading/+page.svelte @@ -188,131 +188,6 @@

Congress Trading

{#if senateTradingList?.length !== 0} - -
-
- -
-
- Buy/Sell - - {buySellRatio?.toFixed(3)} - -
- -
- - - - - - = 0 - ? 100 - (buySellRatio * 100)?.toFixed(2) - : 0} - > - - - -
- {buySellRatio?.toFixed(2)} -
-
- -
- - -
-
- Dem/Rep - - {partyRatio?.toFixed(3)} - -
- -
- - - - - - = 0 - ? 100 - (partyRatio * 100)?.toFixed(2) - : 0} - > - - - -
- {partyRatio?.toFixed(2)} -
-
- -
- -
-
- -
@@ -393,11 +268,11 @@ class="text-end text-sm sm:text-[1rem] whitespace-nowrap" > {#if item?.type === "Bought"} - Bought {:else if item?.type === "Sold"} - Sold {:else if item?.type === "Exchange"} diff --git a/src/routes/stocks/[tickerID]/insider/institute/+page.svelte b/src/routes/stocks/[tickerID]/insider/institute/+page.svelte index 249dfee9..e96ede0c 100644 --- a/src/routes/stocks/[tickerID]/insider/institute/+page.svelte +++ b/src/routes/stocks/[tickerID]/insider/institute/+page.svelte @@ -17,7 +17,7 @@
-
+

13F Institute Ownership

diff --git a/src/routes/stocks/[tickerID]/statistics/fail-to-deliver/+layout.svelte b/src/routes/stocks/[tickerID]/statistics/fail-to-deliver/+layout.svelte index a32f418f..712982e3 100644 --- a/src/routes/stocks/[tickerID]/statistics/fail-to-deliver/+layout.svelte +++ b/src/routes/stocks/[tickerID]/statistics/fail-to-deliver/+layout.svelte @@ -1,6 +1,5 @@
- {@html abbreviateNumber(item?.value, false, true)} + ${abbreviateNumber(item?.value)}
- {transactionStyles[item?.transactionType]} + {item?.transactionType}