update calculator

This commit is contained in:
MuslemRahimi 2025-04-07 20:59:31 +02:00
parent c7cb9d9440
commit 07638762d3

View File

@ -37,14 +37,14 @@
let optionSymbol; let optionSymbol;
let breakEvenPrice; let breakEvenPrice;
let premium; let totalPremium;
let limits = {}; let limits = {};
let rawData = {}; let rawData = {};
let searchBarData = []; let searchBarData = [];
let timeoutId; let timeoutId;
let inputValue = selectedTicker; let inputValue = "";
let touchedInput = false; let touchedInput = false;
let prebuiltStrategy = [ let prebuiltStrategy = [
{ {
@ -160,37 +160,71 @@
}; };
function plotData() { function plotData() {
// total premium paid for 1 contract (premium is calculated per share times 100 shares) userStrategy = [
premium = selectedOptionPrice * 100 * selectedQuantity; {
action: selectedAction,
quantity: selectedQuantity,
date: selectedDate,
strike: selectedStrike,
optionType: selectedOptionType,
optionPrice: selectedOptionPrice,
},
];
// Create a key from the selected action and option type // Determine x-axis range based on current stock price and max leg strike
const scenarioKey = `${selectedAction} ${selectedOptionType}`; const maxLegStrike = Math.max(...userStrategy?.map((leg) => leg.strike));
const xMin = 0;
const xMax = Math.floor(Math.max(currentStockPrice, maxLegStrike) * 3);
const step = 10;
// Calculate break-even price per share using the mapping above. // Calculate the total premium across all legs
// Note: For display, we assume optionPrice is per share. totalPremium = userStrategy?.reduce((sum, leg) => {
breakEvenPrice; return sum + leg.optionPrice * 100 * leg.quantity;
if (breakEvenCalculators[scenarioKey]) { }, 0);
breakEvenPrice = breakEvenCalculators[scenarioKey](
selectedStrike, // Compute the aggregated payoff at each underlying price
selectedOptionPrice, const dataPoints = [];
for (let s = xMin; s <= xMax; s += step) {
let aggregatedPayoff = 0;
userStrategy.forEach((leg) => {
const legPremium = leg.optionPrice * 100 * leg.quantity;
const scenarioKey = `${leg.action} ${leg.optionType}`;
if (payoffFunctions[scenarioKey]) {
aggregatedPayoff += payoffFunctions[scenarioKey](
s,
leg.strike,
legPremium,
); );
} else { } else {
console.error("Break-even scenario not implemented:", scenarioKey); console.error(
breakEvenPrice = selectedStrike; // default fallback "Payoff function not implemented for scenario:",
scenarioKey,
);
}
});
dataPoints.push([s, aggregatedPayoff]);
} }
limits = {}; if (userStrategy.length === 1) {
const leg = userStrategy[0];
const scenarioKey = `${leg?.action} ${leg?.optionType}`;
if (breakEvenCalculators[scenarioKey]) {
breakEvenPrice = breakEvenCalculators[scenarioKey](
leg.strike,
leg.optionPrice,
);
}
if (scenarioKey === "Buy Call") { if (scenarioKey === "Buy Call") {
limits = { limits = {
maxProfit: "Unlimited", maxProfit: "Unlimited",
maxLoss: `-$${premium?.toLocaleString("en-US", { maxLoss: `-$${totalPremium.toLocaleString("en-US", {
minimumFractionDigits: 2, minimumFractionDigits: 2,
maximumFractionDigits: 2, maximumFractionDigits: 2,
})}`, })}`,
}; };
} else if (scenarioKey === "Sell Call") { } else if (scenarioKey === "Sell Call") {
limits = { limits = {
maxProfit: `$${premium?.toLocaleString("en-US", { maxProfit: `$${totalPremium.toLocaleString("en-US", {
minimumFractionDigits: 2, minimumFractionDigits: 2,
maximumFractionDigits: 2, maximumFractionDigits: 2,
})}`, })}`,
@ -198,27 +232,25 @@
}; };
} else if (scenarioKey === "Buy Put") { } else if (scenarioKey === "Buy Put") {
limits = { limits = {
// Maximum profit when underlying goes to 0 maxProfit: `$${(leg.strike * 100 - totalPremium).toLocaleString(
maxProfit: `$${(selectedStrike * 100 - premium)?.toLocaleString(
"en-US", "en-US",
{ {
minimumFractionDigits: 2, minimumFractionDigits: 2,
maximumFractionDigits: 2, maximumFractionDigits: 2,
}, },
)}`, )}`,
maxLoss: `-$${premium?.toLocaleString("en-US", { maxLoss: `-$${totalPremium.toLocaleString("en-US", {
minimumFractionDigits: 2, minimumFractionDigits: 2,
maximumFractionDigits: 2, maximumFractionDigits: 2,
})}`, })}`,
}; };
} else if (scenarioKey === "Sell Put") { } else if (scenarioKey === "Sell Put") {
limits = { limits = {
maxProfit: `$${premium?.toLocaleString("en-US", { maxProfit: `$${totalPremium.toLocaleString("en-US", {
minimumFractionDigits: 2, minimumFractionDigits: 2,
maximumFractionDigits: 2, maximumFractionDigits: 2,
})}`, })}`,
// Maximum loss when underlying goes to 0 maxLoss: `-$${(leg.strike * 100 - totalPremium).toLocaleString(
maxLoss: `-$${(selectedStrike * 100 - premium)?.toLocaleString(
"en-US", "en-US",
{ {
minimumFractionDigits: 2, minimumFractionDigits: 2,
@ -230,31 +262,21 @@
console.error("Limits not defined for scenario:", scenarioKey); console.error("Limits not defined for scenario:", scenarioKey);
limits = { maxProfit: "n/a", maxLoss: "n/a" }; limits = { maxProfit: "n/a", maxLoss: "n/a" };
} }
const dataPoints = [];
const xMin = 0;
const xMax = Math.floor(Math.max(currentStockPrice, selectedStrike) * 3);
const step = 10;
if (payoffFunctions[scenarioKey]) {
for (let s = xMin; s <= xMax; s += step) {
// For each price point, calculate payoff based on the scenario.
const payoff = payoffFunctions[scenarioKey](s, selectedStrike, premium);
dataPoints.push([s, payoff]);
}
} else { } else {
console.error( // For multiple legs, simply display the aggregated premium info
"Payoff function not implemented for scenario:", limits = {
scenarioKey, info: `Aggregated Premium: $${totalPremium.toLocaleString("en-US", {
); minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}`,
};
} }
// Build the chart options (using the first leg's ticker for the title)
const options = { const options = {
credits: { credits: { enabled: false },
enabled: false,
},
chart: { chart: {
type: "area", // or "line" type: "area",
backgroundColor: $mode === "light" ? "#fff" : "#09090B", backgroundColor: $mode === "light" ? "#fff" : "#09090B",
plotBackgroundColor: $mode === "light" ? "#fff" : "#09090B", plotBackgroundColor: $mode === "light" ? "#fff" : "#09090B",
height: 400, height: 400,
@ -272,9 +294,7 @@
text: `${selectedTicker} Price at Expiration ($)`, text: `${selectedTicker} Price at Expiration ($)`,
style: { color: $mode === "light" ? "#545454" : "white" }, style: { color: $mode === "light" ? "#545454" : "white" },
}, },
labels: { labels: { style: { color: $mode === "light" ? "#545454" : "white" } },
style: { color: $mode === "light" ? "#545454" : "white" },
},
plotLines: [ plotLines: [
// Underlying Price line // Underlying Price line
{ {
@ -288,22 +308,27 @@
}, },
zIndex: 5, zIndex: 5,
}, },
{ // Only add a breakeven line if there is a single leg
breakEvenPrice !== null
? {
value: breakEvenPrice, value: breakEvenPrice,
color: "#10B981", color: "#10B981",
dashStyle: "Dash", dashStyle: "Dash",
width: $screenWidth < 640 ? 0 : 1.5, width: $screenWidth < 640 ? 0 : 1.5,
label: { label: {
text: `<span class="hidden sm:block text-black dark:text-white text-sm">Breakeven $${breakEvenPrice.toFixed(2)}</span>`, text: `<span class="hidden sm:block text-black dark:text-white text-sm">Breakeven $${breakEvenPrice.toFixed(
2,
)}</span>`,
style: { color: $mode === "light" ? "black" : "white" }, style: { color: $mode === "light" ? "black" : "white" },
}, },
zIndex: 5, zIndex: 5,
}, }
], : null,
].filter((line) => line !== null),
}, },
yAxis: { yAxis: {
title: { title: {
text: "Expected Profit/Loss ($)", text: "<span class='hidden sm:block'>Expected Profit/Loss ($)</span>",
style: { color: $mode === "light" ? "#545454" : "white" }, style: { color: $mode === "light" ? "#545454" : "white" },
}, },
gridLineWidth: 1, gridLineWidth: 1,
@ -318,24 +343,17 @@
tooltip: { tooltip: {
shared: true, shared: true,
useHTML: true, useHTML: true,
backgroundColor: "rgba(0, 0, 0, 0.8)", // Semi-transparent black backgroundColor: "rgba(0, 0, 0, 0.8)",
borderColor: "rgba(255, 255, 255, 0.2)", // Slightly visible white border borderColor: "rgba(255, 255, 255, 0.2)",
borderWidth: 1, borderWidth: 1,
style: { style: { color: "#fff", fontSize: "16px", padding: "10px" },
color: "#fff",
fontSize: "16px",
padding: "10px",
},
borderRadius: 2, borderRadius: 2,
formatter: function () { formatter: function () {
const underlyingPrice = this.x; const underlyingPrice = this.x;
const profitLoss = this.y; const profitLoss = this.y;
// Calculate percentage change for underlying price relative to currentStockPrice
const underlyingPctChange = const underlyingPctChange =
((underlyingPrice - currentStockPrice) / currentStockPrice) * 100; ((underlyingPrice - currentStockPrice) / currentStockPrice) * 100;
// Calculate profit/loss percentage relative to the total premium paid const profitLossPctChange = (profitLoss / totalPremium) * 100;
const profitLossPctChange = (profitLoss / premium) * 100;
return ` return `
<div class="flex flex-col items-start text-sm"> <div class="flex flex-col items-start text-sm">
<div> <div>
@ -352,33 +370,28 @@
`; `;
}, },
}, },
plotOptions: { plotOptions: {
area: { area: {
fillOpacity: 0.2, fillOpacity: 0.2,
marker: { marker: { enabled: false },
enabled: false,
},
animation: false, animation: false,
}, },
series: { series: {
zoneAxis: "y", zoneAxis: "y",
zones: [ zones: [
{ {
value: 0, // below $0 -> red value: 0,
color: "#E02424", color: "#E02424",
fillColor: "rgba(224,36,36,0.5)", fillColor: "rgba(224,36,36,0.5)",
}, },
{ {
color: "#10B981", // above $0 -> green color: "#10B981",
fillColor: "rgba(16,185,129,0.5)", fillColor: "rgba(16,185,129,0.5)",
}, },
], ],
}, },
}, },
legend: { legend: { enabled: false },
enabled: false,
},
series: [ series: [
{ {
name: "Payoff", name: "Payoff",
@ -432,8 +445,6 @@
} else { } else {
selectedAction = "Buy"; selectedAction = "Buy";
} }
config = plotData();
shouldUpdate = true; shouldUpdate = true;
} }
@ -449,7 +460,6 @@
// Set a new debounce timeout (1 second) // Set a new debounce timeout (1 second)
debounceTimeout = setTimeout(() => { debounceTimeout = setTimeout(() => {
config = plotData(); config = plotData();
shouldUpdate = true;
}, 500); }, 500);
} }
@ -466,7 +476,6 @@
// Set a new debounce timeout (1 second) // Set a new debounce timeout (1 second)
debounceTimeout = setTimeout(() => { debounceTimeout = setTimeout(() => {
config = plotData(); config = plotData();
shouldUpdate = true;
}, 500); }, 500);
} }
@ -519,10 +528,7 @@
const output = await getContractHistory(optionSymbol); const output = await getContractHistory(optionSymbol);
selectedOptionPrice = output?.history?.at(-1)?.mark; selectedOptionPrice = output?.history?.at(-1)?.mark;
config = plotData();
shouldUpdate = true; shouldUpdate = true;
isLoaded = true;
} }
async function getStockData() { async function getStockData() {
@ -557,10 +563,12 @@
await getStockData(); await getStockData();
await loadData("default"); await loadData("default");
inputValue = "";
} }
onMount(async () => { onMount(async () => {
await getStockData(); await getStockData();
await loadData("default"); await loadData("default");
shouldUpdate = true;
}); });
onDestroy(() => { onDestroy(() => {
@ -570,19 +578,10 @@
$: { $: {
if (shouldUpdate) { if (shouldUpdate) {
shouldUpdate = false; shouldUpdate = false;
userStrategy = [
{
ticker: selectedTicker,
action: selectedAction,
quantity: selectedQuantity,
date: selectedDate,
strike: selectedStrike,
optionType: selectedOptionType,
optionPrice: selectedOptionPrice,
},
];
console.log("yes"); config = plotData();
isLoaded = true;
} }
} }
@ -656,6 +655,51 @@
<div class="mt-4"> <div class="mt-4">
{#if isLoaded && config} {#if isLoaded && config}
<Combobox.Root
items={searchBarData}
bind:inputValue
bind:touchedInput
>
<div class="relative w-full">
<Combobox.Input
on:input={search}
class="mb-3 text-sm controls-input bg-white dark:bg-default focus:outline-hidden border border-gray-300 dark:border-gray-500 rounded placeholder:text-gray-600 dark:placeholder:text-gray-200 px-2 py-1.5 grow w-full max-w-48"
placeholder="Search Ticker"
aria-label="Search Ticker"
/>
</div>
{#if inputValue?.length !== 0 && inputValue !== selectedTicker}
<Combobox.Content
class=" z-10 rounded border border-gray-300 dark:border-gray-700 bg-white dark:bg-default px-1 py-3 shadow-sm outline-hidden"
sideOffset={8}
>
{#each searchBarData as searchItem}
<Combobox.Item
class="cursor-pointer border-b border-gray-300 dark:border-gray-500 last:border-none flex h-fit w-auto select-none items-center rounded-button py-1 px-2 text-sm capitalize outline-hidden transition-all duration-75 data-highlighted:bg-gray-200 dark:data-highlighted:bg-primary"
value={searchItem?.symbol}
label={searchItem?.symbol}
on:click={(e) => changeTicker(searchItem)}
>
<div class="flex flex-col items-start">
<span
class="text-sm text-blue-700 dark:text-blue-400"
>{searchItem?.symbol}</span
>
<span
class="text-xs sm:text-sm text-muted dark:text-white"
>{searchItem?.name}</span
>
</div>
</Combobox.Item>
{:else}
<span class="block px-5 py-2 text-sm">
No results found
</span>
{/each}
</Combobox.Content>
{/if}
</Combobox.Root>
<!-- Table container --> <!-- Table container -->
<div <div
class="overflow-x-auto border border-gray-300 dark:border-gray-600 rounded" class="overflow-x-auto border border-gray-300 dark:border-gray-600 rounded"
@ -722,50 +766,7 @@
{#each userStrategy as item} {#each userStrategy as item}
<tr> <tr>
<td class="px-4 py-3 whitespace-nowrap font-semibold"> <td class="px-4 py-3 whitespace-nowrap font-semibold">
<Combobox.Root {selectedTicker}
items={searchBarData}
bind:inputValue
bind:touchedInput
>
<div class="relative w-full">
<Combobox.Input
on:input={search}
class="text-sm controls-input bg-white dark:bg-[#2A2E39] focus:outline-hidden border border-gray-300 dark:border-gray-500 rounded placeholder:text-gray-600 dark:placeholder:text-gray-200 px-2 py-1.5 grow w-full min-w-54"
placeholder="Search Ticker"
aria-label="Search Ticker"
/>
</div>
{#if inputValue?.length !== 0 && inputValue !== item?.ticker}
<Combobox.Content
class=" z-10 rounded border border-gray-300 dark:border-gray-700 bg-white dark:bg-default px-1 py-3 shadow-sm outline-hidden"
sideOffset={8}
>
{#each searchBarData as searchItem}
<Combobox.Item
class="cursor-pointer border-b border-gray-300 dark:border-gray-500 last:border-none flex h-fit w-auto select-none items-center rounded-button py-3 pl-5 pr-1.5 text-sm capitalize outline-hidden transition-all duration-75 data-highlighted:bg-gray-200 dark:data-highlighted:bg-primary"
value={searchItem?.symbol}
label={searchItem?.symbol}
on:click={(e) => changeTicker(searchItem)}
>
<div class="flex flex-col items-start">
<span
class="text-sm text-blue-700 dark:text-blue-400"
>{searchItem?.symbol}</span
>
<span
class="text-xs sm:text-sm text-muted dark:text-white"
>{searchItem?.name}</span
>
</div>
</Combobox.Item>
{:else}
<span class="block px-5 py-2 text-sm">
No results found
</span>
{/each}
</Combobox.Content>
{/if}
</Combobox.Root>
</td> </td>
<td class="px-4 py-3 whitespace-nowrap"> <td class="px-4 py-3 whitespace-nowrap">
<label <label
@ -930,14 +931,24 @@
<div <div
class="border border-gray-300 dark:border-gray-800 rounded-lg p-4 mb-6 shadow-sm max-w-sm" class="border border-gray-300 dark:border-gray-800 rounded-lg p-4 mb-6 shadow-sm max-w-sm"
> >
<div>{selectedStrategy}</div> {#each userStrategy as item}
<div class="text-green-800 dark:text-white font-semibold"> <div>
{selectedAction?.toUpperCase()} +{selectedQuantity} {userStrategy?.length > 2
{selectedTicker} ? "Custom Strategy"
{formatDate(selectedDate)} : selectedStrategy}
{selectedStrike}
{selectedOptionType} @${selectedOptionPrice}
</div> </div>
<div
class="{item?.action === 'Buy'
? 'text-green-800'
: 'text-red-800'} dark:text-white font-semibold"
>
{item?.action?.toUpperCase()} +{item?.quantity}
{selectedTicker}
{formatDate(item?.date)}
{item?.strike}
{item?.optionType} @${item?.optionPrice}
</div>
{/each}
</div> </div>
<!-- Stock Section --> <!-- Stock Section -->
@ -999,7 +1010,7 @@
</div> </div>
<div class="flex items-baseline"> <div class="flex items-baseline">
<span class="text-lg font-semibold" <span class="text-lg font-semibold"
>${premium?.toLocaleString("en-US", { >${totalPremium?.toLocaleString("en-US", {
minimumFractionDigits: 2, minimumFractionDigits: 2,
maximumFractionDigits: 2, maximumFractionDigits: 2,
})} })}
@ -1043,398 +1054,6 @@
</div> </div>
</div> </div>
</div> </div>
<!--
<h2 class="text-xl font-bold text-gray-800 dark:text-white mb-4">
Probability Analysis
</h2>
<div class="grid grid-cols-2 md:grid-cols-4 mb-6">
<div>
<div class="flex items-center text-gray-600 dark:text-white">
Probability of Profit (PoP)
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 ml-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</div>
<div class="text-xl text-start">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
/>
</svg>
</div>
</div>
<div>
<div class="flex items-center text-gray-600 dark:text-white">
Probability of Max Profit
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 ml-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</div>
<div class="text-xl text-center">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 mx-auto"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
/>
</svg>
</div>
</div>
<div>
<div class="flex items-center text-gray-600 dark:text-white">
Probability of Max Loss
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 ml-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</div>
<div class="text-xl text-center">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 mx-auto"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
/>
</svg>
</div>
</div>
</div>
<h2 class="text-xl font-bold text-gray-800 dark:text-white mb-4">
Risk Reward Analysis
</h2>
<div class="grid grid-cols-2 md:grid-cols-3 gap-6 mb-6">
<div>
<div class="flex items-center text-gray-600 dark:text-white">
Expected Value (EV)
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 ml-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</div>
<div class="text-xl text-center">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 mx-auto"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
/>
</svg>
</div>
</div>
<div>
<div class="flex items-center text-gray-600 dark:text-white">
Expected Return (EV/risk)
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 ml-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</div>
<div class="text-xl text-center">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 mx-auto"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
/>
</svg>
</div>
</div>
<div>
<div class="flex items-center text-gray-600 dark:text-white">
Reward/Risk
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 ml-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</div>
<div class="text-xl text-center">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 mx-auto"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
/>
</svg>
</div>
</div>
</div>
<h2
class="text-xl font-bold text-gray-800 dark:text-white mb-4 flex items-center"
>
Position Greeks
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 ml-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</h2>
<div class="grid grid-cols-2 md:grid-cols-4 gap-6 mb-6">
<div>
<div class="flex items-center text-gray-600 dark:text-white">
Delta (Δ)
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 ml-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</div>
<div class="text-xl text-center">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 mx-auto"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
/>
</svg>
</div>
</div>
<div>
<div class="flex items-center text-gray-600 dark:text-white">
Gamma (Γ)
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 ml-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</div>
<div class="text-xl text-center">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 mx-auto"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
/>
</svg>
</div>
</div>
<div>
<div class="flex items-center text-gray-600 dark:text-white">
Theta (Θ)
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 ml-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</div>
<div class="text-xl text-center">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 mx-auto"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
/>
</svg>
</div>
</div>
<div>
<div class="flex items-center text-gray-600 dark:text-white">
Vega (v)
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5 ml-1"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</div>
<div class="text-xl text-center">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 mx-auto"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
/>
</svg>
</div>
</div>
</div>
-->
</div> </div>
{:else} {:else}
<div class="flex justify-center items-center h-80"> <div class="flex justify-center items-center h-80">