DhanHQ 2.1.5 → 2.1.7
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/CHANGELOG.md +21 -0
- data/GUIDE.md +221 -31
- data/README.md +453 -126
- data/README1.md +293 -30
- data/docs/live_order_updates.md +319 -0
- data/docs/rails_websocket_integration.md +847 -0
- data/docs/standalone_ruby_websocket_integration.md +1588 -0
- data/docs/websocket_integration.md +918 -0
- data/examples/comprehensive_websocket_examples.rb +148 -0
- data/examples/instrument_finder_test.rb +195 -0
- data/examples/live_order_updates.rb +118 -0
- data/examples/market_depth_example.rb +144 -0
- data/examples/market_feed_example.rb +81 -0
- data/examples/order_update_example.rb +105 -0
- data/examples/trading_fields_example.rb +215 -0
- data/lib/DhanHQ/configuration.rb +16 -1
- data/lib/DhanHQ/constants.rb +16 -0
- data/lib/DhanHQ/contracts/expired_options_data_contract.rb +103 -0
- data/lib/DhanHQ/contracts/trade_contract.rb +70 -0
- data/lib/DhanHQ/errors.rb +2 -0
- data/lib/DhanHQ/models/expired_options_data.rb +331 -0
- data/lib/DhanHQ/models/instrument.rb +114 -4
- data/lib/DhanHQ/models/instrument_helpers.rb +141 -0
- data/lib/DhanHQ/models/order_update.rb +235 -0
- data/lib/DhanHQ/models/trade.rb +118 -31
- data/lib/DhanHQ/resources/expired_options_data.rb +22 -0
- data/lib/DhanHQ/version.rb +1 -1
- data/lib/DhanHQ/ws/base_connection.rb +249 -0
- data/lib/DhanHQ/ws/connection.rb +2 -2
- data/lib/DhanHQ/ws/decoder.rb +3 -3
- data/lib/DhanHQ/ws/market_depth/client.rb +376 -0
- data/lib/DhanHQ/ws/market_depth/decoder.rb +131 -0
- data/lib/DhanHQ/ws/market_depth.rb +74 -0
- data/lib/DhanHQ/ws/orders/client.rb +175 -11
- data/lib/DhanHQ/ws/orders/connection.rb +40 -81
- data/lib/DhanHQ/ws/orders.rb +28 -0
- data/lib/DhanHQ/ws/segments.rb +18 -2
- data/lib/DhanHQ/ws.rb +3 -2
- data/lib/dhan_hq.rb +5 -0
- metadata +36 -1
data/README.md
CHANGED
|
@@ -4,8 +4,8 @@ A clean Ruby client for **Dhan API v2** with ORM-like models (Orders, Positions,
|
|
|
4
4
|
|
|
5
5
|
* ActiveRecord-style models: `find`, `all`, `where`, `save`, `update`, `cancel`
|
|
6
6
|
* Validations & errors exposed via ActiveModel-like interfaces
|
|
7
|
-
* REST coverage: Orders, Super Orders, Forever Orders, Trades, Positions, Holdings, Funds/Margin, HistoricalData, OptionChain, MarketFeed
|
|
8
|
-
* **WebSocket**: subscribe/unsubscribe dynamically, auto-reconnect with backoff, 429 cool-off, idempotent subs, header+payload binary parsing, normalized ticks
|
|
7
|
+
* REST coverage: Orders, Super Orders, Forever Orders, Trades, Positions, Holdings, Funds/Margin, HistoricalData, OptionChain, MarketFeed, ExpiredOptionsData
|
|
8
|
+
* **WebSocket**: Orders, Market Feed, Market Depth - subscribe/unsubscribe dynamically, auto-reconnect with backoff, 429 cool-off, idempotent subs, header+payload binary parsing, normalized ticks
|
|
9
9
|
|
|
10
10
|
## ⚠️ BREAKING CHANGE NOTICE
|
|
11
11
|
|
|
@@ -146,153 +146,237 @@ initializers, service objects, workers, and ActionCable wiring tailored for the
|
|
|
146
146
|
|
|
147
147
|
---
|
|
148
148
|
|
|
149
|
-
## WebSocket Market Feed
|
|
149
|
+
## WebSocket Integration (Orders, Market Feed, Market Depth)
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
The DhanHQ gem provides comprehensive WebSocket integration with three distinct WebSocket types, featuring improved architecture, security, and reliability:
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
### Key Features
|
|
154
154
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
155
|
+
- **🔒 Secure Logging** - Sensitive information (access tokens) are automatically sanitized from logs
|
|
156
|
+
- **⚡ Rate Limit Protection** - Built-in protection against 429 errors with proper connection management
|
|
157
|
+
- **🔄 Automatic Reconnection** - Exponential backoff with 60-second cool-off periods
|
|
158
|
+
- **🧵 Thread-Safe Operation** - Safe for Rails applications and multi-threaded environments
|
|
159
|
+
- **📊 Comprehensive Examples** - Ready-to-use examples for all WebSocket types
|
|
160
|
+
- **🛡️ Error Handling** - Robust error handling and connection management
|
|
161
|
+
- **🔍 Dynamic Symbol Resolution** - Easy instrument lookup using `.find()` method
|
|
159
162
|
|
|
160
|
-
|
|
161
|
-
{
|
|
162
|
-
kind: :quote, # :ticker | :quote | :full | :oi | :prev_close | :misc
|
|
163
|
-
segment: "NSE_FNO", # string enum
|
|
164
|
-
security_id: "12345",
|
|
165
|
-
ltp: 101.5,
|
|
166
|
-
ts: 1723791300, # LTT epoch (sec) if present
|
|
167
|
-
vol: 123456, # quote/full
|
|
168
|
-
atp: 100.9, # quote/full
|
|
169
|
-
day_open: 100.1, day_high: 102.4, day_low: 99.5, day_close: nil,
|
|
170
|
-
oi: 987654, # full or OI packet
|
|
171
|
-
bid: 101.45, ask: 101.55 # from depth (mode :full)
|
|
172
|
-
}
|
|
173
|
-
```
|
|
163
|
+
### 1. Orders WebSocket - Real-time Order Updates
|
|
174
164
|
|
|
175
|
-
|
|
165
|
+
Receive live updates whenever your orders transition between states (placed → traded → cancelled, etc.).
|
|
176
166
|
|
|
177
167
|
```ruby
|
|
178
|
-
|
|
168
|
+
# Simple connection
|
|
169
|
+
DhanHQ::WS::Orders.connect do |order_update|
|
|
170
|
+
puts "Order Update: #{order_update.order_no} - #{order_update.status}"
|
|
171
|
+
puts " Symbol: #{order_update.symbol}"
|
|
172
|
+
puts " Quantity: #{order_update.quantity}"
|
|
173
|
+
puts " Traded Qty: #{order_update.traded_qty}"
|
|
174
|
+
puts " Price: #{order_update.price}"
|
|
175
|
+
puts " Execution: #{order_update.execution_percentage}%"
|
|
176
|
+
end
|
|
179
177
|
|
|
180
|
-
|
|
181
|
-
|
|
178
|
+
# Advanced usage with multiple event handlers
|
|
179
|
+
client = DhanHQ::WS::Orders.client
|
|
180
|
+
client.on(:update) { |order| puts "📝 Order updated: #{order.order_no}" }
|
|
181
|
+
client.on(:status_change) { |change| puts "🔄 Status: #{change[:previous_status]} -> #{change[:new_status]}" }
|
|
182
|
+
client.on(:execution) { |exec| puts "✅ Executed: #{exec[:new_traded_qty]} shares" }
|
|
183
|
+
client.on(:order_rejected) { |order| puts "❌ Rejected: #{order.order_no}" }
|
|
184
|
+
client.start
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 2. Market Feed WebSocket - Live Market Data
|
|
182
188
|
|
|
183
|
-
|
|
189
|
+
Subscribe to real-time market data for indices and stocks.
|
|
184
190
|
|
|
185
|
-
|
|
186
|
-
|
|
191
|
+
```ruby
|
|
192
|
+
# Ticker data (LTP updates) - Recommended for most use cases
|
|
193
|
+
market_client = DhanHQ::WS.connect(mode: :ticker) do |tick|
|
|
194
|
+
timestamp = tick[:ts] ? Time.at(tick[:ts]) : Time.now
|
|
195
|
+
puts "Market Data: #{tick[:segment]}:#{tick[:security_id]} = #{tick[:ltp]} at #{timestamp}"
|
|
187
196
|
end
|
|
188
197
|
|
|
189
|
-
# Subscribe
|
|
190
|
-
|
|
191
|
-
|
|
198
|
+
# Subscribe to major Indian indices
|
|
199
|
+
market_client.subscribe_one(segment: "IDX_I", security_id: "13") # NIFTY
|
|
200
|
+
market_client.subscribe_one(segment: "IDX_I", security_id: "25") # BANKNIFTY
|
|
201
|
+
market_client.subscribe_one(segment: "IDX_I", security_id: "29") # NIFTYIT
|
|
202
|
+
market_client.subscribe_one(segment: "IDX_I", security_id: "51") # SENSEX
|
|
192
203
|
|
|
193
|
-
#
|
|
194
|
-
|
|
204
|
+
# Quote data (LTP + volume + OHLC)
|
|
205
|
+
DhanHQ::WS.connect(mode: :quote) do |quote|
|
|
206
|
+
puts "#{quote[:symbol]}: LTP=#{quote[:ltp]}, Volume=#{quote[:vol]}"
|
|
207
|
+
end
|
|
195
208
|
|
|
196
|
-
#
|
|
197
|
-
|
|
209
|
+
# Full market data
|
|
210
|
+
DhanHQ::WS.connect(mode: :full) do |full|
|
|
211
|
+
puts "#{full[:symbol]}: #{full.inspect}"
|
|
212
|
+
end
|
|
213
|
+
```
|
|
198
214
|
|
|
199
|
-
|
|
200
|
-
ws.stop
|
|
215
|
+
### 3. Market Depth WebSocket - Real-time Market Depth
|
|
201
216
|
|
|
202
|
-
|
|
203
|
-
DhanHQ::WS.disconnect_all_local!
|
|
204
|
-
```
|
|
217
|
+
Get real-time market depth data including bid/ask levels and order book information.
|
|
205
218
|
|
|
206
|
-
|
|
219
|
+
```ruby
|
|
220
|
+
# Real-time market depth for stocks (using dynamic symbol resolution with underlying_symbol)
|
|
221
|
+
reliance = DhanHQ::Models::Instrument.find("NSE_EQ", "RELIANCE")
|
|
222
|
+
tcs = DhanHQ::Models::Instrument.find("NSE_EQ", "TCS")
|
|
207
223
|
|
|
208
|
-
|
|
224
|
+
symbols = []
|
|
225
|
+
if reliance
|
|
226
|
+
symbols << { symbol: "RELIANCE", exchange_segment: reliance.exchange_segment, security_id: reliance.security_id }
|
|
227
|
+
end
|
|
228
|
+
if tcs
|
|
229
|
+
symbols << { symbol: "TCS", exchange_segment: tcs.exchange_segment, security_id: tcs.security_id }
|
|
230
|
+
end
|
|
209
231
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
232
|
+
DhanHQ::WS::MarketDepth.connect(symbols: symbols) do |depth_data|
|
|
233
|
+
puts "Market Depth: #{depth_data[:symbol]}"
|
|
234
|
+
puts " Best Bid: #{depth_data[:best_bid]}"
|
|
235
|
+
puts " Best Ask: #{depth_data[:best_ask]}"
|
|
236
|
+
puts " Spread: #{depth_data[:spread]}"
|
|
237
|
+
puts " Bid Levels: #{depth_data[:bids].size}"
|
|
238
|
+
puts " Ask Levels: #{depth_data[:asks].size}"
|
|
239
|
+
end
|
|
240
|
+
```
|
|
214
241
|
|
|
215
|
-
|
|
216
|
-
* Up to 5 WS connections per user (per Dhan)
|
|
217
|
-
* **Backoff & 429 cool-off**
|
|
242
|
+
### Unified WebSocket Architecture
|
|
218
243
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
244
|
+
All WebSocket connections provide:
|
|
245
|
+
- **Automatic reconnection** with exponential backoff
|
|
246
|
+
- **Thread-safe operation** for Rails applications
|
|
247
|
+
- **Consistent event handling** patterns
|
|
248
|
+
- **Built-in error handling** and logging
|
|
249
|
+
- **429 rate limiting** protection with cool-off periods
|
|
250
|
+
- **Secure logging** with automatic credential sanitization
|
|
222
251
|
|
|
223
|
-
|
|
224
|
-
* **Graceful shutdown**
|
|
252
|
+
### Connection Management
|
|
225
253
|
|
|
226
|
-
|
|
227
|
-
|
|
254
|
+
```ruby
|
|
255
|
+
# Sequential connections to avoid rate limiting (recommended)
|
|
256
|
+
orders_client = DhanHQ::WS::Orders.connect { |order| puts "Order: #{order.order_no}" }
|
|
257
|
+
orders_client.stop
|
|
258
|
+
sleep(2) # Wait between connections
|
|
228
259
|
|
|
229
|
-
|
|
260
|
+
market_client = DhanHQ::WS.connect(mode: :ticker) { |tick| puts "Market: #{tick[:symbol]}" }
|
|
261
|
+
market_client.stop
|
|
262
|
+
sleep(2)
|
|
230
263
|
|
|
231
|
-
|
|
264
|
+
depth_client = DhanHQ::WS::MarketDepth.connect(symbols: symbols) { |depth| puts "Depth: #{depth[:symbol]}" }
|
|
265
|
+
depth_client.stop
|
|
232
266
|
|
|
233
|
-
|
|
267
|
+
# Check connection status
|
|
268
|
+
puts "Orders connected: #{orders_client.connected?}"
|
|
269
|
+
puts "Market connected: #{market_client.connected?}"
|
|
270
|
+
puts "Depth connected: #{depth_client.connected?}"
|
|
234
271
|
|
|
235
|
-
|
|
272
|
+
# Graceful shutdown
|
|
273
|
+
DhanHQ::WS.disconnect_all_local!
|
|
274
|
+
```
|
|
236
275
|
|
|
237
|
-
|
|
238
|
-
require 'dhan_hq'
|
|
276
|
+
### Examples
|
|
239
277
|
|
|
240
|
-
|
|
241
|
-
DhanHQ.logger.level = (ENV["DHAN_LOG_LEVEL"] || "INFO").upcase.then { |level| Logger.const_get(level) }
|
|
278
|
+
The gem includes comprehensive examples in the `examples/` directory:
|
|
242
279
|
|
|
243
|
-
|
|
280
|
+
- `market_feed_example.rb` - Market Feed WebSocket with major indices
|
|
281
|
+
- `order_update_example.rb` - Order Update WebSocket with event handling
|
|
282
|
+
- `market_depth_example.rb` - Market Depth WebSocket with RELIANCE and TCS
|
|
283
|
+
- `comprehensive_websocket_examples.rb` - All three WebSocket types
|
|
244
284
|
|
|
245
|
-
|
|
246
|
-
data = payload[:Data] || {}
|
|
247
|
-
puts "ORDER #{data[:OrderNo]} #{data[:Status]} traded=#{data[:TradedQty]} avg=#{data[:AvgTradedPrice]}"
|
|
248
|
-
end
|
|
285
|
+
Run examples:
|
|
249
286
|
|
|
250
|
-
|
|
251
|
-
|
|
287
|
+
```bash
|
|
288
|
+
# Individual examples
|
|
289
|
+
bundle exec ruby examples/market_feed_example.rb
|
|
290
|
+
bundle exec ruby examples/order_update_example.rb
|
|
291
|
+
bundle exec ruby examples/market_depth_example.rb
|
|
252
292
|
|
|
253
|
-
#
|
|
254
|
-
|
|
293
|
+
# Comprehensive example
|
|
294
|
+
bundle exec ruby examples/comprehensive_websocket_examples.rb
|
|
255
295
|
```
|
|
256
296
|
|
|
257
|
-
|
|
297
|
+
### Instrument Model with Trading Fields
|
|
298
|
+
|
|
299
|
+
The Instrument model now includes comprehensive trading fields for order validation, risk management, and compliance:
|
|
258
300
|
|
|
259
301
|
```ruby
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
302
|
+
# Find instrument with trading fields
|
|
303
|
+
reliance = DhanHQ::Models::Instrument.find("NSE_EQ", "RELIANCE")
|
|
304
|
+
|
|
305
|
+
# Trading permissions and restrictions
|
|
306
|
+
puts "Trading Allowed: #{reliance.buy_sell_indicator == 'A'}"
|
|
307
|
+
puts "Bracket Orders: #{reliance.bracket_flag == 'Y' ? 'Supported' : 'Not Supported'}"
|
|
308
|
+
puts "Cover Orders: #{reliance.cover_flag == 'Y' ? 'Supported' : 'Not Supported'}"
|
|
309
|
+
puts "ASM/GSM Status: #{reliance.asm_gsm_flag == 'Y' ? reliance.asm_gsm_category : 'No Restrictions'}"
|
|
310
|
+
|
|
311
|
+
# Margin and leverage information
|
|
312
|
+
puts "ISIN: #{reliance.isin}"
|
|
313
|
+
puts "MTF Leverage: #{reliance.mtf_leverage}x"
|
|
314
|
+
puts "Buy Margin %: #{reliance.buy_co_min_margin_per}%"
|
|
315
|
+
puts "Sell Margin %: #{reliance.sell_co_min_margin_per}%"
|
|
263
316
|
```
|
|
264
317
|
|
|
265
|
-
|
|
318
|
+
**Available Trading Fields:**
|
|
319
|
+
- `isin` - International Securities Identification Number
|
|
320
|
+
- `instrument_type` - Classification (ES, INDEX, FUT, OPT)
|
|
321
|
+
- `expiry_flag` - Whether instrument has expiry
|
|
322
|
+
- `bracket_flag` - Bracket order support
|
|
323
|
+
- `cover_flag` - Cover order support
|
|
324
|
+
- `asm_gsm_flag` - Additional Surveillance Measure status
|
|
325
|
+
- `buy_sell_indicator` - Trading permission
|
|
326
|
+
- `buy_co_min_margin_per` - Buy CO minimum margin percentage
|
|
327
|
+
- `sell_co_min_margin_per` - Sell CO minimum margin percentage
|
|
328
|
+
- `mtf_leverage` - Margin Trading Facility leverage
|
|
266
329
|
|
|
267
|
-
|
|
330
|
+
### Instrument Convenience Methods
|
|
268
331
|
|
|
269
|
-
|
|
332
|
+
The Instrument model provides convenient instance methods that automatically use the instrument's attributes (`security_id`, `exchange_segment`, `instrument`) to fetch market data:
|
|
270
333
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
334
|
+
```ruby
|
|
335
|
+
# Find an instrument
|
|
336
|
+
instrument = DhanHQ::Models::Instrument.find("IDX_I", "NIFTY")
|
|
337
|
+
|
|
338
|
+
# Market Feed Methods - automatically uses instrument's attributes
|
|
339
|
+
ltp_data = instrument.ltp # Last traded price
|
|
340
|
+
ohlc_data = instrument.ohlc # OHLC data
|
|
341
|
+
quote_data = instrument.quote # Full quote depth
|
|
342
|
+
|
|
343
|
+
# Historical Data Methods
|
|
344
|
+
daily_data = instrument.daily(
|
|
345
|
+
from_date: "2024-01-01",
|
|
346
|
+
to_date: "2024-01-31",
|
|
347
|
+
expiry_code: 0 # Optional
|
|
348
|
+
)
|
|
274
349
|
|
|
275
|
-
|
|
350
|
+
intraday_data = instrument.intraday(
|
|
351
|
+
from_date: "2024-09-11",
|
|
352
|
+
to_date: "2024-09-15",
|
|
353
|
+
interval: "15" # 1, 5, 15, 25, or 60 minutes
|
|
354
|
+
)
|
|
276
355
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
* Refresh `Execution::PositionGuard` (if present) with fill prices/qty for trailing exits.
|
|
356
|
+
# Option Chain Methods
|
|
357
|
+
expiries = instrument.expiry_list # Get all available expiries
|
|
280
358
|
|
|
281
|
-
|
|
359
|
+
chain = instrument.option_chain(expiry: "2024-02-29") # Get option chain for specific expiry
|
|
360
|
+
```
|
|
282
361
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
362
|
+
**Available Instance Methods:**
|
|
363
|
+
- `instrument.ltp` - Fetches last traded price using `DhanHQ::Models::MarketFeed.ltp`
|
|
364
|
+
- `instrument.ohlc` - Fetches OHLC data using `DhanHQ::Models::MarketFeed.ohlc`
|
|
365
|
+
- `instrument.quote` - Fetches full quote depth using `DhanHQ::Models::MarketFeed.quote`
|
|
366
|
+
- `instrument.daily(from_date:, to_date:, **options)` - Fetches daily historical data using `DhanHQ::Models::HistoricalData.daily`
|
|
367
|
+
- `instrument.intraday(from_date:, to_date:, interval:, **options)` - Fetches intraday historical data using `DhanHQ::Models::HistoricalData.intraday`
|
|
368
|
+
- `instrument.expiry_list` - Fetches expiry list using `DhanHQ::Models::OptionChain.fetch_expiry_list`
|
|
369
|
+
- `instrument.option_chain(expiry:)` - Fetches option chain using `DhanHQ::Models::OptionChain.fetch`
|
|
288
370
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
371
|
+
All methods automatically use the instrument's `security_id`, `exchange_segment`, and `instrument` attributes, eliminating the need to manually pass these parameters.
|
|
372
|
+
|
|
373
|
+
### Comprehensive Documentation
|
|
292
374
|
|
|
293
|
-
|
|
375
|
+
The gem includes detailed documentation for different integration scenarios:
|
|
294
376
|
|
|
295
|
-
|
|
377
|
+
- **[WebSocket Integration Guide](docs/websocket_integration.md)** - Complete guide covering all WebSocket types and trading fields
|
|
378
|
+
- **[Rails Integration Guide](docs/rails_websocket_integration.md)** - Rails-specific patterns and best practices
|
|
379
|
+
- **[Standalone Ruby Guide](docs/standalone_ruby_websocket_integration.md)** - Scripts, daemons, and CLI tools
|
|
296
380
|
|
|
297
381
|
---
|
|
298
382
|
|
|
@@ -397,40 +481,283 @@ end
|
|
|
397
481
|
|
|
398
482
|
---
|
|
399
483
|
|
|
400
|
-
## Super Orders
|
|
484
|
+
## Super Orders
|
|
401
485
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
486
|
+
Super orders are built for smart execution. They club the entry, target, and stop-loss legs (with optional trailing jump) into a single request so you can manage risk immediately after entry.
|
|
487
|
+
|
|
488
|
+
This gem exposes the full REST surface to create, modify, cancel, and list super orders across all supported exchanges and segments.
|
|
489
|
+
|
|
490
|
+
### Endpoints
|
|
491
|
+
|
|
492
|
+
| Method | Path | Description |
|
|
493
|
+
| -------- | -------------------------------------- | ------------------------------------- |
|
|
494
|
+
| `POST` | `/super/orders` | Create a new super order |
|
|
495
|
+
| `PUT` | `/super/orders/{order_id}` | Modify a pending super order |
|
|
496
|
+
| `DELETE` | `/super/orders/{order_id}/{order_leg}` | Cancel a pending super order leg |
|
|
497
|
+
| `GET` | `/super/orders` | Retrieve the list of all super orders |
|
|
498
|
+
|
|
499
|
+
### Place Super Order
|
|
500
|
+
|
|
501
|
+
The place endpoint lets you submit a new super order that can include entry, target, stop-loss, and optional trailing jump definitions. It is available across exchanges and segments, and supports intraday, carry-forward, or MTF orders.
|
|
502
|
+
|
|
503
|
+
> ℹ️ Static IP whitelisting with Dhan support is required before invoking this API.
|
|
504
|
+
|
|
505
|
+
```bash
|
|
506
|
+
curl --request POST \
|
|
507
|
+
--url https://api.dhan.co/v2/super/orders \
|
|
508
|
+
--header 'Content-Type: application/json' \
|
|
509
|
+
--header 'access-token: JWT' \
|
|
510
|
+
--data '{Request JSON}'
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
#### Request body
|
|
514
|
+
|
|
515
|
+
```json
|
|
516
|
+
{
|
|
517
|
+
"dhan_client_id": "1000000003",
|
|
518
|
+
"correlation_id": "123abc678",
|
|
519
|
+
"transaction_type": "BUY",
|
|
520
|
+
"exchange_segment": "NSE_EQ",
|
|
521
|
+
"product_type": "CNC",
|
|
522
|
+
"order_type": "LIMIT",
|
|
523
|
+
"security_id": "11536",
|
|
524
|
+
"quantity": 5,
|
|
525
|
+
"price": 1500,
|
|
526
|
+
"target_price": 1600,
|
|
527
|
+
"stop_loss_price": 1400,
|
|
528
|
+
"trailing_jump": 10
|
|
412
529
|
}
|
|
530
|
+
```
|
|
413
531
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
).
|
|
532
|
+
#### Parameters
|
|
533
|
+
|
|
534
|
+
| Field | Type | Description |
|
|
535
|
+
| ------------------ | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
536
|
+
| `dhan_client_id` | string *(required)* | User specific identification generated by Dhan. When you call through `DhanHQ::Models::SuperOrder`, the gem injects your configured client id so you can omit this key locally. |
|
|
537
|
+
| `correlation_id` | string | Caller generated correlation identifier |
|
|
538
|
+
| `transaction_type` | enum string *(required)* | Trading side. `BUY` or `SELL`. |
|
|
539
|
+
| `exchange_segment` | enum string *(required)* | Exchange segment (see appendix). |
|
|
540
|
+
| `product_type` | enum string *(required)* | Product type. `CNC`, `INTRADAY`, `MARGIN`, or `MTF`. |
|
|
541
|
+
| `order_type` | enum string *(required)* | Order type. `LIMIT` or `MARKET`. |
|
|
542
|
+
| `security_id` | string *(required)* | Exchange standard security identifier. |
|
|
543
|
+
| `quantity` | integer *(required)* | Number of shares for the order. |
|
|
544
|
+
| `price` | float *(required)* | Price at which the entry leg is placed. |
|
|
545
|
+
| `target_price` | float *(required)* | Target price for the super order. |
|
|
546
|
+
| `stop_loss_price` | float *(required)* | Stop-loss price for the super order. |
|
|
547
|
+
| `trailing_jump` | float *(required)* | Price jump size used to trail the stop-loss. |
|
|
548
|
+
|
|
549
|
+
> 🐍 When you call `DhanHQ::Models::SuperOrder.create`, pass snake_case keys as shown above. The client automatically camelizes
|
|
550
|
+
> them before posting to Dhan's REST API and injects your configured `dhan_client_id`, so you can omit that key in Ruby code.
|
|
551
|
+
|
|
552
|
+
#### Response
|
|
553
|
+
|
|
554
|
+
```json
|
|
555
|
+
{
|
|
556
|
+
"order_id": "112111182198",
|
|
557
|
+
"order_status": "PENDING"
|
|
558
|
+
}
|
|
422
559
|
```
|
|
423
560
|
|
|
424
|
-
|
|
561
|
+
| Field | Type | Description |
|
|
562
|
+
| -------------- | ----------- | --------------------------------------------------- |
|
|
563
|
+
| `order_id` | string | Order identifier generated by Dhan |
|
|
564
|
+
| `order_status` | enum string | Latest status. `TRANSIT`, `PENDING`, or `REJECTED`. |
|
|
425
565
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
566
|
+
### Modify Super Order
|
|
567
|
+
|
|
568
|
+
Use the modify endpoint to update any leg while the super order remains in `PENDING` or `PART_TRADED` status.
|
|
569
|
+
|
|
570
|
+
> ℹ️ Static IP whitelisting with Dhan support is required before invoking this API.
|
|
571
|
+
|
|
572
|
+
```bash
|
|
573
|
+
curl --request PUT \
|
|
574
|
+
--url https://api.dhan.co/v2/super/orders/{order_id} \
|
|
575
|
+
--header 'Content-Type: application/json' \
|
|
576
|
+
--header 'access-token: JWT' \
|
|
577
|
+
--data '{Request JSON}'
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
#### Request body
|
|
581
|
+
|
|
582
|
+
```json
|
|
583
|
+
{
|
|
584
|
+
"dhan_client_id": "1000000009",
|
|
585
|
+
"order_id": "112111182045",
|
|
586
|
+
"order_type": "LIMIT",
|
|
587
|
+
"leg_name": "ENTRY_LEG",
|
|
588
|
+
"quantity": 40,
|
|
589
|
+
"price": 1300,
|
|
590
|
+
"target_price": 1450,
|
|
591
|
+
"stop_loss_price": 1350,
|
|
592
|
+
"trailing_jump": 20
|
|
593
|
+
}
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
#### Parameters
|
|
597
|
+
|
|
598
|
+
| Field | Type | Description |
|
|
599
|
+
| ----------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
600
|
+
| `dhan_client_id` | string *(required)* | User specific identification generated by Dhan. Automatically added when you call through the Ruby models. |
|
|
601
|
+
| `order_id` | string *(required)* | Super order identifier generated by Dhan. |
|
|
602
|
+
| `order_type` | enum string *(conditionally required)* | `LIMIT` or `MARKET`. Required when modifying `ENTRY_LEG`. |
|
|
603
|
+
| `leg_name` | enum string *(required)* | `ENTRY_LEG`, `TARGET_LEG`, or `STOP_LOSS_LEG`. Entry leg updates entire order while status is `PENDING` or `PART_TRADED`. |
|
|
604
|
+
| `quantity` | integer *(conditionally required)* | Quantity update for `ENTRY_LEG`. |
|
|
605
|
+
| `price` | float *(conditionally required)* | Entry price update for `ENTRY_LEG`. |
|
|
606
|
+
| `target_price` | float *(conditionally required)* | Target price update for `ENTRY_LEG` or `TARGET_LEG`. |
|
|
607
|
+
| `stop_loss_price` | float *(conditionally required)* | Stop-loss price update for `ENTRY_LEG` or `STOP_LOSS_LEG`. |
|
|
608
|
+
| `trailing_jump` | float *(conditionally required)* | Trailing jump update for `ENTRY_LEG` or `STOP_LOSS_LEG`. Omit or set to `0` to cancel trailing. |
|
|
609
|
+
|
|
610
|
+
> ℹ️ Once the entry leg status becomes `TRADED`, only the `TARGET_LEG` and `STOP_LOSS_LEG` can be modified (price and trailing jump).
|
|
611
|
+
|
|
612
|
+
#### Response
|
|
613
|
+
|
|
614
|
+
```json
|
|
615
|
+
{
|
|
616
|
+
"order_id": "112111182045",
|
|
617
|
+
"order_status": "TRANSIT"
|
|
618
|
+
}
|
|
432
619
|
```
|
|
433
620
|
|
|
621
|
+
| Field | Type | Description |
|
|
622
|
+
| -------------- | ----------- | ------------------------------------------------------------- |
|
|
623
|
+
| `order_id` | string | Order identifier generated by Dhan |
|
|
624
|
+
| `order_status` | enum string | Latest status. `TRANSIT`, `PENDING`, `REJECTED`, or `TRADED`. |
|
|
625
|
+
|
|
626
|
+
### Cancel Super Order
|
|
627
|
+
|
|
628
|
+
Cancel a pending or active super order leg using the order ID. Cancelling the entry leg removes every leg. Cancelling a specific target or stop-loss leg removes only that leg and it cannot be re-added.
|
|
629
|
+
|
|
630
|
+
> ℹ️ Static IP whitelisting with Dhan support is required before invoking this API.
|
|
631
|
+
|
|
632
|
+
```bash
|
|
633
|
+
curl --request DELETE \
|
|
634
|
+
--url https://api.dhan.co/v2/super/orders/{order_id}/{order_leg} \
|
|
635
|
+
--header 'Content-Type: application/json' \
|
|
636
|
+
--header 'access-token: JWT'
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
#### Path parameters
|
|
640
|
+
|
|
641
|
+
| Field | Description | Example |
|
|
642
|
+
| ----------- | ------------------------------------------------------------- | ------------- |
|
|
643
|
+
| `order_id` | Super order identifier. | `11211182198` |
|
|
644
|
+
| `order_leg` | Leg to cancel. `ENTRY_LEG`, `TARGET_LEG`, or `STOP_LOSS_LEG`. | `ENTRY_LEG` |
|
|
645
|
+
|
|
646
|
+
#### Response
|
|
647
|
+
|
|
648
|
+
```json
|
|
649
|
+
{
|
|
650
|
+
"order_id": "112111182045",
|
|
651
|
+
"order_status": "CANCELLED"
|
|
652
|
+
}
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
| Field | Type | Description |
|
|
656
|
+
| -------------- | ----------- | ---------------------------------------------------------------- |
|
|
657
|
+
| `order_id` | string | Order identifier generated by Dhan |
|
|
658
|
+
| `order_status` | enum string | Latest status. `TRANSIT`, `PENDING`, `REJECTED`, or `CANCELLED`. |
|
|
659
|
+
|
|
660
|
+
### Super Order List
|
|
661
|
+
|
|
662
|
+
List every super order placed during the trading day. The API nests leg details under the entry leg, and individual legs also appear in the main order book.
|
|
663
|
+
|
|
664
|
+
```bash
|
|
665
|
+
curl --request GET \
|
|
666
|
+
--url https://api.dhan.co/v2/super/orders \
|
|
667
|
+
--header 'Content-Type: application/json' \
|
|
668
|
+
--header 'access-token: JWT'
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
#### Response
|
|
672
|
+
|
|
673
|
+
```json
|
|
674
|
+
[
|
|
675
|
+
{
|
|
676
|
+
"dhan_client_id": "1100003626",
|
|
677
|
+
"order_id": "5925022734212",
|
|
678
|
+
"correlation_id": "string",
|
|
679
|
+
"order_status": "PENDING",
|
|
680
|
+
"transaction_type": "BUY",
|
|
681
|
+
"exchange_segment": "NSE_EQ",
|
|
682
|
+
"product_type": "CNC",
|
|
683
|
+
"order_type": "LIMIT",
|
|
684
|
+
"validity": "DAY",
|
|
685
|
+
"trading_symbol": "HDFCBANK",
|
|
686
|
+
"security_id": "1333",
|
|
687
|
+
"quantity": 10,
|
|
688
|
+
"remaining_quantity": 10,
|
|
689
|
+
"ltp": 1660.95,
|
|
690
|
+
"price": 1500,
|
|
691
|
+
"after_market_order": false,
|
|
692
|
+
"leg_name": "ENTRY_LEG",
|
|
693
|
+
"exchange_order_id": "11925022734212",
|
|
694
|
+
"create_time": "2025-02-27 19:09:42",
|
|
695
|
+
"update_time": "2025-02-27 19:09:42",
|
|
696
|
+
"exchange_time": "2025-02-27 19:09:42",
|
|
697
|
+
"oms_error_description": "",
|
|
698
|
+
"average_traded_price": 0,
|
|
699
|
+
"filled_qty": 0,
|
|
700
|
+
"leg_details": [
|
|
701
|
+
{
|
|
702
|
+
"order_id": "5925022734212",
|
|
703
|
+
"leg_name": "STOP_LOSS_LEG",
|
|
704
|
+
"transaction_type": "SELL",
|
|
705
|
+
"total_quantity": 0,
|
|
706
|
+
"remaining_quantity": 0,
|
|
707
|
+
"triggered_quantity": 0,
|
|
708
|
+
"price": 1400,
|
|
709
|
+
"order_status": "PENDING",
|
|
710
|
+
"trailing_jump": 10
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
"order_id": "5925022734212",
|
|
714
|
+
"leg_name": "TARGET_LEG",
|
|
715
|
+
"transaction_type": "SELL",
|
|
716
|
+
"remaining_quantity": 0,
|
|
717
|
+
"triggered_quantity": 0,
|
|
718
|
+
"price": 1550,
|
|
719
|
+
"order_status": "PENDING",
|
|
720
|
+
"trailing_jump": 0
|
|
721
|
+
}
|
|
722
|
+
]
|
|
723
|
+
}
|
|
724
|
+
]
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
#### Parameters
|
|
728
|
+
|
|
729
|
+
| Field | Type | Description |
|
|
730
|
+
| ----------------------- | ----------- | --------------------------------------------------------------------------------------------------- |
|
|
731
|
+
| `dhan_client_id` | string | User specific identification generated by Dhan. |
|
|
732
|
+
| `order_id` | string | Order identifier generated by Dhan. |
|
|
733
|
+
| `correlation_id` | string | Correlation identifier supplied by the caller. |
|
|
734
|
+
| `order_status` | enum string | Latest status. `TRANSIT`, `PENDING`, `CLOSED`, `REJECTED`, `CANCELLED`, `PART_TRADED`, or `TRADED`. |
|
|
735
|
+
| `transaction_type` | enum string | Trading side. `BUY` or `SELL`. |
|
|
736
|
+
| `exchange_segment` | enum string | Exchange segment. |
|
|
737
|
+
| `product_type` | enum string | Product type. `CNC`, `INTRADAY`, `MARGIN`, or `MTF`. |
|
|
738
|
+
| `order_type` | enum string | Order type. `LIMIT` or `MARKET`. |
|
|
739
|
+
| `validity` | enum string | Order validity. `DAY`. |
|
|
740
|
+
| `trading_symbol` | string | Trading symbol reference. |
|
|
741
|
+
| `security_id` | string | Exchange security identifier. |
|
|
742
|
+
| `quantity` | integer | Ordered quantity. |
|
|
743
|
+
| `remaining_quantity` | integer | Quantity pending execution. |
|
|
744
|
+
| `ltp` | float | Last traded price. |
|
|
745
|
+
| `price` | float | Order price. |
|
|
746
|
+
| `after_market_order` | boolean | Indicates if the order was placed after market hours. |
|
|
747
|
+
| `leg_name` | enum string | Leg identifier: `ENTRY_LEG`, `TARGET_LEG`, or `STOP_LOSS_LEG`. |
|
|
748
|
+
| `trailing_jump` | float | Trailing jump for stop-loss. |
|
|
749
|
+
| `exchange_order_id` | string | Exchange-generated order identifier. |
|
|
750
|
+
| `create_time` | string | Order creation timestamp. |
|
|
751
|
+
| `update_time` | string | Latest update timestamp. |
|
|
752
|
+
| `exchange_time` | string | Exchange timestamp. |
|
|
753
|
+
| `oms_error_description` | string | OMS error description when applicable. |
|
|
754
|
+
| `average_traded_price` | float | Average traded price. |
|
|
755
|
+
| `filled_qty` | integer | Quantity traded on the exchange. |
|
|
756
|
+
| `triggered_quantity` | integer | Quantity triggered for stop-loss or target legs. |
|
|
757
|
+
| `leg_details` | array | Nested leg details for the super order. |
|
|
758
|
+
|
|
759
|
+
> ✅ `CLOSED` indicates the entry leg plus either target or stop-loss leg completed for the entire quantity. `TRIGGERED` appears on target and stop-loss legs to show which leg fired; inspect `triggered_quantity` for the executed quantity.
|
|
760
|
+
|
|
434
761
|
---
|
|
435
762
|
|
|
436
763
|
## Packet parsing (for reference)
|