DhanHQ 2.1.3 → 2.1.6

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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/.rubocop_todo.yml +185 -0
  4. data/CHANGELOG.md +31 -0
  5. data/GUIDE.md +173 -31
  6. data/README.md +437 -133
  7. data/README1.md +267 -26
  8. data/docs/live_order_updates.md +319 -0
  9. data/docs/rails_integration.md +1 -1
  10. data/docs/rails_websocket_integration.md +847 -0
  11. data/docs/standalone_ruby_websocket_integration.md +1588 -0
  12. data/docs/technical_analysis.md +1 -0
  13. data/docs/websocket_integration.md +871 -0
  14. data/examples/comprehensive_websocket_examples.rb +148 -0
  15. data/examples/instrument_finder_test.rb +195 -0
  16. data/examples/live_order_updates.rb +118 -0
  17. data/examples/market_depth_example.rb +144 -0
  18. data/examples/market_feed_example.rb +81 -0
  19. data/examples/order_update_example.rb +105 -0
  20. data/examples/trading_fields_example.rb +215 -0
  21. data/lib/DhanHQ/config.rb +1 -0
  22. data/lib/DhanHQ/configuration.rb +16 -1
  23. data/lib/DhanHQ/contracts/expired_options_data_contract.rb +103 -0
  24. data/lib/DhanHQ/contracts/modify_order_contract.rb +1 -0
  25. data/lib/DhanHQ/contracts/option_chain_contract.rb +11 -1
  26. data/lib/DhanHQ/contracts/trade_contract.rb +70 -0
  27. data/lib/DhanHQ/errors.rb +2 -0
  28. data/lib/DhanHQ/models/expired_options_data.rb +331 -0
  29. data/lib/DhanHQ/models/instrument.rb +96 -2
  30. data/lib/DhanHQ/models/option_chain.rb +2 -0
  31. data/lib/DhanHQ/models/order_update.rb +235 -0
  32. data/lib/DhanHQ/models/trade.rb +118 -31
  33. data/lib/DhanHQ/rate_limiter.rb +4 -2
  34. data/lib/DhanHQ/resources/expired_options_data.rb +22 -0
  35. data/lib/DhanHQ/version.rb +1 -1
  36. data/lib/DhanHQ/ws/base_connection.rb +249 -0
  37. data/lib/DhanHQ/ws/client.rb +1 -1
  38. data/lib/DhanHQ/ws/connection.rb +3 -3
  39. data/lib/DhanHQ/ws/decoder.rb +3 -3
  40. data/lib/DhanHQ/ws/market_depth/client.rb +376 -0
  41. data/lib/DhanHQ/ws/market_depth/decoder.rb +131 -0
  42. data/lib/DhanHQ/ws/market_depth.rb +74 -0
  43. data/lib/DhanHQ/ws/orders/client.rb +177 -10
  44. data/lib/DhanHQ/ws/orders/connection.rb +41 -83
  45. data/lib/DhanHQ/ws/orders.rb +31 -2
  46. data/lib/DhanHQ/ws/registry.rb +1 -0
  47. data/lib/DhanHQ/ws/segments.rb +21 -5
  48. data/lib/DhanHQ/ws/sub_state.rb +1 -1
  49. data/lib/DhanHQ/ws.rb +3 -2
  50. data/lib/{DhanHQ.rb → dhan_hq.rb} +5 -0
  51. data/lib/dhanhq/analysis/helpers/bias_aggregator.rb +18 -18
  52. data/lib/dhanhq/analysis/helpers/moneyness_helper.rb +1 -0
  53. data/lib/dhanhq/analysis/multi_timeframe_analyzer.rb +2 -0
  54. data/lib/dhanhq/analysis/options_buying_advisor.rb +4 -3
  55. data/lib/dhanhq/contracts/options_buying_advisor_contract.rb +1 -0
  56. data/lib/ta/candles.rb +1 -0
  57. data/lib/ta/fetcher.rb +1 -0
  58. data/lib/ta/indicators.rb +2 -1
  59. data/lib/ta/market_calendar.rb +4 -3
  60. data/lib/ta/technical_analysis.rb +3 -2
  61. metadata +38 -4
  62. data/lib/DhanHQ/ws/errors.rb +0 -0
  63. /data/lib/DhanHQ/contracts/{modify_order_contract copy.rb → modify_order_contract_copy.rb} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ee56ccabd71b9f769e99d6470cf32309c4f6fa17eec5de17417b1c153ee9293
