diff --git a/src/lib/images/hedge_funds/0001037389.png b/src/lib/images/hedge_funds/0001037389.png new file mode 100644 index 00000000..a4c3adfa Binary files /dev/null and b/src/lib/images/hedge_funds/0001037389.png differ diff --git a/src/routes/hedge-funds/[slug]/+page.svelte b/src/routes/hedge-funds/[slug]/+page.svelte index 683e1917..b68f784f 100644 --- a/src/routes/hedge-funds/[slug]/+page.svelte +++ b/src/routes/hedge-funds/[slug]/+page.svelte @@ -3,6 +3,7 @@ import { screenWidth, numberOfUnreadNotification, displayCompanyName } from '$lib/store'; import cardBackground from "$lib/images/bg-hedge-funds.png"; import defaultAvatar from "$lib/images/hedge_funds/default-avatar.png"; + import UpgradeToPro from '$lib/components/UpgradeToPro.svelte'; import { abbreviateNumber, formatString } from '$lib/utils'; import InfiniteLoading from '$lib/components/InfiniteLoading.svelte'; @@ -28,8 +29,90 @@ let numOfAssets; let changeAssetType = 'Share' + const spyData = [{'date': '1993-03-31', 'price': 25.59}, {'date': '1993-06-30', 'price': 25.7}, {'date': '1993-09-30', 'price': 26.36}, {'date': '1993-12-31', 'price': 26.92}, {'date': '1994-03-31', 'price': 25.91}, {'date': '1994-06-30', 'price': 26.01}, {'date': '1994-09-30', 'price': 27.17}, {'date': '1994-12-31', 'price': 27.03}, {'date': '1995-03-31', 'price': 29.89}, {'date': '1995-06-30', 'price': 32.64}, {'date': '1995-09-30', 'price': 35.27}, {'date': '1995-12-31', 'price': 37.31}, {'date': '1996-03-31', 'price': 39.43}, {'date': '1996-06-30', 'price': 41.12}, {'date': '1996-09-30', 'price': 42.27}, {'date': '1996-12-31', 'price': 45.71}, {'date': '1997-03-31', 'price': 46.83}, {'date': '1997-06-30', 'price': 55.08}, {'date': '1997-09-30', 'price': 59.08}, {'date': '1997-12-31', 'price': 61.0}, {'date': '1998-03-31', 'price': 69.3}, {'date': '1998-06-30', 'price': 71.65}, {'date': '1998-09-30', 'price': 64.57}, {'date': '1998-12-31', 'price': 78.51}, {'date': '1999-03-31', 'price': 81.93}, {'date': '1999-06-30', 'price': 87.7}, {'date': '1999-09-30', 'price': 82.65}, {'date': '1999-12-31', 'price': 94.52}, {'date': '2000-03-31', 'price': 97.01}, {'date': '2000-06-30', 'price': 93.95}, {'date': '2000-09-30', 'price': 93.11}, {'date': '2000-12-31', 'price': 85.31}, {'date': '2001-03-31', 'price': 76.09}, {'date': '2001-06-30', 'price': 80.17}, {'date': '2001-09-30', 'price': 68.55}, {'date': '2001-12-31', 'price': 75.28}, {'date': '2002-03-31', 'price': 75.64}, {'date': '2002-06-30', 'price': 65.59}, {'date': '2002-09-30', 'price': 54.45}, {'date': '2002-12-31', 'price': 59.03}, {'date': '2003-03-31', 'price': 56.92}, {'date': '2003-06-30', 'price': 65.82}, {'date': '2003-09-30', 'price': 67.64}, {'date': '2003-12-31', 'price': 75.66}, {'date': '2004-03-31', 'price': 77.17}, {'date': '2004-06-30', 'price': 78.43}, {'date': '2004-09-30', 'price': 76.85}, {'date': '2004-12-31', 'price': 83.76}, {'date': '2005-03-31', 'price': 82.06}, {'date': '2005-06-30', 'price': 83.25}, {'date': '2005-09-30', 'price': 86.31}, {'date': '2005-12-31', 'price': 87.8}, {'date': '2006-03-31', 'price': 91.92}, {'date': '2006-06-30', 'price': 90.51}, {'date': '2006-09-30', 'price': 95.41}, {'date': '2006-12-31', 'price': 101.72}, {'date': '2007-03-31', 'price': 102.39}, {'date': '2007-06-30', 'price': 108.94}, {'date': '2007-09-30', 'price': 111.02}, {'date': '2007-12-31', 'price': 106.95}, {'date': '2008-03-31', 'price': 97.01}, {'date': '2008-06-30', 'price': 94.55}, {'date': '2008-09-30', 'price': 86.19}, {'date': '2008-12-31', 'price': 67.6}, {'date': '2009-03-31', 'price': 59.99}, {'date': '2009-06-30', 'price': 69.76}, {'date': '2009-09-30', 'price': 80.49}, {'date': '2009-12-31', 'price': 85.41}, {'date': '2010-03-31', 'price': 90.04}, {'date': '2010-06-30', 'price': 79.82}, {'date': '2010-09-30', 'price': 88.72}, {'date': '2010-12-31', 'price': 98.27}, {'date': '2011-03-31', 'price': 104.07}, {'date': '2011-06-30', 'price': 104.09}, {'date': '2011-09-30', 'price': 89.71}, {'date': '2011-12-31', 'price': 100.13}, {'date': '2012-03-31', 'price': 112.84}, {'date': '2012-06-30', 'price': 109.63}, {'date': '2012-09-30', 'price': 116.59}, {'date': '2012-12-31', 'price': 116.15}, {'date': '2013-03-31', 'price': 128.34}, {'date': '2013-06-30', 'price': 132.11}, {'date': '2013-09-30', 'price': 139.04}, {'date': '2013-12-31', 'price': 153.67}, {'date': '2014-03-31', 'price': 156.29}, {'date': '2014-06-30', 'price': 164.35}, {'date': '2014-09-30', 'price': 166.21}, {'date': '2014-12-31', 'price': 174.36}, {'date': '2015-03-31', 'price': 175.9}, {'date': '2015-06-30', 'price': 176.25}, {'date': '2015-09-30', 'price': 164.93}, {'date': '2015-12-31', 'price': 176.51}, {'date': '2016-03-31', 'price': 178.86}, {'date': '2016-06-30', 'price': 183.25}, {'date': '2016-09-30', 'price': 190.17}, {'date': '2016-12-31', 'price': 197.69}, {'date': '2017-03-31', 'price': 209.39}, {'date': '2017-06-30', 'price': 215.82}, {'date': '2017-09-30', 'price': 225.35}, {'date': '2017-12-31', 'price': 240.6}, {'date': '2018-03-31', 'price': 238.2}, {'date': '2018-06-30', 'price': 246.66}, {'date': '2018-09-30', 'price': 265.54}, {'date': '2018-12-31', 'price': 229.6}, {'date': '2019-03-31', 'price': 260.66}, {'date': '2019-06-30', 'price': 271.68}, {'date': '2019-09-30', 'price': 276.45}, {'date': '2019-12-31', 'price': 301.3}, {'date': '2020-03-31', 'price': 242.7}, {'date': '2020-06-30', 'price': 291.63}, {'date': '2020-09-30', 'price': 317.99}, {'date': '2020-12-31', 'price': 356.53}, {'date': '2021-03-31', 'price': 379.17}, {'date': '2021-06-30', 'price': 410.87}, {'date': '2021-09-30', 'price': 413.23}, {'date': '2021-12-31', 'price': 458.95}, {'date': '2022-03-31', 'price': 437.78}, {'date': '2022-06-30', 'price': 367.25}, {'date': '2022-09-30', 'price': 349.14}, {'date': '2022-12-31', 'price': 375.54}, {'date': '2023-03-31', 'price': 403.55}, {'date': '2023-06-30', 'price': 438.58}, {'date': '2023-09-30', 'price': 424.44}, {'date': '2023-12-31', 'price': 473.84}, {'date': '2024-03-31', 'price': 523.07}]; + + +// Helper function to calculate percentage difference +function calculatePercentageDifference(startPrice, endPrice) { + return ((endPrice - startPrice) / startPrice) * 100; +} + +// Helper function to get the last day of the quarter for a given date +function getQuarterEndDate(date) { + const d = new Date(date); + const month = d.getMonth(); + const year = d.getFullYear(); + + if (month < 3) return `${year}-03-31`; + if (month < 6) return `${year}-06-30`; + if (month < 9) return `${year}-09-30`; + return `${year}-12-31`; +} + +// Efficient function to add spyPerformance and convert dates to quarter-end dates +function addSpyPerformance(data, spyPriceData) { + // Create a map for quick lookup of spy prices by date + const spyPriceMap = new Map(spyPriceData.map(entry => [entry.date, entry.price])); + + // Convert data dates to quarter-end dates + const quarterData = data.map(item => ({ + ...item, + date: getQuarterEndDate(item.date) + })); + + // Get the starting price from the first date in data + const startDate = quarterData[0].date; + const startSpyPrice = spyPriceMap.get(startDate); + + if (startSpyPrice === undefined) { + console.warn(`Starting price for date ${startDate} not found in spyPriceData. Setting initial spyPerformance to 0.`); + } + + return quarterData.map((item, index) => { + const spyPrice = spyPriceMap.get(item.date); + + if (spyPrice === undefined) { + console.warn(`Price for date ${item.date} not found in spyPriceData. Skipping spyPerformance calculation for this date.`); + return { + ...item, + spyPerformance: index === 0 ? 0 : null // Use null or any indicator for missing data + }; + } + + const spyPerformance = index === 0 ? 0 : calculatePercentageDifference(startSpyPrice, spyPrice); + + return { + ...item, + spyPerformance + }; + }); +} + +// Function to format date to FY and quarter +function formatToFY(dateString) { + const date = new Date(dateString); + const year = date.getFullYear(); + const month = date.getMonth() + 1; // getMonth() returns 0-11, so we add 1 + + // Fiscal year starts in April + const fiscalYear = month >= 4 ? year : year - 1; + const fiscalYearString = fiscalYear.toString().slice(-2); - + // Determine fiscal quarter + let quarter; + if (month >= 4 && month <= 6) { + quarter = 1; + } else if (month >= 7 && month <= 9) { + quarter = 2; + } else if (month >= 10 && month <= 12) { + quarter = 3; + } else { + quarter = 4; + } + + return `FY${fiscalYearString} Q${quarter}`; +} + async function infiniteHandler({ detail: { loaded, complete } }) { if (displayList?.length === rawList?.length) { @@ -80,18 +163,25 @@ function getYearFromDate(dateString) { } async function getPlotOptions() { - // Get unique years from the data - const dates = [...new Set(rawData?.summary?.slice(0,30)?.map(item => getYearFromDate(item?.date)))]?.reverse(); // Initialize boughtList and soldList arrays - const performanceList = rawData?.summary?.slice(0,30)?.map(item => item?.performancePercentage)?.reverse(); - const { unit, denominator } = normalizer(Math.max(...performanceList) ?? 0); - console.log(performanceList) - + const data = rawData?.summary?.slice(0,20) + ?.map(item => ({ date: item?.date, performancePercentage: item?.performancePercentage })) + ?.reverse(); + + const updatedData = addSpyPerformance(data, spyData); + const dates = updatedData?.map(item => formatToFY(item?.date)); + + const hedgeFundPerformance = updatedData?.map(item => item?.performancePercentage?.toFixed(2)) + const spyPerformance = updatedData?.map(item => item?.spyPerformance?.toFixed(2)) + + const { unit, denominator } = normalizer(Math.max(...hedgeFundPerformance) ?? 0); + + const option = { silent: true, grid: { - left: $screenWidth < 640 ? '5.2%' : '0.5%', - right: $screenWidth < 640 ? '5%' : '0.5%', + left: $screenWidth < 640 ? '0.5%' : '0.5%', + right: $screenWidth < 640 ? '1%' : '0.5%', bottom: '0%', containLabel: true }, @@ -108,19 +198,28 @@ function getYearFromDate(dateString) { axisLabel: { color: '#6E7079', // Change label color to white formatter: function (value) { - return +(value / denominator)?.toFixed(0) + unit+'%'; // Format value in millions + return value >= 0 ? +(value / denominator)?.toFixed(0) + unit+'%' : ''; // Format value in millions }, }, }, ], series: [ - { - data: performanceList, + { + name: 'SPY', + data: spyPerformance, type: 'line', + showSymbol: false, + itemStyle: { + color: '#36A2EB' // Change bar color to white + }, + }, + { name: 'Hedge Fund', + data: hedgeFundPerformance, + type: 'line', + showSymbol: false, itemStyle: { color: '#FF6384' // Change bar color to white }, - barWidth: '10%', }, ] }; @@ -216,7 +315,7 @@ function getYearFromDate(dateString) {
- +
@@ -283,11 +382,12 @@ function getYearFromDate(dateString) {
- + +
3 Year Perf. - + {#if rawData?.performancePercentage3year >=0} +{abbreviateNumber(rawData?.performancePercentage3year?.toFixed(2))}% {:else} @@ -296,8 +396,8 @@ function getYearFromDate(dateString) {
-
- +
+ @@ -315,9 +415,78 @@ function getYearFromDate(dateString) {
- - +
+ + + +
+
+ 5 Year Perf. + + {#if rawData?.performancePercentage5year >=0} + +{abbreviateNumber(rawData?.performancePercentage5year?.toFixed(2))}% + {:else} + {abbreviateNumber(rawData?.performancePercentage5year?.toFixed(2))}% + {/if} +
+ +
+ + + + + + = 0 ? 100-(rawData?.performancePercentage5year)?.toFixed(2) : 0}> + + + + + +
+
+ + + + +
+
+ Incept. Perf. + + {#if rawData?.performanceSinceInceptionPercentage >=0} + +{abbreviateNumber(rawData?.performanceSinceInceptionPercentage?.toFixed(2))}% + {:else} + {abbreviateNumber(rawData?.performanceSinceInceptionPercentage?.toFixed(2))}% + {/if} + +
+ +
+ + + + + + = 0 ? 100-(rawData?.performanceSinceInceptionPercentage)?.toFixed(2) : 0}> + + + + + +
+
+ +
@@ -342,26 +511,25 @@ function getYearFromDate(dateString) {
- + - Bought + Hedge Fund
- + - Sold + SPY
- - +
{/if} -
+
@@ -369,7 +537,7 @@ function getYearFromDate(dateString) { {numOfAssets} Assets - -
+
- - {numOfAssets} Assets - @@ -463,42 +628,71 @@ function getYearFromDate(dateString) {
- - - - - - - - - +
Name% of PortfolioDisclosure DateAmount
+ + + + + {#if changeAssetType === 'Share'} + + {/if} + + + {#if changeAssetType !== 'Share'} + + {/if} + + {#each displayList as item,index} - goto(`/${item?.type}/${item?.ticker}`)} class="sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] bg-[#0F0F0F] border-b-[#0F0F0F] cursor-pointer"> + goto(`/${item?.type}/${item?.ticker}`)} class="bg-[#0F0F0F] cursor-pointer"> - - - - - - - - + + + + + {#if changeAssetType === 'Share'} + + {/if} + + + + + {#if changeAssetType !== 'Share'} + + {/if} @@ -527,7 +721,8 @@ function getYearFromDate(dateString) { {/if} - + + diff --git a/src/routes/stocks/[tickerID]/stats/income/+page.svelte b/src/routes/stocks/[tickerID]/stats/income/+page.svelte index 72ec3b4a..582843aa 100644 --- a/src/routes/stocks/[tickerID]/stats/income/+page.svelte +++ b/src/routes/stocks/[tickerID]/stats/income/+page.svelte @@ -205,7 +205,6 @@ function normalizer(value) { const {unit, denominator } = normalizer(Math.max(...valueList) ?? 0) - console.log(unit, denominator) const options = { xAxis: { data: xList,
+ Name + + % of Portfolio + + Change of Shares + + Value Owned + + Avg. Buy Price + + Type +
-
+
+
- {item?.ticker?.replace('_',' ')} - {item?.securityName?.length < charNumber ? formatString(item?.securityName) : formatString(item?.securityName?.slice(0,charNumber)) + '...'} + {item?.symbol?.replace('_',' ')} + {item?.securityName?.length > charNumber ? formatString(item?.securityName?.slice(0,charNumber)) + '...' : formatString(item?.securityName)}
- {new Date(item?.transactionDate)?.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', daySuffix: '2-digit' })} - - {new Date(item?.disclosureDate)?.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', daySuffix: '2-digit' })} - - {item?.amount} - + {item?.weight?.toFixed(2)}% + + {item?.changeInSharesNumberPercentage !== 0 ? abbreviateNumber(item?.changeInSharesNumberPercentage?.toFixed(2))+'%' : '-'} + + {abbreviateNumber(item?.marketValue,true)} + + ${item?.avgPricePaid} + + {formatString(item?.putCallShare)} +