DhanHQ 2.3.0 → 2.5.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +50 -1
  3. data/CODE_REVIEW_ISSUES.md +2 -2
  4. data/GUIDE.md +2 -2
  5. data/README.md +194 -741
  6. data/REVIEW_SUMMARY.md +2 -2
  7. data/{README1.md → docs/ARCHIVE_README.md} +4 -4
  8. data/docs/AUTHENTICATION.md +116 -2
  9. data/docs/CONFIGURATION.md +109 -0
  10. data/docs/SUPER_ORDERS.md +284 -0
  11. data/docs/TESTING_GUIDE.md +8 -8
  12. data/docs/TROUBLESHOOTING.md +117 -0
  13. data/docs/WEBSOCKET_PROTOCOL.md +154 -0
  14. data/docs/live_order_updates.md +2 -2
  15. data/docs/rails_integration.md +7 -7
  16. data/docs/standalone_ruby_websocket_integration.md +24 -24
  17. data/docs/technical_analysis.md +1 -1
  18. data/docs/websocket_integration.md +4 -4
  19. data/examples/comprehensive_websocket_examples.rb +2 -2
  20. data/examples/instrument_finder_test.rb +2 -2
  21. data/examples/market_depth_example.rb +2 -2
  22. data/examples/market_feed_example.rb +2 -2
  23. data/examples/order_update_example.rb +2 -2
  24. data/examples/trading_fields_example.rb +2 -2
  25. data/lib/DhanHQ/auth/token_generator.rb +33 -0
  26. data/lib/DhanHQ/auth/token_manager.rb +88 -0
  27. data/lib/DhanHQ/auth/token_renewal.rb +25 -0
  28. data/lib/DhanHQ/auth.rb +91 -31
  29. data/lib/DhanHQ/client.rb +42 -2
  30. data/lib/DhanHQ/configuration.rb +2 -2
  31. data/lib/DhanHQ/contracts/order_contract.rb +0 -23
  32. data/lib/DhanHQ/contracts/trade_by_order_id_contract.rb +12 -0
  33. data/lib/DhanHQ/contracts/trade_contract.rb +0 -65
  34. data/lib/DhanHQ/contracts/trade_history_contract.rb +52 -0
  35. data/lib/DhanHQ/core/auth_api.rb +21 -0
  36. data/lib/DhanHQ/helpers/request_helper.rb +1 -1
  37. data/lib/DhanHQ/models/alert_order.rb +22 -0
  38. data/lib/DhanHQ/models/edis.rb +110 -0
  39. data/lib/DhanHQ/models/kill_switch.rb +22 -0
  40. data/lib/DhanHQ/models/margin.rb +49 -0
  41. data/lib/DhanHQ/models/pnl_exit.rb +130 -0
  42. data/lib/DhanHQ/models/position.rb +22 -0
  43. data/lib/DhanHQ/models/postback.rb +123 -0
  44. data/lib/DhanHQ/models/token_response.rb +88 -0
  45. data/lib/DhanHQ/resources/kill_switch.rb +8 -0
  46. data/lib/DhanHQ/resources/margin_calculator.rb +9 -0
  47. data/lib/DhanHQ/resources/pnl_exit.rb +37 -0
  48. data/lib/DhanHQ/resources/positions.rb +8 -0
  49. data/lib/DhanHQ/version.rb +1 -1
  50. data/lib/dhan_hq.rb +31 -81
  51. metadata +46 -4
  52. data/lib/DhanHQ/config.rb +0 -33
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DhanHQ
4
+ module Models
5
+ ##
6
+ # Model for managing P&L-based automatic position exit.
7
+ #
8
+ # The P&L Based Exit API allows users to configure automatic exit rules based on
9
+ # cumulative profit or loss thresholds. When the defined limits are breached, all
10
+ # applicable positions are exited automatically.
11
+ #
12
+ # @note The configured P&L based exit remains active for the current day and is
13
+ # reset at the end of the trading session.
14
+ #
15
+ # @example Configure P&L-based exit
16
+ # response = DhanHQ::Models::PnlExit.configure(
17
+ # profit_value: 1500.0,
18
+ # loss_value: 500.0,
19
+ # product_type: ["INTRADAY", "DELIVERY"],
20
+ # enable_kill_switch: true
21
+ # )
22
+ # puts response[:pnl_exit_status] # => "ACTIVE"
23
+ #
24
+ # @example Check current P&L exit configuration
25
+ # config = DhanHQ::Models::PnlExit.status
26
+ # puts "Status: #{config.pnl_exit_status}"
27
+ # puts "Profit threshold: ₹#{config.profit}"
28
+ # puts "Loss threshold: ₹#{config.loss}"
29
+ #
30
+ # @example Stop P&L-based exit
31
+ # response = DhanHQ::Models::PnlExit.stop
32
+ # puts response[:pnl_exit_status] # => "DISABLED"
33
+ #
34
+ class PnlExit < BaseModel
35
+ HTTP_PATH = "/v2/pnlExit"
36
+
37
+ attributes :pnl_exit_status, :profit, :loss, :segments, :enable_kill_switch
38
+
39
+ class << self
40
+ ##
41
+ # Provides a shared instance of the PnlExit resource.
42
+ #
43
+ # @return [DhanHQ::Resources::PnlExit] The PnlExit resource client instance
44
+ def resource
45
+ @resource ||= DhanHQ::Resources::PnlExit.new
46
+ end
47
+
48
+ ##
49
+ # Configure automatic P&L-based position exit.
50
+ #
51
+ # When the defined profit or loss thresholds are breached during the trading day,
52
+ # all applicable positions are exited automatically.
53
+ #
54
+ # @param profit_value [Float] Profit threshold that triggers exit (e.g., 1500.0)
55
+ # @param loss_value [Float] Loss threshold that triggers exit (e.g., 500.0)
56
+ # @param product_type [Array<String>] Product types to apply. e.g., ["INTRADAY", "DELIVERY"]
57
+ # @param enable_kill_switch [Boolean] Whether to activate kill switch after exit
58
+ #
59
+ # @return [Hash{Symbol => String}] Response hash containing:
60
+ # - **:pnl_exit_status** [String] "ACTIVE" on success
61
+ # - **:message** [String] Confirmation message
62
+ #
63
+ # @example Configure with kill switch
64
+ # DhanHQ::Models::PnlExit.configure(
65
+ # profit_value: 2000.0,
66
+ # loss_value: 1000.0,
67
+ # product_type: ["INTRADAY"],
68
+ # enable_kill_switch: true
69
+ # )
70
+ #
71
+ def configure(profit_value:, loss_value:, product_type:, enable_kill_switch: false)
72
+ params = {
73
+ profitValue: profit_value.to_s,
74
+ lossValue: loss_value.to_s,
75
+ productType: product_type,
76
+ enableKillSwitch: enable_kill_switch
77
+ }
78
+ resource.configure(params)
79
+ end
80
+
81
+ ##
82
+ # Stop/disable the active P&L-based exit configuration.
83
+ #
84
+ # @return [Hash{Symbol => String}] Response hash containing:
85
+ # - **:pnl_exit_status** [String] "DISABLED"
86
+ # - **:message** [String] Confirmation message
87
+ #
88
+ # @example Disable P&L exit
89
+ # response = DhanHQ::Models::PnlExit.stop
90
+ # puts response[:pnl_exit_status] # => "DISABLED"
91
+ #
92
+ def stop
93
+ resource.stop
94
+ end
95
+
96
+ ##
97
+ # Fetch the currently active P&L-based exit configuration.
98
+ #
99
+ # @return [PnlExit] PnlExit object with current configuration.
100
+ # - **:pnl_exit_status** [String] "ACTIVE" or "DISABLED"
101
+ # - **:profit** [String] Configured profit threshold
102
+ # - **:loss** [String] Configured loss threshold
103
+ # - **:segments** [Array<String>] Active product types
104
+ # - **:enable_kill_switch** [Boolean] Whether kill switch is enabled
105
+ #
106
+ # @example Check configuration
107
+ # config = DhanHQ::Models::PnlExit.status
108
+ # if config.pnl_exit_status == "ACTIVE"
109
+ # puts "P&L exit active: profit=₹#{config.profit}, loss=₹#{config.loss}"
110
+ # end
111
+ #
112
+ def status
113
+ response = resource.status
114
+ return nil unless response.is_a?(Hash)
115
+
116
+ new(response, skip_validation: true)
117
+ end
118
+ end
119
+
120
+ ##
121
+ # No validation contract needed — server-side validation handles it.
122
+ #
123
+ # @return [nil]
124
+ # @api private
125
+ def validation_contract
126
+ nil
127
+ end
128
+ end
129
+ end
130
+ end
@@ -205,6 +205,28 @@ module DhanHQ
205
205
  response = resource.convert(formatted_params)
