use lmdbx for stockdb in backtest, and limit to calendars within 5% of the money
This commit is contained in:
+23
-22
@@ -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,
|
||||
tsStart: stockAggregate.tsStart,
|
||||
});
|
||||
// console.log(
|
||||
// "Calendar Aggregates:",
|
||||
// calendar,
|
||||
// calendarAggregates.length,
|
||||
// );
|
||||
const calendarAggregateAtCurrentTime = calendarAggregates.find(
|
||||
({ 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"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user