diff --git a/package-lock.json b/package-lock.json
index b492b2d3..e6bfc08e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2230,6 +2230,19 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
+ "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
+ }
+ },
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
@@ -3969,9 +3982,10 @@
}
},
"node_modules/acorn": {
- "version": "8.12.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
- "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
+ "version": "8.14.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
+ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
+ "license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
@@ -4258,9 +4272,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.23.2",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz",
- "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==",
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz",
+ "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==",
"dev": true,
"funding": [
{
@@ -4276,11 +4290,12 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "caniuse-lite": "^1.0.30001640",
- "electron-to-chromium": "^1.4.820",
- "node-releases": "^2.0.14",
- "update-browserslist-db": "^1.1.0"
+ "caniuse-lite": "^1.0.30001688",
+ "electron-to-chromium": "^1.5.73",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.1"
},
"bin": {
"browserslist": "cli.js"
@@ -4304,6 +4319,15 @@
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
"dev": true
},
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true
+ },
"node_modules/bytes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
@@ -4406,9 +4430,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001642",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz",
- "integrity": "sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==",
+ "version": "1.0.30001690",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz",
+ "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==",
"dev": true,
"funding": [
{
@@ -4423,7 +4447,8 @@
"type": "github",
"url": "https://github.com/sponsors/ai"
}
- ]
+ ],
+ "license": "CC-BY-4.0"
},
"node_modules/chai": {
"version": "4.4.1",
@@ -5271,10 +5296,11 @@
"dev": true
},
"node_modules/electron-to-chromium": {
- "version": "1.4.827",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.827.tgz",
- "integrity": "sha512-VY+J0e4SFcNfQy19MEoMdaIcZLmDCprqvBtkii1WTCTQHpRvf5N8+3kTYCgL/PcntvwQvmMJWTuDPsq+IlhWKQ==",
- "dev": true
+ "version": "1.5.79",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.79.tgz",
+ "integrity": "sha512-nYOxJNxQ9Om4EC88BE4pPoNI8xwSFf8pU/BAeOl4Hh/b/i6V4biTAzwV7pXi3ARKeoYO5JZKMIXTryXSVer5RA==",
+ "dev": true,
+ "license": "ISC"
},
"node_modules/emoji-regex": {
"version": "8.0.0",
@@ -5365,9 +5391,10 @@
}
},
"node_modules/escalade": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
- "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -6838,10 +6865,11 @@
}
},
"node_modules/node-releases": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
- "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
- "dev": true
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/normalize-path": {
"version": "3.0.0",
@@ -7883,6 +7911,31 @@
"node": ">=0.10.0"
}
},
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/source-map-support/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/stackback": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
@@ -8511,6 +8564,36 @@
"node": ">=10.13.0"
}
},
+ "node_modules/terser": {
+ "version": "5.37.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz",
+ "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.8.2",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true
+ },
"node_modules/text-segmentation": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
@@ -8618,9 +8701,10 @@
"license": "Apache-2.0"
},
"node_modules/tslib": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
- "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
},
"node_modules/type-detect": {
"version": "4.0.8",
@@ -8691,9 +8775,9 @@
"dev": true
},
"node_modules/update-browserslist-db": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
- "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
+ "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
"dev": true,
"funding": [
{
@@ -8709,9 +8793,10 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "escalade": "^3.1.2",
- "picocolors": "^1.0.1"
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.0"
},
"bin": {
"update-browserslist-db": "cli.js"
diff --git a/src/routes/etf/[tickerID]/options/+layout.svelte b/src/routes/etf/[tickerID]/options/+layout.svelte
index 6aff83df..afcd462a 100644
--- a/src/routes/etf/[tickerID]/options/+layout.svelte
+++ b/src/routes/etf/[tickerID]/options/+layout.svelte
@@ -11,6 +11,8 @@
const subSectionMap = {
overview: "/options",
"hottest-contracts": "/options/hottest-contracts",
+ gex: "/options/gex",
+ dex: "/options/dex",
};
if (state !== "overview" && subSectionMap[state]) {
@@ -28,6 +30,8 @@
const sectionMap = {
overview: "overview",
"hottest-contracts": "hottest-contracts",
+ gex: "gex",
+ dex: "dex",
};
const foundSection = parts?.find((part) =>
@@ -73,6 +77,24 @@
>
Hottest Contracts
+ changeSubSection("gex")}
+ class="p-2 px-5 cursor-pointer {displaySubSection === 'gex'
+ ? 'text-white bg-primary sm:hover:bg-opacity-[0.95]'
+ : 'text-gray-400 sm:hover:text-white sm:hover:bg-primary sm:hover:bg-opacity-[0.95]'}"
+ >
+ GEX
+
+ changeSubSection("dex")}
+ class="p-2 px-5 cursor-pointer {displaySubSection === 'dex'
+ ? 'text-white bg-primary sm:hover:bg-opacity-[0.95]'
+ : 'text-gray-400 sm:hover:text-white sm:hover:bg-primary sm:hover:bg-opacity-[0.95]'}"
+ >
+ DEX
+
diff --git a/src/routes/etf/[tickerID]/options/gex/+layout.svelte b/src/routes/etf/[tickerID]/options/gex/+layout.svelte
new file mode 100644
index 00000000..ca64a74b
--- /dev/null
+++ b/src/routes/etf/[tickerID]/options/gex/+layout.svelte
@@ -0,0 +1,94 @@
+
+
+
diff --git a/src/routes/etf/[tickerID]/options/gex/+page.server.ts b/src/routes/etf/[tickerID]/options/gex/+page.server.ts
new file mode 100644
index 00000000..a6db54dc
--- /dev/null
+++ b/src/routes/etf/[tickerID]/options/gex/+page.server.ts
@@ -0,0 +1,50 @@
+
+
+export const load = async ({ locals, params }) => {
+ const { apiKey, apiURL, user } = locals;
+
+ const getData = async () => {
+ const postData = {
+ params: params.tickerID,
+ category: "overview"
+ };
+
+ 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;
+ };
+
+
+ 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/etf/[tickerID]/options/gex/+page.svelte b/src/routes/etf/[tickerID]/options/gex/+page.svelte
new file mode 100644
index 00000000..d854d4cb
--- /dev/null
+++ b/src/routes/etf/[tickerID]/options/gex/+page.svelte
@@ -0,0 +1,525 @@
+
+
+
+
+
+
+ {$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
+ {$displayCompanyName} ({$stockTicker}) Gamma Exposure · Stocknear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {#if rawData?.length > 0}
+
+
+ Daily Gamma Exposure
+
+
+
+ {#if options !== null}
+
+
+ {#each ["3M", "6M", "1Y"] as item}
+ (timePeriod = item)}
+ class="px-3 py-1 text-sm {timePeriod === item
+ ? 'bg-white text-black '
+ : 'text-white bg-table text-opacity-[0.6]'} transition ease-out duration-100 sm:hover:bg-white sm:hover:text-black rounded-md cursor-pointer"
+ >
+ {item}
+
+ {/each}
+
+
+
+
+ {:else}
+
+ {/if}
+
+
+
+
+
+
+
+ {#each displayList as item, index}
+
+
+ {formatDate(item?.date)}
+
+
+ {@html abbreviateNumberWithColor(
+ item?.call_gamma,
+ false,
+ true,
+ )}
+
+
+ {@html abbreviateNumberWithColor(
+ item?.put_gamma,
+ false,
+ true,
+ )}
+
+
+
+ {@html abbreviateNumberWithColor(
+ item?.net_gamma,
+ false,
+ true,
+ )}
+
+
+
+ {#if item?.put_call_ratio <= 1}
+ {item?.put_call_ratio?.toFixed(2)}
+ {:else}
+ {item?.put_call_ratio?.toFixed(2)}
+ {/if}
+
+
+ {/each}
+
+
+
+
+
+
+ {:else}
+
+
+ Hottest Contracts
+
+
+
+
+
+ {/if}
+
+
+
+
+
diff --git a/src/routes/etf/[tickerID]/options/gex/expiry/+page.server.ts b/src/routes/etf/[tickerID]/options/gex/expiry/+page.server.ts
new file mode 100644
index 00000000..9e7bd003
--- /dev/null
+++ b/src/routes/etf/[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/etf/[tickerID]/options/gex/expiry/+page.svelte b/src/routes/etf/[tickerID]/options/gex/expiry/+page.svelte
new file mode 100644
index 00000000..e6f85ee8
--- /dev/null
+++ b/src/routes/etf/[tickerID]/options/gex/expiry/+page.svelte
@@ -0,0 +1,431 @@
+
+
+
+
+
+
+ {$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
+ {$displayCompanyName} ({$etfTicker}) 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/etf/[tickerID]/options/gex/strike/+page.server.ts b/src/routes/etf/[tickerID]/options/gex/strike/+page.server.ts
new file mode 100644
index 00000000..f33b0e12
--- /dev/null
+++ b/src/routes/etf/[tickerID]/options/gex/strike/+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: "strike"
+ };
+
+ 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/etf/[tickerID]/options/gex/strike/+page.svelte b/src/routes/etf/[tickerID]/options/gex/strike/+page.svelte
new file mode 100644
index 00000000..26831378
--- /dev/null
+++ b/src/routes/etf/[tickerID]/options/gex/strike/+page.svelte
@@ -0,0 +1,420 @@
+
+
+
+
+
+
+ {$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
+ {$displayCompanyName} ({$etfTicker}) Gamma Exposure by Strike Price ·
+ Stocknear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {#if rawData?.length > 0}
+
+
+ Gamma Exposure By Strike
+
+
+
+ {#if options !== null}
+
+
+
+ {:else}
+
+ {/if}
+
+
+
+
+
+
+
+ {#each displayList as item, index}
+
+
+ {item?.strike?.toFixed(2)}
+
+
+ {@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/heatmaps/+page.svelte b/src/routes/heatmaps/+page.svelte
index 9d930d08..63fc9e8e 100644
--- a/src/routes/heatmaps/+page.svelte
+++ b/src/routes/heatmaps/+page.svelte
@@ -1,626 +1,86 @@
-
-
-
-
- {$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""} Market
- Heatmaps · Stocknear
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Market Heatmaps
-
-
-
-
- Latest market changes to never miss another bullish or bearish rally.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {#if isLoaded}
-
-
-
-
-
-
-
- Today, sectorSelector(lowestAvgCategory)}
- class="cursor-pointer text-blue-400 sm:hover:text-white"
- >{lowestAvgCategory}
- took the lead as the {displayIndex} largest loser, marking a average
- return of
- {lowestAvg?.toFixed(2)}% , while
- sectorSelector(highestAvgCategory)}
- class="cursor-pointer text-blue-400 sm:hover:text-white"
- >{highestAvgCategory}
- surged ahead as the top performer with an impressive average return
- of
- {highestAvg?.toFixed(2)}% .
-
-
-
-
-
-
-
-
-
- Market Index:
-
-
- {displayIndex}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {:else}
-
- {/if}
-
-
-
-
-
-
-
-
-
-
- ✕
-
-
-
-
Market Index
-
-
-
changeIndex("S&P500")}
- class="cursor-pointer w-full flex flex-row justify-start items-center mb-5"
- >
-
- S&P500
-
-
-
-
changeIndex("Dow Jones")}
- class="cursor-pointer w-full flex flex-row justify-start items-center mb-5"
- >
-
- Dow Jones
-
-
-
-
changeIndex("Nasdaq")}
- class="cursor-pointer w-full flex flex-row justify-start items-center mb-5"
- >
-
- Nasdaq
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ✕
-
-
-
-
Export
-
-
-
exportTreemap()}
- class="cursor-pointer w-full flex flex-row justify-start items-center mb-5"
- >
-
-
- Save as PNG
-
-
-
-
-
-
-
- Save as JPG
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/src/routes/stocks/[tickerID]/options/dex/+layout.svelte b/src/routes/stocks/[tickerID]/options/dex/+layout.svelte
new file mode 100644
index 00000000..3822b3cc
--- /dev/null
+++ b/src/routes/stocks/[tickerID]/options/dex/+layout.svelte
@@ -0,0 +1,94 @@
+
+
+
diff --git a/src/routes/stocks/[tickerID]/options/dex/+page.server.ts b/src/routes/stocks/[tickerID]/options/dex/+page.server.ts
new file mode 100644
index 00000000..a6db54dc
--- /dev/null
+++ b/src/routes/stocks/[tickerID]/options/dex/+page.server.ts
@@ -0,0 +1,50 @@
+
+
+export const load = async ({ locals, params }) => {
+ const { apiKey, apiURL, user } = locals;
+
+ const getData = async () => {
+ const postData = {
+ params: params.tickerID,
+ category: "overview"
+ };
+
+ 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;
+ };
+
+
+ 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/dex/+page.svelte b/src/routes/stocks/[tickerID]/options/dex/+page.svelte
new file mode 100644
index 00000000..c7ad0d07
--- /dev/null
+++ b/src/routes/stocks/[tickerID]/options/dex/+page.svelte
@@ -0,0 +1,525 @@
+
+
+
+
+
+
+ {$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
+ {$displayCompanyName} ({$stockTicker}) Gamma Exposure · Stocknear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {#if rawData?.length > 0}
+
+
+ Daily Delta Exposure
+
+
+
+ {#if options !== null}
+
+
+ {#each ["3M", "6M", "1Y"] as item}
+ (timePeriod = item)}
+ class="px-3 py-1 text-sm {timePeriod === item
+ ? 'bg-white text-black '
+ : 'text-white bg-table text-opacity-[0.6]'} transition ease-out duration-100 sm:hover:bg-white sm:hover:text-black rounded-md cursor-pointer"
+ >
+ {item}
+
+ {/each}
+
+
+
+
+ {:else}
+
+ {/if}
+
+
+
+
+
+
+
+ {#each displayList as item, index}
+
+
+ {formatDate(item?.date)}
+
+
+ {@html abbreviateNumberWithColor(
+ item?.call_delta,
+ false,
+ true,
+ )}
+
+
+ {@html abbreviateNumberWithColor(
+ item?.put_delta,
+ false,
+ true,
+ )}
+
+
+
+ {@html abbreviateNumberWithColor(
+ item?.net_delta,
+ false,
+ true,
+ )}
+
+
+
+ {#if item?.put_call_ratio <= 1}
+ {item?.put_call_ratio?.toFixed(2)}
+ {:else}
+ {item?.put_call_ratio?.toFixed(2)}
+ {/if}
+
+
+ {/each}
+
+
+
+
+
+
+ {:else}
+
+
+ Hottest Contracts
+
+
+
+
+
+ {/if}
+
+
+
+
+
diff --git a/src/routes/stocks/[tickerID]/options/dex/expiry/+page.server.ts b/src/routes/stocks/[tickerID]/options/dex/expiry/+page.server.ts
new file mode 100644
index 00000000..9e7bd003
--- /dev/null
+++ b/src/routes/stocks/[tickerID]/options/dex/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/dex/expiry/+page.svelte b/src/routes/stocks/[tickerID]/options/dex/expiry/+page.svelte
new file mode 100644
index 00000000..dd369df2
--- /dev/null
+++ b/src/routes/stocks/[tickerID]/options/dex/expiry/+page.svelte
@@ -0,0 +1,432 @@
+
+
+
+
+
+
+ {$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_delta?.toFixed(2),
+ false,
+ true,
+ )}
+
+
+ {@html abbreviateNumberWithColor(
+ item?.put_delta?.toFixed(2),
+ false,
+ true,
+ )}
+
+
+
+ {@html abbreviateNumberWithColor(
+ item?.net_delta?.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/dex/strike/+page.server.ts b/src/routes/stocks/[tickerID]/options/dex/strike/+page.server.ts
new file mode 100644
index 00000000..f33b0e12
--- /dev/null
+++ b/src/routes/stocks/[tickerID]/options/dex/strike/+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: "strike"
+ };
+
+ 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/dex/strike/+page.svelte b/src/routes/stocks/[tickerID]/options/dex/strike/+page.svelte
new file mode 100644
index 00000000..43c70a86
--- /dev/null
+++ b/src/routes/stocks/[tickerID]/options/dex/strike/+page.svelte
@@ -0,0 +1,415 @@
+
+
+
+
+
+
+ {$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
+ {$displayCompanyName} ({$stockTicker}) Delta Exposure by Strike Price ·
+ Stocknear
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {#if rawData?.length > 0}
+
+
+ Gamma Exposure By Strike
+
+
+
+ {#if options !== null}
+
+
+
+ {:else}
+
+ {/if}
+
+
+
+
+
+
+
+ {#each displayList as item, index}
+
+
+ {item?.strike?.toFixed(2)}
+
+
+ {@html abbreviateNumberWithColor(
+ item?.call_delta?.toFixed(2),
+ false,
+ true,
+ )}
+
+
+ {@html abbreviateNumberWithColor(
+ item?.put_delta?.toFixed(2),
+ false,
+ true,
+ )}
+
+
+
+ {@html abbreviateNumberWithColor(
+ item?.net_delta?.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}
+
+ {/if}
+
+
+
+
+
diff --git a/src/routes/stocks/[tickerID]/options/gex/expiry/+page.svelte b/src/routes/stocks/[tickerID]/options/gex/expiry/+page.svelte
index ad8a35a2..98fc498d 100644
--- a/src/routes/stocks/[tickerID]/options/gex/expiry/+page.svelte
+++ b/src/routes/stocks/[tickerID]/options/gex/expiry/+page.svelte
@@ -77,6 +77,7 @@
const netGamma = processedData.map((d) => d.netGamma?.toFixed(2));
const options = {
+ animation: false,
tooltip: {
trigger: "axis",
axisPointer: {
diff --git a/src/routes/stocks/[tickerID]/options/gex/strike/+page.svelte b/src/routes/stocks/[tickerID]/options/gex/strike/+page.svelte
index a1ecbc8a..23338ee3 100644
--- a/src/routes/stocks/[tickerID]/options/gex/strike/+page.svelte
+++ b/src/routes/stocks/[tickerID]/options/gex/strike/+page.svelte
@@ -66,6 +66,7 @@
const netGamma = processedData.map((d) => d.netGamma?.toFixed(2));
const options = {
+ animation: false,
tooltip: {
trigger: "axis",
axisPointer: {