Expand synthetic data across S&P 500
Add S&P 500 symbol list and expand synthetic options/equities feeds with varied contracts, sizes, and bursts to keep alerts firing.
This commit is contained in:
parent
41bdd2c73a
commit
7996d00677
4 changed files with 643 additions and 26 deletions
|
|
@ -1 +1,2 @@
|
||||||
export * from "./events";
|
export * from "./events";
|
||||||
|
export * from "./sp500";
|
||||||
|
|
|
||||||
507
packages/types/src/sp500.ts
Normal file
507
packages/types/src/sp500.ts
Normal file
|
|
@ -0,0 +1,507 @@
|
||||||
|
export const SP500_SYMBOLS = [
|
||||||
|
"MMM",
|
||||||
|
"AOS",
|
||||||
|
"ABT",
|
||||||
|
"ABBV",
|
||||||
|
"ACN",
|
||||||
|
"ADBE",
|
||||||
|
"AMD",
|
||||||
|
"AES",
|
||||||
|
"AFL",
|
||||||
|
"A",
|
||||||
|
"APD",
|
||||||
|
"ABNB",
|
||||||
|
"AKAM",
|
||||||
|
"ALB",
|
||||||
|
"ARE",
|
||||||
|
"ALGN",
|
||||||
|
"ALLE",
|
||||||
|
"LNT",
|
||||||
|
"ALL",
|
||||||
|
"GOOGL",
|
||||||
|
"GOOG",
|
||||||
|
"MO",
|
||||||
|
"AMZN",
|
||||||
|
"AMCR",
|
||||||
|
"AEE",
|
||||||
|
"AEP",
|
||||||
|
"AXP",
|
||||||
|
"AIG",
|
||||||
|
"AMT",
|
||||||
|
"AWK",
|
||||||
|
"AMP",
|
||||||
|
"AME",
|
||||||
|
"AMGN",
|
||||||
|
"APH",
|
||||||
|
"ADI",
|
||||||
|
"AON",
|
||||||
|
"APA",
|
||||||
|
"APO",
|
||||||
|
"AAPL",
|
||||||
|
"AMAT",
|
||||||
|
"APTV",
|
||||||
|
"ACGL",
|
||||||
|
"ADM",
|
||||||
|
"ANET",
|
||||||
|
"AJG",
|
||||||
|
"AIZ",
|
||||||
|
"T",
|
||||||
|
"ATO",
|
||||||
|
"ADSK",
|
||||||
|
"ADP",
|
||||||
|
"AZO",
|
||||||
|
"AVB",
|
||||||
|
"AVY",
|
||||||
|
"AXON",
|
||||||
|
"BKR",
|
||||||
|
"BALL",
|
||||||
|
"BAC",
|
||||||
|
"BAX",
|
||||||
|
"BDX",
|
||||||
|
"BRK.B",
|
||||||
|
"BBY",
|
||||||
|
"TECH",
|
||||||
|
"BIIB",
|
||||||
|
"BLK",
|
||||||
|
"BX",
|
||||||
|
"XYZ",
|
||||||
|
"BK",
|
||||||
|
"BA",
|
||||||
|
"BKNG",
|
||||||
|
"BSX",
|
||||||
|
"BMY",
|
||||||
|
"AVGO",
|
||||||
|
"BR",
|
||||||
|
"BRO",
|
||||||
|
"BF.B",
|
||||||
|
"BLDR",
|
||||||
|
"BG",
|
||||||
|
"BXP",
|
||||||
|
"CHRW",
|
||||||
|
"CDNS",
|
||||||
|
"CZR",
|
||||||
|
"CPT",
|
||||||
|
"CPB",
|
||||||
|
"COF",
|
||||||
|
"CAH",
|
||||||
|
"KMX",
|
||||||
|
"CCL",
|
||||||
|
"CARR",
|
||||||
|
"CAT",
|
||||||
|
"CBOE",
|
||||||
|
"CBRE",
|
||||||
|
"CDW",
|
||||||
|
"COR",
|
||||||
|
"CNC",
|
||||||
|
"CNP",
|
||||||
|
"CF",
|
||||||
|
"CRL",
|
||||||
|
"SCHW",
|
||||||
|
"CHTR",
|
||||||
|
"CVX",
|
||||||
|
"CMG",
|
||||||
|
"CB",
|
||||||
|
"CHD",
|
||||||
|
"CI",
|
||||||
|
"CINF",
|
||||||
|
"CTAS",
|
||||||
|
"CSCO",
|
||||||
|
"C",
|
||||||
|
"CFG",
|
||||||
|
"CLX",
|
||||||
|
"CME",
|
||||||
|
"CMS",
|
||||||
|
"KO",
|
||||||
|
"CTSH",
|
||||||
|
"COIN",
|
||||||
|
"CL",
|
||||||
|
"CMCSA",
|
||||||
|
"CAG",
|
||||||
|
"COP",
|
||||||
|
"ED",
|
||||||
|
"STZ",
|
||||||
|
"CEG",
|
||||||
|
"COO",
|
||||||
|
"CPRT",
|
||||||
|
"GLW",
|
||||||
|
"CPAY",
|
||||||
|
"CTVA",
|
||||||
|
"CSGP",
|
||||||
|
"COST",
|
||||||
|
"CTRA",
|
||||||
|
"CRWD",
|
||||||
|
"CCI",
|
||||||
|
"CSX",
|
||||||
|
"CMI",
|
||||||
|
"CVS",
|
||||||
|
"DHR",
|
||||||
|
"DRI",
|
||||||
|
"DDOG",
|
||||||
|
"DVA",
|
||||||
|
"DAY",
|
||||||
|
"DECK",
|
||||||
|
"DE",
|
||||||
|
"DELL",
|
||||||
|
"DAL",
|
||||||
|
"DVN",
|
||||||
|
"DXCM",
|
||||||
|
"FANG",
|
||||||
|
"DLR",
|
||||||
|
"DG",
|
||||||
|
"DLTR",
|
||||||
|
"D",
|
||||||
|
"DPZ",
|
||||||
|
"DASH",
|
||||||
|
"DOV",
|
||||||
|
"DOW",
|
||||||
|
"DHI",
|
||||||
|
"DTE",
|
||||||
|
"DUK",
|
||||||
|
"DD",
|
||||||
|
"EMN",
|
||||||
|
"ETN",
|
||||||
|
"EBAY",
|
||||||
|
"ECL",
|
||||||
|
"EIX",
|
||||||
|
"EW",
|
||||||
|
"EA",
|
||||||
|
"ELV",
|
||||||
|
"EMR",
|
||||||
|
"ENPH",
|
||||||
|
"ETR",
|
||||||
|
"EOG",
|
||||||
|
"EPAM",
|
||||||
|
"EQT",
|
||||||
|
"EFX",
|
||||||
|
"EQIX",
|
||||||
|
"EQR",
|
||||||
|
"ERIE",
|
||||||
|
"ESS",
|
||||||
|
"EL",
|
||||||
|
"EG",
|
||||||
|
"EVRG",
|
||||||
|
"ES",
|
||||||
|
"EXC",
|
||||||
|
"EXE",
|
||||||
|
"EXPE",
|
||||||
|
"EXPD",
|
||||||
|
"EXR",
|
||||||
|
"XOM",
|
||||||
|
"FFIV",
|
||||||
|
"FDS",
|
||||||
|
"FICO",
|
||||||
|
"FAST",
|
||||||
|
"FRT",
|
||||||
|
"FDX",
|
||||||
|
"FIS",
|
||||||
|
"FITB",
|
||||||
|
"FSLR",
|
||||||
|
"FE",
|
||||||
|
"FI",
|
||||||
|
"F",
|
||||||
|
"FTNT",
|
||||||
|
"FTV",
|
||||||
|
"FOXA",
|
||||||
|
"FOX",
|
||||||
|
"BEN",
|
||||||
|
"FCX",
|
||||||
|
"GRMN",
|
||||||
|
"IT",
|
||||||
|
"GE",
|
||||||
|
"GEHC",
|
||||||
|
"GEV",
|
||||||
|
"GEN",
|
||||||
|
"GNRC",
|
||||||
|
"GD",
|
||||||
|
"GIS",
|
||||||
|
"GM",
|
||||||
|
"GPC",
|
||||||
|
"GILD",
|
||||||
|
"GPN",
|
||||||
|
"GL",
|
||||||
|
"GDDY",
|
||||||
|
"GS",
|
||||||
|
"HAL",
|
||||||
|
"HIG",
|
||||||
|
"HAS",
|
||||||
|
"HCA",
|
||||||
|
"DOC",
|
||||||
|
"HSIC",
|
||||||
|
"HSY",
|
||||||
|
"HPE",
|
||||||
|
"HLT",
|
||||||
|
"HOLX",
|
||||||
|
"HD",
|
||||||
|
"HON",
|
||||||
|
"HRL",
|
||||||
|
"HST",
|
||||||
|
"HWM",
|
||||||
|
"HPQ",
|
||||||
|
"HUBB",
|
||||||
|
"HUM",
|
||||||
|
"HBAN",
|
||||||
|
"HII",
|
||||||
|
"IBM",
|
||||||
|
"IEX",
|
||||||
|
"IDXX",
|
||||||
|
"ITW",
|
||||||
|
"INCY",
|
||||||
|
"IR",
|
||||||
|
"PODD",
|
||||||
|
"INTC",
|
||||||
|
"ICE",
|
||||||
|
"IFF",
|
||||||
|
"IP",
|
||||||
|
"IPG",
|
||||||
|
"INTU",
|
||||||
|
"ISRG",
|
||||||
|
"IVZ",
|
||||||
|
"INVH",
|
||||||
|
"IQV",
|
||||||
|
"IRM",
|
||||||
|
"JBHT",
|
||||||
|
"JBL",
|
||||||
|
"JKHY",
|
||||||
|
"J",
|
||||||
|
"JNJ",
|
||||||
|
"JCI",
|
||||||
|
"JPM",
|
||||||
|
"K",
|
||||||
|
"KVUE",
|
||||||
|
"KDP",
|
||||||
|
"KEY",
|
||||||
|
"KEYS",
|
||||||
|
"KMB",
|
||||||
|
"KIM",
|
||||||
|
"KMI",
|
||||||
|
"KKR",
|
||||||
|
"KLAC",
|
||||||
|
"KHC",
|
||||||
|
"KR",
|
||||||
|
"LHX",
|
||||||
|
"LH",
|
||||||
|
"LRCX",
|
||||||
|
"LW",
|
||||||
|
"LVS",
|
||||||
|
"LDOS",
|
||||||
|
"LEN",
|
||||||
|
"LII",
|
||||||
|
"LLY",
|
||||||
|
"LIN",
|
||||||
|
"LYV",
|
||||||
|
"LKQ",
|
||||||
|
"LMT",
|
||||||
|
"L",
|
||||||
|
"LOW",
|
||||||
|
"LULU",
|
||||||
|
"LYB",
|
||||||
|
"MTB",
|
||||||
|
"MPC",
|
||||||
|
"MKTX",
|
||||||
|
"MAR",
|
||||||
|
"MMC",
|
||||||
|
"MLM",
|
||||||
|
"MAS",
|
||||||
|
"MA",
|
||||||
|
"MTCH",
|
||||||
|
"MKC",
|
||||||
|
"MCD",
|
||||||
|
"MCK",
|
||||||
|
"MDT",
|
||||||
|
"MRK",
|
||||||
|
"META",
|
||||||
|
"MET",
|
||||||
|
"MTD",
|
||||||
|
"MGM",
|
||||||
|
"MCHP",
|
||||||
|
"MU",
|
||||||
|
"MSFT",
|
||||||
|
"MAA",
|
||||||
|
"MRNA",
|
||||||
|
"MHK",
|
||||||
|
"MOH",
|
||||||
|
"TAP",
|
||||||
|
"MDLZ",
|
||||||
|
"MPWR",
|
||||||
|
"MNST",
|
||||||
|
"MCO",
|
||||||
|
"MS",
|
||||||
|
"MOS",
|
||||||
|
"MSI",
|
||||||
|
"MSCI",
|
||||||
|
"NDAQ",
|
||||||
|
"NTAP",
|
||||||
|
"NFLX",
|
||||||
|
"NEM",
|
||||||
|
"NWSA",
|
||||||
|
"NWS",
|
||||||
|
"NEE",
|
||||||
|
"NKE",
|
||||||
|
"NI",
|
||||||
|
"NDSN",
|
||||||
|
"NSC",
|
||||||
|
"NTRS",
|
||||||
|
"NOC",
|
||||||
|
"NCLH",
|
||||||
|
"NRG",
|
||||||
|
"NUE",
|
||||||
|
"NVDA",
|
||||||
|
"NVR",
|
||||||
|
"NXPI",
|
||||||
|
"ORLY",
|
||||||
|
"OXY",
|
||||||
|
"ODFL",
|
||||||
|
"OMC",
|
||||||
|
"ON",
|
||||||
|
"OKE",
|
||||||
|
"ORCL",
|
||||||
|
"OTIS",
|
||||||
|
"PCAR",
|
||||||
|
"PKG",
|
||||||
|
"PLTR",
|
||||||
|
"PANW",
|
||||||
|
"PSKY",
|
||||||
|
"PH",
|
||||||
|
"PAYX",
|
||||||
|
"PAYC",
|
||||||
|
"PYPL",
|
||||||
|
"PNR",
|
||||||
|
"PEP",
|
||||||
|
"PFE",
|
||||||
|
"PCG",
|
||||||
|
"PM",
|
||||||
|
"PSX",
|
||||||
|
"PNW",
|
||||||
|
"PNC",
|
||||||
|
"POOL",
|
||||||
|
"PPG",
|
||||||
|
"PPL",
|
||||||
|
"PFG",
|
||||||
|
"PG",
|
||||||
|
"PGR",
|
||||||
|
"PLD",
|
||||||
|
"PRU",
|
||||||
|
"PEG",
|
||||||
|
"PTC",
|
||||||
|
"PSA",
|
||||||
|
"PHM",
|
||||||
|
"PWR",
|
||||||
|
"QCOM",
|
||||||
|
"DGX",
|
||||||
|
"RL",
|
||||||
|
"RJF",
|
||||||
|
"RTX",
|
||||||
|
"O",
|
||||||
|
"REG",
|
||||||
|
"REGN",
|
||||||
|
"RF",
|
||||||
|
"RSG",
|
||||||
|
"RMD",
|
||||||
|
"RVTY",
|
||||||
|
"ROK",
|
||||||
|
"ROL",
|
||||||
|
"ROP",
|
||||||
|
"ROST",
|
||||||
|
"RCL",
|
||||||
|
"SPGI",
|
||||||
|
"CRM",
|
||||||
|
"SBAC",
|
||||||
|
"SLB",
|
||||||
|
"STX",
|
||||||
|
"SRE",
|
||||||
|
"NOW",
|
||||||
|
"SHW",
|
||||||
|
"SPG",
|
||||||
|
"SWKS",
|
||||||
|
"SJM",
|
||||||
|
"SW",
|
||||||
|
"SNA",
|
||||||
|
"SOLV",
|
||||||
|
"SO",
|
||||||
|
"LUV",
|
||||||
|
"SWK",
|
||||||
|
"SBUX",
|
||||||
|
"STT",
|
||||||
|
"STLD",
|
||||||
|
"STE",
|
||||||
|
"SYK",
|
||||||
|
"SMCI",
|
||||||
|
"SYF",
|
||||||
|
"SNPS",
|
||||||
|
"SYY",
|
||||||
|
"TMUS",
|
||||||
|
"TROW",
|
||||||
|
"TTWO",
|
||||||
|
"TPR",
|
||||||
|
"TRGP",
|
||||||
|
"TGT",
|
||||||
|
"TEL",
|
||||||
|
"TDY",
|
||||||
|
"TER",
|
||||||
|
"TSLA",
|
||||||
|
"TXN",
|
||||||
|
"TPL",
|
||||||
|
"TXT",
|
||||||
|
"TMO",
|
||||||
|
"TJX",
|
||||||
|
"TKO",
|
||||||
|
"TTD",
|
||||||
|
"TSCO",
|
||||||
|
"TT",
|
||||||
|
"TDG",
|
||||||
|
"TRV",
|
||||||
|
"TRMB",
|
||||||
|
"TFC",
|
||||||
|
"TYL",
|
||||||
|
"TSN",
|
||||||
|
"USB",
|
||||||
|
"UBER",
|
||||||
|
"UDR",
|
||||||
|
"ULTA",
|
||||||
|
"UNP",
|
||||||
|
"UAL",
|
||||||
|
"UPS",
|
||||||
|
"URI",
|
||||||
|
"UNH",
|
||||||
|
"UHS",
|
||||||
|
"VLO",
|
||||||
|
"VTR",
|
||||||
|
"VLTO",
|
||||||
|
"VRSN",
|
||||||
|
"VRSK",
|
||||||
|
"VZ",
|
||||||
|
"VRTX",
|
||||||
|
"VTRS",
|
||||||
|
"VICI",
|
||||||
|
"V",
|
||||||
|
"VST",
|
||||||
|
"VMC",
|
||||||
|
"WRB",
|
||||||
|
"GWW",
|
||||||
|
"WAB",
|
||||||
|
"WBA",
|
||||||
|
"WMT",
|
||||||
|
"DIS",
|
||||||
|
"WBD",
|
||||||
|
"WM",
|
||||||
|
"WAT",
|
||||||
|
"WEC",
|
||||||
|
"WFC",
|
||||||
|
"WELL",
|
||||||
|
"WST",
|
||||||
|
"WDC",
|
||||||
|
"WY",
|
||||||
|
"WSM",
|
||||||
|
"WMB",
|
||||||
|
"WTW",
|
||||||
|
"WDAY",
|
||||||
|
"WYNN",
|
||||||
|
"XEL",
|
||||||
|
"XYL",
|
||||||
|
"YUM",
|
||||||
|
"ZBRA",
|
||||||
|
"ZBH",
|
||||||
|
"ZTS",
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type Sp500Symbol = typeof SP500_SYMBOLS[number];
|
||||||
|
|
@ -1,22 +1,40 @@
|
||||||
import type { EquityPrint } from "@islandflow/types";
|
import { SP500_SYMBOLS, type EquityPrint } from "@islandflow/types";
|
||||||
import type { EquityIngestAdapter, EquityIngestHandlers } from "./types";
|
import type { EquityIngestAdapter, EquityIngestHandlers } from "./types";
|
||||||
|
|
||||||
type SyntheticEquitiesAdapterConfig = {
|
type SyntheticEquitiesAdapterConfig = {
|
||||||
emitIntervalMs: number;
|
emitIntervalMs: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildSyntheticPrint = (seq: number, now: number): EquityPrint => {
|
const EXCHANGES = ["NYSE", "NASDAQ", "ARCA", "BATS", "IEX", "TEST"];
|
||||||
|
|
||||||
|
const hashSymbol = (value: string): number => {
|
||||||
|
let hash = 0;
|
||||||
|
for (let i = 0; i < value.length; i += 1) {
|
||||||
|
hash = (hash * 31 + value.charCodeAt(i)) >>> 0;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildSyntheticPrint = (
|
||||||
|
seq: number,
|
||||||
|
now: number,
|
||||||
|
symbol: string,
|
||||||
|
price: number,
|
||||||
|
size: number,
|
||||||
|
exchange: string,
|
||||||
|
offExchangeFlag: boolean
|
||||||
|
): EquityPrint => {
|
||||||
return {
|
return {
|
||||||
source_ts: now,
|
source_ts: now,
|
||||||
ingest_ts: now,
|
ingest_ts: now,
|
||||||
seq,
|
seq,
|
||||||
trace_id: `ingest-equities-${seq}`,
|
trace_id: `synthetic-equities-${seq}`,
|
||||||
ts: now,
|
ts: now,
|
||||||
underlying_id: "SPY",
|
underlying_id: symbol,
|
||||||
price: 450.1,
|
price,
|
||||||
size: 100,
|
size,
|
||||||
exchange: "TEST",
|
exchange,
|
||||||
offExchangeFlag: false
|
offExchangeFlag
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -35,10 +53,21 @@ export const createSyntheticEquitiesAdapter = (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
seq += 1;
|
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const print = buildSyntheticPrint(seq, now);
|
const batchSize = 3;
|
||||||
void handlers.onTrade(print);
|
|
||||||
|
for (let i = 0; i < batchSize; i += 1) {
|
||||||
|
seq += 1;
|
||||||
|
const symbol = SP500_SYMBOLS[(seq + i) % SP500_SYMBOLS.length];
|
||||||
|
const symbolHash = hashSymbol(symbol);
|
||||||
|
const basePrice = 25 + (symbolHash % 475);
|
||||||
|
const price = Number((basePrice + ((seq % 40) - 20) * 0.05).toFixed(2));
|
||||||
|
const size = 10 + (seq % 600);
|
||||||
|
const exchange = EXCHANGES[(seq + symbolHash) % EXCHANGES.length];
|
||||||
|
const offExchangeFlag = (seq + i) % 6 === 0;
|
||||||
|
const print = buildSyntheticPrint(seq, now + i * 4, symbol, price, size, exchange, offExchangeFlag);
|
||||||
|
void handlers.onTrade(print);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
timer = setInterval(emit, config.emitIntervalMs);
|
timer = setInterval(emit, config.emitIntervalMs);
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,72 @@
|
||||||
import type { OptionPrint } from "@islandflow/types";
|
import { SP500_SYMBOLS, type OptionPrint } from "@islandflow/types";
|
||||||
import type { OptionIngestAdapter, OptionIngestHandlers } from "./types";
|
import type { OptionIngestAdapter, OptionIngestHandlers } from "./types";
|
||||||
|
|
||||||
type SyntheticOptionsAdapterConfig = {
|
type SyntheticOptionsAdapterConfig = {
|
||||||
emitIntervalMs: number;
|
emitIntervalMs: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildSyntheticPrint = (seq: number, now: number): OptionPrint => {
|
type Burst = {
|
||||||
|
contractId: string;
|
||||||
|
basePrice: number;
|
||||||
|
baseSize: number;
|
||||||
|
exchange: string;
|
||||||
|
conditions?: string[];
|
||||||
|
burstSize: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
||||||
|
const EXPIRY_OFFSETS = [7, 14, 28, 45, 60, 90];
|
||||||
|
const EXCHANGES = ["CBOE", "PHLX", "ISE", "ARCA", "BOX", "MIAX"];
|
||||||
|
const CONDITIONS = ["SWEEP", "ISO", "FILL", "TEST"];
|
||||||
|
|
||||||
|
const pick = <T,>(items: T[], seed: number): T => {
|
||||||
|
return items[Math.abs(seed) % items.length];
|
||||||
|
};
|
||||||
|
|
||||||
|
const hashSymbol = (value: string): number => {
|
||||||
|
let hash = 0;
|
||||||
|
for (let i = 0; i < value.length; i += 1) {
|
||||||
|
hash = (hash * 31 + value.charCodeAt(i)) >>> 0;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatStrike = (strike: number): string => {
|
||||||
|
const fixed = strike.toFixed(3);
|
||||||
|
return fixed.replace(/\.?0+$/, "");
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatExpiry = (now: number, offsetDays: number): string => {
|
||||||
|
const expiryDate = new Date(now + offsetDays * MS_PER_DAY);
|
||||||
|
return expiryDate.toISOString().slice(0, 10);
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildBurst = (burstIndex: number, now: number): Burst => {
|
||||||
|
const symbol = SP500_SYMBOLS[burstIndex % SP500_SYMBOLS.length];
|
||||||
|
const symbolHash = hashSymbol(symbol);
|
||||||
|
const basePrice = 30 + (symbolHash % 470);
|
||||||
|
const expiryOffset = pick(EXPIRY_OFFSETS, symbolHash + burstIndex);
|
||||||
|
const expiry = formatExpiry(now, expiryOffset);
|
||||||
|
const strikeStep = basePrice >= 200 ? 10 : 5;
|
||||||
|
const strikeOffset = ((burstIndex % 7) - 3) * strikeStep;
|
||||||
|
const strike = Math.max(1, Math.round(basePrice / strikeStep) * strikeStep + strikeOffset);
|
||||||
|
const right = burstIndex % 2 === 0 ? "C" : "P";
|
||||||
|
const contractId = `${symbol}-${expiry}-${formatStrike(strike)}-${right}`;
|
||||||
|
const exchange = pick(EXCHANGES, burstIndex + symbolHash);
|
||||||
|
const isBlock = burstIndex % 4 === 0;
|
||||||
|
const burstSize = isBlock ? 4 : burstIndex % 3 === 0 ? 2 : 1;
|
||||||
|
const baseSize = isBlock ? 1200 + (symbolHash % 1800) : 5 + (symbolHash % 180);
|
||||||
|
const distance = Math.abs(strike - basePrice);
|
||||||
|
const basePricePer = isBlock ? 12 + distance / strikeStep : 0.5 + distance / 30;
|
||||||
|
const conditions = isBlock ? [pick(CONDITIONS, burstIndex)] : undefined;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
source_ts: now,
|
contractId,
|
||||||
ingest_ts: now,
|
basePrice: basePricePer,
|
||||||
seq,
|
baseSize,
|
||||||
trace_id: `ingest-options-${seq}`,
|
exchange,
|
||||||
ts: now,
|
conditions,
|
||||||
option_contract_id: "SPY-2025-01-17-450-C",
|
burstSize
|
||||||
price: 1.25,
|
|
||||||
size: 10,
|
|
||||||
exchange: "TEST",
|
|
||||||
conditions: ["TEST"]
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -27,6 +77,9 @@ export const createSyntheticOptionsAdapter = (
|
||||||
name: "synthetic",
|
name: "synthetic",
|
||||||
start: (handlers: OptionIngestHandlers) => {
|
start: (handlers: OptionIngestHandlers) => {
|
||||||
let seq = 0;
|
let seq = 0;
|
||||||
|
let burstIndex = 0;
|
||||||
|
let currentBurst: Burst | null = null;
|
||||||
|
let remaining = 0;
|
||||||
let timer: ReturnType<typeof setInterval> | null = null;
|
let timer: ReturnType<typeof setInterval> | null = null;
|
||||||
let stopped = false;
|
let stopped = false;
|
||||||
|
|
||||||
|
|
@ -35,10 +88,37 @@ export const createSyntheticOptionsAdapter = (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
seq += 1;
|
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const print = buildSyntheticPrint(seq, now);
|
if (!currentBurst || remaining <= 0) {
|
||||||
void handlers.onTrade(print);
|
burstIndex += 1;
|
||||||
|
currentBurst = buildBurst(burstIndex, now);
|
||||||
|
remaining = currentBurst.burstSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
const burst = currentBurst;
|
||||||
|
const printsToEmit = remaining;
|
||||||
|
|
||||||
|
for (let i = 0; i < printsToEmit; i += 1) {
|
||||||
|
seq += 1;
|
||||||
|
const priceJitter = (i % 3) - 1;
|
||||||
|
const sizeJitter = (i % 4) - 1;
|
||||||
|
const print: OptionPrint = {
|
||||||
|
source_ts: now + i * 5,
|
||||||
|
ingest_ts: now + i * 5,
|
||||||
|
seq,
|
||||||
|
trace_id: `synthetic-options-${seq}`,
|
||||||
|
ts: now + i * 5,
|
||||||
|
option_contract_id: burst.contractId,
|
||||||
|
price: Math.max(0.05, Number((burst.basePrice * (1 + priceJitter * 0.02)).toFixed(2))),
|
||||||
|
size: Math.max(1, Math.round(burst.baseSize * (1 + sizeJitter * 0.05))),
|
||||||
|
exchange: burst.exchange,
|
||||||
|
conditions: burst.conditions
|
||||||
|
};
|
||||||
|
|
||||||
|
void handlers.onTrade(print);
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
timer = setInterval(emit, config.emitIntervalMs);
|
timer = setInterval(emit, config.emitIntervalMs);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue