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}
-
-
-
-
-
-
-
- {(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}
-