206
206
  success_response?(response) ? response : DhanHQ::ErrorObject.new(response)
207
207
  end
208
+
209
+ ##
210
+ # Exits all active positions and cancels all open orders for the current trading day.
211
+ #
212
+ # This is a safety endpoint for emergency position closure. It sends a DELETE request
213
+ # to close all positions and cancel all pending orders in one call.
214
+ #
215
+ # @return [Hash{Symbol => String}] Response hash containing operation result.
216
+ # - **:status** [String] "SUCCESS" or "ERROR"
217
+ # - **:message** [String] Description of the result
218
+ #
219
+ # @example Emergency exit all positions
220
+ # response = DhanHQ::Models::Position.exit_all!
221
+ # if response[:status] == "SUCCESS"
222
+ # puts "✓ All positions exited and orders cancelled"
223
+ # else
224
+ # puts "✗ Failed: #{response[:message]}"
225
+ # end
226
+ #
227
+ def exit_all!
228
+ resource.exit_all
229
+ end
208
230
  end
209
231
  end
210
232
  end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DhanHQ
4
+ module Models
5
+ ##
6
+ # Utility model for parsing Dhan postback (webhook) payloads.
7
+ #
8
+ # Postback is a webhook mechanism where Dhan pushes order status updates to your
9
+ # configured URL. This model provides a convenient way to parse the incoming JSON
10
+ # payload into a typed, attribute-accessible object.
11
+ #
12
+ # @note Postback URL is configured in the Dhan web console when generating an access
13
+ # token. It will NOT work with localhost or 127.0.0.1.
14
+ #
15
+ # @example Parse postback payload in a Rails controller
16
+ # class DhanWebhooksController < ApplicationController
17
+ # skip_before_action :verify_authenticity_token
18
+ #
19
+ # def create
20
+ # postback = DhanHQ::Models::Postback.parse(request.body.read)
21
+ # case postback.order_status
22
+ # when "TRADED"
23
+ # handle_fill(postback)
24
+ # when "REJECTED"
25
+ # handle_rejection(postback)
26
+ # end
27
+ # head :ok
28
+ # end
29
+ # end
30
+ #
31
+ # @example Parse postback payload from a hash
32
+ # postback = DhanHQ::Models::Postback.parse(params)
33
+ # puts "Order #{postback.order_id} is now #{postback.order_status}"
34
+ # puts "Filled: #{postback.filled_qty}/#{postback.quantity}"
35
+ #
36
+ class Postback < BaseModel
37
+ HTTP_PATH = nil # No API endpoint — postback is pushed to the user
38
+
39
+ attributes :dhan_client_id, :order_id, :correlation_id, :order_status,
40
+ :transaction_type, :exchange_segment, :product_type, :order_type,
41
+ :validity, :trading_symbol, :security_id, :quantity,
42
+ :disclosed_quantity, :price, :trigger_price, :after_market_order,
43
+ :bo_profit_value, :bo_stop_loss_value, :leg_name,
44
+ :create_time, :update_time, :exchange_time,
45
+ :drv_expiry_date, :drv_option_type, :drv_strike_price,
46
+ :oms_error_code, :oms_error_description, :filled_qty, :algo_id
47
+
48
+ class << self
49
+ ##
50
+ # Parse a postback webhook payload into a Postback model instance.
51
+ #
52
+ # Accepts either a JSON string (from request body) or a Hash (from parsed params).
53
+ # Keys are normalized to snake_case automatically.
54
+ #
55
+ # @param payload [String, Hash] Raw JSON string or Hash from the webhook
56
+ #
57
+ # @return [Postback] Parsed Postback object with typed attributes
58
+ #
59
+ # @example From raw JSON string
60
+ # postback = DhanHQ::Models::Postback.parse('{"orderId":"123","orderStatus":"TRADED"}')
61
+ # puts postback.order_status # => "TRADED"
62
+ #
63
+ # @example From a hash
64
+ # postback = DhanHQ::Models::Postback.parse(order_id: "123", order_status: "TRADED")
65
+ # puts postback.order_id # => "123"
66
+ #
67
+ def parse(payload)
68
+ data = case payload
69
+ when String
70
+ JSON.parse(payload)
71
+ when Hash
72
+ payload
73
+ else
74
+ raise ArgumentError, "Expected String or Hash, got #{payload.class}"
75
+ end
76
+
77
+ new(data, skip_validation: true)
78
+ end
79
+ end
80
+
81
+ ##
82
+ # Whether the order has been fully traded.
83
+ #
84
+ # @return [Boolean]
85
+ def traded?
86
+ order_status == "TRADED"
87
+ end
88
+
89
+ ##
90
+ # Whether the order was rejected.
91
+ #
92
+ # @return [Boolean]
93
+ def rejected?
94
+ order_status == "REJECTED"
95
+ end
96
+
97
+ ##
98
+ # Whether the order is still pending.
99
+ #
100
+ # @return [Boolean]
101
+ def pending?
102
+ order_status == "PENDING"
103
+ end
104
+
105
+ ##
106
+ # Whether the order was cancelled.
107
+ #
108
+ # @return [Boolean]
109
+ def cancelled?
110
+ order_status == "CANCELLED"
111
+ end
112
+
113
+ ##
114
+ # No validation contract — postback payloads are parsed as-is.
115
+ #
116
+ # @return [nil]
117
+ # @api private
118
+ def validation_contract
119
+ nil
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "time"
4
+
5
+ module DhanHQ
6
+ module Models
7
+ # Represents a Dhan API token response with expiry tracking and validation.
8
+ #
9
+ # TokenResponse wraps the response from Dhan's token generation and renewal
10
+ # endpoints, providing convenient methods for checking token validity and
11
+ # determining when refresh is needed.
12
+ #
13
+ # @example From token generation
14
+ # response = Auth.generate_access_token(
15
+ # dhan_client_id: "123",
16
+ # pin: "1234",
17
+ # totp: "654321"
18
+ # )
19
+ # token = TokenResponse.new(response)
20
+ # token.expired? # => false
21
+ # token.expires_in # => 86400 (seconds)
22
+ # token.needs_refresh? # => false
23
+ #
24
+ # @example Checking token status
25
+ # if token.needs_refresh?(buffer_seconds: 600)
26
+ # # Refresh token 10 minutes before expiry
27
+ # new_token = Auth.renew_token(...)
28
+ # end
29
+ #
30
+ # @attr_reader [String] client_id Dhan client ID
31
+ # @attr_reader [String] client_name Dhan client name
32
+ # @attr_reader [String] ucc Unique client code
33
+ # @attr_reader [Boolean] power_of_attorney POA status
34
+ # @attr_reader [String] access_token The authentication token
35
+ # @attr_reader [Time] expiry_time Token expiration timestamp
36
+ class TokenResponse
37
+ attr_reader :client_id,
38
+ :client_name,
39
+ :ucc,
40
+ :power_of_attorney,
41
+ :access_token,
42
+ :expiry_time
43
+
44
+ def initialize(data)
45
+ data = normalize_keys(data)
46
+
47
+ @client_id = data["dhanClientId"]
48
+ @client_name = data["dhanClientName"]
49
+ @ucc = data["dhanClientUcc"]
50
+ @power_of_attorney = data["givenPowerOfAttorney"]
51
+ @access_token = data["accessToken"]
52
+ @expiry_time = parse_time(data["expiryTime"])
53
+ end
54
+
55
+ def expired?
56
+ return true unless expiry_time
57
+
58
+ Time.now >= expiry_time
59
+ end
60
+
61
+ def expires_in
62
+ return 0 unless expiry_time
63
+
64
+ expiry_time - Time.now
65
+ end
66
+
67
+ def needs_refresh?(buffer_seconds: 300)
68
+ return true unless expiry_time
69
+
70
+ Time.now >= (expiry_time - buffer_seconds)
71
+ end
72
+
73
+ private
74
+
75
+ def normalize_keys(data)
76
+ return {} unless data.is_a?(Hash)
77
+
78
+ data.transform_keys(&:to_s)
79
+ end
80
+
81
+ def parse_time(value)
82
+ return nil if value.nil? || value.to_s.strip.empty?
83
+
84
+ Time.parse(value.to_s)
85
+ end
86
+ end
87
+ end
88
+ end
@@ -16,6 +16,14 @@ module DhanHQ
16
16
  def update(params)
