DhanHQ 2.5.0 → 2.6.0
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 +70 -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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 30825da308f5f85870f4efe9b702f7e2f653840b396b3265d36383d4a8c56f5e
|
|
4
|
+
data.tar.gz: b2874edeb45b60b6e68b4d8c69b9e9e3c6a0b6d2734ca645168626afd27cde76
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fe803337db74aa9689001b458627a532101fd0d298142b74ed0fefd87e7938ef4fd2b5e75bb53d871d8c535df35347065a43428986d930e6a0fa1ebae0c19aaf
|
|
7
|
+
data.tar.gz: aae78dbbbea337312262239f083c8fbb96f65b51b2d70cb9dce2683204f5e506d5a0835c85af6766ce0233262e79aaaf5dde45561eb410d51c52c74a185d5184
|
data/.rubocop.yml
CHANGED
|
@@ -6,6 +6,7 @@ plugins:
|
|
|
6
6
|
|
|
7
7
|
require:
|
|
8
8
|
- rubocop-rake
|
|
9
|
+
- ./lib/rubocop/cop/dhanhq/use_constants.rb
|
|
9
10
|
|
|
10
11
|
AllCops:
|
|
11
12
|
TargetRubyVersion: 3.2
|
|
@@ -25,4 +26,11 @@ RSpec/ExampleLength:
|
|
|
25
26
|
Max: 15
|
|
26
27
|
|
|
27
28
|
RSpec/MultipleMemoizedHelpers:
|
|
28
|
-
Max: 10
|
|
29
|
+
Max: 10
|
|
30
|
+
|
|
31
|
+
DhanHQ/UseConstants:
|
|
32
|
+
Enabled: true
|
|
33
|
+
Exclude:
|
|
34
|
+
- 'lib/DhanHQ/constants.rb'
|
|
35
|
+
- 'lib/DhanHQ/ws/segments.rb'
|
|
36
|
+
- 'spec/**/*'
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,67 @@
|
|
|
1
|
+
## [2.6.0] - 2026-03-06
|
|
2
|
+
|
|
3
|
+
### Fixed (API docs alignment)
|
|
4
|
+
|
|
5
|
+
- **Kill Switch**: Manage API now uses query parameter per [dhanhq.co/docs/v2/traders-control](https://dhanhq.co/docs/v2/traders-control/). `Resources::KillSwitch#update(status)` sends `POST /v2/killswitch?killSwitchStatus=ACTIVATE` (or `DEACTIVATE`) with no body. `Models::KillSwitch.update("ACTIVATE")` / `.activate` / `.deactivate` unchanged.
|
|
6
|
+
- **IP Setup**: Set/Modify now send required API fields. `Resources::IPSetup#set` and `#update` accept `ip:`, `ip_flag: "PRIMARY"` (or `"SECONDARY"`), and optional `dhan_client_id:` (defaults from `DhanHQ.configuration.client_id`). See [dhanhq.co/docs/v2/authentication/#setup-static-ip](https://dhanhq.co/docs/v2/authentication/#setup-static-ip).
|
|
7
|
+
- **Alert Orders (Conditional Trigger)**: Condition now requires `exchange_segment`, `exp_date`, and `frequency` per [dhanhq.co/docs/v2/conditional-trigger](https://dhanhq.co/docs/v2/conditional-trigger/). `time_frame` is required when `comparison_type` starts with `TECHNICAL`. `AlertOrderContract` and all examples updated.
|
|
8
|
+
|
|
9
|
+
### Breaking changes
|
|
10
|
+
|
|
11
|
+
- **AlertOrder.create / AlertOrderContract**: Contract expects nested structure (see 2.5.0). Condition hash must include `exchange_segment`, `exp_date`, and `frequency`; for `comparison_type` starting with `TECHNICAL`, `time_frame` is required. See GUIDE.md and [conditional-trigger](https://dhanhq.co/docs/v2/conditional-trigger/).
|
|
12
|
+
- **Resources::KillSwitch#update**: Signature is now `update(status)` (string). Use `update("ACTIVATE")` or `Models::KillSwitch.activate` / `.deactivate`, unchanged.
|
|
13
|
+
- **AlertOrderContract** — expected payload shape:
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
AlertOrderContract.new.call(
|
|
17
|
+
condition: {
|
|
18
|
+
exchange_segment: "NSE_EQ",
|
|
19
|
+
security_id: "11536",
|
|
20
|
+
comparison_type: "PRICE_WITH_VALUE",
|
|
21
|
+
operator: "GREATER_THAN",
|
|
22
|
+
exp_date: "2026-12-31",
|
|
23
|
+
frequency: "ONCE"
|
|
24
|
+
},
|
|
25
|
+
orders: [
|
|
26
|
+
{ transaction_type: "BUY", exchange_segment: "NSE_EQ", product_type: "INTRADAY", order_type: "MARKET", security_id: "11536", quantity: 5, validity: "DAY" }
|
|
27
|
+
]
|
|
28
|
+
)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
#### Order Model — New Public Methods
|
|
34
|
+
- **`Order#destroy` / `#delete`**: Cancels an order via `DELETE /v2/orders/{id}`. Returns `true` if the API confirms `CANCELLED` status, `false` otherwise. `#delete` is an alias.
|
|
35
|
+
- **`Order#slice_order(params)`**: Splits a large order into multiple legs to exceed freeze-limit quantities on F&O instruments via `POST /v2/slicing`. Delegates to `Resources::Orders#slicing`.
|
|
36
|
+
- **`Order#save`**: ActiveRecord-style save — places a new order for new records, modifies existing records. Returns `true`/`false`.
|
|
37
|
+
- **`Order.place` — `dhan_client_id` auto-injection**: If `dhan_client_id` is not passed in params, it is automatically read from `DhanHQ.configuration.client_id`. Existing code that passes `dhan_client_id` explicitly continues to work unchanged.
|
|
38
|
+
|
|
39
|
+
#### Contract Hardening
|
|
40
|
+
- **`OrderContract`** (base for `PlaceOrderContract` and `ModifyOrderContract`) now enforces:
|
|
41
|
+
- `LIMIT` orders require `price`; `MARKET` orders reject `price`
|
|
42
|
+
- `STOP_LOSS` / `STOP_LOSS_MARKET` require `trigger_price`
|
|
43
|
+
- Stop-loss price relationships: BUY requires `trigger_price >= price`; SELL requires `trigger_price <= price`
|
|
44
|
+
- Bracket Order (BO): both `bo_profit_value` and `bo_stop_loss_value` required; directional profit/loss relationship validated
|
|
45
|
+
- `disclosed_quantity` cannot exceed 30% of `quantity`
|
|
46
|
+
- `amo_time` required when `after_market_order: true`
|
|
47
|
+
- Lot-size and tick-size enforcement when `instrument_meta` is provided
|
|
48
|
+
- Segment-based product restrictions (CNC equity-only, BO/CO currency restrictions)
|
|
49
|
+
- **`ModifyOrderContract`**: Requires at least one modifiable field; inherits all `OrderContract` business rules.
|
|
50
|
+
- **New contracts**: `EdisContract`, `UserIpContract`, `PnlBasedExitContract`, `MultiScripMarginCalcContract`, `SliceOrderContract`.
|
|
51
|
+
|
|
52
|
+
#### Infrastructure
|
|
53
|
+
- **`ApiResponseHandler` concern** (`lib/DhanHQ/models/concerns/api_response_handler.rb`): Shared module for uniform API response handling, attribute merging, and structured logging. Included in `Order` and `ForeverOrder`.
|
|
54
|
+
- **Global Constants Enforcement**: Replaced all hardcoded API strings with `DhanHQ::Constants` across the repository. Built a custom RuboCop cop (`RuboCop::Cop::DhanHQ::UseConstants`) that strictly enforces typed constants instead of loose strings for robust API payloads.
|
|
55
|
+
- **Constants Documentation**: Added `docs/CONSTANTS_REFERENCE.md` detailing all SDK constants (e.g., `ExchangeSegment`, `ProductType`, `OrderType`, etc.).
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
- Replaced 160+ hardcoded usages of strings like `"NSE_EQ"` and `"BUY"` with `DhanHQ::Constants::ExchangeSegment::NSE_EQ` and `DhanHQ::Constants::TransactionType::BUY`.
|
|
59
|
+
- Added `NO_HOLDINGS` (value `"DH-1111"`) to `TradingErrorCode`.
|
|
60
|
+
- `PlaceOrderContract` refactored to inherit from `OrderContract`, eliminating duplicated validation logic. Derivative-specific fields (`drv_expiry_date`, `drv_option_type`, `drv_strike_price`) remain on `PlaceOrderContract`.
|
|
61
|
+
- `Resources::Orders` now fetches optional instrument metadata (lot size, tick size) to pass into contract validation.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
1
65
|
## [2.5.0] - 2026-02-21
|
|
2
66
|
|
|
3
67
|
### Added
|
|
@@ -55,7 +119,7 @@
|
|
|
55
119
|
|
|
56
120
|
### Added
|
|
57
121
|
- **Alert Orders**: `DhanHQ::Resources::AlertOrders` (BaseResource) and `DhanHQ::Models::AlertOrder` with full CRUD. Endpoints: GET/POST `/alerts/orders`, GET/PUT/DELETE `/alerts/orders/{id}` (per API docs). Validation via `DhanHQ::Contracts::AlertOrderContract`.
|
|
58
|
-
- **IP Setup**: `DhanHQ::Resources::IPSetup` (resource-only). Methods: `current` (GET `/ip/getIP`), `set(ip:)` (POST `/ip/setIP`), `update(ip:)` (PUT `/ip/modifyIP`) per API docs.
|
|
122
|
+
- **IP Setup**: `DhanHQ::Resources::IPSetup` (resource-only). Methods: `current` (GET `/ip/getIP`), `set(ip:, ip_flag: "PRIMARY", dhan_client_id: nil)` (POST `/ip/setIP`), `update(ip:, ip_flag: "PRIMARY", dhan_client_id: nil)` (PUT `/ip/modifyIP`). Body includes `dhanClientId` (default from config) and `ipFlag` per API docs.
|
|
59
123
|
- **Trader Control (Kill Switch)**: `DhanHQ::Resources::TraderControl` (resource-only). Methods: `status` (GET `/trader-control`), `enable` (POST action ENABLE), `disable` (POST action DISABLE). `DhanHQ::Resources::KillSwitch` and `DhanHQ::Models::KillSwitch` remain for backward compatibility.
|
|
60
124
|
- **docs/API_VERIFICATION.md**: Documents alignment with [dhanhq.co/docs/v2](https://dhanhq.co/docs/v2/) and [api.dhan.co/v2](https://api.dhan.co/v2/#/) for EDIS, Alert Orders, IP Setup.
|
|
61
125
|
|
|
@@ -92,9 +156,9 @@
|
|
|
92
156
|
- **README.md**: Note under Dynamic access token for RenewToken via `DhanHQ::Auth.renew_token` and that API key/Partner flows are implemented in the app.
|
|
93
157
|
- **GUIDE.md**: “Dynamic access token” section extended with RenewToken (`DhanHQ::Auth.renew_token`) and note that API key/Partner flows are in the app.
|
|
94
158
|
- **docs/TESTING_GUIDE.md**: Optional config comment for RenewToken and pointer to AUTHENTICATION.md (API key/Partner in app).
|
|
95
|
-
- **docs/
|
|
96
|
-
- **docs/
|
|
97
|
-
- **docs/
|
|
159
|
+
- **docs/RAILS_INTEGRATION.md**: “Dynamic access token” section extended with RenewToken (web-generated tokens) and link to AUTHENTICATION.md.
|
|
160
|
+
- **docs/WEBSOCKET_INTEGRATION.md**, **docs/LIVE_ORDER_UPDATES.md**: Notes updated for dynamic token, RenewToken, and API key/Partner in app.
|
|
161
|
+
- **docs/STANDALONE_RUBY_WEBSOCKET_INTEGRATION.md**, **docs/RAILS_WEBSOCKET_INTEGRATION.md**: Configuration section updated with RenewToken and AUTHENTICATION.md link.
|
|
98
162
|
|
|
99
163
|
### CI / Release
|
|
100
164
|
|
|
@@ -144,8 +208,8 @@
|
|
|
144
208
|
- **GUIDE.md**: Short “Dynamic access token” note and link to docs/AUTHENTICATION.md.
|
|
145
209
|
- **docs/AUTHENTICATION.md**: New doc for static vs dynamic token, retry-on-401, and auth-related errors.
|
|
146
210
|
- **docs/TESTING_GUIDE.md**: Optional access_token_provider / on_token_expired in config examples.
|
|
147
|
-
- **docs/
|
|
148
|
-
- **docs/
|
|
211
|
+
- **docs/RAILS_INTEGRATION.md**: “Dynamic access token (optional)” with Rails initializer example.
|
|
212
|
+
- **docs/WEBSOCKET_INTEGRATION.md**, **docs/LIVE_ORDER_UPDATES.md**: Pointer to docs/AUTHENTICATION.md for dynamic token.
|
|
149
213
|
|
|
150
214
|
### Backward compatibility
|
|
151
215
|
|
data/GUIDE.md
CHANGED
|
@@ -150,11 +150,11 @@ Example:
|
|
|
150
150
|
|
|
151
151
|
```ruby
|
|
152
152
|
payload = {
|
|
153
|
-
transaction_type:
|
|
154
|
-
exchange_segment:
|
|
155
|
-
product_type:
|
|
156
|
-
order_type:
|
|
157
|
-
validity:
|
|
153
|
+
transaction_type: DhanHQ::Constants::TransactionType::BUY,
|
|
154
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
155
|
+
product_type: DhanHQ::Constants::ProductType::CNC,
|
|
156
|
+
order_type: DhanHQ::Constants::OrderType::LIMIT,
|
|
157
|
+
validity: DhanHQ::Constants::Validity::DAY,
|
|
158
158
|
security_id: "1333",
|
|
159
159
|
quantity: 10,
|
|
160
160
|
price: 150.0,
|
|
@@ -162,7 +162,7 @@ payload = {
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
order = DhanHQ::Models::Order.place(payload)
|
|
165
|
-
puts order.order_status # =>
|
|
165
|
+
puts order.order_status # => DhanHQ::Constants::OrderStatus::TRADED / "PENDING" / ...
|
|
166
166
|
```
|
|
167
167
|
|
|
168
168
|
### Modification & Cancellation
|
|
@@ -193,10 +193,10 @@ Use the same fields as placement, but the contract allows additional validity op
|
|
|
193
193
|
```ruby
|
|
194
194
|
slice_payload = {
|
|
195
195
|
order_id: order.order_id,
|
|
196
|
-
transaction_type:
|
|
197
|
-
exchange_segment:
|
|
198
|
-
product_type:
|
|
199
|
-
order_type:
|
|
196
|
+
transaction_type: DhanHQ::Constants::TransactionType::BUY,
|
|
197
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
198
|
+
product_type: DhanHQ::Constants::OrderType::STOP_LOSS,
|
|
199
|
+
order_type: DhanHQ::Constants::OrderType::STOP_LOSS,
|
|
200
200
|
validity: "GTC",
|
|
201
201
|
security_id: "1333",
|
|
202
202
|
quantity: 100,
|
|
@@ -381,11 +381,11 @@ The response returns one object per super order with nested `leg_details`. Key a
|
|
|
381
381
|
|
|
382
382
|
```ruby
|
|
383
383
|
params = {
|
|
384
|
-
transaction_type:
|
|
385
|
-
exchange_segment:
|
|
386
|
-
product_type:
|
|
387
|
-
order_type:
|
|
388
|
-
validity:
|
|
384
|
+
transaction_type: DhanHQ::Constants::TransactionType::SELL,
|
|
385
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
386
|
+
product_type: DhanHQ::Constants::ProductType::CNC,
|
|
387
|
+
order_type: DhanHQ::Constants::OrderType::LIMIT,
|
|
388
|
+
validity: DhanHQ::Constants::Validity::DAY,
|
|
389
389
|
security_id: "1333",
|
|
390
390
|
price: 200.0,
|
|
391
391
|
trigger_price: 198.0
|
|
@@ -416,10 +416,10 @@ Convert an intraday position to delivery (or vice versa):
|
|
|
416
416
|
```ruby
|
|
417
417
|
convert_payload = {
|
|
418
418
|
security_id: "1333",
|
|
419
|
-
from_product_type:
|
|
420
|
-
to_product_type:
|
|
419
|
+
from_product_type: DhanHQ::Constants::ProductType::INTRADAY,
|
|
420
|
+
to_product_type: DhanHQ::Constants::ProductType::CNC,
|
|
421
421
|
convert_qty: 10,
|
|
422
|
-
exchange_segment:
|
|
422
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
423
423
|
position_type: "LONG"
|
|
424
424
|
}
|
|
425
425
|
|
|
@@ -496,8 +496,8 @@ Both endpoints return arrays and skip validation because they represent historic
|
|
|
496
496
|
```ruby
|
|
497
497
|
bars = DhanHQ::Models::HistoricalData.intraday(
|
|
498
498
|
security_id: "13",
|
|
499
|
-
exchange_segment:
|
|
500
|
-
instrument:
|
|
499
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::IDX_I,
|
|
500
|
+
instrument: DhanHQ::Constants::InstrumentType::INDEX,
|
|
501
501
|
interval: "5",
|
|
502
502
|
from_date: "2024-08-14",
|
|
503
503
|
to_date: "2024-08-14"
|
|
@@ -509,13 +509,13 @@ bars = DhanHQ::Models::HistoricalData.intraday(
|
|
|
509
509
|
```ruby
|
|
510
510
|
chain = DhanHQ::Models::OptionChain.fetch(
|
|
511
511
|
underlying_scrip: 1333,
|
|
512
|
-
underlying_seg:
|
|
512
|
+
underlying_seg: DhanHQ::Constants::ExchangeSegment::NSE_FNO,
|
|
513
513
|
expiry: "2024-12-26"
|
|
514
514
|
)
|
|
515
515
|
|
|
516
516
|
expiries = DhanHQ::Models::OptionChain.fetch_expiry_list(
|
|
517
517
|
underlying_scrip: 1333,
|
|
518
|
-
underlying_seg:
|
|
518
|
+
underlying_seg: DhanHQ::Constants::ExchangeSegment::NSE_FNO
|
|
519
519
|
)
|
|
520
520
|
```
|
|
521
521
|
|
|
@@ -527,10 +527,10 @@ The model filters strikes where both CE and PE have zero `last_price`, keeping t
|
|
|
527
527
|
|
|
528
528
|
```ruby
|
|
529
529
|
params = {
|
|
530
|
-
exchange_segment:
|
|
531
|
-
transaction_type:
|
|
530
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
531
|
+
transaction_type: DhanHQ::Constants::TransactionType::BUY,
|
|
532
532
|
quantity: 10,
|
|
533
|
-
product_type:
|
|
533
|
+
product_type: DhanHQ::Constants::ProductType::INTRADAY,
|
|
534
534
|
security_id: "1333",
|
|
535
535
|
price: 150.0
|
|
536
536
|
}
|
|
@@ -618,8 +618,8 @@ ws.on(:tick) do |tick|
|
|
|
618
618
|
puts "[#{tick[:segment]} #{tick[:security_id]}] LTP=#{tick[:ltp]} kind=#{tick[:kind]}"
|
|
619
619
|
end
|
|
620
620
|
|
|
621
|
-
ws.subscribe_one(segment:
|
|
622
|
-
ws.unsubscribe_one(segment:
|
|
621
|
+
ws.subscribe_one(segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "13")
|
|
622
|
+
ws.unsubscribe_one(segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "13")
|
|
623
623
|
|
|
624
624
|
ws.disconnect!
|
|
625
625
|
```
|
|
@@ -643,17 +643,34 @@ If the credentials are invalid the helper raises `DhanHQ::InvalidAuthenticationE
|
|
|
643
643
|
|
|
644
644
|
### Alert Orders
|
|
645
645
|
|
|
646
|
+
Condition must include `exchange_segment`, `exp_date`, and `frequency` per [conditional-trigger API](https://dhanhq.co/docs/v2/conditional-trigger/). For technical indicators, `time_frame` is also required.
|
|
647
|
+
|
|
646
648
|
```ruby
|
|
647
649
|
# Model (CRUD)
|
|
648
650
|
DhanHQ::Models::AlertOrder.all
|
|
649
651
|
alert = DhanHQ::Models::AlertOrder.find("alert-id")
|
|
650
652
|
alert = DhanHQ::Models::AlertOrder.create(
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
653
|
+
condition: {
|
|
654
|
+
security_id: "11536",
|
|
655
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
656
|
+
comparison_type: DhanHQ::Constants::ComparisonType::PRICE_WITH_VALUE,
|
|
657
|
+
operator: DhanHQ::Constants::Operator::GREATER_THAN,
|
|
658
|
+
comparing_value: 100.0,
|
|
659
|
+
exp_date: (Date.today + 365).strftime("%Y-%m-%d"),
|
|
660
|
+
frequency: "ONCE"
|
|
661
|
+
},
|
|
662
|
+
orders: [
|
|
663
|
+
{
|
|
664
|
+
transaction_type: DhanHQ::Constants::TransactionType::BUY,
|
|
665
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
666
|
+
product_type: DhanHQ::Constants::ProductType::CNC,
|
|
667
|
+
order_type: DhanHQ::Constants::OrderType::LIMIT,
|
|
668
|
+
security_id: "11536",
|
|
669
|
+
quantity: 10,
|
|
670
|
+
validity: DhanHQ::Constants::Validity::DAY,
|
|
671
|
+
price: 150.0
|
|
672
|
+
}
|
|
673
|
+
]
|
|
657
674
|
)
|
|
658
675
|
alert.save
|
|
659
676
|
alert.destroy
|
|
@@ -687,13 +704,14 @@ Params use snake_case; the client camelizes them before calling `/edis/...`.
|
|
|
687
704
|
|
|
688
705
|
### IP Setup
|
|
689
706
|
|
|
690
|
-
Resource-only (account configuration) per API docs: GET /ip/getIP, POST /ip/setIP, PUT /ip/modifyIP.
|
|
707
|
+
Resource-only (account configuration) per [API docs](https://dhanhq.co/docs/v2/authentication/#setup-static-ip): GET /ip/getIP, POST /ip/setIP, PUT /ip/modifyIP. Set/Modify require `dhanClientId`, `ip`, and `ipFlag` (PRIMARY or SECONDARY).
|
|
691
708
|
|
|
692
709
|
```ruby
|
|
693
710
|
ip = DhanHQ::Resources::IPSetup.new
|
|
694
|
-
ip.current
|
|
695
|
-
ip.set(ip: "103.21.58.121")
|
|
696
|
-
ip.
|
|
711
|
+
ip.current # GET /ip/getIP
|
|
712
|
+
ip.set(ip: "103.21.58.121") # ip_flag defaults to "PRIMARY", dhan_client_id from config
|
|
713
|
+
ip.set(ip: "103.21.58.121", ip_flag: "SECONDARY")
|
|
714
|
+
ip.update(ip: "103.21.58.121", ip_flag: "PRIMARY")
|
|
697
715
|
```
|
|
698
716
|
|
|
699
717
|
### Trader Control (Kill Switch)
|
|
@@ -709,7 +727,7 @@ tc.enable # Trading resumed
|
|
|
709
727
|
|
|
710
728
|
### Kill Switch (model)
|
|
711
729
|
|
|
712
|
-
|
|
730
|
+
Uses query parameter per API doc: `POST /v2/killswitch?killSwitchStatus=ACTIVATE` (or DEACTIVATE), no body.
|
|
713
731
|
|
|
714
732
|
```ruby
|
|
715
733
|
activate_payload = DhanHQ::Models::KillSwitch.activate
|
|
@@ -725,7 +743,7 @@ DhanHQ::Models::KillSwitch.snake_case(deactivate_payload)
|
|
|
725
743
|
DhanHQ::Models::KillSwitch.update("ACTIVATE")
|
|
726
744
|
```
|
|
727
745
|
|
|
728
|
-
Only `"ACTIVATE"` and `"DEACTIVATE"` are accepted
|
|
746
|
+
Only `"ACTIVATE"` and `"DEACTIVATE"` are accepted. Use the `snake_case` helper to normalise API responses when you prefer underscore keys.
|
|
729
747
|
|
|
730
748
|
---
|
|
731
749
|
|
data/README.md
CHANGED
|
@@ -124,11 +124,11 @@ When the API returns 401, the client retries **once** with a fresh token from yo
|
|
|
124
124
|
|
|
125
125
|
```ruby
|
|
126
126
|
order = DhanHQ::Models::Order.new(
|
|
127
|
-
transaction_type:
|
|
128
|
-
exchange_segment:
|
|
129
|
-
product_type:
|
|
130
|
-
order_type:
|
|
131
|
-
validity:
|
|
127
|
+
transaction_type: DhanHQ::Constants::TransactionType::BUY,
|
|
128
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_FNO,
|
|
129
|
+
product_type: DhanHQ::Constants::ProductType::MARGIN,
|
|
130
|
+
order_type: DhanHQ::Constants::OrderType::LIMIT,
|
|
131
|
+
validity: DhanHQ::Constants::Validity::DAY,
|
|
132
132
|
security_id: "43492",
|
|
133
133
|
quantity: 50,
|
|
134
134
|
price: 100.0
|
|
@@ -151,8 +151,8 @@ DhanHQ::Models::Fund.balance
|
|
|
151
151
|
```ruby
|
|
152
152
|
bars = DhanHQ::Models::HistoricalData.intraday(
|
|
153
153
|
security_id: "13",
|
|
154
|
-
exchange_segment:
|
|
155
|
-
instrument:
|
|
154
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::IDX_I,
|
|
155
|
+
instrument: DhanHQ::Constants::InstrumentType::INDEX,
|
|
156
156
|
interval: "5",
|
|
157
157
|
from_date: "2025-08-14",
|
|
158
158
|
to_date: "2025-08-18"
|
|
@@ -190,8 +190,8 @@ client = DhanHQ::WS.connect(mode: :ticker) do |tick|
|
|
|
190
190
|
puts "#{tick[:security_id]} = ₹#{tick[:ltp]}"
|
|
191
191
|
end
|
|
192
192
|
|
|
193
|
-
client.subscribe_one(segment:
|
|
194
|
-
client.subscribe_one(segment:
|
|
193
|
+
client.subscribe_one(segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "13") # NIFTY
|
|
194
|
+
client.subscribe_one(segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "25") # BANKNIFTY
|
|
195
195
|
```
|
|
196
196
|
|
|
197
197
|
### Market Depth
|
|
@@ -220,10 +220,10 @@ Entry + target + stop-loss + trailing jump in a single request:
|
|
|
220
220
|
|
|
221
221
|
```ruby
|
|
222
222
|
DhanHQ::Models::SuperOrder.create(
|
|
223
|
-
transaction_type:
|
|
224
|
-
exchange_segment:
|
|
225
|
-
product_type:
|
|
226
|
-
order_type:
|
|
223
|
+
transaction_type: DhanHQ::Constants::TransactionType::BUY,
|
|
224
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
225
|
+
product_type: DhanHQ::Constants::ProductType::CNC,
|
|
226
|
+
order_type: DhanHQ::Constants::OrderType::LIMIT,
|
|
227
227
|
security_id: "11536",
|
|
228
228
|
quantity: 5,
|
|
229
229
|
price: 1500,
|
|
@@ -246,8 +246,8 @@ DhanHQ.configure_with_env
|
|
|
246
246
|
|
|
247
247
|
# 1. Check the trend using historical 5-min bars
|
|
248
248
|
bars = DhanHQ::Models::HistoricalData.intraday(
|
|
249
|
-
security_id: "13", exchange_segment:
|
|
250
|
-
instrument:
|
|
249
|
+
security_id: "13", exchange_segment: DhanHQ::Constants::ExchangeSegment::IDX_I,
|
|
250
|
+
instrument: DhanHQ::Constants::InstrumentType::INDEX, interval: "5",
|
|
251
251
|
from_date: Date.today.to_s, to_date: Date.today.to_s
|
|
252
252
|
)
|
|
253
253
|
|
|
@@ -260,11 +260,11 @@ puts "NIFTY trend: #{trend} (LTP: #{closes.last}, SMA20: #{sma_20.round(2)})"
|
|
|
260
260
|
client = DhanHQ::WS.connect(mode: :quote) do |tick|
|
|
261
261
|
puts "NIFTY ₹#{tick[:ltp]} | Vol: #{tick[:vol]} | #{Time.now.strftime('%H:%M:%S')}"
|
|
262
262
|
end
|
|
263
|
-
client.subscribe_one(segment:
|
|
263
|
+
client.subscribe_one(segment: DhanHQ::Constants::ExchangeSegment::IDX_I, security_id: "13")
|
|
264
264
|
|
|
265
265
|
# 3. On signal, place a super order with built-in risk management
|
|
266
266
|
# DhanHQ::Models::SuperOrder.create(
|
|
267
|
-
# transaction_type:
|
|
267
|
+
# transaction_type: DhanHQ::Constants::TransactionType::BUY, exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_FNO, ...
|
|
268
268
|
# target_price: entry + 50, stop_loss_price: entry - 30, trailing_jump: 5
|
|
269
269
|
# )
|
|
270
270
|
|
|
@@ -277,7 +277,7 @@ sleep # keep the script alive
|
|
|
277
277
|
|
|
278
278
|
## Rails Integration
|
|
279
279
|
|
|
280
|
-
Need initializers, service objects, ActionCable wiring, and background workers? See the [Rails Integration Guide](docs/
|
|
280
|
+
Need initializers, service objects, ActionCable wiring, and background workers? See the [Rails Integration Guide](docs/RAILS_INTEGRATION.md).
|
|
281
281
|
|
|
282
282
|
---
|
|
283
283
|
|
|
@@ -287,15 +287,16 @@ Need initializers, service objects, ActionCable wiring, and background workers?
|
|
|
287
287
|
| ----- | -------------- |
|
|
288
288
|
| [Authentication](docs/AUTHENTICATION.md) | Token flows, TOTP, OAuth, auto-management |
|
|
289
289
|
| [Configuration Reference](docs/CONFIGURATION.md) | Full ENV matrix, logging, timeouts, available resources |
|
|
290
|
-
| [WebSocket Integration](docs/
|
|
290
|
+
| [WebSocket Integration](docs/WEBSOCKET_INTEGRATION.md) | All WS types, architecture, best practices |
|
|
291
291
|
| [WebSocket Protocol](docs/WEBSOCKET_PROTOCOL.md) | Packet parsing, request codes, tick schema, exchange enums |
|
|
292
|
-
| [Rails WebSocket Guide](docs/
|
|
293
|
-
| [Rails Integration](docs/
|
|
294
|
-
| [Standalone Ruby Guide](docs/
|
|
292
|
+
| [Rails WebSocket Guide](docs/RAILS_WEBSOCKET_INTEGRATION.md) | Rails-specific patterns, ActionCable |
|
|
293
|
+
| [Rails Integration](docs/RAILS_INTEGRATION.md) | Initializers, service objects, workers |
|
|
294
|
+
| [Standalone Ruby Guide](docs/STANDALONE_RUBY_WEBSOCKET_INTEGRATION.md) | Scripts, daemons, CLI tools |
|
|
295
295
|
| [Super Orders API](docs/SUPER_ORDERS.md) | Full REST reference for super orders |
|
|
296
|
+
| [API Constants Reference](docs/CONSTANTS_REFERENCE.md) | All valid enums, exchange segments, and order parameters |
|
|
296
297
|
| [Data API Parameters](docs/DATA_API_PARAMETERS.md) | Historical data, option chain parameters |
|
|
297
298
|
| [Testing Guide](docs/TESTING_GUIDE.md) | WebSocket testing, model testing, console helpers |
|
|
298
|
-
| [Technical Analysis](docs/
|
|
299
|
+
| [Technical Analysis](docs/TECHNICAL_ANALYSIS.md) | Indicators, multi-timeframe aggregation |
|
|
299
300
|
| [Troubleshooting](docs/TROUBLESHOOTING.md) | 429 errors, reconnect, auth issues, debug logging |
|
|
300
301
|
| [Release Guide](docs/RELEASE_GUIDE.md) | Versioning, publishing, changelog |
|
|
301
302
|
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# DhanHQ v2 API docs vs dhanhq-client — gaps and fixes
|
|
2
|
+
|
|
3
|
+
Reference: [dhanhq.co/docs/v2](https://dhanhq.co/docs/v2/)
|
|
4
|
+
|
|
5
|
+
This document lists mismatches between the official DhanHQ v2 API documentation and the dhanhq-client gem, and suggested fixes.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Kill Switch — request format
|
|
10
|
+
|
|
11
|
+
**Doc:** [Trader's Control](https://dhanhq.co/docs/v2/traders-control/)
|
|
12
|
+
|
|
13
|
+
- **Manage Kill Switch:** *"You can pass header parameter as ACTIVATE or DEACTIVATE"* and the curl example uses a **query parameter**:
|
|
14
|
+
`POST https://api.dhan.co/v2/killswitch?killSwitchStatus=ACTIVATE`
|
|
15
|
+
**Request structure: No Body**
|
|
16
|
+
|
|
17
|
+
**Gem:** `Resources::KillSwitch#update(params)` sends a **POST body** with `kill_switch_status: "ACTIVATE"` or `"DEACTIVATE"`.
|
|
18
|
+
|
|
19
|
+
**Gap:** The API may expect `killSwitchStatus` as a **query parameter** (or header), not in the JSON body. That can explain `DH-905: Missing required fields` when calling activate/deactivate.
|
|
20
|
+
|
|
21
|
+
**Suggested fix:** In `Resources::KillSwitch#update(status)`, call the API with a query string, e.g. `post("?killSwitchStatus=#{status}")` (or equivalent), and do not send a body. If the live API accepts body and your integration works, this may be a doc inaccuracy; otherwise prefer matching the doc (query param).
|
|
22
|
+
|
|
23
|
+
**Fixed:** Resource now sends `POST /v2/killswitch?killSwitchStatus=ACTIVATE` (or DEACTIVATE) with no body. Model passes status string to resource.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 2. IP Setup — missing required parameters
|
|
28
|
+
|
|
29
|
+
**Doc:** [Authentication → Setup Static IP](https://dhanhq.co/docs/v2/authentication/#setup-static-ip)
|
|
30
|
+
|
|
31
|
+
- **Set IP:** Body must include:
|
|
32
|
+
- `dhanClientId` (required)
|
|
33
|
+
- `ip` (required)
|
|
34
|
+
- `ipFlag` (required): `"PRIMARY"` or `"SECONDARY"`
|
|
35
|
+
- **Modify IP:** Same body as Set IP.
|
|
36
|
+
|
|
37
|
+
**Gem:** `Resources::IPSetup#set(ip:)` and `#update(ip:)` send only `{ ip: ip }`.
|
|
38
|
+
|
|
39
|
+
**Gap:** `dhanClientId` and `ipFlag` are not sent. Set/Modify IP may fail or behave incorrectly for accounts that require them.
|
|
40
|
+
|
|
41
|
+
**Suggested fix:** Add `dhan_client_id` and `ip_flag` to the resource (e.g. `set(ip:, ip_flag: "PRIMARY", dhan_client_id: nil)`), defaulting `dhan_client_id` from `DhanHQ.configuration.client_id` when not provided.
|
|
42
|
+
|
|
43
|
+
**Fixed:** `IPSetup#set` and `#update` now accept `ip:, ip_flag: "PRIMARY"` (or `"SECONDARY"`), and `dhan_client_id:` (defaults from config when nil).
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 3. Alert Orders (Conditional Trigger) — condition fields
|
|
48
|
+
|
|
49
|
+
**Doc:** [Conditional Trigger](https://dhanhq.co/docs/v2/conditional-trigger/)
|
|
50
|
+
|
|
51
|
+
For **Place** and **Modify**:
|
|
52
|
+
|
|
53
|
+
- `condition.exchangeSegment` — **required**
|
|
54
|
+
- `condition.expDate` — **required** (date, default 1 year)
|
|
55
|
+
- `condition.frequency` — **required** (e.g. `"ONCE"`)
|
|
56
|
+
- `condition.timeFrame` — required for technical conditions (e.g. `"DAY"`, `"ONE_MIN"`)
|
|
57
|
+
|
|
58
|
+
**Gem:** `Contracts::AlertOrderContract` and `Models::AlertOrder`:
|
|
59
|
+
|
|
60
|
+
- Condition has: `security_id`, `comparison_type`, `operator`, and optional `indicator_name`, `time_frame`, `comparing_value`, `comparing_indicator_name`.
|
|
61
|
+
- **Missing from contract/model:** `exchange_segment`, `exp_date`, `frequency` in the condition hash.
|
|
62
|
+
|
|
63
|
+
**Gap:** Creating or modifying alert orders that satisfy the API may require these fields; the gem does not expose or validate them.
|
|
64
|
+
|
|
65
|
+
**Suggested fix:** Add `exchange_segment`, `exp_date`, and `frequency` to the alert order condition in the contract and model (and ensure they are sent in the API payload in the expected format, e.g. camelCase).
|
|
66
|
+
|
|
67
|
+
**Fixed:** `AlertOrderContract` condition now requires `exchange_segment`, `exp_date`, `frequency`; rule added so `time_frame` is required when `comparison_type` starts with `TECHNICAL`. Test script and specs updated.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 4. EDIS — doc typo only
|
|
72
|
+
|
|
73
|
+
**Doc:** [EDIS](https://dhanhq.co/docs/v2/edis/) table lists `POST /edis/from` for the form endpoint.
|
|
74
|
+
|
|
75
|
+
**Gem:** Uses `POST /edis/form`.
|
|
76
|
+
|
|
77
|
+
**Conclusion:** The doc table has a typo ("from" vs "form"). The doc’s curl and request structure use `/edis/form`. No change needed in the gem.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 5. Forever Order list — doc inconsistency
|
|
82
|
+
|
|
83
|
+
**Doc:** [Forever Order](https://dhanhq.co/docs/v2/forever/)
|
|
84
|
+
|
|
85
|
+
- Table: `GET /forever/orders` — retrieve all forever orders.
|
|
86
|
+
- Section "All Forever Order Detail": curl shows `GET /forever/all`.
|
|
87
|
+
|
|
88
|
+
**Gem:** Uses `GET /forever/orders` (e.g. `ForeverOrders#all` → `get("/orders")` with `HTTP_PATH = "/v2/forever"`).
|
|
89
|
+
|
|
90
|
+
**Conclusion:** Doc is inconsistent. The gem matches the table. If the API actually uses `/forever/all`, the resource path would need to change; otherwise no change.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 6. P&L Exit — dhanClientId
|
|
95
|
+
|
|
96
|
+
**Doc:** [Trader's Control → P&L Based Exit](https://dhanhq.co/docs/v2/traders-control/) does not list `dhanClientId` in the request body for Configure.
|
|
97
|
+
|
|
98
|
+
**Gem:** Was updated to send `dhanClientId` from config when present, to fix `DH-905: dhanClientId is required`.
|
|
99
|
+
|
|
100
|
+
**Conclusion:** Either the doc omits this field or the API was updated to require it. The gem’s behaviour is aligned with the API response you saw; no further change unless the doc is updated.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Summary table
|
|
105
|
+
|
|
106
|
+
| Area | Doc reference | Gap / note | Status |
|
|
107
|
+
|-----------------|----------------------|----------------------------------------------------------------------------|----------|
|
|
108
|
+
| Kill Switch | traders-control | Manage API expects query param `killSwitchStatus`, not body | **Fixed** |
|
|
109
|
+
| IP Setup | authentication | Set/Modify IP required `dhanClientId`, `ipFlag` | **Fixed** |
|
|
110
|
+
| Alert Orders | conditional-trigger | Condition required `exchangeSegment`, `expDate`, `frequency` | **Fixed** |
|
|
111
|
+
| EDIS | edis | Doc typo `/edis/from`; gem correctly uses `/edis/form` | None |
|
|
112
|
+
| Forever list | forever | Doc inconsistency `/forever/orders` vs `/forever/all`; gem uses `/orders` | Low |
|
|
113
|
+
| P&L Exit | traders-control | Gem sends `dhanClientId`; doc does not mention it | None |
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Endpoints covered by the gem (no gaps found)
|
|
118
|
+
|
|
119
|
+
- **Orders:** Place, modify, cancel, slicing, order book, get by id, get by correlation id — paths and behaviour match the [Orders](https://dhanhq.co/docs/v2/orders/) doc.
|
|
120
|
+
- **Trades:** Trade book, trades by order id — match doc.
|
|
121
|
+
- **Super Order:** Create, modify, cancel, list — match [Super Order](https://dhanhq.co/docs/v2/super-order/) doc.
|
|
122
|
+
- **Forever Order:** Create, modify, cancel, list — paths match [Forever Order](https://dhanhq.co/docs/v2/forever/) table (list path as above).
|
|
123
|
+
- **Profile:** GET /v2/profile — match [Authentication → User Profile](https://dhanhq.co/docs/v2/authentication/#user-profile).
|
|
124
|
+
- **Trader’s Control:** Kill Switch status (GET), manage via query param (see above). P&L Exit configure/stop/status — match doc.
|
|
125
|
+
- **EDIS:** tpin, form, bulkform, inquire — paths and params match [EDIS](https://dhanhq.co/docs/v2/edis/) (form URL as above).
|
|
126
|
+
- **Postback:** Incoming webhook payload; gem’s `Postback.parse` is for parsing, not an outgoing API — no endpoint gap.
|
|
127
|
+
|
|
128
|
+
The Kill Switch query-param change, IP Setup parameter additions, and Alert Order condition fields have been implemented in the gem. See CHANGELOG (Unreleased), GUIDE.md, docs/API_VERIFICATION.md, and docs/TESTING_GUIDE.md for updated documentation.
|
data/docs/API_VERIFICATION.md
CHANGED
|
@@ -28,7 +28,7 @@ This document records how the gem’s implementation aligns with the official Dh
|
|
|
28
28
|
|
|
29
29
|
## Alert Orders
|
|
30
30
|
|
|
31
|
-
**Doc ref:**
|
|
31
|
+
**Doc ref:** [dhanhq.co/docs/v2/conditional-trigger](https://dhanhq.co/docs/v2/conditional-trigger/).
|
|
32
32
|
|
|
33
33
|
| Doc path | Gem resource | Path used |
|
|
34
34
|
|---------------------------|---------------------------|------------------|
|
|
@@ -36,27 +36,26 @@ This document records how the gem’s implementation aligns with the official Dh
|
|
|
36
36
|
| GET/POST `/alerts/orders` | `#all`, `#create` | BaseResource |
|
|
37
37
|
| GET/PUT/DELETE `/alerts/orders/{trigger-id}` | `#find`, `#update`, `#delete` | `/{id}` |
|
|
38
38
|
|
|
39
|
-
Model: `Models::AlertOrder
|
|
39
|
+
Model: `Models::AlertOrder`. Condition must include `exchange_segment`, `exp_date`, `frequency`; `time_frame` required when `comparison_type` starts with `TECHNICAL`. Validated by `AlertOrderContract`.
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
43
43
|
## IP Setup
|
|
44
44
|
|
|
45
|
-
**Doc ref:**
|
|
45
|
+
**Doc ref:** [dhanhq.co/docs/v2/authentication/#setup-static-ip](https://dhanhq.co/docs/v2/authentication/#setup-static-ip).
|
|
46
46
|
|
|
47
|
-
| Doc path | Gem method | Path
|
|
48
|
-
|
|
49
|
-
| GET /ip/getIP | `#current` | `get("/getIP")`
|
|
50
|
-
| POST /ip/setIP | `#set(ip:)`
|
|
51
|
-
| PUT /ip/modifyIP| `#update(ip:)` | `put("/modifyIP", params: { ip:
|
|
47
|
+
| Doc path | Gem method | Path / body |
|
|
48
|
+
|-----------------|----------------|-------------|
|
|
49
|
+
| GET /ip/getIP | `#current` | `get("/getIP")` |
|
|
50
|
+
| POST /ip/setIP | `#set(ip:, ip_flag: "PRIMARY", dhan_client_id: nil)` | `post("/setIP", params: { ip:, ip_flag:, dhan_client_id: })`; `dhan_client_id` defaults from config |
|
|
51
|
+
| PUT /ip/modifyIP| `#update(ip:, ip_flag: "PRIMARY", dhan_client_id: nil)` | `put("/modifyIP", params: { ip:, ip_flag:, dhan_client_id: })` |
|
|
52
52
|
|
|
53
53
|
---
|
|
54
54
|
|
|
55
55
|
## Trader Control / Kill Switch
|
|
56
56
|
|
|
57
|
-
- **
|
|
58
|
-
- **
|
|
59
|
-
Not found on the public docs pages checked; kept for compatibility with design that referenced trader-control.
|
|
57
|
+
- **Kill Switch:** `Resources::KillSwitch`, `Models::KillSwitch` – path `/v2/killswitch`. Manage (activate/deactivate) uses **query parameter** per [traders-control](https://dhanhq.co/docs/v2/traders-control/): `POST /v2/killswitch?killSwitchStatus=ACTIVATE` (or `DEACTIVATE`) with no body. `#status` is GET.
|
|
58
|
+
- **Trader Control:** `Resources::TraderControl` – path `/trader-control`; `#status`, `#enable`, `#disable`. Not found on the public docs; kept for compatibility.
|
|
60
59
|
|
|
61
60
|
---
|
|
62
61
|
|