optionchain_simulator 0.2.0

OptionChain-Simulator is a lightweight REST API service that simulates an evolving option chain with every request. It is designed for developers building or testing trading systems, backtesters, and visual tools that depend on option data streams but want to avoid relying on live data feeds.
# OptionChain-Simulator — environment variables
#
# Every variable the service reads is listed here with its default and its
# accepted range. Copy this file to `.env` and change what you need; anything
# left unset takes the default shown.
#
# Two behaviours to know before editing:
#
#   * The v2 knobs (OCS_V2_*, OCS_MAX_CACHED_*) are VALIDATED AT STARTUP. An
#     invalid value fails the process with a message naming the variable,
#     because silently reverting to a default would change how long simulations
#     live or how much memory the service holds without anyone noticing.
#
#   * The v1 request caps (OCS_MAX_STEPS, OCS_MAX_CHAIN_SIZE,
#     OCS_MAX_HISTORICAL_PRICES) and OCS_MAX_CACHED_WALKS warn and fall back to
#     their defaults instead, because a bad value there degrades one request
#     rather than the service.


# ---------------------------------------------------------------------------
# Logging
# ---------------------------------------------------------------------------

# Verbosity of the tracing subscriber.
# Values: TRACE | DEBUG | INFO | WARN | ERROR.  Default: DEBUG
LOGLEVEL=INFO


# ---------------------------------------------------------------------------
# Request caps (v1 and v2)
# ---------------------------------------------------------------------------
# These bound what a single request may ask for, so a pathological one cannot
# exhaust memory or CPU. Unset or invalid values fall back to the default and
# emit a warning.

# Maximum simulation steps per session or simulation.
# Range: >= 1.  Default: 10000
OCS_MAX_STEPS=10000

# Maximum option-chain size (strikes) per request.
# Range: >= 1.  Default: 500
OCS_MAX_CHAIN_SIZE=500

# Maximum number of embedded prices a Historical walk request may carry.
# Range: >= 1.  Default: 100000
OCS_MAX_HISTORICAL_PRICES=100000


# ---------------------------------------------------------------------------
# v1 domain cache
# ---------------------------------------------------------------------------

# Maximum random walks held in the v1 simulation cache, evicted
# least-recently-used. Eviction never changes what a client sees: a rebuilt
# walk reproduces the identical tape from the same seed.
# Range: >= 1.  Default: 1000
OCS_MAX_CACHED_WALKS=1000


# ---------------------------------------------------------------------------
# v2 rolling simulations
# ---------------------------------------------------------------------------
# These are about REAL time and REAL memory. None of them touch the simulated
# clock, which may span years regardless of how long a simulation is kept.

# How long an idle v2 simulation is kept before the retention sweep reaps it,
# in seconds. Measured from the last WRITE, not the last read: peeking a
# snapshot persists nothing, so a client that only peeks does not refresh the
# window.
#
# Deliberately longer than v1's 1800 s: a v2 simulation is walked one request
# at a time over a long simulated horizon, and losing it to a short idle
# timeout would make that horizon unusable.
#
# Range: 1 .. 2592000 (30 days).  Default: 3600
OCS_V2_RETENTION_SECS=3600

# How often the retention sweep runs, in seconds. Each pass reaps expired
# simulations and evicts the factor tapes and snapshots they left behind.
# Range: 1 .. 3600.  Default: 60
OCS_V2_CLEANUP_INTERVAL_SECS=60

# Maximum v2 factor tapes held resident, evicted least-recently-used. A tape is
# one small row per step, so this bound is generous relative to the snapshot
# one.
# Range: 1 .. 1000000.  Default: 64
OCS_MAX_CACHED_TAPES=64

# Maximum v2 snapshots held resident, evicted least-recently-used. A snapshot
# holds every strike of every live expiration, so this bound is deliberately
# small. Eviction is never observable in what is served — a rebuilt snapshot
# prices identically, because it is a pure function of the factor row and the
# planner.
# Range: 1 .. 1000000.  Default: 256
OCS_MAX_CACHED_SNAPSHOTS=256

# Maximum contracts one v2 snapshot may price: strikes x the sum of every
# schedule rule's target_count. The chain-size and expiration caps are each
# reasonable alone and multiply into half a million contracts for one /snapshot
# call, which this bounds. Reported against chain_size, the field a client can
# lower without changing what the simulation means.
# Range: 1 .. 10000000.  Default: 200000
OCS_MAX_SNAPSHOT_CONTRACTS=200000