17
17
  post("", params: params)
18
18
  end
19
+
20
+ ##
21
+ # Fetches the current kill switch status.
22
+ #
23
+ # @return [Hash] API response containing dhan_client_id and kill_switch_status.
24
+ def status
25
+ get("")
26
+ end
19
27
  end
20
28
  end
21
29
  end
@@ -17,6 +17,15 @@ module DhanHQ
17
17
  def calculate(params)
18
18
  post("", params: params)
19
19
  end
20
+
21
+ ##
22
+ # Calculate margin requirements for multiple scripts in one request.
23
+ #
24
+ # @param params [Hash] Request parameters including scripList, includePosition, includeOrder.
25
+ # @return [Hash] API response containing combined margin details with hedge benefit.
26
+ def calculate_multi(params)
27
+ post("/multi", params: params)
28
+ end
20
29
  end
21
30
  end
22
31
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DhanHQ
4
+ module Resources
5
+ # Resource for P&L Based Exit endpoints per https://dhanhq.co/docs/v2/traders-control/
6
+ # POST /v2/pnlExit — configure, DELETE /v2/pnlExit — stop, GET /v2/pnlExit — status.
7
+ class PnlExit < BaseAPI
8
+ API_TYPE = :order_api
9
+ HTTP_PATH = "/v2/pnlExit"
10
+
11
+ ##
12
+ # Configure automatic P&L-based position exit.
13
+ #
14
+ # @param params [Hash] Request body with profitValue, lossValue, productType, enableKillSwitch.
15
+ # @return [Hash] API response containing pnlExitStatus and message.
16
+ def configure(params)
17
+ post("", params: params)
18
+ end
19
+
20
+ ##
21
+ # Stop/disable the active P&L-based exit configuration.
22
+ #
23
+ # @return [Hash] API response containing pnlExitStatus and message.
24
+ def stop
25
+ delete("")
26
+ end
27
+
28
+ ##
29
+ # Fetch the currently active P&L-based exit configuration.
30
+ #
31
+ # @return [Hash] API response containing pnlExitStatus, profit, loss, segments, enable_kill_switch.
32
+ def status
33
+ get("")
34
+ end
35
+ end
36
+ end
37
+ end
@@ -24,6 +24,14 @@ module DhanHQ
24
24
  def convert(params)
