Skip to main content

dhan_rs/
lib.rs

1//! # dhan-rs
2//!
3//! An **unofficial** Rust client library for the
4//! [DhanHQ Broker API v2](https://dhanhq.co/docs/v2/).
5//!
6//! ## ⚠️ AI-Generated Code Disclaimer
7//!
8//! **This entire crate was generated by AI.** While it compiles and follows the
9//! DhanHQ API v2 specification, it has **not been extensively tested** against
10//! the live API. Before using this in production or with real money, please:
11//!
12//! - Review the source code thoroughly
13//! - Write your own integration tests
14//! - Validate all order placement, modification, and cancellation flows
15//! - Verify WebSocket market feed parsing against real data
16//!
17//! **The authors accept no responsibility for financial losses incurred through
18//! the use of this library.**
19//!
20//! ## Overview
21//!
22//! `dhan-rs` provides a broad, strongly-typed async Rust client for documented
23//! DhanHQ v2 REST endpoints and WebSocket protocols. Dhan's HTML and linked
24//! OpenAPI sources contain conflicts, and live authenticated compatibility is
25//! not certified:
26//!
27//! - **80 REST API methods** covering orders, portfolio, Data APIs, Global
28//!   Stocks, instruments, historical data, option chains, funds, and more
29//! - **Live Market Feed** with a low-level stream and supervised manager
30//! - **Live Order Updates** with low-level and managed/reconciling APIs
31//! - **Separate 20-level and 200-level Full Market Depth streams**
32//! - **Rich error handling** with [`DhanError`] covering API errors, HTTP
33//!   errors, JSON deserialization errors, and WebSocket errors
34//!
35//! ## Quick Start
36//!
37//! ```no_run
38//! use dhan_rs::DhanClient;
39//! use dhan_rs::types::orders::PlaceOrderRequest;
40//! use dhan_rs::types::enums::*;
41//!
42//! #[tokio::main]
43//! async fn main() -> dhan_rs::Result<()> {
44//!     // Create a client with your DhanHQ credentials
45//!     let client = DhanClient::new("your-client-id", "your-access-token");
46//!
47//!     // Place an order
48//!     let req = PlaceOrderRequest {
49//!         dhan_client_id: "your-client-id".into(),
50//!         correlation_id: None,
51//!         transaction_type: TransactionType::BUY,
52//!         exchange_segment: ExchangeSegment::NSE_EQ,
53//!         product_type: ProductType::INTRADAY,
54//!         order_type: OrderType::LIMIT,
55//!         validity: Validity::DAY,
56//!         security_id: "1333".into(),
57//!         quantity: 1,
58//!         price: Some(1500.0),
59//!         disclosed_quantity: None,
60//!         trigger_price: None,
61//!         after_market_order: None,
62//!         amo_time: None,
63//!         bo_profit_value: None,
64//!         bo_stop_loss_value: None,
65//!     };
66//!     let response = client.place_order(&req).await?;
67//!     println!("Order placed: {:?}", response);
68//!
69//!     // Fetch holdings
70//!     let holdings = client.get_holdings().await?;
71//!     println!("Holdings: {} instruments", holdings.len());
72//!
73//!     Ok(())
74//! }
75//! ```
76//!
77//! ## WebSocket Streaming
78//!
79//! ### Market Feed (Binary)
80//!
81//! ```no_run
82//! use dhan_rs::ws::market_feed::{MarketFeedStream, Instrument};
83//! use dhan_rs::types::enums::FeedRequestCode;
84//! use futures_util::StreamExt;
85//!
86//! # #[tokio::main]
87//! # async fn main() -> dhan_rs::Result<()> {
88//! let mut stream = MarketFeedStream::connect("client-id", "token").await?;
89//!
90//! let instruments = vec![Instrument::new("NSE_EQ", "1333")];
91//! stream.subscribe(FeedRequestCode::SubscribeTicker, &instruments).await?;
92//!
93//! while let Some(event) = stream.next().await {
94//!     println!("{event:?}");
95//! }
96//! # Ok(())
97//! # }
98//! ```
99//!
100//! ### Order Updates (JSON)
101//!
102//! ```no_run
103//! use dhan_rs::ws::order_update::OrderUpdateStream;
104//! use futures_util::StreamExt;
105//!
106//! # #[tokio::main]
107//! # async fn main() -> dhan_rs::Result<()> {
108//! let mut stream = OrderUpdateStream::connect("client-id", "token").await?;
109//!
110//! while let Some(msg) = stream.next().await {
111//!     match msg {
112//!         Ok(update) => println!("Order update: {:?}", update.Data.Status),
113//!         Err(e) => eprintln!("Error: {e}"),
114//!     }
115//! }
116//! # Ok(())
117//! # }
118//! ```
119//!
120//! ## Module Organization
121//!
122//! - [`client`] — The [`DhanClient`] HTTP client with authentication
123//! - [`error`] — [`DhanError`] enum and [`Result`] alias
124//! - [`constants`] — Base URLs, WebSocket URLs, rate limit values
125//! - [`types`] — Request/response structs and shared enums
126//! - [`api`] — REST endpoint implementations (methods on `DhanClient`)
127//! - [`ws`] — Standard feed, order updates, and Full Market Depth streaming
128//!
129//! ## Feature Flags
130//!
131//! The optional `cli` feature enables the `ws_check` diagnostic binary and its
132//! `tracing-subscriber` dependency. Library functionality is available by
133//! default.
134
135#![warn(missing_docs)]
136#![allow(clippy::doc_markdown)]
137#![doc(html_root_url = "https://docs.rs/dhan-rs/0.1.7")]
138
139pub mod api;
140pub mod client;
141pub mod constants;
142pub mod error;
143pub mod types;
144pub mod ws;
145
146/// Re-export the main client type at crate root for convenience.
147pub use client::DhanClient;
148/// Re-export the error type and Result alias.
149pub use error::{DhanError, Result};