import { signal } from "@preact/signals"; import { useCallback, 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, FormControl, InputLabel, Select, MenuItem, Paper, } from "@mui/material"; ChartJS.register(LinearScale, CategoryScale, PointElement, Tooltip, Title); const availableUnderlyings = signal([]); const chosenUnderlying = signal(null); const availableAsOfDates = signal([]); const chosenAsOfDate = signal(null); const availableExpirations = signal([]); const chosenExpiration = signal(null); const availableStrikes = signal([]); const chosenStrike = signal(null); const optionContractUplotData = signal([]); const underlyingUplotData = signal([]); function chooseUnderlying(underlying: string) { chosenUnderlying.value = underlying; trpc.getAvailableAsOfDates .query({ underlying: underlying }) .then((getAvailableAsOfDatesResponse) => { availableAsOfDates.value = getAvailableAsOfDatesResponse; chooseAsOfDate(getAvailableAsOfDatesResponse[0]); }); trpc.getOpensForUnderlying .query({ underlying: underlying }) .then((getOpensForUnderlyingResponse) => { underlyingUplotData.value = getOpensForUnderlyingResponse; }); } function chooseAsOfDate(asOfDate: string) { chosenAsOfDate.value = asOfDate; trpc.getExpirationsForUnderlying .query({ underlying: chosenUnderlying.value, asOfDate: chosenAsOfDate.value, }) .then((getExpirationsForUnderlyingResponse) => { availableExpirations.value = getExpirationsForUnderlyingResponse; chooseExpiration(getExpirationsForUnderlyingResponse[0]); }); } function chooseExpiration(expiration: string) { chosenExpiration.value = expiration; trpc.getStrikesForUnderlying .query({ underlying: chosenUnderlying.value, asOfDate: chosenAsOfDate.value, expirationDate: expiration, }) .then((getStrikesForUnderlyingResponse) => { availableStrikes.value = getStrikesForUnderlyingResponse; chooseStrike(getStrikesForUnderlyingResponse[0]); }); } function chooseStrike(strike: string) { chosenStrike.value = strike; trpc.getOpensForOptionContract .query({ underlying: chosenUnderlying.value, expirationDate: chosenExpiration.value, strike: parseFloat(strike), }) .then((getOpensForOptionContractResponse) => { optionContractUplotData.value = getOpensForOptionContractResponse; }); } export function CalendarOptimizer() { const handleInit = useCallback(() => { trpc.getAvailableUnderlyings .query() .then((availableUnderlyingsResponse) => { availableUnderlyings.value = availableUnderlyingsResponse; // load first underlying in list: chooseUnderlying(availableUnderlyingsResponse[0]); }); }, []); const handleUnderlyingChange = useCallback((e) => { console.log(`Chose Underlying: ${e.target.value}`); chooseUnderlying(e.target.value); }, []); const handleAsOfDateChange = useCallback((e) => { console.log(`Chose Date: ${e.target.value}`); chooseAsOfDate(e.target.value); }, []); const handleExpirationChange = useCallback((e) => { console.log(`Chose Expiration: ${e.target.value}`); chooseExpiration(e.target.value); }, []); const handleStrikeChange = useCallback((e) => { console.log(`Chose Strike: ${e.target.value}`); chooseStrike(e.target.value); }, []); useEffect(handleInit, []); return ( Calendar Optimizer Available Underlyings Available "As-of" Dates Available Expirations Available Strikes {chosenUnderlying.value !== null && underlyingUplotData.value.length > 0 ? ( ) : ( Loading Chart... )} {chosenUnderlying.value !== null && chosenAsOfDate.value !== null && chosenExpiration.value !== null && chosenStrike.value !== null && optionContractUplotData.value.length > 0 ? ( ) : ( Loading Chart... )} ); }