This commit is contained in:
MuslemRahimi 2025-03-09 00:44:30 +01:00
parent e2f2fab507
commit 8f69e96e06
10 changed files with 162 additions and 170 deletions

View File

@ -55,7 +55,7 @@
.table { .table {
tr { tr {
@apply border-b border-gray-800; @apply border-b border-gray-300 dark:border-gray-800;
} }
} }

View File

@ -179,7 +179,9 @@
<HoverCard.Trigger <HoverCard.Trigger
class="rounded-sm underline-offset-4 hover:underline focus-visible:outline-2 focus-visible:outline-offset-8 focus-visible:outline-black" class="rounded-sm underline-offset-4 hover:underline focus-visible:outline-2 focus-visible:outline-offset-8 focus-visible:outline-black"
> >
<a href={getHref(symbol)} class="sm:hover:text-white text-blue-400" <a
href={getHref(symbol)}
class="sm:hover:text-muted dark:sm:hover:text-white text-blue-500 dark:text-blue-400"
>{symbol?.length !== 0 ? symbol : "-"}</a >{symbol?.length !== 0 ? symbol : "-"}</a
> >
</HoverCard.Trigger> </HoverCard.Trigger>

View File

@ -16,11 +16,13 @@
`; `;
</script> </script>
<tr class="bg-default border-b border-[#27272A]"> <tr
class="bg-white dark:bg-default border-b border-[#27272A] text-muted dark:text-white"
>
{#each columns as column} {#each columns as column}
<th <th
on:click={() => sortData(column.key)} on:click={() => sortData(column.key)}
class="cursor-pointer select-none text-white font-semibold text-sm whitespace-nowrap {column.align === class="cursor-pointer select-none font-semibold text-sm whitespace-nowrap {column.align ===
'right' 'right'
? 'text-end' ? 'text-end'
: 'text-start'}" : 'text-start'}"

View File

@ -17,7 +17,7 @@
{transitionConfig} {transitionConfig}
{sideOffset} {sideOffset}
class={cn( class={cn(
"z-50 min-w-[8rem] no-scrollbar rounded-md border border-gray-500 bg-default p-1 text-white shadow-md focus:outline-hidden", "z-50 min-w-[8rem] no-scrollbar rounded-md border border-gray-300 dark:border-gray-500 bg-white dark:bg-default p-1 text-muted dark:text-white shadow-md focus:outline-hidden",
className, className,
)} )}
{...$$restProps} {...$$restProps}

View File

@ -1,14 +1,14 @@
<script lang="ts"> <script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import { cn } from "$lib/utils"; import { cn } from "$lib/utils";
type $$Props = DropdownMenuPrimitive.SeparatorProps; type $$Props = DropdownMenuPrimitive.SeparatorProps;
let className: $$Props["class"] = undefined; let className: $$Props["class"] = undefined;
export { className as class }; export { className as class };
</script> </script>
<DropdownMenuPrimitive.Separator <DropdownMenuPrimitive.Separator
class={cn("-mx-1 my-1 h-px bg-gray-800", className)} class={cn("-mx-1 my-1 h-px bg-gray-300 dark:bg-gray-800", className)}
{...$$restProps} {...$$restProps}
/> />

View File

@ -18,7 +18,7 @@
{transition} {transition}
{transitionConfig} {transitionConfig}
class={cn( class={cn(
"z-50 min-w-[8rem] rounded-md border bg-default p-1 text-white shadow-lg focus:outline-hidden", "z-50 min-w-[8rem] rounded-md border bg-white dark:bg-default p-1 text-white shadow-lg focus:outline-hidden",
className, className,
)} )}
{...$$restProps} {...$$restProps}

View File

@ -53,7 +53,6 @@
import Newspaper from "lucide-svelte/icons/newspaper"; import Newspaper from "lucide-svelte/icons/newspaper";
import AudioLine from "lucide-svelte/icons/audio-lines"; import AudioLine from "lucide-svelte/icons/audio-lines";
import Gem from "lucide-svelte/icons/gem"; import Gem from "lucide-svelte/icons/gem";
import stocknear_logo from "$lib/images/stocknear_logo.png";
export let data; export let data;
@ -812,13 +811,13 @@
</Sheet.Content> </Sheet.Content>
</Sheet.Root> </Sheet.Root>
<a href="/" class="-ml-2 flex shrink-0"> <a href="/" class="-ml-2 flex flex-row items-center shrink-0">
<img <img
class="avatar w-9 3xl:w-10 rounded-full" class="avatar w-9 3xl:w-10 rounded-full"
src="/pwa-192x192.png" src="/pwa-192x192.png"
alt="Stocknear Logo" alt="Stocknear Logo"
/> />
<span class="text-muted dark:text-white font-semibold ml-2 text-lg">Stocknear</span> <span class="text-muted dark:text-white font-semibold ml-2 text-xl">Stocknear</span>
</a> </a>
<div <div

View File

@ -27,12 +27,12 @@
</script> </script>
<section <section
class="w-full max-w-3xl sm:max-w-[1400px] overflow-hidden min-h-screen pb-40 pt-5 px-4 lg:px-3" class="w-full max-w-3xl sm:max-w-[1400px] overflow-hidden min-h-screen pb-40 pt-5 px-4 lg:px-3 text-muted dark:text-white"
> >
<div class="text-sm sm:text-[1rem] breadcrumbs"> <div class="text-sm sm:text-[1rem] breadcrumbs">
<ul> <ul>
<li><a href="/" class="text-gray-300">Home</a></li> <li><a href="/" class="text-muted dark:text-gray-300">Home</a></li>
<li class="text-gray-300">Market Flow</li> <li class="text-muted dark:text-gray-300">Market Flow</li>
</ul> </ul>
</div> </div>
@ -42,18 +42,20 @@
class="relative flex justify-center items-start overflow-hidden w-full" class="relative flex justify-center items-start overflow-hidden w-full"
> >
<main class="w-full lg:w-3/4 lg:pr-10"> <main class="w-full lg:w-3/4 lg:pr-10">
<h1 class="mb-3 text-white text-2xl sm:text-3xl font-bold"> <h1 class="mb-3 text-2xl sm:text-3xl font-bold">
{activeIdx === 0 ? "Market Flow" : "Sector Flow"} {activeIdx === 0 ? "Market Flow" : "Sector Flow"}
</h1> </h1>
<nav class=" border-b-[2px] overflow-x-auto whitespace-nowrap"> <nav
<ul class="flex flex-row items-center w-full text-lg text-white"> class="border-[#2C6288] dark:border-white border-b-[2px] overflow-x-auto whitespace-nowrap"
>
<ul class="flex flex-row items-center w-full text-lg">
{#each tabs as item, i} {#each tabs as item, i}
<a <a
href={item?.path} href={item?.path}
class="p-2 px-5 cursor-pointer {activeIdx === i class="p-2 px-5 cursor-pointer {activeIdx === i
? 'text-white bg-primary/90 font-semibold' ? 'text-muted dark:text-white bg-[#EEEEEE] dark:bg-primary/90 font-semibold'
: 'text-gray-400 sm:hover:text-white sm:hover:bg-primary/90'}" : 'text-blue-500 dark:text-gray-400 sm:hover:text-muted dark:sm:hover:text-white sm:hover:bg-[#EEEEEE] dark:sm:hover:bg-primary/90'}"
> >
{item.title} {item.title}
</a> </a>
@ -67,38 +69,42 @@
</main> </main>
<aside class="hidden lg:block relative fixed w-1/4 ml-4"> <aside class="hidden lg:block relative fixed w-1/4 ml-4">
<div <div
class="w-full text-white border border-gray-600 rounded-md h-fit pb-4 mt-4 cursor-pointer bg-inherit sm:hover:bg-secondary transition ease-out duration-100" class="w-full border border-gray-300 dark:border-gray-600 rounded-md h-fit pb-4 mt-4 cursor-pointer sm:hover:shadow-lg dark:sm:hover:bg-secondary transition ease-out duration-100"
> >
<a <a
href="/list/highest-open-interest-change" href="/list/highest-open-interest-change"
class="w-auto lg:w-full p-1 flex flex-col m-auto px-2 sm:px-0" 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"> <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"> <h2 class="text-start text-xl font-semibold ml-3">
Highest OI Change Highest OI Change
</h2> </h2>
<ArrowLogo class="w-8 h-8 mr-3 shrink-0" /> <ArrowLogo
class="w-8 h-8 mr-3 shrink-0 text-gray-400 dark:text-white"
/>
</div> </div>
<span class="text-white p-3 ml-3 mr-3"> <span class=" p-3 ml-3 mr-3">
Stocks with the highest changes in open interest (OI). Stocks with the highest changes in open interest (OI).
</span> </span>
</a> </a>
</div> </div>
<div <div
class="w-full text-white border border-gray-600 rounded-md h-fit pb-4 mt-4 cursor-pointer bg-inherit sm:hover:bg-secondary transition ease-out duration-100" class="w-full border border-gray-300 dark:border-gray-600 rounded-md h-fit pb-4 mt-4 cursor-pointer sm:hover:shadow-lg dark:sm:hover:bg-secondary transition ease-out duration-100"
> >
<a <a
href="/list/highest-option-premium" href="/list/highest-option-premium"
class="w-auto lg:w-full p-1 flex flex-col m-auto px-2 sm:px-0" 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"> <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"> <h2 class="text-start text-xl font-semibold ml-3">
Highest Option Premium Highest Option Premium
</h2> </h2>
<ArrowLogo class="w-8 h-8 mr-3 shrink-0" /> <ArrowLogo
class="w-8 h-8 mr-3 shrink-0 text-gray-400 dark:text-white"
/>
</div> </div>
<span class="text-white p-3 ml-3 mr-3"> <span class=" p-3 ml-3 mr-3">
Stocks with the highest option premium. Stocks with the highest option premium.
</span> </span>
</a> </a>

View File

@ -1,8 +1,9 @@
<script lang="ts"> <script lang="ts">
import HoverStockChart from "$lib/components/HoverStockChart.svelte"; import HoverStockChart from "$lib/components/HoverStockChart.svelte";
import TableHeader from "$lib/components/Table/TableHeader.svelte"; import TableHeader from "$lib/components/Table/TableHeader.svelte";
import { abbreviateNumberWithColor } from "$lib/utils"; import { abbreviateNumber } from "$lib/utils";
import InfoModal from "$lib/components/InfoModal.svelte"; import InfoModal from "$lib/components/InfoModal.svelte";
import { mode } from "mode-watcher";
import UpgradeToPro from "$lib/components/UpgradeToPro.svelte"; import UpgradeToPro from "$lib/components/UpgradeToPro.svelte";
@ -255,8 +256,8 @@
const options = { const options = {
chart: { chart: {
type: "column", type: "column",
backgroundColor: "#09090B", backgroundColor: $mode === "light" ? "#fff" : "#09090B",
plotBackgroundColor: "#09090B", plotBackgroundColor: $mode === "light" ? "#fff" : "#09090B",
height: 360, // Set the maximum height for the chart height: 360, // Set the maximum height for the chart
animation: false, animation: false,
}, },
@ -295,7 +296,7 @@
// Loop through each point in the shared tooltip // Loop through each point in the shared tooltip
this.points.forEach((point) => { this.points.forEach((point) => {
tooltipContent += `<span class="text-white font-semibold text-sm">${point.series.name}:</span> tooltipContent += `<span class="text-white font-semibold text-sm">${point.series.name}:</span>
<span class="text-white font-normal text-sm" style="color:${point.color}">${abbreviateNumberWithColor( <span class="text-white font-normal text-sm" >${abbreviateNumber(
point.y, point.y,
)}</span><br>`; )}</span><br>`;
}); });
@ -309,14 +310,12 @@
min: startTime, // Force start at 9:30 min: startTime, // Force start at 9:30
max: endTime, // Force end at 16:10 max: endTime, // Force end at 16:10
crosshair: { crosshair: {
color: "#fff", // Set the color of the crosshair line color: $mode === "light" ? "black" : "white", // Set the color of the crosshair line
width: 1, // Adjust the line width as needed width: 1, // Adjust the line width as needed
dashStyle: "Solid", dashStyle: "Solid",
}, },
labels: { labels: {
style: { style: { color: $mode === "light" ? "black" : "white" },
color: "#fff",
},
distance: 20, // Increases space between label and axis distance: 20, // Increases space between label and axis
formatter: function () { formatter: function () {
return new Date(this.value).toLocaleTimeString("en-US", { return new Date(this.value).toLocaleTimeString("en-US", {
@ -352,9 +351,9 @@
}, },
{ {
gridLineWidth: 1, gridLineWidth: 1,
gridLineColor: "#111827", gridLineColor: $mode === "light" ? "#d1d5dc" : "#111827",
labels: { labels: {
style: { color: "white" }, style: { color: $mode === "light" ? "black" : "white" },
}, },
title: { text: null }, title: { text: null },
opposite: true, opposite: true,
@ -367,7 +366,7 @@
type: "spline", type: "spline",
data: priceSeries, data: priceSeries,
yAxis: 0, yAxis: 0,
color: "#fff", color: $mode === "light" ? "#2C6288" : "#fff",
marker: { marker: {
enabled: false, enabled: false,
states: { states: {
@ -379,12 +378,13 @@
lineWidth: 2, lineWidth: 2,
zIndex: 10, zIndex: 10,
}, },
{ {
name: "Net Call Prem", name: "Net Call Prem",
type: "spline", type: "spline",
data: netCallPremSeries, data: netCallPremSeries,
yAxis: 1, yAxis: 1,
color: "#90EE90", color: $mode === "light" ? "#208646" : "#90EE90",
marker: { marker: {
enabled: false, enabled: false,
states: { states: {
@ -399,7 +399,7 @@
type: "spline", type: "spline",
data: netPutPremSeries, data: netPutPremSeries,
yAxis: 1, yAxis: 1,
color: "#FF6B6B", color: $mode === "light" ? "#DC2626" : "#FF6B6B",
marker: { marker: {
enabled: false, enabled: false,
states: { states: {
@ -427,7 +427,11 @@
return options; return options;
} }
config = marketTideData ? getPlotOptions() : null; $: {
if ($mode) {
config = marketTideData ? getPlotOptions() : null;
}
}
</script> </script>
<SEO <SEO
@ -435,7 +439,7 @@
description="Get real-time insights on S&P 500 market flow sentiment through options premium analysis. Track trends and make informed trading decisions." description="Get real-time insights on S&P 500 market flow sentiment through options premium analysis. Track trends and make informed trading decisions."
/> />
<section class="w-full overflow-hidden"> <section class="w-full overflow-hidden text-muted dark:text-white">
<div class="w-full overflow-hidden m-auto"> <div class="w-full overflow-hidden m-auto">
<div class="sm:p-0 flex justify-center w-full m-auto overflow-hidden"> <div class="sm:p-0 flex justify-center w-full m-auto overflow-hidden">
<div <div
@ -444,18 +448,18 @@
<main class="w-full"> <main class="w-full">
<div class="w-full m-auto"> <div class="w-full m-auto">
{#if config !== null} {#if config !== null}
<p class="mt-4 text-white"> <p class="mt-4">
Market Flow evaluates the balance between advancing and Market Flow evaluates the balance between advancing and
declining stocks by analyzing SP& 500 price movements, net call declining stocks by analyzing SP& 500 price movements, net call
premiums and net put premiums, providing a real-time snapshot of premiums and net put premiums, providing a real-time snapshot of
market sentiment and momentum. <a market sentiment and momentum. <a
href="/learning-center/article/market-sentiment-through-options-activity-riding-the-tide" href="/learning-center/article/market-sentiment-through-options-activity-riding-the-tide"
class="text-blue-400 sm:hover:text-white sm:hover:underline sm:hover:underline-offset-4" class="text-blue-500 sm:hover:text-muted dark:text-blue-400 dark:sm:hover:text-white sm:hover:underline sm:hover:underline-offset-4"
>Learn more here.</a >Learn more here.</a
> >
</p> </p>
<div class="text-white text-sm italic mt-5 mb-3"> <div class=" text-sm italic mt-5 mb-3">
Last Updated: {formatDate( Last Updated: {formatDate(
findLastNonNull(marketTideData, "time"), findLastNonNull(marketTideData, "time"),
)} )}
@ -464,15 +468,16 @@
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 mb-6" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 mb-6"
> >
<div <div
class="bg-gray-800/30 rounded-lg p-4 sm:hover:bg-gray-800/40 transition-colors" class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
> >
<div class="text-[#c3c6d0] text-sm mb-2 flex items-center"> <div
class="dark:text-[#c3c6d0] text-sm mb-2 flex items-center"
>
<span>Volume</span> <span>Volume</span>
<span class="ml-1 text-yellow-400"></span>
</div> </div>
<div class="flex items-baseline"> <div class="flex items-baseline">
<span class="text-xl font-bold text-white"> <span class="text-xl font-bold">
{@html abbreviateNumberWithColor( {@html abbreviateNumber(
findLastNonNull(marketTideData, "net_volume"), findLastNonNull(marketTideData, "net_volume"),
false, false,
true, true,
@ -482,15 +487,16 @@
</div> </div>
<div <div
class="bg-gray-800/30 rounded-lg p-4 sm:hover:bg-gray-800/40 transition-colors" class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
> >
<div class="text-[#c3c6d0] text-sm mb-2 flex items-center"> <div
class="dark:text-[#c3c6d0] text-sm mb-2 flex items-center"
>
<span>Net Call Prem</span> <span>Net Call Prem</span>
<span class="ml-1 text-green-500"></span>
</div> </div>
<div class="flex items-baseline"> <div class="flex items-baseline">
<span class="text-xl font-bold text-white" <span class="text-xl font-bold"
>{@html abbreviateNumberWithColor( >{@html abbreviateNumber(
findLastNonNull(marketTideData, "net_call_premium"), findLastNonNull(marketTideData, "net_call_premium"),
false, false,
true, true,
@ -500,15 +506,16 @@
</div> </div>
<div <div
class="bg-gray-800/30 rounded-lg p-4 sm:hover:bg-gray-800/40 transition-colors" class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
> >
<div class="text-[#c3c6d0] text-sm mb-2 flex items-center"> <div
class="dark:text-[#c3c6d0] text-sm mb-2 flex items-center"
>
<span>Net Put Prem</span> <span>Net Put Prem</span>
<span class="ml-1 text-red-400"></span>
</div> </div>
<div class="flex items-baseline"> <div class="flex items-baseline">
<span class="text-xl font-bold text-white" <span class="text-xl font-bold"
>{@html abbreviateNumberWithColor( >{@html abbreviateNumber(
findLastNonNull(marketTideData, "net_put_premium"), findLastNonNull(marketTideData, "net_put_premium"),
false, false,
true, true,
@ -519,7 +526,7 @@
</div> </div>
<div <div
class=" border border-gray-800 rounded w-full" class=" border border-gray-300 dark:border-gray-800 rounded w-full"
use:highcharts={config} use:highcharts={config}
></div> ></div>
{/if} {/if}
@ -530,7 +537,7 @@
<div class="flex flex-row items-center"> <div class="flex flex-row items-center">
<label <label
for="topPosNetPrem" for="topPosNetPrem"
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl font-bold" class="mr-1 cursor-pointer flex flex-row items-center text-xl font-bold"
> >
Top Stocks by Positive Net Prem Top Stocks by Positive Net Prem
</label> </label>
@ -546,7 +553,7 @@
class="w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-auto" class="w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-auto"
> >
<table <table
class="table table-sm table-compact no-scrollbar rounded-none sm:rounded-md text-white w-full bg-table border border-gray-800 m-auto" class="table table-sm table-compact no-scrollbar rounded-none sm:rounded-md w-full bg-table border border-gray-300 dark:border-gray-800 m-auto"
> >
<thead> <thead>
<TableHeader <TableHeader
@ -558,7 +565,7 @@
<tbody> <tbody>
{#each displayPosTickers as item, index} {#each displayPosTickers as item, index}
<tr <tr
class="sm:hover:bg-[#245073]/10 border-b border-gray-800 odd:bg-odd {index + class="bg-white dark:sm:hover:bg-[#245073]/10 odd:bg-[#F6F7F8] dark:odd:bg-odd {index +
1 === 1 ===
originalPosTickers?.length && originalPosTickers?.length &&
!['Pro']?.includes(data?.user?.tier) !['Pro']?.includes(data?.user?.tier)
@ -566,7 +573,7 @@
: ''}" : ''}"
> >
<td <td
class="text-start text-sm sm:text-[1rem] whitespace-nowrap text-white" class="text-start text-sm sm:text-[1rem] whitespace-nowrap"
> >
{item?.rank} {item?.rank}
</td> </td>
@ -578,7 +585,7 @@
</td> </td>
<td <td
class="text-start text-sm sm:text-[1rem] whitespace-nowrap text-white" class="text-start text-sm sm:text-[1rem] whitespace-nowrap"
> >
{item?.name?.length > 20 {item?.name?.length > 20
? item?.name?.slice(0, 20) + "..." ? item?.name?.slice(0, 20) + "..."
@ -586,7 +593,7 @@
</td> </td>
<td <td
class="text-end text-sm sm:text-[1rem] whitespace-nowrap text-white" class="text-end text-sm sm:text-[1rem] whitespace-nowrap"
> >
{item?.price} {item?.price}
</td> </td>
@ -594,28 +601,28 @@
<td <td
class="text-sm sm:text-[1rem] {item?.changesPercentage >= class="text-sm sm:text-[1rem] {item?.changesPercentage >=
0 0
? "text-[#00FC50] before:content-['+'] " ? "text-[#208646] dark:text-[#00FC50] before:content-['+'] "
: 'text-[#FF2F1F]'} text-end" : 'text-[#DC2626] dark:text-[#FF2F1F]'} text-end"
> >
{item?.changesPercentage}% {item?.changesPercentage?.toFixed(2)}%
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{@html abbreviateNumberWithColor( {@html abbreviateNumber(
item?.net_premium, item?.net_premium,
false, false,
true, true,
)} )}
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{@html abbreviateNumberWithColor( {@html abbreviateNumber(
item?.net_call_premium, item?.net_call_premium,
false, false,
true, true,
)} )}
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{@html abbreviateNumberWithColor( {@html abbreviateNumber(
item?.net_put_premium, item?.net_put_premium,
false, false,
true, true,
@ -635,7 +642,7 @@
<div class="flex flex-row items-center"> <div class="flex flex-row items-center">
<label <label
for="topNegNetPrem" for="topNegNetPrem"
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl font-bold" class="mr-1 cursor-pointer flex flex-row items-center text-xl font-bold"
> >
Top Stocks by Negative Net Prem Top Stocks by Negative Net Prem
</label> </label>
@ -650,7 +657,7 @@
class="w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-auto" class="w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-auto"
> >
<table <table
class="table table-sm table-compact no-scrollbar rounded-none sm:rounded-md text-white w-full bg-table border border-gray-800 m-auto" class="table table-sm table-compact no-scrollbar rounded-none sm:rounded-md w-full bg-table border border-gray-300 dark:border-gray-800 m-auto"
> >
<thead> <thead>
<TableHeader <TableHeader
@ -662,7 +669,7 @@
<tbody> <tbody>
{#each displayNegTickers as item, index} {#each displayNegTickers as item, index}
<tr <tr
class="sm:hover:bg-[#245073]/10 border-b border-gray-800 odd:bg-odd {index + class="bg-white dark:sm:hover:bg-[#245073]/10 odd:bg-[#F6F7F8] dark:odd:bg-odd {index +
1 === 1 ===
originalNegTickers?.length && originalNegTickers?.length &&
!['Pro']?.includes(data?.user?.tier) !['Pro']?.includes(data?.user?.tier)
@ -670,7 +677,7 @@
: ''}" : ''}"
> >
<td <td
class="text-start text-sm sm:text-[1rem] whitespace-nowrap text-white" class="text-start text-sm sm:text-[1rem] whitespace-nowrap"
> >
{item?.rank} {item?.rank}
</td> </td>
@ -682,7 +689,7 @@
</td> </td>
<td <td
class="text-start text-sm sm:text-[1rem] whitespace-nowrap text-white" class="text-start text-sm sm:text-[1rem] whitespace-nowrap"
> >
{item?.name?.length > 20 {item?.name?.length > 20
? item?.name?.slice(0, 20) + "..." ? item?.name?.slice(0, 20) + "..."
@ -690,7 +697,7 @@
</td> </td>
<td <td
class="text-end text-sm sm:text-[1rem] whitespace-nowrap text-white" class="text-end text-sm sm:text-[1rem] whitespace-nowrap"
> >
{item?.price} {item?.price}
</td> </td>
@ -705,21 +712,21 @@
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{@html abbreviateNumberWithColor( {@html abbreviateNumber(
item?.net_premium, item?.net_premium,
false, false,
true, true,
)} )}
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{@html abbreviateNumberWithColor( {@html abbreviateNumber(
item?.net_call_premium, item?.net_call_premium,
false, false,
true, true,
)} )}
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{@html abbreviateNumberWithColor( {@html abbreviateNumber(
item?.net_put_premium, item?.net_put_premium,
false, false,
true, true,
@ -742,10 +749,3 @@
</div> </div>
</div> </div>
</section> </section>
<style lang="scss">
.chart {
width: 100%;
transition: none;
}
</style>

View File

@ -3,7 +3,7 @@
import HoverStockChart from "$lib/components/HoverStockChart.svelte"; import HoverStockChart from "$lib/components/HoverStockChart.svelte";
import TableHeader from "$lib/components/Table/TableHeader.svelte"; import TableHeader from "$lib/components/Table/TableHeader.svelte";
import { abbreviateNumberWithColor, sectorList } from "$lib/utils"; import { abbreviateNumber, sectorList } from "$lib/utils";
import InfoModal from "$lib/components/InfoModal.svelte"; import InfoModal from "$lib/components/InfoModal.svelte";
import UpgradeToPro from "$lib/components/UpgradeToPro.svelte"; import UpgradeToPro from "$lib/components/UpgradeToPro.svelte";
@ -11,6 +11,7 @@
import { Button } from "$lib/components/shadcn/button/index.js"; import { Button } from "$lib/components/shadcn/button/index.js";
import SEO from "$lib/components/SEO.svelte"; import SEO from "$lib/components/SEO.svelte";
import highcharts from "$lib/highcharts.ts"; import highcharts from "$lib/highcharts.ts";
import { mode } from "mode-watcher";
export let data; export let data;
let isLoading = false; let isLoading = false;
@ -280,8 +281,8 @@
const options = { const options = {
chart: { chart: {
type: "column", type: "column",
backgroundColor: "#09090B", backgroundColor: $mode === "light" ? "#fff" : "#09090B",
plotBackgroundColor: "#09090B", plotBackgroundColor: $mode === "light" ? "#fff" : "#09090B",
height: 360, // Set the maximum height for the chart height: 360, // Set the maximum height for the chart
animation: false, animation: false,
}, },
@ -320,7 +321,7 @@
// Loop through each point in the shared tooltip // Loop through each point in the shared tooltip
this.points.forEach((point) => { this.points.forEach((point) => {
tooltipContent += `<span class="text-white font-semibold text-sm">${point.series.name}:</span> tooltipContent += `<span class="text-white font-semibold text-sm">${point.series.name}:</span>
<span class="text-white font-normal text-sm" style="color:${point.color}">${abbreviateNumberWithColor( <span class="text-white font-normal text-sm" >${abbreviateNumber(
point.y, point.y,
)}</span><br>`; )}</span><br>`;
}); });
@ -334,13 +335,13 @@
min: startTime, // Force start at 9:30 min: startTime, // Force start at 9:30
max: endTime, // Force end at 16:10 max: endTime, // Force end at 16:10
crosshair: { crosshair: {
color: "#fff", // Set the color of the crosshair line color: $mode === "light" ? "black" : "white", // Set the color of the crosshair line
width: 1, // Adjust the line width as needed width: 1, // Adjust the line width as needed
dashStyle: "Solid", dashStyle: "Solid",
}, },
labels: { labels: {
style: { style: {
color: "#fff", color: $mode === "light" ? "black" : "white",
}, },
distance: 20, // Increases space between label and axis distance: 20, // Increases space between label and axis
formatter: function () { formatter: function () {
@ -377,9 +378,9 @@
}, },
{ {
gridLineWidth: 1, gridLineWidth: 1,
gridLineColor: "#111827", gridLineColor: $mode === "light" ? "#d1d5dc" : "#111827",
labels: { labels: {
style: { color: "white" }, style: { color: $mode === "light" ? "black" : "white" },
}, },
title: { text: null }, title: { text: null },
opposite: true, opposite: true,
@ -392,7 +393,7 @@
type: "spline", type: "spline",
data: priceSeries, data: priceSeries,
yAxis: 0, yAxis: 0,
color: "#fff", color: $mode === "light" ? "#2C6288" : "#fff",
marker: { marker: {
enabled: false, enabled: false,
states: { states: {
@ -404,12 +405,13 @@
lineWidth: 2, lineWidth: 2,
zIndex: 10, zIndex: 10,
}, },
{ {
name: "Net Call Prem", name: "Net Call Prem",
type: "spline", type: "spline",
data: netCallPremSeries, data: netCallPremSeries,
yAxis: 1, yAxis: 1,
color: "#90EE90", color: $mode === "light" ? "#208646" : "#90EE90",
marker: { marker: {
enabled: false, enabled: false,
states: { states: {
@ -424,7 +426,7 @@
type: "spline", type: "spline",
data: netPutPremSeries, data: netPutPremSeries,
yAxis: 1, yAxis: 1,
color: "#FF6B6B", color: $mode === "light" ? "#DC2626" : "#FF6B6B",
marker: { marker: {
enabled: false, enabled: false,
states: { states: {
@ -456,7 +458,7 @@
config = marketTideData ? getPlotOptions() : null; config = marketTideData ? getPlotOptions() : null;
$: { $: {
if (selectedSector) { if (selectedSector || $mode) {
topPosNetPremium = topPosNetPremium =
data?.getData?.topPosNetPremium[sectorDict[selectedSector]] || []; data?.getData?.topPosNetPremium[sectorDict[selectedSector]] || [];
topNegNetPremium = topNegNetPremium =
@ -479,7 +481,9 @@
description="Get real-time insights on all sectors of the stock market flow sentiment through options premium analysis. Track trends and make informed trading decisions." description="Get real-time insights on all sectors of the stock market flow sentiment through options premium analysis. Track trends and make informed trading decisions."
/> />
<section class="w-full max-w-3xl sm:max-w-[1400px] overflow-hidden"> <section
class="w-full max-w-3xl sm:max-w-[1400px] overflow-hidden text-muted dark:text-white"
>
<div class="w-full overflow-hidden m-auto"> <div class="w-full overflow-hidden m-auto">
<div class="sm:p-0 flex justify-center w-full m-auto overflow-hidden"> <div class="sm:p-0 flex justify-center w-full m-auto overflow-hidden">
<div <div
@ -488,7 +492,7 @@
<main class="w-full"> <main class="w-full">
<div class="w-full m-auto"> <div class="w-full m-auto">
{#if config !== null} {#if config !== null}
<p class="mt-4 text-white"> <p class="mt-4">
<strong>{selectedSector}</strong> Flow tracks sector stocks, net <strong>{selectedSector}</strong> Flow tracks sector stocks, net
call/put premiums, and price movements to gauge market sentiment call/put premiums, and price movements to gauge market sentiment
and momentum in real time. and momentum in real time.
@ -497,7 +501,7 @@
<div <div
class="flex flex-col sm:flex-row items-start sm:items-center sm:justify-between w-full mt-2 sm:mt-0" class="flex flex-col sm:flex-row items-start sm:items-center sm:justify-between w-full mt-2 sm:mt-0"
> >
<div class="text-white text-xs sm:text-sm italic mt-5 mb-5"> <div class=" text-xs sm:text-sm italic mt-5 mb-5">
Last Updated: {formatDate( Last Updated: {formatDate(
findLastNonNull(marketTideData, "time"), findLastNonNull(marketTideData, "time"),
)} )}
@ -507,10 +511,9 @@
<DropdownMenu.Trigger asChild let:builder> <DropdownMenu.Trigger asChild let:builder>
<Button <Button
builders={[builder]} builders={[builder]}
class="w-full border-gray-600 border bg-default sm:hover:bg-primary ease-out flex flex-row justify-between items-center px-3 py-2 text-white rounded-md truncate" class="w-full border-gray-300 font-semibold dark:font-normal dark:border-gray-600 border bg-white dark:bg-default sm:hover:bg-gray-100 dark:sm:hover:bg-primary ease-out flex flex-row justify-between items-center px-3 py-2 rounded-md truncate"
> >
<span class="truncate text-white">{selectedSector}</span <span class="truncate">{selectedSector}</span>
>
<svg <svg
class="-mr-1 ml-1 h-5 w-5 xs:ml-2 inline-block" class="-mr-1 ml-1 h-5 w-5 xs:ml-2 inline-block"
viewBox="0 0 20 20" viewBox="0 0 20 20"
@ -529,7 +532,7 @@
<DropdownMenu.Content <DropdownMenu.Content
class="w-56 h-fit max-h-72 overflow-y-auto scroller" class="w-56 h-fit max-h-72 overflow-y-auto scroller"
> >
<DropdownMenu.Label class="text-gray-400"> <DropdownMenu.Label class="text-muted dark:text-gray-400">
Select Sector Select Sector
</DropdownMenu.Label> </DropdownMenu.Label>
<DropdownMenu.Separator /> <DropdownMenu.Separator />
@ -538,14 +541,14 @@
{#if sector === "Technology" || data?.user?.tier === "Pro"} {#if sector === "Technology" || data?.user?.tier === "Pro"}
<DropdownMenu.Item <DropdownMenu.Item
on:click={() => (selectedSector = sector)} on:click={() => (selectedSector = sector)}
class="cursor-pointer hover:bg-primary" class="cursor-pointer sm:hover:bg-gray-300 dark:sm:hover:bg-primary"
> >
{sector} {sector}
</DropdownMenu.Item> </DropdownMenu.Item>
{:else} {:else}
<DropdownMenu.Item <DropdownMenu.Item
on:click={() => goto("/pricing")} on:click={() => goto("/pricing")}
class="cursor-pointer hover:bg-primary" class="cursor-pointer sm:hover:bg-gray-300 dark:sm:hover:bg-primary"
> >
{sector} {sector}
<svg <svg
@ -574,15 +577,14 @@
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 mb-6" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 mb-6"
> >
<div <div
class="bg-gray-800/30 rounded-lg p-4 sm:hover:bg-gray-800/40 transition-colors" class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
> >
<div class="text-[#c3c6d0] text-sm mb-2 flex items-center"> <div class=" text-sm mb-2 flex items-center">
<span>Volume</span> <span>Volume</span>
<span class="ml-1 text-yellow-400"></span>
</div> </div>
<div class="flex items-baseline"> <div class="flex items-baseline">
<span class="text-xl font-bold text-white"> <span class="text-xl font-bold">
{@html abbreviateNumberWithColor( {@html abbreviateNumber(
findLastNonNull(marketTideData, "net_volume"), findLastNonNull(marketTideData, "net_volume"),
false, false,
true, true,
@ -592,15 +594,14 @@
</div> </div>
<div <div
class="bg-gray-800/30 rounded-lg p-4 sm:hover:bg-gray-800/40 transition-colors" class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
> >
<div class="text-[#c3c6d0] text-sm mb-2 flex items-center"> <div class=" text-sm mb-2 flex items-center">
<span>Net Call Prem</span> <span>Net Call Prem</span>
<span class="ml-1 text-green-500"></span>
</div> </div>
<div class="flex items-baseline"> <div class="flex items-baseline">
<span class="text-xl font-bold text-white" <span class="text-xl font-bold"
>{@html abbreviateNumberWithColor( >{@html abbreviateNumber(
findLastNonNull(marketTideData, "net_call_premium"), findLastNonNull(marketTideData, "net_call_premium"),
false, false,
true, true,
@ -610,15 +611,14 @@
</div> </div>
<div <div
class="bg-gray-800/30 rounded-lg p-4 sm:hover:bg-gray-800/40 transition-colors" class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
> >
<div class="text-[#c3c6d0] text-sm mb-2 flex items-center"> <div class=" text-sm mb-2 flex items-center">
<span>Net Put Prem</span> <span>Net Put Prem</span>
<span class="ml-1 text-red-400"></span>
</div> </div>
<div class="flex items-baseline"> <div class="flex items-baseline">
<span class="text-xl font-bold text-white" <span class="text-xl font-bold"
>{@html abbreviateNumberWithColor( >{@html abbreviateNumber(
findLastNonNull(marketTideData, "net_put_premium"), findLastNonNull(marketTideData, "net_put_premium"),
false, false,
true, true,
@ -629,7 +629,7 @@
</div> </div>
<div <div
class="chart border border-gray-800 rounded" class="chart border border-gray-300 dark:border-gray-800 rounded"
use:highcharts={config} use:highcharts={config}
></div> ></div>
{/if} {/if}
@ -640,7 +640,7 @@
<div class="flex flex-row items-center"> <div class="flex flex-row items-center">
<label <label
for="topPosNetPrem" for="topPosNetPrem"
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl font-bold" class="mr-1 cursor-pointer flex flex-row items-center text-xl font-bold"
> >
Top Stocks by Positive Net Prem Top Stocks by Positive Net Prem
</label> </label>
@ -656,7 +656,7 @@
class="w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-auto" class="w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-auto"
> >
<table <table
class="table table-sm table-compact no-scrollbar rounded-none sm:rounded-md text-white w-full bg-table border border-gray-800 m-auto" class="table table-sm table-compact no-scrollbar rounded-none sm:rounded-md w-full bg-table border border-gray-300 dark:border-gray-300 dark:border-gray-800 m-auto"
> >
<thead> <thead>
<TableHeader <TableHeader
@ -668,7 +668,7 @@
<tbody> <tbody>
{#each displayPosTickers as item, index} {#each displayPosTickers as item, index}
<tr <tr
class="sm:hover:bg-[#245073]/10 border-b border-gray-800 odd:bg-odd {index + class="bg-white dark:sm:hover:bg-[#245073]/10 odd:bg-[#F6F7F8] dark:odd:bg-odd {index +
1 === 1 ===
originalPosTickers?.length && originalPosTickers?.length &&
!['Pro']?.includes(data?.user?.tier) !['Pro']?.includes(data?.user?.tier)
@ -676,7 +676,7 @@
: ''}" : ''}"
> >
<td <td
class="text-start text-sm sm:text-[1rem] whitespace-nowrap text-white" class="text-start text-sm sm:text-[1rem] whitespace-nowrap"
> >
{item?.rank} {item?.rank}
</td> </td>
@ -688,7 +688,7 @@
</td> </td>
<td <td
class="text-start text-sm sm:text-[1rem] whitespace-nowrap text-white" class="text-start text-sm sm:text-[1rem] whitespace-nowrap"
> >
{item?.name?.length > 20 {item?.name?.length > 20
? item?.name?.slice(0, 20) + "..." ? item?.name?.slice(0, 20) + "..."
@ -696,7 +696,7 @@
</td> </td>
<td <td
class="text-end text-sm sm:text-[1rem] whitespace-nowrap text-white" class="text-end text-sm sm:text-[1rem] whitespace-nowrap"
> >
{item?.price} {item?.price}
</td> </td>
@ -704,28 +704,28 @@
<td <td
class="text-sm sm:text-[1rem] {item?.changesPercentage >= class="text-sm sm:text-[1rem] {item?.changesPercentage >=
0 0
? "text-[#00FC50] before:content-['+'] " ? "text-[#208646] dark:text-[#00FC50] before:content-['+'] "
: 'text-[#FF2F1F]'} text-end" : 'text-[#DC2626] dark:text-[#FF2F1F]'} text-end"
> >
{item?.changesPercentage}% {item?.changesPercentage?.toFixed(2)}%
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{@html abbreviateNumberWithColor( {@html abbreviateNumber(
item?.net_premium, item?.net_premium,
false, false,
true, true,
)} )}
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{@html abbreviateNumberWithColor( {@html abbreviateNumber(
item?.net_call_premium, item?.net_call_premium,
false, false,
true, true,
)} )}
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{@html abbreviateNumberWithColor( {@html abbreviateNumber(
item?.net_put_premium, item?.net_put_premium,
false, false,
true, true,
@ -745,7 +745,7 @@
<div class="flex flex-row items-center"> <div class="flex flex-row items-center">
<label <label
for="topNegNetPrem" for="topNegNetPrem"
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl font-bold" class="mr-1 cursor-pointer flex flex-row items-center text-xl font-bold"
> >
Top Stocks by Negative Net Prem Top Stocks by Negative Net Prem
</label> </label>
@ -761,7 +761,7 @@
class="w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-auto" class="w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-auto"
> >
<table <table
class="table table-sm table-compact no-scrollbar rounded-none sm:rounded-md text-white w-full bg-table border border-gray-800 m-auto" class="table table-sm table-compact no-scrollbar rounded-none sm:rounded-md w-full bg-table border border-gray-300 dark:border-gray-300 dark:border-gray-800 m-auto"
> >
<thead> <thead>
<TableHeader <TableHeader
@ -773,7 +773,7 @@
<tbody> <tbody>
{#each displayNegTickers as item, index} {#each displayNegTickers as item, index}
<tr <tr
class="sm:hover:bg-[#245073]/10 border-b border-gray-800 odd:bg-odd {index + class="bg-white dark:sm:hover:bg-[#245073]/10 odd:bg-[#F6F7F8] dark:odd:bg-odd {index +
1 === 1 ===
originalNegTickers?.length && originalNegTickers?.length &&
!['Pro']?.includes(data?.user?.tier) !['Pro']?.includes(data?.user?.tier)
@ -781,7 +781,7 @@
: ''}" : ''}"
> >
<td <td
class="text-start text-sm sm:text-[1rem] whitespace-nowrap text-white" class="text-start text-sm sm:text-[1rem] whitespace-nowrap"
> >
{item?.rank} {item?.rank}
</td> </td>
@ -793,7 +793,7 @@
</td> </td>
<td <td
class="text-start text-sm sm:text-[1rem] whitespace-nowrap text-white" class="text-start text-sm sm:text-[1rem] whitespace-nowrap"
> >
{item?.name?.length > 20 {item?.name?.length > 20
? item?.name?.slice(0, 20) + "..." ? item?.name?.slice(0, 20) + "..."
@ -801,7 +801,7 @@
</td> </td>
<td <td
class="text-end text-sm sm:text-[1rem] whitespace-nowrap text-white" class="text-end text-sm sm:text-[1rem] whitespace-nowrap"
> >
{item?.price} {item?.price}
</td> </td>
@ -816,21 +816,21 @@
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{@html abbreviateNumberWithColor( {@html abbreviateNumber(
item?.net_premium, item?.net_premium,
false, false,
true, true,
)} )}
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{@html abbreviateNumberWithColor( {@html abbreviateNumber(
item?.net_call_premium, item?.net_call_premium,
false, false,
true, true,
)} )}
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{@html abbreviateNumberWithColor( {@html abbreviateNumber(
item?.net_put_premium, item?.net_put_premium,
false, false,
true, true,
@ -853,20 +853,3 @@
</div> </div>
</div> </div>
</section> </section>
<style>
.app {
height: 600px;
max-width: 100%; /* Ensure chart width doesn't exceed the container */
}
@media (max-width: 640px) {
.app {
height: 510px;
}
}
.chart {
width: 100%;
}
</style>