Compare commits

...

3 Commits

Author SHA1 Message Date
avraham c83f2ce0a0 use Slider for lookback period 2025-03-03 21:35:51 -05:00
avraham 4d989f10eb gitignore Bruno files 2025-03-02 17:54:41 -05:00
avraham 906e63eb91 use line on stock price chart; more compact data transfer format 2025-03-02 17:53:59 -05:00
6 changed files with 116 additions and 15 deletions
@@ -5,6 +5,7 @@ import {
LinearScale, LinearScale,
CategoryScale, CategoryScale,
PointElement, PointElement,
LineElement,
Tooltip, Tooltip,
Title, Title,
} from "chart.js"; } from "chart.js";
@@ -42,10 +43,16 @@ import { EditableUnderlying } from "./HistoricalCalendarPrices/EditableUnderlyin
import { EditableOpenDTE } from "./HistoricalCalendarPrices/EditableOpenDTE.js"; import { EditableOpenDTE } from "./HistoricalCalendarPrices/EditableOpenDTE.js";
import { EditableExitDTE } from "./HistoricalCalendarPrices/EditableExitDTE.js"; import { EditableExitDTE } from "./HistoricalCalendarPrices/EditableExitDTE.js";
import { EditableSpan } from "./HistoricalCalendarPrices/EditableSpan.js"; import { EditableSpan } from "./HistoricalCalendarPrices/EditableSpan.js";
import { EditableLookbackPeriodStart } from "./HistoricalCalendarPrices/EditableLookbackPeriodStart.js"; import { EditableLookbackPeriod } from "./HistoricalCalendarPrices/EditableLookbackPeriod.js";
import { EditableLookbackPeriodEnd } from "./HistoricalCalendarPrices/EditableLookbackPeriodEnd.js";
ChartJS.register(LinearScale, CategoryScale, PointElement, Tooltip, Title); ChartJS.register(
LinearScale,
CategoryScale,
PointElement,
LineElement,
Tooltip,
Title
);
const handleInit = () => { const handleInit = () => {
trpc.CalendarCharacteristicsForm.getAvailableUnderlyings trpc.CalendarCharacteristicsForm.getAvailableUnderlyings
@@ -125,8 +132,7 @@ export function HistoricalCalendarPrices() {
<Typography gutterBottom minWidth={"8em"}> <Typography gutterBottom minWidth={"8em"}>
Lookback Period Lookback Period
</Typography> </Typography>
<EditableLookbackPeriodStart />- <EditableLookbackPeriod />
<EditableLookbackPeriodEnd />
</Stack> </Stack>
<ClickAwayListener <ClickAwayListener
onClickAway={() => { onClickAway={() => {
@@ -292,6 +298,8 @@ export function HistoricalCalendarPrices() {
], ],
}} }}
options={{ options={{
showLine: true,
normalized: true,
scales: { scales: {
x: { x: {
title: { title: {
@@ -317,9 +325,12 @@ export function HistoricalCalendarPrices() {
}, },
elements: { elements: {
point: { point: {
radius: 1, radius: 2,
borderWidth: 0, borderWidth: 0,
}, },
line: {
borderWidth: 2,
},
}, },
plugins: { plugins: {
tooltip: { tooltip: {
@@ -0,0 +1,66 @@
import TextField from "@mui/material/TextField";
import {
refreshcalendarExitPriceChartData,
refreshSimilarCalendarPriceChartData,
refreshStockPriceChartData,
} from "./actions";
import { lookbackPeriodEnd, lookbackPeriodStart } from "./state";
import Slider from "@mui/material/Slider";
const handleLookbackPeriodChange = (
e,
[newLookbackPeriodStart, newLookbackPeriodEnd]: [number, number]
) => {
const [lookbackPeriodStartUnixTime, lookbackPeriodEndUnixTime] = [
new Date(lookbackPeriodStart.value).getTime(),
new Date(lookbackPeriodEnd.value).getTime(),
];
if (lookbackPeriodStartUnixTime !== newLookbackPeriodStart) {
lookbackPeriodStart.value = new Date(newLookbackPeriodStart)
.toISOString()
.substring(0, 10);
refreshStockPriceChartData();
refreshSimilarCalendarPriceChartData();
refreshcalendarExitPriceChartData();
}
if (lookbackPeriodEndUnixTime !== newLookbackPeriodEnd) {
lookbackPeriodEnd.value = new Date(newLookbackPeriodEnd)
.toISOString()
.substring(0, 10);
refreshStockPriceChartData();
refreshSimilarCalendarPriceChartData();
refreshcalendarExitPriceChartData();
}
};
const earliestDate = new Date("2022-03-07");
const DAY = 1000 * 60 * 60 * 24;
function addDays(date, days) {
const result = new Date(date);
result.setDate(result.getDate() + days);
return result.toISOString().substring(0, 10);
}
function daysBetween(date1, date2) {
return Math.round(Math.abs((date2.getTime() - date1.getTime()) / DAY));
}
export function EditableLookbackPeriod() {
return (
<Slider
value={[
new Date(lookbackPeriodStart.value).getTime(),
new Date(lookbackPeriodEnd.value).getTime(),
]}
onChange={handleLookbackPeriodChange}
valueLabelFormat={(unixTimeMs) =>
new Date(unixTimeMs).toISOString().substring(0, 10)
}
getAriaValueText={(unixTimeMs) =>
new Date(unixTimeMs).toISOString().substring(0, 10)
}
min={earliestDate.getTime()}
max={earliestDate.getTime() + 250 * DAY}
step={DAY}
valueLabelDisplay="on"
/>
);
}
@@ -13,7 +13,29 @@ import {
underlying, underlying,
} from "./state"; } from "./state";
export const refreshStockPriceChartData = () => { function debounce(func, wait) {
let timeout;
return function () {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), wait);
};
}
function throttle(func, limit) {
let inThrottle;
return function () {
const context = this;
const args = arguments;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => (inThrottle = false), limit);
}
};
}
export const refreshStockPriceChartData = throttle(() => {
stockPriceChartData.value = []; stockPriceChartData.value = [];
trpc.StockPriceChart.getChartData trpc.StockPriceChart.getChartData
.query({ .query({
@@ -24,8 +46,8 @@ export const refreshStockPriceChartData = () => {
.then((getChartDataResponse) => { .then((getChartDataResponse) => {
stockPriceChartData.value = getChartDataResponse; stockPriceChartData.value = getChartDataResponse;
}); });
}; }, 400);
export const refreshSimilarCalendarPriceChartData = () => { export const refreshSimilarCalendarPriceChartData = throttle(() => {
similarCalendarPriceChartData.value = []; similarCalendarPriceChartData.value = [];
trpc.SimilarCalendarPriceChart.getChartData trpc.SimilarCalendarPriceChart.getChartData
.query({ .query({
@@ -42,8 +64,8 @@ export const refreshSimilarCalendarPriceChartData = () => {
.then((getChartDataResponse) => { .then((getChartDataResponse) => {
similarCalendarPriceChartData.value = getChartDataResponse; similarCalendarPriceChartData.value = getChartDataResponse;
}); });
}; }, 400);
export const refreshcalendarExitPriceChartData = () => { export const refreshcalendarExitPriceChartData = throttle(() => {
calendarExitPriceChartData.value = []; calendarExitPriceChartData.value = [];
trpc.CalendarExitPriceChart.getChartData trpc.CalendarExitPriceChart.getChartData
.query({ .query({
@@ -56,4 +78,4 @@ export const refreshcalendarExitPriceChartData = () => {
.then((getChartDataResponse) => { .then((getChartDataResponse) => {
calendarExitPriceChartData.value = getChartDataResponse; calendarExitPriceChartData.value = getChartDataResponse;
}); });
}; }, 400);
@@ -16,7 +16,7 @@ export const moninessRadius = signal(1);
export const exitDTE = signal(2); export const exitDTE = signal(2);
export const stockPriceChartData = signal([]); export const stockPriceChartData = signal<Array<[number, number]>>([]);
export const similarCalendarPriceChartData = signal([]); export const similarCalendarPriceChartData = signal([]);
+1
View File
@@ -27,3 +27,4 @@ dist-ssr
.env .env
*.db *.db
*.db-lck *.db-lck
Calendar tRPC
+2 -1
View File
@@ -26,7 +26,8 @@ export const getChartData = publicProcedure
GROUP BY x GROUP BY x
ORDER BY x ASC ORDER BY x ASC
`, `,
"JSONEachRow" "JSONCompactEachRow"
// "JSONEachRow"
); );
}); });