25
25
  post("/convert", params: params)
26
26
  end
27
+
28
+ ##
29
+ # Exit all active positions and cancel all open orders.
30
+ #
31
+ # @return [Hash] API response containing status and message.
32
+ def exit_all
33
+ delete("")
34
+ end
27
35
  end
28
36
  end
29
37
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module DhanHQ
4
4
  # Semantic version of the DhanHQ client gem.
5
- VERSION = "2.3.0"
5
+ VERSION = "2.5.0"
6
6
  end
data/lib/dhan_hq.rb CHANGED
@@ -1,96 +1,46 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dotenv/load"
3
+ require "json"
4
4
  require "logger"
5
-
6
- # Helper Methods
5
+ require "zeitwerk"
6
+ require "dotenv/load"
7
+ # Minimal eager requires for backward-compatible constants.
8
+ # These are widely referenced (e.g. `DhanHQ::BaseAPI`) and should not depend on
9
+ # the autoloader being fully configured.
7
10
  require_relative "DhanHQ/helpers/api_helper"
8
11
  require_relative "DhanHQ/helpers/attribute_helper"
9
12
  require_relative "DhanHQ/helpers/validation_helper"
10
13
  require_relative "DhanHQ/helpers/request_helper"
11
14
  require_relative "DhanHQ/helpers/response_helper"
