ib-symbols 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5dcaabf70cf9ccf59300a44e3bea6b4f3bb71a29530a2487f25a3abfb3d5e7f3
4
+ data.tar.gz: cbb25b2f3a24baab903fdf98fd2591f849048e280d819b7c17b8b1838318470f
5
+ SHA512:
6
+ metadata.gz: 6b66ab926b8322dfbf3e19a85c21f7e8e7a57784fbc85774b92afaf1813e84f8f83c0ab94c0537ff0952aa53e7719dce8e2f9e3ffe5efaca1cb55a4ba22e96d7
7
+ data.tar.gz: ba673e891a08a3f8b1adc82b9ff955007ffdb61ab69d3e5b64bad0d8aed444cb2a9e6f6b8525d53f17fe8b0d7900c62eaedc8b8022fdebf16056ee2c1983623e
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.6.3
6
+ before_install: gem install bundler -v 2.1.4
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at topofocus@gmaiol.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [https://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: https://contributor-covenant.org
74
+ [version]: https://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ib-symbols.gemspec
4
+ gemspec
@@ -0,0 +1,24 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :rspec, cmd: "bundle exec rspec" do
5
+ require "ostruct"
6
+
7
+ # Generic Ruby apps
8
+ rspec = OpenStruct.new
9
+ rspec.spec = ->(m) { "spec/#{m}_spec.rb" }
10
+ rspec.spec_dir = "spec"
11
+ rspec.spec_helper = "spec/spec_helper.rb"
12
+
13
+
14
+ # watch(%r{^lib/models/ib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
15
+ # watch(%r{^lib/ib/messages/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
16
+ # watch(%r{^lib/ib/symbols/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
17
+
18
+ watch(%r{^ib/(.+)\.rb$}) { |m| "spec/ib/#{m[1]}_spec.rb" }
19
+ # watch(%r{^models/(.+)\.rb$}) { |m| "spec/models/#{m[1]}_spec.rb" }
20
+ watch(%r{^spec/.+_spec\.rb$})
21
+ watch('spec/spec_helper.rb') { "spec" }
22
+ # watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
23
+ end
24
+
@@ -0,0 +1,98 @@
1
+ # ib-symbols
2
+
3
+ Predefined symbols and watchlists for contracts
4
+
5
+ to activate use
6
+
7
+ ```
8
+ gem 'ib-symbols', git: 'https://github.com/ib-ruby/ib-symbols.git'
9
+ ```
10
+ in the Gemfile and
11
+ ```
12
+ require 'ib-api'
13
+ require 'ib/symbols'
14
+ ```
15
+ in your script
16
+
17
+ ---
18
+
19
+ The GUI-Version of the TWS organizes symbols in different pages (Watchlists).
20
+
21
+ **`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.
22
+
23
+ By default, Watchlists reside in the `symbols`-directory of `ib-symbols`. This can be changed anytime through
24
+ ```
25
+ > IB::Symbols.set_origin '.' # (a valid path, either relative or absolute)
26
+ => #<Pathname:.>
27
+ > IB::Symbols.set_origin( ".").realpath
28
+ => #<Pathname:/home/ubuntu/workspace/ib-symbols/bin>
29
+ ```
30
+
31
+
32
+ ## Symbol Collections
33
+ Everything is kept elementary simple: Collections are stored as editable files. The format is YAML.
34
+
35
+ The CRUD Cycle
36
+ ```ruby
37
+ > IB::Symbols.allocate_collection :Demo
38
+ => IB::Symbols::Demo # file /symbols/Demo is created and Modul is established
39
+ > IB::Symbols::Demo.add_contract :uso , IB::Stock.new( symbol: 'USO' )
40
+ => 235 # returns the count of written bytes to the file
41
+ > IB::Symbols::Demo.uso # returns the stored contract
42
+ => #<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"}>
43
+ > IB::Symbols::Demo.add_contract :ford , IB::Stock.new( symbol: 'F' )
44
+ => 465
45
+ > IB::Symbols::Demo.all
46
+ => [:ford, :uso] # lists all stored contracts
47
+ > IB::Symbols::Demo.remove_contract :uso
48
+ > IB::Symbols::Demo.all
49
+ => [:ford]
50
+ > IB::Symbols::Demo.purge_collection # deletes the file and erases the contracts kept in memory
51
+ => nil
52
+ head :012 > IB::Symbols::Demo.all
53
+ => []
54
+ ```
55
+
56
+ ## Predefined Collections
57
+
58
+ Most popular `Stocks`, `Options`, `Futures`, `Indices` and `Forex-pairs` are hard-coded.
59
+ ```ruby
60
+ > IB::Symbols::Index.all
61
+ => [:a_d, :asx, :dax, :hsi, :minihsi, :spx, :stoxx, :tick, :trin, :vasx, :vdax, :vhsi, :vix, :volume, :vstoxx]
62
+ > puts IB::Symbols::Index.contracts.values &.to_human
63
+ <Index: DAX EUR (DAX Performance Index.) >
64
+ <Index: AP AUD (ASX 200 Index) >
65
+ <Index: HSI HKD (Hang Seng Index) >
66
+ (...)
67
+ <Index: AD-NYSE (NYSE Advance Decline Index) >
68
+
69
+ > Symbols::Forex.eurusd.to_human
70
+ => "<Contract: EUR forex IDEALPRO USD>"
71
+ # this contract is valid and can be verified, but the opposide is not supported by IB
72
+ > Symbols::Forex.usdeur.verify
73
+ TWS Error 200: No security definition has been found for the request
74
+ Not a valid Contract :: <Contract: USD forex IDEALPRO EUR>
75
+ ```
76
+
77
+ ## Pattern based Contract retrieval
78
+
79
+ To specify a specific Option can be a boaring job.
80
+ You might spend hours searching for a simple error, like a forgotten `:currency` oder `:exchange` entry.
81
+
82
+ Symbol-Collections can be used as template for everyday searches.
83
+
84
+ > Example: Customize a Index-Option with quaterly expiry.
85
+ >
86
+ > The hard coded `Symbols::Options.stoxx` template ensures the retrieval of only one option.
87
+ > A simple merge with customized attributes returns a fully qualified ContractRecord.
88
+
89
+
90
+ ```ruby
91
+ > IB::Symbols.Options.stoxx.to_human
92
+ => "<Option: ESTX50 202012 put 3000.0 DTB EUR>"
93
+ > Symbols::Options.stoxx.merge( strike: 3300, right: :call).to_human
94
+ => "<Option: ESTX50 202012 call 3300.0 DTB EUR>"
95
+
96
+ ```
97
+
98
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env ruby
2
+ ### loads the active-orient environment
3
+ ### and starts an interactive shell
4
+ ###
5
+ ### Parameter: t)ws | g)ateway (or number of port ) Default: Gateway ,
6
+ ### client_id , Default 2000
7
+ ###
8
+ ### Define Parameter in file console.yml
9
+ ###
10
+ require 'bundler/setup'
11
+ require 'yaml'
12
+
13
+ require 'logger'
14
+
15
+ require 'ib/symbols'
16
+
17
+ class Array
18
+ # enables calling members of an array. which are hashes by its name
19
+ # i.e
20
+ #
21
+ # 2.5.0 :006 > C.received[:OpenOrder].local_id
22
+ # => [16, 17, 21, 20, 19, 8, 7]
23
+ # 2.5.0 :007 > C.received[:OpenOrder].contract.to_human
24
+ # => ["<Bag: IECombo SMART USD legs: >", "<Stock: GE USD>", "<Stock: GE USD>", "<Stock: GE USD>", "<Stock: GE USD>", "<Stock: WFC USD>", "<Stock: WFC USD>"]
25
+ #
26
+ # its included only in the console, for inspection purposes
27
+
28
+ def method_missing(method, *key)
29
+ unless method == :to_hash || method == :to_str #|| method == :to_int
30
+ return self.map{|x| x.public_send(method, *key)}
31
+ end
32
+
33
+ end
34
+ end # Array
35
+
36
+
37
+ # read items from console.yml
38
+ read_yml = -> (key) do
39
+ YAML::load_file( File.expand_path('../console.yml',__FILE__))[key]
40
+ end
41
+
42
+
43
+ puts
44
+ puts ">> IB-Ruby Interactive Console <<"
45
+ puts '-'* 45
46
+ puts " Symbols Support is included "
47
+ puts " Predefined Symbols :in: Symbols::Index, Symbols::Futures, Symbols::Forex, Symbols::Options"
48
+ puts
49
+ puts " Namespace is IB ! "
50
+ puts
51
+ puts '-'* 45
52
+ include LogDev
53
+ include IB
54
+ require 'irb'
55
+ client_id = ARGV[1] || read_yml[:client_id]
56
+ specified_port = ARGV[0] || 'Offline'
57
+ port = case specified_port
58
+ when Integer
59
+ specified_port # just use the number
60
+ when /^[gG]/
61
+ read_yml[:gateway]
62
+ when /^[Tt]/
63
+ read_yml[:tws]
64
+ when /^[Oo]/
65
+ -1
66
+ end
67
+
68
+ ARGV.clear
69
+ logger = default_logger # Logger.new STDOUT
70
+
71
+ ## The Block takes instructions which are executed after initializing all instance-variables
72
+ ## and prior to the connection-process
73
+ ## Here we just subscribe to some events
74
+ if port > 0
75
+ C = Connection.new client_id: client_id, port: port do |c| # future use__ , optional_capacities: "+PACEAPI" do |c|
76
+
77
+ c.subscribe( :ContractData, :BondContractData) { |msg| logger.info { msg.contract.to_human } }
78
+ c.subscribe( :Alert, :ContractDataEnd, :ManagedAccounts, :OrderStatus ) {| m| logger.info { m.to_human } }
79
+ c.subscribe( :PortfolioValue, :AccountValue, :OrderStatus, :OpenOrderEnd, :ExecutionData ) {| m| logger.info { m.to_human }}
80
+ # c.subscribe :ManagedAccounts do |msg|
81
+ # puts "------------------------------- Managed Accounts ----------------------------------"
82
+ # puts "Detected Accounts: #{msg.accounts.account.join(' -- ')} "
83
+ # puts
84
+ # end
85
+
86
+ c.subscribe( :OpenOrder){ |msg| "Open Order detected and stored: C.received[:OpenOrders] " }
87
+ c.logger.level = Logger::INFO
88
+ end
89
+ unless C.received[:OpenOrder].blank?
90
+ puts "------------------------------- OpenOrders ----------------------------------"
91
+ puts C.received[:OpenOrder].to_human.join "\n"
92
+ end
93
+ puts "Connection established on Port #{port}, client_id #{client_id} used"
94
+ puts
95
+ puts "----> C points to the connection-instance"
96
+ puts
97
+ puts "some basic Messages are subscribed and accordingly displayed"
98
+
99
+ else
100
+ puts "Offline mode " * 4
101
+ puts
102
+ puts "to connect to the TWS invoke with \" ./console t \""
103
+ puts "to connect to the Gateway invoke with \" ./console g \""
104
+ end
105
+
106
+ puts '-'* 45
107
+
108
+ IRB.start(__FILE__)
@@ -0,0 +1,3 @@
1
+ :gateway: 4002
2
+ :tws: 7496
3
+ :client_id: 2000
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,28 @@
1
+ Process of separation from ib-ruby
2
+ ==================================
3
+
4
+ * Create the gem with bundle
5
+ `bundle gem ib-symbols`
6
+
7
+ * Move essential files from ib-ruby
8
+ Source is `lib/ib/symbols` and `lib/ib/symbols_base.rb`
9
+
10
+ * modify `lib/ib/symbols.rb`
11
+ * Transfer code from `symbols_base.rb_`
12
+ * Add require-statements
13
+
14
+ * include `bin/console`
15
+ Copy from `bin/console` and modify to enable offline usage as default
16
+ Copy `console.yml` as well
17
+
18
+ * add TestSuite
19
+ Copy `Guardfile` from ib-ruby
20
+ Copy `spec_helper` to `spec` directory and modify
21
+ Copy `symbols_spec.rb` to `spec` directory and modify
22
+ Run `bundle exec guard`
23
+
24
+ * push gem to github
25
+
26
+
27
+
28
+
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This script gets details for specific contract from IB
4
+
5
+ require 'bundler/setup'
6
+ # load predefined symbols
7
+ require 'ib/symbols'
8
+
9
+ include IB
10
+ # Definition of what we want market data for. We have to keep track of what ticker id
11
+ # corresponds to what symbol ourselves, because the ticks don't include any other
12
+ # identifying information. The choice of ticker ids is, as far as I can tell, arbitrary.
13
+ #
14
+ # I. Selected Contracts
15
+ contracts = [ IB::Symbols::Stocks.wfc,
16
+ IB::Symbols::Stocks.vxx,
17
+ IB::Symbols::Futures.vix,
18
+ IB::Symbols::Futures.ym,
19
+ IB::Symbols::Options.ge,
20
+ ### OSI-Notation is broken
21
+ # IB::Symbols::Options[:vix20],
22
+ # IB::Symbols::Options[:spy270],
23
+ # IB::Symbols::Options[:vxx40],
24
+ IB::Symbols::Forex.eurusd,
25
+ ### Bonds are not actually not supported
26
+ # 8 => IB::Symbols::Bonds[:wag],
27
+ IB::Symbols::Stocks.wrong ]
28
+ # or
29
+ # II. Use predefined Contracts
30
+ stock_contracts = Symbols::Stocks.all.map{|x| Symbols::Stocks.send x }
31
+ future_contracts = Symbols::Futures.all.map{|x| Symbols::Futures.send x }
32
+ option_contracts = Symbols::Options.all.map{|x| Symbols::Options.send x }
33
+ cfd_contracts = Symbols::CFD.all.map{|x| Symbols::CFD.send x }
34
+ index_contracts = Symbols::Index.all.map{|x| Symbols::Index.send x }
35
+
36
+ ## comment if you want to display selected contracts ( I. )
37
+ contracts = stock_contracts + future_contracts + option_contracts + cfd_contracts + index_contracts
38
+
39
+
40
+ # Connect to IB TWS.
41
+ ib = Connection.new :client_id => 11912 do | gw| # , port: 7497 do | gw | # TWS
42
+ # Subscribe to TWS alerts/errors and contract data end marker
43
+ gw.subscribe(:Alert, :ContractDataEnd) { |msg| puts msg.to_human }
44
+
45
+ # Now, subscribe to ContractData incoming events. The code passed in the block
46
+ # will be executed when a message of that type is received, with the received
47
+ # message as its argument. In this case, we just print out the data.
48
+ gw.subscribe(:ContractData, :BondContractData) do |msg|
49
+ puts msg.contract.to_human + "\n"
50
+ puts "Attributes: "
51
+ puts "\t"+ msg.contract.attributes.map{ |k,v| "#{k} : #{v}" unless v.blank? || (v.is_a?(Numeric) && v.zero?) }.join("\n\t")
52
+ end
53
+
54
+ # Set log level
55
+ gw.logger.level = Logger::FATAL
56
+ end
57
+
58
+ ib.wait_for :NextValidOrderId
59
+
60
+
61
+ contracts.each do |contract|
62
+ puts "\nRequesting contract data for #{contract.description}"
63
+
64
+ # Request Contract details for the symbols we're interested in. TWS will
65
+ # respond with ContractData messages, which will be processed by the code above.
66
+ ib.send_message :RequestContractData, :contract => contract
67
+
68
+ # Wait for IB to respond to our request
69
+ ib.wait_for :ContractDataEnd, 5 #sec
70
+ ib.clear_received :ContractDataEnd
71
+ end