DhanHQ 2.6.3 → 2.8.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/AGENTS.md +23 -0
- data/ARCHITECTURE.md +2 -0
- data/CHANGELOG.md +58 -0
- data/README.md +177 -16
- data/docs/BEST_WAY_TO_USE_DHAN_API_IN_RUBY.md +36 -0
- data/docs/BUILD_A_TRADING_BOT_WITH_RUBY_AND_DHAN.md +111 -0
- data/docs/CONFIGURATION.md +1 -1
- data/docs/DHAN_API_RUBY_EXAMPLES.md +71 -0
- data/docs/DHAN_RUBY_QA.md +27 -0
- data/docs/DHAN_WEBSOCKET_RUBY_GUIDE.md +38 -0
- data/docs/HOW_TO_USE_DHAN_API_WITH_RUBY.md +131 -0
- data/docs/LIVE_ORDER_UPDATES.md +1 -1
- data/docs/RAILS_INTEGRATION.md +1 -1
- data/docs/TESTING_GUIDE.md +2 -2
- data/docs/TROUBLESHOOTING.md +1 -1
- data/docs/WEBSOCKET_INTEGRATION.md +2 -2
- data/docs/architecture-overview.svg +54 -0
- data/lib/DhanHQ/concerns/order_audit.rb +69 -0
- data/lib/DhanHQ/errors.rb +2 -0
- data/lib/DhanHQ/resources/alert_orders.rb +22 -0
- data/lib/DhanHQ/resources/forever_orders.rb +10 -0
- data/lib/DhanHQ/resources/orders.rb +12 -0
- data/lib/DhanHQ/resources/pnl_exit.rb +8 -0
- data/lib/DhanHQ/resources/super_orders.rb +16 -3
- data/lib/DhanHQ/utils/network_inspector.rb +71 -0
- data/lib/DhanHQ/version.rb +1 -1
- metadata +17 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6d2ca9bd3c9c4f61504d06e8b2736baf9ded579d04bb21523a9e0c5fe9a74298
|
|
4
|
+
data.tar.gz: a981472b44efa9c86c1daa83461c27985664a0682022d3aa4b3e925a950788aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 03b2f01541f005e6d9ebd4d706023cf553b17bb80327f480f350e5d465a582006b0fc199cc541a804631a71a034b8cd454c8c715e962b95794df665e75eb0a63
|
|
7
|
+
data.tar.gz: e7320d2ae5e332238cf0e11bcd0f29ecd368772242019567f5dcb525e4b8baa9e71c5191b51b25724cd090ac82fb113524bb0578480f1bf71b82834bc74cda6d
|
data/AGENTS.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Cursor Cloud specific instructions
|
|
4
|
+
|
|
5
|
+
This is a pure-Ruby gem (no Rails, no running servers). Development commands are documented in `CLAUDE.md`.
|
|
6
|
+
|
|
7
|
+
### Quick reference
|
|
8
|
+
|
|
9
|
+
| Task | Command |
|
|
10
|
+
|------|---------|
|
|
11
|
+
| Install deps | `bundle install` |
|
|
12
|
+
| Tests | `bundle exec rspec` |
|
|
13
|
+
| Lint | `bundle exec rubocop` |
|
|
14
|
+
| Both | `bundle exec rake` |
|
|
15
|
+
| Single spec | `bundle exec rspec spec/path/to_spec.rb` |
|
|
16
|
+
|
|
17
|
+
### Non-obvious caveats
|
|
18
|
+
|
|
19
|
+
- **Bundler 4.x required**: The lockfile was bundled with Bundler 4.0.6. Install with `sudo gem install bundler -v 4.0.6` if missing.
|
|
20
|
+
- **`libyaml-dev` must be installed**: The `psych` gem (transitive dep) needs `yaml.h`. Without `libyaml-dev`, `bundle install` fails on native extension build.
|
|
21
|
+
- **`vendor/bundle` path**: Gems are installed to `./vendor/bundle` via `.bundle/config` to avoid needing root write access to `/var/lib/gems`.
|
|
22
|
+
- **No real API calls in tests**: All HTTP interactions are stubbed with WebMock/VCR. No `DHAN_CLIENT_ID` or `DHAN_ACCESS_TOKEN` secrets are needed to run the test suite.
|
|
23
|
+
- **No services to start**: This is a library gem. There is no web server, database, or background worker. Testing is purely `bundle exec rspec` / `bundle exec rubocop`.
|
data/ARCHITECTURE.md
CHANGED
|
@@ -48,6 +48,8 @@ This document describes the architecture of the DhanHQ v2 API client gem: layers
|
|
|
48
48
|
| `resources/` | REST wrappers | One class per API surface (Orders, Positions, MarketFeed, OptionChain, …). Set `HTTP_PATH`, `API_TYPE`; implement get/post/put/delete via BaseAPI. |
|
|
49
49
|
| `contracts/` | Request/response validation | Dry::Validation contracts (PlaceOrderContract, ModifyOrderContract, OptionChainContract, etc.). BaseContract provides shared macros (e.g. lot_size, tick_size). |
|
|
50
50
|
| `auth/` | Token lifecycle | Token generator/renewal/manager for dynamic tokens. |
|
|
51
|
+
| `concerns/` | Shared behavior | Modules included across layers (e.g. `OrderAudit` for live trading guard + audit logging, included in all order resources). |
|
|
52
|
+
| `utils/` | Utilities | Cross-cutting utilities not tied to a single layer (e.g. `NetworkInspector` for IP/hostname/env lookup used by order audit logging). |
|
|
51
53
|
| `ws/` | WebSocket | Connection, packets, decoder, market depth, orders client — isolated from REST. |
|
|
52
54
|
|
|
53
55
|
---
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,61 @@
|
|
|
1
|
+
## [2.8.0] - 2026-03-21
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
|
|
5
|
+
- **Complete SDK Documentation Overhaul**: Added high-level guides and structured learning paths for Ruby developers:
|
|
6
|
+
- `BEST_WAY_TO_USE_DHAN_API_IN_RUBY.md`: Strategic advice for Ruby-centric integration.
|
|
7
|
+
- `BUILD_A_TRADING_BOT_WITH_RUBY_AND_DHAN.md`: Step-by-step tutorial for algo trading.
|
|
8
|
+
- `HOW_TO_USE_DHAN_API_WITH_RUBY.md`: Foundational guide for REST and WebSocket.
|
|
9
|
+
- `DHAN_API_RUBY_EXAMPLES.md`: Curated collection of common API patterns.
|
|
10
|
+
- `DHAN_WEBSOCKET_RUBY_GUIDE.md`: Deep dive into real-time market data and order updates.
|
|
11
|
+
- `DHAN_RUBY_QA.md`: Troubleshooting and frequently asked questions.
|
|
12
|
+
- **Production-Ready Examples**:
|
|
13
|
+
- `examples/basic_trading_bot.rb`: Skeleton for a strategy-based bot.
|
|
14
|
+
- `examples/options_watchlist.rb`: Script for monitoring specific option strikes.
|
|
15
|
+
- `examples/portfolio_monitor.rb`: Live tracker for PnL and position status.
|
|
16
|
+
- **Architectural Visualization**: New `docs/architecture-overview.svg` illustrating the SDK's layered design (Models, Resources, Contracts, WebSocket).
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- **SDK Positioning**: Updated `README.md` and `DhanHQ.gemspec` to reflect the SDK's status as a "production-grade Ruby SDK for Dhan API v2" with an emphasis on algo trading, portfolio monitoring, and resilient streaming.
|
|
21
|
+
- **Documentation Refinement**: Improved clarity and navigation in `CONFIGURATION.md`, `LIVE_ORDER_UPDATES.md`, `RAILS_INTEGRATION.md`, `TESTING_GUIDE.md`, `TROUBLESHOOTING.md`, and `WEBSOCKET_INTEGRATION.md`.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## [2.7.0] - 2026-03-17
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- **Order audit logging across all order types**: Every order submission (regular, super, forever/GTT, and alert orders) now emits a WARN-level structured JSON log line capturing: event type, public IPv4/IPv6, hostname, runtime environment, `security_id`, `correlation_id`, and UTC timestamp. Log output example:
|
|
30
|
+
```json
|
|
31
|
+
{"event":"DHAN_ORDER_ATTEMPT","hostname":"DESKTOP-SHUBHAM","env":"production","ipv4":"122.171.22.40","ipv6":"2401:4900:...","security_id":"11536","correlation_id":"SCALPER_7af1","timestamp":"2026-03-17T06:45:22Z"}
|
|
32
|
+
```
|
|
33
|
+
Events logged: `DHAN_ORDER_ATTEMPT`, `DHAN_ORDER_MODIFY_ATTEMPT`, `DHAN_ORDER_SLICING_ATTEMPT`, `DHAN_SUPER_ORDER_ATTEMPT`, `DHAN_SUPER_ORDER_MODIFY_ATTEMPT`, `DHAN_SUPER_ORDER_CANCEL_ATTEMPT`, `DHAN_FOREVER_ORDER_ATTEMPT`, `DHAN_FOREVER_ORDER_MODIFY_ATTEMPT`, `DHAN_FOREVER_ORDER_CANCEL_ATTEMPT`, `DHAN_ALERT_ORDER_ATTEMPT`, `DHAN_ALERT_ORDER_MODIFY_ATTEMPT`, `DHAN_ALERT_ORDER_DELETE_ATTEMPT`, `DHAN_PNL_EXIT_CONFIGURE_ATTEMPT`, `DHAN_PNL_EXIT_STOP_ATTEMPT`.
|
|
34
|
+
- **`DhanHQ::Concerns::OrderAudit`**: Shared concern providing `log_order_context` and `ensure_live_trading!` — included in `Resources::Orders`, `Resources::SuperOrders`, `Resources::ForeverOrders`, `Resources::AlertOrders`, and `Resources::PnlExit`.
|
|
35
|
+
- **`DhanHQ::Utils::NetworkInspector`**: New utility class that resolves the machine's public IPv4 (via api.ipify.org), IPv6 (via api64.ipify.org), hostname (`Socket.gethostname`), and runtime environment (`RAILS_ENV` / `RACK_ENV` / `APP_ENV`). IP lookups are memoized for the process lifetime; call `NetworkInspector.reset_cache!` to refresh.
|
|
36
|
+
- **Live trading guard**: All mutating order/trader-control calls require `ENV["LIVE_TRADING"]="true"`. Guarded methods:
|
|
37
|
+
- `Resources::Orders#create`, `#update`, `#slicing`, `#cancel`
|
|
38
|
+
- `Resources::SuperOrders#create`, `#update`, `#cancel`
|
|
39
|
+
- `Resources::ForeverOrders#create`, `#update`, `#cancel`
|
|
40
|
+
- `Resources::AlertOrders#create`, `#update`, `#delete`
|
|
41
|
+
- `Resources::PnlExit#configure`, `#stop`
|
|
42
|
+
- **`DhanHQ::LiveTradingDisabledError`**: New error class raised when the live trading guard fires.
|
|
43
|
+
- **Correlation ID prefix convention**: Recommended per-app correlation ID prefixes for instant source identification in the Dhan orderbook (e.g. `SCALPER_7af1`, `TRADER_3bc9`). See README.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- **`Resources::Orders`**: `#create`, `#update`, `#slicing`, `#cancel` log order context and enforce the live trading guard.
|
|
48
|
+
- **`Resources::SuperOrders`**: `#create`, `#update`, `#cancel` log order context and enforce the live trading guard.
|
|
49
|
+
- **`Resources::ForeverOrders`**: `#create`, `#update`, `#cancel` log order context and enforce the live trading guard.
|
|
50
|
+
- **`Resources::AlertOrders`**: `#create`, `#update`, `#delete` log order context and enforce the live trading guard; `#delete` added.
|
|
51
|
+
- **`Resources::PnlExit`**: `#configure` and `#stop` use `OrderAudit` (guard + audit log).
|
|
52
|
+
|
|
53
|
+
### Breaking
|
|
54
|
+
|
|
55
|
+
- **`ENV["LIVE_TRADING"]` required for all order/trader-control mutations**: Any call that creates, updates, cancels, or deletes orders (or configures/stops PnL exit) now raises `LiveTradingDisabledError` unless `ENV["LIVE_TRADING"]="true"`. Affects `Resources::Orders`, `Resources::SuperOrders`, `Resources::ForeverOrders`, `Resources::AlertOrders`, `Resources::PnlExit`, and the corresponding model wrappers. Set `LIVE_TRADING=true` in production and `LIVE_TRADING=false` (or omit) in development/test.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
1
59
|
## [2.6.3] - 2026-03-14
|
|
2
60
|
|
|
3
61
|
### Added
|
data/README.md
CHANGED
|
@@ -1,13 +1,31 @@
|
|
|
1
|
-
# DhanHQ — Ruby
|
|
1
|
+
# DhanHQ — The Ruby SDK for Dhan API v2
|
|
2
2
|
|
|
3
3
|
[](https://rubygems.org/gems/DhanHQ)
|
|
4
4
|
[](https://github.com/shubhamtaywade82/dhanhq-client/actions/workflows/main.yml)
|
|
5
5
|
[](https://www.ruby-lang.org)
|
|
6
6
|
[](LICENSE.txt)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Build trading systems in Ruby without fighting raw HTTP, fragile auth flows, or unreliable market streams.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
DhanHQ is a production-grade Ruby SDK for the [Dhan trading API](https://dhanhq.co/docs/v2/), designed for:
|
|
11
|
+
|
|
12
|
+
- trading bots
|
|
13
|
+
- real-time market data streaming
|
|
14
|
+
- portfolio and order management
|
|
15
|
+
- Rails or standalone trading systems
|
|
16
|
+
|
|
17
|
+
If you're looking for a Ruby SDK for Dhan API, this is built to be the default choice.
|
|
18
|
+
|
|
19
|
+
Unlike thin wrappers, DhanHQ gives you:
|
|
20
|
+
|
|
21
|
+
- typed models for orders, positions, holdings, and more
|
|
22
|
+
- WebSocket clients with auto-reconnect and backoff
|
|
23
|
+
- token lifecycle management with retry-on-401
|
|
24
|
+
- safety rails for live trading
|
|
25
|
+
|
|
26
|
+
This is closer to trading infrastructure than a simple API client.
|
|
27
|
+
|
|
28
|
+
## Install and Run in 60 Seconds
|
|
11
29
|
|
|
12
30
|
```ruby
|
|
13
31
|
# Gemfile
|
|
@@ -22,25 +40,69 @@ DhanHQ.configure do |c|
|
|
|
22
40
|
c.access_token = ENV["DHAN_ACCESS_TOKEN"]
|
|
23
41
|
end
|
|
24
42
|
|
|
25
|
-
# You're live
|
|
43
|
+
# You're live — no manual HTTP, no JSON parsing
|
|
26
44
|
positions = DhanHQ::Models::Position.all
|
|
27
|
-
holdings = DhanHQ::Models::Holding.all
|
|
28
45
|
```
|
|
29
46
|
|
|
30
47
|
---
|
|
31
48
|
|
|
32
|
-
##
|
|
49
|
+
## Who This Is For
|
|
50
|
+
|
|
51
|
+
- Ruby developers building trading bots
|
|
52
|
+
- Rails apps integrating the Dhan API
|
|
53
|
+
- Algo trading systems that need clean abstractions over raw HTTP
|
|
54
|
+
- Long-running processes that rely on WebSocket market data
|
|
55
|
+
|
|
56
|
+
## Who This Is Not For
|
|
57
|
+
|
|
58
|
+
- One-off scripts where raw HTTP is enough
|
|
59
|
+
- Non-Ruby stacks
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Start Here (Pick Your Use Case)
|
|
64
|
+
|
|
65
|
+
Pick the path that matches what you want to build:
|
|
66
|
+
|
|
67
|
+
- **Get live prices fast** → [Market Feed WebSocket](#market-feed-ticker--quote--full)
|
|
68
|
+
- **Place orders safely** → [Order Safety](#order-safety)
|
|
69
|
+
- **Build a trading strategy** → [WebSockets](#websockets)
|
|
70
|
+
- **Build a trading bot** → [examples/basic_trading_bot.rb](examples/basic_trading_bot.rb)
|
|
71
|
+
- **Use with Rails** → [docs/RAILS_INTEGRATION.md](docs/RAILS_INTEGRATION.md)
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Trust Signals
|
|
76
|
+
|
|
77
|
+
- **CI on supported Rubies** — GitHub Actions runs RSpec on Ruby 3.2.0 and 3.3.4, plus RuboCop on every push and pull request
|
|
78
|
+
- **Typed domain models** — Orders, Positions, Holdings, Funds, MarketFeed, OptionChain, Super Orders, and more expose a Ruby-first API instead of raw hashes
|
|
79
|
+
- **No real API calls in the default test suite** — WebMock blocks outbound HTTP and VCR covers cassette-backed integration paths
|
|
80
|
+
- **Auth lifecycle support** — static tokens, dynamic token providers, 401 retry with refresh hooks, and token sanitization in logs
|
|
81
|
+
- **WebSocket resilience** — reconnect, backoff, 429 cool-off, local connection cleanup, and dedicated market/order stream clients
|
|
82
|
+
- **Live trading guardrails** — order placement is blocked unless `LIVE_TRADING=true`, and order attempts emit structured audit logs
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Why Not a Thin Wrapper?
|
|
87
|
+
|
|
88
|
+
Most API clients give you HTTP access. DhanHQ gives you a working Ruby system.
|
|
89
|
+
|
|
90
|
+
| Instead of | You get |
|
|
91
|
+
| ---------- | -------- |
|
|
92
|
+
| JSON parsing and manual field mapping | Typed models |
|
|
93
|
+
| Manual auth refresh | Built-in token lifecycle |
|
|
94
|
+
| Fragile WebSocket code | Auto-reconnect, backoff, and 429 handling |
|
|
95
|
+
| Risky order scripts | Live trading guardrails and audit logs |
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Architecture At A Glance
|
|
33
100
|
|
|
34
|
-
|
|
101
|
+

|
|
35
102
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
| Typed models with validations | Hash soup and runtime surprises |
|
|
40
|
-
| Auto token refresh + retry-on-401 | Silent auth failures at 3 AM |
|
|
41
|
-
| WebSocket reconnection with backoff | Dropped connections during volatile moves |
|
|
42
|
-
| 429 rate-limit cool-off | Getting banned by the exchange |
|
|
43
|
-
| Thread-safe, secure logging | Leaked tokens in production logs |
|
|
103
|
+
Models own the Ruby API. Resources own HTTP calls. Contracts validate inputs. The transport layer handles auth, retries, rate limiting, and error mapping. WebSockets are a separate subsystem that shares configuration but not the REST stack.
|
|
104
|
+
|
|
105
|
+
For the full dependency flow and extension pattern, see [ARCHITECTURE.md](ARCHITECTURE.md).
|
|
44
106
|
|
|
45
107
|
---
|
|
46
108
|
|
|
@@ -53,6 +115,8 @@ You could wire up Faraday and parse JSON yourself. Here's why you shouldn't:
|
|
|
53
115
|
- **Secure logging** — automatic token sanitization in all log output
|
|
54
116
|
- **Super Orders** — entry + stop-loss + target + trailing jump in one request
|
|
55
117
|
- **Instrument convenience methods** — `.ltp`, `.ohlc`, `.option_chain` directly on instruments
|
|
118
|
+
- **Order audit logging** — every order attempt logs machine, IP, environment, and correlation ID as structured JSON
|
|
119
|
+
- **Live trading guard** — prevents accidental order placement unless `ENV["LIVE_TRADING"]="true"`
|
|
56
120
|
- **Full REST coverage** — Orders, Trades, Forever Orders, Super Orders, Positions, Holdings, Funds, HistoricalData, OptionChain, MarketFeed, EDIS, Kill Switch, P&L Exit, Alert Orders, Margin Calculator
|
|
57
121
|
- **P&L Based Exit** — automatic position exit on profit/loss thresholds
|
|
58
122
|
- **Postback parser** — parse Dhan webhook payloads with `Postback.parse` and status predicates
|
|
@@ -60,6 +124,18 @@ You could wire up Faraday and parse JSON yourself. Here's why you shouldn't:
|
|
|
60
124
|
|
|
61
125
|
---
|
|
62
126
|
|
|
127
|
+
## Reliability & Safety
|
|
128
|
+
|
|
129
|
+
- retry-on-401 with token refresh
|
|
130
|
+
- WebSocket auto-reconnect and backoff
|
|
131
|
+
- 429 rate-limit protection
|
|
132
|
+
- live trading guard via `LIVE_TRADING=true`
|
|
133
|
+
- structured order audit logs
|
|
134
|
+
|
|
135
|
+
See [ARCHITECTURE.md](ARCHITECTURE.md), [docs/TESTING_GUIDE.md](docs/TESTING_GUIDE.md), and [docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) for the deeper implementation details.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
63
139
|
## Installation
|
|
64
140
|
|
|
65
141
|
```ruby
|
|
@@ -120,6 +196,57 @@ When the API returns 401, the client retries **once** with a fresh token from yo
|
|
|
120
196
|
|
|
121
197
|
---
|
|
122
198
|
|
|
199
|
+
## Order Safety
|
|
200
|
+
|
|
201
|
+
### Live Trading Guard
|
|
202
|
+
|
|
203
|
+
Order placement (`create`, `slicing`) is blocked unless you explicitly enable it:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# Production (Render, VPS, etc.)
|
|
207
|
+
LIVE_TRADING=true
|
|
208
|
+
|
|
209
|
+
# Development / Test (default — orders are blocked)
|
|
210
|
+
LIVE_TRADING=false # or simply omit
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Attempting to place an order without `LIVE_TRADING=true` raises `DhanHQ::LiveTradingDisabledError`.
|
|
214
|
+
|
|
215
|
+
### Order Audit Logging
|
|
216
|
+
|
|
217
|
+
Every order attempt (place, modify, slice) automatically logs a structured JSON line at WARN level:
|
|
218
|
+
|
|
219
|
+
```json
|
|
220
|
+
{
|
|
221
|
+
"event": "DHAN_ORDER_ATTEMPT",
|
|
222
|
+
"hostname": "DESKTOP-SHUBHAM",
|
|
223
|
+
"env": "production",
|
|
224
|
+
"ipv4": "122.171.22.40",
|
|
225
|
+
"ipv6": "2401:4900:894c:8448:1da9:27f1:48e7:61be",
|
|
226
|
+
"security_id": "11536",
|
|
227
|
+
"correlation_id": "SCALPER_7af1",
|
|
228
|
+
"timestamp": "2026-03-17T06:45:22Z"
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
This tells you instantly which machine, app, IP, and environment placed the order.
|
|
233
|
+
|
|
234
|
+
### Correlation ID Prefixes
|
|
235
|
+
|
|
236
|
+
Use per-app prefixes for instant source identification in the Dhan orderbook:
|
|
237
|
+
|
|
238
|
+
```ruby
|
|
239
|
+
# algo_scalper_api
|
|
240
|
+
correlation_id: "SCALPER_#{SecureRandom.hex(4)}"
|
|
241
|
+
|
|
242
|
+
# algo_trader_api
|
|
243
|
+
correlation_id: "TRADER_#{SecureRandom.hex(4)}"
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
The Dhan orderbook will show `SCALPER_7af1` or `TRADER_3bc9`, making the source obvious.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
123
250
|
## REST API
|
|
124
251
|
|
|
125
252
|
### Orders — Place, Modify, Cancel
|
|
@@ -283,23 +410,56 @@ Need initializers, service objects, ActionCable wiring, and background workers?
|
|
|
283
410
|
|
|
284
411
|
---
|
|
285
412
|
|
|
413
|
+
## Real-World Examples
|
|
414
|
+
|
|
415
|
+
These scripts are designed around user goals rather than API surfaces:
|
|
416
|
+
|
|
417
|
+
| Example | Use case |
|
|
418
|
+
| ------- | -------- |
|
|
419
|
+
| [examples/basic_trading_bot.rb](examples/basic_trading_bot.rb) | Pull historical data, evaluate a simple signal, and place a guarded order |
|
|
420
|
+
| [examples/portfolio_monitor.rb](examples/portfolio_monitor.rb) | Snapshot funds, holdings, and positions for a monitoring script |
|
|
421
|
+
| [examples/options_watchlist.rb](examples/options_watchlist.rb) | Build a live options watchlist with index quotes and option-chain context |
|
|
422
|
+
| [examples/market_feed_example.rb](examples/market_feed_example.rb) | Subscribe to major market indices over WebSocket |
|
|
423
|
+
| [examples/live_order_updates.rb](examples/live_order_updates.rb) | Track order lifecycle events in real time |
|
|
424
|
+
|
|
425
|
+
For search-driven discovery and onboarding content, see:
|
|
426
|
+
|
|
427
|
+
- [docs/HOW_TO_USE_DHAN_API_WITH_RUBY.md](docs/HOW_TO_USE_DHAN_API_WITH_RUBY.md)
|
|
428
|
+
- [docs/BUILD_A_TRADING_BOT_WITH_RUBY_AND_DHAN.md](docs/BUILD_A_TRADING_BOT_WITH_RUBY_AND_DHAN.md)
|
|
429
|
+
|
|
430
|
+
## Use Case Guides
|
|
431
|
+
|
|
432
|
+
- [docs/DHAN_API_RUBY_EXAMPLES.md](docs/DHAN_API_RUBY_EXAMPLES.md)
|
|
433
|
+
- [docs/DHAN_WEBSOCKET_RUBY_GUIDE.md](docs/DHAN_WEBSOCKET_RUBY_GUIDE.md)
|
|
434
|
+
- [docs/BEST_WAY_TO_USE_DHAN_API_IN_RUBY.md](docs/BEST_WAY_TO_USE_DHAN_API_IN_RUBY.md)
|
|
435
|
+
- [docs/DHAN_RUBY_QA.md](docs/DHAN_RUBY_QA.md)
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
286
439
|
## 📚 Documentation
|
|
287
440
|
|
|
288
441
|
| Guide | What it covers |
|
|
289
442
|
| ----- | -------------- |
|
|
443
|
+
| [Architecture](ARCHITECTURE.md) | Layering, dependency flow, design patterns, extension points |
|
|
290
444
|
| [Authentication](docs/AUTHENTICATION.md) | Token flows, TOTP, OAuth, auto-management |
|
|
291
445
|
| [Configuration Reference](docs/CONFIGURATION.md) | Full ENV matrix, logging, timeouts, available resources |
|
|
292
446
|
| [WebSocket Integration](docs/WEBSOCKET_INTEGRATION.md) | All WS types, architecture, best practices |
|
|
293
447
|
| [WebSocket Protocol](docs/WEBSOCKET_PROTOCOL.md) | Packet parsing, request codes, tick schema, exchange enums |
|
|
294
448
|
| [Rails WebSocket Guide](docs/RAILS_WEBSOCKET_INTEGRATION.md) | Rails-specific patterns, ActionCable |
|
|
295
449
|
| [Rails Integration](docs/RAILS_INTEGRATION.md) | Initializers, service objects, workers |
|
|
296
|
-
| [Standalone Ruby Guide](docs/STANDALONE_RUBY_WEBSOCKET_INTEGRATION.md) | Scripts, daemons,
|
|
450
|
+
| [Standalone Ruby Guide](docs/STANDALONE_RUBY_WEBSOCKET_INTEGRATION.md) | Scripts, daemons, and long-running Ruby processes |
|
|
297
451
|
| [Super Orders API](docs/SUPER_ORDERS.md) | Full REST reference for super orders |
|
|
298
452
|
| [API Constants Reference](docs/CONSTANTS_REFERENCE.md) | All valid enums, exchange segments, and order parameters |
|
|
299
453
|
| [Data API Parameters](docs/DATA_API_PARAMETERS.md) | Historical data, option chain parameters |
|
|
300
454
|
| [Testing Guide](docs/TESTING_GUIDE.md) | WebSocket testing, model testing, console helpers |
|
|
301
455
|
| [Technical Analysis](docs/TECHNICAL_ANALYSIS.md) | Indicators, multi-timeframe aggregation |
|
|
302
456
|
| [Troubleshooting](docs/TROUBLESHOOTING.md) | 429 errors, reconnect, auth issues, debug logging |
|
|
457
|
+
| [How To Use Dhan API With Ruby](docs/HOW_TO_USE_DHAN_API_WITH_RUBY.md) | Search-friendly onboarding guide for Ruby users |
|
|
458
|
+
| [Build A Trading Bot With Ruby And Dhan](docs/BUILD_A_TRADING_BOT_WITH_RUBY_AND_DHAN.md) | End-to-end tutorial framing for strategy builders |
|
|
459
|
+
| [Dhan API Ruby Examples](docs/DHAN_API_RUBY_EXAMPLES.md) | Small answer-style snippets for common Ruby + Dhan tasks |
|
|
460
|
+
| [Dhan WebSocket Ruby Guide](docs/DHAN_WEBSOCKET_RUBY_GUIDE.md) | Query-shaped guide for Dhan market data streaming in Ruby |
|
|
461
|
+
| [Best Way To Use Dhan API In Ruby](docs/BEST_WAY_TO_USE_DHAN_API_IN_RUBY.md) | Comparison-focused guide for SDK vs raw HTTP |
|
|
462
|
+
| [Dhan Ruby Q&A](docs/DHAN_RUBY_QA.md) | Publish-ready answers for common Dhan + Ruby questions |
|
|
303
463
|
| [Release Guide](docs/RELEASE_GUIDE.md) | Versioning, publishing, changelog |
|
|
304
464
|
|
|
305
465
|
---
|
|
@@ -311,6 +471,7 @@ Need initializers, service objects, ActionCable wiring, and background workers?
|
|
|
311
471
|
- Don't exceed **100 instruments per subscribe frame** (auto-chunked by the client)
|
|
312
472
|
- Call `DhanHQ::WS.disconnect_all_local!` on shutdown
|
|
313
473
|
- Avoid rapid connect/disconnect loops — the client already backs off on 429
|
|
474
|
+
- Use dynamic token providers in long-running systems instead of hardcoding expiring tokens
|
|
314
475
|
|
|
315
476
|
---
|
|
316
477
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Best Way To Use Dhan API In Ruby
|
|
2
|
+
|
|
3
|
+
The best way to use Dhan API in Ruby is usually not raw HTTP. It is a Ruby SDK that already understands the shape of trading workflows: authentication, market data, streaming, and order execution.
|
|
4
|
+
|
|
5
|
+
That is the role of `DhanHQ`, the Ruby SDK for Dhan API v2.
|
|
6
|
+
|
|
7
|
+
## SDK Vs Raw HTTP
|
|
8
|
+
|
|
9
|
+
Raw HTTP is fine when you only need one endpoint once.
|
|
10
|
+
|
|
11
|
+
For ongoing Ruby applications, the SDK is usually the better fit:
|
|
12
|
+
|
|
13
|
+
- typed models instead of manual JSON mapping
|
|
14
|
+
- token lifecycle support instead of handwritten refresh logic
|
|
15
|
+
- WebSocket reconnect and backoff instead of custom event-loop recovery
|
|
16
|
+
- live-trading guardrails instead of fragile order scripts
|
|
17
|
+
- one Ruby interface for market data, holdings, positions, and orders
|
|
18
|
+
|
|
19
|
+
## When Raw HTTP Is Enough
|
|
20
|
+
|
|
21
|
+
- you are writing a one-off experiment
|
|
22
|
+
- you only need one endpoint
|
|
23
|
+
- you do not need streaming or long-running behavior
|
|
24
|
+
|
|
25
|
+
## When The Ruby SDK Is Better
|
|
26
|
+
|
|
27
|
+
- you are building a trading bot
|
|
28
|
+
- you are integrating Dhan into a Rails app
|
|
29
|
+
- you need Dhan WebSocket support in Ruby
|
|
30
|
+
- you want clean abstractions over raw trading endpoints
|
|
31
|
+
|
|
32
|
+
## Start Here
|
|
33
|
+
|
|
34
|
+
- [README.md](../README.md)
|
|
35
|
+
- [HOW_TO_USE_DHAN_API_WITH_RUBY.md](HOW_TO_USE_DHAN_API_WITH_RUBY.md)
|
|
36
|
+
- [BUILD_A_TRADING_BOT_WITH_RUBY_AND_DHAN.md](BUILD_A_TRADING_BOT_WITH_RUBY_AND_DHAN.md)
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Build A Trading Bot With Ruby And Dhan
|
|
2
|
+
|
|
3
|
+
If your goal is to build a trading bot with Ruby and Dhan, you do not need to start from raw REST calls and custom WebSocket loops. `DhanHQ` is the Ruby SDK for Dhan API v2, and it already gives you the core pieces a Ruby trading bot needs: historical data access, live market data streaming, order models, token lifecycle handling, and live-trading guardrails.
|
|
4
|
+
|
|
5
|
+
This guide shows the minimal path from market data to signal to guarded execution.
|
|
6
|
+
|
|
7
|
+
## 1. Configure The SDK
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
require "dhan_hq"
|
|
11
|
+
|
|
12
|
+
DhanHQ.configure_with_env
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Set:
|
|
16
|
+
|
|
17
|
+
- `DHAN_CLIENT_ID`
|
|
18
|
+
- `DHAN_ACCESS_TOKEN`
|
|
19
|
+
|
|
20
|
+
Only set `LIVE_TRADING=true` when you intentionally want to place live orders.
|
|
21
|
+
|
|
22
|
+
## 2. Pull Historical Data For The Signal
|
|
23
|
+
|
|
24
|
+
Use the Dhan API from Ruby to fetch recent bars:
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
bars = DhanHQ::Models::HistoricalData.intraday(
|
|
28
|
+
security_id: "13",
|
|
29
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::IDX_I,
|
|
30
|
+
instrument: DhanHQ::Constants::InstrumentType::INDEX,
|
|
31
|
+
interval: "5",
|
|
32
|
+
from_date: Date.today.to_s,
|
|
33
|
+
to_date: Date.today.to_s
|
|
34
|
+
)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The runnable version of this flow lives in [examples/basic_trading_bot.rb](../examples/basic_trading_bot.rb).
|
|
38
|
+
|
|
39
|
+
## 3. Compute A Simple Trading Signal
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
closes = bars.map { |bar| bar[:close].to_f }
|
|
43
|
+
last_close = closes.last
|
|
44
|
+
sma20 = closes.last(20).sum / 20.0
|
|
45
|
+
signal = last_close > sma20 ? :bullish : :bearish
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This is intentionally simple. The point is not the strategy itself. The point is that the Ruby SDK for Dhan API gets you to a working trading loop quickly.
|
|
49
|
+
|
|
50
|
+
## 4. Add Live Market Data
|
|
51
|
+
|
|
52
|
+
Most trading bots need streaming updates after the initial historical snapshot.
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
# Example: Subscribe to live market data using Dhan API WebSocket in Ruby
|
|
56
|
+
client = DhanHQ::WS.connect(mode: :quote) do |tick|
|
|
57
|
+
puts "#{tick[:security_id]} -> #{tick[:ltp]}"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
client.subscribe_one(
|
|
61
|
+
segment: DhanHQ::Constants::ExchangeSegment::IDX_I,
|
|
62
|
+
security_id: "13"
|
|
63
|
+
)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
For a fuller live-data script, see [examples/options_watchlist.rb](../examples/options_watchlist.rb).
|
|
67
|
+
|
|
68
|
+
## 5. Execute Safely
|
|
69
|
+
|
|
70
|
+
If the signal is bullish, you can build an order model:
|
|
71
|
+
|
|
72
|
+
```ruby
|
|
73
|
+
order = DhanHQ::Models::Order.new(
|
|
74
|
+
transaction_type: DhanHQ::Constants::TransactionType::BUY,
|
|
75
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
76
|
+
product_type: DhanHQ::Constants::ProductType::CNC,
|
|
77
|
+
order_type: DhanHQ::Constants::OrderType::MARKET,
|
|
78
|
+
validity: DhanHQ::Constants::Validity::DAY,
|
|
79
|
+
security_id: "11536",
|
|
80
|
+
quantity: 1
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# order.save
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Keep `order.save` commented while you are developing. `DhanHQ` will only submit live orders when `LIVE_TRADING=true`, which is one of the reasons it is safer than raw order scripts.
|
|
87
|
+
|
|
88
|
+
## 6. Grow Into A Real Trading System
|
|
89
|
+
|
|
90
|
+
Once you have the basic bot loop, the same SDK supports:
|
|
91
|
+
|
|
92
|
+
- WebSocket order updates
|
|
93
|
+
- option-chain workflows
|
|
94
|
+
- Rails integration for service objects and workers
|
|
95
|
+
- token providers for long-running processes
|
|
96
|
+
|
|
97
|
+
Use these next:
|
|
98
|
+
|
|
99
|
+
- [examples/basic_trading_bot.rb](../examples/basic_trading_bot.rb)
|
|
100
|
+
- [examples/options_watchlist.rb](../examples/options_watchlist.rb)
|
|
101
|
+
- [WEBSOCKET_INTEGRATION.md](WEBSOCKET_INTEGRATION.md)
|
|
102
|
+
- [AUTHENTICATION.md](AUTHENTICATION.md)
|
|
103
|
+
- [RAILS_INTEGRATION.md](RAILS_INTEGRATION.md)
|
|
104
|
+
|
|
105
|
+
## Canonical Publishing Notes
|
|
106
|
+
|
|
107
|
+
If you publish this externally:
|
|
108
|
+
|
|
109
|
+
- keep the title exactly `Build a Trading Bot With Ruby and Dhan`
|
|
110
|
+
- link back to the repo root and the example scripts
|
|
111
|
+
- keep the intro sentence that frames `DhanHQ` as `the Ruby SDK for Dhan API`
|
data/docs/CONFIGURATION.md
CHANGED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Dhan API Ruby Examples
|
|
2
|
+
|
|
3
|
+
This page collects small, direct examples for people searching for `Dhan API Ruby`, `Ruby SDK for Dhan API examples`, or `Dhan trading SDK for Ruby`.
|
|
4
|
+
|
|
5
|
+
All examples use `DhanHQ`, the Ruby SDK for Dhan API v2.
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
require "dhan_hq"
|
|
11
|
+
|
|
12
|
+
DhanHQ.configure_with_env
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Example: Get Positions In Ruby
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
# Example: Fetch positions using Dhan API in Ruby
|
|
19
|
+
positions = DhanHQ::Models::Position.all
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Example: Get Holdings In Ruby
|
|
23
|
+
|
|
24
|
+
```ruby
|
|
25
|
+
# Example: Fetch holdings using Dhan API in Ruby
|
|
26
|
+
holdings = DhanHQ::Models::Holding.all
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Example: Fetch Historical Data In Ruby
|
|
30
|
+
|
|
31
|
+
```ruby
|
|
32
|
+
bars = DhanHQ::Models::HistoricalData.intraday(
|
|
33
|
+
security_id: "13",
|
|
34
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::IDX_I,
|
|
35
|
+
instrument: DhanHQ::Constants::InstrumentType::INDEX,
|
|
36
|
+
interval: "5",
|
|
37
|
+
from_date: Date.today.to_s,
|
|
38
|
+
to_date: Date.today.to_s
|
|
39
|
+
)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Example: Subscribe To Live Market Data In Ruby
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
# Example: Subscribe to live market data using Dhan API WebSocket in Ruby
|
|
46
|
+
client = DhanHQ::WS.connect(mode: :ticker) do |tick|
|
|
47
|
+
puts "#{tick[:security_id]} -> #{tick[:ltp]}"
|
|
48
|
+
end
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Example: Build An Order Payload In Ruby
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
order = DhanHQ::Models::Order.new(
|
|
55
|
+
transaction_type: DhanHQ::Constants::TransactionType::BUY,
|
|
56
|
+
exchange_segment: DhanHQ::Constants::ExchangeSegment::NSE_EQ,
|
|
57
|
+
product_type: DhanHQ::Constants::ProductType::CNC,
|
|
58
|
+
order_type: DhanHQ::Constants::OrderType::MARKET,
|
|
59
|
+
validity: DhanHQ::Constants::Validity::DAY,
|
|
60
|
+
security_id: "11536",
|
|
61
|
+
quantity: 1
|
|
62
|
+
)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Where To Go Next
|
|
66
|
+
|
|
67
|
+
- [README.md](../README.md)
|
|
68
|
+
- [HOW_TO_USE_DHAN_API_WITH_RUBY.md](HOW_TO_USE_DHAN_API_WITH_RUBY.md)
|
|
69
|
+
- [examples/portfolio_monitor.rb](../examples/portfolio_monitor.rb)
|
|
70
|
+
- [examples/basic_trading_bot.rb](../examples/basic_trading_bot.rb)
|
|
71
|
+
- [examples/options_watchlist.rb](../examples/options_watchlist.rb)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Dhan Ruby Q&A
|
|
2
|
+
|
|
3
|
+
This document contains publish-ready answers for common questions about Dhan API and Ruby. The goal is to create question-shaped content that maps `Dhan API + Ruby` to `DhanHQ`.
|
|
4
|
+
|
|
5
|
+
## How To Use Dhan API In Ruby?
|
|
6
|
+
|
|
7
|
+
Use `DhanHQ`, the Ruby SDK for Dhan API v2. It gives you typed models, WebSocket support, token lifecycle management, and safer order workflows. Start with [README.md](../README.md) and [HOW_TO_USE_DHAN_API_WITH_RUBY.md](HOW_TO_USE_DHAN_API_WITH_RUBY.md).
|
|
8
|
+
|
|
9
|
+
## Is There A Ruby SDK For Dhan API?
|
|
10
|
+
|
|
11
|
+
Yes. `DhanHQ` is a Ruby SDK for Dhan API that covers REST, WebSocket market data, order updates, holdings, positions, and order workflows. See [README.md](../README.md).
|
|
12
|
+
|
|
13
|
+
## How Do I Build A Trading Bot With Dhan In Ruby?
|
|
14
|
+
|
|
15
|
+
Use [examples/basic_trading_bot.rb](../examples/basic_trading_bot.rb) together with [BUILD_A_TRADING_BOT_WITH_RUBY_AND_DHAN.md](BUILD_A_TRADING_BOT_WITH_RUBY_AND_DHAN.md). The SDK already provides historical data, live market data, and order models.
|
|
16
|
+
|
|
17
|
+
## How Do I Use Dhan WebSocket In Ruby?
|
|
18
|
+
|
|
19
|
+
Use `DhanHQ::WS.connect` for market data and `DhanHQ::WS::Orders` for order updates. Start with [Dhan WebSocket Ruby Guide](DHAN_WEBSOCKET_RUBY_GUIDE.md) and [examples/options_watchlist.rb](../examples/options_watchlist.rb).
|
|
20
|
+
|
|
21
|
+
## Is DhanHQ Better Than Calling Dhan API With Raw HTTP In Ruby?
|
|
22
|
+
|
|
23
|
+
For long-running Ruby systems, usually yes. The SDK gives you token refresh support, typed models, reconnect handling, and safer order workflows. See [BEST_WAY_TO_USE_DHAN_API_IN_RUBY.md](BEST_WAY_TO_USE_DHAN_API_IN_RUBY.md).
|
|
24
|
+
|
|
25
|
+
## Can I Use DhanHQ In Rails?
|
|
26
|
+
|
|
27
|
+
Yes. The SDK has a dedicated Rails integration guide for initializers, service objects, and worker patterns. See [RAILS_INTEGRATION.md](RAILS_INTEGRATION.md).
|