12
- require_relative "DhanHQ/json_loader"
13
-
14
15
  require_relative "DhanHQ/core/base_api"
15
- require_relative "DhanHQ/core/base_resource"
16
16
  require_relative "DhanHQ/core/base_model"
17
- require_relative "DhanHQ/core/error_handler"
18
-
19
- require_relative "DhanHQ/version"
20
- require_relative "DhanHQ/errors"
21
- require_relative "DhanHQ/error_object"
22
-
23
- require_relative "DhanHQ/client"
24
- require_relative "DhanHQ/configuration"
25
- require_relative "DhanHQ/rate_limiter"
26
- require_relative "DhanHQ/auth"
27
-
28
- # Contracts
29
- require_relative "DhanHQ/contracts/base_contract"
30
- require_relative "DhanHQ/contracts/historical_data_contract"
31
- require_relative "DhanHQ/contracts/margin_calculator_contract"
32
- require_relative "DhanHQ/contracts/position_conversion_contract"
33
- require_relative "DhanHQ/contracts/slice_order_contract"
34
- require_relative "DhanHQ/contracts/trade_contract"
35
- require_relative "DhanHQ/contracts/expired_options_data_contract"
36
- require_relative "DhanHQ/contracts/alert_order_contract"
37
-
38
- # Resources
39
- require_relative "DhanHQ/resources/option_chain"
40
- require_relative "DhanHQ/resources/orders"
41
- require_relative "DhanHQ/resources/forever_orders"
42
- require_relative "DhanHQ/resources/super_orders"
43
- require_relative "DhanHQ/resources/funds"
44
- require_relative "DhanHQ/resources/holdings"
45
- require_relative "DhanHQ/resources/positions"
46
- require_relative "DhanHQ/resources/statements"
47
- require_relative "DhanHQ/resources/trades"
48
- require_relative "DhanHQ/resources/historical_data"
49
- require_relative "DhanHQ/resources/margin_calculator"
50
- require_relative "DhanHQ/resources/market_feed"
51
- require_relative "DhanHQ/resources/instruments"
52
- require_relative "DhanHQ/resources/alert_orders"
53
- require_relative "DhanHQ/resources/edis"
54
- require_relative "DhanHQ/resources/ip_setup"
55
- require_relative "DhanHQ/resources/kill_switch"
56
- require_relative "DhanHQ/resources/trader_control"
57
- require_relative "DhanHQ/resources/profile"
58
- require_relative "DhanHQ/resources/expired_options_data"
59
-
60
- # Models
61
- require_relative "DhanHQ/models/alert_order"
62
- require_relative "DhanHQ/models/order"
63
- require_relative "DhanHQ/models/funds"
64
- require_relative "DhanHQ/models/option_chain"
65
- require_relative "DhanHQ/models/forever_order"
66
- require_relative "DhanHQ/models/super_order"
67
- require_relative "DhanHQ/models/historical_data"
68
- require_relative "DhanHQ/models/market_feed"
69
- require_relative "DhanHQ/models/instrument"
70
- require_relative "DhanHQ/models/position"
71
- require_relative "DhanHQ/models/holding"
72
- require_relative "DhanHQ/models/ledger_entry"
73
- require_relative "DhanHQ/models/trade"
74
- require_relative "DhanHQ/models/margin"
75
- require_relative "DhanHQ/models/kill_switch"
76
- require_relative "DhanHQ/models/profile"
77
- require_relative "DhanHQ/models/order_update"
78
- require_relative "DhanHQ/models/expired_options_data"
79
-
80
- require_relative "DhanHQ/constants"
81
- require_relative "DhanHQ/ws"
82
- require_relative "DhanHQ/ws/singleton_lock"
83
- require_relative "ta"
84
- require_relative "dhanhq/analysis/multi_timeframe_analyzer"
85
- require_relative "dhanhq/analysis/helpers/bias_aggregator"
86
- require_relative "dhanhq/analysis/helpers/moneyness_helper"
87
- require_relative "dhanhq/contracts/options_buying_advisor_contract"
88
- require_relative "dhanhq/analysis/options_buying_advisor"
17
+ require_relative "DhanHQ/core/base_resource"
89
18
 
