upgrade daisyui && update calculator
This commit is contained in:
parent
97d3b168bb
commit
441902dca7
8
package-lock.json
generated
8
package-lock.json
generated
@ -34,7 +34,7 @@
|
|||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"cmdk-sv": "^0.0.18",
|
"cmdk-sv": "^0.0.18",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
"daisyui": "^5.0.12",
|
"daisyui": "^5.0.16",
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"date-fns-tz": "^3.1.3",
|
"date-fns-tz": "^3.1.3",
|
||||||
"date-picker-svelte": "^2.12.0",
|
"date-picker-svelte": "^2.12.0",
|
||||||
@ -4043,9 +4043,9 @@
|
|||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
"node_modules/daisyui": {
|
"node_modules/daisyui": {
|
||||||
"version": "5.0.12",
|
"version": "5.0.16",
|
||||||
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.0.12.tgz",
|
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.0.16.tgz",
|
||||||
"integrity": "sha512-01DU0eYBcHgPtuf5fxcrkGkIN6/Uyaqmkle5Yo3ZyW9YVAu036ALZbjv2KH5euvUbeQ4r9q3gAarGcf7Tywhng==",
|
"integrity": "sha512-MQiZQ21+r91zrKv3fxDOF56dzkfrr2FyXOaR/1T4f9AIeI/ilkc0i+UqOIE/VqjIfkWyq+wBPmBcyIf6iPJpYQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"cmdk-sv": "^0.0.18",
|
"cmdk-sv": "^0.0.18",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
"daisyui": "^5.0.12",
|
"daisyui": "^5.0.16",
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"date-fns-tz": "^3.1.3",
|
"date-fns-tz": "^3.1.3",
|
||||||
"date-picker-svelte": "^2.12.0",
|
"date-picker-svelte": "^2.12.0",
|
||||||
|
|||||||
@ -14,27 +14,6 @@
|
|||||||
import { mode } from "mode-watcher";
|
import { mode } from "mode-watcher";
|
||||||
import highcharts from "$lib/highcharts.ts";
|
import highcharts from "$lib/highcharts.ts";
|
||||||
|
|
||||||
// Types
|
|
||||||
type Strategy = {
|
|
||||||
name: string;
|
|
||||||
sentiment: string;
|
|
||||||
description: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type OptionLeg = {
|
|
||||||
action: string;
|
|
||||||
quantity: number;
|
|
||||||
date: string;
|
|
||||||
strike: number;
|
|
||||||
optionType: string;
|
|
||||||
optionPrice: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SearchResult = {
|
|
||||||
symbol: string;
|
|
||||||
type: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
// State variables with proper types
|
// State variables with proper types
|
||||||
@ -68,13 +47,13 @@
|
|||||||
let rawData: Record<string, any> = {};
|
let rawData: Record<string, any> = {};
|
||||||
|
|
||||||
// Search variables
|
// Search variables
|
||||||
let searchBarData: SearchResult[] = [];
|
let searchBarData = [];
|
||||||
let timeoutId: ReturnType<typeof setTimeout>;
|
let timeoutId: ReturnType<typeof setTimeout>;
|
||||||
let inputValue = "";
|
let inputValue = "";
|
||||||
let touchedInput = false;
|
let touchedInput = false;
|
||||||
|
|
||||||
// Strategy definitions
|
// Strategy definitions
|
||||||
const prebuiltStrategy: Strategy[] = [
|
const prebuiltStrategy = [
|
||||||
{
|
{
|
||||||
name: "Long Call",
|
name: "Long Call",
|
||||||
sentiment: "Bullish",
|
sentiment: "Bullish",
|
||||||
@ -99,6 +78,18 @@
|
|||||||
description:
|
description:
|
||||||
"In this strategy, an investor sells a put option, expecting that the price of the underlying asset will remain stable or increase, allowing the investor to keep the premium received from selling the option. Investors typically use a short put strategy when they have a neutral to bullish outlook on the stock and and views a potential assignment as an opportunity to buy the asset at a desirable price.",
|
"In this strategy, an investor sells a put option, expecting that the price of the underlying asset will remain stable or increase, allowing the investor to keep the premium received from selling the option. Investors typically use a short put strategy when they have a neutral to bullish outlook on the stock and and views a potential assignment as an opportunity to buy the asset at a desirable price.",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Cash Secured Put",
|
||||||
|
sentiment: "Bullish",
|
||||||
|
description:
|
||||||
|
"In this strategy, an investor sells a put option and simultaneously sets aside enough cash to buy the stock. The goal is to be assigned the stock at a desirable price and generate income from the option premium. Investors typically use a cash secured put strategy when they have a neutral to bullish outlook on the stock and view a potential assignment as an opportunity to buy the asset at a desirable price.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bull Call Spread",
|
||||||
|
sentiment: "Bullish",
|
||||||
|
description:
|
||||||
|
"In this strategy, an investor simultaneously purchases call options at a specific strike price and sells the same number of calls at a higher strike price. Both call options have the same expiration date. This strategy is used when the investor is bullish and expects a moderate rise in the price of the underlying asset. The investor limits their upside profit potential but reduces the net premium spent compared to buying a single call option outright. The strategy is also known as a 'debit call spread' because the investor pays a net debit to establish the position.",
|
||||||
|
},
|
||||||
// Other strategies commented out in original code
|
// Other strategies commented out in original code
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -107,7 +98,7 @@
|
|||||||
|
|
||||||
// STRATEGY FUNCTIONS
|
// STRATEGY FUNCTIONS
|
||||||
|
|
||||||
async function changeStrategy(strategy: Strategy) {
|
async function changeStrategy(strategy) {
|
||||||
selectedStrategy = strategy?.name;
|
selectedStrategy = strategy?.name;
|
||||||
description = strategy?.description;
|
description = strategy?.description;
|
||||||
|
|
||||||
@ -129,21 +120,47 @@
|
|||||||
selectedOptionType = "Put";
|
selectedOptionType = "Put";
|
||||||
selectedAction = "Sell";
|
selectedAction = "Sell";
|
||||||
break;
|
break;
|
||||||
|
case "Cash Secured Put":
|
||||||
|
selectedOptionType = "Put";
|
||||||
|
selectedAction = "Sell";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
console.warn("Unknown strategy:", strategy);
|
console.warn("Unknown strategy:", strategy);
|
||||||
selectedOptionType = null;
|
selectedOptionType = null;
|
||||||
selectedAction = null;
|
selectedAction = null;
|
||||||
}
|
}
|
||||||
userStrategy = [
|
if (["Bull Call Spread"]?.includes(selectedStrategy)) {
|
||||||
{
|
userStrategy = [
|
||||||
strike: selectedStrike,
|
{
|
||||||
optionType: selectedOptionType,
|
strike: selectedStrike,
|
||||||
date: selectedDate,
|
optionType: "Call",
|
||||||
optionPrice: selectedOptionPrice,
|
date: selectedDate,
|
||||||
quantity: selectedQuantity,
|
optionPrice: selectedOptionPrice,
|
||||||
action: selectedAction,
|
quantity: 1,
|
||||||
},
|
action: "Buy",
|
||||||
];
|
},
|
||||||
|
{
|
||||||
|
strike: selectedStrike,
|
||||||
|
optionType: "Call",
|
||||||
|
date: selectedDate,
|
||||||
|
optionPrice: selectedOptionPrice,
|
||||||
|
quantity: 1,
|
||||||
|
action: "Sell",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
userStrategy = [
|
||||||
|
{
|
||||||
|
strike: selectedStrike,
|
||||||
|
optionType: selectedOptionType,
|
||||||
|
date: selectedDate,
|
||||||
|
optionPrice: selectedOptionPrice,
|
||||||
|
quantity: selectedQuantity,
|
||||||
|
action: selectedAction,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
shouldUpdate = true;
|
shouldUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,7 +517,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
async function loadData(state: string) {
|
async function loadData() {
|
||||||
if (!rawData?.getData) {
|
if (!rawData?.getData) {
|
||||||
console.error("rawData is undefined or invalid in loadData");
|
console.error("rawData is undefined or invalid in loadData");
|
||||||
return;
|
return;
|
||||||
@ -525,17 +542,16 @@
|
|||||||
item.strikeList = strikeList;
|
item.strikeList = strikeList;
|
||||||
|
|
||||||
// Find closest strike to current stock price
|
// Find closest strike to current stock price
|
||||||
if (!strikeList.includes(selectedStrike) && strikeList.length > 0) {
|
if (!strikeList?.includes(item?.strike) && strikeList?.length > 0) {
|
||||||
selectedStrike = strikeList.reduce((closest, strike) => {
|
selectedStrike = strikeList.reduce((closest, strike) => {
|
||||||
return Math.abs(strike - currentStockPrice) <
|
return Math.abs(strike - currentStockPrice) <
|
||||||
Math.abs(closest - currentStockPrice)
|
Math.abs(closest - currentStockPrice)
|
||||||
? strike
|
? strike
|
||||||
: closest;
|
: closest;
|
||||||
}, strikeList[0]);
|
}, strikeList[0]);
|
||||||
|
item.strike = selectedStrike;
|
||||||
}
|
}
|
||||||
|
|
||||||
item.strike = selectedStrike;
|
|
||||||
|
|
||||||
// Get option price
|
// Get option price
|
||||||
optionSymbol = buildOptionSymbol(
|
optionSymbol = buildOptionSymbol(
|
||||||
selectedTicker,
|
selectedTicker,
|
||||||
@ -547,6 +563,8 @@
|
|||||||
const output = await getContractHistory(optionSymbol);
|
const output = await getContractHistory(optionSymbol);
|
||||||
selectedOptionPrice = output?.history?.at(-1)?.mark || 0;
|
selectedOptionPrice = output?.history?.at(-1)?.mark || 0;
|
||||||
item.optionPrice = selectedOptionPrice;
|
item.optionPrice = selectedOptionPrice;
|
||||||
|
item.optionSymbol = optionSymbol;
|
||||||
|
item.optionType = selectedOptionType;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
optionData = rawData?.getData[selectedOptionType] || {};
|
optionData = rawData?.getData[selectedOptionType] || {};
|
||||||
@ -581,22 +599,20 @@
|
|||||||
selectedOptionPrice = output?.history?.at(-1)?.mark || 0;
|
selectedOptionPrice = output?.history?.at(-1)?.mark || 0;
|
||||||
|
|
||||||
// Update user strategy if necessary
|
// Update user strategy if necessary
|
||||||
if (state === "default") {
|
userStrategy = [
|
||||||
userStrategy = [
|
{
|
||||||
{
|
date: selectedDate,
|
||||||
date: selectedDate,
|
strike: selectedStrike,
|
||||||
strike: selectedStrike,
|
optionType: selectedOptionType,
|
||||||
optionType: selectedOptionType,
|
optionPrice: selectedOptionPrice,
|
||||||
optionPrice: selectedOptionPrice,
|
action: selectedAction,
|
||||||
action: selectedAction,
|
quantity: selectedQuantity,
|
||||||
quantity: selectedQuantity,
|
strikeList: strikeList,
|
||||||
strikeList: strikeList,
|
dateList: dateList,
|
||||||
dateList: dateList,
|
optionSymbol: optionSymbol,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldUpdate = true;
|
shouldUpdate = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error loading data:", error);
|
console.error("Error loading data:", error);
|
||||||
@ -644,6 +660,7 @@
|
|||||||
const newLeg = { ...lastLeg }; // Create a shallow copy
|
const newLeg = { ...lastLeg }; // Create a shallow copy
|
||||||
userStrategy = [...userStrategy, newLeg];
|
userStrategy = [...userStrategy, newLeg];
|
||||||
}
|
}
|
||||||
|
await loadData();
|
||||||
shouldUpdate = true;
|
shouldUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,6 +692,7 @@
|
|||||||
// Update the selectedAction (for new legs)
|
// Update the selectedAction (for new legs)
|
||||||
selectedOptionType = selectedOptionType === "Call" ? "Put" : "Call";
|
selectedOptionType = selectedOptionType === "Call" ? "Put" : "Call";
|
||||||
}
|
}
|
||||||
|
await loadData();
|
||||||
shouldUpdate = true;
|
shouldUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,7 +717,7 @@
|
|||||||
const updatedStrategy = [...userStrategy];
|
const updatedStrategy = [...userStrategy];
|
||||||
updatedStrategy[index].date = selectedDate;
|
updatedStrategy[index].date = selectedDate;
|
||||||
userStrategy = updatedStrategy;
|
userStrategy = updatedStrategy;
|
||||||
await loadData("default");
|
await loadData();
|
||||||
shouldUpdate = true;
|
shouldUpdate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -710,11 +728,12 @@
|
|||||||
const updatedStrategy = [...userStrategy];
|
const updatedStrategy = [...userStrategy];
|
||||||
updatedStrategy[index].strike = selectedStrike;
|
updatedStrategy[index].strike = selectedStrike;
|
||||||
userStrategy = updatedStrategy;
|
userStrategy = updatedStrategy;
|
||||||
|
await loadData();
|
||||||
shouldUpdate = true;
|
shouldUpdate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleOptionPriceInput(event: Event, index) {
|
async function handleOptionPriceInput(event: Event, index) {
|
||||||
const value = (event.target as HTMLInputElement).value;
|
const value = (event.target as HTMLInputElement).value;
|
||||||
|
|
||||||
selectedOptionPrice = value === "" ? null : +value;
|
selectedOptionPrice = value === "" ? null : +value;
|
||||||
@ -726,12 +745,12 @@
|
|||||||
if (debounceTimeout) clearTimeout(debounceTimeout);
|
if (debounceTimeout) clearTimeout(debounceTimeout);
|
||||||
|
|
||||||
// Set a new debounce timeout
|
// Set a new debounce timeout
|
||||||
debounceTimeout = setTimeout(() => {
|
debounceTimeout = setTimeout(async () => {
|
||||||
shouldUpdate = true;
|
shouldUpdate = true;
|
||||||
}, 300);
|
}, 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleQuantityInput(event, index) {
|
async function handleQuantityInput(event, index) {
|
||||||
if (index !== undefined && userStrategy[index]) {
|
if (index !== undefined && userStrategy[index]) {
|
||||||
const value = (event.target as HTMLInputElement).value;
|
const value = (event.target as HTMLInputElement).value;
|
||||||
|
|
||||||
@ -742,7 +761,7 @@
|
|||||||
if (debounceTimeout) clearTimeout(debounceTimeout);
|
if (debounceTimeout) clearTimeout(debounceTimeout);
|
||||||
|
|
||||||
// Set a new debounce timeout
|
// Set a new debounce timeout
|
||||||
debounceTimeout = setTimeout(() => {
|
debounceTimeout = setTimeout(async () => {
|
||||||
shouldUpdate = true;
|
shouldUpdate = true;
|
||||||
}, 300);
|
}, 300);
|
||||||
}
|
}
|
||||||
@ -775,14 +794,14 @@
|
|||||||
}, 50); // delay
|
}, 50); // delay
|
||||||
}
|
}
|
||||||
|
|
||||||
async function changeTicker(data: SearchResult) {
|
async function changeTicker(data) {
|
||||||
if (!data?.symbol) return;
|
if (!data?.symbol) return;
|
||||||
|
|
||||||
selectedTicker = data.symbol;
|
selectedTicker = data.symbol;
|
||||||
assetType = data?.type?.toLowerCase() || "stocks";
|
assetType = data?.type?.toLowerCase() || "stocks";
|
||||||
|
|
||||||
await getStockData();
|
await getStockData();
|
||||||
await loadData("default");
|
await loadData();
|
||||||
inputValue = "";
|
inputValue = "";
|
||||||
shouldUpdate = true;
|
shouldUpdate = true;
|
||||||
}
|
}
|
||||||
@ -791,7 +810,7 @@
|
|||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
await getStockData();
|
await getStockData();
|
||||||
await loadData("default");
|
await loadData();
|
||||||
|
|
||||||
shouldUpdate = true;
|
shouldUpdate = true;
|
||||||
});
|
});
|
||||||
@ -881,6 +900,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="border-b border-gray-400 mt-5"></div>
|
<div class="border-b border-gray-400 mt-5"></div>
|
||||||
<h2 class="mt-5 mb-1 text-xl sm:text-2xl font-bold">
|
<h2 class="mt-5 mb-1 text-xl sm:text-2xl font-bold">
|
||||||
{selectedStrategy}
|
{selectedStrategy}
|
||||||
@ -945,7 +965,7 @@
|
|||||||
>
|
>
|
||||||
<!-- Table head -->
|
<!-- Table head -->
|
||||||
<thead class="bg-gray-50 dark:bg-secondary">
|
<thead class="bg-gray-50 dark:bg-secondary">
|
||||||
<tr>
|
<tr class="">
|
||||||
<th
|
<th
|
||||||
scope="col"
|
scope="col"
|
||||||
class="px-4 py-1.5 text-left text-sm font-semibold"
|
class="px-4 py-1.5 text-left text-sm font-semibold"
|
||||||
@ -997,14 +1017,14 @@
|
|||||||
|
|
||||||
<!-- Table body -->
|
<!-- Table body -->
|
||||||
<tbody
|
<tbody
|
||||||
class="bg-[#F8F9FA] dark:bg-secondary divide-y divide-gray-200 dark:divide-gray-800 text-sm"
|
class="bg-[#F8F9FA] dark:bg-secondary divide-y divide-gray-200 dark:divide-gray-600 text-sm"
|
||||||
>
|
>
|
||||||
{#each userStrategy as item, index}
|
{#each userStrategy as item, index}
|
||||||
<tr>
|
<tr class="">
|
||||||
<td class="px-4 whitespace-nowrap font-semibold">
|
<td class="px-4 whitespace-nowrap font-semibold">
|
||||||
{selectedTicker}
|
{selectedTicker}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 whitespace-nowrap">
|
<td class="px-4 whitespace-nowrap py-2">
|
||||||
<label
|
<label
|
||||||
on:click={() => handleAction(index)}
|
on:click={() => handleAction(index)}
|
||||||
class="badge px-2 select-none rounded-md {item?.action ===
|
class="badge px-2 select-none rounded-md {item?.action ===
|
||||||
@ -1014,7 +1034,7 @@
|
|||||||
>{item?.action}</label
|
>{item?.action}</label
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 whitespace-nowrap">
|
<td class="px-4 whitespace-nowrap py-2">
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
value={userStrategy[index]?.quantity}
|
value={userStrategy[index]?.quantity}
|
||||||
@ -1023,7 +1043,7 @@
|
|||||||
class="border border-gray-300 dark:border-gray-500 rounded px-2 py-1 w-20 focus:outline-none focus:ring-1 focus:ring-blue-500"
|
class="border border-gray-300 dark:border-gray-500 rounded px-2 py-1 w-20 focus:outline-none focus:ring-1 focus:ring-blue-500"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 whitespace-nowrap">
|
<td class="px-4 whitespace-nowrap py-2">
|
||||||
<DropdownMenu.Root>
|
<DropdownMenu.Root>
|
||||||
<DropdownMenu.Trigger asChild let:builder>
|
<DropdownMenu.Trigger asChild let:builder>
|
||||||
<Button
|
<Button
|
||||||
@ -1070,7 +1090,7 @@
|
|||||||
</DropdownMenu.Content>
|
</DropdownMenu.Content>
|
||||||
</DropdownMenu.Root>
|
</DropdownMenu.Root>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 whitespace-nowrap">
|
<td class="px-4 whitespace-nowrap py-2">
|
||||||
<DropdownMenu.Root>
|
<DropdownMenu.Root>
|
||||||
<DropdownMenu.Trigger asChild let:builder>
|
<DropdownMenu.Trigger asChild let:builder>
|
||||||
<Button
|
<Button
|
||||||
@ -1116,14 +1136,14 @@
|
|||||||
</DropdownMenu.Content>
|
</DropdownMenu.Content>
|
||||||
</DropdownMenu.Root>
|
</DropdownMenu.Root>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 whitespace-nowrap">
|
<td class="px-4 whitespace-nowrap py-2">
|
||||||
<label
|
<label
|
||||||
on:click={() => handleOptionType(index)}
|
on:click={() => handleOptionType(index)}
|
||||||
class="select-none badge px-2 rounded-md bg-blue-100 text-blue-800 dark:bg-blue-300 dark:text-muted font-semibold cursor-pointer"
|
class="select-none badge px-2 rounded-md bg-blue-100 text-blue-800 dark:bg-blue-300 dark:text-muted font-semibold cursor-pointer"
|
||||||
>{item?.optionType}</label
|
>{item?.optionType}</label
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 whitespace-nowrap">
|
<td class="px-4 whitespace-nowrap py-2">
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
step="0.1"
|
step="0.1"
|
||||||
@ -1133,13 +1153,13 @@
|
|||||||
class="border border-gray-300 dark:border-gray-500 rounded px-2 py-1 w-24 focus:outline-none focus:ring-1 focus:ring-blue-500"
|
class="border border-gray-300 dark:border-gray-500 rounded px-2 py-1 w-24 focus:outline-none focus:ring-1 focus:ring-blue-500"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 whitespace-nowrap">
|
<td class="px-4 whitespace-nowrap py-2">
|
||||||
<div
|
<div
|
||||||
class="flex flex-row items-center m-auto text-center justify-center"
|
class="flex flex-row items-center m-auto text-center justify-center"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
class="inline-block"
|
class="inline-block"
|
||||||
href={`/${["stocks", "stock"]?.includes(assetType) ? "stocks" : assetType === "etf" ? "etf" : "index"}/${selectedTicker}/options/contract-lookup?query=${optionSymbol}`}
|
href={`/${["stocks", "stock"]?.includes(assetType) ? "stocks" : assetType === "etf" ? "etf" : "index"}/${selectedTicker}/options/contract-lookup?query=${userStrategy[index]?.optionSymbol}`}
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
class="w-4 h-4 text-gray-800 dark:text-gray-100 mt-0.5"
|
class="w-4 h-4 text-gray-800 dark:text-gray-100 mt-0.5"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user