diff --git a/frontend/src/pages/CalendarOptimizer/index.tsx b/frontend/src/pages/CalendarOptimizer/index.tsx index 0f526d1..331e7a4 100644 --- a/frontend/src/pages/CalendarOptimizer/index.tsx +++ b/frontend/src/pages/CalendarOptimizer/index.tsx @@ -1,6 +1,18 @@ 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 "./style.css"; + +ChartJS.register(LinearScale, CategoryScale, PointElement, Tooltip, Title); const availableUnderlyings = signal([]); const chosenUnderlying = signal(null); @@ -151,12 +163,143 @@ export function CalendarOptimizer() { )} - {/* {chosenUnderlying.value!==null && underlyingUplotData.value.length>0 - ? - : <>} - {chosenUnderlying.value!==null && chosenAsOfDate.value!==null && chosenExpiration.value!==null && chosenStrike.value!==null && optionContractUplotData.value.length>0 - ? - : <>} */} +
+ {chosenUnderlying.value !== null && + underlyingUplotData.value.length > 0 ? ( +
+ +
+ ) : ( + <> + )} + {chosenUnderlying.value !== null && + chosenAsOfDate.value !== null && + chosenExpiration.value !== null && + chosenStrike.value !== null && + optionContractUplotData.value.length > 0 ? ( +
+ +
+ ) : ( + <> + )} +
); } diff --git a/frontend/src/pages/CalendarOptimizer/style.css b/frontend/src/pages/CalendarOptimizer/style.css new file mode 100644 index 0000000..093122e --- /dev/null +++ b/frontend/src/pages/CalendarOptimizer/style.css @@ -0,0 +1,11 @@ +.chart-container { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: space-around; + width: 1800px; + height: 480px; +} +.chart-container > .chart { + width: 880px; +} diff --git a/server/src/index.ts b/server/src/index.ts index 534718e..77f503c 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -49,6 +49,7 @@ const appRouter = router({ DISTINCT(asOfDate) as asOfDate FROM option_contracts WHERE symbol = '${underlying}' + ORDER BY asOfDate `) ).map(({ asOfDate }) => asOfDate); }), @@ -66,10 +67,11 @@ const appRouter = router({ return ( await query<{ expirationDate: string }>(` SELECT - DISTINCT(expirationDate) + DISTINCT(expirationDate) as expirationDate FROM option_contracts WHERE symbol = '${underlying}' AND asOfDate = '${asOfDate}' + ORDER BY expirationDate `) ).map(({ expirationDate }) => expirationDate); }), @@ -88,11 +90,12 @@ const appRouter = router({ return ( await query<{ strike: string }>(` SELECT - DISTINCT(strike) + DISTINCT(strike) as strike FROM option_contracts WHERE symbol = '${underlying}' AND asOfDate = '${asOfDate}' AND expirationDate = '${expirationDate}' + ORDER BY strike `) ).map(({ strike }) => strike); }), @@ -106,25 +109,16 @@ const appRouter = router({ ) .query(async (opts) => { const { underlying } = opts.input; - return ( - await query<[number, number]>( - ` + return await query<{ x: number; y: number }>( + ` SELECT - toUnixTimestamp(tsStart), - open + toUnixTimestamp(tsStart) as x, + open as y FROM stock_aggregates WHERE symbol = '${underlying}' ORDER BY tsStart ASC `, - "JSONCompactEachRow" - ) - ).reduce( - (columns, row) => { - columns[0].push(row[0]); - columns[1].push(row[1]); - return columns; - }, - [[], []] + "JSONEachRow" ); }), getOpensForOptionContract: publicProcedure @@ -139,12 +133,11 @@ const appRouter = router({ ) .query(async (opts) => { const { underlying, expirationDate, strike } = opts.input; - return ( - await query<[number, number]>( - ` + return await query<{ x: number; y: number }>( + ` SELECT - toUnixTimestamp(tsStart), - open + toUnixTimestamp(tsStart) as x, + open as y FROM option_aggregates WHERE symbol = '${underlying}' AND expirationDate = '${expirationDate}' @@ -152,15 +145,7 @@ const appRouter = router({ AND type = 'call' ORDER BY tsStart ASC `, - "JSONCompactEachRow" - ) - ).reduce( - (columns, row) => { - columns[0].push(row[0]); - columns[1].push(row[1]); - return columns; - }, - [[], []] + "JSONEachRow" ); }), getHistoricalCalendarPrices: publicProcedure