90
19
  # The top-level module for the DhanHQ client library.
91
20
  #
92
21
  # Provides configuration management for setting credentials and API-related settings.
93
22
  module DhanHQ
23
+ LOADER = Zeitwerk::Loader.new
24
+ LOADER.tag = "dhanhq"
25
+ LOADER.inflector.inflect(
26
+ "api_helper" => "APIHelper",
27
+ "auth_api" => "AuthAPI",
28
+ "base_api" => "BaseAPI",
29
+ "ip_setup" => "IPSetup",
30
+ "json_loader" => "JSONLoader",
31
+ "ws" => "WS"
32
+ )
33
+ LOADER.push_dir(File.join(__dir__, "DhanHQ"), namespace: self)
34
+ LOADER.push_dir(File.join(__dir__, "dhanhq"), namespace: self)
35
+ LOADER.collapse(File.join(__dir__, "DhanHQ", "core"))
36
+ LOADER.collapse(File.join(__dir__, "DhanHQ", "helpers"))
37
+ LOADER.collapse(File.join(__dir__, "dhanhq", "analysis", "helpers"))
38
+ LOADER.ignore(
39
+ File.join(__dir__, "DhanHQ", "errors.rb"),
40
+ File.join(__dir__, "DhanHQ", "version.rb")
41
+ )
42
+ LOADER.setup
43
+
94
44
  class Error < StandardError; end
