diff --git a/frontend/src/pages/HistoricalCalendarPrices.tsx b/frontend/src/pages/HistoricalCalendarPrices.tsx index 9fa5b33..d30ae36 100644 --- a/frontend/src/pages/HistoricalCalendarPrices.tsx +++ b/frontend/src/pages/HistoricalCalendarPrices.tsx @@ -16,6 +16,7 @@ import { Paper, Popper, ClickAwayListener, + Stack, } from "@mui/material"; import { availableUnderlyings, @@ -38,9 +39,9 @@ import { refreshStockPriceChartData, } from "./HistoricalCalendarPrices/actions.js"; import { EditableUnderlying } from "./HistoricalCalendarPrices/EditableUnderlying.js"; -import { EditableDaysToFrontExpiration } from "./HistoricalCalendarPrices/EditableDaysToFrontExpiration.js"; -import { EditableExitToFrontExpiration } from "./HistoricalCalendarPrices/EditableExitToFrontExpiration.js"; -import { EditableDaysBetweenFrontAndBackExpiration } from "./HistoricalCalendarPrices/EditableDaysBetweenFrontAndBackExpiration.js"; +import { EditableOpenDTE } from "./HistoricalCalendarPrices/EditableOpenDTE.js"; +import { EditableExitDTE } from "./HistoricalCalendarPrices/EditableExitDTE.js"; +import { EditableSpan } from "./HistoricalCalendarPrices/EditableSpan.js"; import { EditableLookbackPeriodStart } from "./HistoricalCalendarPrices/EditableLookbackPeriodStart.js"; import { EditableLookbackPeriodEnd } from "./HistoricalCalendarPrices/EditableLookbackPeriodEnd.js"; @@ -64,16 +65,16 @@ export function HistoricalCalendarPrices() { return ( - + {/* + : - + -Day Calendar @ %-from-the-money - Opening at DTE, Closing at{" "} - + Opening at DTE, Closing at DTE @@ -93,17 +94,65 @@ export function HistoricalCalendarPrices() { - + */} + - + + + Underlying + + + + + + Open DTE + + + + + + Exit DTE + + + + + + Span + + + + + + Lookback Period + + - + + + { + isPopperOpen.value = false; + // refreshSimilarCalendarPriceChartData(); + console.log("clicked away"); + }} + > + + + {popperContent.value} + + + + + + + {underlying.value !== null && - stockPriceChartData.value.length > 0 ? ( + similarCalendarPriceChartData.value.length > 0 ? ( `$${value.toString()}`, }, - }, - }, - elements: { - point: { - radius: 1, - borderWidth: 0, + min: 0, + max: maxChartPrice.value, }, }, plugins: { @@ -146,7 +191,7 @@ export function HistoricalCalendarPrices() { }, title: { display: true, - text: "Stock Price", + text: "Calendar Price (Under Like Conditions)", }, }, animation: false, @@ -167,26 +212,24 @@ export function HistoricalCalendarPrices() { data={{ datasets: [ { - label: "Calendar Open Price", - data: similarCalendarPriceChartData.value, + label: "Calendar Exit Price", + data: calendarExitPriceChartData.value, }, ], }} options={{ scales: { x: { + type: "linear", + beginAtZero: false, title: { display: true, - text: "Time", + text: "%-From-the-Money", }, ticks: { callback: (value, index, ticks) => - new Date((value as number) * 1000) - .toISOString() - .substring(0, 10), + `${value.toString()}%`, }, - min: new Date(lookbackPeriodStart.value).getTime() / 1000, - max: new Date(lookbackPeriodEnd.value).getTime() / 1000, }, y: { beginAtZero: true, @@ -198,6 +241,18 @@ export function HistoricalCalendarPrices() { max: maxChartPrice.value, }, }, + elements: { + point: { + borderWidth: 0, + backgroundColor: (context) => { + const n = ( + context.raw as { x: number; y: number; n: number } + ).n; + const alpha = n / maxN.value; + return `rgba(0, 0, 0, ${alpha})`; + }, + }, + }, plugins: { tooltip: { enabled: false, @@ -207,7 +262,10 @@ export function HistoricalCalendarPrices() { }, title: { display: true, - text: "Calendar Price (Under Like Conditions)", + text: [ + "Calendar Prices at Exit", + "by %-age from-the-money", + ], }, }, animation: false, @@ -220,53 +278,47 @@ export function HistoricalCalendarPrices() { )} - - + + {underlying.value !== null && - similarCalendarPriceChartData.value.length > 0 ? ( + stockPriceChartData.value.length > 0 ? ( - `${value.toString()}%`, + new Date((value as number) * 1000) + .toISOString() + .substring(0, 10), }, + min: new Date(lookbackPeriodStart.value).getTime() / 1000, + max: new Date(lookbackPeriodEnd.value).getTime() / 1000, }, y: { - beginAtZero: true, + beginAtZero: false, ticks: { callback: (value, index, ticks) => `$${value.toString()}`, }, - min: 0, - max: maxChartPrice.value, }, }, elements: { point: { + radius: 1, borderWidth: 0, - backgroundColor: (context) => { - const n = ( - context.raw as { x: number; y: number; n: number } - ).n; - const alpha = n / maxN.value; - return `rgba(0, 0, 0, ${alpha})`; - }, }, }, plugins: { @@ -278,10 +330,7 @@ export function HistoricalCalendarPrices() { }, title: { display: true, - text: [ - "Calendar Prices at Exit", - "by %-age from-the-money", - ], + text: "Stock Price", }, }, animation: false, diff --git a/frontend/src/pages/HistoricalCalendarPrices/EditableDaysBetweenFrontAndBackExpiration.tsx b/frontend/src/pages/HistoricalCalendarPrices/EditableDaysBetweenFrontAndBackExpiration.tsx deleted file mode 100644 index 4c4db28..0000000 --- a/frontend/src/pages/HistoricalCalendarPrices/EditableDaysBetweenFrontAndBackExpiration.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import TextField from "@mui/material/TextField"; -import { - refreshcalendarExitPriceChartData, - refreshSimilarCalendarPriceChartData, -} from "./actions"; -import { daysBetweenFrontAndBackExpiration } from "./state"; -import { EditableValue } from "./EditableValue"; - -const handleDaysBetweenFrontAndBackExpirationChange = (e) => { - if ( - daysBetweenFrontAndBackExpiration.value !== Number.parseInt(e.target.value) - ) { - daysBetweenFrontAndBackExpiration.value = Number.parseInt(e.target.value); - refreshSimilarCalendarPriceChartData(); - refreshcalendarExitPriceChartData(); - } -}; - -function DaysBetweenFrontAndBackExpirationChooser() { - return ( - - ); -} - -export function EditableDaysBetweenFrontAndBackExpiration() { - return ( - - - - ); -} diff --git a/frontend/src/pages/HistoricalCalendarPrices/EditableDaysToFrontExpiration.tsx b/frontend/src/pages/HistoricalCalendarPrices/EditableDaysToFrontExpiration.tsx deleted file mode 100644 index 3ac60b7..0000000 --- a/frontend/src/pages/HistoricalCalendarPrices/EditableDaysToFrontExpiration.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import TextField from "@mui/material/TextField"; -import { refreshSimilarCalendarPriceChartData } from "./actions"; -import { EditableValue } from "./EditableValue"; -import { daysToFrontExpiration } from "./state"; - -const handleDaysToFrontExpirationChange = (e) => { - if (daysToFrontExpiration.value !== Number.parseInt(e.target.value)) { - daysToFrontExpiration.value = Number.parseInt(e.target.value); - refreshSimilarCalendarPriceChartData(); - } -}; - -function DaysToFrontExpirationChooser() { - return ( - - ); -} - -export function EditableDaysToFrontExpiration() { - return ( - - - - ); -} diff --git a/frontend/src/pages/HistoricalCalendarPrices/EditableExitDTE.tsx b/frontend/src/pages/HistoricalCalendarPrices/EditableExitDTE.tsx new file mode 100644 index 0000000..5dce089 --- /dev/null +++ b/frontend/src/pages/HistoricalCalendarPrices/EditableExitDTE.tsx @@ -0,0 +1,28 @@ +import TextField from "@mui/material/TextField"; +import { EditableValue } from "./EditableValue"; +import { exitDTE } from "./state"; +import { refreshcalendarExitPriceChartData } from "./actions"; +import Slider from "@mui/material/Slider"; + +const handleExitDTEChange = (e) => { + if (exitDTE.value !== Number.parseInt(e.target.value)) { + exitDTE.value = Number.parseInt(e.target.value); + refreshcalendarExitPriceChartData(); + } +}; + +export function EditableExitDTE() { + return ( + + // + // + // + ); +} diff --git a/frontend/src/pages/HistoricalCalendarPrices/EditableExitToFrontExpiration.tsx b/frontend/src/pages/HistoricalCalendarPrices/EditableExitToFrontExpiration.tsx deleted file mode 100644 index 28d64e0..0000000 --- a/frontend/src/pages/HistoricalCalendarPrices/EditableExitToFrontExpiration.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import TextField from "@mui/material/TextField"; -import { EditableValue } from "./EditableValue"; -import { exitToFrontExpiration } from "./state"; -import { refreshcalendarExitPriceChartData } from "./actions"; - -const handleExitToFrontExpirationChange = (e) => { - if (exitToFrontExpiration.value !== Number.parseInt(e.target.value)) { - exitToFrontExpiration.value = Number.parseInt(e.target.value); - refreshcalendarExitPriceChartData(); - } -}; - -function ExitToFrontExpirationChooser() { - return ( - - ); -} - -export function EditableExitToFrontExpiration() { - return ( - - - - ); -} diff --git a/frontend/src/pages/HistoricalCalendarPrices/EditableOpenDTE.tsx b/frontend/src/pages/HistoricalCalendarPrices/EditableOpenDTE.tsx new file mode 100644 index 0000000..eede1a1 --- /dev/null +++ b/frontend/src/pages/HistoricalCalendarPrices/EditableOpenDTE.tsx @@ -0,0 +1,26 @@ +import { refreshSimilarCalendarPriceChartData } from "./actions"; +import { openDTE } from "./state"; +import Slider from "@mui/material/Slider"; + +const handleOpenDTEChange = (e) => { + if (openDTE.value !== Number.parseInt(e.target.value)) { + openDTE.value = Number.parseInt(e.target.value); + refreshSimilarCalendarPriceChartData(); + } +}; + +export function EditableOpenDTE() { + return ( + + // + // + // + ); +} diff --git a/frontend/src/pages/HistoricalCalendarPrices/EditableSpan.tsx b/frontend/src/pages/HistoricalCalendarPrices/EditableSpan.tsx new file mode 100644 index 0000000..a51a434 --- /dev/null +++ b/frontend/src/pages/HistoricalCalendarPrices/EditableSpan.tsx @@ -0,0 +1,45 @@ +import TextField from "@mui/material/TextField"; +import { + refreshcalendarExitPriceChartData, + refreshSimilarCalendarPriceChartData, +} from "./actions"; +import { span } from "./state"; +import { EditableValue } from "./EditableValue"; +import Slider from "@mui/material/Slider"; + +const handleSpanChange = (e) => { + if (span.value !== Number.parseInt(e.target.value)) { + span.value = Number.parseInt(e.target.value); + refreshSimilarCalendarPriceChartData(); + refreshcalendarExitPriceChartData(); + } +}; + +function DaysBetweenFrontAndBackExpirationChooser() { + return ( + + ); +} + +export function EditableSpan() { + return ( + + // + // + // + ); +} diff --git a/frontend/src/pages/HistoricalCalendarPrices/EditableStrike.tsx b/frontend/src/pages/HistoricalCalendarPrices/EditableStrike.tsx index 37b76ce..6bb3abf 100644 --- a/frontend/src/pages/HistoricalCalendarPrices/EditableStrike.tsx +++ b/frontend/src/pages/HistoricalCalendarPrices/EditableStrike.tsx @@ -1,24 +1,21 @@ import Box from "@mui/material/Box"; import { EditableValue } from "./EditableValue"; -import { - strikePercentageFromUnderlyingPrice, - strikePercentageFromUnderlyingPriceRadius, -} from "./state"; +import { moniness, moninessRadius } from "./state"; import Slider from "@mui/material/Slider"; import { refreshSimilarCalendarPriceChartData } from "./actions"; -function StrikePercentageFromUnderlyingPriceChooser() { +function MoninessChooser() { return ( { - strikePercentageFromUnderlyingPrice.value = value as number; + moniness.value = value as number; }} onChangeCommitted={(e, value) => { refreshSimilarCalendarPriceChartData(); @@ -28,18 +25,18 @@ function StrikePercentageFromUnderlyingPriceChooser() { ); } -function StrikePercentageFromUnderlyingPriceRadiusChooser() { +function MoninessRadiusChooser() { return ( { - strikePercentageFromUnderlyingPriceRadius.value = value as number; + moninessRadius.value = value as number; }} onChangeCommitted={(e, value) => { refreshSimilarCalendarPriceChartData(); @@ -57,13 +54,11 @@ function StrikePercentageFromUnderlyingPriceRadiusChooser() { export function EditableStrike() { return ( - - + + ); diff --git a/frontend/src/pages/HistoricalCalendarPrices/actions.ts b/frontend/src/pages/HistoricalCalendarPrices/actions.ts index d2a4c9b..a0549a8 100644 --- a/frontend/src/pages/HistoricalCalendarPrices/actions.ts +++ b/frontend/src/pages/HistoricalCalendarPrices/actions.ts @@ -1,15 +1,15 @@ import { trpc } from "../../trpc"; import { calendarExitPriceChartData, - daysBetweenFrontAndBackExpiration, - daysToFrontExpiration, - exitToFrontExpiration, + span, + openDTE, + exitDTE, lookbackPeriodEnd, lookbackPeriodStart, similarCalendarPriceChartData, stockPriceChartData, - strikePercentageFromUnderlyingPrice, - strikePercentageFromUnderlyingPriceRadius, + moniness, + moninessRadius, underlying, } from "./state"; @@ -30,17 +30,12 @@ export const refreshSimilarCalendarPriceChartData = () => { trpc.SimilarCalendarPriceChart.getChartData .query({ underlying: underlying.value, - daysToFrontExpiration: daysToFrontExpiration.value, - daysBetweenFrontAndBackExpiration: - daysBetweenFrontAndBackExpiration.value, + daysToFrontExpiration: openDTE.value, + daysBetweenFrontAndBackExpiration: span.value, strikePercentageFromUnderlyingPriceRangeMin: - (strikePercentageFromUnderlyingPrice.value - - strikePercentageFromUnderlyingPriceRadius.value) / - 100, + (moniness.value - moninessRadius.value) / 100, strikePercentageFromUnderlyingPriceRangeMax: - (strikePercentageFromUnderlyingPrice.value + - strikePercentageFromUnderlyingPriceRadius.value) / - 100, + (moniness.value + moninessRadius.value) / 100, lookbackPeriodStart: lookbackPeriodStart.value, lookbackPeriodEnd: lookbackPeriodEnd.value, }) @@ -53,9 +48,8 @@ export const refreshcalendarExitPriceChartData = () => { trpc.CalendarExitPriceChart.getChartData .query({ underlying: underlying.value, - daysToFrontExpiration: exitToFrontExpiration.value, - daysBetweenFrontAndBackExpiration: - daysBetweenFrontAndBackExpiration.value, + daysToFrontExpiration: exitDTE.value, + daysBetweenFrontAndBackExpiration: span.value, lookbackPeriodStart: lookbackPeriodStart.value, lookbackPeriodEnd: lookbackPeriodEnd.value, }) diff --git a/frontend/src/pages/HistoricalCalendarPrices/state.ts b/frontend/src/pages/HistoricalCalendarPrices/state.ts index 7b44445..ddc9892 100644 --- a/frontend/src/pages/HistoricalCalendarPrices/state.ts +++ b/frontend/src/pages/HistoricalCalendarPrices/state.ts @@ -7,14 +7,14 @@ export const popperContent = signal(null); export const availableUnderlyings = signal([]); export const underlying = signal(null); -export const daysToFrontExpiration = signal(14); +export const openDTE = signal(14); -export const daysBetweenFrontAndBackExpiration = signal(14); +export const span = signal(14); -export const strikePercentageFromUnderlyingPrice = signal(1); -export const strikePercentageFromUnderlyingPriceRadius = signal(1); +export const moniness = signal(1); +export const moninessRadius = signal(1); -export const exitToFrontExpiration = signal(2); +export const exitDTE = signal(2); export const stockPriceChartData = signal([]);