@ -5,151 +5,151 @@ import type { CalendarDatabase } from "./calendardb.interfaces.js";
const MAXIMUM_KEY = Buffer . from ( [ 0xff ] ) ;
function makeCalendarDatabase ( ) : CalendarDatabase {
const calendarDatabase : Omit < CalendarDatabase , " getCalendars " > = {
getKeys : async ( { key : { symbol } , date } ) = > {
const optionContracts = await optionContractDatabase . getOptionContracts ( {
date ,
key : { symbol } ,
} ) ;
return optionContracts . flatMap (
( frontOptionContract , i , optionContracts ) = >
optionContracts
. filter ( ( _ , j ) = > i !== j )
. map ( ( backOptionContract ) = > ( {
symbol ,
frontExpirationDate : frontOptionContract.expirationDate ,
backExpirationDate : backOptionContract.expirationDate ,
strike : frontOptionContract.strike ,
type : frontOptionContract . type ,
} ) ) ,
) ;
} ,
getAggregates : async ( {
key : { symbol , frontExpirationDate , backExpirationDate , strike , type } ,
date ,
} ) = > {
const frontOptionContractAggregates =
await optionContractDatabase . getAggregates ( {
date ,
key : { symbol , expirationDate : frontExpirationDate , strike , type } ,
} ) ;
const backOptionContractAggregates =
await optionContractDatabase . getAggregates ( {
date ,
key : { symbol , expirationDate : backExpirationDate , strike , type } ,
} ) ;
const calendarAggregates = [ ] ;
let i = 0 ;
let j = 0 ;
while (
i < frontOptionContractAggregates . length &&
j < backOptionContractAggregates . length
) {
if (
frontOptionContractAggregates [ i ] . tsStart ===
backOptionContractAggregates [ j ] . tsStart
) {
calendarAggregates . push ( {
tsStart : frontOptionContractAggregates [ i ] . tsStart ,
open :
backOptionContractAggregates [ j ] . open -
frontOptionContractAggregates [ i ] . open ,
close :
backOptionContractAggregates [ j ] . close -
frontOptionContractAggregates [ i ] . close ,
// the high and low are not exactly correct since we don't know if each contract's high and low happened at a the same moment as the other:
high :
backOptionContractAggregates [ j ] . high -
frontOptionContractAggregates [ i ] . high ,
low :
backOptionContractAggregates [ j ] . low -
frontOptionContractAggregates [ i ] . low ,
} ) ;
i ++ ;
j ++ ;
} else if (
frontOptionContractAggregates [ i ] . tsStart >
backOptionContractAggregates [ j ] . tsStart
) {
j ++ ;
} else {
i ++ ;
}
}
return calendarAggregates ;
} ,
insertAggregates : async ( aggregates ) = > {
// right now, no-op
} ,
getClosingPrice : async ( {
key : { symbol , strike , type , frontExpirationDate , backExpirationDate } ,
} ) = > {
const startOfLastHourUnix = new Date (
` ${ frontExpirationDate } T00:00:00Z ` ,
) . valueOf ( ) ;
const endOfLastHourUnix = startOfLastHourUnix + 3600 * 1000 ;
const frontOptionContractAggregates = (
await optionContractDatabase . getAggregates ( {
date : frontExpirationDate ,
key : { symbol , expirationDate : frontExpirationDate , strike , type } ,
} )
) . filter (
( { tsStart } ) = >
tsStart >= startOfLastHourUnix && tsStart < endOfLastHourUnix ,
) ;
const backOptionContractAggregates = (
await optionContractDatabase . getAggregates ( {
date : frontExpirationDate ,
key : { symbol , expirationDate : backExpirationDate , strike , type } ,
} )
) . filter (
( { tsStart } ) = >
tsStart >= startOfLastHourUnix && tsStart < endOfLastHourUnix ,
) ;
let i = 0 ;
let j = 0 ;
let minPrice = 0 ;
while (
i < frontOptionContractAggregates . length &&
j < backOptionContractAggregates . length
) {
if (
frontOptionContractAggregates [ i ] . tsStart ===
backOptionContractAggregates [ j ] . tsStart
) {
const calendarClosePrice =
backOptionContractAggregates [ j ] . close -
frontOptionContractAggregates [ j ] . close ;
if ( calendarClosePrice < minPrice || minPrice === 0 ) {
minPrice = calendarClosePrice ;
}
i ++ ;
j ++ ;
} else if (
frontOptionContractAggregates [ i ] . tsStart >
backOptionContractAggregates [ j ] . tsStart
) {
j ++ ;
} else {
i ++ ;
}
}
return minPrice ;
} ,
getTargetPriceByProbability : async ( {
symbol ,
calendarSpan ,
strikePercentageFromTheMoney ,
historicalProbabilityOfSuccess ,
} ) = > {
return 0.24 ;
} ,
} ;
const calendarDatabase : Omit < CalendarDatabase , " getCalendars " > = {
getKeys : async ( { key : { symbol } , date } ) = > {
const optionContracts = await optionContractDatabase . getOptionContracts ( {
date ,
key : { symbol } ,
} ) ;
return optionContracts . flatMap (
( frontOptionContract , i , optionContracts ) = >
optionContracts
. filter ( ( _ , j ) = > i !== j )
. map ( ( backOptionContract ) = > ( {
symbol ,
frontExpirationDate : frontOptionContract.expirationDate ,
backExpirationDate : backOptionContract.expirationDate ,
strike : frontOptionContract.strike ,
type : frontOptionContract . type ,
} ) ) ,
) ;
} ,
getAggregates : async ( {
key : { symbol , frontExpirationDate , backExpirationDate , strike , type } ,
date ,
} ) = > {
const frontOptionContractAggregates =
await optionContractDatabase . getAggregates ( {
date ,
key : { symbol , expirationDate : frontExpirationDate , strike , type } ,
} ) ;
const backOptionContractAggregates =
await optionContractDatabase . getAggregates ( {
date ,
key : { symbol , expirationDate : backExpirationDate , strike , type } ,
} ) ;
const calendarAggregates = [ ] ;
let i = 0 ;
let j = 0 ;
while (
i < frontOptionContractAggregates . length &&
j < backOptionContractAggregates . length
) {
if (
frontOptionContractAggregates [ i ] . tsStart ===
backOptionContractAggregates [ j ] . tsStart
) {
calendarAggregates . push ( {
tsStart : frontOptionContractAggregates [ i ] . tsStart ,
open :
backOptionContractAggregates [ j ] . open -
frontOptionContractAggregates [ i ] . open ,
close :
backOptionContractAggregates [ j ] . close -
frontOptionContractAggregates [ i ] . close ,
// the high and low are not exactly correct since we don't know if each contract's high and low happened at the same moment as the other:
high :
backOptionContractAggregates [ j ] . high -
frontOptionContractAggregates [ i ] . high ,
low :
backOptionContractAggregates [ j ] . low -
frontOptionContractAggregates [ i ] . low ,
} ) ;
i ++ ;
j ++ ;
} else if (
frontOptionContractAggregates [ i ] . tsStart >
backOptionContractAggregates [ j ] . tsStart
) {
j ++ ;
} else {
i ++ ;
}
}
return calendarAggregates ;
} ,
insertAggregates : async ( aggregates ) = > {
// right now, no-op
} ,
getClosingPrice : async ( {
key : { symbol , strike , type , frontExpirationDate , backExpirationDate } ,
} ) = > {
const startOfLastHourUnix = new Date (
` ${ frontExpirationDate } T00:00:00Z ` ,
) . valueOf ( ) ;
const endOfLastHourUnix = startOfLastHourUnix + 3600 * 1000 ;
const frontOptionContractAggregates = (
await optionContractDatabase . getAggregates ( {
date : frontExpirationDate ,
key : { symbol , expirationDate : frontExpirationDate , strike , type } ,
} )
) . filter (
( { tsStart } ) = >
tsStart >= startOfLastHourUnix && tsStart < endOfLastHourUnix ,
) ;
const backOptionContractAggregates = (
await optionContractDatabase . getAggregates ( {
date : frontExpirationDate ,
key : { symbol , expirationDate : backExpirationDate , strike , type } ,
} )
) . filter (
( { tsStart } ) = >
tsStart >= startOfLastHourUnix && tsStart < endOfLastHourUnix ,
) ;
let i = 0 ;
let j = 0 ;
let minPrice = 0 ;
while (
i < frontOptionContractAggregates . length &&
j < backOptionContractAggregates . length
) {
if (
frontOptionContractAggregates [ i ] . tsStart ===
backOptionContractAggregates [ j ] . tsStart
) {
const calendarClosePrice =
backOptionContractAggregates [ j ] . close -
frontOptionContractAggregates [ j ] . close ;
if ( calendarClosePrice < minPrice || minPrice === 0 ) {
minPrice = calendarClosePrice ;
}
i ++ ;
j ++ ;
} else if (
frontOptionContractAggregates [ i ] . tsStart >
backOptionContractAggregates [ j ] . tsStart
) {
j ++ ;
} else {
i ++ ;
}
}
return minPrice ;
} ,
getTargetPriceByProbability : async ( {
symbol ,
calendarSpan ,
strikePercentageFromTheMoney ,
historicalProbabilityOfSuccess ,
} ) = > {
return 0.24 ;
} ,
} ;
return {
. . . calendarDatabase ,
getCalendars : calendarDatabase.getKeys ,
} ;
return {
. . . calendarDatabase ,
getCalendars : calendarDatabase.getKeys ,
} ;
}
export const calendarDatabase : CalendarDatabase = makeCalendarDatabase ( ) ;