update dark pool page
This commit is contained in:
parent
fa939b926b
commit
aa697ccf45
@ -49,7 +49,10 @@
|
|||||||
premium: "none",
|
premium: "none",
|
||||||
assetType: "none",
|
assetType: "none",
|
||||||
volume: "none",
|
volume: "none",
|
||||||
|
avgVolume: "none",
|
||||||
|
dailyVolume: "none",
|
||||||
size: "none",
|
size: "none",
|
||||||
|
sector: "none",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generalized sorting function
|
// Generalized sorting function
|
||||||
@ -84,6 +87,22 @@
|
|||||||
? tickerA.localeCompare(tickerB)
|
? tickerA.localeCompare(tickerB)
|
||||||
: tickerB.localeCompare(tickerA);
|
: tickerB.localeCompare(tickerA);
|
||||||
},
|
},
|
||||||
|
sector: (a, b) => {
|
||||||
|
const sectorA = a.sector || ""; // Default to empty string if undefined
|
||||||
|
const sectorB = b.sector || ""; // Default to empty string if undefined
|
||||||
|
|
||||||
|
// Check if either sector is an empty string and ensure it's placed at the bottom
|
||||||
|
if (sectorA === "" && sectorB !== "") return 1; // Move empty string to the bottom
|
||||||
|
if (sectorB === "" && sectorA !== "") return -1; // Move empty string to the bottom
|
||||||
|
|
||||||
|
// If both are non-empty, sort normally
|
||||||
|
const stringA = sectorA.toUpperCase();
|
||||||
|
const stringB = sectorB.toUpperCase();
|
||||||
|
|
||||||
|
return sortOrder === "asc"
|
||||||
|
? stringA.localeCompare(stringB)
|
||||||
|
: stringB.localeCompare(stringA);
|
||||||
|
},
|
||||||
date: (a, b) => {
|
date: (a, b) => {
|
||||||
const timeA = new Date(a.date);
|
const timeA = new Date(a.date);
|
||||||
const timeB = new Date(b.date);
|
const timeB = new Date(b.date);
|
||||||
@ -120,7 +139,7 @@
|
|||||||
return sortOrder === "asc" ? volA - volB : volB - volA;
|
return sortOrder === "asc" ? volA - volB : volB - volA;
|
||||||
},
|
},
|
||||||
assetType: (a, b) => {
|
assetType: (a, b) => {
|
||||||
const typeOrder = { SWEEP: 1, TRADE: 2 };
|
const typeOrder = { STOCK: 1, ETF: 2 };
|
||||||
const typeA = typeOrder[a.assetType?.toUpperCase()] || 3;
|
const typeA = typeOrder[a.assetType?.toUpperCase()] || 3;
|
||||||
const typeB = typeOrder[b.assetType?.toUpperCase()] || 3;
|
const typeB = typeOrder[b.assetType?.toUpperCase()] || 3;
|
||||||
return sortOrder === "asc" ? typeA - typeB : typeB - typeA;
|
return sortOrder === "asc" ? typeA - typeB : typeB - typeA;
|
||||||
@ -136,7 +155,13 @@
|
|||||||
<div class="table">
|
<div class="table">
|
||||||
<VirtualList
|
<VirtualList
|
||||||
width="100%"
|
width="100%"
|
||||||
height={$screenWidth < 640 ? 550 : 850}
|
height={$screenWidth < 640
|
||||||
|
? data?.user?.tier === "Pro"
|
||||||
|
? 550
|
||||||
|
: 250
|
||||||
|
: data?.user?.tier === "Pro"
|
||||||
|
? 850
|
||||||
|
: 250}
|
||||||
itemCount={displayedData.length}
|
itemCount={displayedData.length}
|
||||||
itemSize={40}
|
itemSize={40}
|
||||||
>
|
>
|
||||||
@ -282,7 +307,7 @@
|
|||||||
on:click={() => sortData("dailyVolume")}
|
on:click={() => sortData("dailyVolume")}
|
||||||
class="td cursor-pointer select-none bg-[#121217] text-slate-300 font-bold text-xs text-start uppercase"
|
class="td cursor-pointer select-none bg-[#121217] text-slate-300 font-bold text-xs text-start uppercase"
|
||||||
>
|
>
|
||||||
% Daily Volume
|
% Size / Vol
|
||||||
<svg
|
<svg
|
||||||
class="flex-shrink-0 w-4 h-4 inline-block {sortOrders[
|
class="flex-shrink-0 w-4 h-4 inline-block {sortOrders[
|
||||||
'dailyVolume'
|
'dailyVolume'
|
||||||
@ -306,7 +331,7 @@
|
|||||||
on:click={() => sortData("avgVolume")}
|
on:click={() => sortData("avgVolume")}
|
||||||
class="td cursor-pointer select-none bg-[#121217] text-slate-300 font-bold text-xs text-start uppercase"
|
class="td cursor-pointer select-none bg-[#121217] text-slate-300 font-bold text-xs text-start uppercase"
|
||||||
>
|
>
|
||||||
% 30D Volume
|
% Size / Avg Vol
|
||||||
<svg
|
<svg
|
||||||
class="flex-shrink-0 w-4 h-4 inline-block {sortOrders[
|
class="flex-shrink-0 w-4 h-4 inline-block {sortOrders[
|
||||||
'avgVolume'
|
'avgVolume'
|
||||||
@ -350,15 +375,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
on:click={() => sortData("vol")}
|
on:click={() => sortData("assetType")}
|
||||||
class="td cursor-pointer select-none bg-[#121217] text-slate-300 font-bold text-xs text-start uppercase"
|
class="td cursor-pointer select-none bg-[#121217] text-slate-300 font-bold text-xs text-start uppercase"
|
||||||
>
|
>
|
||||||
Issue Type
|
Asset Type
|
||||||
<svg
|
<svg
|
||||||
class="flex-shrink-0 w-4 h-4 inline-block {sortOrders['vol'] ===
|
class="flex-shrink-0 w-4 h-4 inline-block {sortOrders[
|
||||||
'asc'
|
'assetType'
|
||||||
|
] === 'asc'
|
||||||
? 'rotate-180'
|
? 'rotate-180'
|
||||||
: sortOrders['vol'] === 'desc'
|
: sortOrders['assetType'] === 'desc'
|
||||||
? ''
|
? ''
|
||||||
: 'hidden'} "
|
: 'hidden'} "
|
||||||
viewBox="0 0 20 20"
|
viewBox="0 0 20 20"
|
||||||
@ -378,7 +404,11 @@
|
|||||||
let:index
|
let:index
|
||||||
let:style
|
let:style
|
||||||
{style}
|
{style}
|
||||||
class="tr {index % 2 === 0 ? 'bg-[#19191F]' : 'bg-[#121217]'}"
|
class="tr {index % 2 === 0 ? 'bg-[#19191F]' : 'bg-[#121217]'} {index +
|
||||||
|
1 ===
|
||||||
|
rawData?.length && data?.user?.tier !== 'Pro'
|
||||||
|
? 'opacity-[0.3]'
|
||||||
|
: ''}"
|
||||||
>
|
>
|
||||||
<!-- Row data -->
|
<!-- Row data -->
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
export const load = async ({ locals }) => {
|
export const load = async ({ locals }) => {
|
||||||
const { apiURL, apiKey } = locals;
|
const { apiURL, apiKey, user } = locals;
|
||||||
|
|
||||||
const getFlowData = async () => {
|
const getFlowData = async () => {
|
||||||
// make the POST request to the endpoint
|
// make the POST request to the endpoint
|
||||||
@ -10,7 +10,8 @@ export const load = async ({ locals }) => {
|
|||||||
"X-API-KEY": apiKey,
|
"X-API-KEY": apiKey,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const output = await response.json();
|
let output = await response.json();
|
||||||
|
output = user?.tier !== "Pro" ? output?.slice(0, 6) : output;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
import * as Popover from "$lib/components/shadcn/popover/index.js";
|
import * as Popover from "$lib/components/shadcn/popover/index.js";
|
||||||
import { Button } from "$lib/components/shadcn/button/index.js";
|
import { Button } from "$lib/components/shadcn/button/index.js";
|
||||||
import CalendarIcon from "lucide-svelte/icons/calendar";
|
import CalendarIcon from "lucide-svelte/icons/calendar";
|
||||||
|
import UpgradeToPro from "$lib/components/UpgradeToPro.svelte";
|
||||||
|
|
||||||
import { page } from "$app/stores";
|
import { page } from "$app/stores";
|
||||||
|
|
||||||
@ -25,7 +26,6 @@
|
|||||||
let shouldLoadWorker = writable(false);
|
let shouldLoadWorker = writable(false);
|
||||||
|
|
||||||
let ruleOfList = data?.getPredefinedCookieRuleOfList || [];
|
let ruleOfList = data?.getPredefinedCookieRuleOfList || [];
|
||||||
|
|
||||||
let displayRules = [];
|
let displayRules = [];
|
||||||
let filteredData = [];
|
let filteredData = [];
|
||||||
let filterQuery = $page.url.searchParams.get("query") || "";
|
let filterQuery = $page.url.searchParams.get("query") || "";
|
||||||
@ -258,8 +258,6 @@
|
|||||||
filteredData = event.data?.filteredData ?? [];
|
filteredData = event.data?.filteredData ?? [];
|
||||||
displayedData = filteredData;
|
displayedData = filteredData;
|
||||||
console.log("handle Message");
|
console.log("handle Message");
|
||||||
|
|
||||||
//console.log(displayedData)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
async function changeRuleCondition(name: string, state: string) {
|
async function changeRuleCondition(name: string, state: string) {
|
||||||
@ -694,29 +692,29 @@
|
|||||||
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" />
|
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" />
|
||||||
|
|
||||||
<title>
|
<title>
|
||||||
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""} Options
|
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""} Dark
|
||||||
Flow Feed · Stocknear
|
Pool Flow Feed · Stocknear
|
||||||
</title>
|
</title>
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content={`Explore unusual options from big institutional traders and hedge funds.`}
|
content={`Explore unusual dark pool trades from big institutional traders and hedge funds.`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Other meta tags -->
|
<!-- Other meta tags -->
|
||||||
<meta property="og:title" content={`Options Flow Feed · Stocknear`} />
|
<meta property="og:title" content={`Dark Pool Flow · Stocknear`} />
|
||||||
<meta
|
<meta
|
||||||
property="og:description"
|
property="og:description"
|
||||||
content={`Explore unusual options from big institutional traders and hedge funds.`}
|
content={`Explore unusual dark pool trades from big institutional traders and hedge funds.`}
|
||||||
/>
|
/>
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<!-- Add more Open Graph meta tags as needed -->
|
<!-- Add more Open Graph meta tags as needed -->
|
||||||
|
|
||||||
<!-- Twitter specific meta tags -->
|
<!-- Twitter specific meta tags -->
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
<meta name="twitter:title" content={`Options Flow Feed · Stocknear`} />
|
<meta name="twitter:title" content={`Dark Pool Flow · Stocknear`} />
|
||||||
<meta
|
<meta
|
||||||
name="twitter:description"
|
name="twitter:description"
|
||||||
content={`Explore unusual options from big institutional traders and hedge funds.`}
|
content={`Explore unusual dark pool trades from big institutional traders and hedge funds.`}
|
||||||
/>
|
/>
|
||||||
<!-- Add more Twitter meta tags as needed -->
|
<!-- Add more Twitter meta tags as needed -->
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
@ -837,6 +835,25 @@
|
|||||||
on:input={debouncedHandleInput}
|
on:input={debouncedHandleInput}
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
/>
|
/>
|
||||||
|
{#if filterQuery?.length > 0}
|
||||||
|
<label
|
||||||
|
class="cursor-pointer"
|
||||||
|
on:click={() => {
|
||||||
|
filterQuery = "";
|
||||||
|
shouldLoadWorker.set(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="ml-auto h-6 w-6 inline-block mr-3"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
><path
|
||||||
|
fill="white"
|
||||||
|
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
|
||||||
|
>
|
||||||
|
</label>
|
||||||
|
{:else}
|
||||||
<svg
|
<svg
|
||||||
class="ml-auto h-7 w-7 sm:h-8 sm:w-8 inline-block mr-5"
|
class="ml-auto h-7 w-7 sm:h-8 sm:w-8 inline-block mr-5"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@ -846,6 +863,7 @@
|
|||||||
d="m19.485 20.154l-6.262-6.262q-.75.639-1.725.989t-1.96.35q-2.402 0-4.066-1.663T3.808 9.503T5.47 5.436t4.064-1.667t4.068 1.664T15.268 9.5q0 1.042-.369 2.017t-.97 1.668l6.262 6.261zM9.539 14.23q1.99 0 3.36-1.37t1.37-3.361t-1.37-3.36t-3.36-1.37t-3.361 1.37t-1.37 3.36t1.37 3.36t3.36 1.37"
|
d="m19.485 20.154l-6.262-6.262q-.75.639-1.725.989t-1.96.35q-2.402 0-4.066-1.663T3.808 9.503T5.47 5.436t4.064-1.667t4.068 1.664T15.268 9.5q0 1.042-.369 2.017t-.97 1.668l6.262 6.261zM9.539 14.23q1.99 0 3.36-1.37t1.37-3.361t-1.37-3.36t-3.36-1.37t-3.361 1.37t-1.37 3.36t1.37 3.36t3.36 1.37"
|
||||||
/></svg
|
/></svg
|
||||||
>
|
>
|
||||||
|
{/if}
|
||||||
</label>
|
</label>
|
||||||
{#if notFound === true}
|
{#if notFound === true}
|
||||||
<span
|
<span
|
||||||
@ -1304,6 +1322,7 @@
|
|||||||
{#if displayedData?.length !== 0}
|
{#if displayedData?.length !== 0}
|
||||||
<div class="mt-3 w-full overflow-x-auto h-[850px] overflow-hidden">
|
<div class="mt-3 w-full overflow-x-auto h-[850px] overflow-hidden">
|
||||||
<DarkPoolTable {data} {displayedData} {filteredData} {rawData} />
|
<DarkPoolTable {data} {displayedData} {filteredData} {rawData} />
|
||||||
|
<UpgradeToPro {data} />
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div
|
<div
|
||||||
@ -1322,12 +1341,6 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--
|
|
||||||
<div class="relative bottom-[400px] w-fit m-auto flex justify-center items-center">
|
|
||||||
<UpgradeToPro data={data} title="Get the recent Options Flow Data from Hedge Funds and major institutional traders to never miss out"/>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
{:else}
|
{:else}
|
||||||
<div class="flex justify-center items-center h-80">
|
<div class="flex justify-center items-center h-80">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
|
|||||||
@ -367,7 +367,7 @@ onmessage = async (event: MessageEvent) => {
|
|||||||
let filteredData = await filterRawData(rawData, ruleOfList, filterQuery);
|
let filteredData = await filterRawData(rawData, ruleOfList, filterQuery);
|
||||||
|
|
||||||
filteredData = Array.from(
|
filteredData = Array.from(
|
||||||
new Map(filteredData?.map((item) => [item?.id, item]))?.values()
|
new Map(filteredData?.map((item) => [item?.trackingID, item]))?.values()
|
||||||
);
|
);
|
||||||
|
|
||||||
postMessage({ message: "success", filteredData });
|
postMessage({ message: "success", filteredData });
|
||||||
|
|||||||
@ -970,11 +970,30 @@
|
|||||||
id="modal-search"
|
id="modal-search"
|
||||||
type="search"
|
type="search"
|
||||||
class="text-white sm:ml-2 text-[1rem] placeholder-gray-300 border-transparent focus:border-transparent focus:ring-0 flex items-center justify-center w-full px-0 py-1.5 bg-inherit"
|
class="text-white sm:ml-2 text-[1rem] placeholder-gray-300 border-transparent focus:border-transparent focus:ring-0 flex items-center justify-center w-full px-0 py-1.5 bg-inherit"
|
||||||
placeholder="Search AAPL, SPY,..."
|
placeholder="Stock or ETF symbol..."
|
||||||
bind:value={filterQuery}
|
bind:value={filterQuery}
|
||||||
on:input={debouncedHandleInput}
|
on:input={debouncedHandleInput}
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
/>
|
/>
|
||||||
|
{#if filterQuery?.length > 0}
|
||||||
|
<label
|
||||||
|
class="cursor-pointer"
|
||||||
|
on:click={() => {
|
||||||
|
filterQuery = "";
|
||||||
|
shouldLoadWorker.set(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="ml-auto h-6 w-6 inline-block mr-3"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
><path
|
||||||
|
fill="white"
|
||||||
|
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
|
||||||
|
>
|
||||||
|
</label>
|
||||||
|
{:else}
|
||||||
<svg
|
<svg
|
||||||
class="ml-auto h-7 w-7 sm:h-8 sm:w-8 inline-block mr-5"
|
class="ml-auto h-7 w-7 sm:h-8 sm:w-8 inline-block mr-5"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@ -984,6 +1003,7 @@
|
|||||||
d="m19.485 20.154l-6.262-6.262q-.75.639-1.725.989t-1.96.35q-2.402 0-4.066-1.663T3.808 9.503T5.47 5.436t4.064-1.667t4.068 1.664T15.268 9.5q0 1.042-.369 2.017t-.97 1.668l6.262 6.261zM9.539 14.23q1.99 0 3.36-1.37t1.37-3.361t-1.37-3.36t-3.36-1.37t-3.361 1.37t-1.37 3.36t1.37 3.36t3.36 1.37"
|
d="m19.485 20.154l-6.262-6.262q-.75.639-1.725.989t-1.96.35q-2.402 0-4.066-1.663T3.808 9.503T5.47 5.436t4.064-1.667t4.068 1.664T15.268 9.5q0 1.042-.369 2.017t-.97 1.668l6.262 6.261zM9.539 14.23q1.99 0 3.36-1.37t1.37-3.361t-1.37-3.36t-3.36-1.37t-3.361 1.37t-1.37 3.36t1.37 3.36t3.36 1.37"
|
||||||
/></svg
|
/></svg
|
||||||
>
|
>
|
||||||
|
{/if}
|
||||||
</label>
|
</label>
|
||||||
{#if notFound === true}
|
{#if notFound === true}
|
||||||
<span
|
<span
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user