ib-symbols 1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,41 @@
1
+ module IB
2
+ module Symbols
3
+ module Forex
4
+ extend Symbols
5
+
6
+ def self.contracts
7
+ @contracts ||= define_contracts
8
+ end
9
+
10
+ private
11
+
12
+ # IDEALPRO is for orders over 20,000 and routes to the interbank quote stream.
13
+ # IDEAL is for smaller orders, and has wider spreads/slower execution... generally
14
+ # used for smaller currency conversions. IB::Symbols::Forex contracts are pre-defined
15
+ # on IDEALPRO, if you need something else please define forex contracts manually.
16
+ def self.define_contracts
17
+ @contracts = {}
18
+
19
+ # use combinations of these currencies for pre-defined forex contracts
20
+ currencies = [ "aud", "cad", "chf", "eur", "gbp", "hkd", "jpy", "nzd", "usd" ]
21
+
22
+ # create pairs list from currency list
23
+ pairs = currencies.product(currencies).
24
+ map { |pair| pair.join.upcase unless pair.first == pair.last }.compact
25
+
26
+ # now define each contract
27
+ pairs.each do |pair|
28
+ @contracts[pair.downcase.to_sym] = IB::Forex.new(
29
+ :symbol => pair[0..2],
30
+ :exchange => "IDEALPRO",
31
+ :currency => pair[3..5],
32
+ :local_symbol => pair[0..2]+'.'+pair[3..5],
33
+ :description => pair
34
+ )
35
+ end
36
+
37
+ @contracts
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,137 @@
1
+ # The Futures module tries to guess the front month future using a crude algorithm that
2
+ # does not take into account expiry/rollover day. This will be valid most of the time,
3
+ # but near/after expiry day the next quarter's contract takes over as the volume leader.
4
+
5
+ module IB
6
+ module Symbols
7
+ module Futures
8
+ extend Symbols
9
+
10
+ # Find the next front month of quarterly futures.
11
+ # N.B. This will not work as expected during the front month before expiration, as
12
+ # it will point to the next quarter even though the current month is still valid!
13
+ def self.next_quarter_month time=Time.now
14
+ [3, 6, 9, 12].find { |month| month > time.month } || 3 # for December, next March
15
+ end
16
+
17
+ def self.next_quarter_year time=Time.now
18
+ next_quarter_month(time) < time.month ? time.year + 1 : time.year
19
+ end
20
+
21
+ # WARNING: This is currently broken. It returns the next
22
+ # quarterly expiration month after the current month. Many futures
23
+ # instruments have monthly contracts for the near months. This
24
+ # method will not work for such contracts; it will return the next
25
+ # quarter after the current month, even though the present month
26
+ # has the majority of the trading volume.
27
+ #
28
+ # For example, in early November of 2011, many contracts have the
29
+ # vast majority of their volume in the Nov 2011 contract, but this
30
+ # method will return the Dec 2011 contract instead.
31
+ #
32
+ def self.next_expiry time=Time.now
33
+ "#{ next_quarter_year(time) }#{ sprintf("%02d", next_quarter_month(time)) }"
34
+ end
35
+
36
+ # Convenience method; generates an IB::Future instance for a futures
37
+ # contract with the given parameters.
38
+ #
39
+ # If expiry is nil, it will use the end month of the current
40
+ # quarter. This will be wrong for most contracts most of the time,
41
+ # since most contracts have the majority of their volume in a
42
+ # nearby intraquarter month.
43
+ #
44
+ # It is recommended that you specify an expiration date manually
45
+ # until next_expiry is fixed. Expiry should be a string in the
46
+ # format "YYYYMM", where YYYY is the 4 digit year and MM is the 2
47
+ # digit month. For example, November 2011 is "201111".
48
+ #
49
+ def self.future(base_symbol, exchange, currency, description="", expiry=nil)
50
+ IB::Future.new :symbol => base_symbol,
51
+ :expiry => expiry || next_expiry,
52
+ :exchange => exchange,
53
+ :currency => currency,
54
+ :sec_type => SECURITY_TYPES[:future],
55
+ :description => description
56
+ end
57
+
58
+ def self.contracts
59
+ @contracts.presence ||( super.merge :ym => IB::Future.new(:symbol => "YM",
60
+ :expiry => next_expiry,
61
+ :exchange => "ECBOT",
62
+ :currency => "USD",
63
+ :description => "Mini-DJIA future"),
64
+ :nq => IB::Future.new(:symbol => "NQ",
65
+ :expiry => next_expiry,
66
+ :exchange => "GLOBEX",
67
+ :currency => "USD",
68
+ :multiplier => 20,
69
+ :description => "E-Mini Nasdaq 100 future"),
70
+ :es => IB::Future.new(:symbol => "ES",
71
+ :expiry => next_expiry,
72
+ :exchange => "GLOBEX",
73
+ :currency => "USD",
74
+ :multiplier => 50,
75
+ :description => "E-Mini S&P 500 future"),
76
+ :zn => IB::Future.new( symbol: 'ZN',
77
+ expiry: next_expiry,
78
+ currency: 'USD',
79
+ multiplier: 1000,
80
+ exchange: 'ECBOT',
81
+ description: 'US Treasury Note -- 10 Years'),
82
+ :zb => IB::Future.new( symbol: 'ZB',
83
+ expiry: next_expiry,
84
+ currency: 'USD',
85
+ multiplier: 1000,
86
+ exchange: 'ECBOT',
87
+ description: 'US Treasury Note -- 30 Years'),
88
+ :mini_dax => IB::Future.new( symbol: 'DAX', exchange: 'DTB',
89
+ expiry: next_expiry,
90
+ currency: 'EUR',
91
+ multiplier: 5,
92
+ description: 'Mini DAX-Future'),
93
+ # :dax => IB::Future.new( symbol: 'DAX', exchange: 'DTB',
94
+ # expiry: next_expiry,
95
+ # currency: 'EUR',
96
+ # multiplier: 25,
97
+ # description: 'DAX-Future'),
98
+ :stoxx=> IB::Future.new( symbol: 'ESTX50', exchange: 'DTB',
99
+ expiry: next_expiry,
100
+ currency: 'EUR',
101
+ multiplier: 10,
102
+ description: 'EuroStoxx 50 -Future'),
103
+ :gbp => IB::Future.new(:symbol => "GBP",
104
+ :expiry => next_expiry,
105
+ :exchange => "GLOBEX",
106
+ :currency => "USD",
107
+ :multiplier => 62500,
108
+ :description => "British Pounds future"),
109
+ :eur => IB::Future.new(:symbol => "EUR",
110
+ :expiry => next_expiry,
111
+ :exchange => "GLOBEX",
112
+ :currency => "USD",
113
+ :multiplier => 12500,
114
+ :description => "Euro FX future"),
115
+ :jpy => IB::Future.new(:symbol => "JPY",
116
+ :expiry => next_expiry,
117
+ :exchange => "GLOBEX",
118
+ :currency => "USD",
119
+ :multiplier => 12500000,
120
+ :description => "Japanese Yen future"),
121
+ :hsi => IB::Future.new(:symbol => "HSI",
122
+ :expiry => next_expiry,
123
+ :exchange => "HKFE",
124
+ :currency => "HKD",
125
+ :multiplier => 50,
126
+ :description => "Hang Seng Index future"),
127
+ :vix => IB::Future.new(:symbol => "VIX",
128
+ :expiry => next_expiry,
129
+ :exchange => "CFE", #"ECBOT",
130
+ :currency => "USD",
131
+ :description => "CBOE Volatility Index future"))
132
+
133
+
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,43 @@
1
+ # Frequently used stock contracts definitions
2
+ module IB
3
+ module Symbols
4
+ module Index
5
+ extend Symbols
6
+
7
+ def self.contracts
8
+ @contracts.presence || super.merge(
9
+ :dax => IB::Index.new(:symbol => "DAX", :currency => "EUR", exchange: 'DTB',
10
+ :description => "DAX Performance Index."),
11
+ :asx => IB::Index.new( :symbol => 'AP', :currency => 'AUD', exchange: 'ASX',
12
+ :description => "ASX 200 Index" ),
13
+ :hsi => IB::Index.new( :symbol => 'HSI', :currency => 'HKD', exchange: 'HKFE',
14
+ :description => "Hang Seng Index" ),
15
+ :minihsi => IB::Index.new( :symbol => 'MHI', :currency => 'HKD', exchange: 'HKFE',
16
+ :description => "Mini Hang Seng Index" ),
17
+ :stoxx => IB::Index.new(:symbol => "ESTX50", :currency => "EUR", exchange: 'DTB',
18
+ :description => "Dow Jones Euro STOXX50"),
19
+ :spx => IB::Index.new(:symbol => "SPX", :currency => "USD", exchange: 'CBOE',
20
+ :description => "Dow Jones Euro STOXX50"),
21
+ :vhsi => IB::Index.new( symbol: 'VHSI', exchange: 'HKFE',
22
+ :description => "Hang Seng Volatility Index"),
23
+ :vasx => IB::Index.new( symbol: 'XVI', exchange: 'ASX',
24
+ :description => "ASX 200 Volatility Index") ,
25
+ :vstoxx => IB::Index.new(:symbol => "V2TX", :currency => "EUR", exchange: 'DTB',
26
+ :description => "VSTOXX Volatility Index"),
27
+ :vdax => IB::Index.new(:symbol => "VDAX", exchange: 'DTB',
28
+ :description => "German VDAX Volatility Index"),
29
+ :vix => IB::Index.new(:symbol => "VIX", exchange: 'CBOE',
30
+ :description => "CBOE Volatility Index"),
31
+ :volume => IB::Index.new( symbol: 'VOL-NYSE', exchange: 'NYSE',
32
+ description: "NYSE Volume Index" ),
33
+ :trin => IB::Index.new( symbol: 'TRIN-NYSE', exchange: 'NYSE',
34
+ description: "NYSE TRIN (or arms) Index"),
35
+ :tick => IB::Index.new( symbol: 'TICK-NYSE', exchange: 'NYSE',
36
+ description: "NYSE TICK Index"),
37
+ :a_d => IB::Index.new( symbol: 'AD-NYSE', exchange: 'NYSE',
38
+ description: "NYSE Advance Decline Index") )
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,82 @@
1
+ # Option contracts definitions.
2
+ # TODO: add next_expiry and other convenience from Futures module.
3
+ # Notice: OSI-Notation is broken
4
+ module IB
5
+ module Symbols
6
+ module Options
7
+ extend Symbols
8
+
9
+
10
+ ## usage: IB::Symbols::Options.stoxx.merge( strike: 3300 )
11
+ def self.contracts
12
+ @contracts ||= {
13
+ stoxx: IB::Option.new( symbol: :ESTX50, strike: 3000,
14
+ expiry: IB::Symbols::Futures.next_expiry ,
15
+ right: :put,
16
+ trading_class: 'OESX',
17
+ currency: 'EUR', exchange: 'DTB',
18
+ description: "ESTX50 Put Option quarterly"),
19
+ :ge => IB::Option.new(:symbol => "GE",
20
+ :expiry => IB::Symbols::Futures.next_expiry,
21
+ :right => "CALL",
22
+ :strike => 7,
23
+ :multiplier => 100,
24
+ :exchange => 'SMART',
25
+ :currency => 'USD',
26
+ :description => "General Electric 7 Call"),
27
+ :aapl => IB::Option.new(:symbol => "AAPL", exchange: 'SMART',
28
+ :expiry => IB::Symbols::Futures.next_expiry,
29
+ :right => "C",
30
+ :strike => 130,
31
+ :currency => 'USD',
32
+ :description => "Apple Call 130"),
33
+ :z750 => IB::Option.new(:symbol => "Z",
34
+ :exchange => "ICEEU",
35
+ :expiry => "201903",
36
+ :right => "CALL",
37
+ :strike => 7000.0,
38
+ :description => " FTSE-100 index 750 Call 2019-03"),
39
+ :ibm_lazy_expiry => IB::Option.new( symbol: 'IBM', right: :put, strike: 140, exchange: 'SMART',
40
+ description: 'IBM-Option Chain with strike 140'),
41
+ :ibm_lazy_strike => IB::Option.new( symbol: 'IBM', exchange: 'SMART', right: :put, expiry: IB::Symbols::Futures.next_expiry ,
42
+ description: 'IBM-Option Chain ( quarterly expiry)'),
43
+
44
+ :goog1100 => IB::Option.new( symbol: 'GOOG',
45
+ currency: 'USD',
46
+ strike: 1100,
47
+ multiplier: 100,
48
+ right: :call,
49
+ expiry: IB::Symbols::Futures.next_expiry,
50
+ description: 'Google Call Option with quarterly expiry'),
51
+ :argo_ise => Option.new( symbol: 'ARGO',
52
+ currency: "USD",
53
+ exchange: "ISE",
54
+ expiry: IB::Symbols::Futures.next_expiry,
55
+ right: :call,
56
+ strike: 10,
57
+ multiplier: 100,
58
+ description: 'Adecoagro Options @ ISE'),
59
+ :san_eu => IB::Option.new( symbol: 'SAN1',
60
+ exchange: "MEFFRV",
61
+ currency: "EUR",
62
+ expiry: IB::Symbols::Futures.next_expiry,
63
+ strike: 4.5,
64
+ right: :call,
65
+ # multiplier: 100, ## non standard multiplier: 102
66
+ trading_class: "SANEU",
67
+ description: 'Santanter Option specified via Trading-Class'),
68
+ :spy => IB::Option.new(:symbol => 'SPY',
69
+ :expiry => IB::Symbols::Futures.next_expiry,
70
+ :right => "P",
71
+ :currency => "USD",
72
+ :exchange => 'SMART',
73
+ :strike => 350,
74
+ :description => "SPY 350 Put next expiration"),
75
+ # :spy270 => IB::Option.new(:osi => 'SPY 190315P002700000'),
76
+ # :vix20 => IB::Option.new(:osi => 'VIX 181121C00020000'),
77
+ # :vxx40 => IB::Option.new(:osi => 'VXX 181117C00040000'),
78
+ }
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,38 @@
1
+ # Frequently used stock contracts definitions
2
+ # TODO: auto-request :ContractDetails from IB if unknown symbol is requested?
3
+ module IB
4
+ module Symbols
5
+ module Stocks
6
+ extend Symbols
7
+
8
+ def self.contracts
9
+ @contracts.presence || super.merge(
10
+ :ib_smart => IB::Stock.new( symbol: 'IBKR',
11
+ :description => 'Interactive Brokers Stock with smart exchange setting'),
12
+ :ib => IB::Stock.new( symbol: 'IBKR', exchange: 'ISLAND',
13
+ :description => 'Interactive Brokers Stock'),
14
+ :aapl => IB::Stock.new(:symbol => "AAPL",
15
+ :currency => "USD",
16
+ :description => "Apple Inc."),
17
+
18
+ :msft => IB::Stock.new( symbol: 'MSFT', primary_exchange: 'ISLAND',
19
+ description: 'Apple, primary trading @ ISLAND'), ## primary exchange set
20
+ :vxx => IB::Stock.new(:symbol => "VXX",
21
+ :exchange => "ARCA",
22
+ :description => "iPath S&P500 VIX short term Futures ETN"),
23
+ :wfc => IB::Stock.new(:symbol => "WFC",
24
+ :exchange => "NYSE",
25
+ :currency => "USD",
26
+ :description => "Wells Fargo"),
27
+ :sie => IB::Stock.new( symbol: 'SIE', currency: 'EUR',
28
+ description: 'Siemes AG'),
29
+ :wrong => IB::Stock.new(:symbol => "QEEUUE",
30
+ :exchange => "NYSE",
31
+ :currency => "USD",
32
+ :description => "Non-existent stock")
33
+ )
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,5 @@
1
+ module IB
2
+ module Symbols
3
+ VERSION = "1.0"
4
+ end
5
+ end
@@ -0,0 +1,58 @@
1
+
2
+ module IB
3
+ # module SymbolExtention # method_missing may not be refined
4
+ # refine Array do
5
+ # def method_missing(method, *key)
6
+ # unless method == :to_hash || method == :to_str #|| method == :to_int
7
+ # return self.map{|x| x.public_send(method, *key)}
8
+ # end
9
+ # end
10
+ # end
11
+ # end
12
+
13
+ module Symbols
14
+ # using SymbolExtention
15
+
16
+
17
+ def hardcoded?
18
+ !self.methods.include? :yml_file
19
+ end
20
+ def method_missing(method, *key)
21
+ if key.empty?
22
+ if contracts.has_key?(method)
23
+ contracts[method]
24
+ elsif methods.include?(:each) && each.methods.include?(method)
25
+ self.each.send method
26
+ else
27
+ error "contract #{method} not defined. Try »all« for a list of defined Contracts.", :symbol
28
+ end
29
+ else
30
+ error "method missing"
31
+ end
32
+ end
33
+
34
+ def all
35
+ contracts.keys.sort rescue contracts.keys
36
+ end
37
+ def print_all
38
+ puts contracts.sort.map{|x,y| [x,y.description].join(" -> ")}.join "\n"
39
+ end
40
+ def contracts
41
+ if @contracts.present?
42
+ @contracts
43
+ else
44
+ @contracts = Hash.new
45
+ end
46
+ end
47
+ def [] symbol
48
+ if c=contracts[symbol]
49
+ return c
50
+ else
51
+ # symbol probably has not been predefined, tell user about it
52
+ file = self.to_s.split(/::/).last.downcase
53
+ msg = "Unknown symbol :#{symbol}, please pre-define it in lib/ib/symbols/#{file}.rb"
54
+ error msg, :symbol
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,20 @@
1
+ This is the default directory of symbol-collections
2
+
3
+ They are created through
4
+
5
+
6
+ ```
7
+ cd bin
8
+ ./console
9
+
10
+ # creates the file Test.yml
11
+ i = IB::Symbols.allocate_collection :Test
12
+
13
+ # add a contract
14
+ i.add_contract :testcontract , IB::Stock.new( symbol: 'TAP')
15
+
16
+ # list
17
+
18
+
19
+
20
+ ```
@@ -0,0 +1,12 @@
1
+ ---
2
+ :testcontract: !ruby/object:IB::Stock
3
+ attributes:
4
+ :symbol: GE
5
+ :con_id: 0
6
+ :exchange: SMART
7
+ :currency: USD
8
+ :sec_type: STK
9
+ :created_at: 2020-10-06 09:21:29.457747233 +00:00
10
+ :right: ''
11
+ :include_expired: false
12
+ description: 'Stock: GE USD'