diff --git a/src/lib/components/AnalystEstimate.svelte b/src/lib/components/AnalystEstimate.svelte
index f40c7894..8ddadceb 100644
--- a/src/lib/components/AnalystEstimate.svelte
+++ b/src/lib/components/AnalystEstimate.svelte
@@ -15,10 +15,17 @@
let analystEstimateList = [];
let isLoaded = false;
- let deactivateContent = data?.user?.tier === "Pro" ? false : true;
-
let xData = [];
- let optionsData;
+ let optionsRevenue = null;
+ let optionsEPS = null;
+ let revenueDateList = [];
+ let avgRevenueList = [];
+ let lowRevenueList = [];
+ let highRevenueList = [];
+ let epsDateList = [];
+ let avgEPSList = [];
+ let lowEPSList = [];
+ let highEPSList = [];
let displayData = "Revenue";
@@ -39,14 +46,13 @@
return index !== -1 && hasNonNullRevenue ? index + 1 : index;
}
- function changeStatement(event) {
- displayData = event.target.value;
- }
+ let tableActualRevenue = [];
+ let tableActualEPS = [];
- let tableDataActual = [];
- let tableDataForecast = [];
+ let tableForecastRevenue = [];
+ let tableForecastEPS = [];
- function getPlotOptions() {
+ function getPlotOptions(dataType: string) {
let dates = [];
let valueList = [];
let avgList = [];
@@ -62,27 +68,13 @@
const date = item.date?.toString().slice(-2);
const isAfterStartIndex = stopIndex <= index + 1;
dates.push(`FY${date}`);
- switch (displayData) {
+ switch (dataType) {
case "Revenue":
valueList.push(item.revenue);
avgList.push(isAfterStartIndex ? item.estimatedRevenueAvg : null);
lowList.push(isAfterStartIndex ? item.estimatedRevenueLow : null);
highList.push(isAfterStartIndex ? item.estimatedRevenueHigh : null);
break;
- case "Net Income":
- valueList.push(item.netIncome);
- avgList.push(isAfterStartIndex ? item.estimatedNetIncomeAvg : null);
- lowList.push(isAfterStartIndex ? item.estimatedNetIncomeLow : null);
- highList.push(
- isAfterStartIndex ? item.estimatedNetIncomeHigh : null,
- );
- break;
- case "EBITDA":
- valueList.push(item.ebitda);
- avgList.push(isAfterStartIndex ? item.estimatedEbitdaAvg : null);
- lowList.push(isAfterStartIndex ? item.estimatedEbitdaLow : null);
- highList.push(isAfterStartIndex ? item.estimatedEbitdaHigh : null);
- break;
case "EPS":
valueList.push(item.eps);
avgList.push(isAfterStartIndex ? item.estimatedEpsAvg : null);
@@ -189,87 +181,84 @@
],
};
- return option;
+ let currentYearSuffix = new Date().getFullYear().toString().slice(-2);
+ let searchString = `FY${currentYearSuffix}`;
+
+ // Assign to global variables based on dataType
+ if (dataType === "Revenue") {
+ let currentYearIndex = dates?.findIndex((date) => date === searchString);
+ optionsRevenue = option;
+ revenueDateList = dates?.slice(currentYearIndex) || [];
+ avgRevenueList = avgList?.slice(currentYearIndex) || [];
+ lowRevenueList = lowList?.slice(currentYearIndex) || [];
+ highRevenueList = highList?.slice(currentYearIndex) || [];
+ } else if (dataType === "EPS") {
+ let currentYearIndex = dates?.findIndex((date) => date === searchString);
+
+ optionsEPS = option;
+ epsDateList = dates?.slice(currentYearIndex) || [];
+ avgEPSList = avgList?.slice(currentYearIndex) || [];
+ lowEPSList = lowList?.slice(currentYearIndex) || [];
+ highEPSList = highList?.slice(currentYearIndex) || [];
+ }
}
//To-do: Optimize this piece of shit
function prepareData() {
- tableDataActual = [];
- tableDataForecast = [];
+ tableActualRevenue = [];
+ tableForecastRevenue = [];
+
+ tableActualEPS = [];
+ tableForecastEPS = [];
let filteredData =
analystEstimateList?.filter((item) => item.date >= 2015) ?? [];
xData = filteredData?.map(({ date }) => Number(String(date)?.slice(-2)));
- if (displayData === "Revenue") {
- filteredData?.forEach((item) => {
- tableDataActual?.push({
- FY: Number(String(item?.date)?.slice(-2)),
- val: item?.revenue,
- });
- tableDataForecast?.push({
- FY: Number(String(item?.date)?.slice(-2)),
- val: item?.estimatedRevenueAvg,
- numOfAnalysts: item?.numOfAnalysts,
- });
+ //Revenue Data
+ filteredData?.forEach((item) => {
+ tableActualRevenue?.push({
+ FY: Number(String(item?.date)?.slice(-2)),
+ val: item?.revenue,
});
- } else if (displayData === "Net Income") {
- filteredData?.forEach((item) => {
- tableDataActual?.push({
- FY: Number(String(item?.date)?.slice(-2)),
- val: item?.netIncome,
- });
- tableDataForecast?.push({
- FY: Number(String(item?.date)?.slice(-2)),
- val: item?.estimatedNetIncomeAvg,
- numOfAnalysts: item?.numOfAnalysts,
- });
+ tableForecastRevenue?.push({
+ FY: Number(String(item?.date)?.slice(-2)),
+ val: item?.estimatedRevenueAvg,
+ numOfAnalysts: item?.numOfAnalysts,
});
- } else if (displayData === "EPS") {
- let forwardPeStart = false;
- filteredData?.forEach((item) => {
- const fy = Number(String(item?.date)?.slice(-2));
- const actualVal = item?.eps ?? null;
- const forecastVal = item?.estimatedEpsAvg;
+ });
+ //EPS Data
+ let forwardPeStart = false;
+ filteredData?.forEach((item) => {
+ const fy = Number(String(item?.date)?.slice(-2));
+ const actualVal = item?.eps ?? null;
+ const forecastVal = item?.estimatedEpsAvg;
- tableDataActual?.push({
- FY: fy,
- val: actualVal,
- });
-
- if (actualVal === null) {
- forwardPeStart = true;
- }
-
- const forecastEntry: any = {
- FY: fy,
- val: forecastVal,
- numOfAnalysts: item?.numOfAnalysts,
- };
-
- // Add forwardPe if the condition is met
- if (forwardPeStart && forecastVal !== null) {
- forecastEntry.forwardPe =
- Math.round((data.getStockQuote.price / forecastVal) * 100) / 100;
- } else {
- forecastEntry.forwardPe = null;
- }
-
- tableDataForecast?.push(forecastEntry);
+ tableActualEPS?.push({
+ FY: fy,
+ val: actualVal,
});
- } else if (displayData === "EBITDA") {
- filteredData?.forEach((item) => {
- tableDataActual?.push({
- FY: Number(String(item?.date)?.slice(-2)),
- val: item?.ebitda,
- });
- tableDataForecast?.push({
- FY: Number(String(item?.date)?.slice(-2)),
- val: item?.estimatedEbitdaAvg,
- numOfAnalysts: item?.numOfAnalysts,
- });
- });
- }
+
+ if (actualVal === null) {
+ forwardPeStart = true;
+ }
+
+ const forecastEntry: any = {
+ FY: fy,
+ val: forecastVal,
+ numOfAnalysts: item?.numOfAnalysts,
+ };
+
+ // Add forwardPe if the condition is met
+ if (forwardPeStart && forecastVal !== null) {
+ forecastEntry.forwardPe =
+ Math.round((data.getStockQuote.price / forecastVal) * 100) / 100;
+ } else {
+ forecastEntry.forwardPe = null;
+ }
+
+ tableForecastEPS?.push(forecastEntry);
+ });
}
$: {
@@ -279,7 +268,9 @@
analystEstimateList = data?.getAnalystEstimate || [];
if (analystEstimateList?.length !== 0) {
$analystEstimateComponent = true;
- optionsData = getPlotOptions();
+ getPlotOptions("Revenue");
+ getPlotOptions("EPS");
+
prepareData();
} else {
$analystEstimateComponent = false;
@@ -291,87 +282,11 @@
-
-
-
-
-
-
-
- We analyze insights from various analysts to offer both historical and
- future fundamental data forecasts.
-
+
+
{#if isLoaded}
{#if analystEstimateList?.length !== 0}
-
-
-
-
-
-
-
-
-
-
-
- Analyst Forecast
-
-
-
-
@@ -397,9 +312,9 @@
- Forecast
+ Revenue
|
- {#each tableDataForecast as item}
+ {#each tableForecastRevenue as item}
@@ -414,68 +329,53 @@
|
|
- Actual
+ Revenue Growth
|
- {#each tableDataActual as item}
+ {#each tableActualRevenue as item, index}
- {item?.val === "0.00" ||
- item?.val === null ||
- item?.val === 0
- ? "-"
- : abbreviateNumber(item?.val)}
- |
- {/each}
-
-
-
- |
- % Change
- |
- {#each tableDataActual as item, index}
-
- {#if index === 0 || tableDataActual?.length === 0}
+ {#if index === 0 || tableActualRevenue?.length === 0}
-
{:else if item?.val === null}
- {#if tableDataForecast[index]?.val - tableDataForecast[index - 1]?.val > 0}
+ {#if tableForecastRevenue[index]?.val - tableForecastRevenue[index - 1]?.val > 0}
{(
- ((tableDataForecast[index]?.val -
- tableDataForecast[index - 1]?.val) /
- Math.abs(tableDataForecast[index - 1]?.val)) *
+ ((tableForecastRevenue[index]?.val -
+ tableForecastRevenue[index - 1]?.val) /
+ Math.abs(
+ tableForecastRevenue[index - 1]?.val,
+ )) *
100
)?.toFixed(2)}%*
- {:else if tableDataForecast[index]?.val - tableDataForecast[index - 1]?.val < 0}
+ {:else if tableForecastRevenue[index]?.val - tableForecastRevenue[index - 1]?.val < 0}
{(
- ((tableDataForecast[index]?.val -
- tableDataForecast[index - 1]?.val) /
- Math.abs(tableDataForecast[index - 1]?.val)) *
+ ((tableForecastRevenue[index]?.val -
+ tableForecastRevenue[index - 1]?.val) /
+ Math.abs(
+ tableForecastRevenue[index - 1]?.val,
+ )) *
100
)?.toFixed(2)}%*
{/if}
- {:else if item?.val - tableDataActual[index - 1]?.val > 0}
+ {:else if item?.val - tableActualRevenue[index - 1]?.val > 0}
{(
- ((item?.val - tableDataActual[index - 1]?.val) /
- Math.abs(tableDataActual[index - 1]?.val)) *
+ ((item?.val - tableActualRevenue[index - 1]?.val) /
+ Math.abs(tableActualRevenue[index - 1]?.val)) *
100
)?.toFixed(2)}%
- {:else if item?.val - tableDataActual[index - 1]?.val < 0}
+ {:else if item?.val - tableActualRevenue[index - 1]?.val < 0}
{(
- ((item?.val - tableDataActual[index - 1]?.val) /
- Math.abs(tableDataActual[index - 1]?.val)) *
+ ((item?.val - tableActualRevenue[index - 1]?.val) /
+ Math.abs(tableActualRevenue[index - 1]?.val)) *
100
)?.toFixed(2)}%
@@ -486,58 +386,114 @@
{/each}
|
- {#if displayData === "EPS"}
-
- | Forward PE |
+
+ EPS
+ |
+ {#each tableForecastEPS as item}
+
- {#each tableDataForecast as item}
- |
- {item?.forwardPe === "0.00" ||
- item?.forwardPe === null ||
- item?.forwardPe === 0
- ? "-"
- : abbreviateNumber(item.forwardPe)}
- |
- {/each}
-
+ {item?.val === "0.00" ||
+ item?.val === null ||
+ item?.val === 0
+ ? "-"
+ : abbreviateNumber(item?.val.toFixed(2))}
+
+ {/each}
+
-
- | No. Analysts |
+
+ EPS Growth
+ |
+ {#each tableActualEPS as item, index}
+
- {#each tableDataForecast as item}
- |
- {item?.numOfAnalysts === (null || 0)
- ? "-"
- : item?.numOfAnalysts}
- |
- {/each}
-
- {:else}
-
- | 0}
+
+ {(
+ ((tableForecastEPS[index]?.val -
+ tableForecastEPS[index - 1]?.val) /
+ Math.abs(tableForecastEPS[index - 1]?.val)) *
+ 100
+ )?.toFixed(2)}%*
+
+ {:else if tableForecastEPS[index]?.val - tableForecastEPS[index - 1]?.val < 0}
+
+ {(
+ ((tableForecastEPS[index]?.val -
+ tableForecastEPS[index - 1]?.val) /
+ Math.abs(tableForecastEPS[index - 1]?.val)) *
+ 100
+ )?.toFixed(2)}%*
+
+ {/if}
+ {:else if item?.val - tableActualEPS[index - 1]?.val > 0}
+
+ {(
+ ((item?.val - tableActualEPS[index - 1]?.val) /
+ Math.abs(tableActualEPS[index - 1]?.val)) *
+ 100
+ )?.toFixed(2)}%
+
+ {:else if item?.val - tableActualEPS[index - 1]?.val < 0}
+
+ {(
+ ((item?.val - tableActualEPS[index - 1]?.val) /
+ Math.abs(tableActualEPS[index - 1]?.val)) *
+ 100
+ )?.toFixed(2)}%
+
+ {:else}
+ 0.00%
+ {/if}
+
+ {/each}
+ |
+
+
+
+ | No. Analysts |
+ {#each tableForecastRevenue as item}
+
+ {item?.numOfAnalysts === (null || 0)
+ ? "-"
+ : item?.numOfAnalysts}
+ |
+ {/each}
+
@@ -566,6 +522,112 @@
{/if}
+
+
+
+
Revenue Forecast
+
+
+ {#if optionsRevenue !== null}
+
+ {/if}
+
+
+
+ | Revenue |
+ {#each revenueDateList as date}
+ {date} |
+ {/each}
+
+ | High |
+ {#each highRevenueList as val}
+ {abbreviateNumber(val)} |
+ {/each}
+
| Avg |
+ {#each avgRevenueList as val}
+ {abbreviateNumber(val)} |
+ {/each}
+
| Low |
+ {#each lowRevenueList as val}
+ {abbreviateNumber(val)} |
+ {/each}
+
+
+
+
+
+
+
+
EPS Forecast
+
+
+ {#if optionsEPS !== null}
+
+ {/if}
+
+
+
+ | EPS |
+ {#each epsDateList as date}
+ {date} |
+ {/each}
+
+ | High |
+ {#each highEPSList as val}
+ {abbreviateNumber(val)} |
+ {/each}
+
| Avg |
+ {#each avgEPSList as val}
+ {abbreviateNumber(val)} |
+ {/each}
+
| Low |
+ {#each lowEPSList as val}
+ {abbreviateNumber(val)} |
+ {/each}
+
+
+
+
+
+
diff --git a/src/routes/stocks/[tickerID]/forecast/+page.svelte b/src/routes/stocks/[tickerID]/forecast/+page.svelte
index a18f2bf7..eae1e9cb 100644
--- a/src/routes/stocks/[tickerID]/forecast/+page.svelte
+++ b/src/routes/stocks/[tickerID]/forecast/+page.svelte
@@ -172,7 +172,6 @@
}
function getPieChart() {
- const consensusRating = "Buy";
let value;
// Determine the value based on the consensus rating
switch (consensusRating) {
@@ -757,9 +756,7 @@
{#await import("$lib/components/AnalystEstimate.svelte") then { default: Comp }}