DhanHQ 2.5.0 → 2.6.1

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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +9 -1
  3. data/CHANGELOG.md +78 -6
  4. data/GUIDE.md +57 -39
  5. data/README.md +24 -23
  6. data/docs/API_DOCS_GAPS.md +128 -0
  7. data/docs/API_VERIFICATION.md +10 -11
  8. data/docs/ARCHIVE_README.md +16 -16
  9. data/docs/AUTHENTICATION.md +1 -1
  10. data/docs/CONSTANTS_REFERENCE.md +477 -0
  11. data/docs/DATA_API_PARAMETERS.md +7 -7
  12. data/docs/{rails_websocket_integration.md → RAILS_WEBSOCKET_INTEGRATION.md} +10 -10
  13. data/docs/{standalone_ruby_websocket_integration.md → STANDALONE_RUBY_WEBSOCKET_INTEGRATION.md} +32 -32
  14. data/docs/{technical_analysis.md → TECHNICAL_ANALYSIS.md} +3 -3
  15. data/docs/TESTING_GUIDE.md +84 -82
  16. data/docs/{websocket_integration.md → WEBSOCKET_INTEGRATION.md} +19 -19
  17. data/docs/WEBSOCKET_PROTOCOL.md +2 -2
  18. data/lib/DhanHQ/constants.rb +456 -151
  19. data/lib/DhanHQ/contracts/alert_order_contract.rb +37 -10
  20. data/lib/DhanHQ/contracts/base_contract.rb +22 -0
  21. data/lib/DhanHQ/contracts/edis_contract.rb +25 -0
  22. data/lib/DhanHQ/contracts/margin_calculator_contract.rb +27 -4
  23. data/lib/DhanHQ/contracts/modify_order_contract.rb +65 -12
  24. data/lib/DhanHQ/contracts/multi_scrip_margin_calc_request_contract.rb +23 -0
  25. data/lib/DhanHQ/contracts/order_contract.rb +171 -39
  26. data/lib/DhanHQ/contracts/place_order_contract.rb +14 -141
  27. data/lib/DhanHQ/contracts/pnl_based_exit_contract.rb +20 -0
  28. data/lib/DhanHQ/contracts/position_conversion_contract.rb +15 -3
  29. data/lib/DhanHQ/contracts/slice_order_contract.rb +10 -1
  30. data/lib/DhanHQ/contracts/user_ip_contract.rb +14 -0
  31. data/lib/DhanHQ/core/base_model.rb +13 -4
  32. data/lib/DhanHQ/helpers/response_helper.rb +2 -2
  33. data/lib/DhanHQ/helpers/validation_helper.rb +1 -1
  34. data/lib/DhanHQ/models/alert_order.rb +7 -11
  35. data/lib/DhanHQ/models/concerns/api_response_handler.rb +46 -0
  36. data/lib/DhanHQ/models/edis.rb +0 -9
  37. data/lib/DhanHQ/models/expired_options_data.rb +6 -12
  38. data/lib/DhanHQ/models/forever_order.rb +8 -5
  39. data/lib/DhanHQ/models/historical_data.rb +0 -8
  40. data/lib/DhanHQ/models/instrument.rb +1 -7
  41. data/lib/DhanHQ/models/instrument_helpers.rb +4 -4
  42. data/lib/DhanHQ/models/kill_switch.rb +1 -11
  43. data/lib/DhanHQ/models/margin.rb +2 -2
  44. data/lib/DhanHQ/models/order.rb +107 -126
  45. data/lib/DhanHQ/models/order_update.rb +7 -13
  46. data/lib/DhanHQ/models/pnl_exit.rb +1 -9
  47. data/lib/DhanHQ/models/position.rb +1 -1
  48. data/lib/DhanHQ/models/postback.rb +4 -13
  49. data/lib/DhanHQ/models/profile.rb +0 -10
  50. data/lib/DhanHQ/models/super_order.rb +13 -3
  51. data/lib/DhanHQ/models/trade.rb +11 -23
  52. data/lib/DhanHQ/resources/ip_setup.rb +16 -5
  53. data/lib/DhanHQ/resources/kill_switch.rb +9 -7
  54. data/lib/DhanHQ/resources/orders.rb +41 -41
  55. data/lib/DhanHQ/version.rb +1 -1
  56. data/lib/DhanHQ/ws/cmd_bus.rb +1 -1
  57. data/lib/DhanHQ/ws/orders/client.rb +6 -6
  58. data/lib/DhanHQ/ws/singleton_lock.rb +2 -1
  59. data/lib/dhanhq/analysis/options_buying_advisor.rb +2 -2
  60. data/lib/rubocop/cop/dhanhq/use_constants.rb +171 -0
  61. metadata +20 -23
  62. data/TODO-1.md +0 -14
  63. data/TODO.md +0 -127
  64. data/app/services/live/order_update_guard_support.rb +0 -75
  65. data/app/services/live/order_update_hub.rb +0 -76
  66. data/app/services/live/order_update_persistence_support.rb +0 -68
  67. data/docs/PR_2.2.0.md +0 -48
  68. data/examples/comprehensive_websocket_examples.rb +0 -148
  69. data/examples/instrument_finder_test.rb +0 -195
  70. data/examples/live_order_updates.rb +0 -118
  71. data/examples/market_depth_example.rb +0 -144
  72. data/examples/market_feed_example.rb +0 -81
  73. data/examples/order_update_example.rb +0 -105
  74. data/examples/trading_fields_example.rb +0 -215
  75. /data/docs/{live_order_updates.md → LIVE_ORDER_UPDATES.md} +0 -0
  76. /data/docs/{rails_integration.md → RAILS_INTEGRATION.md} +0 -0