# Maximum contracts held resident across every cached v2 snapshot. This is the
# bound that protects memory — OCS_MAX_CACHED_SNAPSHOTS bounds the map, and one
# entry is a few hundred contracts in the reference configuration and hundreds
# of thousands in a large one. Roughly a gigabyte at the default. A snapshot
# heavier than this whole budget is served without being cached, rather than
# evicting everything to make room for something that still would not fit.
# Range: 1 .. 100000000.  Default: 4000000
OCS_MAX_CACHED_SNAPSHOT_CONTRACTS=4000000

# Maximum steps one export request may cover. Bounds the WORK, not the memory:
# streaming already keeps the response bounded, but an option_chains export is
# steps x expirations x strikes priced contracts, so an unbounded range is
# minutes of CPU. A client wanting more pages the range with from_step/to_step.
# Range: 1 .. 10000000.  Default: 100000
OCS_MAX_EXPORT_ROWS=100000

# ---------------------------------------------------------------------------
# v2 snapshot persistence (ClickHouse)
# ---------------------------------------------------------------------------
# Files every ADVANCED v2 step in ClickHouse as an immutable, queryable tape:
# one metadata row per step plus one flattened row per expiration and strike.
# A peek and an export replay and persist nothing.
# OFF by default — a deployment without ClickHouse does not have to name the
# feature to not use it, and with it off nothing is added to the serving path.
# Turning it ON makes ClickHouse a HARD STARTUP DEPENDENCY: the tables are
# created at boot, so a schema or connectivity problem fails the boot rather
# than surfacing later as a warning. Writes themselves are detached from the
# request, so a warehouse that degrades later cannot delay a response.
# Values: true/false/1/0/yes/no/on/off.  Default: false
OCS_SNAPSHOT_PERSISTENCE_ENABLED=false

# Maximum quote rows one snapshot may carry into storage. Every quote row of a
# snapshot goes in ONE insert, so this bounds the snapshot and the statement
# alike: a snapshot above it is rejected before a row is written. It must be at
# least OCS_MAX_SNAPSHOT_CONTRACTS, or the API would accept simulations the
# warehouse could never persist — startup refuses that combination rather than
# leaving it to be found in the logs.
# Range: 1 .. 5000000.  Default: 200000 (matches OCS_MAX_SNAPSHOT_CONTRACTS)
OCS_SNAPSHOT_BATCH_ROWS=200000

# Maximum rows one read may return, so a range query cannot be unbounded.
# Range: 1 .. 10000000.  Default: 1000000
OCS_SNAPSHOT_MAX_READ_ROWS=1000000

# How long an insert may take before it is an error the advance tolerates.
# Range: 1 .. 600.  Default: 30
OCS_SNAPSHOT_INSERT_TIMEOUT_SECS=30

# How long persisted snapshots are kept, as a row-level TTL. Anchored on the
# ingestion timestamp, so a backfilled step is kept for its full window.
# Changing this on a live deployment needs an explicit ALTER TABLE MODIFY TTL.
# Range: 1 .. 3650.  Default: 90
OCS_SNAPSHOT_RETENTION_DAYS=90


# ---------------------------------------------------------------------------
# Redis — session and simulation storage
# ---------------------------------------------------------------------------
# Never commit a real password. This file documents the shape; `.env` holds the
# values and is gitignored.

# Host and port of the Redis server.  Defaults: 127.0.0.1 / 6379
REDIS_HOST=127.0.0.1
REDIS_PORT=6379

# Logical database index.  Default: 0
REDIS_DB=0

# Credentials. Both optional; leave unset for an unauthenticated server.
REDIS_USER=
REDIS_PASSWORD=

# Connection timeout, in seconds.  Default: 30
REDIS_TIMEOUT=30

# Timeout for establishing the connection, in seconds.  Default: 5
REDIS_CONNECT_TIMEOUT=5


# ---------------------------------------------------------------------------
# MongoDB — event and step logging
# ---------------------------------------------------------------------------
# Logging is best-effort: a MongoDB failure never fails a request.

# Connection URI.  Default: mongodb://admin:password@localhost:27017
MONGODB_URI=mongodb://admin:password@localhost:27017

# Database and collections.
# Defaults: optionchain_simulator / steps / events
MONGODB_DATABASE=optionchain_simulator
MONGODB_STEPS_COLLECTION=steps
MONGODB_EVENTS_COLLECTION=events

# Server-selection timeout, in seconds. Bounded so a missing MongoDB cannot
# stall startup indefinitely.
# Default: 30
MONGODB_TIMEOUT=30


# ---------------------------------------------------------------------------
# ClickHouse — historical price data
# ---------------------------------------------------------------------------

# Host and port.  Defaults: localhost / 8123
CLICKHOUSE_HOST=localhost
CLICKHOUSE_PORT=8123

# Database and credentials.  Defaults: default / admin / password
CLICKHOUSE_DB=default
CLICKHOUSE_USER=admin
CLICKHOUSE_PASSWORD=password