update forecast overview page
This commit is contained in:
parent
f8ed49b3d4
commit
defd8a9283
@ -1,8 +1,20 @@
|
||||
<script lang="ts">
|
||||
import { numberOfUnreadNotification, displayCompanyName, stockTicker, analystEstimateComponent, currentPortfolioPrice } from "$lib/store";
|
||||
import { numberOfUnreadNotification, displayCompanyName, stockTicker, analystEstimateComponent } from "$lib/store";
|
||||
import { abbreviateNumber } from "$lib/utils";
|
||||
import Lazy from "$lib/components/Lazy.svelte";
|
||||
|
||||
export let data;
|
||||
|
||||
function findIndex(data) {
|
||||
const currentYear = new Date().getFullYear();
|
||||
return data.findIndex(item => item.date >= currentYear && item.revenue === null);
|
||||
}
|
||||
const index = findIndex(data?.getAnalystEstimate);
|
||||
const changeRevenue = abbreviateNumber(((data?.getAnalystEstimate[index-1]?.estimatedRevenueAvg/data?.getAnalystEstimate[index-2]?.revenue-1)*100))?.toFixed(1)
|
||||
const changeNetIncome = abbreviateNumber(((data?.getAnalystEstimate[index-1]?.estimatedNetIncomeAvg/data?.getAnalystEstimate[index-2]?.netIncome-1)*100))?.toFixed(1)
|
||||
const changeEBITDA = abbreviateNumber(((data?.getAnalystEstimate[index-1]?.estimatedEbitdaAvg/data?.getAnalystEstimate[index-2]?.ebitda-1)*100)?.toFixed(1))
|
||||
const changeEPS = abbreviateNumber(((data?.getAnalystEstimate[index-1]?.estimatedEpsAvg/data?.getAnalystEstimate[index-2]?.eps-1)*100))?.toFixed(1)
|
||||
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@ -31,6 +43,84 @@
|
||||
<div class="flex justify-center m-auto h-full overflow-hidden w-full">
|
||||
<div class="relative flex justify-center items-center overflow-hidden w-full">
|
||||
<div class="sm:p-7 w-full m-auto mt-2 sm:mt-0">
|
||||
|
||||
<h2 class="mt-5 text-xl sm:text-2xl text-gray-200 font-bold mb-4">
|
||||
Financial Forecast this Year
|
||||
</h2>
|
||||
|
||||
<div class="mb-4 grid grid-cols-2 grid-rows-1 divide-gray-500 rounded-lg border border-gray-600 bg-[#272727] shadow md:grid-cols-4 md:grid-rows-1 md:divide-x">
|
||||
<div class="p-4 bp:p-5 sm:p-6">
|
||||
<label class="mr-1 cursor-pointer flex flex-row items-center text-white text-[1rem] font-semibold">
|
||||
Revenue
|
||||
</label>
|
||||
<div class="mt-1 flex flex-col items-baseline justify-start space-y-2 bp:space-y-0">
|
||||
<div class="flex items-baseline text-2xl font-semibold text-white">
|
||||
{abbreviateNumber(data?.getAnalystEstimate[index-1]?.estimatedRevenueAvg,true)}
|
||||
</div>
|
||||
<div class="inline-flex items-baseline rounded-full px-2.5 py-0.5 text-sm font-semibold md:mt-2 lg:mt-0 bg-green-100 text-green-800 dark:bg-green-700 dark:text-dark-100">
|
||||
<svg class="-ml-1 mr-0.5 h-5 w-5 flex-shrink-0 self-center {changeRevenue > 0 ? 'text-green-500' : 'text-red-500 rotate-180'}" fill="none" viewBox="0 0 24 24" stroke="currentColor" style="max-width:40px" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 11l5-5m0 0l5 5m-5-5v12"></path></svg>
|
||||
{changeRevenue}%
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-0.5 mt-1.5 text-sm font-semibold text-white/60 lg:block">
|
||||
from {abbreviateNumber(data?.getAnalystEstimate[index-2]?.revenue)}
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4 bp:p-5 sm:p-6 border-l border-contrast md:border-0">
|
||||
<label class="mr-1 cursor-pointer flex flex-row items-center text-white text-[1rem] font-semibold">
|
||||
Net Income
|
||||
</label>
|
||||
<div class="mt-1 flex flex-col items-baseline justify-start space-y-2 bp:space-y-0">
|
||||
<div class="flex items-baseline text-2xl font-semibold text-white">
|
||||
{abbreviateNumber(data?.getAnalystEstimate[index-1]?.estimatedNetIncomeAvg,true)}
|
||||
</div>
|
||||
<div class="inline-flex items-baseline rounded-full px-2.5 py-0.5 text-sm font-semibold md:mt-2 lg:mt-0 bg-green-100 text-green-800 dark:bg-green-700 dark:text-dark-100">
|
||||
<svg class="-ml-1 mr-0.5 h-5 w-5 flex-shrink-0 self-center {changeNetIncome > 0 ? 'text-green-500' : 'text-red-500 rotate-180'}" fill="none" viewBox="0 0 24 24" stroke="currentColor" style="max-width:40px" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 11l5-5m0 0l5 5m-5-5v12"></path></svg>
|
||||
{changeNetIncome}%
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-0.5 mt-1.5 text-sm font-semibold text-white/60 lg:block">
|
||||
from {abbreviateNumber(data?.getAnalystEstimate[index-2]?.netIncome,true)}
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4 bp:p-5 sm:p-6 border-t border-contrast md:border-0">
|
||||
<label class="mr-1 cursor-pointer flex flex-row items-center text-white text-[1rem] font-semibold">
|
||||
EBITDA
|
||||
</label>
|
||||
<div class="mt-1 flex flex-col items-baseline justify-start space-y-2 bp:space-y-0">
|
||||
<div class="flex items-baseline text-2xl font-semibold text-white">
|
||||
{abbreviateNumber(data?.getAnalystEstimate[index-1]?.estimatedEbitdaAvg,true)}
|
||||
</div>
|
||||
<div class="inline-flex items-baseline rounded-full px-2.5 py-0.5 text-sm font-semibold md:mt-2 lg:mt-0 bg-green-100 text-green-800 dark:bg-green-700 dark:text-dark-100">
|
||||
<svg class="-ml-1 mr-0.5 h-5 w-5 flex-shrink-0 self-center {changeEBITDA > 0 ? 'text-green-500' : 'text-red-500 rotate-180'}" fill="none" viewBox="0 0 24 24" stroke="currentColor" style="max-width:40px" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 11l5-5m0 0l5 5m-5-5v12"></path></svg>
|
||||
{changeEBITDA}%
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-0.5 mt-1.5 text-sm font-semibold text-white/60 lg:block">
|
||||
from {abbreviateNumber(data?.getAnalystEstimate[index-2]?.ebitda,true)}
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4 bp:p-5 sm:p-6 border-t border-contrast md:border-0 border-l border-contrast md:border-0">
|
||||
<label class="mr-1 cursor-pointer flex flex-row items-center text-white text-[1rem] font-semibold">
|
||||
EPS
|
||||
</label>
|
||||
<div class="mt-1 flex flex-col items-baseline justify-start space-y-2 bp:space-y-0">
|
||||
<div class="flex items-baseline text-2xl font-semibold text-white">
|
||||
{data?.getAnalystEstimate[index-1]?.estimatedEpsAvg}
|
||||
</div>
|
||||
<div class="inline-flex items-baseline rounded-full px-2.5 py-0.5 text-sm font-semibold md:mt-2 lg:mt-0 bg-green-100 text-green-800 dark:bg-green-700 dark:text-dark-100">
|
||||
<svg class="-ml-1 mr-0.5 h-5 w-5 flex-shrink-0 self-center {changeEPS > 0 ? 'text-green-500' : 'text-red-500 rotate-180'}" fill="none" viewBox="0 0 24 24" stroke="currentColor" style="max-width:40px" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 11l5-5m0 0l5 5m-5-5v12"></path></svg>
|
||||
{changeEPS}%
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-0.5 mt-1.5 text-sm font-semibold text-white/60 lg:block">
|
||||
from {data?.getAnalystEstimate[index-2]?.eps}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<Lazy>
|
||||
<div class="w-full m-auto sm:pb-6 sm:pt-6 {!$analystEstimateComponent ? 'hidden' : ''}">
|
||||
{#await import("$lib/components/AnalystEstimate.svelte") then { default: Comp }}
|
||||
|
||||
@ -1,36 +1,32 @@
|
||||
import { getCache, setCache } from '$lib/store';
|
||||
|
||||
import { getCache, setCache } from "$lib/store";
|
||||
|
||||
export const load = async ({ parent, params }) => {
|
||||
|
||||
const getAnalystTickerHistory = async () => {
|
||||
|
||||
const getAnalystEstimate = async () => {
|
||||
let output;
|
||||
|
||||
const cachedData = getCache(params.tickerID, 'getAnalystTickerHistory');
|
||||
if (cachedData) {
|
||||
output = cachedData;
|
||||
} else {
|
||||
const cachedData = getCache(params.tickerID, "getAnalystEstimate");
|
||||
if (cachedData) {
|
||||
output = cachedData;
|
||||
} else {
|
||||
const { apiURL, apiKey } = await parent();
|
||||
|
||||
const {apiURL, apiKey} = await parent();
|
||||
|
||||
const postData = {
|
||||
ticker: params.tickerID
|
||||
};
|
||||
const postData = {
|
||||
ticker: params.tickerID,
|
||||
};
|
||||
|
||||
// make the POST request to the endpoint
|
||||
const response = await fetch(apiURL + '/analyst-ticker-history', {
|
||||
method: 'POST',
|
||||
const response = await fetch(apiURL + "/analyst-estimate", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json", "X-API-KEY": apiKey
|
||||
"Content-Type": "application/json",
|
||||
"X-API-KEY": apiKey,
|
||||
},
|
||||
body: JSON.stringify(postData)
|
||||
body: JSON.stringify(postData),
|
||||
});
|
||||
|
||||
output = await response.json();
|
||||
output = await response.json();
|
||||
|
||||
setCache(params.tickerID, output, 'getAnalystTickerHistory');
|
||||
|
||||
setCache(params.tickerID, output, "getAnalystEstimate");
|
||||
}
|
||||
|
||||
return output;
|
||||
@ -38,6 +34,6 @@ export const load = async ({ parent, params }) => {
|
||||
|
||||
// Make sure to return a promise
|
||||
return {
|
||||
getAnalystTickerHistory: await getAnalystTickerHistory()
|
||||
getAnalystEstimate: await getAnalystEstimate(),
|
||||
};
|
||||
};
|
||||
|
||||
@ -190,7 +190,7 @@ changeTab(0)
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
@ -3,21 +3,12 @@
|
||||
import ReturnCard from "$lib/components/ReturnCard.svelte";
|
||||
import { numberOfUnreadNotification, displayCompanyName, screenWidth, stockTicker, revenueSegmentationComponent } from "$lib/store";
|
||||
import { abbreviateNumber } from "$lib/utils";
|
||||
import RevenueSegmentation from "$lib/components/RevenueSegmentation.svelte";
|
||||
|
||||
export let data;
|
||||
|
||||
let quantStats = {};
|
||||
let stockQuote;
|
||||
|
||||
let marketCap = "-";
|
||||
|
||||
let currentPrice = 0;
|
||||
let previousClose = "-";
|
||||
let volume = "-";
|
||||
let eps = "-";
|
||||
let pe = "-";
|
||||
let alpha = "-";
|
||||
let beta = "-";
|
||||
|
||||
// Function to check if a date is today or yesterday, adjusting for weekends
|
||||
function ongoingDD(dateString: string) {
|
||||
@ -75,7 +66,6 @@ if (progressYearPriceValue < currentPrice) {
|
||||
|
||||
|
||||
|
||||
stockQuote = data?.getStockQuote;
|
||||
quantStats = data?.getQuantStats ?? {};
|
||||
|
||||
|
||||
@ -218,9 +208,7 @@ updateYearRange()
|
||||
<!--Start RevenueSegmentation-->
|
||||
<Lazy>
|
||||
<div class="w-full pt-10 sm:pb-6 sm:pt-6 m-auto {!$revenueSegmentationComponent ? 'hidden' : ''}">
|
||||
{#await import("$lib/components/RevenueSegmentation.svelte") then { default: Comp }}
|
||||
<svelte:component this={Comp} apiURL={data?.apiURL} apiKey={data?.apiKey} userTier={data?.user?.tier} />
|
||||
{/await}
|
||||
<RevenueSegmentation apiURL={data?.apiURL} apiKey={data?.apiKey} userTier={data?.user?.tier} />
|
||||
</div>
|
||||
</Lazy>
|
||||
<!--End RevenueSegmentation-->
|
||||
@ -230,7 +218,7 @@ updateYearRange()
|
||||
|
||||
|
||||
{#if $stockTicker in quantStats && Object.keys(quantStats[$stockTicker]).length > 0}
|
||||
<h3 class="text-start w-full mt-8 mb-2 text-lg sm:text-2xl font-bold text-white">
|
||||
<h3 class="text-start w-full mb-2 text-lg sm:text-2xl font-bold text-white">
|
||||
Worst 10 Drawdowns of {$stockTicker}
|
||||
</h3>
|
||||
<div class="w-full overflow-x-scroll">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user