bitex_bot 0.3.7 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +63 -0
  3. data/.rubocop.yml +33 -0
  4. data/Gemfile +1 -1
  5. data/Rakefile +1 -1
  6. data/bin/bitex_bot +1 -1
  7. data/bitex_bot.gemspec +34 -34
  8. data/lib/bitex_bot/database.rb +67 -67
  9. data/lib/bitex_bot/models/api_wrappers/api_wrapper.rb +142 -0
  10. data/lib/bitex_bot/models/api_wrappers/bitstamp/bitstamp_api_wrapper.rb +137 -0
  11. data/lib/bitex_bot/models/api_wrappers/itbit/itbit_api_wrapper.rb +116 -0
  12. data/lib/bitex_bot/models/api_wrappers/kraken/kraken_api_wrapper.rb +111 -0
  13. data/lib/bitex_bot/models/api_wrappers/kraken/kraken_order.rb +117 -0
  14. data/lib/bitex_bot/models/buy_closing_flow.rb +23 -16
  15. data/lib/bitex_bot/models/buy_opening_flow.rb +48 -54
  16. data/lib/bitex_bot/models/close_buy.rb +2 -2
  17. data/lib/bitex_bot/models/closing_flow.rb +98 -79
  18. data/lib/bitex_bot/models/open_buy.rb +11 -10
  19. data/lib/bitex_bot/models/open_sell.rb +11 -10
  20. data/lib/bitex_bot/models/opening_flow.rb +157 -99
  21. data/lib/bitex_bot/models/order_book_simulator.rb +62 -67
  22. data/lib/bitex_bot/models/sell_closing_flow.rb +25 -20
  23. data/lib/bitex_bot/models/sell_opening_flow.rb +47 -54
  24. data/lib/bitex_bot/models/store.rb +3 -1
  25. data/lib/bitex_bot/robot.rb +203 -176
  26. data/lib/bitex_bot/settings.rb +71 -12
  27. data/lib/bitex_bot/version.rb +1 -1
  28. data/lib/bitex_bot.rb +40 -16
  29. data/settings.rb.sample +43 -66
  30. data/spec/bitex_bot/settings_spec.rb +87 -15
  31. data/spec/factories/bitex_buy.rb +3 -3
  32. data/spec/factories/bitex_sell.rb +3 -3
  33. data/spec/factories/buy_opening_flow.rb +1 -1
  34. data/spec/factories/open_buy.rb +12 -10
  35. data/spec/factories/open_sell.rb +12 -10
  36. data/spec/factories/sell_opening_flow.rb +1 -1
  37. data/spec/models/api_wrappers/bitstamp_api_wrapper_spec.rb +200 -0
  38. data/spec/models/api_wrappers/itbit_api_wrapper_spec.rb +176 -0
  39. data/spec/models/api_wrappers/kraken_api_wrapper_spec.rb +209 -0
  40. data/spec/models/bitex_api_spec.rb +1 -1
  41. data/spec/models/buy_closing_flow_spec.rb +140 -71
  42. data/spec/models/buy_opening_flow_spec.rb +126 -56
  43. data/spec/models/order_book_simulator_spec.rb +10 -10
  44. data/spec/models/robot_spec.rb +61 -47
  45. data/spec/models/sell_closing_flow_spec.rb +130 -62
  46. data/spec/models/sell_opening_flow_spec.rb +129 -60
  47. data/spec/spec_helper.rb +19 -16
  48. data/spec/support/bitex_stubs.rb +13 -14
  49. data/spec/support/bitstamp/bitstamp_api_wrapper_stubs.rb +35 -0
  50. data/spec/support/bitstamp/bitstamp_stubs.rb +91 -0
  51. metadata +60 -42
  52. data/lib/bitex_bot/models/bitfinex_api_wrapper.rb +0 -118
  53. data/lib/bitex_bot/models/bitstamp_api_wrapper.rb +0 -82
  54. data/lib/bitex_bot/models/itbit_api_wrapper.rb +0 -68
  55. data/lib/bitex_bot/models/kraken_api_wrapper.rb +0 -188
  56. data/spec/models/bitfinex_api_wrapper_spec.rb +0 -17
  57. data/spec/models/bitstamp_api_wrapper_spec.rb +0 -15
  58. data/spec/models/itbit_api_wrapper_spec.rb +0 -15
  59. data/spec/support/bitstamp_stubs.rb +0 -110
