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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitex_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nubis
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-11-09 00:00:00.000000000 Z
12
+ date: 2018-06-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -26,7 +26,21 @@ dependencies:
26
26
  - !ruby/object:Gem::Version
27
27
  version: '4.2'
28
28
  - !ruby/object:Gem::Dependency
29
- name: sqlite3
29
+ name: hashie
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: 3.5.4
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: 3.5.4
42
+ - !ruby/object:Gem::Dependency
43
+ name: mail
30
44
  requirement: !ruby/object:Gem::Requirement
31
45
  requirements:
32
46
  - - ">="
@@ -40,7 +54,7 @@ dependencies:
40
54
  - !ruby/object:Gem::Version
41
55
  version: '0'
42
56
  - !ruby/object:Gem::Dependency
43
- name: bitstamp
57
+ name: sqlite3
44
58
  requirement: !ruby/object:Gem::Requirement
45
59
  requirements:
46
60
  - - ">="
@@ -59,30 +73,30 @@ dependencies:
59
73
  requirements:
60
74
  - - '='
61
75
  - !ruby/object:Gem::Version
62
- version: '0.3'
76
+ version: '0.5'
63
77
  type: :runtime
64
78
  prerelease: false
65
79
  version_requirements: !ruby/object:Gem::Requirement
66
80
  requirements:
67
81
  - - '='
68
82
  - !ruby/object:Gem::Version
69
- version: '0.3'
83
+ version: '0.5'
70
84
  - !ruby/object:Gem::Dependency
71
- name: itbit
85
+ name: bitstamp
72
86
  requirement: !ruby/object:Gem::Requirement
73
87
  requirements:
74
- - - '='
88
+ - - ">="
75
89
  - !ruby/object:Gem::Version
76
- version: 0.0.6
90
+ version: '0'
77
91
  type: :runtime
78
92
  prerelease: false
79
93
  version_requirements: !ruby/object:Gem::Requirement
80
94
  requirements:
81
- - - '='
95
+ - - ">="
82
96
  - !ruby/object:Gem::Version
83
- version: 0.0.6
97
+ version: '0'
84
98
  - !ruby/object:Gem::Dependency
85
- name: bitfinex-rb
99
+ name: itbit
86
100
  requirement: !ruby/object:Gem::Requirement
87
101
  requirements:
88
102
  - - '='
@@ -110,13 +124,13 @@ dependencies:
110
124
  - !ruby/object:Gem::Version
111
125
  version: 1.2.1
112
126
  - !ruby/object:Gem::Dependency
113
- name: mail
127
+ name: bundler
114
128
  requirement: !ruby/object:Gem::Requirement
115
129
  requirements:
116
130
  - - ">="
117
131
  - !ruby/object:Gem::Version
118
132
  version: '0'
119
- type: :runtime
133
+ type: :development
120
134
  prerelease: false
121
135
  version_requirements: !ruby/object:Gem::Requirement
122
136
  requirements:
@@ -124,21 +138,21 @@ dependencies:
124
138
  - !ruby/object:Gem::Version
125
139
  version: '0'
126
140
  - !ruby/object:Gem::Dependency
127
- name: hashie
141
+ name: rake
128
142
  requirement: !ruby/object:Gem::Requirement
129
143
  requirements:
130
- - - "~>"
144
+ - - ">="
131
145
  - !ruby/object:Gem::Version
132
- version: 3.5.4
133
- type: :runtime
146
+ version: '0'
147
+ type: :development
134
148
  prerelease: false
135
149
  version_requirements: !ruby/object:Gem::Requirement
136
150
  requirements:
137
- - - "~>"
151
+ - - ">="
138
152
  - !ruby/object:Gem::Version
139
- version: 3.5.4
153
+ version: '0'
140
154
  - !ruby/object:Gem::Dependency
141
- name: bundler
155
+ name: byebug
142
156
  requirement: !ruby/object:Gem::Requirement
143
157
  requirements:
144
158
  - - ">="
@@ -152,7 +166,7 @@ dependencies:
152
166
  - !ruby/object:Gem::Version
153
167
  version: '0'
154
168
  - !ruby/object:Gem::Dependency
155
- name: byebug
169
+ name: database_cleaner
156
170
  requirement: !ruby/object:Gem::Requirement
157
171
  requirements:
158
172
  - - ">="
@@ -166,7 +180,7 @@ dependencies:
166
180
  - !ruby/object:Gem::Version
