Skip to main content

rustrade/
lib.rs

1#![warn(missing_docs)]
2
3//! # rustrade
4//!
5//! Open-source trading bot framework — the facade crate downstream
6//! services depend on. Re-exports the core types, the supervisor, and the
7//! risk primitives, and adds the [`Bot`] builder that wires them into a
8//! single supervised runtime.
9//!
10//! # Quickstart
11//!
12//! ```rust,ignore
13//! use std::sync::Arc;
14//! use rustrade::{Bot, BotConfig};
15//!
16//! let bot = Bot::new(
17//!     BotConfig::builder().name("my-bot").symbol("BTCUSDT").build()?,
18//!     Arc::new(MyExchangeAdapter::new()),
19//!     vec![Arc::new(MyBrain::new())],
20//! )?;
21//! let handle = bot.handle();
22//! // host can shutdown via handle.shutdown() at any time
23//! bot.run_until_shutdown().await
24//! ```
25//!
26//! # What this crate adds on top of the sub-crates
27//!
28//! - [`Bot`] / [`BotConfig`] / [`BotConfigBuilder`] — the embedding entry
29//!   point. Wraps a [`Supervisor`] and the framework-side services.
30//! - [`BotHandle`] / [`BotHealth`] — cheap cloneable handle for host
31//!   services to query state and trigger shutdown without holding the
32//!   `Bot` itself.
33//! - [`Bot::with_market_source`] / [`Bot::with_fill_source`] /
34//!   [`Bot::with_external_cancel`] — optional wirings for adapters and
35//!   host-driven shutdown.
36//! - [`logging::init_tracing`] — opinionated default tracing subscriber.
37//!   Skippable; downstream services with their own subscriber don't use it.
38//!
39//! # Tokio runtime requirements
40//!
41//! `Bot::run_until_shutdown` must be awaited inside a **multi-thread
42//! tokio runtime context**. Internally the supervisor calls
43//! `tokio::spawn` for every service, and the framework expects the host's
44//! shutdown to be cooperative (services watch a `CancellationToken`).
45//! The simplest valid host is:
46//!
47//! ```rust,ignore
48//! #[tokio::main(flavor = "multi_thread")]
49//! async fn main() -> anyhow::Result<()> {
50//!     // ... build bot ...
51//!     bot.run_until_shutdown().await
52//! }
53//! ```
54//!
55//! Embedding into an existing runtime is supported — just spawn the bot
56//! as a task and hold a [`BotHandle`] for control. See
57//! `examples/embed-in-service/`.
58//!
59//! # Resource expectations
60//!
61//! - **Memory per active symbol:** a few hundred bytes for the position
62//!   cache entry plus the per-symbol `SymbolRisk` (a `SessionPnl` and a
63//!   `CircuitBreaker` whose ring buffer is bounded by `loss_limit`).
64//! - **Channel buffers:** `market_bus_capacity` + `signal_bus_capacity`
65//!   slots per bus, each holding a clone of `MarketDataEvent` / `Signal`.
66//!   Backed by `tokio::sync::broadcast`, which has **drop-oldest**
67//!   semantics: slow subscribers see `RecvError::Lagged(n)` and miss
68//!   the oldest dropped events.
69//! - **Expected shutdown time:** ≤ `shutdown_timeout` (default 30 s).
70//!   Well-behaved services drain in milliseconds; the timeout is the
71//!   worst-case ceiling, not the typical case.
72//! - **Restart-after-crash latency:** bounded by the supervisor's
73//!   `rustrade_supervisor::BackoffConfig`. Defaults: 100 ms base delay,
74//!   60 s cap, 10 retries within a 10-minute window before the circuit
75//!   breaker trips and the service terminates.
76//!
77//! # Module status
78//!
79//! | Module       | Surface                                                    |
80//! | ------------ | ---------------------------------------------------------- |
81//! | `bot`        | `Bot`, `BotConfig`, `BotConfigBuilder`, `RiskConfig`       |
82//! | `handle`     | `BotHandle`, `BotHealth`, `record_trade_outcome`           |
83//! | `execution`  | `ExecutionService` with full risk-gate pipeline            |
84//! | `services`   | `MarketFeedService`, `FillRoutingService`                  |
85//! | `logging`    | `init_tracing`                                             |
86
87pub mod bot;
88pub mod execution;
89pub mod handle;
90pub mod json_store;
91pub mod logging;
92pub mod order_tracker;
93pub(crate) mod pending;
94pub(crate) mod risk_state;
95pub(crate) mod risk_sweep;
96pub mod services;
97
98pub use bot::{Bot, BotConfig, BotConfigBuilder, BracketFailurePolicy, RiskConfig};
99pub use handle::{BotHandle, BotHealth, BrainHealthSnapshot};
100pub use json_store::JsonFileStore;
101pub use order_tracker::{OcoRegistry, OrderReaperService, OrderTracker, TrackedOrder};
102pub use services::{CandlePollerService, FillRoutingService, MarketFeedService};
103
104// Re-exports from sub-crates so downstream depends on `rustrade` only.
105pub use rustrade_core::{
106    AssetClass, Brain, BrainHealth, Candle, CandleSource, Capability, Decision, Error, EventSource,
107    Exchange, ExchangeClient, Fill, FillSource, InMemoryStore, InstrumentSpec, MarketDataBus,
108    MarketDataEvent, MarketSource, MetricsSink, NoopSink, OpenOrder, Order, OrderKind, OrderStatus,
109    Position, Price, Result, Side, Signal, SignalBus, SignalType, SizeHint, StateStore,
110    StopAttachment, StopKind, Symbol, Tick, Volume,
111};
112pub use rustrade_risk::{
113    CircuitBreaker, CircuitBreakerConfig, Clock, ManualClock, PortfolioBlock, PortfolioRisk,
114    PortfolioRiskConfig, PortfolioState, PositionSizer, SessionPnl, SessionPnlConfig, SizingConfig,
115    SystemClock,
116};
117pub use rustrade_supervisor::{
118    BackoffConfig, RestartPolicy, ServiceLifecycleSnapshot, ServicePhase, SpawnOptions, Supervisor,
119    SupervisorConfig, TerminationReason, TradingService,
120};