From d54833f3e96ca09aaa7bb086ebf04fc9c426ed22 Mon Sep 17 00:00:00 2001 From: MuslemRahimi Date: Tue, 23 Jul 2024 23:54:39 +0200 Subject: [PATCH] add otm ratio --- .../etf/[tickerID]/options/+page.svelte | 1258 +++++++++-------- .../stocks/[tickerID]/options/+page.svelte | 111 +- 2 files changed, 720 insertions(+), 649 deletions(-) diff --git a/src/routes/etf/[tickerID]/options/+page.svelte b/src/routes/etf/[tickerID]/options/+page.svelte index 81238ea0..ce183c8d 100644 --- a/src/routes/etf/[tickerID]/options/+page.svelte +++ b/src/routes/etf/[tickerID]/options/+page.svelte @@ -1,642 +1,676 @@ - - - - - - - - {$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ''} {$displayCompanyName} ({$etfTicker}) Options Activity · stocknear - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-

- Unsual Options Activity -

+ async function handleScroll() { + const scrollThreshold = document.body.offsetHeight * 0.8; // 80% of the website height + const isBottom = window.innerHeight + window.scrollY >= scrollThreshold; + if (isBottom && optionList?.length !== rawData?.length) { + const nextIndex = optionList?.length; + const filteredNewResults = rawData?.slice(nextIndex, nextIndex + 25); + optionList = [...optionList, ...filteredNewResults]; + } + } + + + + onMount(async () => { + calculateStats(); -
- - - {#if optionsPlotData?.length !== 0} - Last 3 months of options activity involving {$displayCompanyName} by major institutional traders and hedge funds. - {:else} - There's no data available, indicating that major traders may not be actively betting on {$displayCompanyName}. - {/if} - -
+ if(data?.user?.tier === 'Pro') { + window.addEventListener('scroll', handleScroll); + return () => { + window.removeEventListener('scroll', handleScroll); + }; + } + }) + + + $: { + if(displayData && optionsPlotData?.length !== 0 && typeof window !== 'undefined') { + if (displayData === 'volume') { + options = plotData(callVolumeList, putVolumeList) + } + else if (displayData === 'openInterest') { + options = plotData(callOpenInterestList, putOpenInterestList) + } + } + } + + + + + + -
- + + + + + + {$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ''} {$displayCompanyName} ({$etfTicker}) Options Activity · stocknear + + + + + + + + + + + + + + + + + + - {#if optionsPlotData?.length !== 0} - -
+
+
+
+
+
+

+ Unsual Options Activity +

+ +
+ + + {#if optionsPlotData?.length !== 0} + Last 3 months of options activity involving {$displayCompanyName} by major institutional traders and hedge funds. + {:else} + There's no data available, indicating that major traders may not be actively betting on {$displayCompanyName}. + {/if} + +
+ +
+ + + {#if optionsPlotData?.length !== 0} + +
+ +
-
- -
-
- - -
-
{displayTotalVolume}
-
- - - -
-
- - -
- -
{displayTotalOpenInterest}
-
- -
-
- - -
-
- {totalPutCallRatio !== 'Infinity' ? totalPutCallRatio : '> 1'} -
-
- -
-
- - +
+ +
-
{putCallOpenInterestRatio !== 'Infinity' ? putCallOpenInterestRatio : '> 1'}
-
- -
- -
- - +
{displayTotalVolume}
+
- -
- -
- - -
- + + +
+
+ +
- - -

- Latest Options Activity -

- - - - {#if optionList?.length !== 0} - - -
-
- -
-
- Flow Sentiment - {flowSentiment} -
- +
{displayTotalOpenInterest}
+
+ +
+
+ + +
+
+ {totalPutCallRatio !== 'Infinity' ? totalPutCallRatio : '> 1'} +
+
+ +
+
+ +
- - +
{putCallOpenInterestRatio !== 'Infinity' ? putCallOpenInterestRatio : '> 1'}
+
+ +
+ +
+ + + + +
+ +
+ + +
+ +
+ + + +

+ Latest Options Activity +

+ + + + {#if optionList?.length !== 0} + + +
+
+ +
+
+ Flow Sentiment + {flowSentiment} +
+ +
+ + +
+
+ Put/Call + + {latestPutCallRatio?.toFixed(3)} + +
+ +
+ + + + + + =1 ? 0 : 100-(latestPutCallRatio*100)?.toFixed(2)}> + + + +
+ {latestPutCallRatio?.toFixed(2)} +
+
+ + +
+ +
- Put/Call + Call Flow - {latestPutCallRatio?.toFixed(3)} - -
- -
- - - - - - =1 ? 0 : 100-(latestPutCallRatio*100)?.toFixed(2)}> - - - -
- {latestPutCallRatio?.toFixed(2)} -
-
- - -
- - -
-
- Call Flow - - {new Intl.NumberFormat("en", { - minimumFractionDigits: 0, - maximumFractionDigits: 0 - }).format(displayCallVolume)} - -
- -
- - - - - - - - - -
- {callPercentage}% -
-
- -
- - -
-
- Put Flow - - {new Intl.NumberFormat("en", { - minimumFractionDigits: 0, - maximumFractionDigits: 0 - }).format(displayPutVolume)} - -
- -
- - - - - - - - - -
- {putPercentage}% -
-
- - -
- - - -
-
- - - - - -
- - - - - - - - - - - - - - - - - - - - - {#each (data?.user?.tier === 'Pro' ? optionList : optionList?.slice(0,3)) as item, index} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {/each} - - -
TimeDateExpiryStrikeC/PSent.SpotPricePrem.TypeVol.OI
- {formatTime(item?.time)} - - {formatDate(item?.date)} - - {item?.dte < 0 ? 'expired' : item?.dte +'d'} - - {item?.strike_price} - - {item?.put_call} - - {item?.sentiment} - - {item?.underlying_price} - - {item?.price} - - {abbreviateNumber(item?.cost_basis)} - - {item?.type} - - {new Intl.NumberFormat("en", { - minimumFractionDigits: 0, - maximumFractionDigits: 0 - }).format(item?.volume)} - {new Intl.NumberFormat("en", { minimumFractionDigits: 0, maximumFractionDigits: 0 - }).format(item?.open_interest)} -
- -
- - - - {:else} -
-
- - No Options activity found + }).format(displayCallVolume)} + +
+ +
+ + + + + + + + + +
+ {callPercentage}% +
+
+
-
- {/if} - - {/if} - - - - -
- - -
-
- - -
- - - - - \ No newline at end of file + +
+ + + + + \ No newline at end of file diff --git a/src/routes/stocks/[tickerID]/options/+page.svelte b/src/routes/stocks/[tickerID]/options/+page.svelte index 0d78e0e8..0ec7f10d 100644 --- a/src/routes/stocks/[tickerID]/options/+page.svelte +++ b/src/routes/stocks/[tickerID]/options/+page.svelte @@ -22,6 +22,7 @@ let putPercentage; let displayCallVolume; let displayPutVolume; let latestPutCallRatio; +let displayOTMRatio; const totalPutCallRatio = data?.getOptionsPlotData?.putCallRatio; @@ -89,10 +90,6 @@ function changeStatement(event) displayData = event.target.value; } -let tableVolume = 0; -let tableOpenInterest = 0; -let tableAvgDTE = 0; - function plotData(callData, putData) { @@ -168,40 +165,53 @@ function plotData(callData, putData) { } function calculateStats() { - const { callVolumeSum, putVolumeSum, bullishCount, bearishCount } = rawData?.reduce((acc, item) => { - const volume = parseInt(item?.volume); - - if (item?.put_call === "Calls") { - acc.callVolumeSum += volume; - } else if (item?.put_call === "Puts") { - acc.putVolumeSum += volume; - } + const currentPrice = parseFloat(data?.getStockQuote?.price); + + const { callVolumeSum, putVolumeSum, bullishCount, bearishCount, otmVolume, itmVolume } = rawData?.reduce((acc, item) => { + const volume = parseInt(item?.volume); + const strikePrice = parseFloat(item?.strike_price); + + if (item?.put_call === "Calls") { + acc.callVolumeSum += volume; + if (strikePrice > currentPrice) { + acc.otmVolume += volume; + } else { + acc.itmVolume += volume; + } + } else if (item?.put_call === "Puts") { + acc.putVolumeSum += volume; + if (strikePrice < currentPrice) { + acc.itmVolume += volume; + } else { + acc.otmVolume += volume; + } + } + + if (item?.sentiment === "Bullish") { + acc.bullishCount += 1; + } else if (item?.sentiment === "Bearish") { + acc.bearishCount += 1; + } - if (item?.sentiment === "Bullish") { - acc.bullishCount += 1; - } else if (item?.sentiment === "Bearish") { - acc.bearishCount += 1; - } - return acc; - }, { callVolumeSum: 0, putVolumeSum: 0, bullishCount: 0, bearishCount: 0 }); + }, { callVolumeSum: 0, putVolumeSum: 0, bullishCount: 0, bearishCount: 0, otmVolume: 0, itmVolume: 0 }); - if(bullishCount > bearishCount) { - flowSentiment = 'Bullish' - } - else if (bullishCount < bearishCount) { - flowSentiment = 'Bearish' - } else { + if (bullishCount > bearishCount) { + flowSentiment = 'Bullish'; + } else if (bullishCount < bearishCount) { + flowSentiment = 'Bearish'; + } else { flowSentiment = 'Neutral'; - } - latestPutCallRatio = (putVolumeSum/callVolumeSum); - - callPercentage = Math.floor((callVolumeSum)/(callVolumeSum+putVolumeSum)*100); - putPercentage = (100-callPercentage); + } + latestPutCallRatio = (putVolumeSum / callVolumeSum); + callPercentage = Math.floor((callVolumeSum) / (callVolumeSum + putVolumeSum) * 100); + putPercentage = (100 - callPercentage); displayCallVolume = callVolumeSum; displayPutVolume = putVolumeSum; - + + // Calculate OTM/ITM ratio + displayOTMRatio = otmVolume / (itmVolume+otmVolume) ?? 0; } async function handleScroll() { @@ -217,9 +227,8 @@ async function handleScroll() { onMount(async () => { - calculateStats(); - + if(data?.user?.tier === 'Pro') { window.addEventListener('scroll', handleScroll); return () => { @@ -397,7 +406,7 @@ $: {
- Flow Sentiment + Flow Sentiment {flowSentiment}
@@ -406,7 +415,7 @@ $: {
- Put/Call + Put/Call {latestPutCallRatio?.toFixed(3)} @@ -433,7 +442,7 @@ $: {
- Call Flow + Call Flow {new Intl.NumberFormat("en", { minimumFractionDigits: 0, @@ -462,7 +471,7 @@ $: {
- Put Flow + Put Flow {new Intl.NumberFormat("en", { minimumFractionDigits: 0, @@ -489,6 +498,34 @@ $: {
+ + +
+
+ Ratio % + + OTM / ITM + +
+ +
+ + + + + + =1 ? 0 : 100-(displayOTMRatio*100)?.toFixed(2)}> + + + +
+ {(displayOTMRatio*100)?.toFixed(0)}% +
+
+ + +
+