Class: DhanHQ::Skills::Builtin::ProtectivePut

Inherits:
DhanHQ::Skills::Base show all
Defined in:
lib/DhanHQ/skills/builtin/protective_put.rb

Overview

Skill to build a protective put strategy (buy stock, buy OTM put).

Steps: find instrument → spot price → option chain → select OTM put → build intent.

Examples:

result = DhanHQ::Skills::Registry.call("protective_put",
  symbol: "RELIANCE",
  expiry: "2026-01-30",
  quantity: 100
)

Instance Method Summary collapse

Methods inherited from DhanHQ::Skills::Base

#call, description, #description, #name, param, #param_definitions, params, risk, scope, step, steps, validate_params!

Instance Method Details

#build_intent(ctx) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/DhanHQ/skills/builtin/protective_put.rb', line 73

def build_intent(ctx)
  ctx[:intent] = {
    trade_type: "PROTECTIVE_PUT",
    symbol: ctx[:symbol],
    quantity: ctx[:quantity],
    legs: [
      { action: DhanHQ::Constants::TransactionType::BUY, instrument_type: DhanHQ::Constants::InstrumentType::EQUITY, security_id: ctx[:equity_security_id],
        quantity: ctx[:quantity] },
      { action: DhanHQ::Constants::TransactionType::BUY, option_type: "PE", strike: ctx[:put_strike], security_id: ctx[:put_security_id], quantity: ctx[:quantity], premium: ctx[:put_premium] }
    ],
    note: "Protective put prepared: Buy #{ctx[:quantity]} #{ctx[:symbol]}, Buy #{ctx[:quantity]} #{ctx[:put_strike]} PE. Await human confirmation."
  }
  ctx
end

#find_instrument(ctx) ⇒ Object



35
36
37
38
# File 'lib/DhanHQ/skills/builtin/protective_put.rb', line 35

def find_instrument(ctx)
  ctx[:instrument] = DhanHQ::Models::Instrument.find(DhanHQ::Constants::ExchangeSegment::NSE_EQ, ctx[:symbol])
  ctx
end

#get_option_chain(ctx) ⇒ Object



45
46
47
48
# File 'lib/DhanHQ/skills/builtin/protective_put.rb', line 45

def get_option_chain(ctx)
  ctx[:chain] = ctx[:instrument].option_chain(expiry: ctx[:expiry])
  ctx
end

#get_spot_price(ctx) ⇒ Object



40
41
42
43
# File 'lib/DhanHQ/skills/builtin/protective_put.rb', line 40

def get_spot_price(ctx)
  ctx[:spot_price] = ctx[:instrument].ltp
  ctx
end

#select_otm_put(ctx) ⇒ Object

Raises:

  • (ArgumentError)


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/DhanHQ/skills/builtin/protective_put.rb', line 50

def select_otm_put(ctx)
  spot = ctx[:spot_price].to_f
  chain = ctx[:chain]
  offset_pct = ctx[:strike_offset] / 100.0
  max_prem = ctx[:max_premium_pct] / 100.0

  target_strike = spot * (1 - offset_pct)
  otm_put = nearest_strike(chain, target_strike)

  raise ArgumentError, "Could not find suitable OTM put strike near #{target_strike}" unless otm_put

  premium = leg_premium(otm_put, "PE").to_f
  premium_pct = premium / spot

  raise ArgumentError, "Put premium #{premium_pct * 100}% exceeds max #{ctx[:max_premium_pct]}%" if premium_pct > max_prem

  ctx[:put_strike] = otm_put[:strike]
  ctx[:put_security_id] = leg_security_id(otm_put, "PE")
  ctx[:put_premium] = premium
  ctx[:equity_security_id] = ctx[:instrument].security_id
  ctx
end