Class: DhanHQ::Skills::Builtin::ProtectivePut
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.
Instance Method Summary
collapse
#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
#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
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
|