wdevauld-ib-ruby 0.2
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.
- data/History.txt +5 -0
- data/LICENSE +504 -0
- data/Manifest.txt +20 -0
- data/README.txt +50 -0
- data/Rakefile +33 -0
- data/bin/AccountInfo +71 -0
- data/bin/HistoricToCSV +129 -0
- data/bin/RequestHistoricData +312 -0
- data/bin/RequestMarketData +80 -0
- data/bin/SimpleTimeAndSales +101 -0
- data/bin/ib-ruby +8 -0
- data/lib/ib-ruby.rb +49 -0
- data/lib/ib-ruby/datatypes.rb +402 -0
- data/lib/ib-ruby/ib.rb +242 -0
- data/lib/ib-ruby/messages.rb +1449 -0
- data/lib/ib-ruby/symbols/forex.rb +62 -0
- data/lib/ib-ruby/symbols/futures.rb +114 -0
- data/spec/ib-ruby_spec.rb +7 -0
- data/spec/spec_helper.rb +16 -0
- data/test/test_ib-ruby.rb +162 -0
- metadata +96 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2006 Blue Voodoo Magic LLC.
|
3
|
+
#
|
4
|
+
# This library is free software; you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU Lesser General Public License as
|
6
|
+
# published by the Free Software Foundation; either version 2.1 of the
|
7
|
+
# License, or (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This library is distributed in the hope that it will be useful, but
|
10
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
12
|
+
# Lesser General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Lesser General Public
|
15
|
+
# License along with this library; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
17
|
+
# 02110-1301 USA
|
18
|
+
#
|
19
|
+
|
20
|
+
#
|
21
|
+
# Note that the :description field is particular to ib-ruby, and is NOT part of the standard TWS API.
|
22
|
+
# It is never transmitted to IB. It's purely used clientside, and you can store any arbitrary string that
|
23
|
+
# you may find useful there.
|
24
|
+
#
|
25
|
+
|
26
|
+
$:.push(File.dirname(__FILE__) + "/../")
|
27
|
+
|
28
|
+
require 'ib'
|
29
|
+
require 'datatypes'
|
30
|
+
|
31
|
+
module IB
|
32
|
+
module Symbols
|
33
|
+
Forex =
|
34
|
+
{
|
35
|
+
:gbpusd => Datatypes::Contract.new({
|
36
|
+
:symbol => "GBP",
|
37
|
+
:exchange => "IDEALPRO",
|
38
|
+
:currency => "USD",
|
39
|
+
:sec_type => Datatypes::Contract::SECURITY_TYPES[:forex],
|
40
|
+
:description => "GBPUSD"
|
41
|
+
|
42
|
+
}),
|
43
|
+
:eurusd => Datatypes::Contract.new({
|
44
|
+
:symbol => "EUR",
|
45
|
+
:exchange => "IDEALPRO",
|
46
|
+
:currency => "USD",
|
47
|
+
:sec_type => Datatypes::Contract::SECURITY_TYPES[:forex],
|
48
|
+
:description => "EURUSD"
|
49
|
+
|
50
|
+
}),
|
51
|
+
:usdjpy => Datatypes::Contract.new({
|
52
|
+
:symbol => "USD",
|
53
|
+
:exchange => "IDEALPRO",
|
54
|
+
:currency => "JPY",
|
55
|
+
:sec_type => Datatypes::Contract::SECURITY_TYPES[:forex],
|
56
|
+
:description => "USDJPY"
|
57
|
+
|
58
|
+
})
|
59
|
+
|
60
|
+
}
|
61
|
+
end # Contracts
|
62
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (C) 2006 Blue Voodoo Magic LLC.
|
3
|
+
#
|
4
|
+
# This library is free software; you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU Lesser General Public License as
|
6
|
+
# published by the Free Software Foundation; either version 2.1 of the
|
7
|
+
# License, or (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This library is distributed in the hope that it will be useful, but
|
10
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
12
|
+
# Lesser General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Lesser General Public
|
15
|
+
# License along with this library; if not, write to the Free Software
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
17
|
+
# 02110-1301 USA
|
18
|
+
#
|
19
|
+
|
20
|
+
|
21
|
+
# The Futures constant is currently for testing purposes. It guesses the front month
|
22
|
+
# currency future using a crude algorithm that does not take into account expiry/rollover day.
|
23
|
+
# This will be valid most of the time, but near/after expiry day the next quarter's contract
|
24
|
+
# takes over as the volume leader.
|
25
|
+
#
|
26
|
+
#
|
27
|
+
# Note that the :description field is particular to ib-ruby, and is NOT part of the standard TWS API.
|
28
|
+
# It is never transmitted to IB. It's purely used clientside, and you can store any arbitrary string that
|
29
|
+
# you may find useful there.
|
30
|
+
#
|
31
|
+
|
32
|
+
$:.push(File.dirname(__FILE__) + "/../")
|
33
|
+
|
34
|
+
require 'ib'
|
35
|
+
require 'datatypes'
|
36
|
+
|
37
|
+
module IB
|
38
|
+
module Symbols
|
39
|
+
|
40
|
+
# Get the next valid quarter month >= today, for finding the
|
41
|
+
# front month of quarterly futures.
|
42
|
+
#
|
43
|
+
# N.B. This will not work as expected near/after expiration during that month, as
|
44
|
+
# volume rolls over to the next quarter even though the current month is still valid!
|
45
|
+
#
|
46
|
+
|
47
|
+
|
48
|
+
def self.next_quarter_month(time)
|
49
|
+
sprintf("%02d", [3, 6, 9, 12].find{|month| month >= time.month })
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.next_quarter_year(time)
|
53
|
+
if self.next_quarter_month(time).to_i < time.month
|
54
|
+
time.year + 1
|
55
|
+
else
|
56
|
+
time.year
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.next_expiry(time)
|
61
|
+
"#{ self.next_quarter_year(time) }#{ self.next_quarter_month(time) }"
|
62
|
+
end
|
63
|
+
|
64
|
+
Futures =
|
65
|
+
{
|
66
|
+
:es => Datatypes::Contract.new({
|
67
|
+
:symbol => "ES",
|
68
|
+
:expiry => self.next_expiry(Time.now),
|
69
|
+
:exchange => "GLOBEX",
|
70
|
+
:currency => "USD",
|
71
|
+
:sec_type => Datatypes::Contract::SECURITY_TYPES[:future],
|
72
|
+
:multiplier => 50,
|
73
|
+
:description => "E-Mini S&P 500"
|
74
|
+
}),
|
75
|
+
|
76
|
+
:gbp => Datatypes::Contract.new({
|
77
|
+
:symbol => "GBP",
|
78
|
+
:expiry => self.next_expiry(Time.now),
|
79
|
+
:exchange => "GLOBEX",
|
80
|
+
:currency => "USD",
|
81
|
+
:sec_type => Datatypes::Contract::SECURITY_TYPES[:future],
|
82
|
+
:multiplier => 62500,
|
83
|
+
:description => "British Pounds"
|
84
|
+
}),
|
85
|
+
:eur => Datatypes::Contract.new({
|
86
|
+
:symbol => "EUR",
|
87
|
+
:expiry => self.next_expiry(Time.now),
|
88
|
+
:exchange => "GLOBEX",
|
89
|
+
:currency => "USD",
|
90
|
+
:sec_type => Datatypes::Contract::SECURITY_TYPES[:future],
|
91
|
+
:multiplier => 12500,
|
92
|
+
:description => "Euro FX"
|
93
|
+
}),
|
94
|
+
:jpy => Datatypes::Contract.new({
|
95
|
+
:symbol => "JPY",
|
96
|
+
:expiry => self.next_expiry(Time.now),
|
97
|
+
:exchange => "GLOBEX",
|
98
|
+
:currency => "USD",
|
99
|
+
:sec_type => Datatypes::Contract::SECURITY_TYPES[:future],
|
100
|
+
:multiplier => 12500000,
|
101
|
+
:description => "Japanese Yen"
|
102
|
+
}),
|
103
|
+
:hsi => Datatypes::Contract.new({
|
104
|
+
:symbol => "HSI",
|
105
|
+
:expiry => self.next_expiry(Time.now),
|
106
|
+
:exchange => "HKFE",
|
107
|
+
:currency => "HKD",
|
108
|
+
:sec_type => Datatypes::Contract::SECURITY_TYPES[:future],
|
109
|
+
:multiplier => 50,
|
110
|
+
:description => "Hang Seng Index"
|
111
|
+
})
|
112
|
+
}
|
113
|
+
end
|
114
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
require File.expand_path(
|
3
|
+
File.join(File.dirname(__FILE__), %w[.. lib ib-ruby]))
|
4
|
+
|
5
|
+
Spec::Runner.configure do |config|
|
6
|
+
# == Mock Framework
|
7
|
+
#
|
8
|
+
# RSpec uses it's own mocking framework by default. If you prefer to
|
9
|
+
# use mocha, flexmock or RR, uncomment the appropriate line:
|
10
|
+
#
|
11
|
+
# config.mock_with :mocha
|
12
|
+
# config.mock_with :flexmock
|
13
|
+
# config.mock_with :rr
|
14
|
+
end
|
15
|
+
|
16
|
+
# EOF
|
@@ -0,0 +1,162 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
#
|
3
|
+
# Copyright (C) 2006 Blue Voodoo Magic LLC.
|
4
|
+
#
|
5
|
+
# This library is free software; you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Lesser General Public License as
|
7
|
+
# published by the Free Software Foundation; either version 2.1 of the
|
8
|
+
# License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This library is distributed in the hope that it will be useful, but
|
11
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
# Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with this library; if not, write to the Free Software
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
18
|
+
# 02110-1301 USA
|
19
|
+
#
|
20
|
+
|
21
|
+
$:.push(File.dirname(__FILE__) + "/../")
|
22
|
+
|
23
|
+
require 'test/unit'
|
24
|
+
require 'ib'
|
25
|
+
require 'datatypes'
|
26
|
+
|
27
|
+
class ContractTests < Test::Unit::TestCase
|
28
|
+
def test_plain_instantiation
|
29
|
+
assert_nothing_raised {
|
30
|
+
x = IB::Datatypes::Contract.new
|
31
|
+
assert_not_nil(x)
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_sec_type_filter
|
36
|
+
assert_raise(ArgumentError) {
|
37
|
+
x = IB::Datatypes::Contract.new({:sec_type => "asdf"})
|
38
|
+
}
|
39
|
+
|
40
|
+
assert_raise(ArgumentError) {
|
41
|
+
x = IB::Datatypes::Contract.new
|
42
|
+
x.sec_type = "asdf"
|
43
|
+
}
|
44
|
+
|
45
|
+
IB::Datatypes::Contract::SECURITY_TYPES.values.each {|type|
|
46
|
+
assert_nothing_raised {
|
47
|
+
x = IB::Datatypes::Contract.new({:sec_type => type })
|
48
|
+
}
|
49
|
+
assert_nothing_raised {
|
50
|
+
x = IB::Datatypes::Contract.new
|
51
|
+
x.sec_type = type
|
52
|
+
}
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_expiry
|
57
|
+
assert_raise(ArgumentError) {
|
58
|
+
x = IB::Datatypes::Contract.new({:expiry => "foo" })
|
59
|
+
}
|
60
|
+
assert_raise(ArgumentError) {
|
61
|
+
x = IB::Datatypes::Contract.new
|
62
|
+
x.expiry = "foo"
|
63
|
+
}
|
64
|
+
|
65
|
+
assert_nothing_raised {
|
66
|
+
x = IB::Datatypes::Contract.new({:expiry => "200607" })
|
67
|
+
}
|
68
|
+
assert_nothing_raised {
|
69
|
+
x = IB::Datatypes::Contract.new
|
70
|
+
x.expiry = "200607"
|
71
|
+
}
|
72
|
+
assert_nothing_raised {
|
73
|
+
x = IB::Datatypes::Contract.new({:expiry => 200607 })
|
74
|
+
}
|
75
|
+
assert_nothing_raised {
|
76
|
+
x = IB::Datatypes::Contract.new
|
77
|
+
x.expiry = 200607
|
78
|
+
assert_equal(x.expiry, "200607") # converted to a string
|
79
|
+
}
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_right
|
84
|
+
assert_raise(ArgumentError) {
|
85
|
+
x = IB::Datatypes::Contract.new({:right => "foo" })
|
86
|
+
}
|
87
|
+
assert_raise(ArgumentError) {
|
88
|
+
x = IB::Datatypes::Contract.new
|
89
|
+
x.right = "foo"
|
90
|
+
}
|
91
|
+
|
92
|
+
assert_nothing_raised {
|
93
|
+
x = IB::Datatypes::Contract.new({:right => "PUT"})
|
94
|
+
}
|
95
|
+
assert_nothing_raised {
|
96
|
+
x = IB::Datatypes::Contract.new({:right => "put"})
|
97
|
+
}
|
98
|
+
assert_nothing_raised {
|
99
|
+
x = IB::Datatypes::Contract.new({:right => "call"})
|
100
|
+
}
|
101
|
+
assert_nothing_raised {
|
102
|
+
x = IB::Datatypes::Contract.new({:right => "CALL"})
|
103
|
+
}
|
104
|
+
assert_nothing_raised {
|
105
|
+
x = IB::Datatypes::Contract.new({:right => "P"})
|
106
|
+
}
|
107
|
+
assert_nothing_raised {
|
108
|
+
x = IB::Datatypes::Contract.new({:right => "p"})
|
109
|
+
}
|
110
|
+
assert_nothing_raised {
|
111
|
+
x = IB::Datatypes::Contract.new({:right => "c"})
|
112
|
+
}
|
113
|
+
assert_nothing_raised {
|
114
|
+
x = IB::Datatypes::Contract.new({:right => "C"})
|
115
|
+
}
|
116
|
+
|
117
|
+
assert_nothing_raised {
|
118
|
+
x = IB::Datatypes::Contract.new
|
119
|
+
x.right = "put"
|
120
|
+
}
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_serialize_long
|
125
|
+
x = nil
|
126
|
+
assert_nothing_raised {
|
127
|
+
x = IB::Datatypes::Contract.new
|
128
|
+
x.symbol = "TEST"
|
129
|
+
x.sec_type = IB::Datatypes::Contract::SECURITY_TYPES[:stock]
|
130
|
+
x.expiry = 200609
|
131
|
+
x.strike = 1234
|
132
|
+
x.right = "put"
|
133
|
+
x.multiplier = 123
|
134
|
+
x.exchange = "SMART"
|
135
|
+
x.currency = "USD"
|
136
|
+
x.local_symbol = "baz"
|
137
|
+
}
|
138
|
+
|
139
|
+
assert_equal(["TEST", IB::Datatypes::Contract::SECURITY_TYPES[:stock], "200609", 1234, "PUT", 123, "SMART", nil, "USD", "baz"],
|
140
|
+
x.serialize_long(20))
|
141
|
+
end # test_serialize_long
|
142
|
+
|
143
|
+
def test_serialize_short
|
144
|
+
x = nil
|
145
|
+
assert_nothing_raised {
|
146
|
+
x = IB::Datatypes::Contract.new
|
147
|
+
x.symbol = "TEST"
|
148
|
+
x.sec_type = IB::Datatypes::Contract::SECURITY_TYPES[:stock]
|
149
|
+
x.expiry = 200609
|
150
|
+
x.strike = 1234
|
151
|
+
x.right = "put"
|
152
|
+
x.multiplier = 123
|
153
|
+
x.exchange = "SMART"
|
154
|
+
x.currency = "USD"
|
155
|
+
x.local_symbol = "baz"
|
156
|
+
}
|
157
|
+
|
158
|
+
assert_equal(["TEST", IB::Datatypes::Contract::SECURITY_TYPES[:stock], "200609", 1234, "PUT", 123, "SMART", "USD", "baz"],
|
159
|
+
x.serialize_short(20))
|
160
|
+
end # test_serialize_short
|
161
|
+
|
162
|
+
end # ContractTests
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wdevauld-ib-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.2"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Wes Devauld
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-06-17 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: bones
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.2.0
|
24
|
+
version:
|
25
|
+
description: "* Ruby Implementation of the Interactive Broker' TWS API"
|
26
|
+
email: wes@devauld.ca
|
27
|
+
executables:
|
28
|
+
- AccountInfo
|
29
|
+
- HistoricToCSV
|
30
|
+
- RequestHistoricData
|
31
|
+
- RequestMarketData
|
32
|
+
- SimpleTimeAndSales
|
33
|
+
- ib-ruby
|
34
|
+
extensions: []
|
35
|
+
|
36
|
+
extra_rdoc_files:
|
37
|
+
- History.txt
|
38
|
+
- README.txt
|
39
|
+
- bin/AccountInfo
|
40
|
+
- bin/HistoricToCSV
|
41
|
+
- bin/RequestHistoricData
|
42
|
+
- bin/RequestMarketData
|
43
|
+
- bin/SimpleTimeAndSales
|
44
|
+
- bin/ib-ruby
|
45
|
+
files:
|
46
|
+
- History.txt
|
47
|
+
- LICENSE
|
48
|
+
- Manifest.txt
|
49
|
+
- README.txt
|
50
|
+
- Rakefile
|
51
|
+
- bin/AccountInfo
|
52
|
+
- bin/HistoricToCSV
|
53
|
+
- bin/RequestHistoricData
|
54
|
+
- bin/RequestMarketData
|
55
|
+
- bin/SimpleTimeAndSales
|
56
|
+
- bin/ib-ruby
|
57
|
+
- lib/ib-ruby.rb
|
58
|
+
- lib/ib-ruby/datatypes.rb
|
59
|
+
- lib/ib-ruby/ib.rb
|
60
|
+
- lib/ib-ruby/messages.rb
|
61
|
+
- lib/ib-ruby/symbols/forex.rb
|
62
|
+
- lib/ib-ruby/symbols/futures.rb
|
63
|
+
- spec/ib-ruby_spec.rb
|
64
|
+
- spec/spec_helper.rb
|
65
|
+
- test/test_ib-ruby.rb
|
66
|
+
has_rdoc: true
|
67
|
+
homepage: http://github.com/wdevauld/ib-ruby/tree/master
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options:
|
70
|
+
- --main
|
71
|
+
- README.txt
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
version:
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: "0"
|
85
|
+
version:
|
86
|
+
requirements: []
|
87
|
+
|
88
|
+
rubyforge_project: !binary |
|
89
|
+
AA==
|
90
|
+
|
91
|
+
rubygems_version: 1.2.0
|
92
|
+
signing_key:
|
93
|
+
specification_version: 2
|
94
|
+
summary: "* Ruby Implementation of the Interactive Broker' TWS API"
|
95
|
+
test_files:
|
96
|
+
- test/test_ib-ruby.rb
|