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.
- 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,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This script connects to IB API and subscribes to market data for Forex symbols.
|
4
|
+
# It then prints out all trades that exceed certain size.
|
5
|
+
|
6
|
+
require 'bundler/setup'
|
7
|
+
require 'ib/symbols'
|
8
|
+
|
9
|
+
# Define the symbols we're interested in.
|
10
|
+
@market = {
|
11
|
+
123 => IB::Symbols::Futures[:gbp],
|
12
|
+
234 => IB::Symbols::Futures[:jpy],
|
13
|
+
444 => IB::Symbols::Forex[:usdjpy]
|
14
|
+
}
|
15
|
+
|
16
|
+
# First, connect to IB TWS. Arbitrary :client_id is used to identify your script
|
17
|
+
ib = IB::Connection.new :client_id => 1112 #, :port => 7496 # TWS
|
18
|
+
|
19
|
+
# Subscribe to TWS alerts/errors
|
20
|
+
ib.subscribe(:Alert, :ManagedAccounts) { |msg| puts msg.to_human }
|
21
|
+
|
22
|
+
# This method filters out non-:last type events, and filters out any sale < MIN_SIZE.
|
23
|
+
# Note that we have to look the ticker id of each incoming message
|
24
|
+
# up in local memory to figure out what it's for.
|
25
|
+
# (N.B. The description field is not from IB TWS. It is defined
|
26
|
+
# locally in symbols/futures.rb symbols/forex.rb, and is just arbitrary text.)
|
27
|
+
def show_sales_and_size(msg)
|
28
|
+
#return if msg.type != :last_price || msg.data[:size] < MIN_SIZE
|
29
|
+
puts @market[msg.ticker_id].description + ": " +
|
30
|
+
(msg.is_a?(IB::Messages::Incoming::TickPrice) ?
|
31
|
+
"#{msg.data[:size]} at #{msg.data[:price]}" : msg.to_human)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Now, subscribe to TickerPrice and TickerSize events. The code passed in the block
|
35
|
+
# will be executed when a message of that type is received, with the received message
|
36
|
+
# as its argument. In this case, we just print out the tick.
|
37
|
+
ib.subscribe(:TickPrice, :TickSize, :TickString) { |msg| show_sales_and_size(msg) }
|
38
|
+
|
39
|
+
# Now we actually request market data for the symbols we're interested in.
|
40
|
+
@market.each_pair do |id, contract|
|
41
|
+
ib.send_message :RequestMarketData, :ticker_id => id, :contract => contract
|
42
|
+
end
|
43
|
+
|
44
|
+
puts "\nSubscribed to TWS market data"
|
45
|
+
puts "\n******** Press <Enter> to cancel... *********\n\n"
|
46
|
+
STDIN.gets
|
47
|
+
puts "Unsubscribing from TWS market data.."
|
48
|
+
|
49
|
+
@market.each_pair { |id, contract| ib.send_message :CancelMarketData, :ticker_id => id }
|
50
|
+
|
51
|
+
sleep 2
|
data/ib-symbols.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative 'lib/ib/symbols/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "ib-symbols"
|
5
|
+
spec.version = IB::Symbols::VERSION
|
6
|
+
spec.authors = ["Hartmut Bischoff"]
|
7
|
+
spec.email = ["topofocus@gmail.com"]
|
8
|
+
|
9
|
+
spec.summary = %q{Predefined symbols and watchlist, part of ib-ruby}
|
10
|
+
spec.description = %q{Easy access to most common contracts through templates, define watchlists to perfrom bulk operations}
|
11
|
+
spec.homepage = "https://ib-ruby.github.io/ib-doc/"
|
12
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
|
13
|
+
|
14
|
+
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
15
|
+
|
16
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
17
|
+
spec.metadata["source_code_uri"] = "https://github.com/ib-ruby/ib-symbols"
|
18
|
+
# spec.metadata["changelog_uri"] = "https://github.com/ib-ruby/ib-symbols/changelog.md"
|
19
|
+
|
20
|
+
# Specify which files should be added to the gem when it is released.
|
21
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
22
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
23
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
24
|
+
end
|
25
|
+
spec.bindir = "exe"
|
26
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ["lib"]
|
28
|
+
|
29
|
+
spec.add_dependency "ib-api"
|
30
|
+
spec.add_dependency "ox"
|
31
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
32
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
33
|
+
spec.add_development_dependency 'rspec-collection_matchers'
|
34
|
+
spec.add_development_dependency 'rspec-its'
|
35
|
+
|
36
|
+
spec.add_development_dependency "guard"
|
37
|
+
spec.add_development_dependency "guard-rspec"
|
38
|
+
end
|
data/lib/ib/symbols.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
require "ib/symbols/version"
|
2
|
+
require "ib-api"
|
3
|
+
|
4
|
+
# These modules are used to facilitate referencing of most popular IB Contracts.
|
5
|
+
# Like pages in the TWS-GUI, they can be utilised to organise trading and research.
|
6
|
+
#
|
7
|
+
# Symbol Allocations are organized as modules. They represent the contents of yaml files in
|
8
|
+
#
|
9
|
+
# /lib/symbols/
|
10
|
+
#
|
11
|
+
# Any collection is represented as simple Hash, with __key__ as qualifier and an __IB::Contract__ as value.
|
12
|
+
# The Value is either a fully prequalified Contract (Stock, Option, Future, Forex, CFD, BAG) or
|
13
|
+
# a lazy qualified Contract acting as base für further calucaltions and requests.
|
14
|
+
#
|
15
|
+
# IB::Symbols.allocate_collection :Name
|
16
|
+
#
|
17
|
+
# creates the Module and file. If a previously created file is found, its contents are read and
|
18
|
+
# the vcollection ist reestablished.
|
19
|
+
#
|
20
|
+
# IB::Symbols::Name.add_contract :wfc, IB::Stock.new( symbol: 'WFC' )
|
21
|
+
#
|
22
|
+
# adds the contract and stores it in the yaml file
|
23
|
+
#
|
24
|
+
# IB::Symbols::Name.wfc # or IB::Symbols::Name[:wfc]
|
25
|
+
#
|
26
|
+
# retrieves the contract
|
27
|
+
#
|
28
|
+
# IB::Symbols::Name.all
|
29
|
+
#
|
30
|
+
# returns an Array of stored contracts
|
31
|
+
#
|
32
|
+
# IB::Symbols::Name.remove_contract :wfc
|
33
|
+
#
|
34
|
+
# deletes the contract from the list (and the file)
|
35
|
+
#
|
36
|
+
# To finish the cycle
|
37
|
+
#
|
38
|
+
# IB::Symbols::Name.purge_collection
|
39
|
+
#
|
40
|
+
# deletes the file and erases the collection in memory.
|
41
|
+
#
|
42
|
+
# Additional methods can be introduced
|
43
|
+
# * for individual contracts on the module-level or
|
44
|
+
# * to organize the list as methods of Array in Module IB::SymbolExtention
|
45
|
+
#
|
46
|
+
#
|
47
|
+
# Contracts can be hardcoded in the required standard-collections as well.
|
48
|
+
# Note that the :description field is local to ib-ruby, and is NOT part of the standard TWS API.
|
49
|
+
# It is never transmitted to IB. It's purely used clientside, and you can store any arbitrary
|
50
|
+
# string that you may find useful there.
|
51
|
+
|
52
|
+
module IB
|
53
|
+
module Symbols
|
54
|
+
class Error < StandardError; end
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
def hardcoded?
|
59
|
+
!self.methods.include? :yml_file
|
60
|
+
end
|
61
|
+
def method_missing(method, *key)
|
62
|
+
if key.empty?
|
63
|
+
if contracts.has_key?(method)
|
64
|
+
contracts[method]
|
65
|
+
elsif methods.include?(:each) && each.methods.include?(method)
|
66
|
+
self.each.send method
|
67
|
+
else
|
68
|
+
error "contract #{method} not defined. Try »all« for a list of defined Contracts.", :symbol
|
69
|
+
end
|
70
|
+
else
|
71
|
+
error "method missing"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def all
|
76
|
+
contracts.keys.sort rescue contracts.keys
|
77
|
+
end
|
78
|
+
def print_all
|
79
|
+
puts contracts.sort.map{|x,y| [x,y.description].join(" -> ")}.join "\n"
|
80
|
+
end
|
81
|
+
def contracts
|
82
|
+
if @contracts.present?
|
83
|
+
@contracts
|
84
|
+
else
|
85
|
+
@contracts = Hash.new
|
86
|
+
end
|
87
|
+
end
|
88
|
+
def [] symbol
|
89
|
+
if c=contracts[symbol]
|
90
|
+
return c
|
91
|
+
else
|
92
|
+
# symbol probably has not been predefined, tell user about it
|
93
|
+
file = self.to_s.split(/::/).last.downcase
|
94
|
+
msg = "Unknown symbol :#{symbol}, please pre-define it in lib/ib/symbols/#{file}.rb"
|
95
|
+
error msg, :symbol
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
require 'ib/symbols/forex'
|
103
|
+
require 'ib/symbols/futures'
|
104
|
+
require 'ib/symbols/stocks'
|
105
|
+
require 'ib/symbols/index'
|
106
|
+
require 'ib/symbols/cfd'
|
107
|
+
require 'ib/symbols/commodity'
|
108
|
+
require 'ib/symbols/options'
|
109
|
+
require 'ib/symbols/combo'
|
110
|
+
require 'ib/symbols/bonds'
|
111
|
+
require 'ib/symbols/abstract'
|
112
|
+
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module IB
|
2
|
+
|
3
|
+
# reopen the contract-class and add yml_file
|
4
|
+
class Contract
|
5
|
+
|
6
|
+
# Reading Contract-Defaults
|
7
|
+
#
|
8
|
+
# by default, the yml-file in the base-directory (ib-ruby) is used.
|
9
|
+
# This method can be overloaded to include a file from a different location
|
10
|
+
#
|
11
|
+
# IB::Symbols::Stocks.wfc.yml_file
|
12
|
+
# => "/home/ubuntu/workspace/ib-ruby/contract_config.yml"
|
13
|
+
#
|
14
|
+
def yml_file
|
15
|
+
File.expand_path('../../../../contract_config.yml',__FILE__ )
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
module Symbols
|
21
|
+
|
22
|
+
=begin
|
23
|
+
Creates a Class and associates it with a filename
|
24
|
+
|
25
|
+
raises an IB::Error in case of a conflict with existing class-names
|
26
|
+
=end
|
27
|
+
|
28
|
+
# set the Pathname to "ib-api/symbols" by default
|
29
|
+
@@dir= Pathname.new File.expand_path("../../../../symbols/", __FILE__ )
|
30
|
+
def self.set_origin directory
|
31
|
+
p = Pathname.new directory
|
32
|
+
@@dir = p if p.directory?
|
33
|
+
rescue Errno::ENOENT
|
34
|
+
error "Setting up origin for symbol-files --> Directory (#{directory}) does not exist"
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.allocate_collection name # name might be a string or a symbol
|
38
|
+
symbol_table = Module.new do
|
39
|
+
extend Symbols
|
40
|
+
extend Enumerable
|
41
|
+
def self.yml_file
|
42
|
+
@@dir + name.to_s.downcase.split("::").last.concat( ".yml" )
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.each &b
|
46
|
+
contracts.values.each &b
|
47
|
+
end
|
48
|
+
end # module new
|
49
|
+
name = name.to_s.camelize.to_sym
|
50
|
+
the_collection = if Symbols.send :const_defined?, name
|
51
|
+
Symbols.send :const_get, name
|
52
|
+
else
|
53
|
+
Symbols.const_set name, symbol_table
|
54
|
+
end
|
55
|
+
if the_collection.is_a? Symbols
|
56
|
+
the_collection.send :read_collection if the_collection.all.empty?
|
57
|
+
the_collection # return_value
|
58
|
+
else
|
59
|
+
error "#{the_collection} is already a Class"
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def purge_collection
|
65
|
+
yml_file.delete
|
66
|
+
@contracts = nil
|
67
|
+
end
|
68
|
+
|
69
|
+
=begin
|
70
|
+
cuts the Collection in `bunch_count` pieces. Each bunch is delivered to the block.
|
71
|
+
|
72
|
+
Sleeps for `sleeping time` between processing bunches
|
73
|
+
|
74
|
+
Returns count of created bunches
|
75
|
+
=end
|
76
|
+
def bunch( bunch_count = 50 , sleeping_time = 1)
|
77
|
+
en = self.each
|
78
|
+
the_size = en.size
|
79
|
+
i = 0
|
80
|
+
loop do
|
81
|
+
the_start = i * bunch_count
|
82
|
+
the_end = the_start + bunch_count
|
83
|
+
the_end = the_size -1 if the_end >= the_size
|
84
|
+
it = the_start .. the_end
|
85
|
+
yield it.map{|x| en.next rescue nil}.compact
|
86
|
+
break if the_end == the_size -1
|
87
|
+
i+=1
|
88
|
+
sleep sleeping_time
|
89
|
+
end
|
90
|
+
i -1 # return counts of bunches
|
91
|
+
end
|
92
|
+
|
93
|
+
def read_collection
|
94
|
+
if yml_file.exist?
|
95
|
+
contracts.merge! YAML.load_file yml_file rescue contracts
|
96
|
+
else
|
97
|
+
yml_file.open( "w"){}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def store_collection
|
102
|
+
yml_file.open( 'w' ){|f| f.write @contracts.to_yaml}
|
103
|
+
end
|
104
|
+
|
105
|
+
def add_contract symbol, contract
|
106
|
+
if symbol.is_a? String
|
107
|
+
symbol.to_sym
|
108
|
+
elsif symbol.is_a? Symbol
|
109
|
+
symbol
|
110
|
+
else
|
111
|
+
symbol.to_i
|
112
|
+
end
|
113
|
+
# ensure that evey Sybmol::xxx.yyy entry has a description
|
114
|
+
contract.description = contract.to_human[1..-2] if contract.description.nil?
|
115
|
+
# overwrite contract if existing
|
116
|
+
contracts[ symbol ] = contract.essential
|
117
|
+
store_collection
|
118
|
+
end
|
119
|
+
|
120
|
+
def remove_contract symbol
|
121
|
+
@contracts.delete symbol
|
122
|
+
store_collection
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
def to_human
|
127
|
+
self.to_s.split("::").last
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
module Unspecified
|
133
|
+
extend Symbols
|
134
|
+
end
|
135
|
+
|
136
|
+
end # module Symbols
|
137
|
+
end # module IB
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Sample bond contract definitions
|
2
|
+
module IB
|
3
|
+
module Symbols
|
4
|
+
module Bonds
|
5
|
+
extend Symbols
|
6
|
+
|
7
|
+
def self.contracts
|
8
|
+
@contracts ||= {
|
9
|
+
:abbey => IB::Contract.new(:symbol => "ABBEY",
|
10
|
+
:currency => "USD",
|
11
|
+
:sec_type => :bond,
|
12
|
+
:description => "Any ABBEY bond"),
|
13
|
+
|
14
|
+
:ms => IB::Contract.new(:symbol => "MS",
|
15
|
+
:currency => "USD",
|
16
|
+
:sec_type => :bond,
|
17
|
+
:description => "Any Morgan Stanley bond"),
|
18
|
+
|
19
|
+
:wag => IB::Contract.new(:symbol => "WAG",
|
20
|
+
:currency => "USD",
|
21
|
+
:sec_type => :bond,
|
22
|
+
:description => "Any Wallgreens bond"),
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,19 @@
|
|
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 CFD
|
6
|
+
extend Symbols
|
7
|
+
|
8
|
+
def self.contracts
|
9
|
+
@contracts.presence || super.merge(
|
10
|
+
:dax => IB::Contract.new(:symbol => "IBDE30", sec_type: :cfd,
|
11
|
+
:currency => "EUR",
|
12
|
+
:description => "DAX CFD."),
|
13
|
+
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,52 @@
|
|
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 Combo
|
6
|
+
extend Symbols
|
7
|
+
|
8
|
+
def self.contracts
|
9
|
+
|
10
|
+
@contracts ||= { #super.merge(
|
11
|
+
stoxx_straddle: IB::Straddle.build( from: IB::Symbols::Index.stoxx, strike: 3000,
|
12
|
+
expiry: IB::Symbols::Futures.next_expiry, trading_class: 'OESX') ,
|
13
|
+
stoxx_calendar: IB::Calendar.build( from: IB::Symbols::Index.stoxx, strike: 3000, back: '2m' ,
|
14
|
+
front: IB::Symbols::Futures.next_expiry, trading_class: 'OESX'),
|
15
|
+
stoxx_butterfly: IB::Butterfly.fabricate( Symbols::Options.stoxx.merge( strike: 3300), front: 3250, back: 3350 ),
|
16
|
+
stoxx_vertical: IB::Vertical.build( from: IB::Symbols::Index.stoxx, sell: 3000, buy: 3500, right: :put,
|
17
|
+
expiry: IB::Symbols::Futures.next_expiry, trading_class: 'OESX'),
|
18
|
+
zn_calendar: IB::Calendar.fabricate( IB::Symbols::Futures.zn, '3m') ,
|
19
|
+
|
20
|
+
dbk_straddle: Bag.new( symbol: 'DBK', currency: 'EUR', exchange: 'DTB', combo_legs:
|
21
|
+
[ ComboLeg.new( con_id: 270581032 , action: :buy, exchange: 'DTB', ratio: 1), #DBK Dez20 2018 C
|
22
|
+
ComboLeg.new( con_id: 270580382, action: :buy, exchange: 'DTB', ratio: 1 ) ], #DBK Dez 20 2018 P
|
23
|
+
description: 'Option Straddle: Deutsche Bank(20)[Dez 2018]'
|
24
|
+
),
|
25
|
+
ib_mcd: Bag.new( symbol: 'IBKR,MCD', currency: 'USD', combo_legs:
|
26
|
+
[ ComboLeg.new( con_id: 43645865, action: :buy, ratio: 1), # IKBR STK
|
27
|
+
ComboLeg.new( con_id: 9408, action: :sell,ratio: 1 ) ], # MCD STK
|
28
|
+
description: 'Stock Spread: Buy Interactive Brokers, sell Mc Donalds'
|
29
|
+
),
|
30
|
+
|
31
|
+
vix_calendar: Bag.new( symbol: 'VIX', currency: 'USD', exchange: 'CFE', combo_legs:
|
32
|
+
[ ComboLeg.new( con_id: 256038899, action: :buy, exchange: 'CFE', ratio: 1), # VIX FUT 201708
|
33
|
+
ComboLeg.new( con_id: 260564703, action: :sell, exchange: 'CFE', ratio: 1 ) ], # VIX FUT 201709
|
34
|
+
description: 'VixFuture Calendar-Spread August - September 2017'
|
35
|
+
),
|
36
|
+
wti_coil: Bag.new( symbol: 'WTI', currency: 'USD', exchange: 'SMART', combo_legs:
|
37
|
+
[ ComboLeg.new( con_id: 55928698, action: :buy, exchange: 'IPE', ratio: 1), # WTI future June 2017
|
38
|
+
ComboLeg.new( con_id: 55850663, action: :sell, exchange: 'IPE', ratio: 1 ) ], # COIL future June 2017
|
39
|
+
description: 'Smart Future Spread WTI - COIL (June 2017) '
|
40
|
+
),
|
41
|
+
wti_brent: Bag.new( symbol: 'CL.BZ', currency: 'USD', exchange: 'NYMEX', combo_legs:
|
42
|
+
[ ComboLeg.new( con_id: 47207310, action: :buy, exchange: 'NYMEX', ratio: 1), # CL Dec'16 @NYMEX
|
43
|
+
ComboLeg.new( con_id: 47195961, action: :sell, exchange: 'NYMEX', ratio: 1 ) ], #BZ Dec'16 @NYMEX
|
44
|
+
description: ' WTI - Brent Spread (Dez. 2016)'
|
45
|
+
)
|
46
|
+
}
|
47
|
+
# )
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,17 @@
|
|
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 Commodity
|
6
|
+
extend Symbols
|
7
|
+
|
8
|
+
def self.contracts
|
9
|
+
@contracts.presence || super.merge(
|
10
|
+
:xau => IB::Contract.new( symbol: 'XAUUSD', sec_type: :commodity, currency: 'USD',
|
11
|
+
:description => "London Gold ")
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|