add price reaction section
This commit is contained in:
parent
eba8911b57
commit
32b987b8e1
@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { stockTicker, displayCompanyName } from "$lib/store";
|
import { stockTicker, displayCompanyName } from "$lib/store";
|
||||||
import { abbreviateNumber } from "$lib/utils";
|
import { abbreviateNumber } from "$lib/utils";
|
||||||
import PastEarnings from "$lib/components/PastEarnings.svelte";
|
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
let rawData = {};
|
let rawData = {};
|
||||||
@ -21,7 +20,7 @@
|
|||||||
|
|
||||||
$: {
|
$: {
|
||||||
if ($stockTicker) {
|
if ($stockTicker) {
|
||||||
rawData = data?.getNextEarnings?.next;
|
rawData = data?.getNextEarnings;
|
||||||
epsRatio =
|
epsRatio =
|
||||||
rawData?.epsPrior !== 0
|
rawData?.epsPrior !== 0
|
||||||
? ((rawData?.epsEst / rawData?.epsPrior - 1) * 100)?.toFixed(2)
|
? ((rawData?.epsEst / rawData?.epsPrior - 1) * 100)?.toFixed(2)
|
||||||
@ -100,28 +99,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if data?.getNextEarnings?.past?.length !== 0}
|
|
||||||
<div class="space-y-3 overflow-hidden mt-5 w-full">
|
|
||||||
<!--Start Content-->
|
|
||||||
<div class="w-full p-1 flex flex-col">
|
|
||||||
<div class="flex flex-col items-center w-full mb-3">
|
|
||||||
<div class="flex flex-row justify-start mr-auto items-center">
|
|
||||||
<!--<img class="h-10 inline-block mr-2" src={copilotIcon} />-->
|
|
||||||
<div class="flex flex-row items-center">
|
|
||||||
<h3
|
|
||||||
class="mr-1 flex flex-row items-center text-white text-2xl font-bold"
|
|
||||||
>
|
|
||||||
Past Earnings Volatility
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<PastEarnings
|
|
||||||
userTier={data?.user?.tier}
|
|
||||||
rawData={data?.getNextEarnings?.past}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
function changeSubSection(state) {
|
function changeSubSection(state) {
|
||||||
const subSectionMap = {
|
const subSectionMap = {
|
||||||
"market-cap": "/statistics/market-cap",
|
"market-cap": "/statistics/market-cap",
|
||||||
|
"price-reaction": "/statistics/price-reaction",
|
||||||
employees: "/statistics/employees",
|
employees: "/statistics/employees",
|
||||||
"fail-to-deliver": "/statistics/fail-to-deliver",
|
"fail-to-deliver": "/statistics/fail-to-deliver",
|
||||||
};
|
};
|
||||||
@ -23,6 +24,7 @@
|
|||||||
const parts = $page?.url?.pathname.split("/");
|
const parts = $page?.url?.pathname.split("/");
|
||||||
const sectionMap = {
|
const sectionMap = {
|
||||||
"market-cap": "market-cap",
|
"market-cap": "market-cap",
|
||||||
|
"price-reaction": "price-reaction",
|
||||||
employees: "employees",
|
employees: "employees",
|
||||||
"fail-to-deliver": "fail-to-deliver",
|
"fail-to-deliver": "fail-to-deliver",
|
||||||
};
|
};
|
||||||
@ -66,6 +68,16 @@
|
|||||||
>
|
>
|
||||||
Market Cap
|
Market Cap
|
||||||
</a>
|
</a>
|
||||||
|
<a
|
||||||
|
href={`/stocks/${$stockTicker}/statistics/price-reaction`}
|
||||||
|
on:click={() => changeSubSection("price-reaction")}
|
||||||
|
class="p-2 px-5 cursor-pointer {displaySubSection ===
|
||||||
|
'price-reaction'
|
||||||
|
? 'text-white bg-primary sm:hover:bg-opacity-[0.95]'
|
||||||
|
: 'text-gray-400 sm:hover:text-white sm:hover:bg-primary sm:hover:bg-opacity-[0.95]'}"
|
||||||
|
>
|
||||||
|
Price Reaction
|
||||||
|
</a>
|
||||||
<a
|
<a
|
||||||
href={`/stocks/${$stockTicker}/statistics/employees`}
|
href={`/stocks/${$stockTicker}/statistics/employees`}
|
||||||
on:click={() => changeSubSection("employees")}
|
on:click={() => changeSubSection("employees")}
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
export const load = async ({ locals, params }) => {
|
export const load = async ({ locals, params }) => {
|
||||||
|
|
||||||
const getSimilarStocks = async () => {
|
|
||||||
const { apiKey, apiURL } = locals;
|
const { apiKey, apiURL } = locals;
|
||||||
|
|
||||||
|
const getData = async () => {
|
||||||
const postData = {
|
const postData = {
|
||||||
ticker: params.tickerID,
|
ticker: params.tickerID,
|
||||||
};
|
};
|
||||||
|
|
||||||
// make the POST request to the endpoint
|
// make the POST request to the endpoint
|
||||||
const response = await fetch(apiURL + "/similar-stocks", {
|
const response = await fetch(apiURL + "/price-action-earnings", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@ -20,8 +20,10 @@ export const load = async ({ locals, params }) => {
|
|||||||
return output;
|
return output;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Make sure to return a promise
|
// Make sure to return a promise
|
||||||
return {
|
return {
|
||||||
getSimilarStocks: await getSimilarStocks(),
|
getData: await getData(),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -0,0 +1,413 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import {
|
||||||
|
numberOfUnreadNotification,
|
||||||
|
displayCompanyName,
|
||||||
|
stockTicker,
|
||||||
|
} from "$lib/store";
|
||||||
|
import Infobox from "$lib/components/Infobox.svelte";
|
||||||
|
|
||||||
|
export let data;
|
||||||
|
|
||||||
|
let rawData = data?.getData || [];
|
||||||
|
|
||||||
|
function checkTime(timeString) {
|
||||||
|
const [hours, minutes, seconds] = timeString.split(":").map(Number);
|
||||||
|
|
||||||
|
// Convert the time to total seconds for easy comparison
|
||||||
|
const totalSeconds = hours * 3600 + minutes * 60 + seconds;
|
||||||
|
|
||||||
|
// Define the reference times in seconds
|
||||||
|
const amcStart = 16 * 3600; // 16:00:00
|
||||||
|
const bmcEnd = 9 * 3600 + 30 * 60; // 9:30:00
|
||||||
|
|
||||||
|
if (totalSeconds >= amcStart) {
|
||||||
|
return "AMC";
|
||||||
|
} else if (totalSeconds < bmcEnd) {
|
||||||
|
return "BMC";
|
||||||
|
} else {
|
||||||
|
return "None"; // Optional: if the time is in between
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<title>
|
||||||
|
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
|
||||||
|
{$displayCompanyName} ({$stockTicker}) Value-at-Risk Stocknear
|
||||||
|
</title>
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content={`Historical Value-at-Risk of ${$stockTicker}.`}
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
property="og:title"
|
||||||
|
content={`${$displayCompanyName} (${$stockTicker}) Value-at-Risk · Stocknear`}
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content={`Historical Value-at-Risk of ${$stockTicker}.`}
|
||||||
|
/>
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
|
<meta
|
||||||
|
name="twitter:title"
|
||||||
|
content={`${$displayCompanyName} (${$stockTicker}) Value-at-Risk · Stocknear`}
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
name="twitter:description"
|
||||||
|
content={`Historical Value-at-Risk of ${$stockTicker}.`}
|
||||||
|
/>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<section
|
||||||
|
class="bg-default w-full overflow-hidden min-h-screen text-white h-full"
|
||||||
|
>
|
||||||
|
<div class="w-full flex justify-center w-full sm-auto h-full overflow-hidden">
|
||||||
|
<div
|
||||||
|
class="w-full relative flex justify-center items-center overflow-hidden"
|
||||||
|
>
|
||||||
|
<main class="w-full">
|
||||||
|
<div class="sm:pl-7 sm:pt-7 sm:pb-7 m-auto mt-2 sm:mt-0">
|
||||||
|
<div class="mb-3">
|
||||||
|
<h1 class="text-xl sm:text-2xl text-white font-bold">
|
||||||
|
Price Reaction to Earnings Reports
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if rawData?.length !== 0}
|
||||||
|
<div class="mb-10 w-full">
|
||||||
|
<Infobox
|
||||||
|
text="This table provides an overview of how a stock's price historically reacted around earnings reports. It displays key metrics like price changes over specific timeframes and Relative Strength Index (RSI)."
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="w-full overflow-x-auto">
|
||||||
|
<table
|
||||||
|
class="table-fixed leading-3 border-separate border-spacing-0 font-sans tabular-nums text-white w-full"
|
||||||
|
>
|
||||||
|
<thead
|
||||||
|
><tr class="bg-inherit text-[#c3c6d0]"
|
||||||
|
><th
|
||||||
|
class="w-44 whitespace-nowrap font-normal h-5 text-left px-1"
|
||||||
|
>Report Date</th
|
||||||
|
><th
|
||||||
|
class="px-4 last:pr-11 w-20 last:w-24.5 whitespace-nowrap font-normal h-5 text-right p-0"
|
||||||
|
>-3 Days</th
|
||||||
|
><th
|
||||||
|
class="px-4 last:pr-11 w-20 last:w-24.5 whitespace-nowrap font-normal h-5 text-right p-0"
|
||||||
|
>-2 Days</th
|
||||||
|
><th
|
||||||
|
class="px-4 last:pr-11 w-20 last:w-24.5 whitespace-nowrap font-normal h-5 text-right p-0"
|
||||||
|
>-1 Day</th
|
||||||
|
><th class="px-0 w-1 whitespace-nowrap font-normal h-5 p-0"
|
||||||
|
></th><th
|
||||||
|
class="px-4 last:pr-11 w-20 last:w-24.5 text-violet-300 font-semibold whitespace-nowrap font-normal h-5 text-right p-0"
|
||||||
|
>Open</th
|
||||||
|
><th
|
||||||
|
class="px-4 last:pr-11 w-20 last:w-24.5 text-violet-300 font-semibold whitespace-nowrap font-normal h-5 text-right p-0"
|
||||||
|
>High</th
|
||||||
|
><th
|
||||||
|
class="px-4 last:pr-11 w-20 last:w-24.5 text-violet-300 font-semibold whitespace-nowrap font-normal h-5 text-right p-0"
|
||||||
|
>Low</th
|
||||||
|
><th
|
||||||
|
class="px-4 last:pr-11 w-20 last:w-24.5 text-violet-300 font-semibold whitespace-nowrap font-normal h-5 text-right p-0"
|
||||||
|
>Close</th
|
||||||
|
><th class="px-0 w-1 whitespace-nowrap font-normal h-5 p-0"
|
||||||
|
></th><th
|
||||||
|
class="px-4 last:pr-11 w-20 last:w-24.5 whitespace-nowrap font-normal h-5 text-right p-0"
|
||||||
|
>+1 Day</th
|
||||||
|
><th
|
||||||
|
class="px-4 last:pr-11 w-20 last:w-24.5 whitespace-nowrap font-normal h-5 text-right p-0"
|
||||||
|
>+2 Days</th
|
||||||
|
><th
|
||||||
|
class="px-4 last:pr-11 w-20 last:w-24.5 whitespace-nowrap font-normal h-5 text-right p-0"
|
||||||
|
>+3 Days</th
|
||||||
|
><th
|
||||||
|
class="px-4 last:pr-11 w-20 last:w-24.5 whitespace-nowrap font-normal h-5 text-right p-0"
|
||||||
|
>+1 Week</th
|
||||||
|
><th
|
||||||
|
class="px-4 last:pr-11 w-20 last:w-24.5 whitespace-nowrap font-normal h-5 text-right p-0"
|
||||||
|
>-1 Week</th
|
||||||
|
></tr
|
||||||
|
></thead
|
||||||
|
>
|
||||||
|
{#each rawData as item, index}
|
||||||
|
<tbody class="">
|
||||||
|
<tr class="group"
|
||||||
|
><td
|
||||||
|
class="whitespace-nowrap border-l border-t border-primary py-0.5 rounded-tl-md px-1"
|
||||||
|
><div
|
||||||
|
class="flex flex-col items-start text-white font-medium w-full"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="pr-0.5 mt-2 flex flex-row items-center w-full text-sm"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{item?.date?.length !== undefined
|
||||||
|
? new Date(item?.date)?.toLocaleString(
|
||||||
|
"en-US",
|
||||||
|
{
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
|
daySuffix: "2-digit",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: "n/a"}
|
||||||
|
({item?.quarter})
|
||||||
|
</div>
|
||||||
|
<div class="ml-1 text-end">
|
||||||
|
{checkTime(item?.time)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-[#c3c6d0] text-xs -mt-2 invisible">
|
||||||
|
{item?.quarter}
|
||||||
|
{item?.year}
|
||||||
|
</div>
|
||||||
|
</div></td
|
||||||
|
><td
|
||||||
|
class="border-primary px-3.5 py-0.5 border-t border-l px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
|
||||||
|
><span class="text-white"
|
||||||
|
>{item?.backward_2_days_close}</span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="border-primary px-3.5 py-0.5 border-t px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
|
||||||
|
><span class="text-white"
|
||||||
|
>{item?.backward_1_days_close}</span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="border-primary px-3.5 py-0.5 border-t border-r rounded-tr-md px-4 last:pr-11 w-17 last:w-24.5 border-r px-1 text-right"
|
||||||
|
><span class="text-white"
|
||||||
|
>{item?.forward_0_days_close}</span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="border-primary px-3.5 py-0.5 px-4 last:pr-11 w-17 last:w-24.5 px-1"
|
||||||
|
></td><td
|
||||||
|
class="border-primary px-3.5 py-0.5 border-t border-l {index ===
|
||||||
|
0
|
||||||
|
? 'rounded-tl-md border-t-violet-500'
|
||||||
|
: ''} px-4 last:pr-11 w-17 last:w-24.5 border-l border-l-violet-500 px-1 text-right"
|
||||||
|
><span class="text-white">{item?.open}</span></td
|
||||||
|
><td
|
||||||
|
class="border-primary px-3.5 py-0.5 border-t {index ===
|
||||||
|
0
|
||||||
|
? 'border-t-violet-500'
|
||||||
|
: ''} px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
|
||||||
|
><span class="text-white">{item?.high}</span></td
|
||||||
|
><td
|
||||||
|
class="border-primary px-3.5 py-0.5 border-t {index ===
|
||||||
|
0
|
||||||
|
? 'border-t-violet-500'
|
||||||
|
: ''} px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
|
||||||
|
><span class="text-white">{item?.low?.toFixed(2)}</span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="border-primary px-3.5 py-0.5 border-t {index ===
|
||||||
|
0
|
||||||
|
? 'rounded-tr-md border-t-violet-500'
|
||||||
|
: ''} border-r border-r-violet-500 px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
|
||||||
|
><span class="text-white"
|
||||||
|
>{item?.close?.toFixed(2)}</span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="border-primary px-3.5 py-0.5 px-4 last:pr-11 w-17 last:w-24.5 px-1"
|
||||||
|
></td><td
|
||||||
|
class="border-primary px-3.5 py-0.5 border-t border-l rounded-tl-md px-4 last:pr-11 w-17 last:w-24.5 border-l px-1 text-right"
|
||||||
|
><span class="text-white"
|
||||||
|
>{item?.forward_2_days_close}</span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="border-primary px-3.5 py-0.5 border-t px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
|
||||||
|
><span class="text-white"
|
||||||
|
>{item?.forward_3_days_close}</span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="border-primary px-3.5 py-0.5 border-t px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
|
||||||
|
><span class="text-white"
|
||||||
|
>{item?.forward_4_days_close}</span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="border-primary px-3.5 py-0.5 border-t border-l px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
|
||||||
|
><span class="text-white"
|
||||||
|
>{item?.forward_6_days_close?.toFixed(2)}</span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="border-primary px-3.5 py-0.5 border-t border-r px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
|
||||||
|
><span class="text-white"
|
||||||
|
>{item?.backward_4_days_close?.toFixed(2)}</span
|
||||||
|
></td
|
||||||
|
></tr
|
||||||
|
>
|
||||||
|
<tr class="group"
|
||||||
|
><td
|
||||||
|
class="border-l border-primary pl-1 text-[#c3c6d0] text-sm px-1"
|
||||||
|
><div class="flex w-full justify-between">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="mr-1">RSI</div>
|
||||||
|
<div
|
||||||
|
class="leading-3 w-full whitespace-nowrap rounded-[3px] p-1 font-medium bg-secondary text-white"
|
||||||
|
>
|
||||||
|
{item?.rsi}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>{$stockTicker} %</div>
|
||||||
|
</div></td
|
||||||
|
><td
|
||||||
|
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-l px-1 text-right"
|
||||||
|
><span
|
||||||
|
class="w-full items-baseline justify-end whitespace-nowrap {item?.backward_2_days_change_percent >=
|
||||||
|
0
|
||||||
|
? "text-positive before:content-['+']"
|
||||||
|
: 'text-negative'}"
|
||||||
|
>{item?.backward_2_days_change_percent}%<span
|
||||||
|
class="w-0 text-center"
|
||||||
|
></span></span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-l px-1 text-right"
|
||||||
|
><span
|
||||||
|
class="w-full items-baseline justify-end whitespace-nowrap {item?.backward_1_days_change_percent >=
|
||||||
|
0
|
||||||
|
? "text-positive before:content-['+']"
|
||||||
|
: 'text-negative'}"
|
||||||
|
>{item?.backward_1_days_change_percent}%<span
|
||||||
|
class="w-0 text-center"
|
||||||
|
></span></span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-l px-1 text-right"
|
||||||
|
><span
|
||||||
|
class="w-full items-baseline justify-end whitespace-nowrap {item?.backward_1_days_change_percent >=
|
||||||
|
0
|
||||||
|
? "text-positive before:content-['+']"
|
||||||
|
: 'text-negative'}"
|
||||||
|
>{item?.backward_1_days_change_percent}%<span
|
||||||
|
class="w-0 text-center"
|
||||||
|
></span></span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 px-1 text-right"
|
||||||
|
></td><td
|
||||||
|
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-l border-l-violet-500 px-1 text-right"
|
||||||
|
><div
|
||||||
|
class="w-full whitespace-nowrap rounded-sm badge text-white text-[1rem] font-medium {item?.open_change_percent >=
|
||||||
|
0
|
||||||
|
? "bg-positive bg-opacity-[0.5] before:content-['+'] "
|
||||||
|
: 'bg-negative bg-opacity-[0.6]'}"
|
||||||
|
>
|
||||||
|
{item?.open_change_percent?.toFixed(2)}%
|
||||||
|
</div></td
|
||||||
|
><td
|
||||||
|
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 px-1 text-right"
|
||||||
|
><div
|
||||||
|
class="w-full whitespace-nowrap rounded-sm badge text-white text-[1rem] font-medium {item?.high_change_percent >=
|
||||||
|
0
|
||||||
|
? "bg-positive bg-opacity-[0.5] before:content-['+'] "
|
||||||
|
: 'bg-negative bg-opacity-[0.6]'}"
|
||||||
|
>
|
||||||
|
{item?.high_change_percent?.toFixed(2)}%
|
||||||
|
</div></td
|
||||||
|
><td
|
||||||
|
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 px-1 text-right"
|
||||||
|
><div
|
||||||
|
class="w-full whitespace-nowrap rounded-sm badge text-white text-[1rem] font-medium {item?.low_change_percent >=
|
||||||
|
0
|
||||||
|
? "bg-positive bg-opacity-[0.5] before:content-['+'] "
|
||||||
|
: 'bg-negative bg-opacity-[0.6]'}"
|
||||||
|
>
|
||||||
|
{item?.low_change_percent?.toFixed(2)}%
|
||||||
|
</div></td
|
||||||
|
><td
|
||||||
|
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-r border-r-violet-500 px-1 text-right"
|
||||||
|
><div
|
||||||
|
class="w-full whitespace-nowrap rounded-sm badge text-white text-[1rem] font-medium {item?.close_change_percent >=
|
||||||
|
0
|
||||||
|
? "bg-positive bg-opacity-[0.5] before:content-['+'] "
|
||||||
|
: 'bg-negative bg-opacity-[0.6]'}"
|
||||||
|
>
|
||||||
|
{item?.close_change_percent?.toFixed(2)}%
|
||||||
|
</div></td
|
||||||
|
><td
|
||||||
|
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 px-1 text-right"
|
||||||
|
></td><td
|
||||||
|
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-l px-1 text-right"
|
||||||
|
><span
|
||||||
|
class="w-full items-baseline justify-end whitespace-nowrap {item?.forward_2_days_change_percent >=
|
||||||
|
0
|
||||||
|
? "text-positive before:content-['+']"
|
||||||
|
: 'text-negative'}"
|
||||||
|
>{item?.forward_2_days_change_percent}%<span
|
||||||
|
class="w-0 text-center"
|
||||||
|
></span></span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 px-1 text-right"
|
||||||
|
><span
|
||||||
|
class="w-full items-baseline justify-end whitespace-nowrap {item?.forward_3_days_change_percent >=
|
||||||
|
0
|
||||||
|
? "text-positive before:content-['+']"
|
||||||
|
: 'text-negative'}"
|
||||||
|
>{item?.forward_3_days_change_percent}%<span
|
||||||
|
class="w-0 text-center"
|
||||||
|
></span></span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 px-1 text-right"
|
||||||
|
><span
|
||||||
|
class="w-full items-baseline justify-end whitespace-nowrap {item?.forward_4_days_change_percent >=
|
||||||
|
0
|
||||||
|
? "text-positive before:content-['+']"
|
||||||
|
: 'text-negative'}"
|
||||||
|
>{item?.forward_4_days_change_percent}%<span
|
||||||
|
class="w-0 text-center"
|
||||||
|
></span></span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-l px-1 text-right"
|
||||||
|
><span
|
||||||
|
class="w-full items-baseline justify-end whitespace-nowrap {item?.forward_6_days_change_percent >=
|
||||||
|
0
|
||||||
|
? "text-positive before:content-['+']"
|
||||||
|
: 'text-negative'}"
|
||||||
|
>{item?.forward_6_days_change_percent}%<span
|
||||||
|
class="w-0 text-center"
|
||||||
|
></span></span
|
||||||
|
></td
|
||||||
|
><td
|
||||||
|
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-r px-1 text-right"
|
||||||
|
><span
|
||||||
|
class="w-full items-baseline justify-end whitespace-nowrap {item?.backward_4_days_change_percent >=
|
||||||
|
0
|
||||||
|
? "text-positive before:content-['+']"
|
||||||
|
: 'text-negative'}"
|
||||||
|
>{item?.backward_4_days_change_percent}%<span
|
||||||
|
class="w-0 text-center"
|
||||||
|
></span></span
|
||||||
|
></td
|
||||||
|
></tr
|
||||||
|
>
|
||||||
|
</tbody>
|
||||||
|
{/each}
|
||||||
|
<tfoot
|
||||||
|
><tr
|
||||||
|
><td
|
||||||
|
colspan="15"
|
||||||
|
class="pt-3 text-[#c3c6d0] px-1 leading-tight text-sm"
|
||||||
|
>Daily change and RSI 14 are based on the report date for
|
||||||
|
BMO releases and the following day for AMC releases.</td
|
||||||
|
></tr
|
||||||
|
></tfoot
|
||||||
|
>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<Infobox text="No data available" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
@ -1,92 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { abbreviateNumber } from "$lib/utils";
|
|
||||||
import ArrowLogo from "lucide-svelte/icons/move-up-right";
|
|
||||||
|
|
||||||
export let data;
|
|
||||||
const similarStocks = data?.getSimilarStocks?.sort((a, b) => b?.var - a?.var);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<section class="w-full overflow-hidden">
|
|
||||||
<div class="w-full overflow-hidden m-auto">
|
|
||||||
<div class="sm:p-0 flex justify-center w-full m-auto overflow-hidden">
|
|
||||||
<div
|
|
||||||
class="relative flex justify-center items-start overflow-hidden w-full"
|
|
||||||
>
|
|
||||||
<main class="w-full lg:w-3/4">
|
|
||||||
<slot />
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<aside class="hidden lg:block relative fixed w-1/4 ml-4">
|
|
||||||
{#if data?.user?.tier !== "Pro" || data?.user?.freeTrial}
|
|
||||||
<div
|
|
||||||
class="w-full text-white border border-gray-600 rounded-md h-fit pb-4 mt-4 cursor-pointer bg-primary sm:hover:bg-secondary transition ease-out duration-100"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href="/pricing"
|
|
||||||
class="w-auto lg:w-full p-1 flex flex-col m-auto px-2 sm:px-0"
|
|
||||||
>
|
|
||||||
<div class="w-full flex justify-between items-center p-3 mt-3">
|
|
||||||
<h2 class="text-start text-xl font-semibold text-white ml-3">
|
|
||||||
Pro Subscription
|
|
||||||
</h2>
|
|
||||||
<ArrowLogo class="w-8 h-8 mr-3 flex-shrink-0" />
|
|
||||||
</div>
|
|
||||||
<span class="text-white p-3 ml-3 mr-3">
|
|
||||||
Upgrade now for unlimited access to all data and tools.
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if similarStocks?.length > 0}
|
|
||||||
<div
|
|
||||||
class="w-full p-2 text-white border border-gray-600 bg-primary rounded-md h-fit pb-4 mt-4 cursor-pointer"
|
|
||||||
>
|
|
||||||
<h3 class="p-2 pt-4 text-2xl font-semibold">Related Stocks</h3>
|
|
||||||
<table class="table table-sm table-compact w-full text-white">
|
|
||||||
<thead class="text-white"
|
|
||||||
><tr
|
|
||||||
><th
|
|
||||||
class="whitespace-nowrap border-b font-semibold text-[1rem] text-left"
|
|
||||||
>Company</th
|
|
||||||
>
|
|
||||||
<th
|
|
||||||
class="whitespace-nowrap border-b font-semibold text-[1rem] text-right"
|
|
||||||
>Value-at-Risk</th
|
|
||||||
></tr
|
|
||||||
></thead
|
|
||||||
>
|
|
||||||
<tbody>
|
|
||||||
{#each similarStocks?.slice(0, 8) as item, index}
|
|
||||||
<tr
|
|
||||||
class="border-gray-600 text-[1rem] {index !==
|
|
||||||
similarStocks?.slice(0, 8).length - 1
|
|
||||||
? 'border-b'
|
|
||||||
: ''}"
|
|
||||||
><td class="text-left text-[1rem]"
|
|
||||||
><a
|
|
||||||
href={`/stocks/${item?.symbol}`}
|
|
||||||
class="sm:hover:text-white text-blue-400"
|
|
||||||
>{item?.symbol}</a
|
|
||||||
></td
|
|
||||||
>
|
|
||||||
<td class="text-right cursor-normal text-[1rem]"
|
|
||||||
>{abbreviateNumber(item?.var) + "%"}</td
|
|
||||||
>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<a
|
|
||||||
href="/list/most-ftd-shares"
|
|
||||||
class="flex justify-center items-center rounded cursor-pointer w-full py-2 mt-3 text-[1rem] text-center font-semibold text-black m-auto sm:hover:bg-gray-300 bg-[#fff] transition duration-100"
|
|
||||||
>
|
|
||||||
Fail-to-Deliver Ranks
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</aside>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
export const load = async ({ locals, params }) => {
|
|
||||||
const { apiKey, apiURL } = locals;
|
|
||||||
|
|
||||||
const getVaR = async () => {
|
|
||||||
const postData = {
|
|
||||||
ticker: params.tickerID,
|
|
||||||
};
|
|
||||||
|
|
||||||
// make the POST request to the endpoint
|
|
||||||
const response = await fetch(apiURL + "/value-at-risk", {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-API-KEY": apiKey,
|
|
||||||
},
|
|
||||||
body: JSON.stringify(postData),
|
|
||||||
});
|
|
||||||
|
|
||||||
const output = await response.json();
|
|
||||||
return output;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const getHistoricalPrice = async () => {
|
|
||||||
const postData = { ticker: params.tickerID, timePeriod: "max" };
|
|
||||||
const response = await fetch(apiURL + "/historical-price", {
|
|
||||||
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 {
|
|
||||||
getVaR: await getVaR(),
|
|
||||||
getHistoricalPrice: await getHistoricalPrice(),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,98 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import {
|
|
||||||
numberOfUnreadNotification,
|
|
||||||
displayCompanyName,
|
|
||||||
stockTicker,
|
|
||||||
} from "$lib/store";
|
|
||||||
import Infobox from "$lib/components/Infobox.svelte";
|
|
||||||
import VaR from "$lib/components/VaR.svelte";
|
|
||||||
|
|
||||||
export let data;
|
|
||||||
|
|
||||||
let rawData = data?.getVaR || {};
|
|
||||||
if (!rawData?.history || !data?.getHistoricalPrice) {
|
|
||||||
console.error(
|
|
||||||
"Missing required data: rawData.history or data.getHistoricalPrice is undefined.",
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
for (let i = 0; i < rawData.history.length; i++) {
|
|
||||||
const entry = rawData.history[i];
|
|
||||||
const entryMonth = entry?.date; // "YYYY-MM" format
|
|
||||||
|
|
||||||
let matchingData = null;
|
|
||||||
|
|
||||||
// Find the first price at the beginning of the month
|
|
||||||
for (let j = 0; j < data.getHistoricalPrice.length; j++) {
|
|
||||||
const priceData = data.getHistoricalPrice[j];
|
|
||||||
|
|
||||||
// Extract year and month from the `time` field
|
|
||||||
const priceDate = priceData?.time?.slice(0, 7); // "YYYY-MM" format
|
|
||||||
if (priceDate === entryMonth) {
|
|
||||||
matchingData = priceData;
|
|
||||||
break; // Use the first matching entry
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the 'close' price to the entry if matching data is found
|
|
||||||
if (matchingData) {
|
|
||||||
entry.price = matchingData.close;
|
|
||||||
} else {
|
|
||||||
console.warn(`No matching data found for month: ${entry?.date}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(rawData);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width" />
|
|
||||||
<title>
|
|
||||||
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
|
|
||||||
{$displayCompanyName} ({$stockTicker}) Value-at-Risk Stocknear
|
|
||||||
</title>
|
|
||||||
<meta
|
|
||||||
name="description"
|
|
||||||
content={`Historical Value-at-Risk of ${$stockTicker}.`}
|
|
||||||
/>
|
|
||||||
<meta
|
|
||||||
property="og:title"
|
|
||||||
content={`${$displayCompanyName} (${$stockTicker}) Value-at-Risk · Stocknear`}
|
|
||||||
/>
|
|
||||||
<meta
|
|
||||||
property="og:description"
|
|
||||||
content={`Historical Value-at-Risk of ${$stockTicker}.`}
|
|
||||||
/>
|
|
||||||
<meta property="og:type" content="website" />
|
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
|
||||||
<meta
|
|
||||||
name="twitter:title"
|
|
||||||
content={`${$displayCompanyName} (${$stockTicker}) Value-at-Risk · Stocknear`}
|
|
||||||
/>
|
|
||||||
<meta
|
|
||||||
name="twitter:description"
|
|
||||||
content={`Historical Value-at-Risk of ${$stockTicker}.`}
|
|
||||||
/>
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<section
|
|
||||||
class="bg-default w-full overflow-hidden min-h-screen text-white h-full"
|
|
||||||
>
|
|
||||||
<div class="w-full flex justify-center w-full sm-auto h-full overflow-hidden">
|
|
||||||
<div
|
|
||||||
class="w-full relative flex justify-center items-center overflow-hidden"
|
|
||||||
>
|
|
||||||
<main class="w-full">
|
|
||||||
<div class="sm:p-7 m-auto mt-2 sm:mt-0">
|
|
||||||
{#if rawData?.length !== 0}
|
|
||||||
<div class="grid grid-cols-1 gap-2">
|
|
||||||
<VaR {data} {rawData} />
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<Infobox text="No data available" />
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
@ -30,6 +30,9 @@ module.exports = {
|
|||||||
odd: "#121217",
|
odd: "#121217",
|
||||||
table: "#18181D",
|
table: "#18181D",
|
||||||
default: "#09090B",
|
default: "#09090B",
|
||||||
|
positive: "#00FC50",
|
||||||
|
negative: "#FF2F1F",
|
||||||
|
neutral: "#FFA838",
|
||||||
destructive: {
|
destructive: {
|
||||||
DEFAULT: "hsl(var(--destructive) / <alpha-value>)",
|
DEFAULT: "hsl(var(--destructive) / <alpha-value>)",
|
||||||
foreground: "hsl(var(--destructive-foreground) / <alpha-value>)",
|
foreground: "hsl(var(--destructive-foreground) / <alpha-value>)",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user