4
- data.tar.gz: 000fcabd622e0e690f6c65bf03665b8e4b3dfc23572534d29101fca0576757be
3
+ metadata.gz: 5b28412f443ad7ef0da9f10e99cee98dff8194b0d9da3c9d828dba28e3443fce
4
+ data.tar.gz: 96c1411c9e3c579f35637bfb37f9644348e0d75f5fbe9a502da59789da4607ba
5
5
  SHA512:
6
- metadata.gz: 6aeecd46b742a5cbdf74ffb4e38086be502385fda9e18bee4b6413a488b005b2a713dd089cd2d83c6628096d084d063bb6da468292b785d08f968fc9336838ac
7
- data.tar.gz: b4fe91bca2051073b297693d1ea2789911b8b50b3a948ccf96cc7b0647a1fe824020f39ca0cbfebf53946b453253d8348df7d673eb199068d24d444453191b8d
6
+ metadata.gz: 313c052fc68d670ce53005b091f70280617c0414a9fa1f6222d0f641b3181660bcdbf92eae5f6ece36fa500f1a554faee024114b2e132c1b2e3602b384a67cc3
7
+ data.tar.gz: e20baecdc074b57d78024bf5004a8808eb5397d3d1edb5743178ad50aa369e15250219c1f52384e1f00619fc8edd56bc97501ac8df375c95c7e61ca08dca96d9
data/.rubocop.yml CHANGED
@@ -1,3 +1,5 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
1
3
  plugins:
2
4
  - rubocop-rspec
