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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +58 -0
  3. data/examples/comprehensive_websocket_examples.rb +0 -0
  4. data/examples/instrument_finder_test.rb +0 -0
  5. data/examples/live_order_updates.rb +1 -1
  6. data/examples/market_depth_example.rb +2 -2
  7. data/examples/order_update_example.rb +0 -0
  8. data/examples/trading_fields_example.rb +1 -1
  9. data/lib/DhanHQ/client.rb +2 -1
  10. data/lib/DhanHQ/contracts/expired_options_data_contract.rb +6 -6
  11. data/lib/DhanHQ/core/base_model.rb +9 -1
  12. data/lib/DhanHQ/models/edis.rb +150 -14
  13. data/lib/DhanHQ/models/expired_options_data.rb +307 -82
  14. data/lib/DhanHQ/models/forever_order.rb +261 -22
  15. data/lib/DhanHQ/models/funds.rb +76 -10
  16. data/lib/DhanHQ/models/historical_data.rb +148 -31
  17. data/lib/DhanHQ/models/holding.rb +82 -6
  18. data/lib/DhanHQ/models/instrument_helpers.rb +39 -5
  19. data/lib/DhanHQ/models/kill_switch.rb +113 -11
  20. data/lib/DhanHQ/models/ledger_entry.rb +101 -13
  21. data/lib/DhanHQ/models/margin.rb +133 -8
  22. data/lib/DhanHQ/models/market_feed.rb +181 -17
  23. data/lib/DhanHQ/models/option_chain.rb +184 -12
  24. data/lib/DhanHQ/models/order.rb +399 -34
  25. data/lib/DhanHQ/models/position.rb +161 -10
  26. data/lib/DhanHQ/models/profile.rb +103 -7
  27. data/lib/DhanHQ/models/super_order.rb +275 -15
  28. data/lib/DhanHQ/models/trade.rb +279 -26
  29. data/lib/DhanHQ/rate_limiter.rb +78 -23
  30. data/lib/DhanHQ/resources/expired_options_data.rb +1 -1
  31. data/lib/DhanHQ/version.rb +1 -1
  32. data/lib/DhanHQ/ws/market_depth/client.rb +3 -1
  33. data/lib/DhanHQ/ws/orders/client.rb +2 -1
  34. data/lib/DhanHQ/ws/orders/connection.rb +0 -3
  35. data/lib/DhanHQ/ws/orders.rb +2 -1
  36. metadata +1 -1
@@ -3,34 +3,98 @@
3
3
  module DhanHQ
4
4
  module Models
5
5
  ##
6
- # Represents a single row/entry in the Ledger.
7
- # Ledger data typically returns an array of these objects.
6
+ # Model representing a single ledger entry in the Trading Account Ledger Report.
7
+ #
8
+ # The Ledger Report contains all credit and debit transaction details for a particular time interval.
9
+ # Each entry represents a single transaction with details such as narration, voucher information,
10
+ # debit/credit amounts, and running balance.
11
+ #
12
+ # @example Fetch ledger entries for a date range
13
+ # entries = DhanHQ::Models::LedgerEntry.all(
14
+ # from_date: "2024-04-01",
15
+ # to_date: "2024-04-30"
16
+ # )
17
+ # entries.each do |entry|
18
+ # puts "#{entry.voucherdate}: #{entry.narration} - #{entry.debit} / #{entry.credit}"
19
+ # end
20
+ #
21
+ # @example Calculate total credits and debits
22
+ # entries = DhanHQ::Models::LedgerEntry.all(
23
+ # from_date: "2024-04-01",
24
+ # to_date: "2024-04-30"
25
+ # )
26
+ # total_debits = entries.sum { |e| e.debit.to_f }
27
+ # total_credits = entries.sum { |e| e.credit.to_f }
28
+ #
8
29
  class LedgerEntry < BaseModel
9
- # The endpoint is /v2/ledger?from-date=...&to-date=...
10
- # So we may define a resource path or rely on the Statements resource.
30
+ # Base path for ledger endpoint.
11
31
  HTTP_PATH = "/v2/ledger"
12
32
 
13
- # Typical fields from API docs
14
33
  attributes :dhan_client_id, :narration, :voucherdate, :exchange,
15
34
  :voucherdesc, :vouchernumber, :debit, :credit, :runbal
16
35
 
17
36
  class << self
18
37
  ##
19
- # Provides a **shared instance** of the `Statements` resource.
38
+ # Provides a shared instance of the Statements resource.
20
39
  #
21
- # @return [DhanHQ::Resources::Statements]
40
+ # @return [DhanHQ::Resources::Statements] The Statements resource client instance
22
41
  def resource
23
42
  @resource ||= DhanHQ::Resources::Statements.new
24
43
  end
25
44
 
26
45
  ##
27
- # Fetch ledger entries for the given date range.
46
+ # Retrieves Trading Account Ledger Report entries for the specified date range.
28
47
  #
29
- # @param from_date [String] e.g. "2023-01-01"
30
- # @param to_date [String] e.g. "2023-01-31"
31
- # @return [Array<LedgerEntry>]
48
+ # Fetches all credit and debit transaction details for the given time interval.
49
+ # The ledger entries include transaction descriptions, voucher information, amounts,
50
+ # and running balances.
51
+ #
52
+ # @param from_date [String] Start date of the ledger report in YYYY-MM-DD format.
53
+ # Example: "2024-04-01"
54
+ # @param to_date [String] End date of the ledger report in YYYY-MM-DD format.
55
+ # Example: "2024-04-30"
56
+ #
57
+ # @return [Array<LedgerEntry>] Array of LedgerEntry objects. Returns empty array if no entries exist.
58
+ # Each LedgerEntry object contains (keys normalized to snake_case):
59
+ # - **:dhan_client_id** [String] User-specific identification generated by Dhan
60
+ # - **:narration** [String] Description of the ledger transaction (e.g., "FUNDS WITHDRAWAL", "CLOSING BALANCE")
61
+ # - **:voucherdate** [String] Transaction date in format "Mon DD, YYYY" (e.g., "Jun 22, 2022")
62
+ # - **:exchange** [String] Exchange information for the transaction (e.g., "NSE-CAPITAL", "NSE_CASH")
63
+ # - **:voucherdesc** [String] Nature of transaction (e.g., "PAYBNK", "CLOSING BALANCE", "OPENING BALANCE")
64
+ # - **:vouchernumber** [String] System generated transaction number. May be empty string for balance entries
65
+ # - **:debit** [String] Debit amount as string. Only populated when credit returns "0.00"
66
+ # - **:credit** [String] Credit amount as string. Only populated when debit returns "0.00"
67
+ # - **:runbal** [String] Running balance post transaction as string
68
+ #
69
+ # @example Fetch ledger entries for a month
70
+ # entries = DhanHQ::Models::LedgerEntry.all(
71
+ # from_date: "2024-04-01",
72
+ # to_date: "2024-04-30"
73
+ # )
74
+ # entries.each do |entry|
75
+ # puts "#{entry.voucherdate}: #{entry.narration} - Balance: #{entry.runbal}"
76
+ # end
77
+ #
78
+ # @example Filter entries by transaction type
79
+ # entries = DhanHQ::Models::LedgerEntry.all(
80
+ # from_date: "2024-04-01",
81
+ # to_date: "2024-04-30"
82
+ # )
83
+ # withdrawals = entries.select { |e| e.voucherdesc == "PAYBNK" }
84
+ # puts "Total withdrawals: #{withdrawals.size}"
85
+ #
86
+ # @example Calculate net balance change
87
+ # entries = DhanHQ::Models::LedgerEntry.all(
88
+ # from_date: "2024-04-01",
89
+ # to_date: "2024-04-30"
90
+ # )
91
+ # net_change = entries.sum { |e| e.credit.to_f - e.debit.to_f }
92
+ # puts "Net change: ₹#{net_change}"
93
+ #
94
+ # @note This is a GET request with query parameters. No body required.
95
+ # @note The ledger report represents historical data dumps and entries are returned as-is
96
+ # without additional validation.
32
97
  def all(from_date:, to_date:)
