From 15a5d7c67b90e4111bcbb5faac4dc17a62d5edf7 Mon Sep 17 00:00:00 2001 From: avraham Date: Sun, 11 Aug 2024 17:39:34 -0400 Subject: [PATCH] use lmdbx for stockdb in backtest, and limit to calendars within 5% of the money --- server/src/backtest.ts | 47 +++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/server/src/backtest.ts b/server/src/backtest.ts index dde5a56..98572aa 100644 --- a/server/src/backtest.ts +++ b/server/src/backtest.ts @@ -1,7 +1,6 @@ -import { stockDatabase } from "./stockdb/clickhouse.js"; +import { stockDatabase } from "./stockdb/lmdbx.js"; import { calendarDatabase } from "./calendardb/optiondb-lmdbx.js"; import type { CalendarKey } from "./calendardb/interfaces.js"; -import type { Aggregate } from "./interfaces.js"; import { nextDate } from "./lib/utils/nextDate.js"; type BacktestInput = { @@ -38,49 +37,51 @@ export async function backtest({ // for each minute of that day for which we have a stock candlestick: for (const stockAggregate of stockAggregates) { // console.log("Current Time:", new Date(stockAggregate.tsStart)); - // filter-out calendars that are far-from-the-money (10%) - console.log("Current Date:", date, stockAggregate.tsStart); + // filter-out calendars that are far-from-the-money (5%) const calendarsNearTheMoney = calendars.filter( ({ strike }) => - Math.abs((stockAggregate.open - strike) / stockAggregate.open) < 0.1, + Math.abs((stockAggregate.open - strike) / stockAggregate.open) < 0.05 + ); + console.log( + "Current Date:", + new Intl.DateTimeFormat("en-US", { + timeZone: "America/New_York", + dateStyle: "full", + timeStyle: "long", + }).format(new Date(stockAggregate.tsStart)), + ";", + `${calendarsNearTheMoney.length} Calendars Near The Money` ); // for each relevant calendar on that day: for (const calendar of calendarsNearTheMoney) { const strikePercentageFromTheMoney = Math.abs( - (stockAggregate.open - calendar.strike) / stockAggregate.open, + (stockAggregate.open - calendar.strike) / stockAggregate.open ); - /** In days. */ - const calendarSpan = + /** Number of days between the back and front expiration dates. */ + const calendarSpanInDays = (new Date(calendar.backExpirationDate).valueOf() - new Date(calendar.frontExpirationDate).valueOf()) / (1000 * 60 * 60 * 24); const targetCalendarPrice = await calendarDatabase.getTargetPriceByProbability({ symbol, - calendarSpan, + calendarSpan: calendarSpanInDays, strikePercentageFromTheMoney, historicalProbabilityOfSuccess, }); - const calendarAggregates = calendarDatabase.getAggregatesSync({ + const calendarAggregateAtCurrentTime = + await calendarDatabase.getAggregate({ key: { ...calendar, }, - date, - }); - // console.log( - // "Calendar Aggregates:", - // calendar, - // calendarAggregates.length, - // ); - const calendarAggregateAtCurrentTime = calendarAggregates.find( - ({ tsStart }) => tsStart === stockAggregate.tsStart, - ); + tsStart: stockAggregate.tsStart, + }); // if there exists a matching calendar candlestick for the current minute: if (calendarAggregateAtCurrentTime) { // if the current candlestick is a good price (i.e. less than the target price): const minCalendarPriceInCandlestick = Math.min( calendarAggregateAtCurrentTime.open, - calendarAggregateAtCurrentTime.close, + calendarAggregateAtCurrentTime.close ); if ( minCalendarPriceInCandlestick < targetCalendarPrice && @@ -99,7 +100,7 @@ export async function backtest({ minCalendarPriceInCandlestick * 100, "...$", buyingPower, - "left", + "left" ); didBuyCalendar = true; } @@ -131,7 +132,7 @@ export async function backtest({ calendarClosingPrice, "...$", buyingPower, - "left", + "left" ); } }