diff --git a/src/routes/stocks/[tickerID]/options/gex/+page.svelte b/src/routes/stocks/[tickerID]/options/gex/+page.svelte
index 25348aea..d854d4cb 100644
--- a/src/routes/stocks/[tickerID]/options/gex/+page.svelte
+++ b/src/routes/stocks/[tickerID]/options/gex/+page.svelte
@@ -145,7 +145,7 @@
grid: {
left: $screenWidth < 640 ? "5%" : "0%",
right: $screenWidth < 640 ? "5%" : "0%",
- bottom: "20%",
+ bottom: "10%",
containLabel: true,
},
xAxis: [
@@ -256,7 +256,7 @@
{ key: "date", label: "Date", align: "left" },
{ key: "call_gamma", label: "Call GEX", align: "right" },
{ key: "put_gamma", label: "Put GEX", align: "right" },
- { key: "put_gamma", label: "Net GEX", align: "right" },
+ { key: "net_gamma", label: "Net GEX", align: "right" },
{ key: "put_call_ratio", label: "P/C GEX", align: "right" },
];
diff --git a/src/routes/stocks/[tickerID]/options/gex/expiry/+page.server.ts b/src/routes/stocks/[tickerID]/options/gex/expiry/+page.server.ts
new file mode 100644
index 00000000..9e7bd003
--- /dev/null
+++ b/src/routes/stocks/[tickerID]/options/gex/expiry/+page.server.ts
@@ -0,0 +1,35 @@
+
+
+export const load = async ({ locals, params }) => {
+ const { apiKey, apiURL, user } = locals;
+
+ const getData = async () => {
+ const postData = {
+ params: params.tickerID,
+ category: "expiry"
+ };
+
+ const response = await fetch(apiURL + "/options-gex-dex", {
+ 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 {
+ getData: await getData(),
+ };
+};
+
+
diff --git a/src/routes/stocks/[tickerID]/options/gex/expiry/+page.svelte b/src/routes/stocks/[tickerID]/options/gex/expiry/+page.svelte
index e69de29b..ad8a35a2 100644
--- a/src/routes/stocks/[tickerID]/options/gex/expiry/+page.svelte
+++ b/src/routes/stocks/[tickerID]/options/gex/expiry/+page.svelte
@@ -0,0 +1,431 @@
+
+
+
+
+
+
+ {$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
+ {$displayCompanyName} ({$stockTicker}) Gamma Exposure by Strike Price ·
+ Stocknear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {#if rawData?.length > 0}
+
+
+ Gamma Exposure By Expiry
+
+
+
+ {#if options !== null}
+
+
+
+ {:else}
+
+ {/if}
+
+
+
+
+
+
+
+ {#each displayList as item, index}
+
+ |
+ {formatDate(item?.expiry)}
+ |
+
+ {@html abbreviateNumberWithColor(
+ item?.call_gex?.toFixed(2),
+ false,
+ true,
+ )}
+ |
+
+ {@html abbreviateNumberWithColor(
+ item?.put_gex?.toFixed(2),
+ false,
+ true,
+ )}
+ |
+
+
+ {@html abbreviateNumberWithColor(
+ item?.net_gex?.toFixed(2),
+ false,
+ true,
+ )}
+ |
+
+
+ {#if item?.put_call_ratio <= 1 && item?.put_call_ratio !== null}
+ {item?.put_call_ratio?.toFixed(2)}
+ {:else if item?.put_call_ratio > 1 && item?.put_call_ratio !== null}
+ {item?.put_call_ratio?.toFixed(2)}
+ {:else}
+ n/a
+ {/if}
+ |
+
+ {/each}
+
+
+
+
+
+
+ {:else}
+
+
+ Hottest Contracts
+
+
+
+
+
+ {/if}
+
+
+
+
+
diff --git a/src/routes/stocks/[tickerID]/options/gex/strike/+page.server.ts b/src/routes/stocks/[tickerID]/options/gex/strike/+page.server.ts
index a6db54dc..f33b0e12 100644
--- a/src/routes/stocks/[tickerID]/options/gex/strike/+page.server.ts
+++ b/src/routes/stocks/[tickerID]/options/gex/strike/+page.server.ts
@@ -6,7 +6,7 @@ export const load = async ({ locals, params }) => {
const getData = async () => {
const postData = {
params: params.tickerID,
- category: "overview"
+ category: "strike"
};
const response = await fetch(apiURL + "/options-gex-dex", {
@@ -23,27 +23,12 @@ export const load = async ({ locals, params }) => {
};
- const getHistoricalPrice = async () => {
- const postData = { ticker: params.tickerID, timePeriod: "one-year" };
- 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 {
getData: await getData(),
- getHistoricalPrice: await getHistoricalPrice(),
};
};
diff --git a/src/routes/stocks/[tickerID]/options/gex/strike/+page.svelte b/src/routes/stocks/[tickerID]/options/gex/strike/+page.svelte
index 3747adfc..a1ecbc8a 100644
--- a/src/routes/stocks/[tickerID]/options/gex/strike/+page.svelte
+++ b/src/routes/stocks/[tickerID]/options/gex/strike/+page.svelte
@@ -39,201 +39,107 @@
rawData = rawData?.map((item) => ({
...item,
- net_gamma: (item?.call_gamma || 0) + (item?.put_gamma || 0),
+ net_gex: (item?.call_gex || 0) + (item?.put_gex || 0),
put_call_ratio:
- item?.call_gamma > 0
- ? Math.abs((item?.put_gamma || 0) / item?.call_gamma)
+ item?.call_gex > 0
+ ? Math.abs((item?.put_gex || 0) / item?.call_gex)
: null,
}));
let displayList = rawData?.slice(0, 150);
- let timePeriod = "3M";
-
let options = null;
- function filterDataByPeriod(historicalData, period = "3M") {
- const currentDate = new Date();
- let startDate = new Date();
-
- // Calculate the start date based on the period input
- switch (period) {
- case "3M":
- startDate.setMonth(currentDate.getMonth() - 3);
- break;
- case "6M":
- startDate.setMonth(currentDate.getMonth() - 6);
- break;
- case "1Y":
- startDate.setFullYear(currentDate.getFullYear() - 1);
- break;
- default:
- throw new Error(`Unsupported period: ${period}`);
- }
-
- // Filter the data based on the calculated start date
- let filteredData = historicalData?.filter((item) => {
- if (!item?.date) return false;
- const itemDate = new Date(item.date);
- return itemDate >= startDate && itemDate <= currentDate;
- });
-
- filteredData?.forEach((entry) => {
- const matchingData = data?.getHistoricalPrice?.find(
- (d) => d?.time === entry?.date,
- );
- if (matchingData) {
- entry.price = matchingData?.close;
- }
- });
-
- // Extract the dates and gamma values from the filtered data
- const dateList = filteredData?.map((item) => item.date);
- const gammaList = filteredData?.map((item) => item.net_gamma);
- const priceList = filteredData?.map((item) => item.price);
-
- return { dateList, gammaList, priceList };
- }
-
function plotData() {
- const data = rawData?.sort((a, b) => new Date(a?.date) - new Date(b?.date));
- const { dateList, gammaList, priceList } = filterDataByPeriod(
- data,
- timePeriod,
- );
+ // Process and sort data by strike in descending order
+ const processedData = rawData
+ ?.map((d) => ({
+ strike: d?.strike,
+ callGamma: d?.call_gex,
+ putGamma: d?.put_gex,
+ netGamma: d?.net_gex,
+ }))
+ .sort((a, b) => a.strike - b.strike);
+
+ const strikes = processedData.map((d) => d.strike);
+ const callGamma = processedData.map((d) => d.callGamma?.toFixed(2));
+ const putGamma = processedData.map((d) => d.putGamma?.toFixed(2));
+ const netGamma = processedData.map((d) => d.netGamma?.toFixed(2));
+
const options = {
- animation: false,
tooltip: {
trigger: "axis",
- hideDelay: 100,
- borderColor: "#969696", // Black border color
- borderWidth: 1, // Border width of 1px
- backgroundColor: "#313131", // Optional: Set background color for contrast
+ axisPointer: {
+ type: "shadow",
+ },
+ backgroundColor: "#313131",
textStyle: {
- color: "#fff", // Optional: Text color for better visibility
+ color: "#fff",
},
formatter: function (params) {
- // Get the timestamp from the first parameter
- const timestamp = params[0].axisValue;
+ const strike = params[0].axisValue;
+ const put = params[0].data;
+ const call = params[1].data;
+ const net = params[2].data;
- // Initialize result with timestamp
- let result = timestamp + "
";
-
- // Add each series data
- params?.forEach((param) => {
- const marker =
- '';
- result +=
- marker +
- param.seriesName +
- ": " +
- abbreviateNumber(param.value) +
- "
";
- });
-
- return result;
- },
- axisPointer: {
- lineStyle: {
- color: "#fff",
- },
+ return `
+
+ Strike: ${strike}
+ ● Put Gamma: ${abbreviateNumberWithColor(put, false, true)}
+ ● Call Gamma: ${abbreviateNumberWithColor(call, false, true)}
+ ● Net Gamma: ${abbreviateNumberWithColor(net, false, true)}
+
`;
},
},
- silent: true,
grid: {
left: $screenWidth < 640 ? "5%" : "0%",
right: $screenWidth < 640 ? "5%" : "0%",
- bottom: "20%",
+ bottom: "5%",
containLabel: true,
},
- xAxis: [
- {
- type: "category",
- data: dateList,
- axisLabel: {
- color: "#fff",
-
- formatter: function (value) {
- // Assuming dates are in the format 'yyyy-mm-dd'
- const dateParts = value.split("-");
- const monthIndex = parseInt(dateParts[1]) - 1; // Months are zero-indexed in JavaScript Date objects
- const year = parseInt(dateParts[0]);
- const day = parseInt(dateParts[2]);
- return `${day} ${monthNames[monthIndex]} ${year}`;
- },
- },
+ xAxis: {
+ type: "value",
+ name: "Gamma",
+ nameTextStyle: { color: "#fff" },
+ splitLine: { show: false },
+ axisLabel: {
+ show: false, // Hide y-axis labels
},
- ],
- yAxis: [
- {
- type: "value",
- splitLine: {
- show: false, // Disable x-axis grid lines
- },
- axisLabel: {
- show: false, // Hide y-axis labels
- },
- },
- {
- type: "value",
- splitLine: {
- show: false, // Disable x-axis grid lines
- },
- position: "right",
- axisLabel: {
- show: false, // Hide y-axis labels
- },
- },
- ],
+ },
+ yAxis: {
+ type: "category",
+ data: strikes,
+ axisLine: { lineStyle: { color: "#fff" } },
+ axisLabel: { color: "#fff" },
+ splitLine: { show: false },
+ },
series: [
{
- name: "Price",
- type: "line",
- data: priceList,
- yAxisIndex: 1,
- lineStyle: { width: 2 },
- itemStyle: {
- color: "#fff",
- },
- smooth: true,
- showSymbol: false,
+ name: "Put Gamma",
+ type: "bar",
+ data: putGamma,
+ stack: "gamma",
+ itemStyle: { color: "#9B5DC4" },
},
{
- name: "Gamma",
+ name: "Net Gamma",
type: "bar",
- data: gammaList,
- itemStyle: {
- color: "#9B5DC4",
- },
+ data: netGamma,
+ stack: "gamma",
+ itemStyle: { color: "#FF2F1F" },
+ },
+ {
+ name: "Call Gamma",
+ type: "bar",
+ data: callGamma,
+ stack: "gamma",
+ itemStyle: { color: "#C4E916" },
},
],
};
+
return options;
}
- function formatDate(dateStr) {
- // Parse the input date string (YYYY-mm-dd)
- var date = new Date(dateStr);
-
- // Get month, day, and year
- var month = date.getMonth() + 1; // Month starts from 0
- var day = date.getDate();
- var year = date.getFullYear();
-
- // Extract the last two digits of the year
- var shortYear = year.toString().slice(-2);
-
- // Add leading zeros if necessary
- month = (month < 10 ? "0" : "") + month;
- day = (day < 10 ? "0" : "") + day;
-
- var formattedDate = month + "/" + day + "/" + year;
-
- return formattedDate;
- }
-
async function handleScroll() {
const scrollThreshold = document.body.offsetHeight * 0.8; // 80% of the website height
const isBottom = window.innerHeight + window.scrollY >= scrollThreshold;
@@ -253,18 +159,18 @@
});
$: columns = [
- { key: "date", label: "Date", align: "left" },
- { key: "call_gamma", label: "Call GEX", align: "right" },
- { key: "put_gamma", label: "Put GEX", align: "right" },
- { key: "put_gamma", label: "Net GEX", align: "right" },
+ { key: "strike", label: "Strike Price", align: "left" },
+ { key: "call_gex", label: "Call GEX", align: "right" },
+ { key: "put_gex", label: "Put GEX", align: "right" },
+ { key: "net_gex", label: "Net GEX", align: "right" },
{ key: "put_call_ratio", label: "P/C GEX", align: "right" },
];
$: sortOrders = {
- date: { order: "none", type: "date" },
- call_gamma: { order: "none", type: "number" },
- put_gamma: { order: "none", type: "number" },
- net_gamma: { order: "none", type: "number" },
+ strike: { order: "none", type: "number" },
+ call_gex: { order: "none", type: "number" },
+ put_gex: { order: "none", type: "number" },
+ net_gex: { order: "none", type: "number" },
put_call_ratio: { order: "none", type: "number" },
};
@@ -326,7 +232,7 @@
};
$: {
- if (typeof window !== "undefined" && timePeriod) {
+ if (typeof window !== "undefined") {
options = plotData();
}
}
@@ -337,7 +243,8 @@
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
- {$displayCompanyName} ({$stockTicker}) Gamma Exposure · Stocknear
+ {$displayCompanyName} ({$stockTicker}) Gamma Exposure by Strike Price ·
+ Stocknear
- Daily Gamma Exposure
+ Gamma Exposure By Strike
-
+
{#if options !== null}
-
- {#each ["3M", "6M", "1Y"] as item}
-
- {/each}
-
-
{:else}
@@ -420,7 +312,7 @@
@@ -438,13 +330,13 @@
|
- {formatDate(item?.date)}
+ {item?.strike?.toFixed(2)}
|
{@html abbreviateNumberWithColor(
- item?.call_gamma,
+ item?.call_gex?.toFixed(2),
false,
true,
)}
@@ -453,7 +345,7 @@
class="text-white text-sm sm:text-[1rem] text-end whitespace-nowrap"
>
{@html abbreviateNumberWithColor(
- item?.put_gamma,
+ item?.put_gex?.toFixed(2),
false,
true,
)}
@@ -463,7 +355,7 @@
class="text-white text-sm sm:text-[1rem] text-end whitespace-nowrap"
>
{@html abbreviateNumberWithColor(
- item?.net_gamma,
+ item?.net_gex?.toFixed(2),
false,
true,
)}
@@ -472,14 +364,16 @@
|
- {#if item?.put_call_ratio <= 1}
+ {#if item?.put_call_ratio <= 1 && item?.put_call_ratio !== null}
{item?.put_call_ratio?.toFixed(2)}
- {:else}
+ {:else if item?.put_call_ratio > 1 && item?.put_call_ratio !== null}
{item?.put_call_ratio?.toFixed(2)}
+ {:else}
+ n/a
{/if}
|
@@ -508,14 +402,14 @@