167
181
  version: '0'
168
182
  - !ruby/object:Gem::Dependency
169
- name: rake
183
+ name: factory_bot
170
184
  requirement: !ruby/object:Gem::Requirement
171
185
  requirements:
172
186
  - - ">="
@@ -208,7 +222,7 @@ dependencies:
208
222
  - !ruby/object:Gem::Version
209
223
  version: '0'
210
224
  - !ruby/object:Gem::Dependency
211
- name: database_cleaner
225
+ name: rspec_junit_formatter
212
226
  requirement: !ruby/object:Gem::Requirement
213
227
  requirements:
214
228
  - - ">="
@@ -222,7 +236,7 @@ dependencies:
222
236
  - !ruby/object:Gem::Version
223
237
  version: '0'
224
238
  - !ruby/object:Gem::Dependency
225
- name: factory_girl
239
+ name: rubocop
226
240
  requirement: !ruby/object:Gem::Requirement
227
241
  requirements:
228
242
  - - ">="
@@ -236,7 +250,7 @@ dependencies:
236
250
  - !ruby/object:Gem::Version
237
251
  version: '0'
238
252
  - !ruby/object:Gem::Dependency
239
- name: timecop
253
+ name: shoulda-matchers
240
254
  requirement: !ruby/object:Gem::Requirement
241
255
  requirements:
242
256
  - - ">="
@@ -250,7 +264,7 @@ dependencies:
250
264
  - !ruby/object:Gem::Version
251
265
  version: '0'
252
266
  - !ruby/object:Gem::Dependency
253
- name: shoulda-matchers
267
+ name: timecop
254
268
  requirement: !ruby/object:Gem::Requirement
255
269
  requirements:
256
270
  - - ">="
@@ -278,9 +292,8 @@ dependencies:
278
292
  - !ruby/object:Gem::Version
279
293
  version: '0'
280
294
  description: |-
281
- Both a trading robot and a library to build trading
282
- robots. The bitex-bot lets you buy cheap on bitex and
283
- sell on another exchange and vice versa.
295
+ Both a trading robot and a library to build trading robots. The bitex-bot lets you buy cheap on bitex
296
+ and sell on another exchange and vice versa.
284
297
  email:
285
298
  - nb@bitex.la
286
299
  - tr@bitex.la
@@ -289,8 +302,10 @@ executables:
289
302
  extensions: []
290
303
  extra_rdoc_files: []
291
304
  files:
305
+ - ".circleci/config.yml"
292
306
  - ".gitignore"
293
307
  - ".rspec"
308
+ - ".rubocop.yml"
294
309
  - Gemfile
295
310
  - LICENSE.txt
296
311
  - README.md
@@ -299,15 +314,16 @@ files:
299
314
  - bitex_bot.gemspec
300
315
  - lib/bitex_bot.rb
301
316
  - lib/bitex_bot/database.rb
302
- - lib/bitex_bot/models/bitfinex_api_wrapper.rb
303
- - lib/bitex_bot/models/bitstamp_api_wrapper.rb
317
+ - lib/bitex_bot/models/api_wrappers/api_wrapper.rb
318
+ - lib/bitex_bot/models/api_wrappers/bitstamp/bitstamp_api_wrapper.rb
319
+ - lib/bitex_bot/models/api_wrappers/itbit/itbit_api_wrapper.rb
320
+ - lib/bitex_bot/models/api_wrappers/kraken/kraken_api_wrapper.rb
321
+ - lib/bitex_bot/models/api_wrappers/kraken/kraken_order.rb
304
322
  - lib/bitex_bot/models/buy_closing_flow.rb
305
323
  - lib/bitex_bot/models/buy_opening_flow.rb
306
324
  - lib/bitex_bot/models/close_buy.rb
307
325
  - lib/bitex_bot/models/close_sell.rb
308
326
  - lib/bitex_bot/models/closing_flow.rb
309
- - lib/bitex_bot/models/itbit_api_wrapper.rb
310
- - lib/bitex_bot/models/kraken_api_wrapper.rb
311
327
  - lib/bitex_bot/models/open_buy.rb
312
328
  - lib/bitex_bot/models/open_sell.rb
313
329
  - lib/bitex_bot/models/opening_flow.rb
@@ -326,19 +342,20 @@ files:
326
342
  - spec/factories/open_buy.rb
