add stock price to historical contract data
This commit is contained in:
parent
1b516b3cfb
commit
27b3a29175
@ -22,12 +22,30 @@ export const load = async ({ locals, params }) => {
|
|||||||
output.openInterest = user?.tier !== "Pro" ? output?.openInterest?.slice(0, 3) : output?.openInterest;
|
output.openInterest = user?.tier !== "Pro" ? output?.openInterest?.slice(0, 3) : output?.openInterest;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const getHistoricalPrice = async () => {
|
||||||
|
const postData = { ticker: params.tickerID, timePeriod: "six-months" };
|
||||||
|
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
|
// Make sure to return a promise
|
||||||
return {
|
return {
|
||||||
getData: await getData(),
|
getData: await getData(),
|
||||||
|
getHistoricalPrice: await getHistoricalPrice(),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
abbreviateNumber,
|
abbreviateNumber,
|
||||||
monthNames,
|
monthNames,
|
||||||
} from "$lib/utils";
|
} from "$lib/utils";
|
||||||
import { setCache, getCache, stockTicker, screenWidth } from "$lib/store";
|
import { setCache, getCache, etfTicker, screenWidth } from "$lib/store";
|
||||||
import * as HoverCard from "$lib/components/shadcn/hover-card/index.js";
|
import * as HoverCard from "$lib/components/shadcn/hover-card/index.js";
|
||||||
|
|
||||||
import TableHeader from "$lib/components/Table/TableHeader.svelte";
|
import TableHeader from "$lib/components/Table/TableHeader.svelte";
|
||||||
@ -67,6 +67,7 @@
|
|||||||
function computeOTM(strikePrice, optionType) {
|
function computeOTM(strikePrice, optionType) {
|
||||||
// Get the current stock price
|
// Get the current stock price
|
||||||
const currentPrice = data?.getStockQuote?.price;
|
const currentPrice = data?.getStockQuote?.price;
|
||||||
|
|
||||||
let otmPercentage = 0;
|
let otmPercentage = 0;
|
||||||
|
|
||||||
if (optionType === "C") {
|
if (optionType === "C") {
|
||||||
@ -282,6 +283,7 @@
|
|||||||
|
|
||||||
let dates = data?.map((item) => item?.date);
|
let dates = data?.map((item) => item?.date);
|
||||||
let avgPrice = data?.map((item) => item?.avg_price);
|
let avgPrice = data?.map((item) => item?.avg_price);
|
||||||
|
let priceList = data?.map((item) => item?.price);
|
||||||
let bidVolume = data?.map((item) => item?.bid_volume);
|
let bidVolume = data?.map((item) => item?.bid_volume);
|
||||||
let askVolume = data?.map((item) => item?.ask_volume);
|
let askVolume = data?.map((item) => item?.ask_volume);
|
||||||
let midVolume = data?.map((item) => item?.mid_volume);
|
let midVolume = data?.map((item) => item?.mid_volume);
|
||||||
@ -291,122 +293,51 @@
|
|||||||
let ivList = data?.map((item) =>
|
let ivList = data?.map((item) =>
|
||||||
Math?.floor(item?.implied_volatility * 100),
|
Math?.floor(item?.implied_volatility * 100),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const createLineSeries = (name, data, color, yAxisIndex = 1) => ({
|
||||||
|
name,
|
||||||
|
type: "line",
|
||||||
|
yAxisIndex,
|
||||||
|
data,
|
||||||
|
itemStyle: { color },
|
||||||
|
lineStyle: { width: 2 },
|
||||||
|
smooth: true,
|
||||||
|
showSymbol: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const createBarSeries = (name, data, color, stack = null) => ({
|
||||||
|
name,
|
||||||
|
type: "bar",
|
||||||
|
stack,
|
||||||
|
data,
|
||||||
|
itemStyle: { color },
|
||||||
|
emphasis: { focus: "series" },
|
||||||
|
});
|
||||||
|
|
||||||
let series = [];
|
let series = [];
|
||||||
if (selectGraphType === "Bid/Ask") {
|
if (selectGraphType === "Bid/Ask") {
|
||||||
series = [
|
series = [
|
||||||
{
|
createBarSeries("Ask", askVolume, "#33B890", "Ratio"),
|
||||||
name: "Ask",
|
createBarSeries("Mid", midVolume, "#007BFF", "Ratio"),
|
||||||
type: "bar",
|
createBarSeries("Bid", bidVolume, "#EE5365", "Ratio"),
|
||||||
stack: "Ratio",
|
createLineSeries("Avg Fill", avgPrice, "#FAD776"),
|
||||||
emphasis: {
|
createLineSeries("Stock Price", priceList, "#fff"),
|
||||||
focus: "series",
|
|
||||||
},
|
|
||||||
data: askVolume,
|
|
||||||
itemStyle: {
|
|
||||||
color: "#33B890",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Mid",
|
|
||||||
type: "bar",
|
|
||||||
stack: "Ratio",
|
|
||||||
emphasis: {
|
|
||||||
focus: "series",
|
|
||||||
},
|
|
||||||
data: midVolume,
|
|
||||||
itemStyle: {
|
|
||||||
color: "#007BFF",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Bid",
|
|
||||||
type: "bar",
|
|
||||||
stack: "Ratio",
|
|
||||||
emphasis: {
|
|
||||||
focus: "series",
|
|
||||||
},
|
|
||||||
data: bidVolume,
|
|
||||||
itemStyle: {
|
|
||||||
color: "#EE5365", //'#7A1C16'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Avg Fill", // Name for the line chart
|
|
||||||
type: "line", // Type of the chart (line)
|
|
||||||
yAxisIndex: 1, // Use the second y-axis on the right
|
|
||||||
data: avgPrice, // iv60Data (assumed to be passed as priceList)
|
|
||||||
itemStyle: {
|
|
||||||
color: "#fff", // 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
|
|
||||||
showSymbol: false,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
} else if (selectGraphType === "Vol/OI") {
|
} else if (selectGraphType === "Vol/OI") {
|
||||||
series = [
|
series = [
|
||||||
{
|
createBarSeries("Volume", volumeList, "#FD7E14"),
|
||||||
name: "Volume",
|
createBarSeries("OI", oiList, "#33B890"),
|
||||||
type: "bar",
|
createLineSeries("Avg Fill", avgPrice, "#FAD776"),
|
||||||
data: volumeList,
|
createLineSeries("Stock Price", priceList, "#fff"),
|
||||||
itemStyle: {
|
|
||||||
color: "#FD7E14",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "OI",
|
|
||||||
type: "bar",
|
|
||||||
data: oiList,
|
|
||||||
itemStyle: {
|
|
||||||
color: "#33B890",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
name: "Avg Fill", // Name for the line chart
|
|
||||||
type: "line", // Type of the chart (line)
|
|
||||||
yAxisIndex: 1, // Use the second y-axis on the right
|
|
||||||
data: avgPrice, // iv60Data (assumed to be passed as priceList)
|
|
||||||
itemStyle: {
|
|
||||||
color: "#fff", // 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
|
|
||||||
showSymbol: false,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
series = [
|
series = [
|
||||||
{
|
createLineSeries("IV", ivList, "#B24BF3", 0),
|
||||||
name: "IV",
|
createLineSeries("Avg Fill", avgPrice, "#FAD776"),
|
||||||
type: "line",
|
createLineSeries("Stock Price", priceList, "#fff"),
|
||||||
data: ivList,
|
|
||||||
itemStyle: {
|
|
||||||
color: "#B24BF3",
|
|
||||||
},
|
|
||||||
smooth: true, // Optional: make the line smooth
|
|
||||||
showSymbol: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Avg Fill", // Name for the line chart
|
|
||||||
type: "line", // Type of the chart (line)
|
|
||||||
yAxisIndex: 1, // Use the second y-axis on the right
|
|
||||||
data: avgPrice, // iv60Data (assumed to be passed as priceList)
|
|
||||||
itemStyle: {
|
|
||||||
color: "#fff", // 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
|
|
||||||
showSymbol: false,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
animation: false,
|
animation: false,
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@ -544,6 +475,15 @@
|
|||||||
|
|
||||||
rawDataHistory = await getContractHistory(item?.option_symbol);
|
rawDataHistory = await getContractHistory(item?.option_symbol);
|
||||||
if (rawDataHistory?.length > 0) {
|
if (rawDataHistory?.length > 0) {
|
||||||
|
rawDataHistory.forEach((entry) => {
|
||||||
|
const matchingData = data?.getHistoricalPrice?.find(
|
||||||
|
(d) => d?.time === entry?.date,
|
||||||
|
);
|
||||||
|
if (matchingData) {
|
||||||
|
entry.price = matchingData?.close;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(rawDataHistory);
|
||||||
optionsData = plotData();
|
optionsData = plotData();
|
||||||
rawDataHistory = rawDataHistory?.sort(
|
rawDataHistory = rawDataHistory?.sort(
|
||||||
(a, b) => new Date(b?.date) - new Date(a?.date),
|
(a, b) => new Date(b?.date) - new Date(a?.date),
|
||||||
@ -971,7 +911,7 @@
|
|||||||
<p class="text-white text-[1rem] sm:text-xl font-semibold cursor-text">
|
<p class="text-white text-[1rem] sm:text-xl font-semibold cursor-text">
|
||||||
Contract: <span
|
Contract: <span
|
||||||
class={optionType === "C" ? "text-[#00FC50]" : "text-[#FF2F1F]"}
|
class={optionType === "C" ? "text-[#00FC50]" : "text-[#FF2F1F]"}
|
||||||
>{$stockTicker}
|
>{$etfTicker}
|
||||||
{strikePrice}
|
{strikePrice}
|
||||||
{optionType}
|
{optionType}
|
||||||
{dateExpiration} ({daysLeft(dateExpiration)})
|
{dateExpiration} ({daysLeft(dateExpiration)})
|
||||||
|
|||||||
@ -22,12 +22,30 @@ export const load = async ({ locals, params }) => {
|
|||||||
output.openInterest = user?.tier !== "Pro" ? output?.openInterest?.slice(0, 3) : output?.openInterest;
|
output.openInterest = user?.tier !== "Pro" ? output?.openInterest?.slice(0, 3) : output?.openInterest;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const getHistoricalPrice = async () => {
|
||||||
|
const postData = { ticker: params.tickerID, timePeriod: "six-months" };
|
||||||
|
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
|
// Make sure to return a promise
|
||||||
return {
|
return {
|
||||||
getData: await getData(),
|
getData: await getData(),
|
||||||
|
getHistoricalPrice: await getHistoricalPrice(),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -283,6 +283,7 @@
|
|||||||
|
|
||||||
let dates = data?.map((item) => item?.date);
|
let dates = data?.map((item) => item?.date);
|
||||||
let avgPrice = data?.map((item) => item?.avg_price);
|
let avgPrice = data?.map((item) => item?.avg_price);
|
||||||
|
let priceList = data?.map((item) => item?.price);
|
||||||
let bidVolume = data?.map((item) => item?.bid_volume);
|
let bidVolume = data?.map((item) => item?.bid_volume);
|
||||||
let askVolume = data?.map((item) => item?.ask_volume);
|
let askVolume = data?.map((item) => item?.ask_volume);
|
||||||
let midVolume = data?.map((item) => item?.mid_volume);
|
let midVolume = data?.map((item) => item?.mid_volume);
|
||||||
@ -292,122 +293,51 @@
|
|||||||
let ivList = data?.map((item) =>
|
let ivList = data?.map((item) =>
|
||||||
Math?.floor(item?.implied_volatility * 100),
|
Math?.floor(item?.implied_volatility * 100),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const createLineSeries = (name, data, color, yAxisIndex = 1) => ({
|
||||||
|
name,
|
||||||
|
type: "line",
|
||||||
|
yAxisIndex,
|
||||||
|
data,
|
||||||
|
itemStyle: { color },
|
||||||
|
lineStyle: { width: 2 },
|
||||||
|
smooth: true,
|
||||||
|
showSymbol: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const createBarSeries = (name, data, color, stack = null) => ({
|
||||||
|
name,
|
||||||
|
type: "bar",
|
||||||
|
stack,
|
||||||
|
data,
|
||||||
|
itemStyle: { color },
|
||||||
|
emphasis: { focus: "series" },
|
||||||
|
});
|
||||||
|
|
||||||
let series = [];
|
let series = [];
|
||||||
if (selectGraphType === "Bid/Ask") {
|
if (selectGraphType === "Bid/Ask") {
|
||||||
series = [
|
series = [
|
||||||
{
|
createBarSeries("Ask", askVolume, "#33B890", "Ratio"),
|
||||||
name: "Ask",
|
createBarSeries("Mid", midVolume, "#007BFF", "Ratio"),
|
||||||
type: "bar",
|
createBarSeries("Bid", bidVolume, "#EE5365", "Ratio"),
|
||||||
stack: "Ratio",
|
createLineSeries("Avg Fill", avgPrice, "#FAD776"),
|
||||||
emphasis: {
|
createLineSeries("Stock Price", priceList, "#fff"),
|
||||||
focus: "series",
|
|
||||||
},
|
|
||||||
data: askVolume,
|
|
||||||
itemStyle: {
|
|
||||||
color: "#33B890",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Mid",
|
|
||||||
type: "bar",
|
|
||||||
stack: "Ratio",
|
|
||||||
emphasis: {
|
|
||||||
focus: "series",
|
|
||||||
},
|
|
||||||
data: midVolume,
|
|
||||||
itemStyle: {
|
|
||||||
color: "#007BFF",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Bid",
|
|
||||||
type: "bar",
|
|
||||||
stack: "Ratio",
|
|
||||||
emphasis: {
|
|
||||||
focus: "series",
|
|
||||||
},
|
|
||||||
data: bidVolume,
|
|
||||||
itemStyle: {
|
|
||||||
color: "#EE5365", //'#7A1C16'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Avg Fill", // Name for the line chart
|
|
||||||
type: "line", // Type of the chart (line)
|
|
||||||
yAxisIndex: 1, // Use the second y-axis on the right
|
|
||||||
data: avgPrice, // iv60Data (assumed to be passed as priceList)
|
|
||||||
itemStyle: {
|
|
||||||
color: "#fff", // 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
|
|
||||||
showSymbol: false,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
} else if (selectGraphType === "Vol/OI") {
|
} else if (selectGraphType === "Vol/OI") {
|
||||||
series = [
|
series = [
|
||||||
{
|
createBarSeries("Volume", volumeList, "#FD7E14"),
|
||||||
name: "Volume",
|
createBarSeries("OI", oiList, "#33B890"),
|
||||||
type: "bar",
|
createLineSeries("Avg Fill", avgPrice, "#FAD776"),
|
||||||
data: volumeList,
|
createLineSeries("Stock Price", priceList, "#fff"),
|
||||||
itemStyle: {
|
|
||||||
color: "#FD7E14",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "OI",
|
|
||||||
type: "bar",
|
|
||||||
data: oiList,
|
|
||||||
itemStyle: {
|
|
||||||
color: "#33B890",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
name: "Avg Fill", // Name for the line chart
|
|
||||||
type: "line", // Type of the chart (line)
|
|
||||||
yAxisIndex: 1, // Use the second y-axis on the right
|
|
||||||
data: avgPrice, // iv60Data (assumed to be passed as priceList)
|
|
||||||
itemStyle: {
|
|
||||||
color: "#fff", // 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
|
|
||||||
showSymbol: false,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
series = [
|
series = [
|
||||||
{
|
createLineSeries("IV", ivList, "#B24BF3", 0),
|
||||||
name: "IV",
|
createLineSeries("Avg Fill", avgPrice, "#FAD776"),
|
||||||
type: "line",
|
createLineSeries("Stock Price", priceList, "#fff"),
|
||||||
data: ivList,
|
|
||||||
itemStyle: {
|
|
||||||
color: "#B24BF3",
|
|
||||||
},
|
|
||||||
smooth: true, // Optional: make the line smooth
|
|
||||||
showSymbol: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Avg Fill", // Name for the line chart
|
|
||||||
type: "line", // Type of the chart (line)
|
|
||||||
yAxisIndex: 1, // Use the second y-axis on the right
|
|
||||||
data: avgPrice, // iv60Data (assumed to be passed as priceList)
|
|
||||||
itemStyle: {
|
|
||||||
color: "#fff", // 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
|
|
||||||
showSymbol: false,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
animation: false,
|
animation: false,
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@ -545,6 +475,15 @@
|
|||||||
|
|
||||||
rawDataHistory = await getContractHistory(item?.option_symbol);
|
rawDataHistory = await getContractHistory(item?.option_symbol);
|
||||||
if (rawDataHistory?.length > 0) {
|
if (rawDataHistory?.length > 0) {
|
||||||
|
rawDataHistory.forEach((entry) => {
|
||||||
|
const matchingData = data?.getHistoricalPrice?.find(
|
||||||
|
(d) => d?.time === entry?.date,
|
||||||
|
);
|
||||||
|
if (matchingData) {
|
||||||
|
entry.price = matchingData?.close;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(rawDataHistory);
|
||||||
optionsData = plotData();
|
optionsData = plotData();
|
||||||
rawDataHistory = rawDataHistory?.sort(
|
rawDataHistory = rawDataHistory?.sort(
|
||||||
(a, b) => new Date(b?.date) - new Date(a?.date),
|
(a, b) => new Date(b?.date) - new Date(a?.date),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user