Module: DhanHQ::Agent::ToolHandlers

Included in:
ToolCatalogue
Defined in:
lib/DhanHQ/agent/tool_handlers.rb

Overview

Callables that carry out each agent tool, one per tool.

Every handler takes a hash of symbolized arguments and returns a model, a plain hash, or a boolean. Policy enforcement happens before a handler is reached — see DhanHQ::Agent::ToolRegistry#execute — so handlers here contain no scope or live-trading checks of their own; the resources they call apply the LIVE_TRADING gate and audit logging.

Class Method Summary collapse

Class Method Details

.cancel_order_handlerObject



56
57
58
59
60
61
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 56

def cancel_order_handler
  lambda do |arguments|
    order = DhanHQ::Models::Order.find(arguments[:order_id])
    order&.cancel || false
  end
end

.funds_handlerObject



17
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 17

def funds_handler = ->(_) { DhanHQ::Models::Funds.fetch }

.global_cancel_order_handlerObject



106
107
108
109
110
111
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 106

def global_cancel_order_handler
  lambda do |arguments|
    order_id = arguments[:order_id]
    { order_id: order_id, cancelled: DhanHQ::Models::GlobalStocks::Order.cancel(order_id) }
  end
end

.global_estimate_handlerObject

Combines the charge estimate and the margin requirement so an agent can decide affordability in one call rather than two.



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 86

def global_estimate_handler
  lambda do |arguments|
    estimate = DhanHQ::Models::GlobalStocks::OrderEstimate.calculate(arguments)
    margin = DhanHQ::Models::GlobalStocks::Margin.calculate(arguments)
    {
      total_charges: estimate.total_charges,
      brokerage: estimate.brokerage,
      total_margin: margin.total_margin,
      available_balance: margin.available_bal,
      sufficient: margin.sufficient?
    }
  end
end

.global_funds_handlerObject



65
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 65

def global_funds_handler = ->(_) { DhanHQ::Models::GlobalStocks::Funds.fetch }

.global_holdings_handlerObject



63
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 63

def global_holdings_handler = ->(_) { DhanHQ::Models::GlobalStocks::Holding.all }

.global_market_status_handlerObject



71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 71

def global_market_status_handler
  lambda do |_|
    status = DhanHQ::Models::GlobalStocks::MarketStatus.fetch
    {
      status: status.status,
      open: status.open?,
      holiday: status.holiday?,
      market_open_time: status.market_open_time,
      market_close_time: status.market_close_time
    }
  end
end

.global_orders_handlerObject



67
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 67

def global_orders_handler = ->(_) { DhanHQ::Models::GlobalStocks::Order.all }

.global_place_order_handlerObject

No Risk::Pipeline run here: its checks resolve instruments from the Indian scrip master and encode NSE/BSE rules, neither of which applies to US equities. The LIVE_TRADING gate and audit logging in the resource still apply, as does Policy#require_write!.



104
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 104

def global_place_order_handler = ->(arguments) { DhanHQ::Models::GlobalStocks::Order.place(arguments) }

.global_trades_handlerObject



69
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 69

def global_trades_handler = ->(_) { DhanHQ::Models::GlobalStocks::Trade.all }

.holdings_handlerObject



19
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 19

def holdings_handler = ->(_) { DhanHQ::Models::Holding.all }

.ltp_handlerObject



35
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 35

def ltp_handler = ->(arguments) { DhanHQ::Models::MarketFeed.ltp(arguments[:instruments]) }

.multi_order_handlerObject



113
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 113

def multi_order_handler = ->(arguments) { DhanHQ::Models::MultiOrder.place(arguments[:orders]) }

.orders_handlerObject



23
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 23

def orders_handler = ->(_) { DhanHQ::Models::Order.all }

.place_order_handlerObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 41

def place_order_handler
  lambda do |arguments|
    instrument = DhanHQ::Models::Instrument.find_by_security_id(arguments[:exchange_segment], arguments[:security_id])
    unless instrument
      raise DhanHQ::RiskViolation,
            "Cannot verify risk for unknown instrument: #{arguments[:exchange_segment]}:#{arguments[:security_id]}"
    end

    risk_type = instrument.instrument_type.to_s.start_with?("OPT") ? :options : :equity
    DhanHQ::Risk::Pipeline.run!(instrument: instrument, args: KeyCoercion.stringify(arguments), type: risk_type)

    DhanHQ::Models::Order.place(arguments)
  end
end

.positions_handlerObject



21
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 21

def positions_handler = ->(_) { DhanHQ::Models::Position.all }

.preview_handlerObject



39
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 39

def preview_handler = ->(arguments) { OrderPreview.new(arguments).to_h }

.profile_handlerObject



15
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 15

def profile_handler = ->(_) { DhanHQ::Models::Profile.fetch }

.quote_handlerObject



37
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 37

def quote_handler = ->(arguments) { DhanHQ::Models::MarketFeed.quote(arguments[:instruments]) }

.search_handlerObject



27
28
29
30
31
32
33
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 27

def search_handler
  lambda do |arguments|
    query = arguments.fetch(:query)
    options = arguments.except(:query)
    DhanHQ::Models::Instrument.search(query, **options)
  end
end

.trades_handlerObject



25
# File 'lib/DhanHQ/agent/tool_handlers.rb', line 25

def trades_handler = ->(_) { DhanHQ::Models::Trade.today }