3
5
  - rubocop-performance
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,185 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 999`
3
+ # on 2025-10-12 11:03:03 UTC using RuboCop version 1.80.2.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 4
10
+ # This cop supports safe autocorrection (--autocorrect).
11
+ # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
12
+ # URISchemes: http, https
13
+ Layout/LineLength:
14
+ Exclude:
15
+ - 'lib/DhanHQ/ws/decoder.rb'
16
+
17
+ # Offense count: 2
18
+ # Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
19
+ Lint/DuplicateBranch:
20
+ Exclude:
21
+ - 'bin/ta_strategy.rb'
22
+ - 'lib/dhanhq/analysis/helpers/bias_aggregator.rb'
23
+
24
+ # Offense count: 3
25
+ # Configuration parameters: AllowComments, AllowNil.
26
+ Lint/SuppressedException:
27
+ Exclude:
28
+ - 'lib/DhanHQ/ws/connection.rb'
29
+ - 'lib/DhanHQ/ws/registry.rb'
30
+
31
+ # Offense count: 42
32
+ # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
33
+ Metrics/AbcSize:
34
+ Exclude:
35
+ - 'bin/ta_strategy.rb'
36
+ - 'bin/ws_feed_test.rb'
37
+ - 'lib/DhanHQ/helpers/response_helper.rb'
38
+ - 'lib/DhanHQ/models/order.rb'
39
+ - 'lib/DhanHQ/rate_limiter.rb'
40
+ - 'lib/DhanHQ/ws/client.rb'
41
+ - 'lib/DhanHQ/ws/connection.rb'
42
+ - 'lib/DhanHQ/ws/decoder.rb'
43
+ - 'lib/DhanHQ/ws/orders/connection.rb'
44
+ - 'lib/DhanHQ/ws/websocket_packet_parser.rb'
45
+ - 'lib/dhan_hq.rb'
46
+ - 'lib/dhanhq/analysis/helpers/bias_aggregator.rb'
47
+ - 'lib/dhanhq/analysis/multi_timeframe_analyzer.rb'
48
+ - 'lib/dhanhq/analysis/options_buying_advisor.rb'
49
+ - 'lib/ta/candles.rb'
50
+ - 'lib/ta/fetcher.rb'
51
+ - 'lib/ta/indicators.rb'
52
+ - 'lib/ta/technical_analysis.rb'
53
+
54
+ # Offense count: 1
55
+ # Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
56
+ # AllowedMethods: refine
57
+ Metrics/BlockLength:
58
+ Exclude:
59
+ - 'lib/DhanHQ/ws/connection.rb'
60
+
61
+ # Offense count: 8
62
+ # Configuration parameters: CountComments, Max, CountAsOne.
63
+ Metrics/ClassLength:
64
+ Exclude:
65
+ - 'lib/DhanHQ/core/base_model.rb'
66
+ - 'lib/DhanHQ/models/order.rb'
67
+ - 'lib/DhanHQ/ws/connection.rb'
68
+ - 'lib/DhanHQ/ws/orders/connection.rb'
69
+ - 'lib/DhanHQ/ws/websocket_packet_parser.rb'
70
+ - 'lib/dhanhq/analysis/multi_timeframe_analyzer.rb'
71
+ - 'lib/dhanhq/analysis/options_buying_advisor.rb'
72
+ - 'lib/ta/technical_analysis.rb'
73
+
74
+ # Offense count: 25
75
+ # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
76
+ Metrics/CyclomaticComplexity:
77
+ Exclude:
78
+ - 'bin/ta_strategy.rb'
79
+ - 'bin/ws_feed_test.rb'
80
+ - 'lib/DhanHQ/helpers/response_helper.rb'
81
+ - 'lib/DhanHQ/models/order.rb'
82
+ - 'lib/DhanHQ/ws/connection.rb'
83
+ - 'lib/DhanHQ/ws/decoder.rb'
84
+ - 'lib/DhanHQ/ws/orders/connection.rb'
85
+ - 'lib/DhanHQ/ws/segments.rb'
86
+ - 'lib/DhanHQ/ws/websocket_packet_parser.rb'
87
+ - 'lib/dhanhq/analysis/helpers/bias_aggregator.rb'
88
+ - 'lib/dhanhq/analysis/multi_timeframe_analyzer.rb'
89
+ - 'lib/dhanhq/analysis/options_buying_advisor.rb'
90
+ - 'lib/ta/candles.rb'
91
+ - 'lib/ta/indicators.rb'
92
+ - 'lib/ta/technical_analysis.rb'
93
+
94
+ # Offense count: 52
95
+ # Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns.
96
+ Metrics/MethodLength:
97
+ Exclude:
98
+ - 'bin/ta_strategy.rb'
99
+ - 'bin/ws_feed_test.rb'
100
+ - 'lib/DhanHQ/core/base_model.rb'
101
+ - 'lib/DhanHQ/helpers/response_helper.rb'
102
+ - 'lib/DhanHQ/models/holding.rb'
103
+ - 'lib/DhanHQ/models/instrument.rb'
104
+ - 'lib/DhanHQ/models/ledger_entry.rb'
105
+ - 'lib/DhanHQ/models/order.rb'
106
+ - 'lib/DhanHQ/rate_limiter.rb'
107
+ - 'lib/DhanHQ/ws/connection.rb'
108
+ - 'lib/DhanHQ/ws/decoder.rb'
109
+ - 'lib/DhanHQ/ws/orders/connection.rb'
110
+ - 'lib/DhanHQ/ws/segments.rb'
111
+ - 'lib/DhanHQ/ws/singleton_lock.rb'
112
+ - 'lib/DhanHQ/ws/websocket_packet_parser.rb'
113
+ - 'lib/dhanhq/analysis/helpers/bias_aggregator.rb'
114
+ - 'lib/dhanhq/analysis/multi_timeframe_analyzer.rb'
115
+ - 'lib/dhanhq/analysis/options_buying_advisor.rb'
116
+ - 'lib/ta/candles.rb'
117
+ - 'lib/ta/fetcher.rb'
118
+ - 'lib/ta/indicators.rb'
119
+ - 'lib/ta/technical_analysis.rb'
120
+
121
+ # Offense count: 3
122
+ # Configuration parameters: CountComments, Max, CountAsOne.
123
+ Metrics/ModuleLength:
124
+ Exclude:
125
+ - 'bin/ta_strategy.rb'
126
+ - 'lib/DhanHQ/constants.rb'
127
+ - 'lib/ta/indicators.rb'
128
+
129
+ # Offense count: 1
130
+ # Configuration parameters: Max, CountKeywordArgs, MaxOptionalParameters.
131
+ Metrics/ParameterLists:
132
+ Exclude:
133
+ - 'lib/ta/technical_analysis.rb'
134
+
135
+ # Offense count: 21
136
+ # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
137
+ Metrics/PerceivedComplexity:
138
+ Exclude:
139
+ - 'bin/ta_strategy.rb'
140
+ - 'bin/ws_feed_test.rb'
141
+ - 'lib/DhanHQ/helpers/response_helper.rb'
142
+ - 'lib/DhanHQ/models/order.rb'
143
+ - 'lib/DhanHQ/ws/connection.rb'
144
+ - 'lib/DhanHQ/ws/decoder.rb'
145
+ - 'lib/DhanHQ/ws/orders/connection.rb'
146
+ - 'lib/dhanhq/analysis/helpers/bias_aggregator.rb'
147
+ - 'lib/dhanhq/analysis/multi_timeframe_analyzer.rb'
148
+ - 'lib/dhanhq/analysis/options_buying_advisor.rb'
149
+ - 'lib/ta/candles.rb'
150
+ - 'lib/ta/indicators.rb'
151
+ - 'lib/ta/technical_analysis.rb'
152
+
153
+ # Offense count: 1
154
+ # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
155
+ # AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
156
+ Naming/MethodParameterName:
157
+ Exclude:
158
+ - 'lib/DhanHQ/ws/connection.rb'
159
+
160
+ # Offense count: 7
161
+ # Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
162
+ # AllowedMethods: call
163
+ # WaywardPredicates: nonzero?
164
+ Naming/PredicateMethod:
165
+ Exclude:
166
+ - 'lib/DhanHQ/models/forever_order.rb'
167
+ - 'lib/DhanHQ/models/order.rb'
168
+ - 'lib/DhanHQ/models/super_order.rb'
169
+ - 'lib/DhanHQ/ws/singleton_lock.rb'
170
+
171
+ # Offense count: 5
172
+ # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
173
+ # SupportedStyles: snake_case, normalcase, non_integer
174
+ # AllowedIdentifiers: TLS1_1, TLS1_2, capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64
175
+ Naming/VariableNumber:
176
+ Exclude:
177
+ - 'lib/DhanHQ/ws/connection.rb'
178
+ - 'lib/DhanHQ/ws/orders/connection.rb'
179
+
180
+ # Offense count: 3
181
+ # Configuration parameters: MinSize.
182
+ Performance/CollectionLiteralInLoop:
183
+ Exclude:
184
+ - 'lib/dhanhq/analysis/multi_timeframe_analyzer.rb'
185
+ - 'lib/ta/fetcher.rb'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ### Changed
4
+ - Align Super Order documentation across README, README1, and GUIDE with the latest API contract (place, modify, cancel, list).
5
+ - Normalise remaining documentation examples to snake_case, including order update WebSocket callbacks and kill switch response guidance.
6
+
7
+ ## [2.1.5] - 2025-01-27
8
+
9
+ ### ⚠️ BREAKING CHANGES
10
+ - **Changed require statement**: `require 'DhanHQ'` → `require 'dhan_hq'`
11
+ - This affects all Ruby files that require the gem
12
+ - Update all `require 'DhanHQ'` statements to `require 'dhan_hq'` in your codebase
13
+ - The gem name remains `DhanHQ` in your Gemfile, only the require statement changes
14
+
15
+ ### Added
16
+ - **OptionChain validation**: Added proper parameter validation for `OptionChain.fetch` and `OptionChain.fetch_expiry_list` methods
17
+ - `OptionChain.fetch` requires `underlying_scrip`, `underlying_seg`, and `expiry` parameters
18
+ - `OptionChain.fetch_expiry_list` requires only `underlying_scrip` and `underlying_seg` parameters
19
+ - Validates exchange segments against `%w[IDX_I NSE_FNO BSE_FNO MCX_FO]`
20
+ - Validates expiry format as `YYYY-MM-DD` and ensures it's a valid date
21
+
22
+ ### Fixed
23
+ - **RuboCop compliance**: Fixed all RuboCop offenses (179 → 0 offenses)
24
+ - **Documentation**: Updated all documentation examples to use `require 'dhan_hq'`
25
+ - **Documentation**: Correct Super Order examples to use snake_case parameters for `DhanHQ::Models` helpers
26
+ - **Documentation**: Normalise Super Order path placeholders and response fields to snake_case for consistency
27
+ - **Documentation**: Clarified that model helpers auto-inject `dhan_client_id`, removing the need to add it manually in Ruby payloads
28
+ - **Code quality**: Added comprehensive validation tests for OptionChain methods
29
+
30
+ ### Changed
31
+ - **File structure**: Renamed main library file from `lib/DhanHQ.rb` to `lib/dhan_hq.rb` for better Ruby conventions
32
+ - **Require paths**: Updated all internal require statements to use snake_case naming
33
+
3
34
  ## [2.1.0] - 2025-09-20
4
35
 
5
36
  - Add REST coverage for EDIS (`/edis/form`, `/edis/bulkform`, `/edis/tpin`, `/edis/inquire/{isin}`) and the account kill-switch endpoint.
data/GUIDE.md CHANGED
@@ -32,7 +32,7 @@ bundle install
32
32
  Bootstrap from environment variables:
33
33
 
34
34
  ```ruby
