import { useEffect } from "preact/hooks"; import { trpc } from "../trpc.js"; import { Chart as ChartJS, LinearScale, CategoryScale, PointElement, Tooltip, Title, } from "chart.js"; import { Scatter } from "react-chartjs-2"; import { Container, Grid, Typography, Paper, Popper, ClickAwayListener, } from "@mui/material"; import { availableUnderlyings, calendarExitPriceChartData, isPopperOpen, lookbackPeriodEnd, lookbackPeriodStart, maxChartPrice, maxN, popperAnchorEl, popperContent, similarCalendarPriceChartData, stockPriceChartData, underlying, } from "./HistoricalCalendarPrices/state.js"; import { EditableStrike } from "./HistoricalCalendarPrices/EditableStrike.js"; import { refreshcalendarExitPriceChartData, refreshSimilarCalendarPriceChartData, 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 { EditableLookbackPeriodStart } from "./HistoricalCalendarPrices/EditableLookbackPeriodStart.js"; import { EditableLookbackPeriodEnd } from "./HistoricalCalendarPrices/EditableLookbackPeriodEnd.js"; ChartJS.register(LinearScale, CategoryScale, PointElement, Tooltip, Title); const handleInit = () => { trpc.CalendarCharacteristicsForm.getAvailableUnderlyings .query() .then((availableUnderlyingsResponse) => { availableUnderlyings.value = availableUnderlyingsResponse; underlying.value = availableUnderlyingsResponse[0]; refreshStockPriceChartData(); refreshSimilarCalendarPriceChartData(); refreshcalendarExitPriceChartData(); }); }; export function HistoricalCalendarPrices() { useEffect(handleInit, []); return ( : -Day Calendar @ %-from-the-money Opening at DTE, Closing at{" "} DTE - { isPopperOpen.value = false; // refreshSimilarCalendarPriceChartData(); console.log("clicked away"); }} > {popperContent.value} {underlying.value !== null && stockPriceChartData.value.length > 0 ? ( 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: false, ticks: { callback: (value, index, ticks) => `$${value.toString()}`, }, }, }, elements: { point: { radius: 1, borderWidth: 0, }, }, plugins: { tooltip: { enabled: false, }, legend: { display: false, }, title: { display: true, text: "Stock Price", }, }, animation: false, maintainAspectRatio: false, events: [], }} /> ) : ( Loading Chart... )} {underlying.value !== null && similarCalendarPriceChartData.value.length > 0 ? ( 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, ticks: { callback: (value, index, ticks) => `$${value.toString()}`, }, min: 0, max: maxChartPrice.value, }, }, plugins: { tooltip: { enabled: false, }, legend: { display: false, }, title: { display: true, text: "Calendar Price (Under Like Conditions)", }, }, animation: false, maintainAspectRatio: false, events: [], }} /> ) : ( Loading Chart... )} {underlying.value !== null && similarCalendarPriceChartData.value.length > 0 ? ( `${value.toString()}%`, }, }, y: { beginAtZero: true, ticks: { callback: (value, index, ticks) => `$${value.toString()}`, }, min: 0, 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, }, legend: { display: false, }, title: { display: true, text: [ "Calendar Prices at Exit", "by %-age from-the-money", ], }, }, animation: false, maintainAspectRatio: false, events: [], }} /> ) : ( Loading Chart... )} ); }