@@ -1,15 +1,21 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe BitexBot::Robot do
4
+ let(:taker_settings) do
5
+ BitexBot::SettingsClass.new(
6
+ bitstamp: {
7
+ api_key: 'YOUR_API_KEY', secret: 'YOUR_API_SECRET', client_id: 'YOUR_BITSTAMP_USERNAME'
8
+ }
9
+ )
10
+ end
11
+
4
12
  before(:each) do
13
+ BitexBot::Settings.stub(taker: taker_settings)
14
+ BitexBot::Robot.setup
5
15
  BitexBot::Settings.stub(
6
16
  time_to_live: 10,
7
- buying: double(
8
- amount_to_spend_per_order: 50,
9
- profit: 0),
10
- selling: double(
11
- quantity_to_sell_per_order: 1,
12
- profit: 0),
17
+ buying: double(amount_to_spend_per_order: 50, profit: 0),
18
+ selling: double(quantity_to_sell_per_order: 1, profit: 0),
13
19
  mailer: double(
14
20
  from: 'test@test.com',
15
21
  to: 'test@test.com',
@@ -17,7 +23,6 @@ describe BitexBot::Robot do
17
23
  options: {}
18
24
  )
19
25
  )
20
- Bitex.api_key = "valid_key"
21
26
  Bitex::Profile.stub(get: {
22
27
  fee: 0.5,
23
28
  usd_balance: 10000.00, # Total USD balance
@@ -28,20 +33,22 @@ describe BitexBot::Robot do
28
33
  btc_available: 15.00000000, # BTC available for trading
29
34
  ltc_balance: 250.00000000, # Total LTC balance
30
35
  ltc_reserved: 100.00000000, # LTC reserved in open orders
31
- ltc_available: 150.00000000,
36
+ ltc_available: 150.00000000 # LTC available for trading
32
37
  })
33
38
  stub_bitex_orders
34
39
  stub_bitstamp_sell
35
40
  stub_bitstamp_buy
36
- stub_bitstamp_balance
37
- stub_bitstamp_order_book
41
+ stub_bitstamp_api_wrapper_balance
42
+ stub_bitstamp_api_wrapper_order_book
38
43
  stub_bitstamp_transactions
39
- stub_bitstamp_user_transactions
44
+ stub_bitstamp_empty_user_transactions
40
45
  end
41
- let(:bot){ BitexBot::Robot.new }
46
+
47
+ let(:bot) { BitexBot::Robot.new }
42
48
 
43
49
  it 'Starts out by creating opening flows that timeout' do
44
50
  stub_bitex_orders
51
+ stub_bitstamp_api_wrapper_order_book
45
52
  bot.trade!
46
53
  stub_bitex_transactions
47
54
  buying = BitexBot::BuyOpeningFlow.last
@@ -49,7 +56,7 @@ describe BitexBot::Robot do
49
56
 
50
57
  Timecop.travel 10.minutes.from_now
51
58
  bot.trade!
52
-
59
+
53
60
  buying.reload.should be_settling
54
61
  selling.reload.should be_settling
55
62
 
@@ -57,7 +64,7 @@ describe BitexBot::Robot do
57
64
  buying.reload.should be_finalised
58
65
  selling.reload.should be_finalised
59
66
  end
60
-
67
+
61
68
  it 'creates alternating opening flows' do
62
69
  Bitex::Trade.stub(all: [])
63
70
  bot.trade!
@@ -68,7 +75,7 @@ describe BitexBot::Robot do
68
75
  Timecop.travel 5.seconds.from_now