35
- require 'DhanHQ'
35
+ require 'dhan_hq'
36
36
 
37
37
  DhanHQ.configure_with_env
38
38
  DhanHQ.logger.level = (ENV["DHAN_LOG_LEVEL"] || "INFO").upcase.then { |level| Logger.const_get(level) }
@@ -156,9 +156,9 @@ puts order.order_status # => "TRADED" / "PENDING" / ...
156
156
 
157
157
  `Order#modify` merges the existing attributes with the supplied overrides and validates against `ModifyOrderContract`.
158
158
 
159
- - Required: the instance must have an `order_id` and `dhan_client_id`.
159
+ - Required: the instance must have an `order_id`; the model reuses the saved `dhan_client_id` when building the payload.
160
160
  - At least one of `order_type`, `quantity`, `price`, `trigger_price`, `disclosed_quantity`, `validity` must change.
161
- - Payload is camelised automatically before hitting `/v2/orders/{orderId}`.
161
+ - Payload is camelised automatically before hitting `/v2/orders/{order_id}`.
162
162
 
163
163
  ```ruby
164
164
  order.modify(price: 154.2, trigger_price: 149.5)
@@ -208,42 +208,174 @@ DhanHQ::Models::Order.resource.slicing(payload)
208
208
 
209
209
  ### Super Orders
210
210
 
211
- `DhanHQ::Models::SuperOrder` wraps `/v2/super/orders`.
211
+ `DhanHQ::Models::SuperOrder` wraps the `/v2/super/orders` family. A super order combines entry, target, and stop-loss legs into one atomic instruction and supports an optional trailing jump so risk is managed server-side immediately after entry.
212
212
 
213
- ```ruby
214
- legs = {
215
- transactionType: "BUY",
216
- exchangeSegment: "NSE_FNO",
217
- productType: "CO",
218
- orderType: "LIMIT",
219
- validity: "DAY",
220
- securityId: "43492",
221
- quantity: 50,
222
- price: 100.0,
223
- stopLossPrice: 95.0,
224
- targetPrice: 110.0
213
+ #### Endpoints
214
+
215
+ | Method | Path | Description |
216
+ | --- | --- | --- |
217
+ | `POST` | `/super/orders` | Create a new super order |
218
+ | `PUT` | `/super/orders/{order_id}` | Modify a pending super order |
219
+ | `DELETE` | `/super/orders/{order_id}/{order_leg}` | Cancel a pending super order leg |
220
+ | `GET` | `/super/orders` | Retrieve the list of all super orders |
221
+
222
+ #### Place Super Order
223
+
224
+ > ℹ️ Static IP whitelisting with Dhan support is required before invoking these APIs.
225
+
226
+ ```bash
227
+ curl --request POST \
228
+ --url https://api.dhan.co/v2/super/orders \
229
+ --header 'Content-Type: application/json' \
230
+ --header 'access-token: JWT' \
231
+ --data '{Request JSON}'
232
+ ```
233
+
234
+ Request body:
235
+
236
+ ```json
237
+ {
238
+ "dhan_client_id": "1000000003",
239
+ "correlation_id": "123abc678",
240
+ "transaction_type": "BUY",
241
+ "exchange_segment": "NSE_EQ",
242
+ "product_type": "CNC",
243
+ "order_type": "LIMIT",
244
+ "security_id": "11536",
245
+ "quantity": 5,
246
+ "price": 1500,
247
+ "target_price": 1600,
248
+ "stop_loss_price": 1400,
249
+ "trailing_jump": 10
250
+ }
251
+ ```
252
+
253
+ Key parameters:
254
+
255
+ | Field | Type | Notes |
256
+ | --- | --- | --- |
257
+ | `dhan_client_id` | string *(required)* | User specific identifier generated by Dhan. Automatically merged when you call through the Ruby model helpers. |
258
+ | `correlation_id` | string | Optional caller supplied correlation id. |
259
+ | `transaction_type` | enum string *(required)* | `BUY` or `SELL`. |
260
+ | `exchange_segment` | enum string *(required)* | Exchange segment. |
261
+ | `product_type` | enum string *(required)* | `CNC`, `INTRADAY`, `MARGIN`, or `MTF`. |
262
+ | `order_type` | enum string *(required)* | `LIMIT` or `MARKET`. |
263
+ | `security_id` | string *(required)* | Exchange security identifier. |
264
+ | `quantity` | integer *(required)* | Entry quantity. |
265
+ | `price` | float *(required)* | Entry price. |
266
+ | `target_price` | float *(required)* | Target price for the super order. |
267
+ | `stop_loss_price` | float *(required)* | Stop-loss price for the super order. |
268
+ | `trailing_jump` | float *(required)* | Trailing jump size. |
269
+
270
+ > 🐍 Pass snake_case keys when invoking `DhanHQ::Models::SuperOrder.create`—the client camelizes internally before calling the REST API and injects your configured `dhan_client_id`, so the key is optional in Ruby payloads.
271
+
272
+ Response:
273
+
274
+ ```json
275
+ {
276
+ "order_id": "112111182198",
277
+ "order_status": "PENDING"
225
278
  }
279
+ ```
226
280
 
227
- super_order = DhanHQ::Models::SuperOrder.create(legs)
228
- super_order.modify(trailingJump: 2.5)
229
- super_order.cancel("ENTRY_LEG")
281
+ #### Modify Super Order
282
+
283
+ Modify while the order is `PENDING` or `PART_TRADED`. Entry leg updates adjust the entire super order until the entry trades; afterwards only target and stop-loss legs (price, trailing) remain editable.
284
+
285
+ ```bash
286
+ curl --request PUT \
287
+ --url https://api.dhan.co/v2/super/orders/{order_id} \
288
+ --header 'Content-Type: application/json' \
289
+ --header 'access-token: JWT' \
290
+ --data '{Request JSON}'
291
+ ```
292
+
293
+ Example payload:
294
+
295
+ ```json
296
+ {
297
+ "dhan_client_id": "1000000009",
298
+ "order_id": "112111182045",
299
+ "order_type": "LIMIT",
300
+ "leg_name": "ENTRY_LEG",
301
+ "quantity": 40,
302
+ "price": 1300,
303
+ "target_price": 1450,
304
+ "stop_loss_price": 1350,
305
+ "trailing_jump": 20
306
+ }
307
+ ```
308
+
309
+ Conditional fields:
310
+
311
+ | Field | Required when | Notes |
312
+ | --- | --- | --- |
313
+ | `order_type` | Updating `ENTRY_LEG` | `LIMIT` or `MARKET`. |
314
+ | `quantity` | Updating `ENTRY_LEG` | Adjusts entry quantity. |
315
+ | `price` | Updating `ENTRY_LEG` | Adjusts entry price. |
316
+ | `target_price` | Updating `ENTRY_LEG` or `TARGET_LEG` | Adjusts target price. |
317
+ | `stop_loss_price` | Updating `ENTRY_LEG` or `STOP_LOSS_LEG` | Adjusts stop-loss price. |
318
+ | `trailing_jump` | Updating `ENTRY_LEG` or `STOP_LOSS_LEG` | Pass `0` or omit to cancel trailing. |
319
+
320
+ Response:
321
+
322
+ ```json
323
+ {
324
+ "order_id": "112111182045",
325
+ "order_status": "TRANSIT"
326
+ }
230
327
  ```
231
328
 
329
+ #### Cancel Super Order
330
+
331
+ ```bash
332
+ curl --request DELETE \
333
+ --url https://api.dhan.co/v2/super/orders/{order_id}/{order_leg} \
334
+ --header 'Content-Type: application/json' \
335
+ --header 'access-token: JWT'
336
+ ```
337
+
338
+ Path parameters:
339
+
340
+ | Field | Description | Example |
341
+ | --- | --- | --- |
342
+ | `order_id` | Super order identifier. | `11211182198` |
343
+ | `order_leg` | Leg to cancel (`ENTRY_LEG`, `TARGET_LEG`, or `STOP_LOSS_LEG`). | `ENTRY_LEG` |
344
+
345
+ Response:
346
+
347
+ ```json
348
+ {
349
+ "order_id": "112111182045",
350
+ "order_status": "CANCELLED"
351
+ }
352
+ ```
353
+
354
+ #### Super Order List
355
+
356
+ ```bash
357
+ curl --request GET \
358
+ --url https://api.dhan.co/v2/super/orders \
359
+ --header 'Content-Type: application/json' \
360
+ --header 'access-token: JWT'
361
+ ```
362
+
363
+ The response returns one object per super order with nested `leg_details`. Key attributes include `order_status`, `filled_qty`, `remaining_quantity`, `average_traded_price`, and leg-level trailing configuration. `CLOSED` indicates the entry plus either target or stop-loss filled the entire quantity; `TRIGGERED` surfaces on the target or stop-loss leg that fired.
364
+
232
365
  ### Forever Orders (GTT)
233
366
 
234
367
  `DhanHQ::Models::ForeverOrder` maps to `/v2/forever/orders`.
235
368
 
236
369
  ```ruby
237
370
  params = {
238
- dhanClientId: "123456",
239
- transactionType: "SELL",
240
- exchangeSegment: "NSE_EQ",
241
- productType: "CNC",
242
- orderType: "LIMIT",
371
+ transaction_type: "SELL",
372
+ exchange_segment: "NSE_EQ",
373
+ product_type: "CNC",
374
+ order_type: "LIMIT",
243
375
  validity: "DAY",
244
- securityId: "1333",
376
+ security_id: "1333",
245
377
  price: 200.0,
246
- triggerPrice: 198.0
378
+ trigger_price: 198.0
247
379
  }
248
380
 
249
381
  forever_order = DhanHQ::Models::ForeverOrder.create(params)
@@ -251,6 +383,8 @@ forever_order.modify(price: 205.0)
251
383
  forever_order.cancel
252
384
  ```
253
385
 
386
+ > 🪄 Model helpers merge the configured `dhan_client_id` automatically, so you can omit it when constructing Ruby hashes like the example above.
387
+
254
388
  The forever order helpers accept snake_case parameters and camelize them internally; only the low-level resource requires raw API casing.
255
389
 
256
390
  ---
@@ -268,7 +402,6 @@ Convert an intraday position to delivery (or vice versa):
268
402
 
269
403
  ```ruby
270
404
  convert_payload = {
271
- dhan_client_id: "123456",
272
405
  security_id: "1333",
273
406
  from_product_type: "INTRADAY",
274
407
  to_product_type: "CNC",
@@ -281,6 +414,8 @@ response = DhanHQ::Models::Position.convert(convert_payload)
281
414
  raise response.errors.to_s if response.is_a?(DhanHQ::ErrorObject)
282
415
  ```
283
416
 
417
+ > 🪄 No need to merge `dhan_client_id`; the helper adds it from your configuration before calling `/v2/positions/convert`.
418
+
284
419
  The conversion helper validates the payload with `PositionConversionContract`; missing or invalid fields raise `DhanHQ::Error` before the request is sent.
285
420
 
286
421
  ### Holdings
@@ -379,7 +514,6 @@ The model filters strikes where both CE and PE have zero `last_price`, keeping t
379
514
 
380
515
  ```ruby
381
516
  params = {
382
- dhan_client_id: "123456",
383
517
  exchange_segment: "NSE_EQ",
384
518
  transaction_type: "BUY",
385
519
  quantity: 10,
@@ -392,6 +526,8 @@ margin = DhanHQ::Models::Margin.calculate(params)
392
526
  puts margin.total_margin
393
527
  ```
394
528
 
529
+ > 🪄 The margin helper appends `dhan_client_id` from your credentials before calling `/v2/margincalculator`.
530
+
395
531
  If a required field is missing (for example `transaction_type`), the contract raises `DhanHQ::Error` before any API call is issued.
396
532
 
397
533
  ### REST Market Feed (Batch LTP/OHLC/Quote)
@@ -473,14 +609,20 @@ All helpers accept snake_case keys; the client camelizes them before calling `/v
473
609
  ### Kill Switch
474
610
 
475
611
  ```ruby
476
- DhanHQ::Models::KillSwitch.activate # => {"killSwitchStatus"=>"ACTIVATE"}
477
- DhanHQ::Models::KillSwitch.deactivate # => {"killSwitchStatus"=>"DEACTIVATE"}
612
+ activate_payload = DhanHQ::Models::KillSwitch.activate
613
+ deactivate_payload = DhanHQ::Models::KillSwitch.deactivate
614
+
615
+ DhanHQ::Models::KillSwitch.snake_case(activate_payload)
616
+ # => { kill_switch_status: "ACTIVATE" }
617
+
618
+ DhanHQ::Models::KillSwitch.snake_case(deactivate_payload)
619
+ # => { kill_switch_status: "DEACTIVATE" }
478
620
 
479
621
  # Explicit status update
480
622
  DhanHQ::Models::KillSwitch.update("ACTIVATE")
481
623
  ```
482
624
 
483
- Only `"ACTIVATE"` and `"DEACTIVATE"` are accepted—any other value raises `DhanHQ::Error`.
625
+ Only `"ACTIVATE"` and `"DEACTIVATE"` are accepted—any other value raises `DhanHQ::Error`. Use the `snake_case` helper to normalise API responses when you prefer underscore keys.
484
626
 
485
627
  ---
486
628