To use the Roll-method, activate the roll plugin
require 'ib-api' ib = IB::Connection.new ib.activate_plugin :roll ib.try_connection!
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.
ib = IB::Connection.new
ib.activate_plugin :roll, :verify, :symbols
existing_option = IB::Symbols::Options.stoxx.merge( strike: 5000, right: :put )
puts existing_option.verify.first.to_human
=> "<Option: ESTX50 20240719 put 5000.0 EUREX EUR>"
Setup
Assuming an existing portfolio-position of that option (short put).
To roll this option to the next expiry
roll_option = existing_option.roll to: '1m'
puts roll_option.as_table
┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│ buy 1 <Option: ESTX50 20240719 put 5000.0 EUREX EUR> │
│ sell 1 <Option: ESTX50 20240816 put 5000.0 EUREX EUR> │
├────────┬────────┬─────────────┬──────────┬──────────┬───────────────┬───────┬────────┬──────────┤
│ │ symbol │ con_id │ exchange │ expiry │ trading-class │ right │ strike │ currency │
╞════════╪════════╪═════════════╪══════════╪══════════╪═══════════════╪═══════╪════════╪══════════╡
│ Spread │ ESTX50 │ -1282528162 │ EUREX │ │ │ │ │ EUR │
│ Option │ ESTX50 │ 638077275 │ EUREX │ 20240719 │ OESX │ put │ 5000.0 │ EUR │
│ Option │ ESTX50 │ 644450887 │ EUREX │ 20240816 │ OESX │ put │ 5000.0 │ EUR │
└────────┴────────┴─────────────┴──────────┴──────────┴───────────────┴───────┴────────┴──────────┘
# or
roll_option = existing_option.roll expiry: 202408
This creates an IB::Spread
:
- buy back the existing option
- sell the target expiry
The spread can be placed the usual way.
The complete example:
ib = IB::Connection.new
ib.activate_plugin :roll, :verify, :symbols, :process_orders, :advanced_account
ib.get_account_data # populate portfolio_values
existing_option = IB::Symbols::Options.stoxx.merge( strike: 5000, right: :put ).verify.first
roll_option = existing_option.roll to: '1m'
ib.clients.each do | user |
existing = user.portfolio_values.find do | pv |
pv.contract.con_id == existing_option.con_id
end
unless existing.nil?
user.place contract: roll_option,
order: Limit.order( action: :buy, size: existing.position, price: -40 )
end
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.