bitex_bot 0.3.7 → 0.4.0

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.
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