import { signal, computed } from "@preact/signals"; 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 './style.css'; ChartJS.register(LinearScale, CategoryScale, PointElement, Tooltip, Title,); const availableUnderlyings = signal([]); const chosenUnderlying = signal(null); const chosenDaysToFrontExpiration = signal(14); const chosenDaysBetweenFrontAndBackExpiration = signal(14); const chosenStrikePercentageFromUnderlyingPrice = signal(1.4); const chosenStrikePercentageFromUnderlyingPriceRadius = signal(0.05); const chosenExitToFrontExpiration = signal(2); const historicalStockQuoteChartData = signal([]); const historicalCalendarQuoteChartData = signal([]); const historicalCalendarExitQuoteChartData = signal([]); const chosenLookbackPeriodStart = signal("2022-01-01"); const chosenLookbackPeriodEnd = signal("2024-01-01"); const maxChartPrice = computed(()=> Math.max( Math.max.apply(null, historicalCalendarQuoteChartData.value.map(d=>d.y)), Math.max.apply(null, historicalCalendarExitQuoteChartData.value.map(d=>d.y)), ) ); const refreshHistoricalStockQuoteChartData = ()=>{ trpc.getHistoricalStockQuoteChartData .query({ underlying:chosenUnderlying.value, lookbackPeriodStart:chosenLookbackPeriodStart.value, lookbackPeriodEnd:chosenLookbackPeriodEnd.value, }) .then((getHistoricalStockQuoteChartDataResponse)=>{ historicalStockQuoteChartData.value = getHistoricalStockQuoteChartDataResponse; }) }; const refreshHistoricalCalendarQuoteChartData = ()=>{ trpc.getHistoricalCalendarQuoteChartData .query({ underlying:chosenUnderlying.value, daysToFrontExpiration:chosenDaysToFrontExpiration.value, daysBetweenFrontAndBackExpiration:chosenDaysBetweenFrontAndBackExpiration.value, strikePercentageFromUnderlyingPriceRangeMin:chosenStrikePercentageFromUnderlyingPrice.value - chosenStrikePercentageFromUnderlyingPriceRadius.value, strikePercentageFromUnderlyingPriceRangeMax:chosenStrikePercentageFromUnderlyingPrice.value + chosenStrikePercentageFromUnderlyingPriceRadius.value, lookbackPeriodStart:chosenLookbackPeriodStart.value, lookbackPeriodEnd:chosenLookbackPeriodEnd.value, }) .then((getHistoricalCalendarQuoteChartDataResponse)=>{ historicalCalendarQuoteChartData.value = getHistoricalCalendarQuoteChartDataResponse; }) }; const refreshHistoricalCalendarExitQuoteChartData = ()=>{ trpc.getHistoricalCalendarExitQuoteChartData .query({ underlying:chosenUnderlying.value, daysToFrontExpiration:chosenExitToFrontExpiration.value, daysBetweenFrontAndBackExpiration:chosenDaysBetweenFrontAndBackExpiration.value, lookbackPeriodStart:chosenLookbackPeriodStart.value, lookbackPeriodEnd:chosenLookbackPeriodEnd.value, }) .then((getHistoricalCalendarExitQuoteChartDataResponse)=>{ historicalCalendarExitQuoteChartData.value = getHistoricalCalendarExitQuoteChartDataResponse; }) }; const handleInit = ()=>{ trpc.getAvailableUnderlyings .query() .then((availableUnderlyingsResponse)=>{ availableUnderlyings.value = availableUnderlyingsResponse; chosenUnderlying.value = availableUnderlyingsResponse[0]; refreshHistoricalStockQuoteChartData(); refreshHistoricalCalendarQuoteChartData(); refreshHistoricalCalendarExitQuoteChartData(); }); }; const handleUnderlyingChange = (e)=>{ if(chosenUnderlying.value !== e.target.value){ chosenUnderlying.value = e.target.value; refreshHistoricalStockQuoteChartData(); refreshHistoricalCalendarQuoteChartData(); refreshHistoricalCalendarExitQuoteChartData(); } }; const handleDaysToFrontExpirationChange = (e)=>{ if(chosenDaysToFrontExpiration.value !== parseInt(e.target.value)){ chosenDaysToFrontExpiration.value = parseInt(e.target.value); refreshHistoricalCalendarQuoteChartData(); } }; const handleDaysBetweenFrontAndBackExpirationChange = (e)=>{ if(chosenDaysBetweenFrontAndBackExpiration.value !== parseInt(e.target.value)){ chosenDaysBetweenFrontAndBackExpiration.value = parseInt(e.target.value); refreshHistoricalCalendarQuoteChartData(); refreshHistoricalCalendarExitQuoteChartData(); } }; const handleStrikePercentageFromUnderlyingPriceChange = (e)=>{ if(chosenStrikePercentageFromUnderlyingPrice.value !== parseFloat(e.target.value)){ chosenStrikePercentageFromUnderlyingPrice.value = parseFloat(e.target.value); refreshHistoricalCalendarQuoteChartData(); } }; const handleStrikePercentageFromUnderlyingPriceRadiusChange = (e)=>{ if(chosenStrikePercentageFromUnderlyingPriceRadius.value !== parseFloat(e.target.value)){ chosenStrikePercentageFromUnderlyingPriceRadius.value = parseFloat(e.target.value); refreshHistoricalCalendarQuoteChartData(); } }; const handleExitToFrontExpirationChange = (e)=>{ if(chosenExitToFrontExpiration.value !== parseInt(e.target.value)){ chosenExitToFrontExpiration.value = parseInt(e.target.value); refreshHistoricalCalendarExitQuoteChartData(); } }; const handleLookbackPeriodStartChange = (e)=>{ if(chosenLookbackPeriodStart.value !== e.target.value){ chosenLookbackPeriodStart.value = e.target.value; refreshHistoricalStockQuoteChartData(); refreshHistoricalCalendarQuoteChartData(); refreshHistoricalCalendarExitQuoteChartData(); } }; const handleLookbackPeriodEndChange = (e)=>{ if(chosenLookbackPeriodEnd.value !== e.target.value){ chosenLookbackPeriodEnd.value = e.target.value; refreshHistoricalStockQuoteChartData(); refreshHistoricalCalendarQuoteChartData(); refreshHistoricalCalendarExitQuoteChartData(); } }; export function HistoricalCalendarPrices(){ useEffect(handleInit, []); return (