ib-symbols 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/Guardfile +24 -0
- data/README.md +98 -0
- data/Rakefile +6 -0
- data/bin/console +108 -0
- data/bin/console.yml +3 -0
- data/bin/setup +8 -0
- data/build.md +28 -0
- data/examples/contract_details +71 -0
- data/examples/contract_sample_details +50 -0
- data/examples/contract_samples.rb +716 -0
- data/examples/depth_of_market +45 -0
- data/examples/head_time_stamp +35 -0
- data/examples/historic_data +102 -0
- data/examples/market_data +57 -0
- data/examples/option_data +63 -0
- data/examples/real_time_data +35 -0
- data/examples/snapshot_market_data +105 -0
- data/examples/time_and_sales +51 -0
- data/ib-symbols.gemspec +38 -0
- data/lib/ib/symbols.rb +112 -0
- data/lib/ib/symbols/abstract.rb +137 -0
- data/lib/ib/symbols/bonds.rb +28 -0
- data/lib/ib/symbols/cfd.rb +19 -0
- data/lib/ib/symbols/combo.rb +52 -0
- data/lib/ib/symbols/commodity.rb +17 -0
- data/lib/ib/symbols/forex.rb +41 -0
- data/lib/ib/symbols/futures.rb +137 -0
- data/lib/ib/symbols/index.rb +43 -0
- data/lib/ib/symbols/options.rb +82 -0
- data/lib/ib/symbols/stocks.rb +38 -0
- data/lib/ib/symbols/version.rb +5 -0
- data/lib/ib/symbols_base.rb +58 -0
- data/symbols/README.md +20 -0
- data/symbols/test.yml +12 -0
- metadata +196 -0
@@ -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,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
|
data/symbols/README.md
ADDED
@@ -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
|
+
```
|
data/symbols/test.yml
ADDED
@@ -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'
|