Skip to content

Commit

Permalink
get news providers
Browse files Browse the repository at this point in the history
  • Loading branch information
Wil Boayue committed Oct 29, 2024
1 parent 69a61ed commit 7ea2623
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 75 deletions.
10 changes: 10 additions & 0 deletions examples/news_providers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use ibapi::Client;

fn main() {
let client = Client::connect("127.0.0.1:4002", 100).expect("connection failed");

let news_providers = client.news_providers().expect("request news providers failed");
for news_provider in &news_providers {
println!("news provider {:?}", news_provider);
}
}
28 changes: 24 additions & 4 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ use crate::messages::{IncomingMessages, OutgoingMessages};
use crate::messages::{RequestMessage, ResponseMessage};
use crate::orders::{CancelOrder, Executions, ExerciseOptions, Order, Orders, PlaceOrder};
use crate::transport::{Connection, ConnectionMetadata, InternalSubscription, MessageBus, TcpMessageBus};
use crate::{accounts, contracts, market_data, orders};
use crate::{accounts, contracts, market_data, news, orders};

#[cfg(test)]
mod tests;

// Client

Expand Down Expand Up @@ -1195,6 +1198,26 @@ impl Client {
realtime::market_data(self, contract, generic_ticks, snapshot, regulatory_snapshot)
}

// === News ===

/// Requests news providers which the user has subscribed to.
///
/// # Examples
///
/// ```no_run
/// use ibapi::Client;
///
/// let client = Client::connect("127.0.0.1:4002", 100).expect("connection failed");
///
/// let news_providers = client.news_providers().expect("request news providers failed");
/// for news_provider in &news_providers {
/// println!("news provider {:?}", news_provider);
/// }
/// ```
pub fn news_providers(&self) -> Result<Vec<news::NewsProvider>, Error> {
news::news_providers(self)
}

// == Internal Use ==

#[cfg(test)]
Expand Down Expand Up @@ -1525,6 +1548,3 @@ impl<'a, T: Subscribable<T>> Iterator for SubscriptionTimeoutIter<'a, T> {

/// Marker trait for shared channels
pub trait SharesChannel {}

#[cfg(test)]
mod tests;
57 changes: 0 additions & 57 deletions src/domain.rs

This file was deleted.

2 changes: 2 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub enum Error {
Shutdown,
StreamEnd,
UnexpectedResponse(ResponseMessage),
UnexpectedEndOfStream,
}

impl std::error::Error for Error {}
Expand All @@ -45,6 +46,7 @@ impl std::fmt::Display for Error {
Error::Shutdown => write!(f, "Shutdown"),
Error::StreamEnd => write!(f, "StreamEnd"),
Error::UnexpectedResponse(message) => write!(f, "UnexpectedResponse: {:?}", message),
Error::UnexpectedEndOfStream => write!(f, "UnexpectedEndOfStream"),

Error::Simple(ref err) => write!(f, "error occurred: {err}"),
}
Expand Down
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ pub(crate) mod transport;
/// Every time a new request that requires a contract (i.e. market data, order placing, etc.) is sent to the API, the system will try to match the provided contract object with a single candidate. If there is more than one contract matching the same description, the API will return an error notifying you there is an ambiguity. In these cases the API needs further information to narrow down the list of contracts matching the provided description to a single element.
pub mod contracts;
// Describes primary data structures used by the model.
//pub(crate) mod domain;
pub mod errors;
/// APIs for retrieving market data
pub mod market_data;
Expand Down
4 changes: 4 additions & 0 deletions src/messages/shared_channel_configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,8 @@ pub(crate) const CHANNEL_MAPPINGS: &[ChannelMapping] = &[
request: OutgoingMessages::RequestCurrentTime,
responses: &[IncomingMessages::CurrentTime],
},
ChannelMapping {
request: OutgoingMessages::RequestNewsProviders,
responses: &[IncomingMessages::NewsProviders],
},
];
27 changes: 14 additions & 13 deletions src/news.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::{Client, Error};
use crate::{messages::OutgoingMessages, server_versions, Client, Error};

mod decoders;
mod encoders;

#[derive(Clone, Debug)]
pub struct NewsProvider {
Expand All @@ -14,17 +17,15 @@ pub struct NewsProvider {
/// Requests news providers which the user has subscribed to.
pub fn news_providers(client: &Client) -> Result<Vec<NewsProvider>, Error> {
// request = RequestNewsProvidersRequest::new()
// packet = request.encode()
// client.send_packet(packet)
// packet = client.receive_packet(request_id)
// ReceiveNewsProvidersResponse::decode(packet)
print!("client: {client:?}");
Err(Error::NotImplemented)
}
client.check_server_version(server_versions::REQ_NEWS_PROVIDERS, "It does not support news providers requests.")?;

// :reqNewsArticle below.
let request = encoders::encode_request_news_providers()?;
let subscription = client.send_shared_request(OutgoingMessages::RequestNewsProviders, request)?;

// reqHistoricalNews

//reqNewsArticle s
match subscription.next() {
Some(Ok(message)) => decoders::decode_news_providers(message),
Some(Err(Error::ConnectionReset)) => news_providers(client),
Some(Err(e)) => Err(e),
None => Err(Error::UnexpectedEndOfStream),
}
}
18 changes: 18 additions & 0 deletions src/news/decoders.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use super::{Error, NewsProvider};
use crate::messages::ResponseMessage;

pub(super) fn decode_news_providers(mut message: ResponseMessage) -> Result<Vec<NewsProvider>, Error> {
message.skip(); // message type

let num_providers = message.next_int()?;
let mut news_providers = Vec::with_capacity(num_providers as usize);

for _ in 0..num_providers {
news_providers.push(NewsProvider {
code: message.next_string()?,
name: message.next_string()?,
});
}

Ok(news_providers)
}
12 changes: 12 additions & 0 deletions src/news/encoders.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use crate::{
messages::{OutgoingMessages, RequestMessage},
Error,
};

pub(super) fn encode_request_news_providers() -> Result<RequestMessage, Error> {
let mut message = RequestMessage::new();

message.push_field(&OutgoingMessages::RequestNewsProviders);

Ok(message)
}
1 change: 1 addition & 0 deletions src/orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,7 @@ pub struct ExecutionData {
}

#[derive(Clone, Debug)]
#[allow(clippy::large_enum_variant)]
pub enum PlaceOrder {
OrderStatus(OrderStatus),
OpenOrder(OrderData),
Expand Down

0 comments on commit 7ea2623

Please sign in to comment.