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.

Tags: