1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//! Alpaca options market data client.
//!
//! Provides REST-based option contract discovery and chain snapshots with Greeks.
//!
//! # Endpoints
//!
//! - [`AlpacaOptionsClient::fetch_contracts`]: `GET /v2/options/contracts` — discover available contracts
//! - [`AlpacaOptionsClient::fetch_snapshots`]: `GET /v1beta1/options/snapshots` — chain snapshots with Greeks
//!
//! # Authentication
//!
//! Requires `ALPACA_API_KEY` and `ALPACA_SECRET_KEY` environment variables.
//!
//! # Data Feeds
//!
//! - [`AlpacaOptionFeed::Opra`]: Real-time OPRA feed (requires paid subscription)
//! - [`AlpacaOptionFeed::Indicative`]: 15-minute delayed feed (free)
//!
//! # Example
//!
//! ```ignore
//! use rustrade_data::exchange::alpaca::options::{
//! AlpacaOptionsClient, AlpacaOptionContractQuery, AlpacaOptionFeed,
//! };
//! use chrono::NaiveDate;
//!
//! let client = AlpacaOptionsClient::from_env()?;
//!
//! // Discover AAPL options expiring in next 30 days
//! let query = AlpacaOptionContractQuery::new(vec!["AAPL".into()])
//! .expiration_gte(NaiveDate::from_ymd_opt(2024, 1, 1).unwrap())
//! .expiration_lte(NaiveDate::from_ymd_opt(2024, 1, 31).unwrap());
//!
//! let contracts = client.fetch_contracts(&query).await?;
//!
//! // Fetch snapshots with Greeks (using free delayed feed)
//! let symbols: Vec<_> = contracts.iter().map(|c| c.symbol.clone()).collect();
//! let snapshots = client.fetch_snapshots(&symbols, AlpacaOptionFeed::Indicative).await?;
//! ```
//!
//! # Testing Status
//!
//! **Tested locally, CI planned (free tier — paper trading allowed):**
//! - Contract discovery via `fetch_contracts()`
//! - Indicative feed (15-min delayed) via `fetch_snapshots()`
//!
//! **NOT tested (requires OPRA subscription via Algo Trader Plus):**
//! - OPRA real-time feed — implemented but unverified against real endpoints
//!
//! # Limitations
//!
//! - **REST only**: Greeks streaming is NOT available via WebSocket. Use snapshots for
//! point-in-time Greeks data.
//! - **Rate limits**: Alpaca applies rate limits; the client handles 429 responses with retry.
pub use ;
pub use ;
use AlpacaRestClient;
/// Errors from Alpaca options API operations.
///
/// Alias of the shared [`AlpacaRestError`](super::rest::AlpacaRestError): options requests
/// have no failure modes beyond the common transport/protocol ones, so the single REST error type
/// is reused rather than duplicated per endpoint family.
pub use AlpacaRestError as AlpacaOptionsError;
/// Alpaca options market data client.
///
/// Provides access to option contract discovery and chain snapshots via REST API.
/// The client handles authentication, rate limiting, and pagination automatically.
///
/// # Construction
///
/// Use [`AlpacaOptionsClient::from_env`] to create a client using environment variables,
/// or [`AlpacaOptionsClient::new`] for explicit credentials.
///
/// Internally this is a thin wrapper over the shared [`AlpacaRestClient`] transport.
// Test code: panics on bad input are acceptable