ib-ruby 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/HISTORY +4 -0
  2. data/README.md +25 -17
  3. data/VERSION +1 -1
  4. data/bin/account_info +1 -1
  5. data/bin/cancel_orders +2 -1
  6. data/bin/contract_details +3 -2
  7. data/bin/depth_of_market +1 -1
  8. data/bin/historic_data +1 -1
  9. data/bin/historic_data_cli +57 -104
  10. data/bin/list_orders +4 -3
  11. data/bin/market_data +1 -1
  12. data/bin/option_data +1 -1
  13. data/bin/place_combo_order +63 -0
  14. data/bin/place_order +2 -4
  15. data/bin/template +1 -1
  16. data/bin/{generic_data.rb → tick_data} +3 -1
  17. data/bin/time_and_sales +1 -1
  18. data/lib/ib-ruby.rb +1 -0
  19. data/lib/ib-ruby/connection.rb +68 -68
  20. data/lib/ib-ruby/errors.rb +28 -0
  21. data/lib/ib-ruby/extensions.rb +7 -0
  22. data/lib/ib-ruby/messages.rb +1 -0
  23. data/lib/ib-ruby/messages/abstract_message.rb +16 -11
  24. data/lib/ib-ruby/messages/incoming.rb +125 -329
  25. data/lib/ib-ruby/messages/incoming/open_order.rb +193 -0
  26. data/lib/ib-ruby/messages/incoming/ticks.rb +131 -0
  27. data/lib/ib-ruby/messages/outgoing.rb +44 -45
  28. data/lib/ib-ruby/models/combo_leg.rb +16 -1
  29. data/lib/ib-ruby/models/contract.rb +18 -10
  30. data/lib/ib-ruby/models/contract/bag.rb +1 -7
  31. data/lib/ib-ruby/models/execution.rb +2 -1
  32. data/lib/ib-ruby/models/model.rb +1 -1
  33. data/lib/ib-ruby/models/order.rb +116 -56
  34. data/lib/ib-ruby/socket.rb +24 -3
  35. data/spec/account_helper.rb +2 -1
  36. data/spec/ib-ruby/messages/outgoing_spec.rb +1 -1
  37. data/spec/ib-ruby/models/combo_leg_spec.rb +0 -1
  38. data/spec/integration/account_info_spec.rb +2 -2
  39. data/spec/integration/contract_info_spec.rb +4 -4
  40. data/spec/integration/depth_data_spec.rb +3 -3
  41. data/spec/integration/historic_data_spec.rb +1 -1
  42. data/spec/integration/market_data_spec.rb +4 -4
  43. data/spec/integration/option_data_spec.rb +1 -1
  44. data/spec/integration/orders/combo_spec.rb +51 -0
  45. data/spec/integration/orders/execution_spec.rb +15 -8
  46. data/spec/integration/orders/placement_spec.rb +46 -72
  47. data/spec/integration/orders/valid_ids_spec.rb +6 -6
  48. data/spec/integration_helper.rb +0 -79
  49. data/spec/order_helper.rb +153 -0
  50. metadata +13 -4
@@ -4,7 +4,12 @@ module IB
4
4
  class IBSocket < TCPSocket
5
5
 
6
6
  # send nice null terminated binary data into socket
7
- def send data
7
+ def write_data data
8
+ # TWS wants to receive booleans as 1 or 0
9
+ data = "1" if data == true
10
+ data = "0" if data == false
11
+
12
+ #p data.to_s + EOL
8
13
  self.syswrite(data.to_s + EOL)
9
14
  end
10
15
 
@@ -26,11 +31,12 @@ module IB
26
31
 
27
32
  def read_int_max
28
33
  str = self.read_string
29
- str.nil? || str.empty? ? nil : str.to_i
34
+ str.to_i unless str.nil? || str.empty?
30
35
  end
31
36
 
32
37
  def read_boolean
33
- self.read_string.to_i != 0
38
+ str = self.read_string
39
+ str.nil? ? false : str.to_i != 0
34
40
  end
35
41
 
36
42
  def read_decimal
@@ -60,6 +66,21 @@ module IB
60
66
  def read_decimal_limit_2
61
67
  read_decimal_limit -2
62
68
  end
69
+
70
+ ### Complex operations
71
+
72
+ # Returns loaded Array or [] if count was 0
73
+ def read_array &block
74
+ count = read_int
75
+ count > 0 ? Array.new(count, &block) : []
76
+ end
77
+
78
+ # Returns loaded Hash
79
+ def read_hash
80
+ tags = read_array { |_| [read_string, read_string] }
81
+ tags.empty? ? Hash.new : Hash[*tags.flatten]
82
+ end
83
+
63
84
  end # class IBSocket
64
85
 
65
86
  end # module IB
@@ -16,7 +16,8 @@ def verify_account
16
16
  @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
17
17
  @ib.send_message :RequestAccountData, :subscribe => true
18
18
 
19
- @ib.wait_for 3, :AccountValue
19
+ @ib.wait_for :AccountDownloadEnd
20
+ @ib.send_message :RequestAccountData, :subscribe => false
20
21
  raise "Unable to verify IB PAPER ACCOUNT" unless @ib.received?(:AccountValue)
21
22
 
22
23
  received = @ib.received[:AccountValue].first.account_name
@@ -25,7 +25,7 @@ describe IB::Messages::Outgoing do
25
25
  end
26
26
 
27
27
  it 'encodes into Array' do
28
- subject.encode.should == [6, 2, true, "DUH"]
28
+ subject.encode(:server_version => 60).should == [6, 2, true, "DUH"]
29
29
  end
30
30
 
31
31
  end
@@ -19,7 +19,6 @@ describe IB::Models::ComboLeg do
19
19
 
20
20
  it { should_not be_nil }
21
21
  its(:con_id) {should == 0}
22
- its(:ratio) {should == 0}
23
22
  its(:open_close) {should == 0}
24
23
  its(:short_sale_slot) {should == 0}
25
24
  its(:designated_location) {should == ''}
@@ -12,7 +12,7 @@ describe "Request Account Data", :connected => true, :integration => true do
12
12
  context "with subscribe option set" do
13
13
  before(:all) do
14
14
  @ib.send_message :RequestAccountData, :subscribe => true
15
- @ib.wait_for 5, :AccountDownloadEnd
15
+ @ib.wait_for :AccountDownloadEnd, 5 # sec
16
16
  end
17
17
  after(:all) do
18
18
  @ib.send_message :RequestAccountData, :subscribe => false
@@ -25,7 +25,7 @@ describe "Request Account Data", :connected => true, :integration => true do
25
25
  context "without subscribe option" do
26
26
  before(:all) do
27
27
  @ib.send_message :RequestAccountData
28
- @ib.wait_for 5, :AccountDownloadEnd
28
+ @ib.wait_for :AccountDownloadEnd, 5 # sec
29
29
  end
30
30
 
31
31
  after(:all) do
@@ -16,7 +16,7 @@ describe "Request Contract Info", :connected => true, :integration => true do
16
16
  @contract = IB::Models::Contract.new :symbol => 'AAPL',
17
17
  :sec_type => IB::SECURITY_TYPES[:stock]
18
18
  @ib.send_message :RequestContractData, :id => 111, :contract => @contract
19
- @ib.wait_for 3, :ContractDataEnd
19
+ @ib.wait_for :ContractDataEnd, 3 # sec
20
20
  end
21
21
 
22
22
  after(:all) { clean_connection } # Clear logs and message collector
@@ -66,7 +66,7 @@ describe "Request Contract Info", :connected => true, :integration => true do
66
66
  :right => "CALL",
67
67
  :strike => 500
68
68
  @ib.send_message :RequestContractData, :id => 123, :contract => @contract
69
- @ib.wait_for 3, :ContractDataEnd
69
+ @ib.wait_for :ContractDataEnd, 3 # sec
70
70
  end
71
71
 
72
72
  after(:all) { clean_connection } # Clear logs and message collector
@@ -112,7 +112,7 @@ describe "Request Contract Info", :connected => true, :integration => true do
112
112
  :exchange => "IDEALPRO",
113
113
  :sec_type => IB::SECURITY_TYPES[:forex]
114
114
  @ib.send_message :RequestContractData, :id => 135, :contract => @contract
115
- @ib.wait_for 3, :ContractDataEnd
115
+ @ib.wait_for :ContractDataEnd, 3 # sec
116
116
  end
117
117
 
118
118
  after(:all) { clean_connection } # Clear logs and message collector
@@ -155,7 +155,7 @@ describe "Request Contract Info", :connected => true, :integration => true do
155
155
  before(:all) do
156
156
  @contract = IB::Symbols::Futures[:ym] # Mini Dow Jones Industrial
157
157
  @ib.send_message :RequestContractData, :id => 147, :contract => @contract
158
- @ib.wait_for 3, :ContractDataEnd
158
+ @ib.wait_for :ContractDataEnd, 3 # sec
159
159
  end
160
160
 
161
161
  after(:all) { clean_connection } # Clear logs and message collector
@@ -10,7 +10,7 @@ describe 'Request Depth of Market Data', :connected => true,
10
10
  @ib.send_message :RequestMarketDepth, :id => 456, :num_rows => 3,
11
11
  :contract => IB::Symbols::Forex[:eurusd]
12
12
 
13
- @ib.wait_for 10, [:MarketDepth, 8]
13
+ @ib.wait_for [:MarketDepth, 4], 6 # sec
14
14
  end
15
15
 
16
16
  after(:all) do
@@ -20,7 +20,7 @@ describe 'Request Depth of Market Data', :connected => true,
20
20
 
21
21
  subject { @ib.received[:MarketDepth].last }
22
22
 
23
- it { @ib.received[:MarketDepth].should have_at_least(8).depth_data }
23
+ it { @ib.received[:MarketDepth].should have_at_least(4).depth_data }
24
24
 
25
25
  it { should be_an IB::Messages::Incoming::MarketDepth }
26
26
  its(:request_id) { should == 456 }
@@ -30,7 +30,7 @@ describe 'Request Depth of Market Data', :connected => true,
30
30
 
31
31
  it 'has position field reflecting the row Id of this market depth entry' do
32
32
  subject.position.should be_an Integer
33
- subject.position.should be >= 1
33
+ subject.position.should be >= 0
34
34
  subject.position.should be <= 3
35
35
  end
36
36
 
@@ -37,7 +37,7 @@ describe 'Request Historic Data', :connected => true, :integration => true do
37
37
  before(:all) do
38
38
  # No historical data for GBP/CASH@IDEALPRO
39
39
  @ib.send_message :RequestHistoricalData, CORRECT_OPTS
40
- @ib.wait_for 5, :HistoricalData
40
+ @ib.wait_for :HistoricalData, 5 # sec
41
41
  end
42
42
 
43
43
  subject { @ib.received[:HistoricalData].last }
@@ -19,7 +19,7 @@ describe 'Request Market Data', :connected => true, :integration => true do
19
19
  :description => "Apple"
20
20
  )
21
21
  @ib.send_message :RequestMarketData, :id => 456, :contract => @contract
22
- @ib.wait_for 5, :TickSize, :TickString
22
+ @ib.wait_for :TickSize, :TickString, 3 # sec
23
23
  end
24
24
 
25
25
  after(:all) do
@@ -48,12 +48,12 @@ describe 'Request Market Data', :connected => true, :integration => true do
48
48
  before(:all) do
49
49
  @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
50
50
 
51
- ##TODO consider a follow the sun market lookup for windening the types tested
51
+ ##TODO consider a follow the sun market lookup for widening the types tested
52
52
  @ib.subscribe(:Alert, :TickPrice, :TickSize) {}
53
53
  @ib.send_message :RequestMarketData, :id => 456,
54
54
  :contract => IB::Symbols::Forex[:eurusd]
55
55
 
56
- @ib.wait_for 3, :TickPrice, :TickSize
56
+ @ib.wait_for :TickPrice, :TickSize, 3 # sec
57
57
  end
58
58
 
59
59
  after(:all) do
@@ -84,7 +84,7 @@ describe 'Request Market Data', :connected => true, :integration => true do
84
84
 
85
85
  @ib.send_message :RequestMarketData, :id => 456,
86
86
  :contract => IB::Symbols::Forex[:eurusd]
87
- @ib.wait_for 3, :TickPrice, :TickSize
87
+ @ib.wait_for :TickPrice, :TickSize, 3 # sec
88
88
  end
89
89
 
90
90
  after(:all) do
@@ -9,7 +9,7 @@ describe 'Request Market Data for Options', :if => :us_trading_hours,
9
9
 
10
10
  @ib.send_message :RequestMarketData, :id => 456,
11
11
  :contract => IB::Symbols::Options[:aapl500]
12
- @ib.wait_for 5, :TickPrice, :TickSize, :TickString, :TickOption
12
+ @ib.wait_for :TickPrice, :TickSize, :TickString, :TickOption, 5 # sec
13
13
  end
14
14
 
15
15
  after(:all) do
@@ -0,0 +1,51 @@
1
+ require 'order_helper'
2
+
3
+ #OPTS[:silent] = false
4
+
5
+ def butterfly symbol, expiry, right, *strikes
6
+ raise 'No Connection!' unless @ib && @ib.connected?
7
+
8
+ legs = strikes.zip([1, -2, 1]).map do |strike, weight|
9
+ # Create contract
10
+ contract = IB::Models::Contract::Option.new :symbol => symbol,
11
+ :expiry => expiry,
12
+ :right => right,
13
+ :strike => strike
14
+ # Find out contract's con_id
15
+ @ib.clear_received :ContractData, :ContractDataEnd
16
+ @ib.send_message :RequestContractData, :id => strike, :contract => contract
17
+ @ib.wait_for :ContractDataEnd, 3
18
+ con_id = @ib.received[:ContractData].last.contract.con_id
19
+
20
+ # Create Comboleg from con_id and weight
21
+ IB::Models::ComboLeg.new :con_id => con_id, :weight => weight
22
+ end
23
+
24
+ # Create new Combo contract
25
+ IB::Models::Contract::Bag.new :symbol => symbol,
26
+ :currency => "USD", # Only US options in combo Contracts
27
+ :exchange => "SMART",
28
+ :legs => legs
29
+ end
30
+
31
+ describe "Combo Order", :connected => true, :integration => true do
32
+
33
+ before(:all) { verify_account }
34
+
35
+ context "Limit" do # , :if => :us_trading_hours
36
+ before(:all) do
37
+ @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
38
+ @ib.wait_for :NextValidId
39
+ @ib.clear_received # to avoid conflict with pre-existing Orders
40
+
41
+ @combo = butterfly 'GOOG', '201301', 'CALL', 500, 510, 520
42
+
43
+ place_order @combo, :limit_price => 0.01 #, :what_if => true
44
+ @ib.wait_for [:OpenOrder, 3], [:OrderStatus, 2], 5
45
+ end
46
+
47
+ after(:all) { close_connection }
48
+
49
+ it_behaves_like 'Placed Order'
50
+ end # Limit
51
+ end # Combo Orders
@@ -1,5 +1,6 @@
1
- require 'integration_helper'
1
+ require 'order_helper'
2
2
 
3
+ #OPTS[:silent] = false
3
4
  describe "Trades", :connected => true, :integration => true, :slow => true do
4
5
 
5
6
  before(:all) { verify_account }
@@ -21,9 +22,15 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
21
22
  :total_quantity => 20000,
22
23
  :limit_price => 2,
23
24
  :action => 'BUY'
25
+ #:all_or_none => 1,
26
+ #:fa_profile => 2,
27
+ #:percent_offset => 3,
28
+ #:clearing_account => 'z',
29
+ #:what_if => true
24
30
 
25
31
  @ib.wait_for(5, :ExecutionData, :OpenOrder) do
26
- @ib.received[:OpenOrder].last.order.commission
32
+ @ib.received[:OpenOrder].last &&
33
+ @ib.received[:OpenOrder].last.order.commission
27
34
  end
28
35
  end
29
36
 
@@ -43,7 +50,7 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
43
50
  it { @ib.received[:ExecutionDataEnd].should be_empty }
44
51
 
45
52
  it 'receives filled OpenOrder' do
46
- open_order_should_be 'Filled', -1
53
+ order_should_be 'Filled', -1
47
54
  msg = @ib.received[:OpenOrder].last
48
55
  msg.order.commission.should == 2.5
49
56
  end
@@ -53,7 +60,7 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
53
60
  end
54
61
 
55
62
  it 'receives OrderStatus with fill details' do
56
- order_status_should_be 'Filled', -1
63
+ status_should_be 'Filled', -1
57
64
  end
58
65
  end # Placing BUY
59
66
 
@@ -65,7 +72,7 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
65
72
  :limit_price => 1,
66
73
  :action => 'SELL'
67
74
 
68
- @ib.wait_for(5, :ExecutionData, :OpenOrder) do
75
+ @ib.wait_for(:ExecutionData, :OpenOrder, 5) do
69
76
  @ib.received[:OpenOrder].last.order.commission
70
77
  end
71
78
  end
@@ -85,7 +92,7 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
85
92
  it { @ib.received[:ExecutionData].should have_exactly(1).execution_data }
86
93
 
87
94
  it 'receives filled OpenOrder' do
88
- open_order_should_be 'Filled', -1
95
+ order_should_be 'Filled', -1
89
96
  msg = @ib.received[:OpenOrder].last
90
97
  msg.order.commission.should == 2.5
91
98
  end
@@ -95,7 +102,7 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
95
102
  end
96
103
 
97
104
  it 'receives OrderStatus with fill details' do
98
- order_status_should_be 'Filled', -1
105
+ status_should_be 'Filled', -1
99
106
  end
100
107
  end # Placing SELL
101
108
 
@@ -107,7 +114,7 @@ describe "Trades", :connected => true, :integration => true, :slow => true do
107
114
  :request_id => 456,
108
115
  :client_id => OPTS[:connection][:client_id],
109
116
  :time => (Time.now-10).to_ib # Time zone problems possible
110
- @ib.wait_for 3, :ExecutionData
117
+ @ib.wait_for :ExecutionData, 3 # sec
111
118
  end
112
119
 
113
120
  #after(:all) { clean_connection }
@@ -1,19 +1,19 @@
1
- require 'integration_helper'
1
+ require 'order_helper'
2
2
 
3
- describe "Orders", :connected => true, :integration => true do
3
+ #OPTS[:silent] = false
4
+ describe 'Orders', :connected => true, :integration => true do
4
5
 
5
6
  before(:all) { verify_account }
6
7
 
7
- context "Placing wrong order", :slow => true do
8
+ context 'Placing wrong order', :slow => true do
8
9
 
9
10
  before(:all) do
10
11
  @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
11
-
12
12
  @ib.wait_for :NextValidId
13
13
 
14
14
  place_order IB::Symbols::Stocks[:wfc],
15
15
  :limit_price => 9.131313 # Weird non-acceptable price
16
- @ib.wait_for 1
16
+ @ib.wait_for 1 # sec
17
17
  end
18
18
 
19
19
  after(:all) { close_connection }
@@ -39,88 +39,62 @@ describe "Orders", :connected => true, :integration => true do
39
39
 
40
40
  end # Placing wrong order
41
41
 
42
- context "Off-market stock order" do
42
+ context 'What-if order' do
43
43
  before(:all) do
44
44
  @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
45
45
  @ib.wait_for :NextValidId
46
46
 
47
47
  place_order IB::Symbols::Stocks[:wfc],
48
- :limit_price => 9.13 # Set acceptable price
49
- @ib.wait_for [:OpenOrder, 3], [:OrderStatus, 2]
48
+ :limit_price => 9.13, # Set acceptable price
49
+ :what_if => true # Hypothetical
50
+ @ib.wait_for 1
50
51
  end
51
52
 
52
53
  after(:all) { close_connection }
53
54
 
54
- context "Placing" do
55
- after(:all) { clean_connection } # Clear logs and message collector
56
-
57
- it 'changes client`s next_order_id' do
58
- @order_id_placed.should == @order_id_before
59
- @ib.next_order_id.should == @order_id_before + 1
60
- end
61
-
62
- it { @ib.received[:OpenOrder].should have_at_least(1).open_order_message }
63
- it { @ib.received[:OrderStatus].should have_at_least(1).status_message }
64
-
65
- it 'receives confirmation of Order submission' do
66
- open_order_should_be /Submitted/ # ()Pre)Submitted
67
- order_status_should_be /Submitted/
68
- end
69
- end # Placing
70
-
71
- context "Retrieving placed orders" do
72
- before(:all) do
73
- @ib.send_message :RequestOpenOrders
74
- @ib.wait_for :OpenOrderEnd
75
- end
76
-
77
- after(:all) { clean_connection } # Clear logs and message collector
78
-
79
- it 'does not increase client`s next_order_id further' do
80
- @ib.next_order_id.should == @order_id_after
81
- end
82
-
83
- it { @ib.received[:OpenOrder].should have_exactly(1).open_order_message }
84
- it { @ib.received[:OrderStatus].should have_exactly(1).status_message }
85
- it { @ib.received[:OpenOrderEnd].should have_exactly(1).order_end_message }
86
- it { @ib.received[:Alert].should have_exactly(0).alert_messages }
87
-
88
- it 'receives OpenOrder and OrderStatus for placed order' do
89
- open_order_should_be /Submitted/
90
- order_status_should_be /Submitted/
91
- end
92
- end # Retrieving
93
-
94
- context "Cancelling placed order" do
95
- before(:all) do
96
- @ib.cancel_order @order_id_placed
97
-
98
- @ib.wait_for :OrderStatus, :Alert
99
- end
55
+ it 'changes client`s next_order_id' do
56
+ @order_id_placed.should == @order_id_before
57
+ @ib.next_order_id.should == @order_id_before + 1
58
+ end
100
59
 
101
- after(:all) { clean_connection } # Clear logs and message collector
60
+ it { @ib.received[:OpenOrder].should have_at_least(1).open_order_message }
61
+ it { @ib.received[:OrderStatus].should have_exactly(0).status_messages }
62
+
63
+ it 'returns as what-if Order with margin and commission info' do
64
+ order_should_be /PreSubmitted/
65
+ order = @ib.received[:OpenOrder].first.order
66
+ order.what_if.should == true
67
+ order.equity_with_loan.should be_a Float
68
+ order.init_margin.should be_a Float
69
+ order.maint_margin.should be_a Float
70
+ order.commission.should be_a Float
71
+ order.equity_with_loan.should be > 0
72
+ order.init_margin.should be > 0
73
+ order.maint_margin.should be > 0
74
+ order.commission.should be > 1
75
+ end
102
76
 
103
- it 'does not increase client`s next_order_id further' do
104
- @ib.next_order_id.should == @order_id_after
105
- end
77
+ it 'is not actually opened though' do
78
+ @ib.clear_received
79
+ @ib.send_message :RequestOpenOrders
80
+ @ib.wait_for :OpenOrderEnd
81
+ @ib.received[:OpenOrder].should have_exactly(0).order_message
82
+ end
83
+ end
106
84
 
107
- it 'does not receive OpenOrder message' do
108
- @ib.received?(:OpenOrder).should be_false
109
- end
85
+ context 'Off-market stock order' do
86
+ before(:all) do
87
+ @ib = IB::Connection.new OPTS[:connection].merge(:logger => mock_logger)
88
+ @ib.wait_for :NextValidId
110
89
 
111
- it { @ib.received[:OrderStatus].should have_exactly(1).status_message }
112
- it { @ib.received[:Alert].should have_exactly(1).alert_message }
90
+ place_order IB::Symbols::Stocks[:wfc],
91
+ :limit_price => 9.13 # Set acceptable price
92
+ @ib.wait_for [:OpenOrder, 3], [:OrderStatus, 2]
93
+ end
113
94
 
114
- it 'receives cancellation Order Status' do
115
- order_status_should_be /Cancel/ # Cancelled / PendingCancel
116
- end
95
+ after(:all) { close_connection }
117
96
 
118
- it 'receives Order cancelled Alert' do
119
- alert = @ib.received[:Alert].first
120
- alert.should be_an IB::Messages::Incoming::Alert
121
- alert.message.should =~ /Order Canceled - reason:/
122
- end
123
- end # Cancelling
97
+ it_behaves_like 'Placed Order'
124
98
 
125
99
  context "Cancelling wrong order" do
126
100
  before(:all) do