|
|
@ -49,20 +49,20 @@ const maxChartPrice = computed(() =>
|
|
|
|
Math.max(
|
|
|
|
Math.max(
|
|
|
|
Math.max.apply(
|
|
|
|
Math.max.apply(
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
historicalCalendarQuoteChartData.value.map((d) => d.y)
|
|
|
|
historicalCalendarQuoteChartData.value.map((d) => d.y),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
Math.max.apply(
|
|
|
|
Math.max.apply(
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
historicalCalendarExitQuoteChartData.value.map((d) => d.y)
|
|
|
|
historicalCalendarExitQuoteChartData.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)
|
|
|
|
historicalCalendarExitQuoteChartData.value.map((d) => d.n),
|
|
|
|
)
|
|
|
|
),
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const refreshHistoricalStockQuoteChartData = () => {
|
|
|
|
const refreshHistoricalStockQuoteChartData = () => {
|
|
|
@ -134,16 +134,19 @@ const handleUnderlyingChange = (e) => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const handleDaysToFrontExpirationChange = (e) => {
|
|
|
|
const handleDaysToFrontExpirationChange = (e) => {
|
|
|
|
if (chosenDaysToFrontExpiration.value !== parseInt(e.target.value)) {
|
|
|
|
if (chosenDaysToFrontExpiration.value !== Number.parseInt(e.target.value)) {
|
|
|
|
chosenDaysToFrontExpiration.value = parseInt(e.target.value);
|
|
|
|
chosenDaysToFrontExpiration.value = Number.parseInt(e.target.value);
|
|
|
|
refreshHistoricalCalendarQuoteChartData();
|
|
|
|
refreshHistoricalCalendarQuoteChartData();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const handleDaysBetweenFrontAndBackExpirationChange = (e) => {
|
|
|
|
const handleDaysBetweenFrontAndBackExpirationChange = (e) => {
|
|
|
|
if (
|
|
|
|
if (
|
|
|
|
chosenDaysBetweenFrontAndBackExpiration.value !== parseInt(e.target.value)
|
|
|
|
chosenDaysBetweenFrontAndBackExpiration.value !==
|
|
|
|
|
|
|
|
Number.parseInt(e.target.value)
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
chosenDaysBetweenFrontAndBackExpiration.value = parseInt(e.target.value);
|
|
|
|
chosenDaysBetweenFrontAndBackExpiration.value = Number.parseInt(
|
|
|
|
|
|
|
|
e.target.value,
|
|
|
|
|
|
|
|
);
|
|
|
|
refreshHistoricalCalendarQuoteChartData();
|
|
|
|
refreshHistoricalCalendarQuoteChartData();
|
|
|
|
refreshHistoricalCalendarExitQuoteChartData();
|
|
|
|
refreshHistoricalCalendarExitQuoteChartData();
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -151,10 +154,10 @@ const handleDaysBetweenFrontAndBackExpirationChange = (e) => {
|
|
|
|
const handleStrikePercentageFromUnderlyingPriceChange = (e) => {
|
|
|
|
const handleStrikePercentageFromUnderlyingPriceChange = (e) => {
|
|
|
|
if (
|
|
|
|
if (
|
|
|
|
chosenStrikePercentageFromUnderlyingPrice.value !==
|
|
|
|
chosenStrikePercentageFromUnderlyingPrice.value !==
|
|
|
|
parseFloat(e.target.value)
|
|
|
|
Number.parseFloat(e.target.value)
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
chosenStrikePercentageFromUnderlyingPrice.value = parseFloat(
|
|
|
|
chosenStrikePercentageFromUnderlyingPrice.value = Number.parseFloat(
|
|
|
|
e.target.value
|
|
|
|
e.target.value,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
refreshHistoricalCalendarQuoteChartData();
|
|
|
|
refreshHistoricalCalendarQuoteChartData();
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -162,17 +165,17 @@ const handleStrikePercentageFromUnderlyingPriceChange = (e) => {
|
|
|
|
const handleStrikePercentageFromUnderlyingPriceRadiusChange = (e) => {
|
|
|
|
const handleStrikePercentageFromUnderlyingPriceRadiusChange = (e) => {
|
|
|
|
if (
|
|
|
|
if (
|
|
|
|
chosenStrikePercentageFromUnderlyingPriceRadius.value !==
|
|
|
|
chosenStrikePercentageFromUnderlyingPriceRadius.value !==
|
|
|
|
parseFloat(e.target.value)
|
|
|
|
Number.parseFloat(e.target.value)
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
chosenStrikePercentageFromUnderlyingPriceRadius.value = parseFloat(
|
|
|
|
chosenStrikePercentageFromUnderlyingPriceRadius.value = Number.parseFloat(
|
|
|
|
e.target.value
|
|
|
|
e.target.value,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
refreshHistoricalCalendarQuoteChartData();
|
|
|
|
refreshHistoricalCalendarQuoteChartData();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
const handleExitToFrontExpirationChange = (e) => {
|
|
|
|
const handleExitToFrontExpirationChange = (e) => {
|
|
|
|
if (chosenExitToFrontExpiration.value !== parseInt(e.target.value)) {
|
|
|
|
if (chosenExitToFrontExpiration.value !== Number.parseInt(e.target.value)) {
|
|
|
|
chosenExitToFrontExpiration.value = parseInt(e.target.value);
|
|
|
|
chosenExitToFrontExpiration.value = Number.parseInt(e.target.value);
|
|
|
|
refreshHistoricalCalendarExitQuoteChartData();
|
|
|
|
refreshHistoricalCalendarExitQuoteChartData();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -198,320 +201,324 @@ export function HistoricalCalendarPrices() {
|
|
|
|
useEffect(handleInit, []);
|
|
|
|
useEffect(handleInit, []);
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<Container maxWidth="lg">
|
|
|
|
<Container maxWidth="lg">
|
|
|
|
<Grid container spacing={4}>
|
|
|
|
<Grid container spacing={4}>
|
|
|
|
<Grid item xs={12}>
|
|
|
|
<Grid item xs={12}>
|
|
|
|
<Typography variant="h4" gutterBottom>
|
|
|
|
<Typography variant="h4" gutterBottom>
|
|
|
|
Historical Calendar Prices
|
|
|
|
Historical Calendar Prices
|
|
|
|
</Typography>
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} md={6}>
|
|
|
|
<Grid item xs={12} md={6}>
|
|
|
|
<Paper elevation={3} sx={{ p: 3 }}>
|
|
|
|
<Paper elevation={3} sx={{ p: 3 }}>
|
|
|
|
<Grid container spacing={2}>
|
|
|
|
<Grid container spacing={2}>
|
|
|
|
<Grid item xs={12}>
|
|
|
|
<Grid item xs={12}>
|
|
|
|
<FormControl fullWidth>
|
|
|
|
<FormControl fullWidth>
|
|
|
|
<InputLabel>Available Underlyings</InputLabel>
|
|
|
|
<InputLabel>Available Underlyings</InputLabel>
|
|
|
|
<Select
|
|
|
|
<Select
|
|
|
|
value={chosenUnderlying.value || ""}
|
|
|
|
value={chosenUnderlying.value || ""}
|
|
|
|
onChange={handleUnderlyingChange}
|
|
|
|
onChange={handleUnderlyingChange}
|
|
|
|
label="Available Underlyings"
|
|
|
|
label="Available Underlyings"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{availableUnderlyings.value.map((underlying) => (
|
|
|
|
{availableUnderlyings.value.map((underlying) => (
|
|
|
|
<MenuItem key={underlying} value={underlying}>
|
|
|
|
<MenuItem key={underlying} value={underlying}>
|
|
|
|
{underlying}
|
|
|
|
{underlying}
|
|
|
|
</MenuItem>
|
|
|
|
</MenuItem>
|
|
|
|
))}
|
|
|
|
))}
|
|
|
|
</Select>
|
|
|
|
</Select>
|
|
|
|
</FormControl>
|
|
|
|
</FormControl>
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
|
|
|
<TextField
|
|
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
|
|
label="Now-to-Front-Month Days to Expiration"
|
|
|
|
|
|
|
|
type="number"
|
|
|
|
|
|
|
|
value={chosenDaysToFrontExpiration.value}
|
|
|
|
|
|
|
|
onChange={handleDaysToFrontExpirationChange}
|
|
|
|
|
|
|
|
InputProps={{ endAdornment: "Days" }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
|
|
|
<TextField
|
|
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
|
|
label="Front-to-Back-Month Days to Expiration Difference"
|
|
|
|
|
|
|
|
type="number"
|
|
|
|
|
|
|
|
value={chosenDaysBetweenFrontAndBackExpiration.value}
|
|
|
|
|
|
|
|
onChange={handleDaysBetweenFrontAndBackExpirationChange}
|
|
|
|
|
|
|
|
InputProps={{ endAdornment: "Days Difference" }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={6}>
|
|
|
|
|
|
|
|
<TextField
|
|
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
|
|
label="Strike % From Underlying Price"
|
|
|
|
|
|
|
|
type="number"
|
|
|
|
|
|
|
|
value={chosenStrikePercentageFromUnderlyingPrice.value}
|
|
|
|
|
|
|
|
onChange={handleStrikePercentageFromUnderlyingPriceChange}
|
|
|
|
|
|
|
|
InputProps={{ endAdornment: "%" }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={6}>
|
|
|
|
|
|
|
|
<TextField
|
|
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
|
|
label="Strike % Radius"
|
|
|
|
|
|
|
|
type="number"
|
|
|
|
|
|
|
|
value={chosenStrikePercentageFromUnderlyingPriceRadius.value}
|
|
|
|
|
|
|
|
onChange={handleStrikePercentageFromUnderlyingPriceRadiusChange}
|
|
|
|
|
|
|
|
InputProps={{ endAdornment: "%" }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
|
|
|
<TextField
|
|
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
|
|
label="Exit-to-Front-Month Days to Expiration"
|
|
|
|
|
|
|
|
type="number"
|
|
|
|
|
|
|
|
value={chosenExitToFrontExpiration.value}
|
|
|
|
|
|
|
|
onChange={handleExitToFrontExpirationChange}
|
|
|
|
|
|
|
|
InputProps={{ endAdornment: "Days" }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={6}>
|
|
|
|
|
|
|
|
<TextField
|
|
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
|
|
label="Lookback Period Start"
|
|
|
|
|
|
|
|
type="date"
|
|
|
|
|
|
|
|
value={chosenLookbackPeriodStart.value}
|
|
|
|
|
|
|
|
onChange={(e) => handleLookbackPeriodStartChange({ target: { value: e.target.value } })}
|
|
|
|
|
|
|
|
InputLabelProps={{ shrink: true }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={6}>
|
|
|
|
|
|
|
|
<TextField
|
|
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
|
|
label="Lookback Period End"
|
|
|
|
|
|
|
|
type="date"
|
|
|
|
|
|
|
|
value={chosenLookbackPeriodEnd.value}
|
|
|
|
|
|
|
|
onChange={(e) => handleLookbackPeriodEndChange({ target: { value: e.target.value } })}
|
|
|
|
|
|
|
|
InputLabelProps={{ shrink: true }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
</Paper>
|
|
|
|
<Grid item xs={12}>
|
|
|
|
</Grid>
|
|
|
|
<TextField
|
|
|
|
<Grid item xs={12} md={6}>
|
|
|
|
fullWidth
|
|
|
|
<Paper elevation={3} sx={{ p: 3, height: '100%' }}>
|
|
|
|
label="Now-to-Front-Month Days to Expiration"
|
|
|
|
{chosenUnderlying.value !== null &&
|
|
|
|
type="number"
|
|
|
|
historicalStockQuoteChartData.value.length > 0 ? (
|
|
|
|
value={chosenDaysToFrontExpiration.value}
|
|
|
|
<Scatter
|
|
|
|
onChange={handleDaysToFrontExpirationChange}
|
|
|
|
data={{
|
|
|
|
InputProps={{ endAdornment: "Days" }}
|
|
|
|
datasets: [
|
|
|
|
/>
|
|
|
|
{
|
|
|
|
</Grid>
|
|
|
|
label: "Stock Open Price",
|
|
|
|
<Grid item xs={12}>
|
|
|
|
data: historicalStockQuoteChartData.value,
|
|
|
|
<TextField
|
|
|
|
},
|
|
|
|
fullWidth
|
|
|
|
],
|
|
|
|
label="Front-to-Back-Month Days to Expiration Difference"
|
|
|
|
}}
|
|
|
|
type="number"
|
|
|
|
options={{
|
|
|
|
value={chosenDaysBetweenFrontAndBackExpiration.value}
|
|
|
|
scales: {
|
|
|
|
onChange={handleDaysBetweenFrontAndBackExpirationChange}
|
|
|
|
x: {
|
|
|
|
InputProps={{ endAdornment: "Days Difference" }}
|
|
|
|
title: {
|
|
|
|
/>
|
|
|
|
display: true,
|
|
|
|
</Grid>
|
|
|
|
text: "Time",
|
|
|
|
<Grid item xs={6}>
|
|
|
|
},
|
|
|
|
<TextField
|
|
|
|
ticks: {
|
|
|
|
fullWidth
|
|
|
|
callback: function (value, index, ticks) {
|
|
|
|
label="Strike % From Underlying Price"
|
|
|
|
return new Date((value as number) * 1000)
|
|
|
|
type="number"
|
|
|
|
.toISOString()
|
|
|
|
value={chosenStrikePercentageFromUnderlyingPrice.value}
|
|
|
|
.substring(0, 10);
|
|
|
|
onChange={handleStrikePercentageFromUnderlyingPriceChange}
|
|
|
|
},
|
|
|
|
InputProps={{ endAdornment: "%" }}
|
|
|
|
},
|
|
|
|
/>
|
|
|
|
min:
|
|
|
|
</Grid>
|
|
|
|
new Date(chosenLookbackPeriodStart.value).getTime() /
|
|
|
|
<Grid item xs={6}>
|
|
|
|
1000,
|
|
|
|
<TextField
|
|
|
|
max:
|
|
|
|
fullWidth
|
|
|
|
new Date(chosenLookbackPeriodEnd.value).getTime() /
|
|
|
|
label="Strike % Radius"
|
|
|
|
1000,
|
|
|
|
type="number"
|
|
|
|
|
|
|
|
value={chosenStrikePercentageFromUnderlyingPriceRadius.value}
|
|
|
|
|
|
|
|
onChange={
|
|
|
|
|
|
|
|
handleStrikePercentageFromUnderlyingPriceRadiusChange
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
InputProps={{ endAdornment: "%" }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
|
|
|
<TextField
|
|
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
|
|
label="Exit-to-Front-Month Days to Expiration"
|
|
|
|
|
|
|
|
type="number"
|
|
|
|
|
|
|
|
value={chosenExitToFrontExpiration.value}
|
|
|
|
|
|
|
|
onChange={handleExitToFrontExpirationChange}
|
|
|
|
|
|
|
|
InputProps={{ endAdornment: "Days" }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={6}>
|
|
|
|
|
|
|
|
<TextField
|
|
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
|
|
label="Lookback Period Start"
|
|
|
|
|
|
|
|
type="date"
|
|
|
|
|
|
|
|
value={chosenLookbackPeriodStart.value}
|
|
|
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
|
|
|
handleLookbackPeriodStartChange({
|
|
|
|
|
|
|
|
target: { value: e.target.value },
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
InputLabelProps={{ shrink: true }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={6}>
|
|
|
|
|
|
|
|
<TextField
|
|
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
|
|
label="Lookback Period End"
|
|
|
|
|
|
|
|
type="date"
|
|
|
|
|
|
|
|
value={chosenLookbackPeriodEnd.value}
|
|
|
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
|
|
|
handleLookbackPeriodEndChange({
|
|
|
|
|
|
|
|
target: { value: e.target.value },
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
InputLabelProps={{ shrink: true }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
</Paper>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={12} md={6}>
|
|
|
|
|
|
|
|
<Paper elevation={3} sx={{ p: 3, height: "100%" }}>
|
|
|
|
|
|
|
|
{chosenUnderlying.value !== null &&
|
|
|
|
|
|
|
|
historicalStockQuoteChartData.value.length > 0 ? (
|
|
|
|
|
|
|
|
<Scatter
|
|
|
|
|
|
|
|
data={{
|
|
|
|
|
|
|
|
datasets: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
label: "Stock Open Price",
|
|
|
|
|
|
|
|
data: historicalStockQuoteChartData.value,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
options={{
|
|
|
|
|
|
|
|
scales: {
|
|
|
|
|
|
|
|
x: {
|
|
|
|
|
|
|
|
title: {
|
|
|
|
|
|
|
|
display: true,
|
|
|
|
|
|
|
|
text: "Time",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
y: {
|
|
|
|
ticks: {
|
|
|
|
beginAtZero: false,
|
|
|
|
callback: (value, index, ticks) =>
|
|
|
|
ticks: {
|
|
|
|
new Date((value as number) * 1000)
|
|
|
|
callback: function (value, index, ticks) {
|
|
|
|
.toISOString()
|
|
|
|
return "$" + value.toString();
|
|
|
|
.substring(0, 10),
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
min:
|
|
|
|
|
|
|
|
new Date(chosenLookbackPeriodStart.value).getTime() /
|
|
|
|
|
|
|
|
1000,
|
|
|
|
|
|
|
|
max:
|
|
|
|
|
|
|
|
new Date(chosenLookbackPeriodEnd.value).getTime() /
|
|
|
|
|
|
|
|
1000,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
elements: {
|
|
|
|
y: {
|
|
|
|
point: {
|
|
|
|
beginAtZero: false,
|
|
|
|
radius: 1,
|
|
|
|
ticks: {
|
|
|
|
borderWidth: 0,
|
|
|
|
callback: (value, index, ticks) =>
|
|
|
|
|
|
|
|
`$${value.toString()}`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
plugins: {
|
|
|
|
},
|
|
|
|
tooltip: {
|
|
|
|
elements: {
|
|
|
|
enabled: false,
|
|
|
|
point: {
|
|
|
|
},
|
|
|
|
radius: 1,
|
|
|
|
legend: {
|
|
|
|
borderWidth: 0,
|
|
|
|
display: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
plugins: {
|
|
|
|
|
|
|
|
tooltip: {
|
|
|
|
|
|
|
|
enabled: false,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
legend: {
|
|
|
|
|
|
|
|
display: false,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
title: {
|
|
|
|
|
|
|
|
display: true,
|
|
|
|
|
|
|
|
text: "Stock Price",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
animation: false,
|
|
|
|
|
|
|
|
maintainAspectRatio: false,
|
|
|
|
|
|
|
|
events: [],
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
) : (
|
|
|
|
|
|
|
|
<Typography>Loading Chart...</Typography>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</Paper>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
|
|
|
<Paper elevation={3} sx={{ p: 3 }}>
|
|
|
|
|
|
|
|
{chosenUnderlying.value !== null &&
|
|
|
|
|
|
|
|
historicalCalendarQuoteChartData.value.length > 0 ? (
|
|
|
|
|
|
|
|
<Scatter
|
|
|
|
|
|
|
|
data={{
|
|
|
|
|
|
|
|
datasets: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
label: "Calendar Open Price",
|
|
|
|
|
|
|
|
data: historicalCalendarQuoteChartData.value,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
options={{
|
|
|
|
|
|
|
|
scales: {
|
|
|
|
|
|
|
|
x: {
|
|
|
|
title: {
|
|
|
|
title: {
|
|
|
|
display: true,
|
|
|
|
display: true,
|
|
|
|
text: "Stock Price",
|
|
|
|
text: "Time",
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
animation: false,
|
|
|
|
|
|
|
|
maintainAspectRatio: false,
|
|
|
|
|
|
|
|
events: [],
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
) : (
|
|
|
|
|
|
|
|
<Typography>Loading Chart...</Typography>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</Paper>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
|
|
|
<Paper elevation={3} sx={{ p: 3 }}>
|
|
|
|
|
|
|
|
{chosenUnderlying.value !== null &&
|
|
|
|
|
|
|
|
historicalCalendarQuoteChartData.value.length > 0 ? (
|
|
|
|
|
|
|
|
<Scatter
|
|
|
|
|
|
|
|
data={{
|
|
|
|
|
|
|
|
datasets: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
label: "Calendar Open Price",
|
|
|
|
|
|
|
|
data: historicalCalendarQuoteChartData.value,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
options={{
|
|
|
|
|
|
|
|
scales: {
|
|
|
|
|
|
|
|
x: {
|
|
|
|
|
|
|
|
title: {
|
|
|
|
|
|
|
|
display: true,
|
|
|
|
|
|
|
|
text: "Time",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
ticks: {
|
|
|
|
|
|
|
|
callback: function (value, index, ticks) {
|
|
|
|
|
|
|
|
return new Date((value as number) * 1000)
|
|
|
|
|
|
|
|
.toISOString()
|
|
|
|
|
|
|
|
.substring(0, 10);
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
min:
|
|
|
|
|
|
|
|
new Date(chosenLookbackPeriodStart.value).getTime() /
|
|
|
|
|
|
|
|
1000,
|
|
|
|
|
|
|
|
max:
|
|
|
|
|
|
|
|
new Date(chosenLookbackPeriodEnd.value).getTime() /
|
|
|
|
|
|
|
|
1000,
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
y: {
|
|
|
|
ticks: {
|
|
|
|
beginAtZero: true,
|
|
|
|
callback: (value, index, ticks) =>
|
|
|
|
ticks: {
|
|
|
|
new Date((value as number) * 1000)
|
|
|
|
callback: function (value, index, ticks) {
|
|
|
|
.toISOString()
|
|
|
|
return "$" + value.toString();
|
|
|
|
.substring(0, 10),
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
min: 0,
|
|
|
|
|
|
|
|
max: maxChartPrice.value,
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
min:
|
|
|
|
|
|
|
|
new Date(chosenLookbackPeriodStart.value).getTime() /
|
|
|
|
|
|
|
|
1000,
|
|
|
|
|
|
|
|
max:
|
|
|
|
|
|
|
|
new Date(chosenLookbackPeriodEnd.value).getTime() /
|
|
|
|
|
|
|
|
1000,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
plugins: {
|
|
|
|
y: {
|
|
|
|
tooltip: {
|
|
|
|
beginAtZero: true,
|
|
|
|
enabled: false,
|
|
|
|
ticks: {
|
|
|
|
},
|
|
|
|
callback: (value, index, ticks) =>
|
|
|
|
legend: {
|
|
|
|
`$${value.toString()}`,
|
|
|
|
display: false,
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
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: [],
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
) : (
|
|
|
|
|
|
|
|
<Typography>Loading Chart...</Typography>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</Paper>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
|
|
|
<Paper elevation={3} sx={{ p: 3 }}>
|
|
|
|
|
|
|
|
{chosenUnderlying.value !== null &&
|
|
|
|
|
|
|
|
historicalCalendarQuoteChartData.value.length > 0 ? (
|
|
|
|
|
|
|
|
<Scatter
|
|
|
|
|
|
|
|
data={{
|
|
|
|
|
|
|
|
datasets: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
label: "Calendar Exit Price",
|
|
|
|
|
|
|
|
data: historicalCalendarExitQuoteChartData.value,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
options={{
|
|
|
|
|
|
|
|
scales: {
|
|
|
|
|
|
|
|
x: {
|
|
|
|
|
|
|
|
type: "linear",
|
|
|
|
|
|
|
|
beginAtZero: false,
|
|
|
|
title: {
|
|
|
|
title: {
|
|
|
|
display: true,
|
|
|
|
display: true,
|
|
|
|
text: "Calendar Price (Under Like Conditions)",
|
|
|
|
text: "%-From-the-Money",
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
animation: false,
|
|
|
|
|
|
|
|
maintainAspectRatio: false,
|
|
|
|
|
|
|
|
events: [],
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
) : (
|
|
|
|
|
|
|
|
<Typography>Loading Chart...</Typography>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</Paper>
|
|
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={12}>
|
|
|
|
|
|
|
|
<Paper elevation={3} sx={{ p: 3 }}>
|
|
|
|
|
|
|
|
{chosenUnderlying.value !== null &&
|
|
|
|
|
|
|
|
historicalCalendarQuoteChartData.value.length > 0 ? (
|
|
|
|
|
|
|
|
<Scatter
|
|
|
|
|
|
|
|
data={{
|
|
|
|
|
|
|
|
datasets: [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
label: "Calendar Exit Price",
|
|
|
|
|
|
|
|
data: historicalCalendarExitQuoteChartData.value,
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
],
|
|
|
|
ticks: {
|
|
|
|
}}
|
|
|
|
callback: (value, index, ticks) =>
|
|
|
|
options={{
|
|
|
|
`${value.toString()}%`,
|
|
|
|
scales: {
|
|
|
|
|
|
|
|
x: {
|
|
|
|
|
|
|
|
type: "linear",
|
|
|
|
|
|
|
|
beginAtZero: false,
|
|
|
|
|
|
|
|
title: {
|
|
|
|
|
|
|
|
display: true,
|
|
|
|
|
|
|
|
text: "%-From-the-Money",
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
ticks: {
|
|
|
|
|
|
|
|
callback: function (value, index, ticks) {
|
|
|
|
|
|
|
|
return value.toString() + "%";
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
y: {
|
|
|
|
|
|
|
|
beginAtZero: true,
|
|
|
|
|
|
|
|
ticks: {
|
|
|
|
|
|
|
|
callback: function (value, index, ticks) {
|
|
|
|
|
|
|
|
return "$" + value.toString();
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
min: 0,
|
|
|
|
|
|
|
|
max: maxChartPrice.value,
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
elements: {
|
|
|
|
y: {
|
|
|
|
point: {
|
|
|
|
beginAtZero: true,
|
|
|
|
borderWidth: 0,
|
|
|
|
ticks: {
|
|
|
|
backgroundColor: function (context) {
|
|
|
|
callback: (value, index, ticks) =>
|
|
|
|
const n = (
|
|
|
|
`$${value.toString()}`,
|
|
|
|
context.raw as { x: number; y: number; n: number }
|
|
|
|
|
|
|
|
).n;
|
|
|
|
|
|
|
|
const alpha = n / maxN.value;
|
|
|
|
|
|
|
|
return `rgba(0, 0, 0, ${alpha})`;
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
min: 0,
|
|
|
|
|
|
|
|
max: maxChartPrice.value,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
plugins: {
|
|
|
|
},
|
|
|
|
tooltip: {
|
|
|
|
elements: {
|
|
|
|
enabled: false,
|
|
|
|
point: {
|
|
|
|
},
|
|
|
|
borderWidth: 0,
|
|
|
|
legend: {
|
|
|
|
backgroundColor: (context) => {
|
|
|
|
display: false,
|
|
|
|
const n = (
|
|
|
|
},
|
|
|
|
context.raw as { x: number; y: number; n: number }
|
|
|
|
title: {
|
|
|
|
).n;
|
|
|
|
display: true,
|
|
|
|
const alpha = n / maxN.value;
|
|
|
|
text: [
|
|
|
|
return `rgba(0, 0, 0, ${alpha})`;
|
|
|
|
"Calendar Prices at Exit",
|
|
|
|
|
|
|
|
"by %-age from-the-money",
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
animation: false,
|
|
|
|
},
|
|
|
|
maintainAspectRatio: false,
|
|
|
|
plugins: {
|
|
|
|
events: [],
|
|
|
|
tooltip: {
|
|
|
|
}}
|
|
|
|
enabled: false,
|
|
|
|
/>
|
|
|
|
},
|
|
|
|
) : (
|
|
|
|
legend: {
|
|
|
|
<Typography>Loading Chart...</Typography>
|
|
|
|
display: false,
|
|
|
|
)}
|
|
|
|
},
|
|
|
|
</Paper>
|
|
|
|
title: {
|
|
|
|
</Grid>
|
|
|
|
display: true,
|
|
|
|
|
|
|
|
text: [
|
|
|
|
|
|
|
|
"Calendar Prices at Exit",
|
|
|
|
|
|
|
|
"by %-age from-the-money",
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
animation: false,
|
|
|
|
|
|
|
|
maintainAspectRatio: false,
|
|
|
|
|
|
|
|
events: [],
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
) : (
|
|
|
|
|
|
|
|
<Typography>Loading Chart...</Typography>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</Paper>
|
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
</Container>
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
</Container>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|