To use the Roll-method, include the ib-extensions Gem in the Gemfile and note
require 'ib-api' require 'ib/extensions'in your scripts.
Rolling an option into another strike or expiry is a common feature in options-trading.
IB-Ruby
provides a simple ‘Option#roll’ method to accomplish that.
Prerequisites
An existing Option Contract.
ge = IB::Stock.new symbol: :ge
# Get the ATM-Option for the nearest expiry
ge.atm_option.first
=> [2104, [#<IB::Option:0x0000000003077738 @attributes={:symbol=>"ge", :exchange=>"SMART",
:trading_class=>"GE", :multiplier=>100, :currency=>"USD", :last_trading_day=>"2021-04-16",
:strike=>12.5, :right=>"P", :created_at=>2021-03-25 07:40:58.516278968 +0000,
:con_id=>0, :include_expired=>false, :sec_type=>"OPT"}, @metadata={}>]]
ge_option = ge.atm_option[2104].first
ge_option.to_human
"<Option: ge 20210416 put 12.5 SMART USD>"
Setup
Assuming an existing portfolio-position of that option (short put).
To roll this option to the next expiry
roll_option = ge_option.roll 20210507, 12.5
This creates an IB::Spread
:
- buy back GE put 12.5, Apr. 16
- sell GE put 12.5, May 7
Essentially,
roll_option = IB::Spread.new, symbol: 'GE', currency: 'USD', exchange: 'SMART'
roll_option.add_leg ge_option, action: :buy
roll_opton.add_leg IB::Option.new( symbol: 'GE', expiry: 20210507, strike: 12.5 ... ), action: :sell,
is performed.
The spread can be placed the usual way, thus, assuming the gateway-app is used:
G = IB::Gateway.current
orders = G.clients.map do | user |
# get the existing position
the_pv= user.portfolio_values.find do | pv |
pv.contract.con_id == ge_option.con_id
end
# place the order, place returs the order-object
user.place contract: roll_option,
order: Limit.order( action: :buy, size: the_pv.position, price: -0.56 )
end
Notice: If the rolling of an option leads to a collection of some premium (which is the usual case), the Limit-Price is NEGATIVE.