cache options endpoint

This commit is contained in:
MuslemRahimi 2024-06-23 18:45:56 +02:00
parent 05302bbf96
commit 6b8d0b69c8
4 changed files with 144 additions and 62 deletions

View File

@ -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 @@ $: {
<!-- Other meta tags -->
<meta property="og:title" content={`${$displayCompanyName} (${$etfTicker}) Options Activity · stocknear`}/>
<meta property="og:description" content={`Detailed informaton of unusual options activity for ${$displayCompanyName} (${$etfTicker}).`} />
<meta property="og:image" content="https://stocknear-pocketbase.s3.amazonaws.com/logo/meta_logo.jpg"/>
<meta property="og:type" content="website"/>
<!-- Add more Open Graph meta tags as needed -->
@ -258,7 +268,6 @@ $: {
<meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:title" content={`${$displayCompanyName} (${$etfTicker}) Options Activity · stocknear`}/>
<meta name="twitter:description" content={`Detailed informaton of unusual options activity for ${$displayCompanyName} (${$etfTicker}).`} />
<meta name="twitter:image" content="https://stocknear-pocketbase.s3.amazonaws.com/logo/meta_logo.jpg"/>
<!-- Add more Twitter meta tags as needed -->
</svelte:head>
@ -389,7 +398,7 @@ $: {
<div class="w-full mt-5 mb-10 m-auto flex justify-center items-center">
<div class="w-full grid grid-cols-2 lg:grid-cols-3 gap-y-3 lg:gap-y-3 gap-x-3 ">
<!--Start Flow Sentiment-->
<div class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#262626] shadow-lg rounded-lg h-20">
<div class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#262626] shadow-lg rounded-md h-20">
<div class="flex flex-col items-start">
<span class="font-medium text-gray-200 text-sm ">Flow Sentiment</span>
<span class="text-start text-[1rem] font-medium {flowSentiment === 'Bullish' ? 'text-[#00FC50]' : 'text-[#FC2120]'}">{flowSentiment}</span>
@ -398,7 +407,7 @@ $: {
</div>
<!--End Flow Sentiment-->
<!--Start Put/Call-->
<div class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#262626] shadow-lg rounded-lg h-20">
<div class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#262626] shadow-lg rounded-md h-20">
<div class="flex flex-col items-start">
<span class="font-medium text-gray-200 text-sm ">Put/Call</span>
<span class="text-start text-sm sm:text-[1rem] font-medium text-white">
@ -425,7 +434,7 @@ $: {
</div>
<!--End Put/Call-->
<!--Start Call Flow-->
<div class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#262626] shadow-lg rounded-lg h-20">
<div class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#262626] shadow-lg rounded-md h-20">
<div class="flex flex-col items-start">
<span class="font-medium text-gray-200 text-sm ">Call Flow</span>
<span class="text-start text-sm sm:text-[1rem] font-medium text-white">
@ -454,7 +463,7 @@ $: {
</div>
<!--End Call Flow-->
<!--Start Put Flow-->
<div class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#262626] shadow-lg rounded-lg h-20">
<div class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#262626] shadow-lg rounded-md h-20">
<div class="flex flex-col items-start">
<span class="font-medium text-gray-200 text-sm ">Put Flow</span>
<span class="text-start text-sm sm:text-[1rem] font-medium text-white">
@ -499,6 +508,7 @@ $: {
<thead>
<tr class="">
<td class="text-slate-200 font-semibold text-sm text-start">Time</td>
<td class="text-slate-200 font-semibold text-sm text-start">Date</td>
<td class="text-slate-200 font-semibold text-sm text-end">Expiry</td>
<td class="text-slate-200 font-semibold text-sm text-end">Strike</td>
<td class="text-slate-200 font-semibold text-sm text-end">C/P</td>
@ -512,10 +522,14 @@ $: {
</tr>
</thead>
<tbody>
{#each optionList as item}
{#each (data?.user?.tier === 'Pro' ? optionList : optionList?.slice(0,3)) as item, index}
<!-- row -->
<tr class="bg-[#0F0F0F] border-b-[#0F0F0F] ">
<tr class="odd:bg-[#202020] border-b-[#0F0F0F] {index+1 === optionList?.slice(0,3)?.length && data?.user?.tier !== 'Pro' ? 'opacity-[0.1]' : ''}">
<td class="text-white text-xs sm:text-sm text-start">
{formatTime(item?.updated)}
</td>
<td class="text-white text-xs sm:text-sm text-start">
{formatDate(item?.updated)}
</td>

View File

@ -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()
};
};

View File

@ -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 @@ $: {
<thead>
<tr class="">
<td class="text-slate-200 font-semibold text-sm text-start">Time</td>
<td class="text-slate-200 font-semibold text-sm text-start">Date</td>
<td class="text-slate-200 font-semibold text-sm text-end">Expiry</td>
<td class="text-slate-200 font-semibold text-sm text-end">Strike</td>
<td class="text-slate-200 font-semibold text-sm text-end">C/P</td>
@ -510,8 +524,12 @@ $: {
<tbody>
{#each (data?.user?.tier === 'Pro' ? optionList : optionList?.slice(0,3)) as item, index}
<!-- row -->
<tr class="bg-[#0F0F0F] border-b-[#0F0F0F] {index+1 === optionList?.slice(0,3)?.length && data?.user?.tier !== 'Pro' ? 'opacity-[0.1]' : ''}">
<tr class="odd:bg-[#202020] border-b-[#0F0F0F] {index+1 === optionList?.slice(0,3)?.length && data?.user?.tier !== 'Pro' ? 'opacity-[0.1]' : ''}">
<td class="text-white text-xs sm:text-sm text-start">
{formatTime(item?.updated)}
</td>
<td class="text-white text-xs sm:text-sm text-start">
{formatDate(item?.updated)}
</td>

View File

@ -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()
};
};