This commit is contained in:
MuslemRahimi 2025-04-03 19:31:43 +02:00
parent 4f302a94d5
commit 47ee632513
4 changed files with 189 additions and 130 deletions

View File

@ -249,7 +249,7 @@
type: "datetime", type: "datetime",
endOnTick: false, endOnTick: false,
crosshair: { crosshair: {
color: "#fff", color: $mode === "light" ? "black" : "white",
width: 1, width: 1,
dashStyle: "Solid", dashStyle: "Solid",
}, },

View File

@ -425,7 +425,7 @@
type: "datetime", type: "datetime",
endOnTick: false, endOnTick: false,
crosshair: { crosshair: {
color: "#fff", color: $mode === "light" ? "black" : "white",
width: 1, width: 1,
dashStyle: "Solid", dashStyle: "Solid",
}, },

View File

@ -347,8 +347,44 @@
// Build series based on the selected graph type, using filteredData // Build series based on the selected graph type, using filteredData
let series = []; let series = [];
const fillColorStart = "rgb(70, 129, 244,0.5)";
const fillColorEnd = "rgb(70, 129, 244,0.001)";
if (selectGraphType == "Vol/OI") { if (selectGraphType == "Vol/OI") {
series = [ series = [
{
name: "Stock Price",
type: "area",
yAxis: 1,
data: filteredData.map((item) => [
new Date(item.date).getTime(),
item.price,
]),
fillColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [
[0, fillColorStart],
[1, fillColorEnd],
],
},
color: "#4681f4",
borderColor: "4681f4",
lineWidth: 1.3,
marker: { enabled: false },
animation: false,
},
{
name: "Avg Fill",
type: "spline", // smooth line
data: filteredData.map((item) => [
new Date(item.date).getTime(),
item.mark,
]),
color: "#F21C64",
yAxis: 2,
lineWidth: 1.3,
animation: false,
marker: { enabled: false },
},
{ {
name: "Volume", name: "Volume",
type: "column", type: "column",
@ -375,72 +411,55 @@
yAxis: 0, yAxis: 0,
animation: false, animation: false,
}, },
{
name: "Avg Fill",
type: "spline", // smooth line
data: filteredData.map((item) => [
new Date(item.date).getTime(),
item.mark,
]),
color: "#FAD776",
yAxis: 2,
animation: false,
marker: { enabled: false },
},
{
name: "Price",
type: "spline",
yAxis: 1,
data: filteredData.map((item) => [
new Date(item.date).getTime(),
item.price,
]),
color: $mode === "light" ? "#3B82F6" : "white",
lineWidth: 1,
marker: { enabled: false },
animation: false,
},
]; ];
} else { } else {
series = [ series = [
{ {
name: "IV", name: "Stock Price",
type: "spline", type: "area",
data: filteredData.map((item) => [
new Date(item.date).getTime(),
Math.floor(item.implied_volatility * 100),
]),
color: "#B24BF3",
yAxis: 0,
animation: false,
marker: { enabled: false },
},
{
name: "Avg Fill",
type: "spline",
data: filteredData.map((item) => [
new Date(item.date).getTime(),
item.mark,
]),
color: "#FAD776",
yAxis: 2,
lineWidth: 1,
animation: false,
marker: { enabled: false },
},
{
name: "Price",
type: "spline",
yAxis: 1, yAxis: 1,
data: filteredData.map((item) => [ data: filteredData.map((item) => [
new Date(item.date).getTime(), new Date(item.date).getTime(),
item.price, item.price,
]), ]),
color: $mode === "light" ? "black" : "white", fillColor: {
lineWidth: 1, linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [
[0, fillColorStart],
[1, fillColorEnd],
],
},
color: "#4681f4",
borderColor: "4681f4",
lineWidth: 1.3,
marker: { enabled: false }, marker: { enabled: false },
animation: false, animation: false,
}, },
{
name: "Avg Fill",
type: "spline", // smooth line
data: filteredData?.map((item) => [
new Date(item.date).getTime(),
item.mark,
]),
color: "#F21C64",
yAxis: 2,
lineWidth: 1.3,
animation: false,
marker: { enabled: false },
},
{
name: "IV",
type: "spline",
data: filteredData?.map((item) => [
new Date(item.date).getTime(),
Math.floor(item.implied_volatility * 100),
]),
color: $mode === "light" ? "black" : "white",
yAxis: 0,
animation: false,
marker: { enabled: false },
},
]; ];
} }
@ -478,7 +497,7 @@
dashStyle: "Solid", dashStyle: "Solid",
}, },
labels: { labels: {
style: { color: "#fff" }, style: { color: $mode === "light" ? "#545454" : "white" },
distance: 20, distance: 20,
formatter: function () { formatter: function () {
return new Date(this.value).toLocaleDateString("en-US", { return new Date(this.value).toLocaleDateString("en-US", {
@ -503,7 +522,9 @@
{ {
gridLineWidth: 1, gridLineWidth: 1,
gridLineColor: $mode === "light" ? "#e5e7eb" : "#111827", gridLineColor: $mode === "light" ? "#e5e7eb" : "#111827",
labels: { style: { color: $mode === "light" ? "black" : "white" } }, labels: {
style: { color: $mode === "light" ? "#545454" : "white" },
},
title: { text: null }, title: { text: null },
opposite: true, opposite: true,
}, },
@ -548,7 +569,6 @@
// Loop through each point in the shared tooltip // Loop through each point in the shared tooltip
this.points.forEach((point) => { this.points.forEach((point) => {
tooltipContent += ` tooltipContent += `
<span style="display:inline-block; width:10px; height:10px; background-color:${point.color}; border-radius:50%; margin-right:5px;"></span>
<span class="font-semibold text-sm">${point.series.name}:</span> <span class="font-semibold text-sm">${point.series.name}:</span>
<span class="font-normal text-sm">${abbreviateNumber(point.y)}</span><br>`; <span class="font-normal text-sm">${abbreviateNumber(point.y)}</span><br>`;
}); });
@ -556,7 +576,19 @@
return tooltipContent; return tooltipContent;
}, },
}, },
legend: { enabled: false },
legend: {
enabled: true,
align: "center", // Positions legend at the left edge
verticalAlign: "top", // Positions legend at the top
layout: "horizontal", // Align items horizontally (use 'vertical' if preferred)
itemStyle: {
color: $mode === "light" ? "black" : "white",
},
symbolWidth: 16, // Controls the width of the legend symbol
symbolRadius: 8, // Creates circular symbols (adjust radius as needed)
squareSymbol: false, // Ensures symbols are circular, not square
},
series: series, series: series,
}; };

View File

@ -113,11 +113,9 @@
style: `border-radius: 5px; background: #fff; color: #000; border-color: ${$mode === "light" ? "#F9FAFB" : "#4B5563"}; font-size: 15px;`, style: `border-radius: 5px; background: #fff; color: #000; border-color: ${$mode === "light" ? "#F9FAFB" : "#4B5563"}; font-size: 15px;`,
}); });
} else { } else {
optionsWatchlist = optionsWatchlist?.filter( rawData = rawData?.filter((item) => !deleteOptionsId?.includes(item?.id));
(item) => !deleteOptionsId?.includes(item?.id),
);
optionsWatchlist = [...optionsWatchlist]; rawData = [...rawData];
const postData = { const postData = {
itemIdList: deleteOptionsId, itemIdList: deleteOptionsId,
@ -168,8 +166,6 @@
contract: optionSymbol, contract: optionSymbol,
}; };
console.log(postData);
// make the POST request to the endpoint // make the POST request to the endpoint
const response = await fetch("/api/options-contract-history", { const response = await fetch("/api/options-contract-history", {
method: "POST", method: "POST",
@ -221,18 +217,17 @@
optionDetailsDesktopModal?.showModal(); optionDetailsDesktopModal?.showModal();
strikePrice = item?.strike_price; strikePrice = item?.strike_price;
optionType = item?.option_type; optionType = item?.put_call;
ticker = item?.ticker; ticker = item?.ticker;
dateExpiration = item?.date_expiration; dateExpiration = item?.date_expiration;
optionSymbol = item?.option_symbol; optionSymbol = item?.option_symbol;
const output = await getContractHistory(); const output = await getContractHistory();
const historicalPrice = await getHistoricalPrice(); const historicalPrice = await getHistoricalPrice();
console.log(historicalPrice);
rawDataHistory = output?.history; rawDataHistory = output?.history;
if (rawDataHistory?.length > 0) { if (rawDataHistory?.length > 0) {
rawDataHistory.forEach((entry) => { rawDataHistory?.forEach((entry) => {
const matchingData = historicalPrice?.find( const matchingData = historicalPrice?.find(
(d) => d?.time === entry?.date, (d) => d?.time === entry?.date,
); );
@ -264,8 +259,44 @@
// Build series based on the selected graph type, using filteredData // Build series based on the selected graph type, using filteredData
let series = []; let series = [];
const fillColorStart = "rgb(70, 129, 244,0.5)";
const fillColorEnd = "rgb(70, 129, 244,0.001)";
if (selectGraphType == "Vol/OI") { if (selectGraphType == "Vol/OI") {
series = [ series = [
{
name: "Stock Price",
type: "area",
yAxis: 1,
data: filteredData.map((item) => [
new Date(item.date).getTime(),
item.price,
]),
fillColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [
[0, fillColorStart],
[1, fillColorEnd],
],
},
color: "#4681f4",
borderColor: "4681f4",
lineWidth: 1.3,
marker: { enabled: false },
animation: false,
},
{
name: "Avg Fill",
type: "spline", // smooth line
data: filteredData.map((item) => [
new Date(item.date).getTime(),
item.mark,
]),
color: "#F21C64",
yAxis: 2,
lineWidth: 1.3,
animation: false,
marker: { enabled: false },
},
{ {
name: "Volume", name: "Volume",
type: "column", type: "column",
@ -292,72 +323,55 @@
yAxis: 0, yAxis: 0,
animation: false, animation: false,
}, },
{
name: "Avg Fill",
type: "spline", // smooth line
data: filteredData.map((item) => [
new Date(item.date).getTime(),
item.mark,
]),
color: "#FAD776",
yAxis: 2,
animation: false,
marker: { enabled: false },
},
{
name: "Price",
type: "spline",
yAxis: 1,
data: filteredData.map((item) => [
new Date(item.date).getTime(),
item.price,
]),
color: $mode === "light" ? "#3B82F6" : "white",
lineWidth: 1,
marker: { enabled: false },
animation: false,
},
]; ];
} else { } else {
series = [ series = [
{ {
name: "IV", name: "Stock Price",
type: "spline", type: "area",
data: filteredData.map((item) => [
new Date(item.date).getTime(),
Math.floor(item.implied_volatility * 100),
]),
color: "#B24BF3",
yAxis: 0,
animation: false,
marker: { enabled: false },
},
{
name: "Avg Fill",
type: "spline",
data: filteredData.map((item) => [
new Date(item.date).getTime(),
item.mark,
]),
color: "#FAD776",
yAxis: 2,
lineWidth: 1,
animation: false,
marker: { enabled: false },
},
{
name: "Price",
type: "spline",
yAxis: 1, yAxis: 1,
data: filteredData.map((item) => [ data: filteredData.map((item) => [
new Date(item.date).getTime(), new Date(item.date).getTime(),
item.price, item.price,
]), ]),
color: $mode === "light" ? "black" : "white", fillColor: {
lineWidth: 1, linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [
[0, fillColorStart],
[1, fillColorEnd],
],
},
color: "#4681f4",
borderColor: "4681f4",
lineWidth: 1.3,
marker: { enabled: false }, marker: { enabled: false },
animation: false, animation: false,
}, },
{
name: "Avg Fill",
type: "spline", // smooth line
data: filteredData?.map((item) => [
new Date(item.date).getTime(),
item.mark,
]),
color: "#F21C64",
yAxis: 2,
lineWidth: 1.3,
animation: false,
marker: { enabled: false },
},
{
name: "IV",
type: "spline",
data: filteredData?.map((item) => [
new Date(item.date).getTime(),
Math.floor(item.implied_volatility * 100),
]),
color: $mode === "light" ? "black" : "white",
yAxis: 0,
animation: false,
marker: { enabled: false },
},
]; ];
} }
@ -395,7 +409,7 @@
dashStyle: "Solid", dashStyle: "Solid",
}, },
labels: { labels: {
style: { color: "#fff" }, style: { color: $mode === "light" ? "#545454" : "white" },
distance: 20, distance: 20,
formatter: function () { formatter: function () {
return new Date(this.value).toLocaleDateString("en-US", { return new Date(this.value).toLocaleDateString("en-US", {
@ -420,7 +434,9 @@
{ {
gridLineWidth: 1, gridLineWidth: 1,
gridLineColor: $mode === "light" ? "#e5e7eb" : "#111827", gridLineColor: $mode === "light" ? "#e5e7eb" : "#111827",
labels: { style: { color: $mode === "light" ? "black" : "white" } }, labels: {
style: { color: $mode === "light" ? "#545454" : "white" },
},
title: { text: null }, title: { text: null },
opposite: true, opposite: true,
}, },
@ -465,7 +481,6 @@
// Loop through each point in the shared tooltip // Loop through each point in the shared tooltip
this.points.forEach((point) => { this.points.forEach((point) => {
tooltipContent += ` tooltipContent += `
<span style="display:inline-block; width:10px; height:10px; background-color:${point.color}; border-radius:50%; margin-right:5px;"></span>
<span class="font-semibold text-sm">${point.series.name}:</span> <span class="font-semibold text-sm">${point.series.name}:</span>
<span class="font-normal text-sm">${abbreviateNumber(point.y)}</span><br>`; <span class="font-normal text-sm">${abbreviateNumber(point.y)}</span><br>`;
}); });
@ -473,7 +488,19 @@
return tooltipContent; return tooltipContent;
}, },
}, },
legend: { enabled: false },
legend: {
enabled: true,
align: "center", // Positions legend at the left edge
verticalAlign: "top", // Positions legend at the top
layout: "horizontal", // Align items horizontally (use 'vertical' if preferred)
itemStyle: {
color: $mode === "light" ? "black" : "white",
},
symbolWidth: 16, // Controls the width of the legend symbol
symbolRadius: 8, // Creates circular symbols (adjust radius as needed)
squareSymbol: false, // Ensures symbols are circular, not square
},
series: series, series: series,
}; };
@ -1065,13 +1092,13 @@
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{abbreviateNumber(item?.total_premium, false, true)} {abbreviateNumber(item?.total_premium)}
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{abbreviateNumber(item?.gex, false, true)} {abbreviateNumber(item?.gex?.toFixed(2))}
</td> </td>
<td class="text-sm sm:text-[1rem] text-end"> <td class="text-sm sm:text-[1rem] text-end">
{abbreviateNumber(item?.dex, false, true)} {abbreviateNumber(item?.dex?.toFixed(2))}
</td> </td>
</tr> </tr>
{/each} {/each}