DhanHQ 2.4.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 +103 -7
- data/GUIDE.md +57 -39
- data/README.md +198 -755
- data/docs/API_DOCS_GAPS.md +128 -0
- data/docs/API_VERIFICATION.md +10 -11
- data/{README1.md → docs/ARCHIVE_README.md} +16 -16
- data/docs/AUTHENTICATION.md +72 -10
- data/docs/CONFIGURATION.md +109 -0
- 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/SUPER_ORDERS.md +284 -0
- data/docs/{technical_analysis.md → TECHNICAL_ANALYSIS.md} +3 -3
- data/docs/TESTING_GUIDE.md +84 -82
- data/docs/TROUBLESHOOTING.md +117 -0
- data/docs/{websocket_integration.md → WEBSOCKET_INTEGRATION.md} +19 -19
- data/docs/WEBSOCKET_PROTOCOL.md +154 -0
- 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 +29 -11
- data/lib/DhanHQ/models/concerns/api_response_handler.rb +46 -0
- data/lib/DhanHQ/models/edis.rb +101 -0
- 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 +23 -11
- data/lib/DhanHQ/models/margin.rb +51 -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 +122 -0
- data/lib/DhanHQ/models/position.rb +23 -1
- data/lib/DhanHQ/models/postback.rb +114 -0
- 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 +17 -7
- data/lib/DhanHQ/resources/margin_calculator.rb +9 -0
- data/lib/DhanHQ/resources/orders.rb +41 -41
- data/lib/DhanHQ/resources/pnl_exit.rb +37 -0
- data/lib/DhanHQ/resources/positions.rb +8 -0
- 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 +29 -24
- 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,4 +1,100 @@
|
|
|
1
|
-
## [
|
|
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
|
+
|
|
65
|
+
## [2.5.0] - 2026-02-21
|
|
66
|
+
|
|
67
|
+
### Added
|
|
68
|
+
|
|
69
|
+
#### New Endpoints — Full Dhan API v2 Parity
|
|
70
|
+
- **Exit All Positions**: `DhanHQ::Models::Position.exit_all!` — emergency closure of all positions and cancellation of all open orders via `DELETE /v2/positions`. Resource method: `DhanHQ::Resources::Positions#exit_all`.
|
|
71
|
+
- **Kill Switch Status**: `DhanHQ::Models::KillSwitch.status` — query current kill switch state via `GET /v2/killswitch`. Resource method: `DhanHQ::Resources::KillSwitch#status`.
|
|
72
|
+
- **P&L Based Exit**: New `DhanHQ::Models::PnlExit` model and `DhanHQ::Resources::PnlExit` resource for automatic profit/loss-based position exit:
|
|
73
|
+
- `PnlExit.configure(profit_value:, loss_value:, product_type:, enable_kill_switch:)` — `POST /v2/pnlExit`
|
|
74
|
+
- `PnlExit.stop` — `DELETE /v2/pnlExit`
|
|
75
|
+
- `PnlExit.status` — `GET /v2/pnlExit`
|
|
76
|
+
- **Multi-Order Margin Calculator**: `DhanHQ::Models::Margin.calculate_multi` — batch margin calculation with hedge benefit across multiple instruments via `POST /v2/margincalculator/multi`. Resource method: `DhanHQ::Resources::MarginCalculator#calculate_multi`.
|
|
77
|
+
- **EDIS Model**: New `DhanHQ::Models::Edis` wrapping existing `DhanHQ::Resources::Edis` with ORM-style class methods:
|
|
78
|
+
- `Edis.generate_tpin`, `Edis.generate_form`, `Edis.generate_bulk_form`, `Edis.inquire`
|
|
79
|
+
- **Postback Payload Parser**: New `DhanHQ::Models::Postback` utility model for parsing Dhan webhook payloads:
|
|
80
|
+
- `Postback.parse(json_or_hash)` — accepts JSON string or Hash
|
|
81
|
+
- Status predicates: `traded?`, `rejected?`, `pending?`, `cancelled?`
|
|
82
|
+
- **AlertOrder Modify**: Explicit `DhanHQ::Models::AlertOrder.modify(alert_id, params)` class method for updating conditional triggers with better discoverability.
|
|
83
|
+
|
|
84
|
+
#### Tests
|
|
85
|
+
- **28 new specs** across 7 files (442 total, 0 failures):
|
|
86
|
+
- `spec/dhan_hq/models/pnl_exit_spec.rb` — configure, stop, status, defaults, nil handling
|
|
87
|
+
- `spec/dhan_hq/models/edis_spec.rb` — generate_tpin, generate_form, bulk_form, inquire
|
|
88
|
+
- `spec/dhan_hq/models/postback_spec.rb` — JSON/Hash parsing, snake_case support, status predicates
|
|
89
|
+
- Updated: `kill_switch_spec.rb`, `positions_spec.rb`, `margin_spec.rb`, `alert_order_spec.rb`
|
|
90
|
+
|
|
91
|
+
### Changed
|
|
92
|
+
- **README.md**: Updated Key Features to reflect full API v2 parity including P&L Exit, Postback parser, and EDIS model.
|
|
93
|
+
- **Bundler**: Updated `BUNDLED WITH` to latest version, eliminating platform constant re-definition warnings.
|
|
94
|
+
|
|
95
|
+
### Notes
|
|
96
|
+
- **Backward Compatible**: All changes are additive — no existing APIs or method signatures changed.
|
|
97
|
+
- **Full API v2 Parity**: The gem now covers every endpoint documented at [dhanhq.co/docs/v2](https://dhanhq.co/docs/v2/).
|
|
2
98
|
|
|
3
99
|
---
|
|
4
100
|
|
|
@@ -23,7 +119,7 @@
|
|
|
23
119
|
|
|
24
120
|
### Added
|
|
25
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`.
|
|
26
|
-
- **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.
|
|
27
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.
|
|
28
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.
|
|
29
125
|
|
|
@@ -60,9 +156,9 @@
|
|
|
60
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.
|
|
61
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.
|
|
62
158
|
- **docs/TESTING_GUIDE.md**: Optional config comment for RenewToken and pointer to AUTHENTICATION.md (API key/Partner in app).
|
|
63
|
-
- **docs/
|
|
64
|
-
- **docs/
|
|
65
|
-
- **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.
|
|
66
162
|
|
|
67
163
|
### CI / Release
|
|
68
164
|
|
|
@@ -112,8 +208,8 @@
|
|
|
112
208
|
- **GUIDE.md**: Short “Dynamic access token” note and link to docs/AUTHENTICATION.md.
|
|
113
209
|
- **docs/AUTHENTICATION.md**: New doc for static vs dynamic token, retry-on-401, and auth-related errors.
|
|
114
210
|
- **docs/TESTING_GUIDE.md**: Optional access_token_provider / on_token_expired in config examples.
|
|
115
|
-
- **docs/
|
|
116
|
-
- **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.
|
|
117
213
|
|
|
118
214
|
### Backward compatibility
|
|
119
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
|
|