DhanHQ 2.1.7 → 2.1.10
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 +58 -0
- data/examples/comprehensive_websocket_examples.rb +0 -0
- data/examples/instrument_finder_test.rb +0 -0
- data/examples/live_order_updates.rb +1 -1
- data/examples/market_depth_example.rb +2 -2
- data/examples/order_update_example.rb +0 -0
- data/examples/trading_fields_example.rb +1 -1
- data/lib/DhanHQ/client.rb +2 -1
- data/lib/DhanHQ/contracts/expired_options_data_contract.rb +6 -6
- data/lib/DhanHQ/core/base_model.rb +9 -1
- data/lib/DhanHQ/models/edis.rb +150 -14
- data/lib/DhanHQ/models/expired_options_data.rb +307 -82
- data/lib/DhanHQ/models/forever_order.rb +261 -22
- data/lib/DhanHQ/models/funds.rb +76 -10
- data/lib/DhanHQ/models/historical_data.rb +148 -31
- data/lib/DhanHQ/models/holding.rb +82 -6
- data/lib/DhanHQ/models/instrument_helpers.rb +39 -5
- data/lib/DhanHQ/models/kill_switch.rb +113 -11
- data/lib/DhanHQ/models/ledger_entry.rb +101 -13
- data/lib/DhanHQ/models/margin.rb +133 -8
- data/lib/DhanHQ/models/market_feed.rb +181 -17
- data/lib/DhanHQ/models/option_chain.rb +184 -12
- data/lib/DhanHQ/models/order.rb +399 -34
- data/lib/DhanHQ/models/position.rb +161 -10
- data/lib/DhanHQ/models/profile.rb +103 -7
- data/lib/DhanHQ/models/super_order.rb +275 -15
- data/lib/DhanHQ/models/trade.rb +279 -26
- data/lib/DhanHQ/rate_limiter.rb +78 -23
- data/lib/DhanHQ/resources/expired_options_data.rb +1 -1
- data/lib/DhanHQ/version.rb +1 -1
- data/lib/DhanHQ/ws/market_depth/client.rb +3 -1
- data/lib/DhanHQ/ws/orders/client.rb +2 -1
- data/lib/DhanHQ/ws/orders/connection.rb +0 -3
- data/lib/DhanHQ/ws/orders.rb +2 -1
- metadata +1 -1
|
@@ -4,22 +4,151 @@ require_relative "../contracts/option_chain_contract"
|
|
|
4
4
|
|
|
5
5
|
module DhanHQ
|
|
6
6
|
module Models
|
|
7
|
-
|
|
7
|
+
##
|
|
8
|
+
# Model for fetching option chain data for any option instrument across exchanges.
|
|
9
|
+
#
|
|
10
|
+
# The Option Chain API provides the entire option chain for any underlying instrument
|
|
11
|
+
# across NSE, BSE, and MCX exchanges. For each strike price, you get Open Interest (OI),
|
|
12
|
+
# Greeks (Delta, Theta, Gamma, Vega), Volume, Last Traded Price, Best Bid/Ask prices,
|
|
13
|
+
# Implied Volatility (IV), and other option analytics.
|
|
14
|
+
#
|
|
15
|
+
# @note **Rate Limits**: You can call the Option Chain API once every 3 seconds.
|
|
16
|
+
# This rate limit is enforced because OI data updates slowly compared to LTP or
|
|
17
|
+
# other data parameters. The client's internal rate limiter automatically throttles
|
|
18
|
+
# calls to prevent exceeding limits.
|
|
19
|
+
#
|
|
20
|
+
# @note **Data Filtering**: The model automatically filters out strikes where both
|
|
21
|
+
# Call (CE) and Put (PE) options have zero `last_price`, keeping the payload compact
|
|
22
|
+
# and focused on actively traded strikes.
|
|
23
|
+
#
|
|
24
|
+
# @example Fetch option chain for NIFTY index options
|
|
25
|
+
# chain = DhanHQ::Models::OptionChain.fetch(
|
|
26
|
+
# underlying_scrip: 13,
|
|
27
|
+
# underlying_seg: "IDX_I",
|
|
28
|
+
# expiry: "2024-10-31"
|
|
29
|
+
# )
|
|
30
|
+
# puts "Underlying LTP: ₹#{chain[:last_price]}"
|
|
31
|
+
# nifty_25000 = chain[:oc]["25000.000000"]
|
|
32
|
+
# puts "CE LTP: ₹#{nifty_25000['ce'][:last_price]}"
|
|
33
|
+
# puts "CE OI: #{nifty_25000['ce'][:oi]}"
|
|
34
|
+
#
|
|
35
|
+
# @example Fetch expiry list for an underlying
|
|
36
|
+
# expiries = DhanHQ::Models::OptionChain.fetch_expiry_list(
|
|
37
|
+
# underlying_scrip: 13,
|
|
38
|
+
# underlying_seg: "IDX_I"
|
|
39
|
+
# )
|
|
40
|
+
# expiries.each { |expiry| puts expiry }
|
|
41
|
+
#
|
|
42
|
+
# @example Access Greeks for a strike
|
|
43
|
+
# chain = DhanHQ::Models::OptionChain.fetch(
|
|
44
|
+
# underlying_scrip: 1333,
|
|
45
|
+
# underlying_seg: "NSE_FNO",
|
|
46
|
+
# expiry: "2024-12-26"
|
|
47
|
+
# )
|
|
48
|
+
# strike_data = chain[:oc]["25000.000000"]
|
|
49
|
+
# ce_greeks = strike_data['ce'][:greeks]
|
|
50
|
+
# puts "Delta: #{ce_greeks[:delta]}"
|
|
51
|
+
# puts "Gamma: #{ce_greeks[:gamma]}"
|
|
52
|
+
# puts "Theta: #{ce_greeks[:theta]}"
|
|
53
|
+
# puts "Vega: #{ce_greeks[:vega]}"
|
|
54
|
+
#
|
|
8
55
|
class OptionChain < BaseModel
|
|
9
56
|
attr_reader :underlying_scrip, :underlying_seg, :expiry, :last_price, :option_data
|
|
10
57
|
|
|
11
58
|
class << self
|
|
12
|
-
|
|
59
|
+
##
|
|
60
|
+
# Provides a shared instance of the OptionChain resource.
|
|
13
61
|
#
|
|
14
|
-
# @return [DhanHQ::Resources::OptionChain]
|
|
62
|
+
# @return [DhanHQ::Resources::OptionChain] The OptionChain resource client instance
|
|
15
63
|
def resource
|
|
16
64
|
@resource ||= DhanHQ::Resources::OptionChain.new
|
|
17
65
|
end
|
|
18
66
|
|
|
19
|
-
|
|
67
|
+
##
|
|
68
|
+
# Fetches the entire option chain for a specified underlying instrument and expiry.
|
|
20
69
|
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
70
|
+
# Retrieves real-time option chain data across all strikes for the given underlying.
|
|
71
|
+
# The response includes Open Interest (OI), Greeks, Volume, Last Traded Price,
|
|
72
|
+
# Best Bid/Ask prices, Implied Volatility (IV), and other option analytics for
|
|
73
|
+
# both Call (CE) and Put (PE) options at each strike price.
|
|
74
|
+
#
|
|
75
|
+
# @param params [Hash{Symbol => Integer, String}] Request parameters for option chain
|
|
76
|
+
# @option params [Integer] :underlying_scrip (required) Security ID of the underlying
|
|
77
|
+
# instrument. Can be found via the Instruments API.
|
|
78
|
+
# @option params [String] :underlying_seg (required) Exchange and segment of underlying
|
|
79
|
+
# for which data is to be fetched.
|
|
80
|
+
# Valid values: "IDX_I" (Index), "NSE_FNO" (NSE F&O), "BSE_FNO" (BSE F&O), "MCX_FO" (MCX)
|
|
81
|
+
# @option params [String] :expiry (required) Expiry date of the option contract for
|
|
82
|
+
# which the option chain is requested. Must be in "YYYY-MM-DD" format.
|
|
83
|
+
# List of active expiries can be fetched using {fetch_expiry_list}.
|
|
84
|
+
#
|
|
85
|
+
# @return [HashWithIndifferentAccess] Filtered option chain data.
|
|
86
|
+
# Response structure:
|
|
87
|
+
# - **:last_price** [Float] Last Traded Price (LTP) of the underlying instrument
|
|
88
|
+
# - **:oc** [Hash{String => Hash}] Option chain data organized by strike price.
|
|
89
|
+
# Strike prices are stored as string keys (e.g., "25000.000000").
|
|
90
|
+
# Each strike contains:
|
|
91
|
+
# - **"ce"** [Hash{Symbol => Float, Integer, Hash}] Call Option data for this strike:
|
|
92
|
+
# - **:greeks** [Hash{Symbol => Float}] Option Greeks:
|
|
93
|
+
# - **:delta** [Float] Measures the change of option's premium based on
|
|
94
|
+
# every 1 rupee change in underlying
|
|
95
|
+
# - **:theta** [Float] Measures how quickly an option's value decreases over time
|
|
96
|
+
# - **:gamma** [Float] Rate of change in an option's delta in relation to the
|
|
97
|
+
# price of the underlying asset
|
|
98
|
+
# - **:vega** [Float] Measures the change of option's premium in response to
|
|
99
|
+
# a 1% change in implied volatility
|
|
100
|
+
# - **:implied_volatility** [Float] Value of expected volatility of a stock
|
|
101
|
+
# over the life of the option
|
|
102
|
+
# - **:last_price** [Float] Last Traded Price of the Call Option Instrument
|
|
103
|
+
# - **:oi** [Integer] Open Interest of the Call Option Instrument
|
|
104
|
+
# - **:previous_close_price** [Float] Previous day close price
|
|
105
|
+
# - **:previous_oi** [Integer] Previous day Open Interest
|
|
106
|
+
# - **:previous_volume** [Integer] Previous day volume
|
|
107
|
+
# - **:top_ask_price** [Float] Current best ask price available
|
|
108
|
+
# - **:top_ask_quantity** [Integer] Quantity available at current best ask price
|
|
109
|
+
# - **:top_bid_price** [Float] Current best bid price available
|
|
110
|
+
# - **:top_bid_quantity** [Integer] Quantity available at current best bid price
|
|
111
|
+
# - **:volume** [Integer] Day volume for Call Option Instrument
|
|
112
|
+
# - **"pe"** [Hash{Symbol => Float, Integer, Hash}] Put Option data for this strike.
|
|
113
|
+
# Contains the same fields as "ce" (Call Option data).
|
|
114
|
+
#
|
|
115
|
+
# @note Strikes where both CE and PE have zero `last_price` are automatically filtered out.
|
|
116
|
+
# This keeps the payload compact and focused on actively traded strikes.
|
|
117
|
+
#
|
|
118
|
+
# @example Fetch option chain for NIFTY index options
|
|
119
|
+
# chain = DhanHQ::Models::OptionChain.fetch(
|
|
120
|
+
# underlying_scrip: 13,
|
|
121
|
+
# underlying_seg: "IDX_I",
|
|
122
|
+
# expiry: "2024-10-31"
|
|
123
|
+
# )
|
|
124
|
+
# puts "NIFTY LTP: ₹#{chain[:last_price]}"
|
|
125
|
+
#
|
|
126
|
+
# @example Access Call and Put data for a specific strike
|
|
127
|
+
# chain = DhanHQ::Models::OptionChain.fetch(
|
|
128
|
+
# underlying_scrip: 13,
|
|
129
|
+
# underlying_seg: "IDX_I",
|
|
130
|
+
# expiry: "2024-10-31"
|
|
131
|
+
# )
|
|
132
|
+
# strike_25000 = chain[:oc]["25000.000000"]
|
|
133
|
+
# ce_data = strike_25000["ce"]
|
|
134
|
+
# pe_data = strike_25000["pe"]
|
|
135
|
+
# puts "CE LTP: ₹#{ce_data[:last_price]}, OI: #{ce_data[:oi]}"
|
|
136
|
+
# puts "PE LTP: ₹#{pe_data[:last_price]}, OI: #{pe_data[:oi]}"
|
|
137
|
+
#
|
|
138
|
+
# @example Calculate OI change and analyze Greeks
|
|
139
|
+
# chain = DhanHQ::Models::OptionChain.fetch(
|
|
140
|
+
# underlying_scrip: 1333,
|
|
141
|
+
# underlying_seg: "NSE_FNO",
|
|
142
|
+
# expiry: "2024-12-26"
|
|
143
|
+
# )
|
|
144
|
+
# strike_data = chain[:oc]["25000.000000"]
|
|
145
|
+
# ce = strike_data["ce"]
|
|
146
|
+
# oi_change = ce[:oi] - ce[:previous_oi]
|
|
147
|
+
# puts "OI Change: #{oi_change}"
|
|
148
|
+
# puts "Delta: #{ce[:greeks][:delta]}"
|
|
149
|
+
# puts "IV: #{ce[:implied_volatility]}%"
|
|
150
|
+
#
|
|
151
|
+
# @raise [DhanHQ::ValidationError] If validation fails for any parameter or date format
|
|
23
152
|
def fetch(params)
|
|
24
153
|
validate_params!(params, DhanHQ::Contracts::OptionChainContract)
|
|
25
154
|
|
|
@@ -29,10 +158,44 @@ module DhanHQ
|
|
|
29
158
|
filter_valid_strikes(response[:data]).with_indifferent_access
|
|
30
159
|
end
|
|
31
160
|
|
|
32
|
-
|
|
161
|
+
##
|
|
162
|
+
# Fetches the list of active expiry dates for an underlying instrument.
|
|
33
163
|
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
164
|
+
# Retrieves all expiry dates for which option instruments are active for the given
|
|
165
|
+
# underlying. This list is useful for selecting valid expiry dates when fetching
|
|
166
|
+
# option chains.
|
|
167
|
+
#
|
|
168
|
+
# @param params [Hash{Symbol => Integer, String}] Request parameters for expiry list
|
|
169
|
+
# @option params [Integer] :underlying_scrip (required) Security ID of the underlying
|
|
170
|
+
# instrument. Can be found via the Instruments API.
|
|
171
|
+
# @option params [String] :underlying_seg (required) Exchange and segment of underlying
|
|
172
|
+
# for which expiry list is to be fetched.
|
|
173
|
+
# Valid values: "IDX_I" (Index), "NSE_FNO" (NSE F&O), "BSE_FNO" (BSE F&O), "MCX_FO" (MCX)
|
|
174
|
+
#
|
|
175
|
+
# @return [Array<String>] Array of expiry dates in "YYYY-MM-DD" format.
|
|
176
|
+
# Returns empty array if the API response status is not "success" or if no expiries are found.
|
|
177
|
+
#
|
|
178
|
+
# @example Fetch expiry list for NIFTY index
|
|
179
|
+
# expiries = DhanHQ::Models::OptionChain.fetch_expiry_list(
|
|
180
|
+
# underlying_scrip: 13,
|
|
181
|
+
# underlying_seg: "IDX_I"
|
|
182
|
+
# )
|
|
183
|
+
# puts "Available expiries:"
|
|
184
|
+
# expiries.each { |expiry| puts " #{expiry}" }
|
|
185
|
+
#
|
|
186
|
+
# @example Use expiry list to fetch option chains
|
|
187
|
+
# expiries = DhanHQ::Models::OptionChain.fetch_expiry_list(
|
|
188
|
+
# underlying_scrip: 1333,
|
|
189
|
+
# underlying_seg: "NSE_FNO"
|
|
190
|
+
# )
|
|
191
|
+
# nearest_expiry = expiries.first
|
|
192
|
+
# chain = DhanHQ::Models::OptionChain.fetch(
|
|
193
|
+
# underlying_scrip: 1333,
|
|
194
|
+
# underlying_seg: "NSE_FNO",
|
|
195
|
+
# expiry: nearest_expiry
|
|
196
|
+
# )
|
|
197
|
+
#
|
|
198
|
+
# @raise [DhanHQ::ValidationError] If validation fails for any parameter
|
|
36
199
|
def fetch_expiry_list(params)
|
|
37
200
|
validate_params!(params, DhanHQ::Contracts::OptionChainExpiryListContract)
|
|
38
201
|
|
|
@@ -42,10 +205,17 @@ module DhanHQ
|
|
|
42
205
|
|
|
43
206
|
private
|
|
44
207
|
|
|
45
|
-
|
|
208
|
+
##
|
|
209
|
+
# Filters valid strikes where at least one of CE or PE has a non-zero last_price.
|
|
210
|
+
#
|
|
211
|
+
# Removes strikes from the option chain where both Call (CE) and Put (PE) options
|
|
212
|
+
# have zero `last_price`, keeping only actively traded strikes. This keeps the
|
|
213
|
+
# payload compact and focused on relevant data.
|
|
214
|
+
#
|
|
215
|
+
# @param data [Hash] The API response data containing option chain information
|
|
216
|
+
# @return [Hash] The filtered option chain data with original strike price keys preserved
|
|
46
217
|
#
|
|
47
|
-
# @
|
|
48
|
-
# @return [Hash] The filtered option chain data with original strike price keys
|
|
218
|
+
# @api private
|
|
49
219
|
def filter_valid_strikes(data)
|
|
50
220
|
return {} unless data.is_a?(Hash) && data.key?(:oc)
|
|
51
221
|
|
|
@@ -63,6 +233,7 @@ module DhanHQ
|
|
|
63
233
|
# Validation contract for option chain
|
|
64
234
|
#
|
|
65
235
|
# @return [DhanHQ::Contracts::OptionChainContract]
|
|
236
|
+
# @api private
|
|
66
237
|
def validation_contract
|
|
67
238
|
DhanHQ::Contracts::OptionChainContract.new
|
|
68
239
|
end
|
|
@@ -73,6 +244,7 @@ module DhanHQ
|
|
|
73
244
|
# Validation contract for option chain
|
|
74
245
|
#
|
|
75
246
|
# @return [DhanHQ::Contracts::OptionChainContract]
|
|
247
|
+
# @api private
|
|
76
248
|
def validation_contract
|
|
77
249
|
DhanHQ::Contracts::OptionChainContract.new
|
|
78
250
|
end
|