From 6b8d0b69c8fdea7bd037bd6c0a55e69f03dbdff7 Mon Sep 17 00:00:00 2001 From: MuslemRahimi Date: Sun, 23 Jun 2024 18:45:56 +0200 Subject: [PATCH] cache options endpoint --- .../etf/[tickerID]/options/+page.svelte | 60 ++++++++++++------- .../options/{+page.server.ts => +page.ts} | 51 ++++++++++++---- .../stocks/[tickerID]/options/+page.svelte | 44 ++++++++++---- .../options/{+page.server.ts => +page.ts} | 51 ++++++++++++---- 4 files changed, 144 insertions(+), 62 deletions(-) rename src/routes/etf/[tickerID]/options/{+page.server.ts => +page.ts} (70%) rename src/routes/stocks/[tickerID]/options/{+page.server.ts => +page.ts} (70%) diff --git a/src/routes/etf/[tickerID]/options/+page.svelte b/src/routes/etf/[tickerID]/options/+page.svelte index 6f478a75..a571b2d2 100644 --- a/src/routes/etf/[tickerID]/options/+page.svelte +++ b/src/routes/etf/[tickerID]/options/+page.svelte @@ -9,12 +9,13 @@ import UpgradeToPro from '$lib/components/UpgradeToPro.svelte'; export let data; +const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; let optionsPlotData = data?.getOptionsPlotData?.plot; let displayData = 'volume'; let options; let rawData = data?.getOptionsFlowData -let optionList = rawData?.slice(0,15); +let optionList = rawData?.slice(0,30); let flowSentiment = 'n/a'; let callPercentage; let putPercentage; @@ -23,7 +24,6 @@ let displayPutVolume; let latestPutCallRatio; const totalPutCallRatio = data?.getOptionsPlotData?.putCallRatio; -const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; const totalVolume = data?.getOptionsPlotData?.totalVolume; @@ -47,31 +47,45 @@ const putOpenInterestList = data?.getOptionsPlotData?.putOpenInterestList; -function formatDate(timestamp) { +function formatTime(timestamp) { // Convert timestamp to milliseconds var date = new Date(timestamp * 1000); - // Get month, day, hours, minutes, and seconds - var month = date.getMonth() + 1; // Month starts from 0 - var day = date.getDate(); + // hours, minutes, and seconds var hours = date.getHours(); var minutes = date.getMinutes(); var seconds = date.getSeconds(); - // Add leading zeros if necessary - month = (month < 10 ? "0" : "") + month; - day = (day < 10 ? "0" : "") + day; hours = (hours < 10 ? "0" : "") + hours; minutes = (minutes < 10 ? "0" : "") + minutes; seconds = (seconds < 10 ? "0" : "") + seconds; // Format the date string - var formattedDate = month + "/" + day + " " + hours + ":" + minutes + ":" + seconds; + var formattedDate = hours + ":" + minutes + ":" + seconds //var formattedDate = hours + ":" + minutes + ":" + seconds; return formattedDate; } +function formatDate(timestamp) { + // Convert timestamp to milliseconds and create a Date object + var date = new Date(timestamp * 1000); + + // Get month, day, and year + var month = date.getMonth() + 1; // Month starts from 0 + var day = date.getDate(); + var year = date.getFullYear(); + + // Add leading zeros if necessary + month = (month < 10 ? "0" : "") + month; + day = (day < 10 ? "0" : "") + day; + + // Format the date string in mm/dd/YYYY + var formattedDate = month + "/" + day + "/" + year; + + return formattedDate; +} + function changeStatement(event) { @@ -127,7 +141,6 @@ function plotData(callData, putData) { } ], series: [ - { name: 'Call', type: 'bar', @@ -137,9 +150,8 @@ function plotData(callData, putData) { }, data: callData, itemStyle: { - color: '#0FB307' + color: '#00FC50' }, - barWidth: '30%' }, { name: 'Put', @@ -150,10 +162,9 @@ function plotData(callData, putData) { }, data: putData, itemStyle: { - color: '#FF2F1F' //'#7A1C16' + color: '#EE5365' //'#7A1C16' }, }, - ] }; return options; @@ -250,7 +261,6 @@ $: { - @@ -258,7 +268,6 @@ $: { - @@ -389,7 +398,7 @@ $: {
-
+
Flow Sentiment {flowSentiment} @@ -398,7 +407,7 @@ $: {
-
+
Put/Call @@ -425,7 +434,7 @@ $: {
-
+
Call Flow @@ -454,7 +463,7 @@ $: {
-
+
Put Flow @@ -499,6 +508,7 @@ $: { Time + Date Expiry Strike C/P @@ -512,10 +522,14 @@ $: { - {#each optionList as item} + {#each (data?.user?.tier === 'Pro' ? optionList : optionList?.slice(0,3)) as item, index} - + + + {formatTime(item?.updated)} + + {formatDate(item?.updated)} diff --git a/src/routes/etf/[tickerID]/options/+page.server.ts b/src/routes/etf/[tickerID]/options/+page.ts similarity index 70% rename from src/routes/etf/[tickerID]/options/+page.server.ts rename to src/routes/etf/[tickerID]/options/+page.ts index 7239d5f0..e2511aa7 100644 --- a/src/routes/etf/[tickerID]/options/+page.server.ts +++ b/src/routes/etf/[tickerID]/options/+page.ts @@ -1,5 +1,19 @@ +import { userRegion, getCache, setCache } from '$lib/store'; + const usRegion = ['cle1','iad1','pdx1','sfo1']; +let apiURL = import.meta.env.VITE_EU_API_URL; // Set a default API URL + +userRegion.subscribe(value => { + + if (usRegion.includes(value)) { + apiURL = import.meta.env.VITE_USEAST_API_URL; + } else { + apiURL = import.meta.env.VITE_EU_API_URL; + } +}); + + function daysLeft(targetDate) { const targetTime = new Date(targetDate).getTime(); @@ -13,19 +27,16 @@ function daysLeft(targetDate) { } -export const load = async ({ params, locals }) => { - - const userRegion = locals.region?.split("::")[0]; - - let apiURL; - - if (usRegion?.includes(userRegion)) { - apiURL = import.meta.env.VITE_USEAST_API_URL; - } else { - apiURL = import.meta.env.VITE_EU_API_URL; - }; +export const load = async ({ params }) => { + const getOptionsPlotData = async () => { + let res; + + const cachedData = getCache(params.tickerID, 'getOptionsPlotData'); + if (cachedData) { + res = cachedData; + } else { // make the POST request to the endpoint const postData = { @@ -71,13 +82,23 @@ export const load = async ({ params, locals }) => { const callOpenInterestList = output?.map(item => item?.CALL?.open_interest); const putOpenInterestList = output?.map(item => item?.PUT?.open_interest); + res = {plot: output, 'dateList': dateList, 'callOpenInterestList': callOpenInterestList, 'putOpenInterestList': putOpenInterestList, 'callVolumeList': callVolumeList, 'putVolumeList': putVolumeList, 'putCallRatio': putCallRatio, 'putCallOpenInterestRatio': putCallOpenInterestRatio,'totalVolume': totalVolume, 'totalOpenInterest': totalOpenInterest }; + setCache(params.tickerID, res, 'getOptionsPlotData'); - return {plot: output, 'dateList': dateList, 'callOpenInterestList': callOpenInterestList, 'putOpenInterestList': putOpenInterestList, 'callVolumeList': callVolumeList, 'putVolumeList': putVolumeList, 'putCallRatio': putCallRatio, 'putCallOpenInterestRatio': putCallOpenInterestRatio,'totalVolume': totalVolume, 'totalOpenInterest': totalOpenInterest }; + } + + return res; }; const getOptionsFlowData = async () => { + let output; + const cachedData = getCache(params.tickerID, 'getOptionsFlowData'); + if (cachedData) { + output = cachedData; + } else { + const postData = { ticker: params.tickerID }; @@ -91,11 +112,14 @@ export const load = async ({ params, locals }) => { body: JSON.stringify(postData) }); - const output = await response.json(); + output = await response.json(); output?.forEach(item => { item.dte = daysLeft(item?.date_expiration); }); + + setCache(params.tickerID, output, 'getOptionsFlowData'); + } return output; }; @@ -105,4 +129,5 @@ export const load = async ({ params, locals }) => { getOptionsPlotData: await getOptionsPlotData(), getOptionsFlowData: await getOptionsFlowData() }; + }; diff --git a/src/routes/stocks/[tickerID]/options/+page.svelte b/src/routes/stocks/[tickerID]/options/+page.svelte index e1096de9..f30201eb 100644 --- a/src/routes/stocks/[tickerID]/options/+page.svelte +++ b/src/routes/stocks/[tickerID]/options/+page.svelte @@ -15,7 +15,7 @@ let optionsPlotData = data?.getOptionsPlotData?.plot; let displayData = 'volume'; let options; let rawData = data?.getOptionsFlowData -let optionList = rawData?.slice(0,15); +let optionList = rawData?.slice(0,30); let flowSentiment = 'n/a'; let callPercentage; let putPercentage; @@ -47,31 +47,45 @@ const putOpenInterestList = data?.getOptionsPlotData?.putOpenInterestList; -function formatDate(timestamp) { +function formatTime(timestamp) { // Convert timestamp to milliseconds var date = new Date(timestamp * 1000); - // Get month, day, hours, minutes, and seconds - var month = date.getMonth() + 1; // Month starts from 0 - var day = date.getDate(); + // hours, minutes, and seconds var hours = date.getHours(); var minutes = date.getMinutes(); var seconds = date.getSeconds(); - // Add leading zeros if necessary - month = (month < 10 ? "0" : "") + month; - day = (day < 10 ? "0" : "") + day; hours = (hours < 10 ? "0" : "") + hours; minutes = (minutes < 10 ? "0" : "") + minutes; seconds = (seconds < 10 ? "0" : "") + seconds; // Format the date string - var formattedDate = month + "/" + day + " " + hours + ":" + minutes + ":" + seconds; + var formattedDate = hours + ":" + minutes + ":" + seconds //var formattedDate = hours + ":" + minutes + ":" + seconds; return formattedDate; } +function formatDate(timestamp) { + // Convert timestamp to milliseconds and create a Date object + var date = new Date(timestamp * 1000); + + // Get month, day, and year + var month = date.getMonth() + 1; // Month starts from 0 + var day = date.getDate(); + var year = date.getFullYear(); + + // Add leading zeros if necessary + month = (month < 10 ? "0" : "") + month; + day = (day < 10 ? "0" : "") + day; + + // Format the date string in mm/dd/YYYY + var formattedDate = month + "/" + day + "/" + year; + + return formattedDate; +} + function changeStatement(event) { @@ -136,9 +150,8 @@ function plotData(callData, putData) { }, data: callData, itemStyle: { - color: '#0FB307' + color: '#00FC50' }, - barWidth: '30%', }, { name: 'Put', @@ -149,7 +162,7 @@ function plotData(callData, putData) { }, data: putData, itemStyle: { - color: '#FF2F1F' //'#7A1C16' + color: '#EE5365' //'#7A1C16' }, }, ] @@ -495,6 +508,7 @@ $: { Time + Date Expiry Strike C/P @@ -510,8 +524,12 @@ $: { {#each (data?.user?.tier === 'Pro' ? optionList : optionList?.slice(0,3)) as item, index} - + + + {formatTime(item?.updated)} + + {formatDate(item?.updated)} diff --git a/src/routes/stocks/[tickerID]/options/+page.server.ts b/src/routes/stocks/[tickerID]/options/+page.ts similarity index 70% rename from src/routes/stocks/[tickerID]/options/+page.server.ts rename to src/routes/stocks/[tickerID]/options/+page.ts index 7239d5f0..e2511aa7 100644 --- a/src/routes/stocks/[tickerID]/options/+page.server.ts +++ b/src/routes/stocks/[tickerID]/options/+page.ts @@ -1,5 +1,19 @@ +import { userRegion, getCache, setCache } from '$lib/store'; + const usRegion = ['cle1','iad1','pdx1','sfo1']; +let apiURL = import.meta.env.VITE_EU_API_URL; // Set a default API URL + +userRegion.subscribe(value => { + + if (usRegion.includes(value)) { + apiURL = import.meta.env.VITE_USEAST_API_URL; + } else { + apiURL = import.meta.env.VITE_EU_API_URL; + } +}); + + function daysLeft(targetDate) { const targetTime = new Date(targetDate).getTime(); @@ -13,19 +27,16 @@ function daysLeft(targetDate) { } -export const load = async ({ params, locals }) => { - - const userRegion = locals.region?.split("::")[0]; - - let apiURL; - - if (usRegion?.includes(userRegion)) { - apiURL = import.meta.env.VITE_USEAST_API_URL; - } else { - apiURL = import.meta.env.VITE_EU_API_URL; - }; +export const load = async ({ params }) => { + const getOptionsPlotData = async () => { + let res; + + const cachedData = getCache(params.tickerID, 'getOptionsPlotData'); + if (cachedData) { + res = cachedData; + } else { // make the POST request to the endpoint const postData = { @@ -71,13 +82,23 @@ export const load = async ({ params, locals }) => { const callOpenInterestList = output?.map(item => item?.CALL?.open_interest); const putOpenInterestList = output?.map(item => item?.PUT?.open_interest); + res = {plot: output, 'dateList': dateList, 'callOpenInterestList': callOpenInterestList, 'putOpenInterestList': putOpenInterestList, 'callVolumeList': callVolumeList, 'putVolumeList': putVolumeList, 'putCallRatio': putCallRatio, 'putCallOpenInterestRatio': putCallOpenInterestRatio,'totalVolume': totalVolume, 'totalOpenInterest': totalOpenInterest }; + setCache(params.tickerID, res, 'getOptionsPlotData'); - return {plot: output, 'dateList': dateList, 'callOpenInterestList': callOpenInterestList, 'putOpenInterestList': putOpenInterestList, 'callVolumeList': callVolumeList, 'putVolumeList': putVolumeList, 'putCallRatio': putCallRatio, 'putCallOpenInterestRatio': putCallOpenInterestRatio,'totalVolume': totalVolume, 'totalOpenInterest': totalOpenInterest }; + } + + return res; }; const getOptionsFlowData = async () => { + let output; + const cachedData = getCache(params.tickerID, 'getOptionsFlowData'); + if (cachedData) { + output = cachedData; + } else { + const postData = { ticker: params.tickerID }; @@ -91,11 +112,14 @@ export const load = async ({ params, locals }) => { body: JSON.stringify(postData) }); - const output = await response.json(); + output = await response.json(); output?.forEach(item => { item.dte = daysLeft(item?.date_expiration); }); + + setCache(params.tickerID, output, 'getOptionsFlowData'); + } return output; }; @@ -105,4 +129,5 @@ export const load = async ({ params, locals }) => { getOptionsPlotData: await getOptionsPlotData(), getOptionsFlowData: await getOptionsFlowData() }; + };