This commit is contained in:
MuslemRahimi 2024-10-31 18:18:24 +01:00
parent edf98dda63
commit f073e07edf
4 changed files with 171 additions and 102 deletions

View File

@ -1,41 +1,60 @@
export const load = async ({ locals, params }) => { export const load = async ({ locals, params }) => {
const { apiURL, apiKey } = locals; const { apiURL, apiKey, user } = locals;
const postData = { const postData = {
ticker: params.tickerID, ticker: params.tickerID,
}; };
const getAnalystEstimate = async () => {
// make the POST request to the endpoint const getAnalystTickerHistory = async () => {
const response = await fetch(apiURL + "/analyst-estimate", { // make the POST request to the endpoint
method: "POST", const response = await fetch(apiURL + "/analyst-ticker-history", {
headers: { method: "POST",
"Content-Type": "application/json", headers: {
"X-API-KEY": apiKey, "Content-Type": "application/json",
}, "X-API-KEY": apiKey,
body: JSON.stringify(postData), },
}); body: JSON.stringify(postData),
});
const output = await response.json();
let output = await response.json();
return output; output = user?.tier !== "Pro" ? output?.slice(0, 6) : output;
};
return output;
const getAnalystInsight = async () => { };
const response = await fetch(apiURL + "/analyst-insight", {
method: "POST", const getAnalystEstimate = async () => {
headers: { // make the POST request to the endpoint
"Content-Type": "application/json", const response = await fetch(apiURL + "/analyst-estimate", {
"X-API-KEY": apiKey, method: "POST",
}, headers: {
body: JSON.stringify(postData), "Content-Type": "application/json",
}); "X-API-KEY": apiKey,
},
const output = await response.json(); body: JSON.stringify(postData),
return output; });
};
const output = await response.json();
// Make sure to return a promise
return { return output;
getAnalystEstimate: await getAnalystEstimate(), };
getAnalystInsight: await getAnalystInsight(),
}; const getAnalystInsight = async () => {
}; const response = await fetch(apiURL + "/analyst-insight", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
body: JSON.stringify(postData),
});
const output = await response.json();
return output;
};
// Make sure to return a promise
return {
getAnalystEstimate: await getAnalystEstimate(),
getAnalystInsight: await getAnalystInsight(),
getAnalystTickerHistory: await getAnalystTickerHistory(),
};
};

View File

