pub struct ZerodhaEndpoints {
pub rest_base: &'static str,
pub _ws_base: Option<&'static str>,
pub _login_url: &'static str,
}
impl Default for ZerodhaEndpoints {
fn default() -> Self {
Self {
rest_base: "https://api.kite.trade",
_ws_base: Some("wss://ws.kite.trade"),
_login_url: "https://kite.zerodha.com/connect/login",
}
}
}
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum ZerodhaEndpoint {
SessionToken, SessionLogout,
UserProfile,
Instruments, InstrumentsExchange(String), Quote, QuoteOhlc, QuoteLtp, HistoricalCandles(u32, String),
PlaceOrder(String), ModifyOrder(String, String), CancelOrder(String, String), GetOrders, GetOrder(String), GetTrades, GetOrderTrades(String),
PlaceGtt, ModifyGtt(u64), DeleteGtt(u64), GetGtts, GetGtt(u64),
GetMargins, GetMarginsSegment(String), OrderMargins, BasketMargins,
Holdings, HoldingsAuctions, AuthorizeHoldings, Positions, ConvertPosition,
BasketOrders, }
impl ZerodhaEndpoint {
pub fn path(&self) -> String {
match self {
Self::SessionToken => "/session/token".to_string(),
Self::SessionLogout => "/session/token".to_string(),
Self::UserProfile => "/user/profile".to_string(),
Self::Instruments => "/instruments".to_string(),
Self::InstrumentsExchange(exchange) => format!("/instruments/{}", exchange),
Self::Quote => "/quote".to_string(),
Self::QuoteOhlc => "/quote/ohlc".to_string(),
Self::QuoteLtp => "/quote/ltp".to_string(),
Self::HistoricalCandles(token, interval) => {
format!("/instruments/historical/{}/{}", token, interval)
}
Self::PlaceOrder(variety) => format!("/orders/{}", variety),
Self::ModifyOrder(variety, order_id) => format!("/orders/{}/{}", variety, order_id),
Self::CancelOrder(variety, order_id) => format!("/orders/{}/{}", variety, order_id),
Self::GetOrders => "/orders".to_string(),
Self::GetOrder(order_id) => format!("/orders/{}", order_id),
Self::GetTrades => "/trades".to_string(),
Self::GetOrderTrades(order_id) => format!("/orders/{}/trades", order_id),
Self::PlaceGtt => "/gtt/triggers".to_string(),
Self::ModifyGtt(trigger_id) => format!("/gtt/triggers/{}", trigger_id),
Self::DeleteGtt(trigger_id) => format!("/gtt/triggers/{}", trigger_id),
Self::GetGtts => "/gtt/triggers".to_string(),
Self::GetGtt(trigger_id) => format!("/gtt/triggers/{}", trigger_id),
Self::GetMargins => "/user/margins".to_string(),
Self::GetMarginsSegment(segment) => format!("/user/margins/{}", segment),
Self::OrderMargins => "/margins/orders".to_string(),
Self::BasketMargins => "/margins/basket".to_string(),
Self::Holdings => "/portfolio/holdings".to_string(),
Self::HoldingsAuctions => "/portfolio/holdings/auctions".to_string(),
Self::AuthorizeHoldings => "/portfolio/holdings/authorise".to_string(),
Self::Positions => "/portfolio/positions".to_string(),
Self::ConvertPosition => "/portfolio/positions".to_string(),
Self::BasketOrders => "/orders/baskets".to_string(),
}
}
}
pub fn format_symbol(symbol: &crate::core::types::Symbol) -> String {
let exchange = if symbol.quote.is_empty() || symbol.quote == "INR" {
"NSE"
} else {
&symbol.quote
};
format!("{}:{}", exchange, symbol.base.to_uppercase())
}
pub fn _parse_symbol(api_symbol: &str) -> crate::core::types::Symbol {
if let Some((exchange, tradingsymbol)) = api_symbol.split_once(':') {
crate::core::types::Symbol {
base: tradingsymbol.to_string(),
quote: exchange.to_string(),
raw: Some(api_symbol.to_string()),
}
} else {
crate::core::types::Symbol {
base: api_symbol.to_string(),
quote: "INR".to_string(),
raw: Some(api_symbol.to_string()),
}
}
}