This commit is contained in:
MuslemRahimi 2025-03-26 01:46:26 +01:00
parent 022bd792d2
commit 1ff20190fa
2 changed files with 143 additions and 246 deletions

View File

@ -4,6 +4,7 @@
import * as DropdownMenu from "$lib/components/shadcn/dropdown-menu/index.js"; import * as DropdownMenu from "$lib/components/shadcn/dropdown-menu/index.js";
import { Button } from "$lib/components/shadcn/button/index.js"; import { Button } from "$lib/components/shadcn/button/index.js";
import Infobox from "$lib/components/Infobox.svelte"; import Infobox from "$lib/components/Infobox.svelte";
import { onMount } from "svelte";
import highcharts from "$lib/highcharts.ts"; import highcharts from "$lib/highcharts.ts";
import { mode } from "mode-watcher"; import { mode } from "mode-watcher";
@ -23,15 +24,15 @@
let strikeList = optionData[selectedDate] || []; let strikeList = optionData[selectedDate] || [];
let selectedStrike = strikeList?.at(0) || []; let selectedStrike = strikeList?.at(0) || [];
let optionSymbol = buildOptionSymbol(
selectedDate,
selectedOptionType,
selectedStrike,
);
let optionHistoryList = []; let displayList = [];
let selectGraphType = "Vol/OI"; let selectGraphType = "Vol/OI";
let container;
let rawDataHistory = []; let rawDataHistory = [];
let strikePrice;
let optionType;
let dateExpiration;
let otmPercentage;
const formatDate = (dateString) => { const formatDate = (dateString) => {
const date = new Date(dateString); const date = new Date(dateString);
@ -41,47 +42,24 @@
year: "numeric", year: "numeric",
}); });
}; };
function computeOTM(strikePrice, optionType) {
// Get the current stock price
const currentPrice = data?.getStockQuote?.price;
let otmPercentage = 0; function buildOptionSymbol(dateExpiration, optionType, strikePrice) {
// Format the expiration date as YYMMDD
const date = new Date(dateExpiration);
const year = date.getFullYear() % 100; // Last two digits of the year
const month = (date.getMonth() + 1).toString().padStart(2, "0"); // Months are 0-indexed
const day = date.getDate().toString().padStart(2, "0");
const expirationStr = `${year}${month}${day}`;
if (optionType === "C") { // Convert option type to a single uppercase letter (C for Call, P for Put)
// Call option: OTM is positive if strike > currentPrice, negative (ITM) otherwise const optionTypeChar = optionType.charAt(0).toUpperCase();
otmPercentage = (
((strikePrice - currentPrice) / currentPrice) *
100
)?.toFixed(2);
} else if (optionType === "P") {
// Put option: OTM is positive if strike < currentPrice, negative (ITM) otherwise
otmPercentage = (
((currentPrice - strikePrice) / currentPrice) *
100
)?.toFixed(2);
} else {
otmPercentage = "n/a";
}
return otmPercentage; // Return the percentage rounded to two decimal places // Format strike price as 8 digits (multiply by 1000 and pad with leading zeros)
} const strikePriceScaled = Math.round(strikePrice * 1000);
const strikeStr = strikePriceScaled.toString().padStart(8, "0");
function getScroll() { // Combine all components into the final option symbol
const scrollThreshold = container.scrollHeight * 0.8; // 80% of the container height return `${ticker}${expirationStr}${optionTypeChar}${strikeStr}`;
// Check if the user has scrolled to the bottom based on the threshold
const isBottom =
container.scrollTop + container.clientHeight >= scrollThreshold;
// Only load more data if at the bottom and there is still data to load
if (isBottom && optionHistoryList?.length !== rawDataHistory?.length) {
const nextIndex = optionHistoryList.length; // Ensure optionHistoryList is defined
const filteredNewResults = rawDataHistory.slice(
nextIndex,
nextIndex + 25,
); // Ensure rawData is defined
optionHistoryList = [...optionHistoryList, ...filteredNewResults];
}
} }
const currentTime = new Date( const currentTime = new Date(
@ -115,20 +93,7 @@
}); });
} }
let rawDataVolume = data?.getData?.volume?.map((item) => ({ function plotData() {
...item,
dte: daysLeft(item?.date_expiration),
otm: computeOTM(item?.strike_price, item?.option_type),
}));
let rawDataOI = data?.getData?.openInterest?.map((item) => ({
...item,
dte: daysLeft(item?.date_expiration),
otm: computeOTM(item?.strike_price, item?.option_type),
}));
function plotContractHistory() {
// Ensure rawDataHistory exists and sort it by date
const sortedData = const sortedData =
rawDataHistory?.sort((a, b) => new Date(a?.date) - new Date(b?.date)) || rawDataHistory?.sort((a, b) => new Date(a?.date) - new Date(b?.date)) ||
[]; [];
@ -173,20 +138,20 @@
new Date(item.date).getTime(), new Date(item.date).getTime(),
item.mark, item.mark,
]), ]),
color: "#FAD776", color: "#FF0006",
yAxis: 2, yAxis: 2,
animation: false, animation: false,
marker: { enabled: false }, marker: { enabled: false },
}, },
{ {
name: "Price", name: "Stock Price",
type: "spline", type: "spline",
yAxis: 1, yAxis: 1,
data: filteredData.map((item) => [ data: filteredData.map((item) => [
new Date(item.date).getTime(), new Date(item.date).getTime(),
item.price, item.price,
]), ]),
color: "#fff", color: $mode === "light" ? "#005AFF" : "white",
lineWidth: 1, lineWidth: 1,
marker: { enabled: false }, marker: { enabled: false },
animation: false, animation: false,
@ -213,21 +178,21 @@
new Date(item.date).getTime(), new Date(item.date).getTime(),
item.mark, item.mark,
]), ]),
color: "#FAD776", color: "#FF0006",
yAxis: 2, yAxis: 2,
lineWidth: 1, lineWidth: 1,
animation: false, animation: false,
marker: { enabled: false }, marker: { enabled: false },
}, },
{ {
name: "Price", name: "Stock Price",
type: "spline", type: "spline",
yAxis: 1, yAxis: 1,
data: filteredData.map((item) => [ data: filteredData.map((item) => [
new Date(item.date).getTime(), new Date(item.date).getTime(),
item.price, item.price,
]), ]),
color: "#fff", color: $mode === "light" ? "#005AFF" : "white",
lineWidth: 1, lineWidth: 1,
marker: { enabled: false }, marker: { enabled: false },
animation: false, animation: false,
@ -242,16 +207,31 @@
animation: false, animation: false,
height: 360, height: 360,
}, },
legend: {
enabled: true,
align: "left", // Positions legend at the left edge
verticalAlign: "top", // Positions legend at the top
layout: "horizontal", // Align items horizontally (use 'vertical' if preferred)
itemStyle: {
color: $mode === "light" ? "black" : "white",
},
symbolWidth: 16, // Controls the width of the legend symbol
symbolRadius: 8, // Creates circular symbols (adjust radius as needed)
squareSymbol: false, // Ensures symbols are circular, not square
},
credits: { enabled: false }, credits: { enabled: false },
title: { title: {
text: `<h3 class="mt-3 mb-1 text-[1rem] sm:text-lg">Contract History</h3>`, text: `<h3 class="mt-3 mb-1 text-[1rem] sm:text-lg">${ticker}
${formatDate(selectedDate)}
${selectedStrike}
${selectedOptionType}</h3>`,
useHTML: true, useHTML: true,
style: { color: "white" }, style: { color: $mode === "light" ? "black" : "white" },
}, },
// Disable markers globally on hover for all series // Disable markers globally on hover for all series
plotOptions: { plotOptions: {
series: { series: {
color: "white", color: $mode === "light" ? "black" : "white",
animation: false, // Disable series animation animation: false, // Disable series animation
states: { states: {
hover: { hover: {
@ -264,12 +244,12 @@
type: "datetime", type: "datetime",
endOnTick: false, endOnTick: false,
crosshair: { crosshair: {
color: "#fff", color: $mode === "light" ? "black" : "white",
width: 1, width: 1,
dashStyle: "Solid", dashStyle: "Solid",
}, },
labels: { labels: {
style: { color: "#fff" }, style: { color: $mode === "light" ? "black" : "white" },
distance: 20, distance: 20,
formatter: function () { formatter: function () {
return new Date(this.value).toLocaleDateString("en-US", { return new Date(this.value).toLocaleDateString("en-US", {
@ -293,8 +273,8 @@
yAxis: [ yAxis: [
{ {
gridLineWidth: 1, gridLineWidth: 1,
gridLineColor: "#111827", gridLineColor: $mode === "light" ? "#d1d5dc" : "#111827",
labels: { style: { color: "white" } }, labels: { style: { color: $mode === "light" ? "black" : "white" } },
title: { text: null }, title: { text: null },
opposite: true, opposite: true,
}, },
@ -327,7 +307,7 @@
}, },
borderRadius: 4, borderRadius: 4,
formatter: function () { formatter: function () {
let tooltipContent = `<span class=" m-auto text-black text-[1rem] font-[501]">${new Date( let tooltipContent = `<span class=" m-auto text-[1rem] font-[501]">${new Date(
this.x, this.x,
).toLocaleDateString("en-US", { ).toLocaleDateString("en-US", {
year: "numeric", year: "numeric",
@ -337,14 +317,13 @@
this.points.forEach((point) => { this.points.forEach((point) => {
tooltipContent += `<span class=" font-semibold text-sm">${point.series.name}:</span> tooltipContent += `<span class=" font-semibold text-sm">${point.series.name}:</span>
<span class=" font-normal text-sm" style="color:${point.color}">${abbreviateNumber( <span class=" font-normal text-sm" >${abbreviateNumber(
point.y, point.y,
)}</span><br>`; )}</span><br>`;
}); });
return tooltipContent; return tooltipContent;
}, },
}, },
legend: { enabled: false },
series: series, series: series,
}; };
@ -379,19 +358,26 @@
return output; return output;
}; };
async function handleViewData(item) { async function handleScroll() {
const scrollThreshold = document.body.offsetHeight * 0.8; // 80% of the website height
const isBottom = window.innerHeight + window.scrollY >= scrollThreshold;
if (isBottom && displayList?.length !== rawDataHistory?.length) {
const nextIndex = displayList?.length;
const filteredNewResults = rawDataHistory?.slice(
nextIndex,
nextIndex + 50,
);
displayList = [...displayList, ...filteredNewResults];
}
}
onMount(async () => {
if (selectGraphType) {
isLoaded = false; isLoaded = false;
selectGraphType = "Vol/OI";
optionDetailsDesktopModal?.showModal();
strikePrice = item?.strike_price; const output = await getContractHistory(optionSymbol);
optionType = item?.option_type;
dateExpiration = item?.date_expiration;
otmPercentage = item?.otm;
const output = await getContractHistory(item?.option_symbol);
rawDataHistory = output?.history; rawDataHistory = output?.history;
if (rawDataHistory?.length > 0) { if (rawDataHistory?.length > 0) {
rawDataHistory.forEach((entry) => { rawDataHistory.forEach((entry) => {
const matchingData = data?.getHistoricalPrice?.find( const matchingData = data?.getHistoricalPrice?.find(
@ -402,12 +388,12 @@
} }
}); });
rawDataHistory = calculateDTE(rawDataHistory, dateExpiration); rawDataHistory = calculateDTE(rawDataHistory, selectedDate);
config = plotContractHistory(); config = plotData();
rawDataHistory = rawDataHistory?.sort( rawDataHistory = rawDataHistory?.sort(
(a, b) => new Date(b?.date) - new Date(a?.date), (a, b) => new Date(b?.date) - new Date(a?.date),
); );
optionHistoryList = rawDataHistory?.slice(0, 20); displayList = rawDataHistory?.slice(0, 20);
} else { } else {
config = null; config = null;
} }
@ -415,18 +401,11 @@
isLoaded = true; isLoaded = true;
} }
$: { window.addEventListener("scroll", handleScroll);
if (selectGraphType) { return () => {
isLoaded = false; window.removeEventListener("scroll", handleScroll);
if (rawDataHistory?.length > 0) { };
config = plotContractHistory(); });
} else {
config = null;
}
isLoaded = true;
}
}
</script> </script>
<section class="w-full overflow-hidden"> <section class="w-full overflow-hidden">
@ -454,9 +433,9 @@
> >
<!--Start Added Rules--> <!--Start Added Rules-->
<div <div
class="flex items-center justify-between space-x-2 px-1 py-1.5 text-smaller leading-tight sm:border-none py-3 sm:py-0 border-b border-gray-300 dark:border-gray-600" class="flex items-center justify-between space-x-2 px-1 py-1.5 leading-tight sm:py-0 border-b border-gray-300 dark:border-gray-600"
> >
<div class="hide-scroll"> <div class="hide-scroll mb-1">
Date Expiration Date Expiration
<span class="relative" role="tooltip" <span class="relative" role="tooltip"
><label for="mobileTooltip" class="relative" role="tooltip"> ><label for="mobileTooltip" class="relative" role="tooltip">
@ -480,7 +459,7 @@
<DropdownMenu.Trigger asChild let:builder> <DropdownMenu.Trigger asChild let:builder>
<Button <Button
builders={[builder]} builders={[builder]}
class="border-gray-300 dark:border-none shadow-sm bg-white dark:bg-[#000] h-[35px] flex flex-row justify-between items-center min-w-[130px] w-[140px] sm:w-auto px-3 rounded-md truncate" class="mb-1 border-gray-300 dark:border-none shadow-sm bg-white dark:bg-[#000] h-[35px] flex flex-row justify-between items-center min-w-[130px] w-[140px] sm:w-auto px-3 rounded-md truncate"
> >
<span class="truncate text-sm" <span class="truncate text-sm"
>{formatDate(selectedDate)}</span >{formatDate(selectedDate)}</span
@ -519,9 +498,9 @@
</DropdownMenu.Root> </DropdownMenu.Root>
</div> </div>
<div <div
class="flex items-center justify-between space-x-2 px-1 py-1.5 text-smaller leading-tight sm:border-none py-3 sm:py-0 border-b border-gray-300 dark:border-gray-600" class="flex items-center justify-between space-x-2 px-1 py-1.5 leading-tight sm:py-0 border-b border-gray-300 dark:border-gray-600"
> >
<div class="hide-scroll"> <div class="hide-scroll mb-1">
Strike Price Strike Price
<span class="relative" role="tooltip" <span class="relative" role="tooltip"
><label for="mobileTooltip" class="relative" role="tooltip"> ><label for="mobileTooltip" class="relative" role="tooltip">
@ -545,7 +524,7 @@
<DropdownMenu.Trigger asChild let:builder> <DropdownMenu.Trigger asChild let:builder>
<Button <Button
builders={[builder]} builders={[builder]}
class="border-gray-300 dark:border-none shadow-sm bg-white dark:bg-[#000] h-[35px] flex flex-row justify-between items-center min-w-[130px] w-[140px] sm:w-auto px-3 rounded-md truncate" class="mb-1 border-gray-300 dark:border-none shadow-sm bg-white dark:bg-[#000] h-[35px] flex flex-row justify-between items-center min-w-[130px] w-[140px] sm:w-auto px-3 rounded-md truncate"
> >
<span class="truncate text-sm">{selectedStrike}</span> <span class="truncate text-sm">{selectedStrike}</span>
<svg <svg
@ -583,9 +562,9 @@
</DropdownMenu.Root> </DropdownMenu.Root>
</div> </div>
<div <div
class="flex items-center justify-between space-x-2 px-1 py-1.5 text-smaller leading-tight sm:border-none py-3 sm:py-0 border-b border-gray-300 dark:border-gray-600" class="flex items-center justify-between space-x-2 px-1 py-1.5 leading-tight sm:py-0 border-b border-gray-300 dark:border-gray-600"
> >
<div class="hide-scroll"> <div class="hide-scroll mb-1">
Option Type Option Type
<span class="relative" role="tooltip" <span class="relative" role="tooltip"
><label for="mobileTooltip" class="relative" role="tooltip"> ><label for="mobileTooltip" class="relative" role="tooltip">
@ -609,7 +588,7 @@
<DropdownMenu.Trigger asChild let:builder> <DropdownMenu.Trigger asChild let:builder>
<Button <Button
builders={[builder]} builders={[builder]}
class="border-gray-300 dark:border-none shadow-sm bg-white dark:bg-[#000] h-[35px] flex flex-row justify-between items-center min-w-[130px] w-[140px] sm:w-auto px-3 rounded-md truncate" class="mb-1 border-gray-300 dark:border-none shadow-sm bg-white dark:bg-[#000] h-[35px] flex flex-row justify-between items-center min-w-[130px] w-[140px] sm:w-auto px-3 rounded-md truncate"
> >
<span class="truncate text-sm">{selectedOptionType}</span> <span class="truncate text-sm">{selectedOptionType}</span>
<svg <svg
@ -653,12 +632,15 @@
<h3 <h3
class=" flex flex-row items-center text-xl sm:text-xl font-bold mt-10" class=" flex flex-row items-center text-xl sm:text-xl font-bold mt-10"
> >
{ticker} Mar 28, 2025 50.0 Call {ticker}
{formatDate(selectedDate)}
{selectedStrike}
{selectedOptionType}
</h3> </h3>
<h3 <h3
class="text-gray-500 dark:text-gray-400 flex flex-row items-center text-sm sm:text-[1rem] mb-2 sm:mb-0" class="text-gray-500 dark:text-gray-400 flex flex-row items-center text-sm sm:text-[1rem] mb-2 sm:mb-0"
> >
NVDA250328C00050000 {optionSymbol}
</h3> </h3>
<div <div
@ -674,7 +656,7 @@
> >
<td <td
class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]" class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]"
>n/a</td >{rawDataHistory?.at(0)?.close || "n/a"}</td
></tr ></tr
> >
@ -686,7 +668,7 @@
> >
<td <td
class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]" class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]"
>n/a</td >{rawDataHistory?.at(0)?.high || "n/a"}</td
></tr ></tr
> >
@ -698,7 +680,7 @@
> >
<td <td
class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]" class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]"
>n/a</td >{rawDataHistory?.at(0)?.low || "n/a"}</td
></tr ></tr
> >
@ -706,11 +688,11 @@
class="flex flex-col border-b border-gray-300 dark:border-gray-600 py-1 sm:table-row sm:py-0" class="flex flex-col border-b border-gray-300 dark:border-gray-600 py-1 sm:table-row sm:py-0"
><td ><td
class="whitespace-nowrap px-0.5 py-[1px] xs:px-1 sm:py-2 text-[1rem]" class="whitespace-nowrap px-0.5 py-[1px] xs:px-1 sm:py-2 text-[1rem]"
>Mid >Open
</td> </td>
<td <td
class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]" class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]"
>n/a</td >{rawDataHistory?.at(0)?.open || "n/a"}</td
></tr ></tr
> >
<tr <tr
@ -721,7 +703,7 @@
</td> </td>
<td <td
class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]" class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]"
>n/a</td >{rawDataHistory?.at(0)?.volume || "n/a"}</td
></tr ></tr
> >
<tr <tr
@ -732,7 +714,7 @@
</td> </td>
<td <td
class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]" class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]"
>n/a</td >{rawDataHistory?.at(0)?.open_interest || "n/a"}</td
></tr ></tr
> >
</tbody> </tbody>
@ -747,7 +729,7 @@
> >
<td <td
class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]" class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]"
>n/a</td >{rawDataHistory?.at(0)?.implied_volatility || "n/a"}</td
></tr ></tr
> >
@ -759,7 +741,7 @@
> >
<td <td
class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]" class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]"
>n/a</td >{rawDataHistory?.at(0)?.delta || "n/a"}</td
></tr ></tr
> >
@ -771,7 +753,7 @@
> >
<td <td
class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]" class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]"
>n/a</td >{rawDataHistory?.at(0)?.gamma || "n/a"}</td
></tr ></tr
> >
@ -784,7 +766,7 @@
<td <td
class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]" class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]"
> >
n/a {rawDataHistory?.at(0)?.theta || "n/a"}
</td></tr </td></tr
> >
<tr <tr
@ -796,98 +778,23 @@
<td <td
class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]" class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]"
> >
n/a {rawDataHistory?.at(0)?.vega || "n/a"}
</td></tr </td></tr
> >
<tr class="flex flex-col py-1 sm:table-row sm:py-0" <tr class="flex flex-col py-1 sm:table-row sm:py-0"
><td ><td
class="whitespace-nowrap px-0.5 py-[1px] xs:px-1 sm:py-2 text-[1rem] invisible" class="whitespace-nowrap px-0.5 py-[1px] xs:px-1 sm:py-2 text-[1rem] invisible"
>Vega</td >XXX</td
> >
<td <td
class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem] invisible" class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm xs:px-1 sm:py-2 sm:text-right sm:text-[1rem] invisible"
> >
n/a XXX
</td></tr </td></tr
> >
</tbody> </tbody>
</table> </table>
</div> </div>
</div>
</div>
</div>
</section>
<dialog
id="optionDetailsDesktopModal"
class="modal {$screenWidth < 640 ? 'modal-bottom ' : ''} bg-[#000]/40 sm:px-5"
>
<div
class="modal-box bg-white dark:bg-default w-full {rawDataHistory?.length > 0
? 'max-w-7xl'
: 'w-full'} rounded-md border-t sm:border border-gray-300 dark:border-gray-800 min-h-48 h-auto"
>
<form
method="dialog"
class="modal-backdrop backdrop-blur-[4px] flex flex-row items-center w-full justify-between"
>
<p
class="text-muted dark:text-white text-[1rem] sm:text-xl font-semibold cursor-text"
>
Contract: <span
class={optionType === "Calls"
? "text-green-600 dark:text-[#00FC50]"
: "text-red-600 dark:text-[#FF2F1F]"}
>{ticker}
{strikePrice}
{optionType}
{dateExpiration} ({daysLeft(dateExpiration)})
</span>
</p>
<button class="cursor-pointer text-[1.8rem] focus:outline-hidden">
<svg
class="w-8 h-8 text-muted dark:text-white"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="currentColor"
d="m6.4 18.308l-.708-.708l5.6-5.6l-5.6-5.6l.708-.708l5.6 5.6l5.6-5.6l.708.708l-5.6 5.6l5.6 5.6l-.708.708l-5.6-5.6z"
/>
</svg>
</button>
</form>
{#if rawDataHistory?.length > 0}
<div
class="border-b border-gray-300 dark:border-gray-800 w-full mt-2 mb-2 sm:mb-3 sm:mt-3"
></div>
<div class="hidden sm:flex flex-wrap pb-2">
<div class="mr-3 whitespace-nowrap">
{formatDate(optionHistoryList?.at(0)?.date)}:
</div>
<div class="mr-3 whitespace-nowrap">
<span class="text-[var(--light-text-color)] font-normal">Vol:</span>
{optionHistoryList?.at(0)?.volume?.toLocaleString("en-US")}
</div>
<div class="mr-3 whitespace-nowrap">
<span class="text-[var(--light-text-color)] font-normal">OI:</span>
{optionHistoryList?.at(0)?.open_interest?.toLocaleString("en-US")}
</div>
<div class="mr-3 whitespace-nowrap">
<span class="text-[var(--light-text-color)] font-normal">Avg:</span>
${optionHistoryList?.at(0)?.mark}
</div>
<div class="mr-3 whitespace-nowrap">
<span class="text-[var(--light-text-color)] font-normal">Prem:</span>
{abbreviateNumber(optionHistoryList?.at(0)?.total_premium, true)}
</div>
<div class="mr-3 whitespace-nowrap">
<span class="text-[var(--light-text-color)] font-normal">IV:</span>
{(optionHistoryList?.at(0)?.implied_volatility * 100)?.toLocaleString(
"en-US",
)}%
</div>
</div>
<div class="pb-8 sm:pb-2 rounded-md overflow-hidden"> <div class="pb-8 sm:pb-2 rounded-md overflow-hidden">
<div <div
@ -904,17 +811,14 @@
</label> </label>
{/each} {/each}
</div> </div>
{#if config}
<div <div
class="mt-2 border border-gray-300 dark:border-gray-800 rounded" class="mt-2 border border-gray-300 dark:border-gray-800 rounded"
use:highcharts={config} use:highcharts={config}
></div> ></div>
{/if}
</div> </div>
<div
bind:this={container}
on:scroll={getScroll}
class="h-full max-h-[500px] overflow-y-auto overflow-x-auto"
>
<div class="flex justify-start items-center m-auto cursor-normal"> <div class="flex justify-start items-center m-auto cursor-normal">
{#if isLoaded} {#if isLoaded}
<table <table
@ -936,12 +840,14 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{#each optionHistoryList as item} {#each displayList as item}
<!-- row --> <!-- row -->
<tr <tr
class="dark:sm:hover:bg-[#245073]/10 odd:bg-[#F6F7F8] dark:odd:bg-odd" class="dark:sm:hover:bg-[#245073]/10 odd:bg-[#F6F7F8] dark:odd:bg-odd"
> >
<td class="text-sm sm:text-[1rem] text-start"> <td
class="text-sm sm:text-[1rem] text-start whitespace-nowrap"
>
{formatDate(item?.date)} {formatDate(item?.date)}
</td> </td>
@ -1027,15 +933,6 @@
{/if} {/if}
</div> </div>
</div> </div>
{:else}
<div
class="mt-10 flex justify-center sm:justify-start items-center w-full"
>
No historical data available yet for the given contract
</div> </div>
{/if}
</div> </div>
<form method="dialog" class="modal-backdrop"> </section>
<button>close</button>
</form>
</dialog>

View File

@ -75,7 +75,7 @@
title: { title: {
text: `<h3 class="mt-3 mb-1 ">${title === "Gamma" ? "GEX" : "DEX"} Chart</h3>`, text: `<h3 class="mt-3 mb-1 ">${title === "Gamma" ? "GEX" : "DEX"} Chart</h3>`,
style: { style: {
color: "white", color: $mode === "light" ? "black" : "white",
// Using inline CSS for margin-top and margin-bottom // Using inline CSS for margin-top and margin-bottom
}, },
useHTML: true, // Enable HTML to apply custom class styling useHTML: true, // Enable HTML to apply custom class styling