@ -26,13 +26,10 @@
function changeSubSection(state) { function changeSubSection(state) {
const subSectionMap = { const subSectionMap = {
overview: "/forecast", overview: "/forecast",
ai: "/forecast/ai", //ai: "/forecast/ai",
analyst: "/forecast/analyst", analyst: "/forecast/analyst",
}; };
console.log(state);
console.log(subSectionMap[state]);
if (state !== "overview" && subSectionMap[state]) { if (state !== "overview" && subSectionMap[state]) {
displaySubSection = state; displaySubSection = state;
//goto(`/stocks/${$stockTicker}${subSectionMap[state]}`); //goto(`/stocks/${$stockTicker}${subSectionMap[state]}`);
@ -86,6 +83,7 @@
: 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[4rem]" : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[4rem]"
/> />
</li> </li>
<!--
<li class="cursor-pointer flex flex-col items-center"> <li class="cursor-pointer flex flex-col items-center">
<a <a
href={`/stocks/${$stockTicker}/forecast/ai`} href={`/stocks/${$stockTicker}/forecast/ai`}
@ -103,6 +101,7 @@
: 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[4rem]" : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[4rem]"
/> />
</li> </li>
-->
<li class="cursor-pointer flex flex-col items-center"> <li class="cursor-pointer flex flex-col items-center">
<a <a
href={`/stocks/${$stockTicker}/forecast/analyst`} href={`/stocks/${$stockTicker}/forecast/analyst`}
@ -112,7 +111,7 @@
? 'text-white ' ? 'text-white '
: 'bg-[#09090B]'}" : 'bg-[#09090B]'}"
> >
Analysts Analysts Ratings
</a> </a>
<div <div
class="{displaySubSection === 'analyst' class="{displaySubSection === 'analyst'

View File

@ -5,18 +5,17 @@
stockTicker, stockTicker,
analystEstimateComponent, analystEstimateComponent,
} from "$lib/store"; } from "$lib/store";
import { abbreviateNumber } from "$lib/utils"; import { abbreviateNumber, monthNames } from "$lib/utils";
import { Chart } from "svelte-echarts"; import { Chart } from "svelte-echarts";
import { init, use } from "echarts/core"; import { init, use } from "echarts/core";
import { BarChart } from "echarts/charts"; import { BarChart, GaugeChart } from "echarts/charts";
import { GridComponent, TooltipComponent } from "echarts/components"; import { GridComponent, TooltipComponent } from "echarts/components";
import { CanvasRenderer } from "echarts/renderers"; import { CanvasRenderer } from "echarts/renderers";
import { onMount } from "svelte";
export let data; export let data;
use([BarChart, GridComponent, TooltipComponent, CanvasRenderer]); use([GaugeChart, BarChart, GridComponent, TooltipComponent, CanvasRenderer]);
let index = 0; let index = 0;
let changeRevenue = 0; let changeRevenue = 0;
@ -90,8 +89,8 @@
} }
// Define categories in the exact order you specified // Define categories in the exact order you specified
const categories = ["Strong Buy", "Buy", "Hold", "Sell", "Strong Sell"]; const categories = ["Strong Sell", "Sell", "Hold", "Buy", "Strong Buy"];
const colors = ["#008A00", "#31B800", "#FF9E21", "#D9220E", "#9E190A"]; const colors = ["#9E190A", "#D9220E", "#FF9E21", "#31B800", "#008A00"];
// Create a consistent mapping for data // Create a consistent mapping for data
const formattedData = rawAnalystList.map((item) => const formattedData = rawAnalystList.map((item) =>
@ -124,9 +123,6 @@
itemStyle: { itemStyle: {
color: colors[idx], color: colors[idx],
}, },
tooltip: {
valueFormatter: (value) => `${value.toFixed(2)}%`,
},
})); }));
// Define chart option // Define chart option
@ -138,12 +134,7 @@
top: "5%", top: "5%",
containLabel: true, containLabel: true,
}, },
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
},
legend: { legend: {
data: categories, data: categories,
bottom: 0, bottom: 0,
@ -153,6 +144,12 @@
data: rawAnalystList.map((item) => item.date), data: rawAnalystList.map((item) => item.date),
axisLabel: { axisLabel: {
color: "#fff", color: "#fff",
formatter: function (value) {
const dateParts = value.split("-");
const year = dateParts[0].substring(0);
const monthIndex = parseInt(dateParts[1]) - 1;
return `${monthNames[monthIndex]} ${year}`;
},
}, },
}, },
yAxis: { yAxis: {
@ -168,11 +165,96 @@
}, },
series, series,
animation: false, animation: false,
silent: true,
}; };
return option; return option;
} }
function getPieChart() {
const consensusRating = "Buy";
let value;
// Determine the value based on the consensus rating
switch (consensusRating) {
case "Strong Sell":
value = 0;
break;
case "Sell":
value = 0.25;
break;
case "Hold":
value = 0.5;
break;
case "Buy":
value = 0.75;
break;
case "Strong Buy":
value = 1;
break;
default:
value = 0.5;
break;
}
const option = {
silent: true,
animation: false,
series: [
{
type: "gauge",
startAngle: 180,
endAngle: 0,
center: ["50%", "45%"],
radius: "70%",
min: 0,
max: 1,
splitNumber: 4,
axisLine: {
lineStyle: {
width: 25,
color: [
[0.2, "#9E190A"],
[0.4, "#D9220E"],
[0.6, "#FF9E21"],
[0.8, "#31B800"],
[1, "#008A00"],
],
},
},
pointer: {
icon: "path://M12.8,0.7l12,40.1H0.7L12.8,0.7z",
length: "25%",
width: 20,
offsetCenter: [0, "-30%"],
itemStyle: {
color: "#fff",
},
},
axisTick: {
length: 0,
},
splitLine: {
length: 0,
},
axisLabel: {
show: false,
},
detail: {
show: false, // Hide the numerical value display
},
data: [
{
value: value,
label: {
show: false, // Hide the data label
},
},
],
},
],
};
return option;
}
if (data?.getAnalystEstimate?.length !== 0) { if (data?.getAnalystEstimate?.length !== 0) {
index = findIndex(data?.getAnalystEstimate); index = findIndex(data?.getAnalystEstimate);
@ -198,6 +280,7 @@
} }
let optionsData = getPlotOptions() || null; let optionsData = getPlotOptions() || null;
let optionsPieChart = getPieChart() || null;
</script> </script>
<svelte:head> <svelte:head>
@ -265,20 +348,17 @@
stock have an median target of {medianPriceTarget}, with a low stock have an median target of {medianPriceTarget}, with a low
estimate of {lowPriceTarget} estimate of {lowPriceTarget}
and a high estimate of {highPriceTarget}. The median target and a high estimate of {highPriceTarget}. The median target
predicts an increase of {medianChange}% from the current stock predicts {medianChange > 0 ? "an increase" : "a decrease"} of {medianChange}%
price of {price}. from the current stock price of {price}.
</p> </p>
</div> </div>
<div> <div>
<div class="h-[160px]"> <div class="app h-[160px]">
<canvas {#if optionsPieChart !== null}
id="myChart" <Chart {init} options={optionsPieChart} class="chart" />
style="display: block; box-sizing: border-box; height: 160px; width: 352px;" {/if}
width="529"
height="240"
></canvas>
</div> </div>
<div class="-mt-2 text-center text-xl font-semibold"> <div class="-mt-36 text-center text-xl font-semibold">
Analyst Consensus: <span Analyst Consensus: <span
class="font-bold {['Strong Buy', 'Buy']?.includes( class="font-bold {['Strong Buy', 'Buy']?.includes(
consensusRating, consensusRating,
@ -338,7 +418,7 @@
<td <td
class={medianChange > 0 class={medianChange > 0
? "before:content-['+'] text-[#00FC50]" ? "before:content-['+'] text-[#00FC50]"
: "text-[#FF2F1F]"}>{lowChange}%</td : "text-[#FF2F1F]"}>{medianChange}%</td
> >
<td <td
class={highChange > 0 class={highChange > 0
@ -674,7 +754,7 @@
@media (max-width: 640px) { @media (max-width: 640px) {
.app { .app {
height: 210px; height: 300px;
} }
} }

View File

@ -1,29 +0,0 @@
export const load = async ({ locals, params }) => {
const getAnalystTickerHistory = async () => {
const { apiURL, apiKey, user } = locals;
const postData = {
ticker: params.tickerID,
};
// make the POST request to the endpoint
const response = await fetch(apiURL + "/analyst-ticker-history", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
body: JSON.stringify(postData),
});
let output = await response.json();
output = user?.tier !== "Pro" ? output?.slice(0, 6) : output;
return output;
};
// Make sure to return a promise
return {
getAnalystTickerHistory: await getAnalystTickerHistory(),
};
};