95
45
 
96
46
  class << self
@@ -131,7 +81,7 @@ module DhanHQ
131
81
 
132
82
  # Configures the DhanHQ client using environment variables.
133
83
  #
134
- # When credentials are injected via `ACCESS_TOKEN` and `CLIENT_ID` this helper
84
+ # When credentials are injected via `DHAN_ACCESS_TOKEN` and `DHAN_CLIENT_ID` this helper
135
85
  # can be used to initialise a configuration without a block.
136
86
  #
137
87
  # @example
@@ -140,8 +90,8 @@ module DhanHQ
140
90
  # @return [void]
141
91
  def configure_with_env
142
92
  self.configuration ||= Configuration.new
143
- configuration.access_token = ENV.fetch("ACCESS_TOKEN", nil)
144
- configuration.client_id = ENV.fetch("CLIENT_ID", nil)
93
+ configuration.access_token = ENV.fetch("DHAN_ACCESS_TOKEN", nil)
94
+ configuration.client_id = ENV.fetch("DHAN_CLIENT_ID", nil)
145
95
  configuration.base_url = ENV.fetch("DHAN_BASE_URL", BASE_URL)
146
96
  configuration.ws_version = ENV.fetch("DHAN_WS_VERSION", configuration.ws_version || 2).to_i
147
97
  configuration.ws_order_url = ENV.fetch("DHAN_WS_ORDER_URL", configuration.ws_order_url)