The GUI-Version of the TWS organizes symbols in different pages (Watchlists).

IB-Ruby uses the same concept to organize and optimize operational issues and to support research and systematic trading efforts. The lists are organized as Enumerator, which extents its use. This feature lives entirely in the filesystem, no database is required, no further dependency is involved.

By default, Watchlists reside in the symbols-directory of ib-symbols. This can be changed anytime through

 IB::Symbols.set_origin '.'  # (a valid path, either relative or absolute)
 => #<Pathname:.> 
 IB::Symbols.set_origin( "." ).realpath
 => #<Pathname:/home/ubuntu/workspace/ib-ruby/bin>

Watchlists are used to organize the output of IB::Account.portfolio_values. If IB::Gateway is called with a :watchlist-parameter, IB::Account.focuses is initialized and portfolio-entries are grouped by their occurrence in provided watchlists. In particular, if complex contracts are defined in a watchlist, they are restored in IB::Account.focuses when the response to :RequestAccountData-Message is processed.

Symbol Collections

Everything is kept elementary simple: Collections are stored as editable files. The format is YAML.

The CRUD Cycle

 IB::Symbols.allocate_collection :Demo
  => IB::Symbols::Demo           # file /symbols/Demo is created 
 IB::Symbols::Demo.add_contract :uso , IB::Stock.new( symbol: 'USO'  )
  => 235                         # returns the count of written bytes to the file 
 IB::Symbols::Demo.uso          # returns the stored contract
	=> #<IB::Stock:0x0000000002c814f8 @attributes={:symbol=>"USO", :created_at=>2018-04-29 18:47:01 +0000, :con_id=>0, :right=>"", :exchange=>"SMART", :include_expired=>false, :sec_type=>"STK", :currency=>"USD"}> 
 IB::Symbols::Demo.add_contract :ford , IB::Stock.new( symbol: 'F'  )
  => 465 
 IB::Symbols::Demo.all
	=> [:ford, :uso]               # lists all stored contracts
 IB::Symbols::Demo.remove_contract :uso
 IB::Symbols::Demo.all
  => [:ford] 
 IB::Symbols::Demo.purge_collection  # deletes the file and erases contracts kept in memory
	=> nil 

 IB::Symbols::Demo.all
  => [] 

Using the Collection to Trade Complex Contracts

Any IB::Contract can be stored in the Collection. The composition of suitable Contracts and their trading can be separated using Collections as handy Contract-Stores.

If – for instant – trading-ideas for several scenarios are outlined, Collections can act as easy and transparent stores. Occasionally the stored trading-concepts can be transmitted.

 bear = IB::Symbols.allocate_collection :BearishSzenario
 bear.add_contract :bear_spread_3000_2400, 
       IB::Vertical.new(  underlying: IB::Symbols::Index.stoxx, sell: 2500, buy: 3000,
                         right: :put, expiry: 201903)
 neutral = IB::Symbols.allocate_collection :NeurtalSzenario
 neutral.add_contract :slight_defensive_straddle, 
       IB::Straddle.new( underlying: IB::Symbols::Index.stoxx, strike: 3200, expiry: 291893 )

Option Chains

Dynamically allocated Collections implement an Enumerator of IB::Contracts. This has neat consequences.

First read an option chain into the collection

 IB::Symbols.allocate_collection :Test
 IB::Symbols::Options.ibm_lazy_strike.verify{|y| Symbols::Test.add_contract y.strike.to_i, y }  

29 Options are stored in the collection.

They can be inspected and manipulated as comfortably as ordinary arrays:

 IB::Symbols::Test.size                           => 29
 IB::Symbols::Test.first.to_human                 
  => "<Option: IBM 20180921 put 100.0 SMART USD>"  
 IB::Symbols::Test.map &:strike
  => [100.0, 105.0, 110.0, 115.0, 120.0, 125.0, 130.0, 135.0, 140.0, 145.0, 150.0, 155.0, 160.0, 165.0, 170.0, 175.0, 180.0, 185.0, 190.0, 195.0, 200.0, 210.0, 220.0, 230.0, 80.0, 85.0, 90.0, 95.0, 75.0] 
 IB::Symbols::Test[100].to_human                
  => "<Option: IBM 20180921 put 100.0 SMART USD>"
 IB::Symbols::Test.find{| x | x.strike == 130 }.to_human
  => "<Option: IBM 20180921 put 130.0 SMART USD>" 
 puts IB::Symbols::Test.find_all {| x | x.strike > 130 && x.strike < 190 }.to_human.join "\n"
		<Option: IBM 20180921 put 135.0 SMART USD>
		<Option: IBM 20180921 put 140.0 SMART USD>
		<Option: IBM 20180921 put 145.0 SMART USD>
		<Option: IBM 20180921 put 150.0 SMART USD>
		<Option: IBM 20180921 put 155.0 SMART USD>
		<Option: IBM 20180921 put 160.0 SMART USD>
		<Option: IBM 20180921 put 165.0 SMART USD>
		<Option: IBM 20180921 put 170.0 SMART USD>
		<Option: IBM 20180921 put 175.0 SMART USD>
		<Option: IBM 20180921 put 180.0 SMART USD>
		<Option: IBM 20180921 put 185.0 SMART USD>
 puts IB::Symbols::Test.sort{|x,y| x.strike <=> y.strike }.to_human.join("\n")
		<Option: IBM 20180921 put 75.0 SMART USD>
		<Option: IBM 20180921 put 80.0 SMART USD>
		<Option: IBM 20180921 put 85.0 SMART USD>
		<Option: IBM 20180921 put 90.0 SMART USD>
		<Option: IBM 20180921 put 95.0 SMART USD>
		<Option: IBM 20180921 put 100.0 SMART USD>
		<Option: IBM 20180921 put 105.0 SMART USD>
		<Option: IBM 20180921 put 110.0 SMART USD>
		<Option: IBM 20180921 put 115.0 SMART USD>
		<Option: IBM 20180921 put 120.0 SMART USD>
		<Option: IBM 20180921 put 125.0 SMART USD>
		<Option: IBM 20180921 put 130.0 SMART USD>
		<Option: IBM 20180921 put 135.0 SMART USD>
		<Option: IBM 20180921 put 140.0 SMART USD>
		<Option: IBM 20180921 put 145.0 SMART USD>
		<Option: IBM 20180921 put 150.0 SMART USD>
		<Option: IBM 20180921 put 155.0 SMART USD>
		<Option: IBM 20180921 put 160.0 SMART USD>
		<Option: IBM 20180921 put 165.0 SMART USD>
		<Option: IBM 20180921 put 170.0 SMART USD>
		<Option: IBM 20180921 put 175.0 SMART USD>
		<Option: IBM 20180921 put 180.0 SMART USD>
		<Option: IBM 20180921 put 185.0 SMART USD>
		<Option: IBM 20180921 put 190.0 SMART USD>
		<Option: IBM 20180921 put 195.0 SMART USD>
		<Option: IBM 20180921 put 200.0 SMART USD>
		<Option: IBM 20180921 put 210.0 SMART USD>
		<Option: IBM 20180921 put 220.0 SMART USD>
		<Option: IBM 20180921 put 230.0 SMART USD>
																																														
Tags: