main
avraham 7 months ago
parent 7bca5e701d
commit ea9bd307f3

@ -25,175 +25,171 @@ import {
ChartJS.register(LinearScale, CategoryScale, PointElement, Tooltip, Title); ChartJS.register(LinearScale, CategoryScale, PointElement, Tooltip, Title);
const availableUnderlyings = signal([]); const availableUnderlyings = signal([]);
const chosenUnderlying = signal(null); const underlying = signal(null);
const chosenDaysToFrontExpiration = signal(14); const daysToFrontExpiration = signal(14);
const chosenDaysBetweenFrontAndBackExpiration = signal(14); const daysBetweenFrontAndBackExpiration = signal(14);
const chosenStrikePercentageFromUnderlyingPrice = signal(1.4); const strikePercentageFromUnderlyingPrice = signal(1.4);
const chosenStrikePercentageFromUnderlyingPriceRadius = signal(0.05); const strikePercentageFromUnderlyingPriceRadius = signal(0.05);
const chosenExitToFrontExpiration = signal(2); const exitToFrontExpiration = signal(2);
const historicalStockQuoteChartData = signal([]); const stockPriceChartData = signal([]);
const historicalCalendarQuoteChartData = signal([]); const similarCalendarPriceChartData = signal([]);
const historicalCalendarExitQuoteChartData = signal([]); const calendarExitPriceChartData = signal([]);
const chosenLookbackPeriodStart = signal("2022-01-01"); const lookbackPeriodStart = signal("2022-01-01");
const chosenLookbackPeriodEnd = signal("2024-01-01"); const lookbackPeriodEnd = signal("2024-01-01");
const maxChartPrice = computed(() => const maxChartPrice = computed(() =>
Math.max( Math.max(
Math.max.apply( Math.max.apply(
null, null,
historicalCalendarQuoteChartData.value.map((d) => d.y), similarCalendarPriceChartData.value.map((d) => d.y)
), ),
Math.max.apply( Math.max.apply(
null, null,
historicalCalendarExitQuoteChartData.value.map((d) => d.y), calendarExitPriceChartData.value.map((d) => d.y)
), )
), )
); );
const maxN = computed(() => const maxN = computed(() =>
Math.max.apply( Math.max.apply(
null, null,
historicalCalendarExitQuoteChartData.value.map((d) => d.n), calendarExitPriceChartData.value.map((d) => d.n)
), )
); );
const refreshHistoricalStockQuoteChartData = () => { const refreshStockPriceChartData = () => {
historicalStockQuoteChartData.value = []; stockPriceChartData.value = [];
trpc.getHistoricalStockQuoteChartData trpc.StockPriceChart.getChartData
.query({ .query({
underlying: chosenUnderlying.value, underlying: underlying.value,
lookbackPeriodStart: chosenLookbackPeriodStart.value, lookbackPeriodStart: lookbackPeriodStart.value,
lookbackPeriodEnd: chosenLookbackPeriodEnd.value, lookbackPeriodEnd: lookbackPeriodEnd.value,
}) })
.then((getHistoricalStockQuoteChartDataResponse) => { .then((getChartDataResponse) => {
historicalStockQuoteChartData.value = stockPriceChartData.value = getChartDataResponse;
getHistoricalStockQuoteChartDataResponse;
}); });
}; };
const refreshHistoricalCalendarQuoteChartData = () => { const refreshSimilarCalendarPriceChartData = () => {
historicalCalendarQuoteChartData.value = []; similarCalendarPriceChartData.value = [];
trpc.getHistoricalCalendarQuoteChartData trpc.SimilarCalendarPriceChart.getChartData
.query({ .query({
underlying: chosenUnderlying.value, underlying: underlying.value,
daysToFrontExpiration: chosenDaysToFrontExpiration.value, daysToFrontExpiration: daysToFrontExpiration.value,
daysBetweenFrontAndBackExpiration: daysBetweenFrontAndBackExpiration:
chosenDaysBetweenFrontAndBackExpiration.value, daysBetweenFrontAndBackExpiration.value,
strikePercentageFromUnderlyingPriceRangeMin: strikePercentageFromUnderlyingPriceRangeMin:
chosenStrikePercentageFromUnderlyingPrice.value - strikePercentageFromUnderlyingPrice.value -
chosenStrikePercentageFromUnderlyingPriceRadius.value, strikePercentageFromUnderlyingPriceRadius.value,
strikePercentageFromUnderlyingPriceRangeMax: strikePercentageFromUnderlyingPriceRangeMax:
chosenStrikePercentageFromUnderlyingPrice.value + strikePercentageFromUnderlyingPrice.value +
chosenStrikePercentageFromUnderlyingPriceRadius.value, strikePercentageFromUnderlyingPriceRadius.value,
lookbackPeriodStart: chosenLookbackPeriodStart.value, lookbackPeriodStart: lookbackPeriodStart.value,
lookbackPeriodEnd: chosenLookbackPeriodEnd.value, lookbackPeriodEnd: lookbackPeriodEnd.value,
}) })
.then((getHistoricalCalendarQuoteChartDataResponse) => { .then((getChartDataResponse) => {
historicalCalendarQuoteChartData.value = similarCalendarPriceChartData.value = getChartDataResponse;
getHistoricalCalendarQuoteChartDataResponse;
}); });
}; };
const refreshHistoricalCalendarExitQuoteChartData = () => { const refreshcalendarExitPriceChartData = () => {
historicalCalendarExitQuoteChartData.value = []; calendarExitPriceChartData.value = [];
trpc.getHistoricalCalendarExitQuoteChartData trpc.CalendarExitPriceChart.getChartData
.query({ .query({
underlying: chosenUnderlying.value, underlying: underlying.value,
daysToFrontExpiration: chosenExitToFrontExpiration.value, daysToFrontExpiration: exitToFrontExpiration.value,
daysBetweenFrontAndBackExpiration: daysBetweenFrontAndBackExpiration:
chosenDaysBetweenFrontAndBackExpiration.value, daysBetweenFrontAndBackExpiration.value,
lookbackPeriodStart: chosenLookbackPeriodStart.value, lookbackPeriodStart: lookbackPeriodStart.value,
lookbackPeriodEnd: chosenLookbackPeriodEnd.value, lookbackPeriodEnd: lookbackPeriodEnd.value,
}) })
.then((getHistoricalCalendarExitQuoteChartDataResponse) => { .then((getChartDataResponse) => {
historicalCalendarExitQuoteChartData.value = calendarExitPriceChartData.value = getChartDataResponse;
getHistoricalCalendarExitQuoteChartDataResponse;
}); });
}; };
const handleInit = () => { const handleInit = () => {
trpc.getAvailableUnderlyings.query().then((availableUnderlyingsResponse) => { trpc.CalendarCharacteristicsForm.getAvailableUnderlyings
availableUnderlyings.value = availableUnderlyingsResponse; .query()
chosenUnderlying.value = availableUnderlyingsResponse[0]; .then((availableUnderlyingsResponse) => {
refreshHistoricalStockQuoteChartData(); availableUnderlyings.value = availableUnderlyingsResponse;
refreshHistoricalCalendarQuoteChartData(); underlying.value = availableUnderlyingsResponse[0];
refreshHistoricalCalendarExitQuoteChartData(); refreshStockPriceChartData();
}); refreshSimilarCalendarPriceChartData();
refreshcalendarExitPriceChartData();
});
}; };
const handleUnderlyingChange = (e) => { const handleUnderlyingChange = (e) => {
if (chosenUnderlying.value !== e.target.value) { if (underlying.value !== e.target.value) {
chosenUnderlying.value = e.target.value; underlying.value = e.target.value;
refreshHistoricalStockQuoteChartData(); refreshStockPriceChartData();
refreshHistoricalCalendarQuoteChartData(); refreshSimilarCalendarPriceChartData();
refreshHistoricalCalendarExitQuoteChartData(); refreshcalendarExitPriceChartData();
} }
}; };
const handleDaysToFrontExpirationChange = (e) => { const handleDaysToFrontExpirationChange = (e) => {
if (chosenDaysToFrontExpiration.value !== Number.parseInt(e.target.value)) { if (daysToFrontExpiration.value !== Number.parseInt(e.target.value)) {
chosenDaysToFrontExpiration.value = Number.parseInt(e.target.value); daysToFrontExpiration.value = Number.parseInt(e.target.value);
refreshHistoricalCalendarQuoteChartData(); refreshSimilarCalendarPriceChartData();
} }
}; };
const handleDaysBetweenFrontAndBackExpirationChange = (e) => { const handleDaysBetweenFrontAndBackExpirationChange = (e) => {
if ( if (
chosenDaysBetweenFrontAndBackExpiration.value !== daysBetweenFrontAndBackExpiration.value !== Number.parseInt(e.target.value)
Number.parseInt(e.target.value)
) { ) {
chosenDaysBetweenFrontAndBackExpiration.value = Number.parseInt( daysBetweenFrontAndBackExpiration.value = Number.parseInt(e.target.value);
e.target.value, refreshSimilarCalendarPriceChartData();
); refreshcalendarExitPriceChartData();
refreshHistoricalCalendarQuoteChartData();
refreshHistoricalCalendarExitQuoteChartData();
} }
}; };
const handleStrikePercentageFromUnderlyingPriceChange = (e) => { const handleStrikePercentageFromUnderlyingPriceChange = (e) => {
if ( if (
chosenStrikePercentageFromUnderlyingPrice.value !== strikePercentageFromUnderlyingPrice.value !==
Number.parseFloat(e.target.value) Number.parseFloat(e.target.value)
) { ) {
chosenStrikePercentageFromUnderlyingPrice.value = Number.parseFloat( strikePercentageFromUnderlyingPrice.value = Number.parseFloat(
e.target.value, e.target.value
); );
refreshHistoricalCalendarQuoteChartData(); refreshSimilarCalendarPriceChartData();
} }
}; };
const handleStrikePercentageFromUnderlyingPriceRadiusChange = (e) => { const handleStrikePercentageFromUnderlyingPriceRadiusChange = (e) => {
if ( if (
chosenStrikePercentageFromUnderlyingPriceRadius.value !== strikePercentageFromUnderlyingPriceRadius.value !==
Number.parseFloat(e.target.value) Number.parseFloat(e.target.value)
) { ) {
chosenStrikePercentageFromUnderlyingPriceRadius.value = Number.parseFloat( strikePercentageFromUnderlyingPriceRadius.value = Number.parseFloat(
e.target.value, e.target.value
); );
refreshHistoricalCalendarQuoteChartData(); refreshSimilarCalendarPriceChartData();
} }
}; };
const handleExitToFrontExpirationChange = (e) => { const handleExitToFrontExpirationChange = (e) => {
if (chosenExitToFrontExpiration.value !== Number.parseInt(e.target.value)) { if (exitToFrontExpiration.value !== Number.parseInt(e.target.value)) {
chosenExitToFrontExpiration.value = Number.parseInt(e.target.value); exitToFrontExpiration.value = Number.parseInt(e.target.value);
refreshHistoricalCalendarExitQuoteChartData(); refreshcalendarExitPriceChartData();
} }
}; };
const handleLookbackPeriodStartChange = (e) => { const handleLookbackPeriodStartChange = (e) => {
if (chosenLookbackPeriodStart.value !== e.target.value) { if (lookbackPeriodStart.value !== e.target.value) {
chosenLookbackPeriodStart.value = e.target.value; lookbackPeriodStart.value = e.target.value;
refreshHistoricalStockQuoteChartData(); refreshStockPriceChartData();
refreshHistoricalCalendarQuoteChartData(); refreshSimilarCalendarPriceChartData();
refreshHistoricalCalendarExitQuoteChartData(); refreshcalendarExitPriceChartData();
} }
}; };
const handleLookbackPeriodEndChange = (e) => { const handleLookbackPeriodEndChange = (e) => {
if (chosenLookbackPeriodEnd.value !== e.target.value) { if (lookbackPeriodEnd.value !== e.target.value) {
chosenLookbackPeriodEnd.value = e.target.value; lookbackPeriodEnd.value = e.target.value;
refreshHistoricalStockQuoteChartData(); refreshStockPriceChartData();
refreshHistoricalCalendarQuoteChartData(); refreshSimilarCalendarPriceChartData();
refreshHistoricalCalendarExitQuoteChartData(); refreshcalendarExitPriceChartData();
} }
}; };
@ -215,7 +211,7 @@ export function HistoricalCalendarPrices() {
<FormControl fullWidth> <FormControl fullWidth>
<InputLabel>Available Underlyings</InputLabel> <InputLabel>Available Underlyings</InputLabel>
<Select <Select
value={chosenUnderlying.value || ""} value={underlying.value || ""}
onChange={handleUnderlyingChange} onChange={handleUnderlyingChange}
label="Available Underlyings" label="Available Underlyings"
> >
@ -232,7 +228,7 @@ export function HistoricalCalendarPrices() {
fullWidth fullWidth
label="Now-to-Front-Month Days to Expiration" label="Now-to-Front-Month Days to Expiration"
type="number" type="number"
value={chosenDaysToFrontExpiration.value} value={daysToFrontExpiration.value}
onChange={handleDaysToFrontExpirationChange} onChange={handleDaysToFrontExpirationChange}
InputProps={{ endAdornment: "Days" }} InputProps={{ endAdornment: "Days" }}
/> />
@ -242,7 +238,7 @@ export function HistoricalCalendarPrices() {
fullWidth fullWidth
label="Front-to-Back-Month Days to Expiration Difference" label="Front-to-Back-Month Days to Expiration Difference"
type="number" type="number"
value={chosenDaysBetweenFrontAndBackExpiration.value} value={daysBetweenFrontAndBackExpiration.value}
onChange={handleDaysBetweenFrontAndBackExpirationChange} onChange={handleDaysBetweenFrontAndBackExpirationChange}
InputProps={{ endAdornment: "Days Difference" }} InputProps={{ endAdornment: "Days Difference" }}
/> />
@ -252,7 +248,7 @@ export function HistoricalCalendarPrices() {
fullWidth fullWidth
label="Strike % From Underlying Price" label="Strike % From Underlying Price"
type="number" type="number"
value={chosenStrikePercentageFromUnderlyingPrice.value} value={strikePercentageFromUnderlyingPrice.value}
onChange={handleStrikePercentageFromUnderlyingPriceChange} onChange={handleStrikePercentageFromUnderlyingPriceChange}
InputProps={{ endAdornment: "%" }} InputProps={{ endAdornment: "%" }}
/> />
@ -262,7 +258,7 @@ export function HistoricalCalendarPrices() {
fullWidth fullWidth
label="Strike % Radius" label="Strike % Radius"
type="number" type="number"
value={chosenStrikePercentageFromUnderlyingPriceRadius.value} value={strikePercentageFromUnderlyingPriceRadius.value}
onChange={ onChange={
handleStrikePercentageFromUnderlyingPriceRadiusChange handleStrikePercentageFromUnderlyingPriceRadiusChange
} }
@ -274,7 +270,7 @@ export function HistoricalCalendarPrices() {
fullWidth fullWidth
label="Exit-to-Front-Month Days to Expiration" label="Exit-to-Front-Month Days to Expiration"
type="number" type="number"
value={chosenExitToFrontExpiration.value} value={exitToFrontExpiration.value}
onChange={handleExitToFrontExpirationChange} onChange={handleExitToFrontExpirationChange}
InputProps={{ endAdornment: "Days" }} InputProps={{ endAdornment: "Days" }}
/> />
@ -284,7 +280,7 @@ export function HistoricalCalendarPrices() {
fullWidth fullWidth
label="Lookback Period Start" label="Lookback Period Start"
type="date" type="date"
value={chosenLookbackPeriodStart.value} value={lookbackPeriodStart.value}
onChange={(e) => onChange={(e) =>
handleLookbackPeriodStartChange({ handleLookbackPeriodStartChange({
target: { value: e.target.value }, target: { value: e.target.value },
@ -298,7 +294,7 @@ export function HistoricalCalendarPrices() {
fullWidth fullWidth
label="Lookback Period End" label="Lookback Period End"
type="date" type="date"
value={chosenLookbackPeriodEnd.value} value={lookbackPeriodEnd.value}
onChange={(e) => onChange={(e) =>
handleLookbackPeriodEndChange({ handleLookbackPeriodEndChange({
target: { value: e.target.value }, target: { value: e.target.value },
@ -312,14 +308,14 @@ export function HistoricalCalendarPrices() {
</Grid> </Grid>
<Grid item xs={12} md={6}> <Grid item xs={12} md={6}>
<Paper elevation={3} sx={{ p: 3, height: "100%" }}> <Paper elevation={3} sx={{ p: 3, height: "100%" }}>
{chosenUnderlying.value !== null && {underlying.value !== null &&
historicalStockQuoteChartData.value.length > 0 ? ( stockPriceChartData.value.length > 0 ? (
<Scatter <Scatter
data={{ data={{
datasets: [ datasets: [
{ {
label: "Stock Open Price", label: "Stock Open Price",
data: historicalStockQuoteChartData.value, data: stockPriceChartData.value,
}, },
], ],
}} }}
@ -336,12 +332,8 @@ export function HistoricalCalendarPrices() {
.toISOString() .toISOString()
.substring(0, 10), .substring(0, 10),
}, },
min: min: new Date(lookbackPeriodStart.value).getTime() / 1000,
new Date(chosenLookbackPeriodStart.value).getTime() / max: new Date(lookbackPeriodEnd.value).getTime() / 1000,
1000,
max:
new Date(chosenLookbackPeriodEnd.value).getTime() /
1000,
}, },
y: { y: {
beginAtZero: false, beginAtZero: false,
@ -381,14 +373,14 @@ export function HistoricalCalendarPrices() {
</Grid> </Grid>
<Grid item xs={12}> <Grid item xs={12}>
<Paper elevation={3} sx={{ p: 3 }}> <Paper elevation={3} sx={{ p: 3 }}>
{chosenUnderlying.value !== null && {underlying.value !== null &&
historicalCalendarQuoteChartData.value.length > 0 ? ( similarCalendarPriceChartData.value.length > 0 ? (
<Scatter <Scatter
data={{ data={{
datasets: [ datasets: [
{ {
label: "Calendar Open Price", label: "Calendar Open Price",
data: historicalCalendarQuoteChartData.value, data: similarCalendarPriceChartData.value,
}, },
], ],
}} }}
@ -405,12 +397,8 @@ export function HistoricalCalendarPrices() {
.toISOString() .toISOString()
.substring(0, 10), .substring(0, 10),
}, },
min: min: new Date(lookbackPeriodStart.value).getTime() / 1000,
new Date(chosenLookbackPeriodStart.value).getTime() / max: new Date(lookbackPeriodEnd.value).getTime() / 1000,
1000,
max:
new Date(chosenLookbackPeriodEnd.value).getTime() /
1000,
}, },
y: { y: {
beginAtZero: true, beginAtZero: true,
@ -446,14 +434,14 @@ export function HistoricalCalendarPrices() {
</Grid> </Grid>
<Grid item xs={12}> <Grid item xs={12}>
<Paper elevation={3} sx={{ p: 3 }}> <Paper elevation={3} sx={{ p: 3 }}>
{chosenUnderlying.value !== null && {underlying.value !== null &&
historicalCalendarQuoteChartData.value.length > 0 ? ( similarCalendarPriceChartData.value.length > 0 ? (
<Scatter <Scatter
data={{ data={{
datasets: [ datasets: [
{ {
label: "Calendar Exit Price", label: "Calendar Exit Price",
data: historicalCalendarExitQuoteChartData.value, data: calendarExitPriceChartData.value,
}, },
], ],
}} }}

@ -1,5 +1,5 @@
import { query } from "./lib/clickhouse"; import { query } from "./lib/clickhouse.js";
import { publicProcedure, RpcType, router } from "./trpc"; import { publicProcedure, RpcType, router } from "./trpc.js";
import { import {
Object as ObjectT, Object as ObjectT,
String as StringT, String as StringT,

@ -1,5 +1,5 @@
import { query } from "./lib/clickhouse"; import { query } from "./lib/clickhouse.js";
import { publicProcedure, RpcType, router } from "./trpc"; import { publicProcedure, RpcType, router } from "./trpc.js";
import { import {
Object as ObjectT, Object as ObjectT,
String as StringT, String as StringT,

@ -1,5 +1,5 @@
import { query } from "./lib/clickhouse"; import { query } from "./lib/clickhouse.js";
import { publicProcedure, RpcType, router } from "./trpc"; import { publicProcedure, RpcType, router } from "./trpc.js";
import { import {
Object as ObjectT, Object as ObjectT,
String as StringT, String as StringT,

@ -1,5 +1,5 @@
import { query } from "./lib/clickhouse"; import { query } from "./lib/clickhouse.js";
import { publicProcedure, RpcType, router } from "./trpc"; import { publicProcedure, RpcType, router } from "./trpc.js";
import { Object as ObjectT, String as StringT } from "@sinclair/typebox"; import { Object as ObjectT, String as StringT } from "@sinclair/typebox";
export const getChartData = publicProcedure export const getChartData = publicProcedure

@ -9,7 +9,7 @@ import {
} from "@sinclair/typebox"; } from "@sinclair/typebox";
import { createServer } from "node:http"; import { createServer } from "node:http";
import { Env } from "@humanwhocodes/env"; import { Env } from "@humanwhocodes/env";
import UnderlyingPriceChart from "./UnderlyingPriceChart.js"; import StockPriceChart from "./StockPriceChart.js";
import SimilarCalendarPriceChart from "./SimilarCalendarPriceChart.js"; import SimilarCalendarPriceChart from "./SimilarCalendarPriceChart.js";
import CalendarExitPriceChart from "./CalendarExitPriceChart.js"; import CalendarExitPriceChart from "./CalendarExitPriceChart.js";
import CalendarCharacteristicsForm from "./CalendarCharacteristicsForm.js"; import CalendarCharacteristicsForm from "./CalendarCharacteristicsForm.js";
@ -71,7 +71,7 @@ export const getOpensForOptionContract = publicProcedure
const appRouter = router({ const appRouter = router({
CalendarCharacteristicsForm, CalendarCharacteristicsForm,
UnderlyingPriceChart, StockPriceChart,
SimilarCalendarPriceChart, SimilarCalendarPriceChart,
CalendarExitPriceChart, CalendarExitPriceChart,

Loading…
Cancel
Save