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
//! Asynchronous implementation of Wall Street Horizon functionality
use time::Date;
use crate::{
common::request_helpers,
protocol::{check_version, Features},
subscriptions::Subscription,
Client, Error,
};
use super::{common::decoders, encoders, AutoFill, WshEventData, WshMetadata};
impl Client {
/// Fetch Wall Street Horizon metadata table with retry semantics.
///
/// # Examples
///
/// ```no_run
/// use ibapi::prelude::*;
///
/// #[tokio::main]
/// async fn main() {
/// let client = Client::connect("127.0.0.1:4002", 100).await.expect("connection failed");
/// let metadata = client.wsh_metadata().await.expect("request wsh metadata failed");
/// println!("{metadata:?}");
/// }
/// ```
pub async fn wsh_metadata(&self) -> Result<WshMetadata, Error> {
check_version(self.server_version(), Features::WSHE_CALENDAR)?;
request_helpers::one_shot_request_with_retry(self, encoders::encode_request_wsh_metadata, decoders::decode_metadata_message, || {
Err(Error::UnexpectedEndOfStream)
})
.await
}
/// Fetch WSH event data filtered by contract identifier.
///
/// # Arguments
///
/// * `contract_id` - Contract identifier for the event request.
/// * `start_date` - Start date of the event request.
/// * `end_date` - End date of the event request.
/// * `limit` - Maximum number of events to return. Maximum of 100.
/// * `auto_fill` - Fields to automatically fill in. See [`AutoFill`] for more information.
///
/// # Examples
///
/// ```no_run
/// use ibapi::prelude::*;
///
/// #[tokio::main]
/// async fn main() {
/// let client = Client::connect("127.0.0.1:4002", 100).await.expect("connection failed");
///
/// let contract_id = 76792991; // TSLA
/// let event_data = client
/// .wsh_event_data_by_contract(contract_id, None, None, None, None)
/// .await
/// .expect("request wsh event data failed");
/// println!("{event_data:?}");
/// }
/// ```
pub async fn wsh_event_data_by_contract(
&self,
contract_id: i32,
start_date: Option<Date>,
end_date: Option<Date>,
limit: Option<i32>,
auto_fill: Option<AutoFill>,
) -> Result<WshEventData, Error> {
check_version(self.server_version(), Features::WSHE_CALENDAR)?;
if auto_fill.is_some() {
check_version(self.server_version(), Features::WSH_EVENT_DATA_FILTERS)?;
}
if start_date.is_some() || end_date.is_some() || limit.is_some() {
check_version(self.server_version(), Features::WSH_EVENT_DATA_FILTERS_DATE)?;
}
request_helpers::one_shot_request_with_retry(
self,
|request_id| encoders::encode_request_wsh_event_data(request_id, Some(contract_id), None, start_date, end_date, limit, auto_fill),
decoders::decode_event_data_message,
|| Err(Error::UnexpectedEndOfStream),
)
.await
}
/// Subscribe to WSH event data using a filter expression.
///
/// # Arguments
///
/// * `filter` - JSON-formatted string containing all filter values.
/// * `limit` - Maximum number of events to return. Maximum of 100.
/// * `auto_fill` - Fields to automatically fill in. See [`AutoFill`] for more information.
///
/// # Examples
///
/// ```no_run
/// use ibapi::prelude::*;
///
/// #[tokio::main]
/// async fn main() {
/// let client = Client::connect("127.0.0.1:4002", 100).await.expect("connection failed");
///
/// let filter = ""; // see https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#wsheventdata-object
/// let subscription = client
/// .wsh_event_data_by_filter(filter, None, None)
/// .await
/// .expect("request wsh event data failed");
/// let mut data = subscription.filter_data();
/// while let Some(result) = data.next().await {
/// println!("{result:?}");
/// }
/// }
/// ```
pub async fn wsh_event_data_by_filter(
&self,
filter: &str,
limit: Option<i32>,
auto_fill: Option<AutoFill>,
) -> Result<Subscription<WshEventData>, Error> {
if limit.is_some() {
check_version(self.server_version(), Features::WSH_EVENT_DATA_FILTERS_DATE)?;
}
request_helpers::request_with_id(self, Features::WSH_EVENT_DATA_FILTERS, |request_id| {
encoders::encode_request_wsh_event_data(
request_id,
None,
Some(filter),
None, // start_date
None, // end_date
limit,
auto_fill,
)
})
.await
}
}
#[cfg(test)]
#[path = "async_tests.rs"]
mod tests;