@@ -1,118 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # Live Order Updates Example
5
- # Demonstrates comprehensive order state tracking via WebSocket
6
-
7
- require_relative "lib/dhan_hq"
8
-
9
- # Configure DhanHQ
10
- DhanHQ.configure_with_env
11
-
12
- puts "🚀 DhanHQ Live Order Updates Example"
13
- puts "====================================="
14
-
15
- # Create order tracking client
16
- client = DhanHQ::WS::Orders.client
17
-
18
- # Track order statistics
19
- stats = {
20
- total_orders: 0,
21
- status_counts: Hash.new(0),
22
- executions: 0
23
- }
24
-
25
- # Set up comprehensive event handling
26
- client.on(:update) do |order|
27
- stats[:total_orders] += 1
28
- stats[:status_counts][order.status] += 1
29
-
30
- puts "\n📋 Order Update: #{order.order_no}"
31
- puts " Symbol: #{order.symbol} (#{order.display_name})"
32
- puts " Status: #{order.status}"
33
- puts " Type: #{order.txn_type} #{order.order_type}"
34
- puts " Quantity: #{order.traded_qty}/#{order.quantity} (#{order.execution_percentage}%)"
35
- puts " Price: #{order.price} | Avg: #{order.avg_traded_price}"
36
-
37
- puts " Super Order Leg: #{order.leg_no}" if order.super_order?
38
- end
39
-
40
- client.on(:status_change) do |data|
41
- order = data[:order_update]
42
- puts "\n🔄 Status Change: #{order.order_no}"
43
- puts " #{data[:previous_status]} -> #{data[:new_status]}"
44
- end
45
-
46
- client.on(:execution) do |data|
47
- order = data[:order_update]
48
- stats[:executions] += 1
49
-
50
- puts "\n💰 Execution: #{order.order_no}"
51
- puts " #{data[:previous_traded_qty]} -> #{data[:new_traded_qty]} shares"
52
- puts " Execution: #{data[:execution_percentage]}%"
53
- end
54
-
55
- client.on(:order_traded) do |order|
56
- puts "\n✅ Order Fully Executed: #{order.order_no}"
57
- puts " Symbol: #{order.symbol} | Quantity: #{order.traded_qty}"
58
- puts " Average Price: #{order.avg_traded_price}"
59
- end
60
-
61
- client.on(:order_rejected) do |order|
62
- puts "\n❌ Order Rejected: #{order.order_no}"
63
- puts " Reason: #{order.reason_description}"
64
- end
65
-
66
- client.on(:order_cancelled) do |order|
67
- puts "\n🚫 Order Cancelled: #{order.order_no}"
68
- end
69
-
70
- client.on(:raw) do |msg|
71
- # Uncomment for debugging raw messages
72
- # puts "Raw: #{msg}"
73
- end
74
-
75
- # Start monitoring
76
- puts "\n🔌 Connecting to order updates WebSocket..."
77
- client.start
78
-
79
- puts "✅ Connected! Monitoring order updates..."
80
- puts "Press Ctrl+C to stop\n"
81
-
82
- # Print periodic summaries
83
- summary_timer = Thread.new do
84
- loop do
85
- sleep 30
86
-
87
- puts "\n📊 Order Summary (Last 30 seconds):"
88
- puts " Total Updates: #{stats[:total_orders]}"
89
- puts " Executions: #{stats[:executions]}"
90
- puts " Status Distribution:"
91
- stats[:status_counts].each do |status, count|
92
- puts " #{status}: #{count}"
93
- end
94
-
95
- # Show current order states
96
- all_orders = client.all_orders
97
- if all_orders.any?
98
- puts " Current Orders:"
99
- all_orders.each do |order_no, order|
100
- puts " #{order_no}: #{order.symbol} - #{order.status} (#{order.execution_percentage}%)"
101
- end
102
- end
103
-
104
- puts "\n#{"=" * 50}"
105
- end
106
- end
107
-
108
- # Keep running until interrupted
109
- begin
110
- loop do
111
- sleep 1
112
- end
113
- rescue Interrupt
114
- puts "\n\n🛑 Shutting down..."
115
- client.stop
116
- summary_timer.kill
117
- puts "✅ Disconnected. Goodbye!"
118
- end
@@ -1,144 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # Market Depth WebSocket Example
5
- # This script demonstrates how to use the DhanHQ Market Depth WebSocket
6
- # Receives real-time market depth data (bid/ask levels) for specific symbols
7
- # NOTE: Uses a SINGLE connection to avoid rate limiting
8
-
9
- require "dhan_hq"
10
-
11
- # Configure DhanHQ
12
- DhanHQ.configure do |config|
13
- config.client_id = ENV["DHAN_CLIENT_ID"] || "your_client_id"
14
- config.access_token = ENV["DHAN_ACCESS_TOKEN"] || "your_access_token"
15
- config.ws_user_type = ENV["DHAN_WS_USER_TYPE"] || "SELF"
16
- end
17
-
18
- puts "DhanHQ Market Depth WebSocket Example"
19
- puts "===================================="
20
- puts "Receives real-time market depth data including:"
21
- puts "- Bid/Ask levels"
22
- puts "- Order book information"
23
- puts "- Market depth snapshots"
24
- puts "- Depth updates"
25
- puts ""
26
- puts "Subscribing to popular stocks:"
27
- puts "- RELIANCE (Reliance Industries) - NSE_EQ:2885"
28
- puts "- TCS (Tata Consultancy Services) - NSE_EQ:11536"
29
- puts ""
30
- puts "NOTE: Using SINGLE connection to avoid rate limiting (429 errors)"
31
- puts "Dhan allows up to 5 WebSocket connections per user"
32
- puts ""
33
-
34
- # Market Depth WebSocket Connection
35
- puts "Market Depth WebSocket Connection"
36
- puts "================================="
37
-
38
- # Create a single market depth WebSocket connection
39
- puts "Creating Market Depth WebSocket connection..."
40
-
41
- # Find instruments using the new .find method (now uses underlying_symbol for equity)
42
- reliance_instrument = DhanHQ::Models::Instrument.find("NSE_EQ", "RELIANCE")
43
- tcs_instrument = DhanHQ::Models::Instrument.find("NSE_EQ", "TCS")
44
-
45
- # Define symbols with correct exchange segments and security IDs
46
- symbols = []
47
- if reliance_instrument
48
- symbols << { symbol: "RELIANCE", exchange_segment: reliance_instrument.exchange_segment,
49
- security_id: reliance_instrument.security_id }
50
- puts "✅ Found RELIANCE: #{reliance_instrument.symbol_name} (#{reliance_instrument.exchange_segment}:#{reliance_instrument.security_id})"
51
- else
52
- puts "❌ Could not find RELIANCE INDUSTRIES LTD"
53
- end
54
-
55
- if tcs_instrument
56
- symbols << { symbol: "TCS", exchange_segment: tcs_instrument.exchange_segment,
57
- security_id: tcs_instrument.security_id }
58
- puts "✅ Found TCS: #{tcs_instrument.symbol_name} (#{tcs_instrument.exchange_segment}:#{tcs_instrument.security_id})"
59
- else
60
- puts "❌ Could not find TATA CONSULTANCY SERV LT"
61
- end
62
-
63
- if symbols.empty?
64
- puts "❌ No symbols found. Exiting..."
65
- exit(1)
66
- end
67
-
68
- depth_client = DhanHQ::WS::MarketDepth.connect(symbols: symbols) do |depth_data|
69
- puts "Market Depth: #{depth_data[:symbol]}"
70
- puts " Best Bid: #{depth_data[:best_bid]}"
71
- puts " Best Ask: #{depth_data[:best_ask]}"
72
- puts " Spread: #{depth_data[:spread]}"
73
- puts " Bid Levels: #{depth_data[:bids].size}"
74
- puts " Ask Levels: #{depth_data[:asks].size}"
75
-
76
- # Show top 3 bid/ask levels if available
77
- if depth_data[:bids]&.size&.positive?
78
- puts " Top Bids:"
79
- depth_data[:bids].first(3).each_with_index do |bid, i|
80
- puts " #{i + 1}. Price: #{bid[:price]}, Qty: #{bid[:quantity]}"
81
- end
82
- end
83
-
84
- if depth_data[:asks]&.size&.positive?
85
- puts " Top Asks:"
86
- depth_data[:asks].first(3).each_with_index do |ask, i|
87
- puts " #{i + 1}. Price: #{ask[:price]}, Qty: #{ask[:quantity]}"
88
- end
89
- end
90
-
91
- puts " ---"
92
- end
93
-
94
- # Add event handlers for different depth events
95
- puts "\nSetting up event handlers..."
96
-
97
- depth_client.on(:depth_update) do |update_data|
98
- puts "📊 Depth Update: #{update_data[:symbol]} - #{update_data[:side]} side updated"
99
- end
100
-
101
- depth_client.on(:depth_snapshot) do |snapshot_data|
102
- puts "📸 Depth Snapshot: #{snapshot_data[:symbol]} - Full order book received"
103
- end
104
-
105
- depth_client.on(:error) do |error|
106
- puts "⚠️ WebSocket Error: #{error}"
107
- end
108
-
109
- depth_client.on(:close) do |close_info|
110
- if close_info.is_a?(Hash)
111
- puts "🔌 WebSocket Closed: #{close_info[:code]} - #{close_info[:reason]}"
112
- else
113
- puts "🔌 WebSocket Closed: #{close_info}"
114
- end
115
- end
116
-
117
- puts "\nMarket Depth WebSocket connected successfully!"
118
- puts "Waiting 30 seconds to receive market depth data..."
119
- puts "Press Ctrl+C to stop early"
120
- puts ""
121
-
122
- # Wait for market depth data
123
- begin
124
- sleep(30)
125
- rescue Interrupt
126
- puts "\nStopping early due to user interrupt..."
127
- end
128
-
129
- # Graceful shutdown
130
- puts "\nShutting down Market Depth WebSocket connection..."
131
- depth_client.stop
132
-
133
- puts "Market Depth WebSocket connection closed."
134
- puts "Example completed!"
135
- puts ""
136
- puts "Summary:"
137
- puts "- Successfully demonstrated Market Depth WebSocket"
138
- puts "- Real-time bid/ask level tracking:"
139
- puts " * RELIANCE (Reliance Industries) - dynamically resolved using .find method"
140
- puts " * TCS (Tata Consultancy Services) - dynamically resolved using .find method"
141
- puts "- Order book depth visualization"
142
- puts "- Used single connection to avoid rate limiting (429 errors)"
143
- puts "- Proper connection cleanup prevents resource leaks"
144
- puts "- Dynamic symbol resolution using DhanHQ::Models::Instrument.find"
@@ -1,81 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # Market Feed WebSocket Example
5
- # This script demonstrates how to use the DhanHQ Market Feed WebSocket
6
- # Subscribes to major Indian indices (NIFTY, BANKNIFTY, NIFTYIT, SENSEX)
7
- # NOTE: Uses a SINGLE connection to avoid rate limiting
8
-
9
- require "dhan_hq"
10
-
11
- # Configure DhanHQ
12
- DhanHQ.configure do |config|
13
- config.client_id = ENV["DHAN_CLIENT_ID"] || "your_client_id"
14
- config.access_token = ENV["DHAN_ACCESS_TOKEN"] || "your_access_token"
15
- config.ws_user_type = ENV["DHAN_WS_USER_TYPE"] || "SELF"
16
- end
17
-
18
- puts "DhanHQ Market Feed WebSocket Example"
19
- puts "===================================="
20
- puts "Subscribing to major Indian indices:"
21
- puts "- NIFTY (Nifty 50)"
22
- puts "- BANKNIFTY (Nifty Bank)"
23
- puts "- NIFTYIT (Nifty IT)"
24
- puts "- SENSEX (Sensex)"
25
- puts ""
26
- puts "NOTE: Using SINGLE connection to avoid rate limiting (429 errors)"
27
- puts "Dhan allows up to 5 WebSocket connections per user"
28
- puts ""
29
-
30
- # Market Feed WebSocket Connection
31
- puts "Market Feed WebSocket Connection"
32
- puts "================================"
33
-
34
- # Create a single market feed WebSocket connection
35
- puts "Creating Market Feed WebSocket connection..."
36
- market_client = DhanHQ::WS.connect(mode: :ticker) do |tick|
37
- timestamp = tick[:ts] ? Time.at(tick[:ts]) : Time.now
38
- puts "Market Data: #{tick[:segment]}:#{tick[:security_id]} = #{tick[:ltp]} at #{timestamp}"
39
- end
40
-
41
- # Subscribe to specific IDX_I instruments only
42
- # Note: IDX_I is the correct segment for index instruments
43
- puts "\nSubscribing to IDX_I instruments:"
44
- puts "- Security ID 13: NIFTY (Nifty 50)"
45
- puts "- Security ID 25: BANKNIFTY (Nifty Bank)"
46
- puts "- Security ID 29: NIFTYIT (Nifty IT)"
47
- puts "- Security ID 51: SENSEX (Sensex)"
48
-
49
- market_client.subscribe_one(segment: "IDX_I", security_id: "13") # NIFTY (Nifty 50)
50
- market_client.subscribe_one(segment: "IDX_I", security_id: "25") # BANKNIFTY (Nifty Bank)
51
- market_client.subscribe_one(segment: "IDX_I", security_id: "29") # NIFTYIT (Nifty IT)
52
- market_client.subscribe_one(segment: "IDX_I", security_id: "51") # SENSEX (Sensex)
53
-
54
- puts "\nMarket Feed WebSocket connected successfully!"
55
- puts "Waiting 15 seconds to receive market data..."
56
- puts "Press Ctrl+C to stop early"
57
- puts ""
58
-
59
- # Wait for market data
60
- begin
61
- sleep(15)
62
- rescue Interrupt
63
- puts "\nStopping early due to user interrupt..."
64
- end
65
-
66
- # Graceful shutdown
67
- puts "\nShutting down WebSocket connection..."
68
- market_client.stop
69
-
70
- puts "WebSocket connection closed."
71
- puts "Example completed!"
72
- puts ""
73
- puts "Summary:"
74
- puts "- Successfully demonstrated IDX_I subscriptions:"
75
- puts " * Security ID 13: NIFTY (Nifty 50)"
76
- puts " * Security ID 25: BANKNIFTY (Nifty Bank)"
77
- puts " * Security ID 29: NIFTYIT (Nifty IT)"
78
- puts " * Security ID 51: SENSEX (Sensex)"
79
- puts "- Used single connection to avoid rate limiting (429 errors)"
80
- puts "- Proper connection cleanup prevents resource leaks"
81
- puts "- No multiple connection issues!"
@@ -1,105 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # Order Update WebSocket Example
5
- # This script demonstrates how to use the DhanHQ Order Update WebSocket
6
- # Receives real-time order status updates and execution notifications
7
- # NOTE: Uses a SINGLE connection to avoid rate limiting
8
-
9
- require "dhan_hq"
10
-
11
- # Configure DhanHQ
12
- DhanHQ.configure do |config|
13
- config.client_id = ENV["DHAN_CLIENT_ID"] || "your_client_id"
14
- config.access_token = ENV["DHAN_ACCESS_TOKEN"] || "your_access_token"
15
- config.ws_user_type = ENV["DHAN_WS_USER_TYPE"] || "SELF"
16
- end
17
-
18
- puts "DhanHQ Order Update WebSocket Example"
19
- puts "====================================="
20
- puts "Receives real-time order updates including:"
21
- puts "- Order status changes"
22
- puts "- Execution notifications"
23
- puts "- Order rejections"
24
- puts "- Trade confirmations"
25
- puts ""
26
- puts "NOTE: Using SINGLE connection to avoid rate limiting (429 errors)"
27
- puts "Dhan allows up to 5 WebSocket connections per user"
28
- puts ""
29
-
30
- # Order Update WebSocket Connection
31
- puts "Order Update WebSocket Connection"
32
- puts "================================="
33
-
34
- # Create a single order update WebSocket connection
35
- puts "Creating Order Update WebSocket connection..."
36
- orders_client = DhanHQ::WS::Orders.connect do |order_update|
37
- puts "Order Update: #{order_update.order_no} - #{order_update.status}"
38
- puts " Symbol: #{order_update.symbol}"
39
- puts " Quantity: #{order_update.quantity}"
40
- puts " Traded Qty: #{order_update.traded_qty}"
41
- puts " Price: #{order_update.price}"
42
- puts " Execution: #{order_update.execution_percentage}%"
43
- puts " ---"
44
- end
45
-
46
- # Add event handlers for different order events
47
- puts "\nSetting up event handlers..."
48
-
49
- orders_client.on(:update) do |order_update|
50
- puts "📝 Order Updated: #{order_update.order_no} - #{order_update.status}"
51
- end
52
-
53
- orders_client.on(:status_change) do |change_data|
54
- puts "🔄 Status Changed: #{change_data[:previous_status]} -> #{change_data[:new_status]}"
55
- end
56
-
57
- orders_client.on(:execution) do |execution_data|
58
- puts "✅ Execution: #{execution_data[:new_traded_qty]} shares executed"
59
- end
60
-
61
- orders_client.on(:order_traded) do |order_update|
62
- puts "💰 Order Traded: #{order_update.order_no} - #{order_update.symbol}"
63
- end
64
-
65
- orders_client.on(:order_rejected) do |order_update|
66
- puts "❌ Order Rejected: #{order_update.order_no} - #{order_update.reason_description}"
67
- end
68
-
69
- orders_client.on(:error) do |error|
70
- puts "⚠️ WebSocket Error: #{error}"
71
- end
72
-
73
- orders_client.on(:close) do |close_info|
74
- if close_info.is_a?(Hash)
75
- puts "🔌 WebSocket Closed: #{close_info[:code]} - #{close_info[:reason]}"
76
- else
77
- puts "🔌 WebSocket Closed: #{close_info}"
78
- end
79
- end
80
-
81
- puts "\nOrder Update WebSocket connected successfully!"
82
- puts "Waiting 30 seconds to receive order updates..."
83
- puts "Press Ctrl+C to stop early"
84
- puts ""
85
-
86
- # Wait for order updates
87
- begin
88
- sleep(30)
89
- rescue Interrupt
90
- puts "\nStopping early due to user interrupt..."
91
- end
92
-
93
- # Graceful shutdown
94
- puts "\nShutting down Order Update WebSocket connection..."
95
- orders_client.stop
96
-
97
- puts "Order Update WebSocket connection closed."
98
- puts "Example completed!"
99
- puts ""
100
- puts "Summary:"
101
- puts "- Successfully demonstrated Order Update WebSocket"
102
- puts "- Real-time order status tracking"
103
- puts "- Multiple event handlers for different order events"
104
- puts "- Used single connection to avoid rate limiting (429 errors)"
105
- puts "- Proper connection cleanup prevents resource leaks"
@@ -1,215 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # DhanHQ Trading Fields Example
5
- # This script demonstrates how to use the new trading fields in the Instrument model
6
- # for practical trading operations and risk management
7
-
8
- require "dhan_hq"
9
-
10
- # Configure DhanHQ
11
- DhanHQ.configure do |config|
12
- config.client_id = ENV["DHAN_CLIENT_ID"] || "your_client_id"
13
- config.access_token = ENV["DHAN_ACCESS_TOKEN"] || "your_access_token"
14
- config.ws_user_type = ENV["DHAN_WS_USER_TYPE"] || "SELF"
15
- end
16
-
17
- puts "DhanHQ Trading Fields Example"
18
- puts "============================="
19
- puts "Demonstrating essential trading fields for risk management and order validation"
20
- puts ""
21
-
22
- # Helper method to display trading information
23
- def display_trading_info(instrument, name)
24
- return unless instrument
25
-
26
- puts "✅ #{name} Trading Information:"
27
- puts " Symbol: #{instrument.symbol_name}"
28
- puts " Underlying Symbol: #{instrument.underlying_symbol}" if instrument.underlying_symbol
29
- puts " Security ID: #{instrument.security_id}"
30
- puts " ISIN: #{instrument.isin}"
31
- puts " Instrument Type: #{instrument.instrument_type}"
32
- puts " Exchange Segment: #{instrument.exchange_segment}"
33
- puts " Lot Size: #{instrument.lot_size}"
34
- puts " Tick Size: #{instrument.tick_size}"
35
- puts " Expiry Flag: #{instrument.expiry_flag}"
36
- puts " Bracket Flag: #{instrument.bracket_flag}"
37
- puts " Cover Flag: #{instrument.cover_flag}"
38
- puts " ASM/GSM Flag: #{instrument.asm_gsm_flag}"
39
- puts " ASM/GSM Category: #{instrument.asm_gsm_category}" if instrument.asm_gsm_category != "NA"
40
- puts " Buy/Sell Indicator: #{instrument.buy_sell_indicator}"
41
- puts " Buy CO Min Margin %: #{instrument.buy_co_min_margin_per}"
42
- puts " Sell CO Min Margin %: #{instrument.sell_co_min_margin_per}"
43
- puts " MTF Leverage: #{instrument.mtf_leverage}"
44
- puts ""
45
- end
46
-
47
- # Helper method to check trading eligibility
48
- def check_trading_eligibility(instrument, name)
49
- return unless instrument
50
-
51
- puts "🔍 #{name} Trading Eligibility Check:"
52
-
53
- # Check if instrument allows trading
54
- if instrument.buy_sell_indicator == "A"
55
- puts " ✅ Trading Allowed"
56
- else
57
- puts " ❌ Trading Not Allowed"
58
- return
59
- end
60
-
61
- # Check bracket orders
62
- if instrument.bracket_flag == "Y"
63
- puts " ✅ Bracket Orders Allowed"
64
- else
65
- puts " ❌ Bracket Orders Not Allowed"
66
- end
67
-
68
- # Check cover orders
69
- if instrument.cover_flag == "Y"
70
- puts " ✅ Cover Orders Allowed"
71
- else
72
- puts " ❌ Cover Orders Not Allowed"
73
- end
74
-
75
- # Check ASM/GSM status
76
- if instrument.asm_gsm_flag == "Y"
77
- puts " ⚠️ ASM/GSM Applied: #{instrument.asm_gsm_category}"
78
- else
79
- puts " ✅ No ASM/GSM Restrictions"
80
- end
81
-
82
- # Check expiry
83
- if instrument.expiry_flag == "Y"
84
- puts " ⚠️ Instrument Has Expiry: #{instrument.expiry_date}"
85
- else
86
- puts " ✅ No Expiry (Perpetual)"
87
- end
88
-
89
- puts ""
90
- end
91
-
92
- # Helper method to calculate margin requirements
93
- def calculate_margin_requirements(instrument, name, quantity, price)
94
- return unless instrument
95
-
96
- puts "💰 #{name} Margin Calculation:"
97
- puts " Quantity: #{quantity}"
98
- puts " Price: ₹#{price}"
99
- puts " Lot Size: #{instrument.lot_size}"
100
-
101
- total_value = quantity * price * instrument.lot_size
102
- puts " Total Value: ₹#{total_value}"
103
-
104
- # Calculate margin requirements
105
- buy_margin = total_value * (instrument.buy_co_min_margin_per / 100.0)
106
- sell_margin = total_value * (instrument.sell_co_min_margin_per / 100.0)
107
-
108
- puts " Buy CO Margin Required: ₹#{buy_margin}"
109
- puts " Sell CO Margin Required: ₹#{sell_margin}"
110
-
111
- # Calculate MTF leverage
112
- if instrument.mtf_leverage.positive?
113
- mtf_value = total_value * instrument.mtf_leverage
114
- puts " MTF Leverage: #{instrument.mtf_leverage}x"
115
- puts " MTF Value: ₹#{mtf_value}"
116
- end
117
-
118
- puts ""
119
- end
120
-
121
- puts "1. Finding Instruments with Trading Fields"
122
- puts "=" * 50
123
-
124
- # Find popular trading instruments
125
- reliance = DhanHQ::Models::Instrument.find("NSE_EQ", "RELIANCE")
126
- tcs = DhanHQ::Models::Instrument.find("NSE_EQ", "TCS")
127
- hdfc = DhanHQ::Models::Instrument.find("NSE_EQ", "HDFC")
128
- nifty = DhanHQ::Models::Instrument.find("IDX_I", "NIFTY")
129
- banknifty = DhanHQ::Models::Instrument.find("IDX_I", "BANKNIFTY")
130
-
131
- # Display trading information
132
- display_trading_info(reliance, "RELIANCE")
133
- display_trading_info(tcs, "TCS")
134
- display_trading_info(hdfc, "HDFC")
135
- display_trading_info(nifty, "NIFTY")
136
- display_trading_info(banknifty, "BANKNIFTY")
137
-
138
- puts "2. Trading Eligibility Checks"
139
- puts "=" * 40
140
-
141
- # Check trading eligibility
142
- check_trading_eligibility(reliance, "RELIANCE")
143
- check_trading_eligibility(tcs, "TCS")
144
- check_trading_eligibility(nifty, "NIFTY")
145
-
146
- puts "3. Margin Calculations"
147
- puts "=" * 25
148
-
149
- # Calculate margin requirements for different scenarios
150
- calculate_margin_requirements(reliance, "RELIANCE", 10, 2500)
151
- calculate_margin_requirements(tcs, "TCS", 5, 3500)
152
- calculate_margin_requirements(nifty, "NIFTY", 1, 20_000)
153
-
154
- puts "4. Practical Trading Scenarios"
155
- puts "=" * 35
156
-
157
- # Scenario 1: Check if instrument supports bracket orders
158
- puts "Scenario 1: Bracket Order Support"
159
- puts "-" * 30
160
- instruments = [reliance, tcs, hdfc, nifty, banknifty]
161
- instruments.each do |instrument|
162
- next unless instrument
163
-
164
- puts "#{instrument.underlying_symbol || instrument.symbol_name}: #{instrument.bracket_flag == "Y" ? "✅ Supports" : "❌ No Support"}"
165
- end
166
- puts ""
167
-
168
- # Scenario 2: Find instruments with ASM/GSM restrictions
169
- puts "Scenario 2: ASM/GSM Restricted Instruments"
170
- puts "-" * 40
171
- asm_instruments = instruments.select { |i| i&.asm_gsm_flag == "Y" }
172
- if asm_instruments.any?
173
- asm_instruments.each do |instrument|
174
- puts "#{instrument.underlying_symbol || instrument.symbol_name}: #{instrument.asm_gsm_category}"
175
- end
176
- else
177
- puts "No ASM/GSM restricted instruments found in sample"
178
- end
179
- puts ""
180
-
181
- # Scenario 3: Find instruments with high MTF leverage
182
- puts "Scenario 3: High MTF Leverage Instruments"
183
- puts "-" * 40
184
- high_leverage = instruments.select { |i| i&.mtf_leverage && i.mtf_leverage > 3.0 }
185
- if high_leverage.any?
186
- high_leverage.each do |instrument|
187
- puts "#{instrument.underlying_symbol || instrument.symbol_name}: #{instrument.mtf_leverage}x leverage"
188
- end
189
- else
190
- puts "No high leverage instruments found in sample"
191
- end
192
- puts ""
193
-
194
- puts "5. Trading Field Summary"
195
- puts "=" * 25
196
- puts "Essential trading fields now available:"
197
- puts "✅ ISIN - International Securities Identification Number"
198
- puts "✅ Instrument Type - Classification (ES, INDEX, etc.)"
199
- puts "✅ Expiry Flag - Whether instrument has expiry"
200
- puts "✅ Bracket Flag - Bracket order support"
201
- puts "✅ Cover Flag - Cover order support"
202
- puts "✅ ASM/GSM Flag - Additional Surveillance Measure status"
203
- puts "✅ Buy/Sell Indicator - Trading permission"
204
- puts "✅ Margin Requirements - CO minimum margin percentages"
205
- puts "✅ MTF Leverage - Margin Trading Facility leverage"
206
- puts ""
207
-
208
- puts "Example completed!"
209
- puts "=================="
210
- puts "These trading fields enable:"
211
- puts "- Order validation and eligibility checks"
212
- puts "- Margin requirement calculations"
213
- puts "- Risk management and compliance"
214
- puts "- Trading strategy implementation"
215
- puts "- Regulatory compliance monitoring"