DhanHQ 2.5.0 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -1
- data/CHANGELOG.md +78 -6
- data/GUIDE.md +57 -39
- data/README.md +24 -23
- data/docs/API_DOCS_GAPS.md +128 -0
- data/docs/API_VERIFICATION.md +10 -11
- data/docs/ARCHIVE_README.md +16 -16
- data/docs/AUTHENTICATION.md +1 -1
- data/docs/CONSTANTS_REFERENCE.md +477 -0
- data/docs/DATA_API_PARAMETERS.md +7 -7
- data/docs/{rails_websocket_integration.md → RAILS_WEBSOCKET_INTEGRATION.md} +10 -10
- data/docs/{standalone_ruby_websocket_integration.md → STANDALONE_RUBY_WEBSOCKET_INTEGRATION.md} +32 -32
- data/docs/{technical_analysis.md → TECHNICAL_ANALYSIS.md} +3 -3
- data/docs/TESTING_GUIDE.md +84 -82
- data/docs/{websocket_integration.md → WEBSOCKET_INTEGRATION.md} +19 -19
- data/docs/WEBSOCKET_PROTOCOL.md +2 -2
- data/lib/DhanHQ/constants.rb +456 -151
- data/lib/DhanHQ/contracts/alert_order_contract.rb +37 -10
- data/lib/DhanHQ/contracts/base_contract.rb +22 -0
- data/lib/DhanHQ/contracts/edis_contract.rb +25 -0
- data/lib/DhanHQ/contracts/margin_calculator_contract.rb +27 -4
- data/lib/DhanHQ/contracts/modify_order_contract.rb +65 -12
- data/lib/DhanHQ/contracts/multi_scrip_margin_calc_request_contract.rb +23 -0
- data/lib/DhanHQ/contracts/order_contract.rb +171 -39
- data/lib/DhanHQ/contracts/place_order_contract.rb +14 -141
- data/lib/DhanHQ/contracts/pnl_based_exit_contract.rb +20 -0
- data/lib/DhanHQ/contracts/position_conversion_contract.rb +15 -3
- data/lib/DhanHQ/contracts/slice_order_contract.rb +10 -1
- data/lib/DhanHQ/contracts/user_ip_contract.rb +14 -0
- data/lib/DhanHQ/core/base_model.rb +13 -4
- data/lib/DhanHQ/helpers/response_helper.rb +2 -2
- data/lib/DhanHQ/helpers/validation_helper.rb +1 -1
- data/lib/DhanHQ/models/alert_order.rb +7 -11
- data/lib/DhanHQ/models/concerns/api_response_handler.rb +46 -0
- data/lib/DhanHQ/models/edis.rb +0 -9
- data/lib/DhanHQ/models/expired_options_data.rb +6 -12
- data/lib/DhanHQ/models/forever_order.rb +8 -5
- data/lib/DhanHQ/models/historical_data.rb +0 -8
- data/lib/DhanHQ/models/instrument.rb +1 -7
- data/lib/DhanHQ/models/instrument_helpers.rb +4 -4
- data/lib/DhanHQ/models/kill_switch.rb +1 -11
- data/lib/DhanHQ/models/margin.rb +2 -2
- data/lib/DhanHQ/models/order.rb +107 -126
- data/lib/DhanHQ/models/order_update.rb +7 -13
- data/lib/DhanHQ/models/pnl_exit.rb +1 -9
- data/lib/DhanHQ/models/position.rb +1 -1
- data/lib/DhanHQ/models/postback.rb +4 -13
- data/lib/DhanHQ/models/profile.rb +0 -10
- data/lib/DhanHQ/models/super_order.rb +13 -3
- data/lib/DhanHQ/models/trade.rb +11 -23
- data/lib/DhanHQ/resources/ip_setup.rb +16 -5
- data/lib/DhanHQ/resources/kill_switch.rb +9 -7
- data/lib/DhanHQ/resources/orders.rb +41 -41
- data/lib/DhanHQ/version.rb +1 -1
- data/lib/DhanHQ/ws/cmd_bus.rb +1 -1
- data/lib/DhanHQ/ws/orders/client.rb +6 -6
- data/lib/DhanHQ/ws/singleton_lock.rb +2 -1
- data/lib/dhanhq/analysis/options_buying_advisor.rb +2 -2
- data/lib/rubocop/cop/dhanhq/use_constants.rb +171 -0
- metadata +20 -23
- data/TODO-1.md +0 -14
- data/TODO.md +0 -127
- data/app/services/live/order_update_guard_support.rb +0 -75
- data/app/services/live/order_update_hub.rb +0 -76
- data/app/services/live/order_update_persistence_support.rb +0 -68
- data/docs/PR_2.2.0.md +0 -48
- data/examples/comprehensive_websocket_examples.rb +0 -148
- data/examples/instrument_finder_test.rb +0 -195
- data/examples/live_order_updates.rb +0 -118
- data/examples/market_depth_example.rb +0 -144
- data/examples/market_feed_example.rb +0 -81
- data/examples/order_update_example.rb +0 -105
- data/examples/trading_fields_example.rb +0 -215
- /data/docs/{live_order_updates.md → LIVE_ORDER_UPDATES.md} +0 -0
- /data/docs/{rails_integration.md → RAILS_INTEGRATION.md} +0 -0
data/docs/ARCHIVE_README.md
CHANGED
|
@@ -81,11 +81,11 @@ To override defaults (base URL, WebSocket settings, partner credentials), set
|
|
|
81
81
|
|
|
82
82
|
```ruby
|
|
83
83
|
order = DhanHQ::Models::Order.new(
|
|
84
|
-
transaction_type:
|
|
85
|
-
exchange_segment:
|
|
86
|
-
product_type:
|
|
87
|
-
order_type:
|
|
88
|
-
validity:
|
|
84
|
+
transaction_type: DhanHQ::Constants::TransactionType::BUY,
|
|
85
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_FNO,
|
|
86
|
+
product_type: DhanHQ::Constants::ProductType::MARGIN,
|
|
87
|
+
order_type: DhanHQ::Constants::OrderType::LIMIT,
|
|
88
|
+
validity: DhanHQ::Constants::Validity::DAY,
|
|
89
89
|
security_id: "43492",
|
|
90
90
|
quantity: 125,
|
|
91
91
|
price: 100.0
|
|
@@ -125,7 +125,7 @@ puts orders.count
|
|
|
125
125
|
✅ Querying Orders
|
|
126
126
|
|
|
127
127
|
```ruby
|
|
128
|
-
pending_orders = DhanHQ::Models::Order.where(status:
|
|
128
|
+
pending_orders = DhanHQ::Models::Order.where(status: DhanHQ::Constants::OrderStatus::PENDING)
|
|
129
129
|
puts pending_orders.first.order_id
|
|
130
130
|
```
|
|
131
131
|
|
|
@@ -142,7 +142,7 @@ position.exit!
|
|
|
142
142
|
#### Place
|
|
143
143
|
|
|
144
144
|
```ruby
|
|
145
|
-
order = DhanHQ::Models::Order.new(transaction_type:
|
|
145
|
+
order = DhanHQ::Models::Order.new(transaction_type: DhanHQ::Constants::TransactionType::BUY, security_id: "123", quantity: 1)
|
|
146
146
|
order.save
|
|
147
147
|
```
|
|
148
148
|
|
|
@@ -170,7 +170,7 @@ DhanHQ::Models::Trade.find_by_order_id("452501297117")
|
|
|
170
170
|
```ruby
|
|
171
171
|
positions = DhanHQ::Models::Position.all
|
|
172
172
|
active = DhanHQ::Models::Position.active
|
|
173
|
-
DhanHQ::Models::Position.convert(position_id: "1", product_type:
|
|
173
|
+
DhanHQ::Models::Position.convert(position_id: "1", product_type: DhanHQ::Constants::ProductType::CNC)
|
|
174
174
|
```
|
|
175
175
|
|
|
176
176
|
### Holdings
|
|
@@ -196,8 +196,8 @@ DhanHQ::Models::OptionChain.fetch_expiry_list(security_id: "1333")
|
|
|
196
196
|
### Historical Data
|
|
197
197
|
|
|
198
198
|
```ruby
|
|
199
|
-
DhanHQ::Models::HistoricalData.daily(security_id: "1333", exchange_segment:
|
|
200
|
-
DhanHQ::Models::HistoricalData.intraday(security_id: "1333", exchange_segment:
|
|
199
|
+
DhanHQ::Models::HistoricalData.daily(security_id: "1333", exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ, instrument: DhanHQ::Constants::InstrumentType::EQUITY, from_date: "2024-01-01", to_date: "2024-01-31")
|
|
200
|
+
DhanHQ::Models::HistoricalData.intraday(security_id: "1333", exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ, instrument: DhanHQ::Constants::InstrumentType::EQUITY, interval: "15", from_date: "2024-09-11", to_date: "2024-09-15")
|
|
201
201
|
```
|
|
202
202
|
|
|
203
203
|
### Instrument Model with Convenience Methods
|
|
@@ -278,7 +278,7 @@ bundle exec rake release
|
|
|
278
278
|
```ruby
|
|
279
279
|
{
|
|
280
280
|
kind: :quote, # :ticker | :quote | :full | :oi | :prev_close | :misc
|
|
281
|
-
segment:
|
|
281
|
+
segment: DhanHQ::Constants::ExchangeSegment::NSE_FNO, # string enum
|
|
282
282
|
security_id: "12345",
|
|
283
283
|
ltp: 101.5,
|
|
284
284
|
ts: 1723791300, # LTT epoch (sec) if present
|
|
@@ -303,11 +303,11 @@ ws.on(:tick) do |t|
|
|
|
303
303
|
end
|
|
304
304
|
|
|
305
305
|
# Subscribe instruments (≤100 per frame; send multiple frames if needed)
|
|
306
|
-
ws.subscribe_one(segment:
|
|
307
|
-
ws.subscribe_one(segment:
|
|
306
|
+
ws.subscribe_one(segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "13") # NIFTY index value
|
|
307
|
+
ws.subscribe_one(segment: DhanHQ::Constants::ExchangeSegment::NSE_FNO, security_id: "12345") # an option
|
|
308
308
|
|
|
309
309
|
# Unsubscribe
|
|
310
|
-
ws.unsubscribe_one(segment:
|
|
310
|
+
ws.unsubscribe_one(segment: DhanHQ::Constants::ExchangeSegment::NSE_FNO, security_id: "12345")
|
|
311
311
|
|
|
312
312
|
# Graceful disconnect (sends broker disconnect code 12, no reconnect)
|
|
313
313
|
ws.disconnect!
|
|
@@ -412,8 +412,8 @@ end
|
|
|
412
412
|
|
|
413
413
|
```ruby
|
|
414
414
|
INDICES = [
|
|
415
|
-
{ segment:
|
|
416
|
-
{ segment:
|
|
415
|
+
{ segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "13" }, # NIFTY index value
|
|
416
|
+
{ segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "25" } # BANKNIFTY index value
|
|
417
417
|
]
|
|
418
418
|
|
|
419
419
|
Rails.application.config.to_prepare do
|
data/docs/AUTHENTICATION.md
CHANGED
|
@@ -105,7 +105,7 @@ Rescue `AuthenticationError` for local config/token resolution failures; rescue
|
|
|
105
105
|
|
|
106
106
|
- [README.md](../README.md) — Configuration and “Dynamic access token”
|
|
107
107
|
- [GUIDE.md](../GUIDE.md) — Dynamic access token and RenewToken
|
|
108
|
-
- [
|
|
108
|
+
- [RAILS_INTEGRATION.md](RAILS_INTEGRATION.md) — Rails initializer with optional `access_token_provider` and RenewToken
|
|
109
109
|
- [TESTING_GUIDE.md](TESTING_GUIDE.md) — Config examples and RenewToken
|
|
110
110
|
- [CHANGELOG.md](../CHANGELOG.md) — 2.2.0 and 2.2.1 auth and token changes
|
|
111
111
|
|
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
# DhanHQ API v2 Constants Reference
|
|
2
|
+
|
|
3
|
+
Complete reference of all constants available in the DhanHQ API v2. These constants should be defined in your `dhanhq-client` Ruby gem.
|
|
4
|
+
|
|
5
|
+
**Source:** [DhanHQ API v2 Documentation](https://dhanhq.co/docs/v2/)
|
|
6
|
+
**Reference:** [Annexure](https://dhanhq.co/docs/v2/annexure/)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Exchange Segments
|
|
11
|
+
|
|
12
|
+
Exchange segments for different markets and instruments.
|
|
13
|
+
|
|
14
|
+
| Constant | Value | Description | Enum Value |
|
|
15
|
+
|----------|-------|-------------|------------|
|
|
16
|
+
| `IDX_I` | `"IDX_I"` | Index - Index Value | 0 |
|
|
17
|
+
| `NSE_EQ` | `"NSE_EQ"` | NSE - Equity Cash | 1 |
|
|
18
|
+
| `NSE_FNO` | `"NSE_FNO"` | NSE - Futures & Options | 2 |
|
|
19
|
+
| `NSE_CURRENCY` | `"NSE_CURRENCY"` | NSE - Currency | 3 |
|
|
20
|
+
| `BSE_EQ` | `"BSE_EQ"` | BSE - Equity Cash | 4 |
|
|
21
|
+
| `MCX_COMM` | `"MCX_COMM"` | MCX - Commodity | 5 |
|
|
22
|
+
| `BSE_CURRENCY` | `"BSE_CURRENCY"` | BSE - Currency | 7 |
|
|
23
|
+
| `BSE_FNO` | `"BSE_FNO"` | BSE - Futures & Options | 8 |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Product Types
|
|
28
|
+
|
|
29
|
+
Product types for order placement.
|
|
30
|
+
|
|
31
|
+
**Note:** CO & BO product types are valid only for INTRADAY.
|
|
32
|
+
|
|
33
|
+
| Constant | Value | Description |
|
|
34
|
+
|----------|-------|-------------|
|
|
35
|
+
| `CNC` | `"CNC"` | Cash & Carry for equity deliveries |
|
|
36
|
+
| `INTRADAY` | `"INTRADAY"` | Intraday for Equity, Futures & Options |
|
|
37
|
+
| `MARGIN` | `"MARGIN"` | Carry Forward in Futures & Options |
|
|
38
|
+
| `MTF` | `"MTF"` | Margin Trading Facility |
|
|
39
|
+
| `CO` | `"CO"` | Cover Order (Intraday only) |
|
|
40
|
+
| `BO` | `"BO"` | Bracket Order (Intraday only) |
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Transaction Types
|
|
45
|
+
|
|
46
|
+
Buy/Sell transaction types.
|
|
47
|
+
|
|
48
|
+
| Constant | Value | Description |
|
|
49
|
+
|----------|-------|-------------|
|
|
50
|
+
| `BUY` | `"BUY"` | Buy transaction |
|
|
51
|
+
| `SELL` | `"SELL"` | Sell transaction |
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Order Types
|
|
56
|
+
|
|
57
|
+
Order types for placement and modification.
|
|
58
|
+
|
|
59
|
+
| Constant | Value | Description |
|
|
60
|
+
|----------|-------|-------------|
|
|
61
|
+
| `LIMIT` | `"LIMIT"` | Limit order |
|
|
62
|
+
| `MARKET` | `"MARKET"` | Market order |
|
|
63
|
+
| `STOP_LOSS` | `"STOP_LOSS"` | Stop loss limit order |
|
|
64
|
+
| `STOP_LOSS_MARKET` | `"STOP_LOSS_MARKET"` | Stop loss market order |
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Validity Types
|
|
69
|
+
|
|
70
|
+
Order validity types.
|
|
71
|
+
|
|
72
|
+
| Constant | Value | Description |
|
|
73
|
+
|----------|-------|-------------|
|
|
74
|
+
| `DAY` | `"DAY"` | Valid for the day |
|
|
75
|
+
| `IOC` | `"IOC"` | Immediate or Cancel |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Order Status
|
|
80
|
+
|
|
81
|
+
Order status values across the lifecycle.
|
|
82
|
+
|
|
83
|
+
| Constant | Value | Description |
|
|
84
|
+
|----------|-------|-------------|
|
|
85
|
+
| `TRANSIT` | `"TRANSIT"` | Did not reach the exchange server |
|
|
86
|
+
| `PENDING` | `"PENDING"` | Awaiting execution |
|
|
87
|
+
| `CLOSED` | `"CLOSED"` | Used for Super Order, once both entry and exit orders are placed |
|
|
88
|
+
| `TRIGGERED` | `"TRIGGERED"` | Used for Super Order, if Target or Stop Loss leg is triggered |
|
|
89
|
+
| `REJECTED` | `"REJECTED"` | Rejected by broker/exchange |
|
|
90
|
+
| `CANCELLED` | `"CANCELLED"` | Cancelled by user |
|
|
91
|
+
| `PART_TRADED` | `"PART_TRADED"` | Partial Quantity traded successfully |
|
|
92
|
+
| `TRADED` | `"TRADED"` | Executed successfully |
|
|
93
|
+
| `EXPIRED` | `"EXPIRED"` | Order expired |
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## After Market Order Time
|
|
98
|
+
|
|
99
|
+
AMO (After Market Order) timing options.
|
|
100
|
+
|
|
101
|
+
| Constant | Value | Description |
|
|
102
|
+
|----------|-------|-------------|
|
|
103
|
+
| `PRE_OPEN` | `"PRE_OPEN"` | AMO pumped at pre-market session |
|
|
104
|
+
| `OPEN` | `"OPEN"` | AMO pumped at market open |
|
|
105
|
+
| `OPEN_30` | `"OPEN_30"` | AMO pumped 30 minutes after market open |
|
|
106
|
+
| `OPEN_60` | `"OPEN_60"` | AMO pumped 60 minutes after market open |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Expiry Code
|
|
111
|
+
|
|
112
|
+
Expiry codes for futures and options contracts.
|
|
113
|
+
|
|
114
|
+
| Constant | Value | Description |
|
|
115
|
+
|----------|-------|-------------|
|
|
116
|
+
| `CURRENT` | `0` | Current Expiry/Near Expiry |
|
|
117
|
+
| `NEXT` | `1` | Next Expiry |
|
|
118
|
+
| `FAR` | `2` | Far Expiry |
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Instrument Types
|
|
123
|
+
|
|
124
|
+
Instrument types across different exchanges.
|
|
125
|
+
|
|
126
|
+
| Constant | Value | Description |
|
|
127
|
+
|----------|-------|-------------|
|
|
128
|
+
| `INDEX` | `"INDEX"` | Index |
|
|
129
|
+
| `FUTIDX` | `"FUTIDX"` | Futures of Index |
|
|
130
|
+
| `OPTIDX` | `"OPTIDX"` | Options of Index |
|
|
131
|
+
| `EQUITY` | `"EQUITY"` | Equity |
|
|
132
|
+
| `FUTSTK` | `"FUTSTK"` | Futures of Stock |
|
|
133
|
+
| `OPTSTK` | `"OPTSTK"` | Options of Stock |
|
|
134
|
+
| `FUTCOM` | `"FUTCOM"` | Futures of Commodity |
|
|
135
|
+
| `OPTFUT` | `"OPTFUT"` | Options of Commodity Futures |
|
|
136
|
+
| `FUTCUR` | `"FUTCUR"` | Futures of Currency |
|
|
137
|
+
| `OPTCUR` | `"OPTCUR"` | Options of Currency |
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Option Types
|
|
142
|
+
|
|
143
|
+
Option types for derivatives trading.
|
|
144
|
+
|
|
145
|
+
| Constant | Value | Description |
|
|
146
|
+
|----------|-------|-------------|
|
|
147
|
+
| `CALL` | `"CALL"` | Call option |
|
|
148
|
+
| `PUT` | `"PUT"` | Put option |
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Leg Names
|
|
153
|
+
|
|
154
|
+
Leg names for Bracket Orders, Cover Orders, Super Orders, and Forever Orders.
|
|
155
|
+
|
|
156
|
+
| Constant | Value | Description |
|
|
157
|
+
|----------|-------|-------------|
|
|
158
|
+
| `ENTRY_LEG` | `"ENTRY_LEG"` | Entry leg |
|
|
159
|
+
| `TARGET_LEG` | `"TARGET_LEG"` | Target/profit leg |
|
|
160
|
+
| `STOP_LOSS_LEG` | `"STOP_LOSS_LEG"` | Stop loss leg |
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Order Flags
|
|
165
|
+
|
|
166
|
+
Order flags for Forever Orders.
|
|
167
|
+
|
|
168
|
+
| Constant | Value | Description |
|
|
169
|
+
|----------|-------|-------------|
|
|
170
|
+
| `SINGLE` | `"SINGLE"` | Single order |
|
|
171
|
+
| `OCO` | `"OCO"` | One-Cancels-the-Other order |
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Position Types
|
|
176
|
+
|
|
177
|
+
Position types for position conversion.
|
|
178
|
+
|
|
179
|
+
| Constant | Value | Description |
|
|
180
|
+
|----------|-------|-------------|
|
|
181
|
+
| `LONG` | `"LONG"` | Long position |
|
|
182
|
+
| `SHORT` | `"SHORT"` | Short position |
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Feed Request Codes (WebSocket)
|
|
187
|
+
|
|
188
|
+
Feed request codes for Live Market Feed WebSocket subscription.
|
|
189
|
+
|
|
190
|
+
| Constant | Value | Description |
|
|
191
|
+
|----------|-------|-------------|
|
|
192
|
+
| `CONNECT` | `11` | Connect Feed |
|
|
193
|
+
| `DISCONNECT` | `12` | Disconnect Feed |
|
|
194
|
+
| `SUBSCRIBE_TICKER` | `15` | Subscribe - Ticker Packet |
|
|
195
|
+
| `UNSUBSCRIBE_TICKER` | `16` | Unsubscribe - Ticker Packet |
|
|
196
|
+
| `SUBSCRIBE_QUOTE` | `17` | Subscribe - Quote Packet |
|
|
197
|
+
| `UNSUBSCRIBE_QUOTE` | `18` | Unsubscribe - Quote Packet |
|
|
198
|
+
| `SUBSCRIBE_FULL` | `21` | Subscribe - Full Packet |
|
|
199
|
+
| `UNSUBSCRIBE_FULL` | `22` | Unsubscribe - Full Packet |
|
|
200
|
+
| `SUBSCRIBE_DEPTH` | `23` | Subscribe - Full Market Depth |
|
|
201
|
+
| `UNSUBSCRIBE_DEPTH` | `24` | Unsubscribe - Full Market Depth |
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Feed Response Codes (WebSocket)
|
|
206
|
+
|
|
207
|
+
Feed response codes for Live Market Feed WebSocket.
|
|
208
|
+
|
|
209
|
+
| Constant | Value | Description |
|
|
210
|
+
|----------|-------|-------------|
|
|
211
|
+
| `INDEX_PACKET` | `1` | Index Packet |
|
|
212
|
+
| `TICKER_PACKET` | `2` | Ticker Packet |
|
|
213
|
+
| `QUOTE_PACKET` | `4` | Quote Packet |
|
|
214
|
+
| `OI_PACKET` | `5` | OI (Open Interest) Packet |
|
|
215
|
+
| `PREV_CLOSE_PACKET` | `6` | Previous Close Packet |
|
|
216
|
+
| `MARKET_STATUS_PACKET` | `7` | Market Status Packet |
|
|
217
|
+
| `FULL_PACKET` | `8` | Full Packet (Quote + OI + Depth) |
|
|
218
|
+
| `FEED_DISCONNECT` | `50` | Feed Disconnect |
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Conditional Triggers
|
|
223
|
+
|
|
224
|
+
### Comparison Types
|
|
225
|
+
|
|
226
|
+
Comparison types for conditional trigger alerts.
|
|
227
|
+
|
|
228
|
+
| Constant | Value | Description | Mandatory Fields |
|
|
229
|
+
|----------|-------|-------------|------------------|
|
|
230
|
+
| `TECHNICAL_WITH_VALUE` | `"TECHNICAL_WITH_VALUE"` | Compare technical indicator against fixed value | indicatorName, operator, timeFrame, comparingValue |
|
|
231
|
+
| `TECHNICAL_WITH_INDICATOR` | `"TECHNICAL_WITH_INDICATOR"` | Compare technical indicator against another indicator | indicatorName, operator, timeFrame, comparingIndicatorName |
|
|
232
|
+
| `TECHNICAL_WITH_CLOSE` | `"TECHNICAL_WITH_CLOSE"` | Compare technical indicator with closing price | indicatorName, operator, timeFrame |
|
|
233
|
+
| `PRICE_WITH_VALUE` | `"PRICE_WITH_VALUE"` | Compare market price against fixed value | operator, comparingValue |
|
|
234
|
+
|
|
235
|
+
### Indicator Names
|
|
236
|
+
|
|
237
|
+
Technical indicators for conditional triggers.
|
|
238
|
+
|
|
239
|
+
#### Simple Moving Averages
|
|
240
|
+
|
|
241
|
+
| Constant | Value | Description |
|
|
242
|
+
|----------|-------|-------------|
|
|
243
|
+
| `SMA_5` | `"SMA_5"` | Simple Moving Average (5 periods) |
|
|
244
|
+
| `SMA_10` | `"SMA_10"` | Simple Moving Average (10 periods) |
|
|
245
|
+
| `SMA_20` | `"SMA_20"` | Simple Moving Average (20 periods) |
|
|
246
|
+
| `SMA_50` | `"SMA_50"` | Simple Moving Average (50 periods) |
|
|
247
|
+
| `SMA_100` | `"SMA_100"` | Simple Moving Average (100 periods) |
|
|
248
|
+
| `SMA_200` | `"SMA_200"` | Simple Moving Average (200 periods) |
|
|
249
|
+
|
|
250
|
+
#### Exponential Moving Averages
|
|
251
|
+
|
|
252
|
+
| Constant | Value | Description |
|
|
253
|
+
|----------|-------|-------------|
|
|
254
|
+
| `EMA_5` | `"EMA_5"` | Exponential Moving Average (5 periods) |
|
|
255
|
+
| `EMA_10` | `"EMA_10"` | Exponential Moving Average (10 periods) |
|
|
256
|
+
| `EMA_20` | `"EMA_20"` | Exponential Moving Average (20 periods) |
|
|
257
|
+
| `EMA_50` | `"EMA_50"` | Exponential Moving Average (50 periods) |
|
|
258
|
+
| `EMA_100` | `"EMA_100"` | Exponential Moving Average (100 periods) |
|
|
259
|
+
| `EMA_200` | `"EMA_200"` | Exponential Moving Average (200 periods) |
|
|
260
|
+
|
|
261
|
+
#### Other Indicators
|
|
262
|
+
|
|
263
|
+
| Constant | Value | Description |
|
|
264
|
+
|----------|-------|-------------|
|
|
265
|
+
| `BB_UPPER` | `"BB_UPPER"` | Upper Bollinger Band |
|
|
266
|
+
| `BB_LOWER` | `"BB_LOWER"` | Lower Bollinger Band |
|
|
267
|
+
| `RSI_14` | `"RSI_14"` | Relative Strength Index (14 periods) |
|
|
268
|
+
| `ATR_14` | `"ATR_14"` | Average True Range (14 periods) |
|
|
269
|
+
| `STOCHASTIC` | `"STOCHASTIC"` | Stochastic Oscillator |
|
|
270
|
+
| `STOCHRSI_14` | `"STOCHRSI_14"` | Stochastic RSI (14 periods) |
|
|
271
|
+
| `MACD_26` | `"MACD_26"` | MACD long-term component |
|
|
272
|
+
| `MACD_12` | `"MACD_12"` | MACD short-term component |
|
|
273
|
+
| `MACD_HIST` | `"MACD_HIST"` | MACD histogram |
|
|
274
|
+
|
|
275
|
+
### Operators
|
|
276
|
+
|
|
277
|
+
Operators for conditional trigger comparisons.
|
|
278
|
+
|
|
279
|
+
| Constant | Value | Description |
|
|
280
|
+
|----------|-------|-------------|
|
|
281
|
+
| `CROSSING_UP` | `"CROSSING_UP"` | Crosses above |
|
|
282
|
+
| `CROSSING_DOWN` | `"CROSSING_DOWN"` | Crosses below |
|
|
283
|
+
| `CROSSING_ANY_SIDE` | `"CROSSING_ANY_SIDE"` | Crosses either side |
|
|
284
|
+
| `GREATER_THAN` | `"GREATER_THAN"` | Greater than |
|
|
285
|
+
| `LESS_THAN` | `"LESS_THAN"` | Less than |
|
|
286
|
+
| `GREATER_THAN_EQUAL` | `"GREATER_THAN_EQUAL"` | Greater than or equal |
|
|
287
|
+
| `LESS_THAN_EQUAL` | `"LESS_THAN_EQUAL"` | Less than or equal |
|
|
288
|
+
| `EQUAL` | `"EQUAL"` | Equal |
|
|
289
|
+
| `NOT_EQUAL` | `"NOT_EQUAL"` | Not equal |
|
|
290
|
+
|
|
291
|
+
### Trigger Status
|
|
292
|
+
|
|
293
|
+
Status values for conditional triggers.
|
|
294
|
+
|
|
295
|
+
| Constant | Value | Description |
|
|
296
|
+
|----------|-------|-------------|
|
|
297
|
+
| `ACTIVE` | `"ACTIVE"` | Alert is currently active |
|
|
298
|
+
| `TRIGGERED` | `"TRIGGERED"` | Alert condition met |
|
|
299
|
+
| `EXPIRED` | `"EXPIRED"` | Alert expired |
|
|
300
|
+
| `CANCELLED` | `"CANCELLED"` | Alert cancelled |
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Error Codes
|
|
305
|
+
|
|
306
|
+
### Trading API Error Codes
|
|
307
|
+
|
|
308
|
+
Error codes for Trading APIs (DH-900 series).
|
|
309
|
+
|
|
310
|
+
| Constant | Code | Description |
|
|
311
|
+
|----------|------|-------------|
|
|
312
|
+
| `INVALID_AUTHENTICATION` | `"DH-901"` | Client ID or access token invalid/expired |
|
|
313
|
+
| `INVALID_ACCESS` | `"DH-902"` | User not subscribed to Data APIs or no Trading API access |
|
|
314
|
+
| `USER_ACCOUNT` | `"DH-903"` | User account errors (segments, requirements) |
|
|
315
|
+
| `RATE_LIMIT` | `"DH-904"` | Rate limit exceeded |
|
|
316
|
+
| `INPUT_EXCEPTION` | `"DH-905"` | Missing fields, bad parameter values |
|
|
317
|
+
| `ORDER_ERROR` | `"DH-906"` | Incorrect order request |
|
|
318
|
+
| `DATA_ERROR` | `"DH-907"` | Unable to fetch data, incorrect parameters |
|
|
319
|
+
| `INTERNAL_SERVER_ERROR` | `"DH-908"` | Server processing error |
|
|
320
|
+
| `NETWORK_ERROR` | `"DH-909"` | Network communication error |
|
|
321
|
+
| `OTHERS` | `"DH-910"` | Other errors |
|
|
322
|
+
|
|
323
|
+
### Data API Error Codes
|
|
324
|
+
|
|
325
|
+
Error codes for Data APIs (800 series).
|
|
326
|
+
|
|
327
|
+
| Constant | Code | Description |
|
|
328
|
+
|----------|------|-------------|
|
|
329
|
+
| `INTERNAL_SERVER_ERROR` | `800` | Internal Server Error |
|
|
330
|
+
| `INSTRUMENTS_LIMIT` | `804` | Requested instruments exceed limit |
|
|
331
|
+
| `TOO_MANY_REQUESTS` | `805` | Rate limit exceeded |
|
|
332
|
+
| `NOT_SUBSCRIBED` | `806` | Data APIs not subscribed |
|
|
333
|
+
| `TOKEN_EXPIRED` | `807` | Access token expired |
|
|
334
|
+
| `AUTH_FAILED` | `808` | Client ID or Access Token invalid |
|
|
335
|
+
| `INVALID_TOKEN` | `809` | Access token invalid |
|
|
336
|
+
| `INVALID_CLIENT_ID` | `810` | Client ID invalid |
|
|
337
|
+
| `INVALID_EXPIRY_DATE` | `811` | Invalid Expiry Date |
|
|
338
|
+
| `INVALID_DATE_FORMAT` | `812` | Invalid Date Format |
|
|
339
|
+
| `INVALID_SECURITY_ID` | `813` | Invalid SecurityId |
|
|
340
|
+
| `INVALID_REQUEST` | `814` | Invalid Request |
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Usage Examples
|
|
345
|
+
|
|
346
|
+
### Basic Order Placement
|
|
347
|
+
|
|
348
|
+
```ruby
|
|
349
|
+
require 'dhanhq'
|
|
350
|
+
|
|
351
|
+
# Using constants
|
|
352
|
+
DhanHQ.place_order(
|
|
353
|
+
transaction_type: DhanHQ::Constants::TransactionType::BUY,
|
|
354
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
355
|
+
product_type: DhanHQ::Constants::ProductType::INTRADAY,
|
|
356
|
+
order_type: DhanHQ::Constants::OrderType::MARKET,
|
|
357
|
+
validity: DhanHQ::Constants::Validity::DAY,
|
|
358
|
+
security_id: "1333",
|
|
359
|
+
quantity: 10
|
|
360
|
+
)
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### Conditional Trigger
|
|
364
|
+
|
|
365
|
+
Condition must include `exchange_segment`, `exp_date`, and `frequency`. For technical comparisons, `indicator_name` and `time_frame` are required. See [Conditional Triggers API](https://dhanhq.co/docs/v2/conditional-trigger/).
|
|
366
|
+
|
|
367
|
+
```ruby
|
|
368
|
+
# Create a conditional trigger when RSI crosses above 30 (technical comparison)
|
|
369
|
+
DhanHQ::Models::AlertOrder.create(
|
|
370
|
+
condition: {
|
|
371
|
+
security_id: "1333",
|
|
372
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
373
|
+
comparison_type: DhanHQ::Constants::ComparisonType::TECHNICAL_WITH_VALUE,
|
|
374
|
+
indicator_name: DhanHQ::Constants::IndicatorName::RSI_14,
|
|
375
|
+
time_frame: "DAY",
|
|
376
|
+
operator: DhanHQ::Constants::Operator::CROSSING_UP,
|
|
377
|
+
comparing_value: 30,
|
|
378
|
+
exp_date: (Date.today + 365).strftime("%Y-%m-%d"),
|
|
379
|
+
frequency: "ONCE"
|
|
380
|
+
},
|
|
381
|
+
orders: [
|
|
382
|
+
{
|
|
383
|
+
transaction_type: DhanHQ::Constants::TransactionType::BUY,
|
|
384
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
385
|
+
product_type: DhanHQ::Constants::ProductType::CNC,
|
|
386
|
+
order_type: DhanHQ::Constants::OrderType::LIMIT,
|
|
387
|
+
security_id: "1333",
|
|
388
|
+
quantity: 10,
|
|
389
|
+
validity: DhanHQ::Constants::Validity::DAY,
|
|
390
|
+
price: 250.0
|
|
391
|
+
}
|
|
392
|
+
]
|
|
393
|
+
)
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### WebSocket Subscription
|
|
397
|
+
|
|
398
|
+
```ruby
|
|
399
|
+
# Subscribe to ticker feed
|
|
400
|
+
DhanHQ::WebSocket.send_request(
|
|
401
|
+
request_code: DhanHQ::Constants::FeedRequest::SUBSCRIBE_TICKER,
|
|
402
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
403
|
+
security_id: "1333"
|
|
404
|
+
)
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## Implementation Notes
|
|
410
|
+
|
|
411
|
+
### Module Structure
|
|
412
|
+
|
|
413
|
+
The constants should be organized in nested modules:
|
|
414
|
+
|
|
415
|
+
```ruby
|
|
416
|
+
module DhanHQ
|
|
417
|
+
module Constants
|
|
418
|
+
module ExchangeSegment
|
|
419
|
+
NSE_EQ = "NSE_EQ"
|
|
420
|
+
# ...
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
module ProductType
|
|
424
|
+
CNC = "CNC"
|
|
425
|
+
# ...
|
|
426
|
+
end
|
|
427
|
+
# ... other constant modules
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Validation Helpers
|
|
433
|
+
|
|
434
|
+
Consider adding validation helpers:
|
|
435
|
+
|
|
436
|
+
```ruby
|
|
437
|
+
module DhanHQ
|
|
438
|
+
module Constants
|
|
439
|
+
def self.valid?(module_name, value)
|
|
440
|
+
const_get(module_name)::ALL.include?(value)
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
def self.all_for(module_name)
|
|
444
|
+
const_get(module_name)::ALL
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
# Usage
|
|
450
|
+
DhanHQ::Constants.valid?(:ExchangeSegment, "NSE_EQ") # => true
|
|
451
|
+
DhanHQ::Constants.all_for(:OrderType) # => ["LIMIT", "MARKET", ...]
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
## Rate Limits
|
|
457
|
+
|
|
458
|
+
| API Type | Per Second | Per Minute | Per Hour | Per Day |
|
|
459
|
+
|----------|------------|------------|----------|---------|
|
|
460
|
+
| Order APIs | 10 | 250 | 1,000 | 7,000 |
|
|
461
|
+
| Data APIs | 5 | - | - | 100,000 |
|
|
462
|
+
| Quote APIs | 1 | Unlimited | Unlimited | Unlimited |
|
|
463
|
+
| Non Trading APIs | 20 | Unlimited | Unlimited | Unlimited |
|
|
464
|
+
|
|
465
|
+
**Note:** Order modifications are capped at 25 modifications per order.
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## References
|
|
470
|
+
|
|
471
|
+
- [DhanHQ API v2 Documentation](https://dhanhq.co/docs/v2/)
|
|
472
|
+
- [Annexure - Constants Reference](https://dhanhq.co/docs/v2/annexure/)
|
|
473
|
+
- [Orders API](https://dhanhq.co/docs/v2/orders/)
|
|
474
|
+
- [Super Order API](https://dhanhq.co/docs/v2/super-order/)
|
|
475
|
+
- [Forever Order API](https://dhanhq.co/docs/v2/forever/)
|
|
476
|
+
- [Conditional Triggers API](https://dhanhq.co/docs/v2/conditional-trigger/)
|
|
477
|
+
- [Live Market Feed](https://dhanhq.co/docs/v2/live-market-feed/)
|
data/docs/DATA_API_PARAMETERS.md
CHANGED
|
@@ -93,8 +93,8 @@ response = DhanHQ::Models::MarketFeed.quote(payload)
|
|
|
93
93
|
```ruby
|
|
94
94
|
data = DhanHQ::Models::HistoricalData.daily(
|
|
95
95
|
security_id: "1333",
|
|
96
|
-
exchange_segment:
|
|
97
|
-
instrument:
|
|
96
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
97
|
+
instrument: DhanHQ::Constants::InstrumentType::EQUITY,
|
|
98
98
|
from_date: "2022-01-08",
|
|
99
99
|
to_date: "2022-02-08"
|
|
100
100
|
)
|
|
@@ -126,8 +126,8 @@ data = DhanHQ::Models::HistoricalData.daily(
|
|
|
126
126
|
```ruby
|
|
127
127
|
data = DhanHQ::Models::HistoricalData.intraday(
|
|
128
128
|
security_id: "1333",
|
|
129
|
-
exchange_segment:
|
|
130
|
-
instrument:
|
|
129
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
130
|
+
instrument: DhanHQ::Constants::InstrumentType::EQUITY,
|
|
131
131
|
interval: "15",
|
|
132
132
|
from_date: "2024-09-11",
|
|
133
133
|
to_date: "2024-09-15"
|
|
@@ -155,7 +155,7 @@ data = DhanHQ::Models::HistoricalData.intraday(
|
|
|
155
155
|
```ruby
|
|
156
156
|
chain = DhanHQ::Models::OptionChain.fetch(
|
|
157
157
|
underlying_scrip: 13,
|
|
158
|
-
underlying_seg:
|
|
158
|
+
underlying_seg: DhanHQ::Constants::ExchangeSegment::IDX_I,
|
|
159
159
|
expiry: "2024-10-31"
|
|
160
160
|
)
|
|
161
161
|
```
|
|
@@ -178,7 +178,7 @@ chain = DhanHQ::Models::OptionChain.fetch(
|
|
|
178
178
|
```ruby
|
|
179
179
|
expiries = DhanHQ::Models::OptionChain.fetch_expiry_list(
|
|
180
180
|
underlying_scrip: 13,
|
|
181
|
-
underlying_seg:
|
|
181
|
+
underlying_seg: DhanHQ::Constants::ExchangeSegment::IDX_I
|
|
182
182
|
)
|
|
183
183
|
```
|
|
184
184
|
|
|
@@ -219,7 +219,7 @@ expiries = DhanHQ::Models::OptionChain.fetch_expiry_list(
|
|
|
219
219
|
**Example:**
|
|
220
220
|
```ruby
|
|
221
221
|
data = DhanHQ::Models::ExpiredOptionsData.fetch(
|
|
222
|
-
exchange_segment:
|
|
222
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_FNO,
|
|
223
223
|
interval: "1",
|
|
224
224
|
security_id: 13,
|
|
225
225
|
instrument: "OPTIDX",
|
|
@@ -61,10 +61,10 @@ class MarketDataService
|
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
# Subscribe to major indices
|
|
64
|
-
@market_client.subscribe_one(segment:
|
|
65
|
-
@market_client.subscribe_one(segment:
|
|
66
|
-
@market_client.subscribe_one(segment:
|
|
67
|
-
@market_client.subscribe_one(segment:
|
|
64
|
+
@market_client.subscribe_one(segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "13") # NIFTY
|
|
65
|
+
@market_client.subscribe_one(segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "25") # BANKNIFTY
|
|
66
|
+
@market_client.subscribe_one(segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "29") # NIFTYIT
|
|
67
|
+
@market_client.subscribe_one(segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "51") # SENSEX
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def stop_market_feed
|
|
@@ -203,10 +203,10 @@ class MarketDataService
|
|
|
203
203
|
|
|
204
204
|
def subscribe_to_indices
|
|
205
205
|
indices = [
|
|
206
|
-
{ segment:
|
|
207
|
-
{ segment:
|
|
208
|
-
{ segment:
|
|
209
|
-
{ segment:
|
|
206
|
+
{ segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "13", name: "NIFTY" },
|
|
207
|
+
{ segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "25", name: "BANKNIFTY" },
|
|
208
|
+
{ segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "29", name: "NIFTYIT" },
|
|
209
|
+
{ segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "51", name: "SENSEX" }
|
|
210
210
|
]
|
|
211
211
|
|
|
212
212
|
indices.each do |index|
|
|
@@ -402,8 +402,8 @@ class MarketDepthService
|
|
|
402
402
|
|
|
403
403
|
def default_symbols
|
|
404
404
|
[
|
|
405
|
-
{ symbol: "RELIANCE", exchange_segment:
|
|
406
|
-
{ symbol: "TCS", exchange_segment:
|
|
405
|
+
{ symbol: "RELIANCE", exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ, security_id: "2885" },
|
|
406
|
+
{ symbol: "TCS", exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ, security_id: "11536" }
|
|
407
407
|
]
|
|
408
408
|
end
|
|
409
409
|
|