Simple OUCH 5.0 client for communication of orders to NASDAQ.
Contains strong types for order-related messages and a simple client to send and receive them.
This crate should be presumed experimental and non-functional until integration testing has been completed. If you are willing and able to assist with integration testing, please leave a response under this issue.
- Add
slouchto your Rust project (v2024or more recent):
cargo add slouch- Create an
OuchClientto handle order entry by wrapping a TCP stream that is already logged in to an OUCH account. When the client is created, it will attempt to query the account. Setup will fail if anAccountQueryResponseis not received from the server.
use std::net::{ SocketAddr, TcpStream };
use slouch::OuchClient;
let mut stream = TcpStream::connect(SocketAddr::new(
/* IP address */,
/* Port number */
));
// TODO: Login to your account as described during OUCH onboarding.
let mut client = OuchClient::new(stream).unwrap();- Send a request and receive a response.
OuchResponseis an enum that can be matched to extract message values.
use slouch::account_query;
use slouch::msg::OuchResponse::*;
let request = account_query!();
client.send(request).unwrap();
let response = client.recv().unwrap();
match response {
AccountQueryResponse(aqr) => {
let _time: chrono::NaiveTime = aqr.timestamp();
let _num: UserRefNum = aqr.next_user_ref_num();
let _opts: &Vec<TagValue> = aqr.options();
},
_ => {/* Do something else */}
}- Each
OuchRequesthas a macro to simplify message creation.
Check the documentation comment for a macro to see how it is used.
use slouch::{ enter, types::* };
let request = enter!{
user_ref_num: client.new_user_ref_num(),
side: Side::Buy,
quantity: 69u32,
symbol: StockSymbol::from("STONKS").unwrap(),
price: Price::new(35000u64).unwrap(),
time_in_force: TimeInForce::Day,
display: Display::Visible,
capacity: Capacity::Agency,
intermarket_sweep: false,
cross_type: CrossType::Opening,
order_token: OrderToken::from("To The Moon").unwrap()
};
client.send(request).unwrap();- Client logging is provided by the
logcrate and can be enabled through thelogsfeature. An asynchronous version of the client usestokioand can be enabled through theasyncfeature. By default,OuchClientis synchronous and its events are not logged.
# Cargo.toml
[dependencies]
slouch = { version = "0.0.3", features = ["logs", "async"] }OuchRequestandOuchResponsemay also be used without anOuchClient.
use std::net;
use slouch::{ account_query, msg::OuchResponse };
// OUCH Server port
let addr = net::SocketAddr::new(/* IP address */, /* Port number */);
let mut stream = net::TcpStream::connect(addr).unwrap();
// TODO: Login to your account as described during OUCH onboarding.
let bytes = account_query!().encode();
stream.write_all(&bytes).unwrap();
let mut buf = vec![];
let n = stream.read(&mut buf).unwrap();
let (_buf, response) = OuchResponse::parse(&self.buf[..n]).unwrap();Development history and current tasks are tracked in TODO.md.
Developer resources:
Contributions are welcome! Submit issues and pull requests to this repository.