Open source from Qian Capital

# sekai · 世界

A modern, flexible reinforcement-learning environment framework, built for complex environments and financial markets.

[Get started](/getting-started/quickstart.html){ .md-button .md-button--primary } [Migrating from gymnasium](/guide/gymnasium.html){ .md-button }
**sekai** is a reinforcement-learning environment framework for Python: a modern take on the gym/gymnasium API with structured results instead of tuples, async-native environments, observations whose size can change, native and multiprocess vectorisation, renderers kept outside the environment, and typed episode statistics. Its finance toolkit (point-in-time market data, simulators, costs, rewards, metrics and a limit order book) powers environments for trading, portfolio allocation over changing universes, market making, optimal execution and order-book markets. It ships the classic-control benchmarks too (dynamics bit-identical to gymnasium), and two-way gymnasium and PettingZoo bridges mean Stable-Baselines3, CleanRL, RLlib and multi-agent libraries work out of the box.

Install

pip install sekai                 # NumPy is the only hard dependency
pip install "sekai[gymnasium]"    # + gymnasium bridge (SB3, CleanRL, RLlib, ...)
pip install "sekai[all]"          # + PettingZoo bridge, pandas data loading, video export

A first look

=== “Classic control”

```python
import sekai

env = sekai.make("CartPole-v1")
env.action_space.seed(0)              # spaces have their own RNG
result = env.reset(seed=0)            # ResetResult(observation, info)
total = 0.0
while not result.done:                # ResetResult.done is always False
    result = env.step(env.action_space.sample())
    total += result.reward            # StepResult: a frozen dataclass, not a tuple
print(result.terminated, result.truncated, total)  # True False 18.0
```

=== “Finance”

```python
import sekai

env = sekai.make("OptimalExecution-v0")    # Almgren–Chriss liquidation
schedule = env.almgren_chriss_actions()    # closed-form optimal policy

result = env.reset(seed=0)
for action in schedule:
    result = env.step(action)
print(result.done, round(result.info["shortfall_bps"], 1))  # True 207.1
```

Features

- :material-code-braces:{ .lg .middle } **Structured results** --- `step()` returns a frozen `StepResult` with a `.done` property; `reset()` returns a `ResetResult`. No more unpacking five values in the wrong order. [:octicons-arrow-right-24: Environments](/guide/environments.html) - :material-lightning-bolt:{ .lg .middle } **Async-native** --- Every environment has `async_step()` / `async_reset()`. `AsyncVecEnv` overlaps the I/O of live feeds and remote simulators with `asyncio`. [:octicons-arrow-right-24: Async environments](/guide/async.html) - :material-layers-triple:{ .lg .middle } **Fast vectorisation** --- Native vector environments step thousands of sub-envs with array operations; plus `SyncVecEnv`, `AsyncVecEnv` (asyncio) and `ProcVecEnv` (worker processes, shared memory), all with same-step autoreset and normalisation wrappers. [:octicons-arrow-right-24: Vector environments](/guide/vector.html) - :material-shape-plus:{ .lg .middle } **Variable-size observations** --- `MaskedBox` padded sets and `Sequence` spaces for observations that grow and shrink, with action masks that `check_env`, wrappers and masked-policy learners understand. [:octicons-arrow-right-24: Variable-size observations](/guide/dynamic.html) - :material-finance:{ .lg .middle } **Financial markets** --- Trading, portfolios over changing universes, Avellaneda–Stoikov market making, Almgren–Chriss execution and limit order books, on simulated markets or your own history. [:octicons-arrow-right-24: Finance environments](/environments/finance.html) - :material-toolbox:{ .lg .middle } **Finance toolkit** --- Point-in-time market data and walk-forward splits, a look-ahead detector, market simulators, cost and impact models, rewards and performance metrics. [:octicons-arrow-right-24: Finance toolkit](/finance/) - :material-swap-horizontal:{ .lg .middle } **gymnasium both ways** --- `to_gymnasium()` exposes any sekai env to gymnasium-based libraries; `from_gymnasium()` brings any gymnasium env into sekai. [:octicons-arrow-right-24: Migrating from gymnasium](/guide/gymnasium.html) - :material-movie-open:{ .lg .middle } **Renderers, not render modes** --- Rendering lives in `Renderer` objects. A NumPy `Canvas`, renderers for every classic control env and `RecordFrames` for GIF/MP4, with no pygame needed. [:octicons-arrow-right-24: Rendering](/guide/rendering.html) - :material-chart-box:{ .lg .middle } **Typed statistics** --- `info["episode"]` is an `EpisodeStats` dataclass, reported to pluggable trackers (in memory, logging, or your own). [:octicons-arrow-right-24: Episode statistics](/guide/statistics.html) - :material-puzzle:{ .lg .middle } **Registry, plugins and tooling** --- `make()` / `make_vec()`, lazy plugin namespaces, `check_env()` for your test suite and a `sekai` command line (`list`, `info`, `check`, `bench`). [:octicons-arrow-right-24: Registry](/guide/registry.html)

Why sekai?

gym and gymnasium have a set of friction points that compound in large or production codebases. sekai keeps the familiar shape of the API and fixes these:

  gymnasium sekai
Step / reset results obs, rew, term, trunc, info = env.step(a): easy to unpack wrong frozen StepResult / ResetResult dataclasses with .done
Async environments not supported async_step() / async_reset() on every env; AsyncVecEnv runs them concurrently
Vector env naming AsyncVectorEnv means multiprocessing SyncVecEnv, AsyncVecEnv (asyncio), ProcVecEnv (multiprocessing)
Vector autoreset next-step by default (an extra step returns the reset obs) same-step: terminal obs in infos[i]["final_observation"]
Vector infos dict of arrays plus _key masks list[dict], one per sub-env; stack_infos() when you want arrays
Rendering render() on the env, render_mode fixed at construction Renderer objects, injected and swappable; RecordFrames wrapper
Episode statistics info["episode"]["r"] in an untyped dict info["episode"] is a typed EpisodeStats
Multi-agent a separate library (PettingZoo) MultiAgentEnv with per-agent spaces, event-driven turns, and a PettingZoo bridge
Variable-size observations Sequence / Graph spaces that do not batch MaskedBox padded sets that batch, flatten and normalise; Sequence with padding
Fast vector envs vector_entry_point NativeVecEnv base class and native finance envs; shared-memory ProcVecEnv
Registry plugins register at import time register_namespace() lazy loaders, sekai -m plugin on the CLI
Env checking PassiveEnvChecker wrapped into every make() check_env() in your test suite; zero overhead in training

Where next