Add env example and require Alpaca creds from env
- add .env.example with ingest/config defaults - warn on missing Alpaca/Databento envs and remove hardcoded Alpaca defaults - document .env setup in README - allow .env.example to be tracked
This commit is contained in:
parent
baaadcf105
commit
3eb7dc9211
4 changed files with 58 additions and 4 deletions
45
.env.example
Normal file
45
.env.example
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
NATS_URL=nats://localhost:4222
|
||||||
|
CLICKHOUSE_URL=http://localhost:8123
|
||||||
|
CLICKHOUSE_DATABASE=default
|
||||||
|
|
||||||
|
# Options ingest
|
||||||
|
INGEST_ADAPTER=alpaca
|
||||||
|
ALPACA_KEY_ID=
|
||||||
|
ALPACA_SECRET_KEY=
|
||||||
|
ALPACA_REST_URL=https://data.alpaca.markets
|
||||||
|
ALPACA_WS_BASE_URL=wss://stream.data.alpaca.markets/v1beta1
|
||||||
|
ALPACA_FEED=indicative
|
||||||
|
ALPACA_UNDERLYINGS=SPY
|
||||||
|
ALPACA_STRIKES_PER_SIDE=8
|
||||||
|
ALPACA_MAX_DTE_DAYS=30
|
||||||
|
ALPACA_MONEYNESS_PCT=0.06
|
||||||
|
ALPACA_MONEYNESS_FALLBACK_PCT=0.1
|
||||||
|
ALPACA_MAX_QUOTES=200
|
||||||
|
|
||||||
|
# Databento replay
|
||||||
|
DATABENTO_API_KEY=
|
||||||
|
DATABENTO_DATASET=OPRA.PILLAR
|
||||||
|
DATABENTO_SCHEMA=trades
|
||||||
|
DATABENTO_START=
|
||||||
|
DATABENTO_END=
|
||||||
|
DATABENTO_SYMBOLS=SPY.OPT
|
||||||
|
DATABENTO_STYPE_IN=parent
|
||||||
|
DATABENTO_STYPE_OUT=instrument_id
|
||||||
|
DATABENTO_LIMIT=0
|
||||||
|
DATABENTO_PRICE_SCALE=1
|
||||||
|
DATABENTO_PYTHON_BIN=py/.venv/bin/python
|
||||||
|
|
||||||
|
# IBKR adapter (options)
|
||||||
|
IBKR_HOST=127.0.0.1
|
||||||
|
IBKR_PORT=7497
|
||||||
|
IBKR_CLIENT_ID=0
|
||||||
|
IBKR_SYMBOL=SPY
|
||||||
|
IBKR_EXPIRY=20250117
|
||||||
|
IBKR_STRIKE=450
|
||||||
|
IBKR_RIGHT=C
|
||||||
|
IBKR_EXCHANGE=SMART
|
||||||
|
IBKR_CURRENCY=USD
|
||||||
|
IBKR_PYTHON_BIN=python3
|
||||||
|
|
||||||
|
# Equities ingest
|
||||||
|
EMIT_INTERVAL_MS=1000
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -6,6 +6,7 @@ node_modules/
|
||||||
dist/
|
dist/
|
||||||
.env
|
.env
|
||||||
.env.*
|
.env.*
|
||||||
|
!.env.example
|
||||||
coverage/
|
coverage/
|
||||||
logs/
|
logs/
|
||||||
.tmp/
|
.tmp/
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,12 @@ Done now (in repo):
|
||||||
- Synthetic options/equity prints published to NATS and persisted to ClickHouse
|
- Synthetic options/equity prints published to NATS and persisted to ClickHouse
|
||||||
- Deterministic option FlowPacket clustering (time window) + persistence
|
- Deterministic option FlowPacket clustering (time window) + persistence
|
||||||
- API: REST for prints/flow packets, WS for live options/equities/flow, replay endpoints
|
- API: REST for prints/flow packets, WS for live options/equities/flow, replay endpoints
|
||||||
- UI: live tapes for options/equities/flow + replay toggle + pause controls
|
- UI: live tapes for options/equities/flow + replay toggle + pause controls + replay time/completion
|
||||||
|
- Databento historical replay adapter (options) with symbol mapping
|
||||||
|
- Alpaca options adapter (dev-only, bounded contract list)
|
||||||
|
|
||||||
In progress / blocked:
|
In progress / blocked:
|
||||||
- Live data adapters (requires licensed data source)
|
- Live data adapters beyond dev-only feeds (requires licensed data source)
|
||||||
- Rolling stats and advanced clustering
|
- Rolling stats and advanced clustering
|
||||||
|
|
||||||
Not started:
|
Not started:
|
||||||
|
|
@ -84,6 +86,9 @@ Install dependencies:
|
||||||
Start infra:
|
Start infra:
|
||||||
- `docker compose up -d`
|
- `docker compose up -d`
|
||||||
|
|
||||||
|
Create env file:
|
||||||
|
- Copy `.env.example` to `.env` and fill in the API keys you plan to use.
|
||||||
|
|
||||||
Start everything (infra + services + web):
|
Start everything (infra + services + web):
|
||||||
- `bun run dev`
|
- `bun run dev`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ const envSchema = z.object({
|
||||||
CLICKHOUSE_URL: z.string().default("http://localhost:8123"),
|
CLICKHOUSE_URL: z.string().default("http://localhost:8123"),
|
||||||
CLICKHOUSE_DATABASE: z.string().default("default"),
|
CLICKHOUSE_DATABASE: z.string().default("default"),
|
||||||
INGEST_ADAPTER: z.string().min(1).default("alpaca"),
|
INGEST_ADAPTER: z.string().min(1).default("alpaca"),
|
||||||
ALPACA_KEY_ID: z.string().default("PKQDUYKNHDYCPONSMWIXZHT6QV"),
|
ALPACA_KEY_ID: z.string().default(""),
|
||||||
ALPACA_SECRET_KEY: z.string().default("5ktmszfCiWg125GtPguuFpSeTB2zHNewScncAaY4hnKo"),
|
ALPACA_SECRET_KEY: z.string().default(""),
|
||||||
ALPACA_REST_URL: z.string().default("https://data.alpaca.markets"),
|
ALPACA_REST_URL: z.string().default("https://data.alpaca.markets"),
|
||||||
ALPACA_WS_BASE_URL: z.string().default("wss://stream.data.alpaca.markets/v1beta1"),
|
ALPACA_WS_BASE_URL: z.string().default("wss://stream.data.alpaca.markets/v1beta1"),
|
||||||
ALPACA_FEED: z.enum(["indicative", "opra"]).default("indicative"),
|
ALPACA_FEED: z.enum(["indicative", "opra"]).default("indicative"),
|
||||||
|
|
@ -105,6 +105,7 @@ const selectAdapter = (name: string): OptionIngestAdapter => {
|
||||||
|
|
||||||
if (name === "alpaca") {
|
if (name === "alpaca") {
|
||||||
if (!env.ALPACA_KEY_ID || !env.ALPACA_SECRET_KEY) {
|
if (!env.ALPACA_KEY_ID || !env.ALPACA_SECRET_KEY) {
|
||||||
|
logger.warn("alpaca credentials missing; set ALPACA_KEY_ID and ALPACA_SECRET_KEY");
|
||||||
throw new Error("ALPACA_KEY_ID and ALPACA_SECRET_KEY are required for the alpaca adapter.");
|
throw new Error("ALPACA_KEY_ID and ALPACA_SECRET_KEY are required for the alpaca adapter.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,10 +128,12 @@ const selectAdapter = (name: string): OptionIngestAdapter => {
|
||||||
|
|
||||||
if (name === "databento") {
|
if (name === "databento") {
|
||||||
if (!env.DATABENTO_API_KEY) {
|
if (!env.DATABENTO_API_KEY) {
|
||||||
|
logger.warn("databento api key missing; set DATABENTO_API_KEY");
|
||||||
throw new Error("DATABENTO_API_KEY is required for the databento adapter.");
|
throw new Error("DATABENTO_API_KEY is required for the databento adapter.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!env.DATABENTO_START) {
|
if (!env.DATABENTO_START) {
|
||||||
|
logger.warn("databento start missing; set DATABENTO_START");
|
||||||
throw new Error("DATABENTO_START is required for the databento adapter.");
|
throw new Error("DATABENTO_START is required for the databento adapter.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue