ib-ruby 0.7.8 → 0.7.9
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 +4 -0
- data/VERSION +1 -1
- data/lib/ib-ruby/models/model_properties.rb +59 -50
- data/lib/ib-ruby/models/order.rb +7 -1
- data/lib/ib-ruby/models/order_state.rb +25 -0
- data/spec/ib-ruby/models/order_spec.rb +23 -0
- data/spec/ib-ruby/models/order_state_spec.rb +61 -1
- metadata +2 -2
data/HISTORY
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.9
|
@@ -27,11 +27,20 @@ module IB
|
|
27
27
|
# Comparison support
|
28
28
|
def content_attributes
|
29
29
|
HashWithIndifferentAccess[attributes.reject do |(attr, _)|
|
30
|
-
attr.to_s =~ /(
|
31
|
-
[:created_at, :updated_at, :type,
|
30
|
+
attr.to_s =~ /(_count)$/ ||
|
31
|
+
[:created_at, :updated_at, :type,
|
32
|
+
:id, :order_id, :contract_id].include?(attr.to_sym)
|
32
33
|
end]
|
33
34
|
end
|
34
35
|
|
36
|
+
# Update nil attributes from given Hash or model
|
37
|
+
def update_missing attrs
|
38
|
+
attrs = attrs.content_attributes unless attrs.kind_of?(Hash)
|
39
|
+
|
40
|
+
attrs.each { |attr, val| send "#{attr}=", val if send(attr).blank? }
|
41
|
+
self # for chaining
|
42
|
+
end
|
43
|
+
|
35
44
|
# Default Model comparison
|
36
45
|
def == other
|
37
46
|
content_attributes.inject(true) { |res, (attr, value)| res && other.send(attr) == value } &&
|
@@ -73,58 +82,58 @@ module IB
|
|
73
82
|
def self.define_property_methods name, body={}
|
74
83
|
#p name, body
|
75
84
|
case body
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
end
|
85
|
+
when '' # default getter and setter
|
86
|
+
define_property_methods name
|
87
|
+
|
88
|
+
when Array # [setter, getter, validators]
|
89
|
+
define_property_methods name,
|
90
|
+
:get => body[0],
|
91
|
+
:set => body[1],
|
92
|
+
:validate => body[2]
|
93
|
+
|
94
|
+
when Hash # recursion base case
|
95
|
+
getter = case # Define getter
|
96
|
+
when body[:get].respond_to?(:call)
|
97
|
+
body[:get]
|
98
|
+
when body[:get]
|
99
|
+
proc { self[name].send "to_#{body[:get]}" }
|
100
|
+
when VALUES[name] # property is encoded
|
101
|
+
proc { VALUES[name][self[name]] }
|
102
|
+
#when respond_to?(:column_names) && column_names.include?(name.to_s)
|
103
|
+
# # noop, ActiveRecord will take care of it...
|
104
|
+
# p "#{name} => get noop"
|
105
|
+
# p respond_to?(:column_names) && column_names
|
106
|
+
else
|
107
|
+
proc { self[name] }
|
108
|
+
end
|
109
|
+
define_method name, &getter if getter
|
110
|
+
|
111
|
+
setter = case # Define setter
|
112
|
+
when body[:set].respond_to?(:call)
|
113
|
+
body[:set]
|
114
|
+
when body[:set]
|
115
|
+
proc { |value| self[name] = value.send "to_#{body[:set]}" }
|
116
|
+
when CODES[name] # property is encoded
|
117
|
+
proc { |value| self[name] = CODES[name][value] || value }
|
118
|
+
else
|
119
|
+
proc { |value| self[name] = value } # p name, value;
|
120
|
+
end
|
121
|
+
define_method "#{name}=", &setter if setter
|
122
|
+
|
123
|
+
# Define validator(s)
|
124
|
+
[body[:validate]].flatten.compact.each do |validator|
|
125
|
+
case validator
|
126
|
+
when Proc
|
127
|
+
validates_each name, &validator
|
128
|
+
when Hash
|
129
|
+
validates name, validator.dup
|
122
130
|
end
|
131
|
+
end
|
123
132
|
|
124
133
|
# TODO define self[:name] accessors for :virtual and :flag properties
|
125
134
|
|
126
|
-
|
127
|
-
|
135
|
+
else # setter given
|
136
|
+
define_property_methods name, :set => body, :get => body
|
128
137
|
end
|
129
138
|
end
|
130
139
|
|
data/lib/ib-ruby/models/order.rb
CHANGED
@@ -264,7 +264,13 @@ module IB
|
|
264
264
|
:last_fill_price, # double
|
265
265
|
:average_price, # double
|
266
266
|
:average_fill_price, # double
|
267
|
-
:why_held # String: comma-separated list of reasons for order to be held.
|
267
|
+
:why_held, # String: comma-separated list of reasons for order to be held.
|
268
|
+
# Testing Order state:
|
269
|
+
:new?,
|
270
|
+
:pending?,
|
271
|
+
:active?,
|
272
|
+
:inactive?,
|
273
|
+
:complete_fill?,
|
268
274
|
].each { |property| define_method(property) { order_state.send(property) } }
|
269
275
|
|
270
276
|
# Order is not valid without correct :local_id (:order_id)
|
@@ -63,6 +63,31 @@ module IB
|
|
63
63
|
validates_numericality_of :local_id, :perm_id, :client_id, :parent_id, :filled,
|
64
64
|
:remaining, :only_integer => true, :allow_nil => true
|
65
65
|
|
66
|
+
## Testing Order state:
|
67
|
+
|
68
|
+
def new?
|
69
|
+
status.empty? || status == 'New'
|
70
|
+
end
|
71
|
+
|
72
|
+
# Order is in a valid, working state on TWS side
|
73
|
+
def pending?
|
74
|
+
status == 'PendingSubmit' || status == 'PreSubmitted' || status == 'Submitted'
|
75
|
+
end
|
76
|
+
|
77
|
+
# Order is in invalid state
|
78
|
+
def active?
|
79
|
+
new? || pending?
|
80
|
+
end
|
81
|
+
|
82
|
+
# Order is in invalid state
|
83
|
+
def inactive?
|
84
|
+
!active? # status == 'Inactive'
|
85
|
+
end
|
86
|
+
|
87
|
+
def complete_fill?
|
88
|
+
status == 'Filled' && remaining == 0 # filled >= total_quantity # Manually corrected
|
89
|
+
end
|
90
|
+
|
66
91
|
# Comparison
|
67
92
|
def == other
|
68
93
|
other && other.is_a?(OrderState) &&
|
@@ -117,7 +117,30 @@ describe IB::Models::Order do
|
|
117
117
|
|
118
118
|
it 'has extra accessors to OrderState properties' do
|
119
119
|
subject.order_state.should_not be_nil
|
120
|
+
|
120
121
|
subject.status.should == 'New'
|
122
|
+
subject.commission.should be_nil
|
123
|
+
subject.commission_currency.should be_nil
|
124
|
+
subject.min_commission.should be_nil
|
125
|
+
subject.max_commission.should be_nil
|
126
|
+
subject.warning_text.should be_nil
|
127
|
+
subject.init_margin.should be_nil
|
128
|
+
subject.maint_margin.should be_nil
|
129
|
+
subject.equity_with_loan.should be_nil
|
130
|
+
# Properties arriving via OrderStatus messagesubject.
|
131
|
+
subject.filled.should be_nil
|
132
|
+
subject.remaining.should be_nil
|
133
|
+
subject.price.should be_nil
|
134
|
+
subject.last_fill_price.should be_nil
|
135
|
+
subject.average_price.should be_nil
|
136
|
+
subject.average_fill_price.should be_nil
|
137
|
+
subject.why_held.should be_nil
|
138
|
+
# Testing Order statesubject.
|
139
|
+
subject.should be_new
|
140
|
+
subject.should_not be_pending
|
141
|
+
subject.should be_active
|
142
|
+
subject.should_not be_inactive
|
143
|
+
subject.should_not be_complete_fill
|
121
144
|
end
|
122
145
|
|
123
146
|
context 'update Order state by ' do
|
@@ -38,7 +38,7 @@ describe IB::Models::OrderState do
|
|
38
38
|
let(:assigns) do
|
39
39
|
{[:status] =>
|
40
40
|
{[nil, ''] => /must not be empty/,
|
41
|
-
['Zorro', :Zorro] => 'Zorro'
|
41
|
+
['Zorro', :Zorro] => 'Zorro'}
|
42
42
|
}
|
43
43
|
end
|
44
44
|
|
@@ -52,4 +52,64 @@ describe IB::Models::OrderState do
|
|
52
52
|
it_behaves_like 'Model'
|
53
53
|
it_behaves_like 'Self-equal Model'
|
54
54
|
|
55
|
+
context '#update_missing' do
|
56
|
+
context 'updating with Hash' do
|
57
|
+
|
58
|
+
subject { IB::OrderState.new.update_missing(props) }
|
59
|
+
|
60
|
+
it_behaves_like 'Model instantiated with properties'
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'updating with Model' do
|
65
|
+
|
66
|
+
subject { IB::OrderState.new.update_missing(IB::OrderState.new(props)) }
|
67
|
+
|
68
|
+
it_behaves_like 'Model instantiated with properties'
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'has extra test methods' do
|
75
|
+
empty_state = IB::OrderState.new
|
76
|
+
empty_state.should be_new
|
77
|
+
empty_state.should be_active
|
78
|
+
empty_state.should_not be_inactive
|
79
|
+
empty_state.should_not be_complete_fill
|
80
|
+
|
81
|
+
state = IB::OrderState.new(props)
|
82
|
+
['PendingSubmit', 'PreSubmitted', 'Submitted'].each do |status|
|
83
|
+
state.status = status
|
84
|
+
state.should_not be_new
|
85
|
+
state.should be_active
|
86
|
+
state.should_not be_inactive
|
87
|
+
state.should_not be_complete_fill
|
88
|
+
state.should be_pending
|
89
|
+
end
|
90
|
+
|
91
|
+
['PendingCancel', 'Cancelled', 'ApiCancelled', 'Inactive'].each do |status|
|
92
|
+
state.status = status
|
93
|
+
state.should_not be_new
|
94
|
+
state.should_not be_active
|
95
|
+
state.should be_inactive
|
96
|
+
state.should_not be_complete_fill
|
97
|
+
state.should_not be_pending
|
98
|
+
end
|
99
|
+
|
100
|
+
state.status = 'Filled'
|
101
|
+
state.should_not be_new
|
102
|
+
state.should_not be_active
|
103
|
+
state.should be_inactive
|
104
|
+
state.should_not be_complete_fill
|
105
|
+
state.should_not be_pending
|
106
|
+
|
107
|
+
state.remaining = 0
|
108
|
+
state.should_not be_new
|
109
|
+
state.should_not be_active
|
110
|
+
state.should be_inactive
|
111
|
+
state.should be_complete_fill
|
112
|
+
state.should_not be_pending
|
113
|
+
end
|
114
|
+
|
55
115
|
end # describe IB::Order
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: ib-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.7.
|
5
|
+
version: 0.7.9
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Paul Legato
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2012-04-
|
14
|
+
date: 2012-04-24 00:00:00 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|