use crate::core::types::AccountType;
#[derive(Debug, Clone)]
pub struct DhanUrls {
pub rest: &'static str,
pub ws_live_feed: &'static str,
pub ws_depth_20: &'static str,
pub ws_depth_200: &'static str,
}
impl DhanUrls {
pub const MAINNET: Self = Self {
rest: "https://api.dhan.co",
ws_live_feed: "wss://api-feed.dhan.co",
ws_depth_20: "wss://depth-api-feed.dhan.co/twentydepth",
ws_depth_200: "wss://full-depth-api.dhan.co/twohundreddepth",
};
pub const TESTNET: Self = Self {
rest: "https://api.dhan.co",
ws_live_feed: "wss://api-feed.dhan.co",
ws_depth_20: "wss://depth-api-feed.dhan.co/twentydepth",
ws_depth_200: "wss://full-depth-api.dhan.co/twohundreddepth",
};
pub fn rest_url(&self) -> &str {
self.rest
}
pub fn ws_url(&self) -> &str {
self.ws_live_feed
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DhanEndpoint {
GenerateToken,
RenewToken,
LTP,
OHLC,
Quote,
HistoricalDaily,
HistoricalIntraday,
OptionChain,
InstrumentList,
PlaceOrder,
ModifyOrder,
CancelOrder,
GetOrderBook,
GetOrder,
PlaceSlicedOrder,
PlaceSuperOrder,
ModifySuperOrder,
CancelSuperOrder,
GetSuperOrders,
GetSuperOrder,
PlaceForeverOrder,
ModifyForeverOrder,
CancelForeverOrder,
GetForeverOrders,
GetTradesByOrder,
GetTradeHistory,
GetRecentTrades,
GetHoldings,
GetPositions,
ConvertPosition,
GetFunds,
GetLedger,
GenerateTPIN,
GetEDISForm,
CheckEDISStatus,
KillSwitch,
}
impl DhanEndpoint {
pub fn path(&self) -> &'static str {
match self {
Self::GenerateToken => "/v2/access_token",
Self::RenewToken => "/v2/access_token/renew",
Self::LTP => "/v2/marketfeed/ltp",
Self::OHLC => "/v2/marketfeed/ohlc",
Self::Quote => "/v2/marketfeed/quote",
Self::HistoricalDaily => "/v2/charts/historical",
Self::HistoricalIntraday => "/v2/charts/intraday",
Self::OptionChain => "/v2/optionchain",
Self::InstrumentList => "/v2/instrument/{exchangeSegment}",
Self::PlaceOrder => "/v2/orders",
Self::ModifyOrder => "/v2/orders/{orderId}",
Self::CancelOrder => "/v2/orders/{orderId}",
Self::GetOrderBook => "/v2/orders",
Self::GetOrder => "/v2/orders/{orderId}",
Self::PlaceSlicedOrder => "/v2/orders/slicing",
Self::PlaceSuperOrder => "/v2/super/orders",
Self::ModifySuperOrder => "/v2/super/orders/{orderId}",
Self::CancelSuperOrder => "/v2/super/orders/{orderId}/{orderLeg}",
Self::GetSuperOrders => "/v2/super/orders",
Self::GetSuperOrder => "/v2/super/orders/{orderId}",
Self::PlaceForeverOrder => "/v2/forever/orders",
Self::ModifyForeverOrder => "/v2/forever/orders/{orderId}",
Self::CancelForeverOrder => "/v2/forever/orders/{orderId}",
Self::GetForeverOrders => "/v2/forever/orders",
Self::GetTradesByOrder => "/v2/trades/{orderId}",
Self::GetTradeHistory => "/v2/trades/{fromDate}/{toDate}/{page}",
Self::GetRecentTrades => "/v2/trades",
Self::GetHoldings => "/v2/holdings",
Self::GetPositions => "/v2/positions",
Self::ConvertPosition => "/v2/positions/convert",
Self::GetFunds => "/v2/funds",
Self::GetLedger => "/v2/ledger",
Self::GenerateTPIN => "/v2/edis/tpin",
Self::GetEDISForm => "/v2/edis/form",
Self::CheckEDISStatus => "/v2/edis/inquiry",
Self::KillSwitch => "/v2/killswitch",
}
}
pub fn requires_auth(&self) -> bool {
match self {
Self::InstrumentList => false,
_ => true,
}
}
pub fn method(&self) -> &'static str {
match self {
Self::GenerateToken
| Self::RenewToken
| Self::LTP
| Self::OHLC
| Self::Quote
| Self::HistoricalDaily
| Self::HistoricalIntraday
| Self::OptionChain
| Self::PlaceOrder
| Self::PlaceSlicedOrder
| Self::PlaceSuperOrder
| Self::PlaceForeverOrder
| Self::ConvertPosition
| Self::GenerateTPIN
| Self::GetEDISForm
| Self::CheckEDISStatus
| Self::KillSwitch => "POST",
Self::ModifyOrder | Self::ModifySuperOrder | Self::ModifyForeverOrder => "PUT",
Self::CancelOrder | Self::CancelSuperOrder | Self::CancelForeverOrder => "DELETE",
_ => "GET",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(dead_code)]
pub enum DhanExchangeSegment {
NseEq = 0,
NseFno = 1,
BseEq = 2,
McxComm = 3,
}
impl DhanExchangeSegment {
pub fn as_str(&self) -> &'static str {
match self {
Self::NseEq => "NSE_EQ",
Self::NseFno => "NSE_FNO",
Self::BseEq => "BSE_EQ",
Self::McxComm => "MCX_COMM",
}
}
pub fn _as_int(&self) -> u8 {
*self as u8
}
pub fn _from_str(s: &str) -> Option<Self> {
match s {
"NSE_EQ" => Some(Self::NseEq),
"NSE_FNO" => Some(Self::NseFno),
"BSE_EQ" => Some(Self::BseEq),
"MCX_COMM" => Some(Self::McxComm),
_ => None,
}
}
}
pub fn _format_symbol(trading_symbol: &str, segment: DhanExchangeSegment) -> String {
format!("{} ({})", trading_symbol, segment.as_str())
}
pub fn map_interval(interval: &str) -> &'static str {
match interval {
"1m" => "1",
"5m" => "5",
"15m" => "15",
"25m" => "25",
"1h" | "60m" => "60",
_ => "60", }
}
pub fn map_product_type(account_type: AccountType) -> &'static str {
match account_type {
AccountType::Spot => "CNC", AccountType::Margin => "INTRADAY", AccountType::FuturesCross => "MARGIN", AccountType::FuturesIsolated => "MARGIN",
_ => "CNC",
}
}