Skip to content

Commit 1587815

Browse files
author
Hartmut Bischoff
committed
Including test-suite
1 parent b8a40d4 commit 1587815

40 files changed

+169
-1107
lines changed

Rakefile

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
require "bundler/gem_tasks"
2-
require "rspec/api/rake_task"
32

4-
RSpec::Api::RakeTask.new(:spec)
3+
require "rake"
4+
require "rspec/core/rake_task"
55

6-
task :default => :spec
6+
RSpec::Core::RakeTask.new(:spec) do |t|
7+
t.pattern = Dir.glob("spec/**/*_spec.rb")
8+
t.rspec_opts = "--format documentation"
9+
end
10+
11+
task default: :spec

lib/api/version.rb

Lines changed: 0 additions & 3 deletions
This file was deleted.

lib/extensions/contract.rb

Lines changed: 0 additions & 37 deletions
This file was deleted.

lib/ib/messages/incoming/abstract_message.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def version # Per message, received messages may have the different versions
2020

2121
def check_version actual, expected
2222
unless actual == expected || expected.is_a?(Array) && expected.include?(actual)
23+
puts self.class.name
2324
error "Unsupported version #{actual} received, expected #{expected}"
2425
end
2526
end
@@ -34,7 +35,7 @@ def initialize source
3435
@buffer = source
3536
### DEBUG DEBUG DEBUG RAW STREAM ###############
3637
# if uncommented, the raw-input from the tws is included in the logging
37-
# puts "BUFFER :> #{buffer.inspect} "
38+
# puts "BUFFER :> #{buffer.inspect} "
3839
### DEBUG DEBUG DEBUG RAW STREAM ###############
3940
@data = Hash.new
4041
self.load

lib/ib/messages/incoming/contract_data.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module ContractAccessors
77

88
ContractDetails = ContractData =
99
def_message([10, [6, 8]],
10-
[:request_id, :int], # request id
10+
[:request_id, :int], ## request id
1111
[:contract, :symbol, :string], ## next the major contract-fields
1212
[:contract, :sec_type, :string], ## are transmitted
1313
[:contract, :last_trading_day, :date], ## difference to the array.get_contract
@@ -16,8 +16,8 @@ module ContractAccessors
1616
[:contract, :exchange, :string], ##
1717
[:contract, :currency, :string], ## thus we have to read the fields separately
1818
[:contract, :local_symbol, :string],
19-
[:contract_detail, :market_name, :string], # extended
20-
[:contract, :trading_class, :string], # new Version 8
19+
[:contract_detail, :market_name, :string], ## extended
20+
[:contract, :trading_class, :string], ## new Version 8
2121
[:contract, :con_id, :int],
2222
[:contract_detail, :min_tick, :decimal],
2323
[:contract_detail, :md_size_multiplier, :int],

lib/ib/messages/outgoing/abstract_message.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def initialize data={}
2626
def send_to socket
2727
### debugging of outgoing Messages
2828
# puts "------sendto ---------(debugging output in outgoing/abstract_message)"
29-
# puts socket.prepare_message( self.preprocess).inspect.split('\x00')[3..-1].inspect
29+
# puts socket.prepare_message( self.preprocess).inspect.split('\x00')[3..-1].inspect
3030
# puts "------sendto ---------"
3131
socket.send_messages self.preprocess #.each {|data| socket.write_data data}
3232
end

lib/ib/messages/outgoing/account_requests.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,16 @@ module Outgoing
8989
# accounts and/or models. The account and model parameters are
9090
# optional if there are not multiple accounts or models available.
9191
RequestPositionsMulti = def_message( 74, :request_id, # autogenerated
92-
:account,
92+
[ :account, 'ALL' ],
9393
[:model_code, nil ] )
9494

95-
CancelPositionsMulti = def_message 75 # :request_id required
95+
CancelPositionsMulti = def_message( 75, :request_id ) # required
9696

9797
RequestAccountUpdatesMulti = def_message( 76, :request_id, # autogenerated
98-
:account, # account or account-group
98+
[ :account, 'ALL'], # account or account-group
9999
[:model_code, nil],
100-
[ :leger_and_nlv, nil ])
101-
CancelAccountUpdatesMulti = def_message 77 # :request_id required
100+
[:leger_and_nlv, nil ])
101+
CancelAccountUpdatesMulti = def_message 77, :request_id # required
102102
end # module outgoing
103103
end # module messages
104104
end # module ib

lib/models/ib/contract.rb

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -371,13 +371,6 @@ def order_requirements
371371
require 'models/ib/future'
372372
require 'models/ib/stock'
373373
require 'models/ib/index'
374-
require 'models/ib/spread'
375-
# require 'models/ib/straddle'
376-
# require 'models/ib/strangle'
377-
# require 'models/ib/calendar'
378-
# require 'models/ib/vertical'
379-
# require 'models/ib/butterfly'
380-
# require 'models/ib/stock_spread'
381374

382375
class Contract
383376
# Contract subclasses representing specialized security types.
@@ -389,17 +382,11 @@ class Contract
389382
Subclasses[:stock] = IB::Stock
390383
Subclasses[:forex] = IB::Forex
391384
Subclasses[:index] = IB::Index
392-
Subclasses[:Spread] = IB::Spread
393-
# Subclasses[:strangle] = IB::Strangle
394-
# Subclasses[:calendar] = IB::Calendar
395-
# Subclasses[:vertical] = IB::Vertical
396385

397386

398387
# This builds an appropriate Contract subclass based on its type
399388
#
400-
# does NOT work with Straddle,Strangle,Calendar,Vertical and other spread-types
401-
#
402-
# is used to copy Contracts by value
389+
# the method is also used to copy Contract.values to new instances
403390
def self.build opts = {}
404391
subclass =( VALUES[:sec_type][opts[:sec_type]] || opts['sec_type'] || opts[:sec_type]).to_sym
405392
Contract::Subclasses[subclass].new opts

spec/account_helper.rb

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@
2929
context "received :AccountUpdateTime message" do
3030
subject { IB::Connection.current.received[:AccountUpdateTime].first }
3131

32-
it { should be_an IB::Messages::Incoming::AccountUpdateTime }
33-
its(:data) { should be_a Hash }
34-
its(:time_stamp) { should =~ /\d\d:\d\d/ }
35-
its(:to_human) { should =~ /AccountUpdateTime/ }
32+
it { is_expected.to be_an IB::Messages::Incoming::AccountUpdateTime }
33+
its(:data) { is_expected.to be_a Hash }
34+
its(:time_stamp) { is_expected.to match /\d\d:\d\d/ }
35+
its(:to_human) { is_expected.to match /AccountUpdateTime/ }
3636
end
3737

3838
context "received :AccountValue message" do
@@ -52,8 +52,8 @@
5252
subject { IB::Connection.current.received[:PortfolioValue].first }
5353

5454
it { is_expected.to be_an IB::Messages::Incoming::PortfolioValue }
55-
its( :contract ) { should be_a IB::Contract }
56-
its( :data ) { should be_a Hash }
55+
its( :contract ) { is_expected.to be_a IB::Contract }
56+
its( :data ) { is_expected.to be_a Hash }
5757
its( :portfolio_value ){is_expected.to be_a IB::PortfolioValue }
5858
its( :account ) { is_expected.to match /\w\d/ }
5959

@@ -77,3 +77,17 @@
7777
its(:to_human) { should =~ /AccountDownloadEnd/ }
7878
end
7979
end
80+
81+
shared_examples_for 'ReceiveFA message' do
82+
it { is_expected.to be_an IB::Messages::Incoming::ReceiveFA }
83+
its(:message_type) { is_expected.to eq :ReceiveFA }
84+
its(:message_id) { is_expected.to eq 16 }
85+
its(:accounts) {is_expected.to be_an Array}
86+
its( :buffer ){ is_expected.to be_empty }
87+
88+
it 'has class accessors as well' do
89+
expect( subject.class.message_id).to eq 16
90+
expect( subject.class.message_type).to eq :ReceiveFA
91+
end
92+
end
93+

spec/contract_helper.rb

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@
66
After calling the helper-function, the fetched ContractDetail-Messages are still present in received-buffer
77
=end
88

9-
def request_con_id contract: SAMPLE
9+
def request_con_id sample: SAMPLE
10+
1011

1112
ib = IB::Connection.current
13+
while ib.nil?
14+
establish_connection unless ib.is_a? IB::Connection
15+
ib = IB::Connection.current
16+
end
17+
1218
ib.clear_received
1319
raise 'Unable to verify contract, no connection' unless ib && ib.connected?
1420

15-
ib.send_message :RequestContractDetails, contract: contract
21+
ib.send_message :RequestContractDetails, contract: sample
1622
ib.wait_for :ContractDetailsEnd
1723

1824
ib.received[:ContractData].contract.map &:con_id # return an array of con_id's
@@ -27,7 +33,7 @@ def request_con_id contract: SAMPLE
2733
its( :primary_exchange){ is_expected.to be_a String }
2834
end
2935
RSpec.shared_examples 'a valid Contract Object' do
30-
subject{ the_contract }
36+
# subject{ the_contract }
3137
it { is_expected.to be_an IB::Contract }
3238
its( :con_id ){ is_expected.to be_empty.or be_a(Numeric) }
3339
its( :contract_detail ){ is_expected.to be_nil.or be_a(IB::ContractDetail) }
@@ -39,3 +45,17 @@ def request_con_id contract: SAMPLE
3945
its( :exchange ){ is_expected.to be_a String }
4046
its( :primary_exchange){ is_expected.to be_nil.or be_a(String) }
4147
end
48+
RSpec.shared_examples 'ContractData Message' do
49+
subject{ the_message }
50+
it { is_expected.to be_an IB::Messages::Incoming::ContractData }
51+
its( :contract ){ is_expected.to be_a IB::Contract }
52+
its( :contract_details ){ is_expected.to be_a IB::ContractDetail }
53+
its( :message_id ){ is_expected.to eq 10 }
54+
its( :version ){ is_expected.to eq 8 }
55+
its( :buffer ){ is_expected.to be_empty }
56+
57+
it 'has class accessors as well' do
58+
expect( subject.class.message_id).to eq 10
59+
expect( subject.class.message_type).to eq :ContractData
60+
end
61+
end

0 commit comments

Comments
 (0)