From 0e3219fbf8efec817ff621cb82acfcea0317ac4e Mon Sep 17 00:00:00 2001 From: MuslemRahimi Date: Wed, 29 May 2024 10:21:14 +0200 Subject: [PATCH] update hedge fund page --- src/lib/images/hedge_funds/0001037389.png | Bin 0 -> 7738 bytes src/routes/hedge-funds/[slug]/+page.svelte | 315 ++++++++++++++---- .../[tickerID]/stats/income/+page.svelte | 1 - 3 files changed, 255 insertions(+), 61 deletions(-) create mode 100644 src/lib/images/hedge_funds/0001037389.png diff --git a/src/lib/images/hedge_funds/0001037389.png b/src/lib/images/hedge_funds/0001037389.png new file mode 100644 index 0000000000000000000000000000000000000000..a4c3adfa2f94efaba2b24fd34b308f904de5b271 GIT binary patch literal 7738 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 [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)} +