Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
OptionChain-Simulator API and Architecture
System Architecture
flowchart TD
Client[Client Applications] --> API[API Layer]
API --> SM[Session Management]
SM --> App[Application Layer]
App --> Domain[Domain Layer]
App --> Infra[Infrastructure Layer]
Domain --> SimEngine[Simulation Engine]
Infra --> ClickHouse[(ClickHouse DB)]
Infra --> Redis[(Redis)]
Infra --> MongoDB[(MongoDB)]
Session State Transitions
stateDiagram-v2
[*] --> Initialized: POST /api/v1/chain
Initialized --> InProgress: POST /api/v1/chain/step
InProgress --> InProgress: POST /api/v1/chain/step
InProgress --> Modified: PATCH
Modified --> InProgress: POST /api/v1/chain/step
InProgress --> Reinitialized: PUT
Modified --> Reinitialized: PUT
Reinitialized --> InProgress: POST /api/v1/chain/step
Initialized --> [*]: DELETE
InProgress --> [*]: DELETE
Modified --> [*]: DELETE
Reinitialized --> [*]: DELETE
GET /api/v1/chain is a safe, repeatable peek and does not appear here because it
never changes the session state — only POST /api/v1/chain/step advances the cursor.
API Request Flow
sequenceDiagram
participant Client
participant API as REST API
participant SM as Session Manager
participant SS as Simulator Service
Client->>API: POST /api/v1/chain
API->>SM: Create new session
SM->>SS: Initialize simulation
SS-->>SM: Initial state
SM-->>API: Session created (id: abc123)
API-->>Client: 201 Created (session details)
Client->>API: POST /api/v1/chain/step
API->>SM: Advance one step
SM->>SS: Advance simulation
SS-->>SM: Step data
SM-->>API: Chain data
API-->>Client: 200 OK (Chain data)
Client->>API: GET /api/v1/chain
API->>SM: Peek current step
SM->>SS: Read current snapshot
SS-->>SM: Step data (no advance)
SM-->>API: Chain data
API-->>Client: 200 OK (same snapshot, repeatable)
REST API Endpoints
The OptionChain-Simulator exposes the following REST API endpoints:
| Method | Endpoint | Action | Description |
|---|---|---|---|
| POST | /api/v1/chain | Create Session | Creates a new simulation session |
| GET | /api/v1/chain | Read Current Step | Returns the snapshot the next advance will serve (safe, repeatable) |
| POST | /api/v1/chain/step | Advance Step | Serves the snapshot at the cursor (index 0 first), then advances |
| PUT | /api/v1/chain | Replace Session | Completely replaces session parameters |
| PATCH | /api/v1/chain | Update Parameters | Updates specific session parameters |
| DELETE | /api/v1/chain | Delete Session | Terminates and removes a session |
Step cursor semantics (serve-then-advance): current_step is the 0-based index
of the NEXT snapshot to serve. POST /api/v1/chain/step serves the snapshot at the
cursor and then advances it, so a session with steps = N serves EXACTLY indices
0..N-1 over N advances. The advance that serves the last snapshot persists the
Completed state, and any further advance returns 410 Gone. GET /api/v1/chain
peeks the snapshot the next advance would serve without moving the cursor.
Migration (breaking, issue #21):
GET /api/v1/chainused to advance the session and consume a step. It is now a read-only, repeatable peek that returns the current snapshot without mutating state. To advance the cursor, clients must now callPOST /api/v1/chain/step(same response shape, same 200/404/410/500 status codes as the old GET). Downstream consumers such as IronCondor must switch their step-advancing call fromGET /api/v1/chaintoPOST /api/v1/chain/step.
Request/Response Models
1. Create Session (POST /api/v1/chain)
Request Body:
Response (201 Created):
2. Peek Current Step (GET /api/v1/chain?sessionid=6af613b6-569c-5c22-9c37-2ed93f31d3af)
Safe and repeatable: returns the session's current snapshot without advancing the
cursor or persisting anything. To advance the session and consume a step, use
POST /api/v1/chain/step?sessionid=... (issue #21) — it takes the same query
parameter and returns the same body shown below.
Response (200 OK):
3. Update Session Parameters (PATCH /api/v1/chain?sessionid=6af613b6-569c-5c22-9c37-2ed93f31d3af)
Request Body:
Response (200 OK):
4. Replace Session (PUT /api/v1/chain)
Request Body:
Response (200 OK):
5. Delete Session (DELETE /api/v1/chain?sessionid=6af613b6-569c-5c22-9c37-2ed93f31d3af)
Response (200 OK):
Domain Models
classDiagram
class SessionManager {
+createSession(params) Session
+getNextStep(id) (Session, OptionChain)
+updateSession(id, params) Session
+reinitializeSession(id, params) Session
+deleteSession(id) bool
}
class Session {
+id UUID
+createdAt DateTime
+updatedAt DateTime
+parameters SimulationParameters
+currentStep usize
+totalSteps usize
+state SessionState
+advanceStep() Result
+modifyParameters(params)
+reinitialize(params, steps)
}
class SessionState {
<<enumeration>>
Initialized
InProgress
Modified
Reinitialized
Completed
Error
}
class SimulationParameters {
+symbol String
+initialPrice Positive
+volatility Positive
+riskFreeRate Decimal
+strikes Vec~Positive~
+expirations Vec~String~
+method SimulationMethod
+timeFrame TimeFrame
}
class Simulator {
+simulateNextStep(session) OptionChain
-createRandomWalk(session) RandomWalk
}
class OptionChain {
+underlying String
+timestamp DateTime
+price Positive
+contracts Vec~OptionContract~
}
class OptionContract {
+strike Positive
+expiration String
+call OptionData
+put OptionData
+impliedVolatility Positive
+gamma Positive
}
Session --> SimulationParameters
Session --> SessionState
SessionManager --> Session: manages
SessionManager --> Simulator: uses
Simulator --> OptionChain: produces
OptionChain --> OptionContract: contains
Infrastructure Components
classDiagram
class SessionStore {
<<interface>>
+get(id) Session
+save(session) void
+delete(id) bool
+cleanup() int
}
class InMemorySessionStore {
-sessions Map~UUID, Session~
+get(id) Session
+save(session) void
+delete(id) bool
+cleanup() int
}
class RedisSessionStore {
-client RedisClient
+get(id) Session
+save(session) void
+delete(id) bool
+cleanup() int
}
class HistoricalDataRepository {
<<interface>>
+getHistoricalPrices(symbol, timeframe, startDate, endDate) Vec~Positive~
+listAvailableSymbols() Vec~String~
+getDateRangeForSymbol(symbol) (DateTime, DateTime)
}
class ClickHouseHistoricalRepository {
-client ClickHouseClient
+getHistoricalPrices(symbol, timeframe, startDate, endDate) Vec~Positive~
+listAvailableSymbols() Vec~String~
+getDateRangeForSymbol(symbol) (DateTime, DateTime)
}
SessionStore <|.. InMemorySessionStore: implements
SessionStore <|.. RedisSessionStore: implements
HistoricalDataRepository <|.. ClickHouseHistoricalRepository: implements
🚀 Deploy the project
To deploy the services defined in Docker/docker-compose.yml, run the following command:
This will:
- Build the Docker images (
--build) - Force container recreation (
--force-recreate) - Run everything in detached mode (
-d) - Use
optionchain-simulatoras the project name to namespace containers and resources
Make sure Docker and Docker Compose are installed and running on your system.
Makefile Commands for Development
The project includes a Makefile with useful commands for development:
| Command | Description |
|---|---|
make build |
Builds the project |
make release |
Builds the project in release mode |
make test |
Runs all tests |
make fmt |
Formats the code using rustfmt |
make lint |
Runs clippy for linting |
make check |
Runs tests, formatting check, and linting |
make run |
Runs the project |
make clean |
Cleans build artifacts |
make doc |
Generates documentation |
make coverage |
Generates code coverage report |
make bench |
Runs benchmarks |
make deploy |
deploy the services in local |
Additional commands for CI/CD and deployment:
| Command | Description |
|---|---|
make pre-push |
Runs fixes, formatting, linting, and tests before pushing |
make workflow |
Runs all GitHub Actions workflows locally |
make publish |
Publishes the package to crates.io |
make zip |
Creates a ZIP archive of the project |
Contribution and Contact
We welcome contributions to this project! If you would like to contribute, please follow these steps:
- Fork the repository.
- Create a new branch for your feature or bug fix.
- Make your changes and ensure that the project still builds and all tests pass.
- Commit your changes and push your branch to your forked repository.
- Submit a pull request to the main repository.
If you have any questions, issues, or would like to provide feedback, please feel free to contact the project maintainer:
Joaquín Béjar García
- Email: jb@taunais.com
- GitHub: joaquinbejar
We appreciate your interest and look forward to your contributions!
✍️ License
Licensed under MIT license