From 6bc6146ad14650f6d705961f01ff9a3e6629308a Mon Sep 17 00:00:00 2001 From: MuslemRahimi Date: Thu, 7 Nov 2024 13:50:55 +0100 Subject: [PATCH] add implied volatility to plot --- .../etf/[tickerID]/options/+page.server.ts | 68 ++++++++++------ .../etf/[tickerID]/options/+page.svelte | 80 ++++++++++++------- .../stocks/[tickerID]/options/+page.server.ts | 48 +++++------ .../stocks/[tickerID]/options/+page.svelte | 25 +++++- 4 files changed, 134 insertions(+), 87 deletions(-) diff --git a/src/routes/etf/[tickerID]/options/+page.server.ts b/src/routes/etf/[tickerID]/options/+page.server.ts index 1bb17d33..7f9a0bab 100644 --- a/src/routes/etf/[tickerID]/options/+page.server.ts +++ b/src/routes/etf/[tickerID]/options/+page.server.ts @@ -1,14 +1,35 @@ export const load = async ({ locals, params }) => { + const { apiKey, apiURL } = locals; + + const getOptionsNetFlow = async () => { + const postData = { + ticker: params.tickerID, + }; + + const response = await fetch(apiURL + "/options-net-flow-ticker", { + method: "POST", + headers: { + "Content-Type": "application/json", + "X-API-KEY": apiKey, + }, + body: JSON.stringify(postData), + }); + + const output = await response.json(); + + return output; + }; + const getOptionsPlotData = async () => { const postData = { ticker: params.tickerID, }; - const response = await fetch(locals?.apiURL + "/options-plot-ticker", { + const response = await fetch(apiURL + "/options-plot-ticker", { method: "POST", headers: { "Content-Type": "application/json", - "X-API-KEY": locals?.apiKey, + "X-API-KEY": apiKey, }, body: JSON.stringify(postData), }); @@ -24,17 +45,14 @@ export const load = async ({ locals, params }) => { }; // make the POST request to the endpoint - const response = await fetch( - locals?.apiURL + "/options-historical-data-ticker", - { - method: "POST", - headers: { - "Content-Type": "application/json", - "X-API-KEY": locals?.apiKey, - }, - body: JSON.stringify(postData), - } - ); + const response = await fetch(apiURL + "/options-historical-data-ticker", { + method: "POST", + headers: { + "Content-Type": "application/json", + "X-API-KEY": apiKey, + }, + body: JSON.stringify(postData), + }); const output = await response.json(); @@ -47,17 +65,14 @@ export const load = async ({ locals, params }) => { }; // make the POST request to the endpoint - const response = await fetch( - locals?.apiURL + "/options-chain-data-ticker", - { - method: "POST", - headers: { - "Content-Type": "application/json", - "X-API-KEY": locals?.apiKey, - }, - body: JSON.stringify(postData), - } - ); + const response = await fetch(apiURL + "/options-chain-data-ticker", { + method: "POST", + headers: { + "Content-Type": "application/json", + "X-API-KEY": apiKey, + }, + body: JSON.stringify(postData), + }); const output = await response.json(); @@ -70,11 +85,11 @@ export const load = async ({ locals, params }) => { }; // make the POST request to the endpoint - const response = await fetch(locals?.apiURL + "/options-gex-ticker", { + const response = await fetch(apiURL + "/options-gex-ticker", { method: "POST", headers: { "Content-Type": "application/json", - "X-API-KEY": locals?.apiKey, + "X-API-KEY": apiKey, }, body: JSON.stringify(postData), }); @@ -86,6 +101,7 @@ export const load = async ({ locals, params }) => { // Make sure to return a promise return { + getOptionsNetFlow: await getOptionsNetFlow(), getOptionsPlotData: await getOptionsPlotData(), getOptionsHistoricalData: await getOptionsHistoricalData(), getOptionsChainData: await getOptionsChainData(), diff --git a/src/routes/etf/[tickerID]/options/+page.svelte b/src/routes/etf/[tickerID]/options/+page.svelte index 6bdfb101..4d455517 100644 --- a/src/routes/etf/[tickerID]/options/+page.svelte +++ b/src/routes/etf/[tickerID]/options/+page.svelte @@ -93,6 +93,7 @@ let putVolumeList; //= data?.getOptionsPlotData?.putVolumeList; let callOpenInterestList; //= data?.getOptionsPlotData?.callOpenInterestList; let putOpenInterestList; //= data?.getOptionsPlotData?.putOpenInterestList; + let iv60List; let displayTimePeriod = "threeMonths"; @@ -141,7 +142,7 @@ displayData = event.target.value; } - function plotData(callData, putData) { + function plotData(callData, putData, ivData) { const options = { animation: false, tooltip: { @@ -162,6 +163,8 @@ type: "category", data: dateList, axisLabel: { + color: "#fff", + formatter: function (value) { // Assuming dates are in the format 'yyyy-mm-dd' const dateParts = value.split("-"); @@ -179,7 +182,6 @@ splitLine: { show: false, // Disable x-axis grid lines }, - axisLabel: { show: false, // Hide y-axis labels }, @@ -220,6 +222,19 @@ color: "#EE5365", //'#7A1C16' }, }, + { + name: "IV60", // Name for the line chart + type: "line", // Type of the chart (line) + yAxisIndex: 1, // Use the second y-axis on the right + data: ivData, // iv60Data (assumed to be passed as ivData) + itemStyle: { + color: "#FFD700", // Choose a color for the line (gold in this case) + }, + lineStyle: { + width: 2, // Set the width of the line + }, + smooth: true, // Optional: make the line smooth + }, ], }; return options; @@ -369,6 +384,8 @@ dateList = filteredList?.map((item) => item.date); callVolumeList = filteredList?.map((item) => item?.CALL?.volume); putVolumeList = filteredList?.map((item) => item?.PUT?.volume); + iv60List = filteredList?.map((item) => item?.iv60); + callOpenInterestList = filteredList?.map( (item) => item?.CALL?.open_interest, ); @@ -389,9 +406,9 @@ // Determine the type of plot data to generate based on displayData if (displayData === "volume") { - options = plotData(callVolumeList, putVolumeList); + options = plotData(callVolumeList, putVolumeList, iv60List); } else if (displayData === "openInterest") { - options = plotData(callOpenInterestList, putOpenInterestList); + options = plotData(callOpenInterestList, putOpenInterestList, iv60List); } } @@ -552,18 +569,22 @@ -
-
+
+
-
-
-

- Unsual Options Activity -

+
+
+
+ {#await import("$lib/components/OptionsNetFlow.svelte") then { default: Comp }} + + {/await} +
-
+
{#if filteredList?.length !== 0} {:else} @@ -752,7 +773,7 @@ {/each}
-
+
{/if} @@ -817,38 +838,35 @@
{#if activeIdx === 0} - - - - - - - - - - diff --git a/src/routes/stocks/[tickerID]/options/+page.server.ts b/src/routes/stocks/[tickerID]/options/+page.server.ts index 82b97915..7f9a0bab 100644 --- a/src/routes/stocks/[tickerID]/options/+page.server.ts +++ b/src/routes/stocks/[tickerID]/options/+page.server.ts @@ -1,14 +1,16 @@ export const load = async ({ locals, params }) => { + const { apiKey, apiURL } = locals; + const getOptionsNetFlow = async () => { const postData = { ticker: params.tickerID, }; - const response = await fetch(locals?.apiURL + "/options-net-flow-ticker", { + const response = await fetch(apiURL + "/options-net-flow-ticker", { method: "POST", headers: { "Content-Type": "application/json", - "X-API-KEY": locals?.apiKey, + "X-API-KEY": apiKey, }, body: JSON.stringify(postData), }); @@ -23,11 +25,11 @@ export const load = async ({ locals, params }) => { ticker: params.tickerID, }; - const response = await fetch(locals?.apiURL + "/options-plot-ticker", { + const response = await fetch(apiURL + "/options-plot-ticker", { method: "POST", headers: { "Content-Type": "application/json", - "X-API-KEY": locals?.apiKey, + "X-API-KEY": apiKey, }, body: JSON.stringify(postData), }); @@ -43,17 +45,14 @@ export const load = async ({ locals, params }) => { }; // make the POST request to the endpoint - const response = await fetch( - locals?.apiURL + "/options-historical-data-ticker", - { - method: "POST", - headers: { - "Content-Type": "application/json", - "X-API-KEY": locals?.apiKey, - }, - body: JSON.stringify(postData), + const response = await fetch(apiURL + "/options-historical-data-ticker", { + method: "POST", + headers: { + "Content-Type": "application/json", + "X-API-KEY": apiKey, }, - ); + body: JSON.stringify(postData), + }); const output = await response.json(); @@ -66,17 +65,14 @@ export const load = async ({ locals, params }) => { }; // make the POST request to the endpoint - const response = await fetch( - locals?.apiURL + "/options-chain-data-ticker", - { - method: "POST", - headers: { - "Content-Type": "application/json", - "X-API-KEY": locals?.apiKey, - }, - body: JSON.stringify(postData), + const response = await fetch(apiURL + "/options-chain-data-ticker", { + method: "POST", + headers: { + "Content-Type": "application/json", + "X-API-KEY": apiKey, }, - ); + body: JSON.stringify(postData), + }); const output = await response.json(); @@ -89,11 +85,11 @@ export const load = async ({ locals, params }) => { }; // make the POST request to the endpoint - const response = await fetch(locals?.apiURL + "/options-gex-ticker", { + const response = await fetch(apiURL + "/options-gex-ticker", { method: "POST", headers: { "Content-Type": "application/json", - "X-API-KEY": locals?.apiKey, + "X-API-KEY": apiKey, }, body: JSON.stringify(postData), }); diff --git a/src/routes/stocks/[tickerID]/options/+page.svelte b/src/routes/stocks/[tickerID]/options/+page.svelte index f24f3abf..73740757 100644 --- a/src/routes/stocks/[tickerID]/options/+page.svelte +++ b/src/routes/stocks/[tickerID]/options/+page.svelte @@ -93,6 +93,7 @@ let putVolumeList; //= data?.getOptionsPlotData?.putVolumeList; let callOpenInterestList; //= data?.getOptionsPlotData?.callOpenInterestList; let putOpenInterestList; //= data?.getOptionsPlotData?.putOpenInterestList; + let iv60List; let displayTimePeriod = "threeMonths"; @@ -141,7 +142,7 @@ displayData = event.target.value; } - function plotData(callData, putData) { + function plotData(callData, putData, ivData) { const options = { animation: false, tooltip: { @@ -162,6 +163,8 @@ type: "category", data: dateList, axisLabel: { + color: "#fff", + formatter: function (value) { // Assuming dates are in the format 'yyyy-mm-dd' const dateParts = value.split("-"); @@ -179,7 +182,6 @@ splitLine: { show: false, // Disable x-axis grid lines }, - axisLabel: { show: false, // Hide y-axis labels }, @@ -220,6 +222,19 @@ color: "#EE5365", //'#7A1C16' }, }, + { + name: "IV60", // Name for the line chart + type: "line", // Type of the chart (line) + yAxisIndex: 1, // Use the second y-axis on the right + data: ivData, // iv60Data (assumed to be passed as ivData) + itemStyle: { + color: "#FFD700", // Choose a color for the line (gold in this case) + }, + lineStyle: { + width: 2, // Set the width of the line + }, + smooth: true, // Optional: make the line smooth + }, ], }; return options; @@ -369,6 +384,8 @@ dateList = filteredList?.map((item) => item.date); callVolumeList = filteredList?.map((item) => item?.CALL?.volume); putVolumeList = filteredList?.map((item) => item?.PUT?.volume); + iv60List = filteredList?.map((item) => item?.iv60); + callOpenInterestList = filteredList?.map( (item) => item?.CALL?.open_interest, ); @@ -389,9 +406,9 @@ // Determine the type of plot data to generate based on displayData if (displayData === "volume") { - options = plotData(callVolumeList, putVolumeList); + options = plotData(callVolumeList, putVolumeList, iv60List); } else if (displayData === "openInterest") { - options = plotData(callOpenInterestList, putOpenInterestList); + options = plotData(callOpenInterestList, putOpenInterestList, iv60List); } }
+ Date% ChangeP/CBear/BullBid/Ask Vol% OTMTotal VolumeTotal OITotal Prem