diff --git a/src/lib/components/TickerInfoCard.svelte b/src/lib/components/TickerInfoCard.svelte index c6bff573..ca5e4ac9 100644 --- a/src/lib/components/TickerInfoCard.svelte +++ b/src/lib/components/TickerInfoCard.svelte @@ -90,7 +90,7 @@ $: {
{#if earningDate} -
+
Earnings Call - {earningDate}
{/if} diff --git a/src/routes/most-shorted-stocks/+page.svelte b/src/routes/most-shorted-stocks/+page.svelte index ac7e4071..4b9e775f 100644 --- a/src/routes/most-shorted-stocks/+page.svelte +++ b/src/routes/most-shorted-stocks/+page.svelte @@ -5,6 +5,7 @@ import { onMount } from 'svelte'; import UpgradeToPro from '$lib/components/UpgradeToPro.svelte'; import ArrowLogo from "lucide-svelte/icons/move-up-right"; + import TableHeader from "$lib/components/Table/TableHeader.svelte"; export let data; @@ -37,7 +38,85 @@ async function handleScroll() { }; }) - + let columns = [ + {key: "rank", label: "#", align: "right"}, + { key: "symbol", label: "Symbol", align: "left" }, + { key: "name", label: "Name", align: "left" }, + { key: "shortRatio", label: "Short Ratio", align: "right" }, + { key: "sharesShort", label: "Short Interest", align: "right" }, + { key: "shortFloatPercent", label: "Short % Float", align: "right" }, + { key: "shortOutStandingPercent", label: "Short % of Shares Out", align: "right" }, + ]; + + let sortOrders = { + rank: { order: "none", type: "number" }, + symbol: { order: "none", type: "string" }, + name: { order: "none", type: "string" }, + shortRatio: { order: "none", type: "number" }, + sharesShort: { order: "none", type: "number" }, + shortFloatPercent: { order: "none", type: "number" }, + shortOutStandingPercent: { order: "none", type: "number" }, + }; + + + const sortData = (key) => { + // Reset all other keys to 'none' except the current key + for (const k in sortOrders) { + if (k !== key) { + sortOrders[k].order = "none"; + } + } + + // Cycle through 'none', 'asc', 'desc' for the clicked key + const orderCycle = ["none", "asc", "desc"]; + + let originalData = rawData; + + const currentOrderIndex = orderCycle.indexOf(sortOrders[key].order); + sortOrders[key].order = + orderCycle[(currentOrderIndex + 1) % orderCycle.length]; + const sortOrder = sortOrders[key].order; + + // Reset to original data when 'none' and stop further sorting + if (sortOrder === "none") { + stockList = [...originalData]; // Reset to original data (spread to avoid mutation) + return; + } + + // Define a generic comparison function + const compareValues = (a, b) => { + const { type } = sortOrders[key]; + let valueA, valueB; + + switch (type) { + case "date": + valueA = new Date(a[key]); + valueB = new Date(b[key]); + break; + case "string": + valueA = a[key].toUpperCase(); + valueB = b[key].toUpperCase(); + return sortOrder === "asc" + ? valueA.localeCompare(valueB) + : valueB.localeCompare(valueA); + case "number": + default: + valueA = parseFloat(a[key]); + valueB = parseFloat(b[key]); + break; + } + + if (sortOrder === "asc") { + return valueA < valueB ? -1 : valueA > valueB ? 1 : 0; + } else { + return valueA > valueB ? -1 : valueA < valueB ? 1 : 0; + } + }; + + // Sort using the generic comparison function + stockList = [...originalData].sort(compareValues); + }; + $: charNumber = $screenWidth < 640 ? 15 : 20; @@ -137,37 +216,14 @@ async function handleScroll() {
- - - - - - - - - - + {#each stockList as item, index} goto(`/stocks/${item?.symbol}`)} class="border-b border-[#27272A] sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] odd:bg-[#27272A] {index+1 === stockList?.length && data?.user?.tier !== 'Pro' ? 'opacity-[0.1]' : ''}">
- # - - Symbol - - Name - - Short Ratio - - Short Interest - - Short % Float - - Short % of Shares Out -
- {index+1} + {item?.rank} diff --git a/src/routes/stock-screener/+page.svelte b/src/routes/stock-screener/+page.svelte index 997cb072..b56738a2 100644 --- a/src/routes/stock-screener/+page.svelte +++ b/src/routes/stock-screener/+page.svelte @@ -354,6 +354,27 @@ defaultCondition: "over", defaultValue: "any", }, + epsGrowthYears: { + label: "EPS Growth Years", + step: ["10", "5", "3", "1"], + category: "fund", + defaultCondition: "over", + defaultValue: "any", + }, + netIncomeGrowthYears: { + label: "Net Income Growth Years", + step: ["10", "5", "3", "1"], + category: "fund", + defaultCondition: "over", + defaultValue: "any", + }, + grossProfitGrowthYears: { + label: "Gross Profit Growth Years", + step: ["10", "5", "3", "1"], + category: "fund", + defaultCondition: "over", + defaultValue: "any", + }, growthRevenue: { label: "Revenue Growth", step: ["200%", "100%", "50%", "20%", "10%", "5%", "1%"],