69
76
  bot.trade!
70
77
  BitexBot::BuyOpeningFlow.active.count.should == 2
71
-
78
+
72
79
  # When transactions appear, all opening flows
73
80
  # should get old and die.
74
81
  # We stub our finder to make it so all orders
@@ -89,7 +96,7 @@ describe BitexBot::Robot do
89
96
  stub_bitex_transactions
90
97
  expect do
91
98
  bot.trade!
92
- end.to change{ BitexBot::BuyClosingFlow.count }.by(1)
99
+ end.to change { BitexBot::BuyClosingFlow.count }.by(1)
93
100
 
94
101
  Timecop.travel 15.seconds.from_now
95
102
  bot.trade!
@@ -101,25 +108,25 @@ describe BitexBot::Robot do
101
108
  expect do
102
109
  bot.trade!
103
110
  bot.should_not be_active_closing_flows
104
- end.to change{ BitexBot::BuyOpeningFlow.count }.by(1)
111
+ end.to change { BitexBot::BuyOpeningFlow.count }.by(1)
105
112
  end
106
-
113
+
107
114
  it 'does not place new opening flows when ordered to hold' do
108
115
  other_bot = BitexBot::Robot.new
109
116
  other_bot.store.hold = true
110
117
  other_bot.store.save!
111
118
  expect do
112
119
  bot.trade!
113
- end.not_to change{ BitexBot::BuyOpeningFlow.count }
120
+ end.not_to change { BitexBot::BuyOpeningFlow.count }
114
121
  end
115
122
 
116
- it 'stops trading when btc stop is reached' do
123
+ it 'stops trading when fiat stop is reached' do
117
124
  other_bot = BitexBot::Robot.new
118
- other_bot.store.usd_stop = 11000
125
+ other_bot.store.btc_stop = 30
119
126
  other_bot.store.save!
120
127
  expect do
121
128
  bot.trade!
122
- end.not_to change{ BitexBot::BuyOpeningFlow.count }
129
+ end.not_to change { BitexBot::BuyOpeningFlow.count }
123
130
  end
124
131
 
125
132
  it 'stops trading when usd stop is reached' do
@@ -128,27 +135,36 @@ describe BitexBot::Robot do
128
135
  other_bot.store.save!
129
136
  expect do
130
137
  bot.trade!
131
- end.not_to change{ BitexBot::BuyOpeningFlow.count }
138
+ end.not_to change { BitexBot::BuyOpeningFlow.count }
139
+ end
140
+
141
+ it 'stops trading when btc stop is reached' do
142
+ other_bot = BitexBot::Robot.new
143
+ other_bot.store.fiat_stop = 11000
144
+ other_bot.store.save!
145
+ expect do
146
+ bot.trade!
147
+ end.not_to change { BitexBot::BuyOpeningFlow.count }
132
148
  end
133
149
 
134
150
  it 'warns every 30 minutes when usd warn is reached' do
135
151
  Bitex::Trade.stub(all: [])
136
152
  other_bot = BitexBot::Robot.new
137
- other_bot.store.usd_warning = 11000
153
+ other_bot.store.fiat_warning = 11000
138
154
  other_bot.store.save!
139
155
  expect do
140
156
  bot.trade!
141
- end.to change{ Mail::TestMailer.deliveries.count }.by(1)
157
+ end.to change { Mail::TestMailer.deliveries.count }.by(1)
142
158
  Timecop.travel 1.minute.from_now
143
- stub_bitstamp_order_book # Re-stub so orderbook does not get old
159
+ stub_bitstamp_order_book # Re-stub so order book does not get old
144
160
  expect do
145
161
  bot.trade!
146
- end.not_to change{ Mail::TestMailer.deliveries.count }
162
+ end.not_to change { Mail::TestMailer.deliveries.count }
147
163
  Timecop.travel 31.minutes.from_now
148
- stub_bitstamp_order_book # Re-stub so orderbook does not get old
164
+ stub_bitstamp_order_book # Re-stub so order book does not get old
149
165
  expect do
150
166
  bot.trade!
151
- end.to change{ Mail::TestMailer.deliveries.count }.by(1)
167
+ end.to change { Mail::TestMailer.deliveries.count }.by(1)
152
168
  end
153
169
 
154
170
  it 'warns every 30 minutes when btc warn is reached' do
@@ -156,38 +172,36 @@ describe BitexBot::Robot do
156
172
  other_bot = BitexBot::Robot.new
157
173
  other_bot.store.btc_warning = 30
158
174
  other_bot.store.save!
175
+
159
176
  expect do
160
177
  bot.trade!
161
- end.to change{ Mail::TestMailer.deliveries.count }.by(1)
178
+ end.to change { Mail::TestMailer.deliveries.count }.by(1)
179
+
162
180
  Timecop.travel 1.minute.from_now
163
- stub_bitstamp_order_book # Re-stub so orderbook does not get old
181
+ stub_bitstamp_order_book # Re-stub so order book does not get old
164
182
  expect do
165
183
  bot.trade!
166
- end.not_to change{ Mail::TestMailer.deliveries.count }
184
+ end.not_to change { Mail::TestMailer.deliveries.count }
185
+
167
186
  Timecop.travel 31.minutes.from_now
168
- stub_bitstamp_order_book # Re-stub so orderbook does not get old
187
+ stub_bitstamp_order_book # Re-stub so order book does not get old
188
+
169
189
  expect do
170
190
  bot.trade!
171
- end.to change{ Mail::TestMailer.deliveries.count }.by(1)
191
+ end.to change { Mail::TestMailer.deliveries.count }.by(1)
172
192
  end
173
-
174
- it 'updates taker_usd and taker_btc' do
193
+
194
+ it 'updates taker_fiat and taker_btc' do
175
195
  bot.trade!
176
- bot.store.taker_usd.should_not be_nil
196
+ bot.store.taker_fiat.should_not be_nil
177
197
  bot.store.taker_btc.should_not be_nil
178
198
  end
179
-
199
+
180
200
  it 'notifies exceptions and sleeps' do
181
- Bitstamp.stub(:balance) do
182
- raise StandardError.new('oh moova')
183
- end
201
+ BitstampApiWrapper.stub(:balance) { raise StandardError.new('oh moova') }
202
+
184
203
  expect do
185
204
  bot.trade!
186
- end.to change{ Mail::TestMailer.deliveries.count }.by(1)
187
- end
188
-
189
- it 'knows how to setup sandbox mode for both gems' do
190
- pending
191
- fail
205
+ end.to change { Mail::TestMailer.deliveries.count }.by(1)
192
206
  end
193
207
  end
@@ -1,101 +1,166 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe BitexBot::SellClosingFlow do
4
- it "closes a single open position completely" do
4
+ let(:taker_settings) do
5
+ BitexBot::SettingsClass.new(
6
+ bitstamp: {
7
+ api_key: 'YOUR_API_KEY', secret: 'YOUR_API_SECRET', client_id: 'YOUR_BITSTAMP_USERNAME'
8
+ }
9
+ )
10
+ end
11
+
12
+ before(:each) do
13
+ BitexBot::Settings.stub(taker: taker_settings)
14
+ BitexBot::Robot.setup
15
+ end
16
+
17
+ it 'closes a single open position completely' do
5
18
  stub_bitstamp_buy
6
19
  open = create :open_sell
7
- flow = BitexBot::SellClosingFlow.close_open_positions
20
+ BitexBot::SellClosingFlow.close_open_positions
21
+ flow = BitexBot::SellClosingFlow.last
22
+
8
23
  open.reload.closing_flow.should == flow
24
+
9
25
  flow.open_positions.should == [open]
10
26
  flow.desired_price.should == 290
11
27
  flow.quantity.should == 2
12
28
  flow.amount.should == 600
13
29
  flow.btc_profit.should be_nil
14
- flow.usd_profit.should be_nil
30
+ flow.fiat_profit.should be_nil
31
+
15
32
  close = flow.close_positions.first
16
33
  close.order_id.should == '1'
17
34
  close.amount.should be_nil
18
35
  close.quantity.should be_nil
19
36
  end
20
-
21
- it "closes an aggregate of several open positions" do
37
+
38
+ it 'closes an aggregate of several open positions' do
22
39
  stub_bitstamp_buy
23
40
  open_one = create :tiny_open_sell
24
41
  open_two = create :open_sell
25
- flow = BitexBot::SellClosingFlow.close_open_positions
42
+ BitexBot::SellClosingFlow.close_open_positions
43
+ flow = BitexBot::SellClosingFlow.last
44
+
26
45
  close = flow.close_positions.first
46
+
27
47
  open_one.reload.closing_flow.should == flow
28
48
  open_two.reload.closing_flow.should == flow
49
+
29
50
  flow.open_positions.should == [open_one, open_two]
30
- flow.desired_price.round(15).should == '290.497512437810945'.to_d
51
+ flow.desired_price.round(10).should == '290.4975124378'.to_d
31
52
  flow.quantity.should == 2.01
32
53
  flow.amount.should == 604
33
54
  flow.btc_profit.should be_nil
34
- flow.usd_profit.should be_nil
55
+ flow.fiat_profit.should be_nil
56
+
35
57
  close.order_id.should == '1'
36
58
  close.amount.should be_nil
37
59
  close.quantity.should be_nil
38
60
  end
39
61
 
40
- it 'keeps trying to place a closed position on bitstamp errors' do
41
- stub_bitstamp_buy
42
- Bitstamp.orders.stub(:buy) do
43
- double(id: nil, error: {price: ['Ensure it is good']})
62
+ describe 'when there are errors placing the closing order' do
63
+ it 'keeps trying to place a closed position on bitstamp errors' do
64
+ BitstampApiWrapper.stub(send_order: nil)
65
+ BitstampApiWrapper.stub(find_lost: nil)
66
+
67
+ open = create :open_sell
68
+ expect do
69
+ flow = BitexBot::SellClosingFlow.close_open_positions
70
+ end.to raise_exception(OrderNotFound)
71
+ flow = BitexBot::SellClosingFlow.last
72
+
73
+ open.reload.closing_flow.should == flow
74
+
75
+ flow.open_positions.should == [open]
76
+ flow.desired_price.should == 290
77
+ flow.quantity.should == 2
78
+ flow.btc_profit.should be_nil
79
+ flow.fiat_profit.should be_nil
80
+ flow.close_positions.should be_empty
44
81
  end
45
- open = create :open_sell
46
- flow = BitexBot::SellClosingFlow.close_open_positions
47
- open.reload.closing_flow.should == flow
48
- flow.open_positions.should == [open]
49
- flow.desired_price.should == 290
50
- flow.quantity.should == 2
51
- flow.btc_profit.should be_nil
52
- flow.usd_profit.should be_nil
53
- flow.close_positions.should be_empty
54
82
 
55
- stub_bitstamp_user_transactions
56
- stub_bitstamp_buy
57
- flow.sync_closed_positions(Bitstamp.orders.all, Bitstamp.user_transactions.all)
58
- close = flow.close_positions.first
59
- close.order_id.should == '1'
60
- close.amount.should be_nil
61
- close.quantity.should be_nil
83
+ it 'retries until it finds the lost order' do
84
+ BitstampApiWrapper.stub(send_order: nil)
85
+ BitstampApiWrapper.stub(:orders) do
86
+ [BitstampApiWrapper::Order.new(1, :buy, 290, 2, 1.minute.ago.to_i)]
87
+ end
88
+
89
+ open = create(:open_sell)
90
+ BitexBot::SellClosingFlow.close_open_positions
91
+ flow = BitexBot::SellClosingFlow.last
92
+
93
+ flow.close_positions.should_not be_empty
94
+ flow.close_positions.first do |position|
95
+ position.id.should eq 1234
96
+ position.type.should eq 1
97
+ position.amount.should eq 1000
98
+ position.price.should eq 2000
99
+ end
100
+ end
62
101
  end
63
-
64
- it "does not try to close if the amount is too low" do
102
+
103
+ it 'does not try to close if the amount is too low' do
65
104
  open = create :tiny_open_sell
66
105
  expect do
67
106
  BitexBot::SellClosingFlow.close_open_positions.should be_nil
68
107
  end.not_to change{ BitexBot::SellClosingFlow.count }
69
108
  end
70
-
71
- it "does not try to close if there are no open positions" do
109
+
110
+ it 'does not try to close if there are no open positions' do
72
111
  expect do
73
112
  BitexBot::SellClosingFlow.close_open_positions.should be_nil
74
113
  end.not_to change{ BitexBot::SellClosingFlow.count }
75
114
  end
76
-
77
- describe "when syncinc executed orders" do
115
+
116
+ describe 'when syncinc executed orders' do
78
117
  before(:each) do
79
118
  stub_bitstamp_buy
80
- stub_bitstamp_user_transactions
119
+ stub_bitstamp_empty_user_transactions
81
120
  create :tiny_open_sell
82
121
  create :open_sell
83
122
  end
84
-
85
- it "syncs the executed orders, calculates profit" do
86
- flow = BitexBot::SellClosingFlow.close_open_positions
123
+
124
+ it 'syncs the executed orders, calculates profit' do
125
+ BitexBot::SellClosingFlow.close_open_positions
126
+ flow = BitexBot::SellClosingFlow.last
87
127
  stub_bitstamp_orders_into_transactions
128
+
88
129
  flow.sync_closed_positions(Bitstamp.orders.all, Bitstamp.user_transactions.all)
130
+
89
131
  close = flow.close_positions.last
90
- close.amount.should == "583.905".to_d
132
+ close.amount.should == '583.905'.to_d
91
133
  close.quantity.should == 2.01
134
+
92
135
  flow.should be_done
93
136
  flow.btc_profit.should == 0
94
- flow.usd_profit.should == "20.095".to_d
137
+ flow.fiat_profit.should == '20.095'.to_d
95
138
  end
96
-
97
- it "retries closing at a higher price every minute" do
98
- flow = BitexBot::SellClosingFlow.close_open_positions
139
+
140
+ context 'with other fx rate and closed open positions' do
141
+ let(:fx_rate) { 10.to_d }
142
+ let(:flow) { subject.class.last }
143
+ let(:positions_balance_amount) { flow.open_positions.sum(:amount) - flow.positions_balance_amount }
144
+
145
+ before(:each) do
146
+ BitexBot::Settings.stub(fx_rate: fx_rate)
147
+ subject.class.close_open_positions
148
+
149
+ stub_bitstamp_orders_into_transactions
150
+ flow.sync_closed_positions(Bitstamp.orders.all, Bitstamp.user_transactions.all)
151
+ end
152
+
153
+ it 'syncs the executed orders, calculates profit with other fx rate' do
154
+ flow.should be_done
155
+ flow.btc_profit.should be_zero
156
+ flow.fiat_profit.should eq positions_balance_amount
157
+ end
158
+ end
159
+
160
+ it 'retries closing at a higher price every minute' do
161
+ BitexBot::SellClosingFlow.close_open_positions
162
+ flow = BitexBot::SellClosingFlow.last
163
+
99
164
  expect do
100
165
  flow.sync_closed_positions(Bitstamp.orders.all, Bitstamp.user_transactions.all)
101
166
  end.not_to change{ BitexBot::CloseSell.count }
@@ -115,36 +180,38 @@ describe BitexBot::SellClosingFlow do
115
180
  end.not_to change{ BitexBot::CloseSell.count }
116
181
  Bitstamp.orders.all.size.should == 0
117
182
  flow.should_not be_done
118
-
183
+
119
184
  # Next time we try to sync_closed_positions the flow
120
185
  # detects the previous close_buy was cancelled correctly so
121
186
  # it syncs it's total amounts and tries to place a new one.
122
187
  expect do
123
188
  flow.sync_closed_positions(Bitstamp.orders.all, Bitstamp.user_transactions.all)
124
189
  end.to change{ BitexBot::CloseSell.count }.by(1)
190
+
125
191
  flow.close_positions.first.tap do |close|
126
- close.amount.should == "291.9525".to_d
192
+ close.amount.should == '291.9525'.to_d
127
193
  close.quantity.should == 1.005
128
194
  end
129
195
 
130
196
  # The second ask is executed completely so we can wrap it up and consider
131
197
  # this closing flow done.
132
198
  stub_bitstamp_orders_into_transactions
199
+
133
200
  flow.sync_closed_positions(Bitstamp.orders.all, Bitstamp.user_transactions.all)
134
201
  flow.close_positions.last.tap do |close|
135
- close.amount.should == "291.953597".to_d
202
+ close.amount.should == '291.953597'.to_d
136
203
  close.quantity.should == '1.0049'.to_d
137
204
  end
138
205
  flow.should be_done
139
206
  flow.btc_profit.should == '-0.0001'.to_d
140
- flow.usd_profit.should == '20.093903'.to_d
141
-
207
+ flow.fiat_profit.should == '20.093903'.to_d
142
208
  end
143
-
144
- it "does not retry for an amount less than minimum_for_closing" do
145
- flow = BitexBot::SellClosingFlow.close_open_positions
146
209
 
147
- 20.times do
210
+ it 'does not retry for an amount less than minimum_for_closing' do
211
+ BitexBot::SellClosingFlow.close_open_positions
212
+ flow = BitexBot::SellClosingFlow.last
213
+
214
+ 20.times do
148
215
  Timecop.travel 60.seconds.from_now
149
216
  flow.sync_closed_positions(Bitstamp.orders.all, Bitstamp.user_transactions.all)
150
217
  end
@@ -158,14 +225,16 @@ describe BitexBot::SellClosingFlow do
158
225
 
159
226
  flow.should be_done
160
227
  flow.btc_profit.should == '-0.0224895'.to_d
161
- flow.usd_profit.should == '20.66566825'.to_d
228
+ flow.fiat_profit.should == '20.66566825'.to_d
162
229
  end
163
-
164
- it "can lose BTC if price had to be raised dramatically" do
230
+
231
+ it 'can lose BTC if price had to be raised dramatically' do
165
232
  # This flow is forced to spend the original USD amount paying more than
166
233
  # expected, thus regaining less BTC than what was sold on bitex.
167
- flow = BitexBot::SellClosingFlow.close_open_positions
168
- 60.times do
234
+ BitexBot::SellClosingFlow.close_open_positions
235
+ flow = BitexBot::SellClosingFlow.last
236
+
237
+ 60.times do
169
238
  Timecop.travel 60.seconds.from_now
170
239
  flow.sync_closed_positions(Bitstamp.orders.all, Bitstamp.user_transactions.all)
171
240
  end
@@ -173,13 +242,12 @@ describe BitexBot::SellClosingFlow do
173
242
  stub_bitstamp_orders_into_transactions
174
243
 
175
244
  flow.sync_closed_positions(Bitstamp.orders.all, Bitstamp.user_transactions.all)
176
-
177
245
  flow.reload.should be_done
178
- flow.btc_profit.should == "-0.1709".to_d
179
- flow.usd_profit.should == "20.08575".to_d
246
+ flow.btc_profit.should == '-0.1709'.to_d
247
+ flow.fiat_profit.should == '20.08575'.to_d
248
+
180
249
  close = flow.close_positions.last
181
- (close.amount / close.quantity)
182
- .should == '317.5'.to_d
250
+ (close.amount / close.quantity).should == '317.5'.to_d
183
251
  end
184
252
  end
185
253
  end