DhanHQ 2.1.5 → 2.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/GUIDE.md +215 -73
- data/README.md +416 -132
- data/README1.md +267 -26
- data/docs/live_order_updates.md +319 -0
- data/docs/rails_websocket_integration.md +847 -0
- data/docs/standalone_ruby_websocket_integration.md +1588 -0
- data/docs/websocket_integration.md +871 -0
- data/examples/comprehensive_websocket_examples.rb +148 -0
- data/examples/instrument_finder_test.rb +195 -0
- data/examples/live_order_updates.rb +118 -0
- data/examples/market_depth_example.rb +144 -0
- data/examples/market_feed_example.rb +81 -0
- data/examples/order_update_example.rb +105 -0
- data/examples/trading_fields_example.rb +215 -0
- data/lib/DhanHQ/configuration.rb +16 -1
- data/lib/DhanHQ/contracts/expired_options_data_contract.rb +103 -0
- data/lib/DhanHQ/contracts/trade_contract.rb +70 -0
- data/lib/DhanHQ/errors.rb +2 -0
- data/lib/DhanHQ/models/expired_options_data.rb +331 -0
- data/lib/DhanHQ/models/instrument.rb +96 -2
- data/lib/DhanHQ/models/order_update.rb +235 -0
- data/lib/DhanHQ/models/trade.rb +118 -31
- data/lib/DhanHQ/resources/expired_options_data.rb +22 -0
- data/lib/DhanHQ/version.rb +1 -1
- data/lib/DhanHQ/ws/base_connection.rb +249 -0
- data/lib/DhanHQ/ws/connection.rb +2 -2
- data/lib/DhanHQ/ws/decoder.rb +3 -3
- data/lib/DhanHQ/ws/market_depth/client.rb +376 -0
- data/lib/DhanHQ/ws/market_depth/decoder.rb +131 -0
- data/lib/DhanHQ/ws/market_depth.rb +74 -0
- data/lib/DhanHQ/ws/orders/client.rb +175 -11
- data/lib/DhanHQ/ws/orders/connection.rb +40 -81
- data/lib/DhanHQ/ws/orders.rb +28 -0
- data/lib/DhanHQ/ws/segments.rb +18 -2
- data/lib/DhanHQ/ws.rb +3 -2
- data/lib/dhan_hq.rb +5 -0
- metadata +35 -1
@@ -6,28 +6,40 @@ require_relative "connection"
|
|
6
6
|
module DhanHQ
|
7
7
|
module WS
|
8
8
|
module Orders
|
9
|
-
|
9
|
+
##
|
10
|
+
# Enhanced WebSocket client for real-time order updates
|
11
|
+
# Provides comprehensive order state tracking and event handling
|
12
|
+
# rubocop:disable Metrics/ClassLength
|
10
13
|
class Client
|
11
|
-
def initialize(url: nil)
|
14
|
+
def initialize(url: nil, **options)
|
12
15
|
@callbacks = Concurrent::Map.new { |h, k| h[k] = [] }
|
13
|
-
@started
|
14
|
-
|
15
|
-
|
16
|
+
@started = Concurrent::AtomicBoolean.new(false)
|
17
|
+
@order_tracker = Concurrent::Map.new
|
18
|
+
cfg = DhanHQ.configuration
|
19
|
+
@url = url || cfg.ws_order_url
|
20
|
+
@connection_options = options
|
16
21
|
end
|
17
22
|
|
23
|
+
##
|
24
|
+
# Start the WebSocket connection and begin receiving order updates
|
25
|
+
# @return [Client] self for method chaining
|
18
26
|
def start
|
19
27
|
return self if @started.true?
|
20
28
|
|
21
29
|
@started.make_true
|
22
|
-
@conn = Connection.new(url: @url)
|
23
|
-
|
24
|
-
|
25
|
-
|
30
|
+
@conn = Connection.new(url: @url, **@connection_options)
|
31
|
+
@conn.on(:open) { emit(:open, true) }
|
32
|
+
@conn.on(:close) { |payload| emit(:close, payload) }
|
33
|
+
@conn.on(:error) { |error| emit(:error, error) }
|
34
|
+
@conn.on(:message) { |msg| handle_message(msg) }
|
26
35
|
@conn.start
|
27
36
|
DhanHQ::WS::Registry.register(self) if defined?(DhanHQ::WS::Registry)
|
28
37
|
self
|
29
38
|
end
|
30
39
|
|
40
|
+
##
|
41
|
+
# Stop the WebSocket connection
|
42
|
+
# @return [void]
|
31
43
|
def stop
|
32
44
|
return unless @started.true?
|
33
45
|
|
@@ -37,17 +49,166 @@ module DhanHQ
|
|
37
49
|
DhanHQ::WS::Registry.unregister(self) if defined?(DhanHQ::WS::Registry)
|
38
50
|
end
|
39
51
|
|
52
|
+
##
|
53
|
+
# Force disconnect the WebSocket
|
54
|
+
# @return [void]
|
40
55
|
def disconnect!
|
41
56
|
@conn&.disconnect!
|
42
57
|
end
|
43
58
|
|
44
|
-
|
45
|
-
|
59
|
+
##
|
60
|
+
# Register event handlers
|
61
|
+
# @param event [Symbol] Event type (:update, :raw, :status_change, :execution, :error)
|
62
|
+
# @param block [Proc] Event handler
|
63
|
+
# @return [Client] self for method chaining
|
64
|
+
def on(event, &block)
|
65
|
+
@callbacks[event] << block
|
46
66
|
self
|
47
67
|
end
|
48
68
|
|
69
|
+
##
|
70
|
+
# Get current order state for a specific order
|
71
|
+
# @param order_no [String] Order number
|
72
|
+
# @return [OrderUpdate, nil] Latest order update or nil if not found
|
73
|
+
def order_state(order_no)
|
74
|
+
@order_tracker[order_no]
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# Get all tracked orders
|
79
|
+
# @return [Hash] Hash of order_no => OrderUpdate
|
80
|
+
def all_orders
|
81
|
+
@order_tracker.dup
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Get orders by status
|
86
|
+
# @param status [String] Order status (TRANSIT, PENDING, REJECTED, etc.)
|
87
|
+
# @return [Array<OrderUpdate>] Orders with the specified status
|
88
|
+
def orders_by_status(status)
|
89
|
+
@order_tracker.values.select { |order| order.status == status }
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Get orders by symbol
|
94
|
+
# @param symbol [String] Trading symbol
|
95
|
+
# @return [Array<OrderUpdate>] Orders for the specified symbol
|
96
|
+
def orders_by_symbol(symbol)
|
97
|
+
@order_tracker.values.select { |order| order.symbol == symbol }
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# Get partially executed orders
|
102
|
+
# @return [Array<OrderUpdate>] Orders that are partially executed
|
103
|
+
def partially_executed_orders
|
104
|
+
@order_tracker.values.select(&:partially_executed?)
|
105
|
+
end
|
106
|
+
|
107
|
+
##
|
108
|
+
# Get fully executed orders
|
109
|
+
# @return [Array<OrderUpdate>] Orders that are fully executed
|
110
|
+
def fully_executed_orders
|
111
|
+
@order_tracker.values.select(&:fully_executed?)
|
112
|
+
end
|
113
|
+
|
114
|
+
##
|
115
|
+
# Get pending orders (not executed)
|
116
|
+
# @return [Array<OrderUpdate>] Orders that are not executed
|
117
|
+
def pending_orders
|
118
|
+
@order_tracker.values.select(&:not_executed?)
|
119
|
+
end
|
120
|
+
|
121
|
+
##
|
122
|
+
# Check if connection is active
|
123
|
+
# @return [Boolean] true if connected
|
124
|
+
def connected?
|
125
|
+
@conn&.open? || false
|
126
|
+
end
|
127
|
+
|
49
128
|
private
|
50
129
|
|
130
|
+
##
|
131
|
+
# Handle incoming WebSocket messages
|
132
|
+
# @param msg [Hash] Raw WebSocket message
|
133
|
+
def handle_message(msg)
|
134
|
+
# Emit raw message for debugging
|
135
|
+
emit(:raw, msg)
|
136
|
+
|
137
|
+
# Handle order updates
|
138
|
+
if msg&.dig(:Type) == "order_alert"
|
139
|
+
order_update = DhanHQ::Models::OrderUpdate.from_websocket_message(msg)
|
140
|
+
handle_order_update(order_update) if order_update
|
141
|
+
end
|
142
|
+
|
143
|
+
# Handle other message types
|
144
|
+
emit(:message, msg)
|
145
|
+
end
|
146
|
+
|
147
|
+
##
|
148
|
+
# Handle order update and track state changes
|
149
|
+
# @param order_update [OrderUpdate] Parsed order update
|
150
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
151
|
+
def handle_order_update(order_update)
|
152
|
+
order_no = order_update.order_no
|
153
|
+
previous_state = @order_tracker[order_no]
|
154
|
+
|
155
|
+
# Update order tracker
|
156
|
+
@order_tracker[order_no] = order_update
|
157
|
+
|
158
|
+
# Emit update event
|
159
|
+
emit(:update, order_update)
|
160
|
+
|
161
|
+
# Check for status changes
|
162
|
+
if previous_state && previous_state.status != order_update.status
|
163
|
+
emit(:status_change, {
|
164
|
+
order_update: order_update,
|
165
|
+
previous_status: previous_state.status,
|
166
|
+
new_status: order_update.status
|
167
|
+
})
|
168
|
+
end
|
169
|
+
|
170
|
+
# Check for execution updates
|
171
|
+
if previous_state && previous_state.traded_qty != order_update.traded_qty
|
172
|
+
emit(:execution, {
|
173
|
+
order_update: order_update,
|
174
|
+
previous_traded_qty: previous_state.traded_qty,
|
175
|
+
new_traded_qty: order_update.traded_qty,
|
176
|
+
execution_percentage: order_update.execution_percentage
|
177
|
+
})
|
178
|
+
end
|
179
|
+
|
180
|
+
# Emit specific status events
|
181
|
+
emit_status_specific_events(order_update, previous_state)
|
182
|
+
end
|
183
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
184
|
+
|
185
|
+
##
|
186
|
+
# Emit status-specific events
|
187
|
+
# @param order_update [OrderUpdate] Current order update
|
188
|
+
# @param previous_state [OrderUpdate, nil] Previous order state
|
189
|
+
# rubocop:disable Metrics/MethodLength
|
190
|
+
def emit_status_specific_events(order_update, _previous_state)
|
191
|
+
case order_update.status
|
192
|
+
when "TRANSIT"
|
193
|
+
emit(:order_transit, order_update)
|
194
|
+
when "PENDING"
|
195
|
+
emit(:order_pending, order_update)
|
196
|
+
when "REJECTED"
|
197
|
+
emit(:order_rejected, order_update)
|
198
|
+
when "CANCELLED"
|
199
|
+
emit(:order_cancelled, order_update)
|
200
|
+
when "TRADED"
|
201
|
+
emit(:order_traded, order_update)
|
202
|
+
when "EXPIRED"
|
203
|
+
emit(:order_expired, order_update)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
# rubocop:enable Metrics/MethodLength
|
207
|
+
|
208
|
+
##
|
209
|
+
# Emit events to registered callbacks
|
210
|
+
# @param event [Symbol] Event type
|
211
|
+
# @param payload [Object] Event payload
|
51
212
|
def emit(event, payload)
|
52
213
|
list = begin
|
53
214
|
@callbacks[event]
|
@@ -55,8 +216,11 @@ module DhanHQ
|
|
55
216
|
[]
|
56
217
|
end
|
57
218
|
list.each { |cb| cb.call(payload) }
|
219
|
+
rescue StandardError => e
|
220
|
+
DhanHQ.logger&.error("[DhanHQ::WS::Orders] Error in event handler: #{e.class} #{e.message}")
|
58
221
|
end
|
59
222
|
end
|
223
|
+
# rubocop:enable Metrics/ClassLength
|
60
224
|
end
|
61
225
|
end
|
62
226
|
end
|
@@ -1,107 +1,52 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require "faye/websocket"
|
5
|
-
require "json"
|
6
|
-
require "thread" # rubocop:disable Lint/RedundantRequireStatement
|
3
|
+
require_relative "../base_connection"
|
7
4
|
|
8
5
|
module DhanHQ
|
9
6
|
module WS
|
10
7
|
module Orders
|
8
|
+
##
|
11
9
|
# WebSocket connection for real-time order updates
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
@stop = false
|
21
|
-
@cooloff_until = nil
|
22
|
-
end
|
23
|
-
|
24
|
-
def start
|
25
|
-
Thread.new { loop_run }
|
26
|
-
self
|
27
|
-
end
|
28
|
-
|
29
|
-
def stop
|
30
|
-
@stop = true
|
31
|
-
@ws&.close
|
32
|
-
end
|
33
|
-
|
34
|
-
def disconnect!
|
35
|
-
# spec does not list a separate disconnect message; just close
|
36
|
-
@ws&.close
|
10
|
+
# Inherits from BaseConnection for consistent behavior
|
11
|
+
class Connection < BaseConnection
|
12
|
+
##
|
13
|
+
# Initialize Orders WebSocket connection
|
14
|
+
# @param url [String] WebSocket endpoint URL
|
15
|
+
# @param options [Hash] Connection options
|
16
|
+
def initialize(url:, **options)
|
17
|
+
super
|
37
18
|
end
|
38
19
|
|
39
20
|
private
|
40
21
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
failed = false
|
45
|
-
got_429 = false
|
46
|
-
sleep (@cooloff_until - Time.now).ceil if @cooloff_until && Time.now < @cooloff_until
|
47
|
-
|
48
|
-
begin
|
49
|
-
failed, got_429 = run_session
|
50
|
-
rescue StandardError => e
|
51
|
-
DhanHQ.logger&.error("[DhanHQ::WS::Orders] crashed #{e.class} #{e.message}")
|
52
|
-
failed = true
|
53
|
-
ensure
|
54
|
-
break if @stop
|
55
|
-
|
56
|
-
if got_429
|
57
|
-
@cooloff_until = Time.now + COOL_OFF_429
|
58
|
-
DhanHQ.logger&.warn("[DhanHQ::WS::Orders] cooling off #{COOL_OFF_429}s due to 429")
|
59
|
-
end
|
60
|
-
|
61
|
-
if failed
|
62
|
-
sleep_time = [backoff, MAX_BACKOFF].min
|
63
|
-
jitter = rand(0.2 * sleep_time)
|
64
|
-
DhanHQ.logger&.warn("[DhanHQ::WS::Orders] reconnecting in #{(sleep_time + jitter).round(1)}s")
|
65
|
-
sleep(sleep_time + jitter)
|
66
|
-
backoff *= 2.0
|
67
|
-
else
|
68
|
-
backoff = 2.0
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
22
|
+
##
|
23
|
+
# Run WebSocket session for Orders
|
24
|
+
# @return [Array<Boolean>] [failed, got_429]
|
74
25
|
def run_session
|
75
|
-
failed
|
26
|
+
failed = false
|
76
27
|
got_429 = false
|
77
|
-
latch
|
28
|
+
latch = Queue.new
|
78
29
|
|
79
30
|
runner = proc do |stopper|
|
80
31
|
@ws = Faye::WebSocket::Client.new(@url, nil, headers: default_headers)
|
81
32
|
|
82
33
|
@ws.on :open do |_|
|
83
|
-
|
84
|
-
|
34
|
+
handle_open
|
35
|
+
authenticate
|
85
36
|
end
|
86
37
|
|
87
38
|
@ws.on :message do |ev|
|
88
|
-
|
89
|
-
@on_json&.call(msg)
|
90
|
-
rescue StandardError => e
|
91
|
-
DhanHQ.logger&.error("[DhanHQ::WS::Orders] bad JSON #{e.class}: #{e.message}")
|
39
|
+
handle_message(ev)
|
92
40
|
end
|
93
41
|
|
94
42
|
@ws.on :close do |ev|
|
95
|
-
|
96
|
-
failed = (ev.code != 1000)
|
97
|
-
got_429 = ev.reason.to_s.include?("429")
|
43
|
+
failed, got_429 = handle_close(ev)
|
98
44
|
latch << true
|
99
45
|
stopper.call
|
100
46
|
end
|
101
47
|
|
102
48
|
@ws.on :error do |ev|
|
103
|
-
|
104
|
-
failed = true
|
49
|
+
failed, got_429 = handle_error(ev)
|
105
50
|
end
|
106
51
|
end
|
107
52
|
|
@@ -114,16 +59,29 @@ module DhanHQ
|
|
114
59
|
end
|
115
60
|
|
116
61
|
latch.pop
|
117
|
-
|
118
62
|
[failed, got_429]
|
119
63
|
end
|
120
64
|
|
121
|
-
|
122
|
-
|
65
|
+
##
|
66
|
+
# Process incoming WebSocket message
|
67
|
+
# @param ev [Event] WebSocket message event
|
68
|
+
def handle_message(ev)
|
69
|
+
msg = JSON.parse(ev.data, symbolize_names: true)
|
70
|
+
emit(:raw, msg)
|
71
|
+
emit(:message, msg)
|
72
|
+
rescue JSON::ParserError => e
|
73
|
+
DhanHQ.logger&.error("[DhanHQ::WS::Orders] Bad JSON #{e.class}: #{e.message}")
|
74
|
+
emit(:error, e)
|
75
|
+
rescue StandardError => e
|
76
|
+
DhanHQ.logger&.error("[DhanHQ::WS::Orders] Message processing error: #{e.class} #{e.message}")
|
77
|
+
emit(:error, e)
|
123
78
|
end
|
124
79
|
|
125
|
-
|
80
|
+
##
|
81
|
+
# Authenticate with DhanHQ Orders WebSocket
|
82
|
+
def authenticate
|
126
83
|
cfg = DhanHQ.configuration
|
84
|
+
|
127
85
|
if cfg.ws_user_type.to_s.upcase == "PARTNER"
|
128
86
|
payload = {
|
129
87
|
LoginReq: { MsgCode: 42, ClientId: cfg.partner_id },
|
@@ -132,14 +90,15 @@ module DhanHQ
|
|
132
90
|
}
|
133
91
|
else
|
134
92
|
token = cfg.access_token or raise "DhanHQ.access_token not set"
|
135
|
-
cid
|
93
|
+
cid = cfg.client_id or raise "DhanHQ.client_id not set"
|
136
94
|
payload = {
|
137
95
|
LoginReq: { MsgCode: 42, ClientId: cid, Token: token },
|
138
96
|
UserType: "SELF"
|
139
97
|
}
|
140
98
|
end
|
99
|
+
|
141
100
|
DhanHQ.logger&.info("[DhanHQ::WS::Orders] LOGIN -> (#{payload[:UserType]})")
|
142
|
-
|
101
|
+
send_message(payload)
|
143
102
|
end
|
144
103
|
end
|
145
104
|
end
|
data/lib/DhanHQ/ws/orders.rb
CHANGED
@@ -4,11 +4,39 @@ require_relative "orders/client"
|
|
4
4
|
|
5
5
|
module DhanHQ
|
6
6
|
module WS
|
7
|
+
##
|
7
8
|
# WebSocket orders module for real-time order updates
|
9
|
+
# Provides comprehensive order state tracking and event handling
|
8
10
|
module Orders
|
11
|
+
##
|
12
|
+
# Connect to order updates WebSocket with a simple callback
|
13
|
+
# @param block [Proc] Callback for order updates
|
14
|
+
# @return [Client] WebSocket client instance
|
9
15
|
def self.connect(&)
|
10
16
|
Client.new.start.on(:update, &)
|
11
17
|
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Create a new order updates client with advanced features
|
21
|
+
# @param url [String, nil] Optional custom WebSocket URL
|
22
|
+
# @return [Client] New client instance
|
23
|
+
def self.client(url: nil)
|
24
|
+
Client.new(url: url)
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Quick connection with multiple event handlers
|
29
|
+
# @param handlers [Hash] Event handlers
|
30
|
+
# @return [Client] Started client instance
|
31
|
+
def self.connect_with_handlers(handlers = {})
|
32
|
+
client = Client.new.start
|
33
|
+
|
34
|
+
handlers.each do |event, handler|
|
35
|
+
client.on(event, &handler)
|
36
|
+
end
|
37
|
+
|
38
|
+
client
|
39
|
+
end
|
12
40
|
end
|
13
41
|
end
|
14
42
|
end
|
data/lib/DhanHQ/ws/segments.rb
CHANGED
@@ -50,9 +50,16 @@ module DhanHQ
|
|
50
50
|
# @param hash [Hash]
|
51
51
|
# @return [Hash] Normalized instrument hash.
|
52
52
|
def self.normalize_instrument(hash)
|
53
|
-
|
53
|
+
raw_segment = hash[:ExchangeSegment] || hash["ExchangeSegment"]
|
54
54
|
sid = (hash[:SecurityId] || hash["SecurityId"]).to_s
|
55
|
-
|
55
|
+
seg = to_request_string(raw_segment)
|
56
|
+
# Some instruments—especially indices—require IDX_I even when the caller
|
57
|
+
# supplies only the security token. Fall back to documented defaults.
|
58
|
+
if seg.nil? || seg.empty?
|
59
|
+
fallback = default_segment_for_security_id(sid)
|
60
|
+
seg = fallback unless fallback.nil?
|
61
|
+
end
|
62
|
+
{ ExchangeSegment: seg.to_s, SecurityId: sid }
|
56
63
|
end
|
57
64
|
|
58
65
|
# Normalizes all instruments in the provided list.
|
@@ -70,6 +77,15 @@ module DhanHQ
|
|
70
77
|
def self.from_code(code_byte)
|
71
78
|
CODE_TO_STRING[code_byte] || code_byte.to_s
|
72
79
|
end
|
80
|
+
|
81
|
+
# Known security ids that must be subscribed on the index segment.
|
82
|
+
INDEX_SECURITY_IDS = %w[13 25 51].freeze
|
83
|
+
|
84
|
+
def self.default_segment_for_security_id(security_id)
|
85
|
+
return "IDX_I" if INDEX_SECURITY_IDS.include?(security_id.to_s)
|
86
|
+
|
87
|
+
nil
|
88
|
+
end
|
73
89
|
end
|
74
90
|
end
|
75
91
|
end
|
data/lib/DhanHQ/ws.rb
CHANGED
@@ -2,12 +2,13 @@
|
|
2
2
|
|
3
3
|
require_relative "ws/client"
|
4
4
|
require_relative "ws/orders"
|
5
|
+
require_relative "ws/market_depth"
|
5
6
|
|
6
7
|
module DhanHQ
|
7
8
|
# Namespace for the WebSocket streaming client helpers.
|
8
9
|
#
|
9
|
-
# The helpers provide a simple façade around
|
10
|
-
# applications can start streaming
|
10
|
+
# The helpers provide a simple façade around WebSocket clients so that
|
11
|
+
# applications can start streaming data with single method calls.
|
11
12
|
module WS
|
12
13
|
# Establishes a WebSocket connection and yields decoded ticks.
|
13
14
|
#
|
data/lib/dhan_hq.rb
CHANGED
@@ -30,6 +30,8 @@ require_relative "DhanHQ/contracts/historical_data_contract"
|
|
30
30
|
require_relative "DhanHQ/contracts/margin_calculator_contract"
|
31
31
|
require_relative "DhanHQ/contracts/position_conversion_contract"
|
32
32
|
require_relative "DhanHQ/contracts/slice_order_contract"
|
33
|
+
require_relative "DhanHQ/contracts/trade_contract"
|
34
|
+
require_relative "DhanHQ/contracts/expired_options_data_contract"
|
33
35
|
|
34
36
|
# Resources
|
35
37
|
require_relative "DhanHQ/resources/option_chain"
|
@@ -48,6 +50,7 @@ require_relative "DhanHQ/resources/instruments"
|
|
48
50
|
require_relative "DhanHQ/resources/edis"
|
49
51
|
require_relative "DhanHQ/resources/kill_switch"
|
50
52
|
require_relative "DhanHQ/resources/profile"
|
53
|
+
require_relative "DhanHQ/resources/expired_options_data"
|
51
54
|
|
52
55
|
# Models
|
53
56
|
require_relative "DhanHQ/models/order"
|
@@ -66,6 +69,8 @@ require_relative "DhanHQ/models/margin"
|
|
66
69
|
require_relative "DhanHQ/models/edis"
|
67
70
|
require_relative "DhanHQ/models/kill_switch"
|
68
71
|
require_relative "DhanHQ/models/profile"
|
72
|
+
require_relative "DhanHQ/models/order_update"
|
73
|
+
require_relative "DhanHQ/models/expired_options_data"
|
69
74
|
|
70
75
|
require_relative "DhanHQ/constants"
|
71
76
|
require_relative "DhanHQ/ws"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: DhanHQ
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shubham Taywade
|
@@ -65,6 +65,20 @@ dependencies:
|
|
65
65
|
- - ">="
|
66
66
|
- !ruby/object:Gem::Version
|
67
67
|
version: '0'
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: csv
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
type: :runtime
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
68
82
|
- !ruby/object:Gem::Dependency
|
69
83
|
name: dry-validation
|
70
84
|
requirement: !ruby/object:Gem::Requirement
|
@@ -162,14 +176,26 @@ files:
|
|
162
176
|
- config/initializers/order_update_hub.rb
|
163
177
|
- diagram.html
|
164
178
|
- diagram.md
|
179
|
+
- docs/live_order_updates.md
|
165
180
|
- docs/rails_integration.md
|
181
|
+
- docs/rails_websocket_integration.md
|
182
|
+
- docs/standalone_ruby_websocket_integration.md
|
166
183
|
- docs/technical_analysis.md
|
184
|
+
- docs/websocket_integration.md
|
185
|
+
- examples/comprehensive_websocket_examples.rb
|
186
|
+
- examples/instrument_finder_test.rb
|
187
|
+
- examples/live_order_updates.rb
|
188
|
+
- examples/market_depth_example.rb
|
189
|
+
- examples/market_feed_example.rb
|
190
|
+
- examples/order_update_example.rb
|
191
|
+
- examples/trading_fields_example.rb
|
167
192
|
- exe/DhanHQ
|
168
193
|
- lib/DhanHQ/client.rb
|
169
194
|
- lib/DhanHQ/config.rb
|
170
195
|
- lib/DhanHQ/configuration.rb
|
171
196
|
- lib/DhanHQ/constants.rb
|
172
197
|
- lib/DhanHQ/contracts/base_contract.rb
|
198
|
+
- lib/DhanHQ/contracts/expired_options_data_contract.rb
|
173
199
|
- lib/DhanHQ/contracts/historical_data_contract.rb
|
174
200
|
- lib/DhanHQ/contracts/instrument_list_contract.rb
|
175
201
|
- lib/DhanHQ/contracts/margin_calculator_contract.rb
|
@@ -180,6 +206,7 @@ files:
|
|
180
206
|
- lib/DhanHQ/contracts/place_order_contract.rb
|
181
207
|
- lib/DhanHQ/contracts/position_conversion_contract.rb
|
182
208
|
- lib/DhanHQ/contracts/slice_order_contract.rb
|
209
|
+
- lib/DhanHQ/contracts/trade_contract.rb
|
183
210
|
- lib/DhanHQ/core/base_api.rb
|
184
211
|
- lib/DhanHQ/core/base_model.rb
|
185
212
|
- lib/DhanHQ/core/base_resource.rb
|
@@ -194,6 +221,7 @@ files:
|
|
194
221
|
- lib/DhanHQ/helpers/validation_helper.rb
|
195
222
|
- lib/DhanHQ/json_loader.rb
|
196
223
|
- lib/DhanHQ/models/edis.rb
|
224
|
+
- lib/DhanHQ/models/expired_options_data.rb
|
197
225
|
- lib/DhanHQ/models/forever_order.rb
|
198
226
|
- lib/DhanHQ/models/funds.rb
|
199
227
|
- lib/DhanHQ/models/historical_data.rb
|
@@ -205,6 +233,7 @@ files:
|
|
205
233
|
- lib/DhanHQ/models/market_feed.rb
|
206
234
|
- lib/DhanHQ/models/option_chain.rb
|
207
235
|
- lib/DhanHQ/models/order.rb
|
236
|
+
- lib/DhanHQ/models/order_update.rb
|
208
237
|
- lib/DhanHQ/models/position.rb
|
209
238
|
- lib/DhanHQ/models/profile.rb
|
210
239
|
- lib/DhanHQ/models/super_order.rb
|
@@ -214,6 +243,7 @@ files:
|
|
214
243
|
- lib/DhanHQ/requests/optionchain/nifty_expiries.json
|
215
244
|
- lib/DhanHQ/requests/orders/create.json
|
216
245
|
- lib/DhanHQ/resources/edis.rb
|
246
|
+
- lib/DhanHQ/resources/expired_options_data.rb
|
217
247
|
- lib/DhanHQ/resources/forever_orders.rb
|
218
248
|
- lib/DhanHQ/resources/funds.rb
|
219
249
|
- lib/DhanHQ/resources/historical_data.rb
|
@@ -231,10 +261,14 @@ files:
|
|
231
261
|
- lib/DhanHQ/resources/trades.rb
|
232
262
|
- lib/DhanHQ/version.rb
|
233
263
|
- lib/DhanHQ/ws.rb
|
264
|
+
- lib/DhanHQ/ws/base_connection.rb
|
234
265
|
- lib/DhanHQ/ws/client.rb
|
235
266
|
- lib/DhanHQ/ws/cmd_bus.rb
|
236
267
|
- lib/DhanHQ/ws/connection.rb
|
237
268
|
- lib/DhanHQ/ws/decoder.rb
|
269
|
+
- lib/DhanHQ/ws/market_depth.rb
|
270
|
+
- lib/DhanHQ/ws/market_depth/client.rb
|
271
|
+
- lib/DhanHQ/ws/market_depth/decoder.rb
|
238
272
|
- lib/DhanHQ/ws/orders.rb
|
239
273
|
- lib/DhanHQ/ws/orders/client.rb
|
240
274
|
- lib/DhanHQ/ws/orders/connection.rb
|