33
- # The resource call returns an Array<Hash>, according to the docs.
34
98
  response = resource.ledger(from_date: from_date, to_date: to_date)
35
99
 
36
100
  return [] unless response.is_a?(Array)
@@ -41,7 +105,31 @@ module DhanHQ
41
105
  end
42
106
  end
43
107
 
44
- # Optional: you can override #to_h or #inspect if you want a custom representation
108
+ ##
109
+ # Converts the LedgerEntry model attributes to a hash representation.
110
+ #
111
+ # Useful for serialization, logging, or passing ledger entry data to other methods.
112
+ #
113
+ # @return [Hash{Symbol => String}] Hash representation of the LedgerEntry model containing:
114
+ # - **:dhan_client_id** [String] User-specific identification
115
+ # - **:narration** [String] Transaction description
116
+ # - **:voucherdate** [String] Transaction date
117
+ # - **:exchange** [String] Exchange information
118
+ # - **:voucherdesc** [String] Nature of transaction
119
+ # - **:vouchernumber** [String] Transaction number
120
+ # - **:debit** [String] Debit amount
121
+ # - **:credit** [String] Credit amount
122
+ # - **:runbal** [String] Running balance
123
+ #
124
+ # @example Convert entry to hash
125
+ # entry = DhanHQ::Models::LedgerEntry.all(
126
+ # from_date: "2024-04-01",
127
+ # to_date: "2024-04-30"
128
+ # ).first
129
+ # entry_hash = entry.to_h
130
+ # puts entry_hash[:narration] # => "FUNDS WITHDRAWAL"
131
+ # puts entry_hash[:runbal] # => "957.29"
132
+ #
45
133
  def to_h