327
343
  - spec/factories/open_sell.rb
328
344
  - spec/factories/sell_opening_flow.rb
345
+ - spec/models/api_wrappers/bitstamp_api_wrapper_spec.rb
346
+ - spec/models/api_wrappers/itbit_api_wrapper_spec.rb
347
+ - spec/models/api_wrappers/kraken_api_wrapper_spec.rb
329
348
  - spec/models/bitex_api_spec.rb
330
- - spec/models/bitfinex_api_wrapper_spec.rb
331
- - spec/models/bitstamp_api_wrapper_spec.rb
332
349
  - spec/models/buy_closing_flow_spec.rb
333
350
  - spec/models/buy_opening_flow_spec.rb
334
- - spec/models/itbit_api_wrapper_spec.rb
335
351
  - spec/models/order_book_simulator_spec.rb
336
352
  - spec/models/robot_spec.rb
337
353
  - spec/models/sell_closing_flow_spec.rb
338
354
  - spec/models/sell_opening_flow_spec.rb
339
355
  - spec/spec_helper.rb
340
356
  - spec/support/bitex_stubs.rb
341
- - spec/support/bitstamp_stubs.rb
357
+ - spec/support/bitstamp/bitstamp_api_wrapper_stubs.rb
358
+ - spec/support/bitstamp/bitstamp_stubs.rb
342
359
  homepage: ''
343
360
  licenses:
344
361
  - MIT
@@ -371,16 +388,17 @@ test_files:
371
388
  - spec/factories/open_buy.rb
372
389
  - spec/factories/open_sell.rb
373
390
  - spec/factories/sell_opening_flow.rb
391
+ - spec/models/api_wrappers/bitstamp_api_wrapper_spec.rb
392
+ - spec/models/api_wrappers/itbit_api_wrapper_spec.rb
393
+ - spec/models/api_wrappers/kraken_api_wrapper_spec.rb
374
394
  - spec/models/bitex_api_spec.rb
375
- - spec/models/bitfinex_api_wrapper_spec.rb
376
- - spec/models/bitstamp_api_wrapper_spec.rb
377
395
  - spec/models/buy_closing_flow_spec.rb
378
396
  - spec/models/buy_opening_flow_spec.rb
379
- - spec/models/itbit_api_wrapper_spec.rb
380
397
  - spec/models/order_book_simulator_spec.rb
381
398
  - spec/models/robot_spec.rb
382
399
  - spec/models/sell_closing_flow_spec.rb
383
400
  - spec/models/sell_opening_flow_spec.rb
384
401
  - spec/spec_helper.rb
385
402
  - spec/support/bitex_stubs.rb
386
- - spec/support/bitstamp_stubs.rb
403
+ - spec/support/bitstamp/bitstamp_api_wrapper_stubs.rb
404
+ - spec/support/bitstamp/bitstamp_stubs.rb
@@ -1,118 +0,0 @@
1
- require "bigdecimal"
2
- require "bigdecimal/util"
3
-
4
- module Bitfinex
5
- module WithUserAgent
6
- def new_rest_connection
7
- super.tap do |conn|
8
- conn.headers['User-Agent'] = BitexBot.user_agent
9
- end
10
- end
11
- end
12
-
13
- class Client
14
- prepend WithUserAgent
15
- end
16
- end
17
-
18
- class BitfinexApiWrapper
19
- def self.setup(settings)
20
- Bitfinex::Client.configure do |conf|
21
- conf.api_key = settings.bitfinex.api_key
22
- conf.secret = settings.bitfinex.api_secret
23
- end
24
- end
25
-
26
- def self.with_retry(action, &block)
27
- begin
28
- block.call
29
- rescue StandardError, Bitfinex::ClientError => e
30
- raise e if BitexBot::Robot.test_mode
31
- BitexBot::Robot.logger.info("Bitfinex #{action} failed. Retrying in 5 seconds.")
32
- sleep 5
33
- retry
34
- end
35
- end
36
-
37
- def self.transactions
38
- with_retry 'transactions' do
39
- Bitfinex::Client.new.trades.collect do |t|
40
- Hashie::Mash.new({
41
- tid: t['tid'].to_i,
42
- price: t['price'],
43
- amount: t['amount'],
44
- date: t['timestamp']
45
- })
46
- end
47
- end
48
- end
49
-
50
- def self.order_book
51
- with_retry 'order_book' do
52
- book = Bitfinex::Client.new.orderbook
53
- { 'bids' => book['bids'].collect{|b| [b['price'], b['amount']] },
54
- 'asks' => book['asks'].collect{|a| [a['price'], a['amount']] } }
55
- end
56
- end
57
-
58
- def self.balance
59
- with_retry 'balance' do
60
- balances = Bitfinex::Client.new.balances(type: 'exchange')
61
- sleep 1 # Sleep to avoid sending two consecutive requests to bitfinex.
62
- fee = Bitfinex::Client.new.account_info.first['taker_fees']
63
- btc = balances.find{|b| b['currency'] == 'btc' } || {}
64
- usd = balances.find{|b| b['currency'] == 'usd' } || {}
65
- { "btc_balance" => btc['amount'].to_d,
66
- "btc_reserved" => btc['amount'].to_d - btc['available'].to_d,
67
- "btc_available" => btc['available'].to_d,
68
- "usd_balance" => usd['amount'].to_d,
69
- "usd_reserved" => usd['amount'].to_d - usd['available'].to_d,
70
- "usd_available" => usd['available'].to_d,
71
- "fee" => fee.to_d
72
- }
73
- end
74
- end
75
-
76
- def self.orders
77
- with_retry 'orders' do
78
- Bitfinex::Client.new.orders.collect{|o| BitfinexOrder.new(o) }
79
- end
80
- end
81
-
82
- # We don't need to fetch the list of transactions
83
- # for bitfinex
84
- def self.user_transactions
85
- []
86
- end
87
-
88
- def self.amount_and_quantity(order_id, transactions)
89
- with_retry "find order #{order_id}" do
90
- order = Bitfinex::Client.new.order_status(order_id)
91
- [order['avg_execution_price'].to_d * order['executed_amount'].to_d, order['executed_amount'].to_d]
92
- end
93
- end
94
-
95
- def self.place_order(type, price, quantity)
96
- with_retry "place order #{type} #{price} #{quantity}" do
97
- order_data = Bitfinex::Client.new
98
- .new_order('btcusd', quantity.round(4), 'exchange limit', type.to_s, price.round(2))
99
- BitfinexOrder.new(order_data)
100
- end
101
- end
102
- end
103
-
104
- class BitfinexOrder
105
- attr_accessor :id, :amount, :price, :type, :datetime
106
- def initialize(order_data)
107
- self.id = order_data['id'].to_i
108
- self.amount = order_data['original_amount'].to_d
109
- self.price = order_data['price'].to_d
110
- self.type = order_data['side'].to_sym
111
- self.datetime = order_data['timestamp'].to_i
112
- end
113
-
114
- def cancel!
115
- Bitfinex::Client.new.cancel_orders(id)
116
- end
117
- end
118
-
@@ -1,82 +0,0 @@
1
- class BitstampApiWrapper
2
- def self.setup(settings)
3
- Bitstamp.setup do |config|
4
- config.key = settings.bitstamp.api_key
5
- config.secret = settings.bitstamp.secret
6
- config.client_id = settings.bitstamp.client_id.to_s
7
- end
8
- end
9
-
10
- #{
11
- # tid:i,
12
- # date: (i+1).seconds.ago.to_i.to_s,
13
- # price: price.to_s,
14
- # amount: amount.to_s
15
- #}
16
- def self.transactions
17
- Bitstamp.transactions
18
- end
19
-
20
- # { 'timestamp' => DateTime.now.to_i.to_s,
21
- # 'bids' =>
22
- # [['30', '3'], ['25', '2'], ['20', '1.5'], ['15', '4'], ['10', '5']],
23
- # 'asks' =>
24
- # [['10', '2'], ['15', '3'], ['20', '1.5'], ['25', '3'], ['30', '3']]
25
- # }
26
- def self.order_book(retries = 20)
27
- begin
28
- book = Bitstamp.order_book
29
- age = Time.now.to_i - book["timestamp"].to_i
30
- if age > 300
31
- BitexBot::Robot.logger.info("Refusing to continue as orderbook is #{age} seconds old")
32
- self.order_book(retries)
33
- else
34
- book
35
- end
36
- rescue StandardError => e
37
- if retries == 0
38
- raise
39
- else
40
- BitexBot::Robot.logger.info("Bitstamp order_book failed, retrying #{retries} more times")
41
- sleep 1
42
- self.order_book(retries - 1)
43
- end
44
- end
45
- end
46
-
47
- # {"btc_balance"=> "10.0", "btc_reserved"=> "0", "btc_available"=> "10.0",
48
- # "usd_balance"=> "100.0", "usd_reserved"=>"0", "usd_available"=> "100.0",
49
- # "fee"=> "0.5000"}
50
- def self.balance
51
- Bitstamp.balance
52
- end
53
-
54
- # ask = double(amount: args[:amount], price: args[:price],
55
- # type: 1, id: remote_id, datetime: DateTime.now.to_s)
56
- # ask.stub(:cancel!) do
57
- def self.orders
58
- Bitstamp.orders.all
59
- end
60
-
61
- # double(usd: (usd * ratio).to_s, btc: (btc * ratio).to_s,
62
- # btc_usd: o.price.to_s, order_id: o.id, fee: "0.5", type: 2,
63
- # datetime: DateTime.now.to_s)
64
- def self.user_transactions
65
- Bitstamp.user_transactions.all
66
- end
67
-
68
- def self.order_is_done?(order)
69
- order.nil?
70
- end
71
-
72
- def self.amount_and_quantity(order_id, transactions)
73
- closes = transactions.select{|t| t.order_id.to_s == order_id}
74
- amount = closes.collect{|x| x.usd.to_d }.sum.abs
75
- quantity = closes.collect{|x| x.btc.to_d }.sum.abs
76
- [amount, quantity]
77
- end
78
-
79
- def self.place_order(type, price, quantity)
80
- Bitstamp.orders.send(type, amount: quantity.round(4), price: price.round(2))
81
- end
82
- end
@@ -1,68 +0,0 @@
1
- class ItbitApiWrapper
2
- def self.setup(settings)
3
- Itbit.client_key = settings.itbit.client_key
4
- Itbit.secret = settings.itbit.secret
5
- Itbit.user_id = settings.itbit.user_id
6
- Itbit.default_wallet_id = settings.itbit.default_wallet_id
7
- Itbit.sandbox = settings.sandbox
8
- end
9
-
10
- def self.transactions
11
- Itbit::XBTUSDMarketData.trades.collect{|t| Hashie::Mash.new(t) }
12
- end
13
-
14
- def self.order_book
15
- Itbit::XBTUSDMarketData.orders.stringify_keys
16
- end
17
-
18
- def self.balance
19
- balances = Itbit::Wallet.all
20
- .find{|i| i[:id] == Itbit.default_wallet_id }[:balances]
21
- usd = balances.find{|x| x[:currency] == :usd }
22
- btc = balances.find{|x| x[:currency] == :xbt }
23
- { "btc_balance" => btc[:total_balance],
24
- "btc_reserved" => btc[:total_balance] - btc[:available_balance],
25
- "btc_available" => btc[:available_balance],
26
- "usd_balance" => usd[:total_balance],
27
- "usd_reserved" => usd[:total_balance] - usd[:available_balance],
28
- "usd_available" => usd[:available_balance],
29
- "fee" => 0.5
30
- }
31
- end
32
-
33
- def self.orders
34
- Itbit::Order.all(status: :open)
35
- end
36
-
37
- # We don't need to fetch the list of transactions
38
- # for itbit since we wont actually use them later.
39
- def self.user_transactions
40
- []
41
- end
42
-
43
- def self.amount_and_quantity(order_id, transactions)
44
- order = Itbit::Order.find(order_id)
45
- [order.volume_weighted_average_price * order.amount_filled, order.amount_filled]
46
- end
47
-
48
- def self.place_order(type, price, quantity)
49
- begin
50
- return Itbit::Order.create!(type, :xbtusd, quantity.round(4), price.round(2), wait: true)
51
- rescue RestClient::RequestTimeout => e
52
- # On timeout errors, we still look for the latest active closing order
53
- # that may be available. We have a magic threshold of 5 minutes
54
- # and also use the price to recognize an order as the current one.
55
- # TODO: Maybe we can identify the order using metadata instead of price.
56
- BitexBot::Robot.logger.error("Captured Timeout on itbit")
57
- latest = Itbit::Order.all.select do |x|
58
- x.price == price && (x.created_time - Time.now.to_i).abs < 500
59
- end.first
60
- if latest
61
- return latest
62
- else
63
- BitexBot::Robot.logger.error("Could not find my order")
64
- raise e
65
- end
66
- end
67
- end
68
- end