46
134
  {
47
135
  dhan_client_id: dhan_client_id,
@@ -2,7 +2,47 @@
2
2
 
3
3
  module DhanHQ
4
4
  module Models
5
- # Model for the on-demand margin calculator response.
5
+ ##
6
+ # Model for fetching margin calculation results for orders.
7
+ #
8
+ # The Margin Calculator API provides span margin, exposure margin, VAR (variable margin),
9
+ # brokerage, leverage, and available margin values for any type of order and instrument
10
+ # you want to place. This helps you determine the margin requirements before placing an order.
11
+ #
12
+ # @example Calculate margin for a CNC order
13
+ # margin = DhanHQ::Models::Margin.calculate(
14
+ # dhan_client_id: "1000000132",
15
+ # exchange_segment: "NSE_EQ",
16
+ # transaction_type: "BUY",
17
+ # quantity: 5,
18
+ # product_type: "CNC",
19
+ # security_id: "1333",
20
+ # price: 1428.0
21
+ # )
22
+ # puts "Total margin required: ₹#{margin.total_margin}"
23
+ # puts "Available balance: ₹#{margin.available_balance}"
24
+ #
25
+ # @example Calculate margin for stop-loss order
26
+ # margin = DhanHQ::Models::Margin.calculate(
27
+ # dhan_client_id: "1000000132",
28
+ # exchange_segment: "NSE_EQ",
29
+ # transaction_type: "BUY",
30
+ # quantity: 10,
31
+ # product_type: "INTRADAY",
32
+ # security_id: "1333",
33
+ # price: 1428.0,
34
+ # trigger_price: 1427.0
35
+ # )
36
+ # puts "Leverage: #{margin.leverage}x"
37
+ #
38
+ # @example Check if sufficient margin is available
39
+ # margin = DhanHQ::Models::Margin.calculate(params)
40
+ # if margin.insufficient_balance > 0
41
+ # puts "Insufficient balance: ₹#{margin.insufficient_balance}"
42
+ # else
43
+ # puts "Sufficient margin available"
44
+ # end
45
+ #
6
46
  class Margin < BaseModel
7
47
  # Base path used to invoke the calculator.
8
48
  HTTP_PATH = "/v2/margincalculator"
@@ -12,18 +52,86 @@ module DhanHQ
12
52
 
13
53
  class << self
14
54
  ##
15
- # Provides a **shared instance** of the `MarginCalculator` resource.
55
+ # Provides a shared instance of the MarginCalculator resource.
16
56
  #
17
- # @return [DhanHQ::Resources::MarginCalculator]
57
+ # @return [DhanHQ::Resources::MarginCalculator] The MarginCalculator resource client instance
18
58
  def resource
19
59
  @resource ||= DhanHQ::Resources::MarginCalculator.new
20
60
  end
21
61
 
22
62
  ##
23
- # Calculate margin requirements for an order.
63
+ # Calculates margin requirements for an order before placement.
24
64
  #
25
- # @param params [Hash] Request parameters for margin calculation.
26
- # @return [Margin]
65
+ # Fetches span margin, exposure margin, VAR (variable margin), brokerage, leverage,
66
+ # and available margin values for the specified order parameters. This allows you to
67
+ # check margin requirements and availability before actually placing the order.
68
+ #
69
+ # @param params [Hash{Symbol => String, Integer, Float}] Request parameters for margin calculation
70
+ # @option params [String] :dhan_client_id (required) User-specific identification generated by Dhan.
71
+ # Must be explicitly provided in the params hash
72
+ # @option params [String] :exchange_segment (required) Exchange and segment identifier.
73
+ # Valid values: "NSE_EQ", "NSE_FNO", "BSE_EQ", "BSE_FNO", "MCX_COMM"
74
+ # @option params [String] :transaction_type (required) The trading side of transaction.
75
+ # Valid values: "BUY", "SELL"
76
+ # @option params [Integer] :quantity (required) Number of shares for the order. Must be greater than 0
77
+ # @option params [String] :product_type (required) Product type.
78
+ # Valid values: "CNC", "INTRADAY", "MARGIN", "MTF", "CO", "BO"
79
+ # @option params [String] :security_id (required) Exchange standard ID for each scrip
80
+ # @option params [Float] :price (required) Price at which order is placed. Must be greater than 0
81
+ # @option params [Float] :trigger_price (conditionally required) Price at which the order is triggered.
82
+ # Required for STOP_LOSS and STOP_LOSS_MARKET order types
83
+ #
84
+ # @return [Margin] Margin object containing margin calculation results.
85
+ # Response structure (keys normalized to snake_case):
86
+ # - **:total_margin** [Float] Total margin required for placing the order successfully
87
+ # - **:span_margin** [Float] SPAN margin required
88
+ # - **:exposure_margin** [Float] Exposure margin required
89
+ # - **:available_balance** [Float] Available amount in trading account
90
+ # - **:variable_margin** [Float] VAR or Variable margin required
91
+ # - **:insufficient_balance** [Float] Insufficient amount in trading account
92
+ # (Available Balance - Total Margin). Negative or zero indicates sufficient margin
93
+ # - **:brokerage** [Float] Brokerage charges for executing the order
94
+ # - **:leverage** [String] Margin leverage provided for the order as per product type
95
+ #
96
+ # @example Calculate margin for CNC equity order
97
+ # margin = DhanHQ::Models::Margin.calculate(
98
+ # dhan_client_id: "1000000132",
99
+ # exchange_segment: "NSE_EQ",
100
+ # transaction_type: "BUY",
101
+ # quantity: 5,
102
+ # product_type: "CNC",
103
+ # security_id: "1333",
104
+ # price: 1428.0
105
+ # )
106
+ # puts "Total Margin: ₹#{margin.total_margin}"
107
+ # puts "Brokerage: ₹#{margin.brokerage}"
108
+ #
109
+ # @example Calculate margin for intraday order
110
+ # margin = DhanHQ::Models::Margin.calculate(
111
+ # dhan_client_id: "1000000132",
112
+ # exchange_segment: "NSE_EQ",
113
+ # transaction_type: "SELL",
114
+ # quantity: 10,
115
+ # product_type: "INTRADAY",
116
+ # security_id: "1333",
117
+ # price: 1500.0
118
+ # )
119
+ # puts "Leverage: #{margin.leverage}x"
120
+ # puts "SPAN Margin: ₹#{margin.span_margin}"
121
+ #
122
+ # @example Calculate margin for stop-loss order
123
+ # margin = DhanHQ::Models::Margin.calculate(
124
+ # dhan_client_id: "1000000132",
125
+ # exchange_segment: "NSE_EQ",
126
+ # transaction_type: "BUY",
127
+ # quantity: 5,
128
+ # product_type: "INTRADAY",
129
+ # security_id: "1333",
130
+ # price: 1428.0,
131
+ # trigger_price: 1427.0
132
+ # )
133
+ #
134
+ # @raise [DhanHQ::ValidationError] If validation fails for any parameter
27
135
  def calculate(params)
28
136
  formatted_params = camelize_keys(params)
29
137
  validate_params!(formatted_params, DhanHQ::Contracts::MarginCalculatorContract)
@@ -34,9 +142,26 @@ module DhanHQ
34
142
  end
35
143
 
36
144
  ##
37
- # Convert model attributes to a hash.
145
+ # Converts the Margin model attributes to a hash representation.
146
+ #
147
+ # Useful for serialization, logging, or passing margin data to other methods.
148
+ #
149
+ # @return [Hash{Symbol => Float, String}] Hash representation of the Margin model containing:
150
+ # - **:total_margin** [Float] Total margin required
151
+ # - **:span_margin** [Float] SPAN margin
152
+ # - **:exposure_margin** [Float] Exposure margin
153
+ # - **:available_balance** [Float] Available balance
154
+ # - **:variable_margin** [Float] Variable margin
155
+ # - **:insufficient_balance** [Float] Insufficient balance amount
156
+ # - **:brokerage** [Float] Brokerage charges
157
+ # - **:leverage** [String] Leverage as string
158
+ #
159
+ # @example Convert margin to hash
160
+ # margin = DhanHQ::Models::Margin.calculate(params)
161
+ # margin_hash = margin.to_h
162
+ # puts margin_hash[:total_margin] # => 2800.00
163
+ # puts margin_hash[:leverage] # => "4.00"
38
164
  #
39
- # @return [Hash] Hash representation of the Margin model.
40
165
  def to_h
41
166
  {
42
167
  total_margin: total_margin,
@@ -2,39 +2,203 @@
2
2
 
3
3
  module DhanHQ
4
4
  module Models
5
- # Lightweight wrapper exposing market feed resources.
5
+ ##
6
+ # Model for fetching real-time market snapshots for multiple instruments.
7
+ #
8
+ # The Market Feed API provides snapshots of multiple instruments at once. You can fetch
9
+ # LTP (Last Traded Price), OHLC (Open, High, Low, Close), or Market Depth (quote) data
10
+ # for instruments via a single API request. Data is returned in real-time at the time
11
+ # of the API request.
12
+ #
13
+ # @note **Rate Limits**: You can fetch up to 1000 instruments in a single API request
14
+ # with a rate limit of 1 request per second. The client's internal rate limiter
15
+ # automatically throttles calls to prevent exceeding limits.
16
+ #
17
+ # @example Fetch LTP for multiple instruments
18
+ # payload = {
19
+ # "NSE_EQ" => [11536, 3456],
20
+ # "NSE_FNO" => [49081, 49082]
21
+ # }
22
+ # response = DhanHQ::Models::MarketFeed.ltp(payload)
23
+ # nse_eq_data = response[:data]["NSE_EQ"]
24
+ # puts "TCS LTP: ₹#{nse_eq_data["11536"][:last_price]}"
25
+ #
26
+ # @example Fetch OHLC data for equity instruments
27
+ # payload = {
28
+ # "NSE_EQ" => [11536]
29
+ # }
30
+ # response = DhanHQ::Models::MarketFeed.ohlc(payload)
31
+ # tcs_data = response[:data]["NSE_EQ"]["11536"]
32
+ # puts "Open: ₹#{tcs_data[:ohlc][:open]}"
33
+ # puts "High: ₹#{tcs_data[:ohlc][:high]}"
34
+ #
35
+ # @example Fetch full market depth quote
36
+ # payload = {
37
+ # "NSE_FNO" => [49081]
38
+ # }
39
+ # response = DhanHQ::Models::MarketFeed.quote(payload)
40
+ # quote_data = response[:data]["NSE_FNO"]["49081"]
41
+ # puts "Volume: #{quote_data[:volume]}"
42
+ # puts "Open Interest: #{quote_data[:oi]}"
43
+ #
6
44
  class MarketFeed < BaseModel
7
45
  class << self
8
- # Fetches last traded price snapshots.
46
+ ##
47
+ # Provides a shared instance of the MarketFeed resource.
48
+ #
49
+ # @return [DhanHQ::Resources::MarketFeed] The MarketFeed resource client instance
50
+ def resource
51
+ @resource ||= DhanHQ::Resources::MarketFeed.new
52
+ end
53
+
54
+ ##
55
+ # Fetches Last Traded Price (LTP) snapshots for multiple instruments.
56
+ #
57
+ # Retrieves the last traded price for a list of instruments with a single API request.
58
+ # Supports up to 1000 instruments per request, organized by exchange segment.
59
+ #
60
+ # @param params [Hash{String => Array<Integer>}] Request payload mapping exchange segments
61
+ # to arrays of security IDs. Exchange segments are keys (e.g., "NSE_EQ", "NSE_FNO", "BSE_EQ").
62
+ # Values are arrays of security IDs (integer identifiers for each scrip).
63
+ # Valid exchange segment values: "NSE_EQ", "NSE_FNO", "BSE_EQ", "BSE_FNO", etc.
64
+ #
65
+ # @return [HashWithIndifferentAccess] Response hash containing market data.
66
+ # Response structure:
67
+ # - **:data** [Hash{String => Hash{String => Hash}}] Market data organized by exchange segment
68
+ # and security ID. Each instrument's data contains:
69
+ # - **:last_price** [Float] Last traded price of the instrument
70
+ # - **:status** [String] Response status (typically "success")
71
+ #
72
+ # @example Fetch LTP for equity and F&O instruments
73
+ # payload = {
74
+ # "NSE_EQ" => [11536],
75
+ # "NSE_FNO" => [49081, 49082]
76
+ # }
77
+ # response = DhanHQ::Models::MarketFeed.ltp(payload)
78
+ # tcs_ltp = response[:data]["NSE_EQ"]["11536"][:last_price]
79
+ # puts "TCS LTP: ₹#{tcs_ltp}"
80
+ #
81
+ # @example Access data from response
82
+ # response = DhanHQ::Models::MarketFeed.ltp("NSE_EQ" => [11536])
83
+ # data = response[:data]["NSE_EQ"]["11536"]
84
+ # puts "Last Price: ₹#{data[:last_price]}"
9
85
  #
10
- # @param params [Hash]
11
- # @return [Hash]
12
86
  def ltp(params)
13
87
  resource.ltp(params)
14
88
  end
15
89
 
16
- # Fetches OHLC data for the requested instruments.
90
+ ##
91
+ # Fetches OHLC (Open, High, Low, Close) data along with LTP for specified instruments.
92
+ #
93
+ # Retrieves the open, high, low, and close prices along with the last traded price
94
+ # for a list of instruments. Supports up to 1000 instruments per request.
95
+ #
96
+ # @param params [Hash{String => Array<Integer>}] Request payload mapping exchange segments
97
+ # to arrays of security IDs. Exchange segments are keys (e.g., "NSE_EQ", "NSE_FNO", "BSE_EQ").
98
+ # Values are arrays of security IDs (integer identifiers for each scrip).
99
+ # Valid exchange segment values: "NSE_EQ", "NSE_FNO", "BSE_EQ", "BSE_FNO", etc.
100
+ #
101
+ # @return [HashWithIndifferentAccess] Response hash containing OHLC market data.
102
+ # Response structure:
103
+ # - **:data** [Hash{String => Hash{String => Hash}}] Market data organized by exchange segment
104
+ # and security ID. Each instrument's data contains:
105
+ # - **:last_price** [Float] Last traded price of the instrument
106
+ # - **:ohlc** [Hash{Symbol => Float}] OHLC data:
107
+ # - **:open** [Float] Market opening price of the day
108
+ # - **:close** [Float] Market closing price of the day (previous day close for current session)
109
+ # - **:high** [Float] Day high price
110
+ # - **:low** [Float] Day low price
111
+ # - **:status** [String] Response status (typically "success")
112
+ #
113
+ # @note For newly listed instruments or instruments without trading activity,
114
+ # OHLC values may be 0. The close price typically represents the previous day's
115
+ # closing price during the current trading session.
116
+ #
117
+ # @example Fetch OHLC for equity instruments
118
+ # payload = {
119
+ # "NSE_EQ" => [11536]
120
+ # }
121
+ # response = DhanHQ::Models::MarketFeed.ohlc(payload)
122
+ # tcs_data = response[:data]["NSE_EQ"]["11536"]
123
+ # puts "Open: ₹#{tcs_data[:ohlc][:open]}"
124
+ # puts "High: ₹#{tcs_data[:ohlc][:high]}"
125
+ # puts "Low: ₹#{tcs_data[:ohlc][:low]}"
126
+ # puts "Close: ₹#{tcs_data[:ohlc][:close]}"
127
+ # puts "LTP: ₹#{tcs_data[:last_price]}"
17
128
  #
18
- # @param params [Hash]
19
- # @return [Hash]
20
129
  def ohlc(params)
21
130
  resource.ohlc(params)
22
131
  end
23
132
 
24
- # Fetches full quote depth and analytics.
133
+ ##
134
+ # Fetches full market depth data including OHLC, Open Interest, Volume, and order book depth.
135
+ #
136
+ # Retrieves comprehensive market data including market depth (buy/sell orders), OHLC data,
137
+ # Open Interest (for derivatives), Volume, circuit limits, and other trading analytics
138
+ # for specified instruments. Supports up to 1000 instruments per request.
139
+ #
140
+ # @param params [Hash{String => Array<Integer>}] Request payload mapping exchange segments
141
+ # to arrays of security IDs. Exchange segments are keys (e.g., "NSE_EQ", "NSE_FNO", "BSE_EQ").
142
+ # Values are arrays of security IDs (integer identifiers for each scrip).
143
+ # Valid exchange segment values: "NSE_EQ", "NSE_FNO", "BSE_EQ", "BSE_FNO", etc.
144
+ #
145
+ # @return [HashWithIndifferentAccess] Response hash containing full quote market data.
146
+ # Response structure:
147
+ # - **:data** [Hash{String => Hash{String => Hash}}] Market data organized by exchange segment
148
+ # and security ID. Each instrument's data contains:
149
+ # - **:last_price** [Float] Last traded price of the instrument
150
+ # - **:last_quantity** [Integer] Last traded quantity
151
+ # - **:last_trade_time** [String] Timestamp of last trade in "DD/MM/YYYY HH:MM:SS" format
152
+ # - **:average_price** [Float] Volume weighted average price (VWAP) of the day
153
+ # - **:buy_quantity** [Integer] Total buy order quantity pending at the exchange
154
+ # - **:sell_quantity** [Integer] Total sell order quantity pending at the exchange
155
+ # - **:volume** [Integer] Total traded volume for the day
156
+ # - **:oi** [Integer] Open Interest in the contract (for derivatives)
157
+ # - **:oi_day_high** [Integer] Highest Open Interest for the day (only for NSE_FNO)
158
+ # - **:oi_day_low** [Integer] Lowest Open Interest for the day (only for NSE_FNO)
159
+ # - **:net_change** [Float] Absolute change in LTP from previous day closing price
160
+ # - **:upper_circuit_limit** [Float] Current upper circuit limit
161
+ # - **:lower_circuit_limit** [Float] Current lower circuit limit
162
+ # - **:ohlc** [Hash{Symbol => Float}] OHLC data:
163
+ # - **:open** [Float] Market opening price of the day
164
+ # - **:close** [Float] Market closing price of the day
165
+ # - **:high** [Float] Day high price
166
+ # - **:low** [Float] Day low price
167
+ # - **:depth** [Hash{Symbol => Array<Hash>}] Market depth (order book) data:
168
+ # - **:buy** [Array<Hash{Symbol => Integer, Float}>] Buy side depth levels (up to 5 levels):
169
+ # - **:quantity** [Integer] Number of quantity at this price depth
170
+ # - **:orders** [Integer] Number of open BUY orders at this price depth
171
+ # - **:price** [Float] Price at which the BUY depth stands
172
+ # - **:sell** [Array<Hash{Symbol => Integer, Float}>] Sell side depth levels (up to 5 levels):
173
+ # - **:quantity** [Integer] Number of quantity at this price depth
174
+ # - **:orders** [Integer] Number of open SELL orders at this price depth
175
+ # - **:price** [Float] Price at which the SELL depth stands
176
+ # - **:status** [String] Response status (typically "success")
177
+ #
178
+ # @note This endpoint uses a separate quote API with stricter rate limits (1 request per second).
179
+ # The client automatically handles rate limiting for quote requests.
180
+ #
181
+ # @example Fetch full quote for futures contract
182
+ # payload = {
183
+ # "NSE_FNO" => [49081]
184
+ # }
185
+ # response = DhanHQ::Models::MarketFeed.quote(payload)
186
+ # quote = response[:data]["NSE_FNO"]["49081"]
187
+ # puts "LTP: ₹#{quote[:last_price]}"
188
+ # puts "Volume: #{quote[:volume]}"
189
+ # puts "Open Interest: #{quote[:oi]}"
190
+ # puts "Day High OI: #{quote[:oi_day_high]}"
191
+ #
192
+ # @example Access market depth (order book)
193
+ # response = DhanHQ::Models::MarketFeed.quote("NSE_FNO" => [49081])
194
+ # quote = response[:data]["NSE_FNO"]["49081"]
195
+ # buy_depth = quote[:depth][:buy]
196
+ # puts "Best Buy Price: ₹#{buy_depth[0][:price]}"
197
+ # puts "Best Buy Quantity: #{buy_depth[0][:quantity]}"
25
198
  #
26
- # @param params [Hash]
27
- # @return [Hash]
28
199
  def quote(params)
29
200
  resource.quote(params)
30
201
  end
31
-
32
- # Shared market feed resource instance.
33
- #
34
- # @return [DhanHQ::Resources::MarketFeed]
35
- def resource
36
- @resource ||= DhanHQ::Resources::MarketFeed.new
37
- end
38
202
  end
39
203
  end
40
204
  end