bitex_bot 0.2.12 → 0.2.13

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1ee843a4baa723bdd9e31d57f8c8ed732e00517e
4
- data.tar.gz: cc4acde842e3f0bec10163a55b3dd17567f65995
3
+ metadata.gz: b8994e54974f11a72d84fe860f4089d59561e6ac
4
+ data.tar.gz: 70e62bb47abb627a4b1f71312bc7b5b9f6c3389e
5
5
  SHA512:
6
- metadata.gz: 13725177100dd9fdc419c1fe6a8d6039e71322bb6fe15d208d431acec1569b26758ad8061c793872bdc620257f99924f3c1dff3ab93856b12cda0d0faeba4522
7
- data.tar.gz: 41ed89f74566c6e45fee4441a62ee846051dfae9b020b5dc247b6008bac2b5a004be0877d6dbd1a3e01e6231a6cbe75e24d34daf12c67d82c6f1c82446b2cf78
6
+ metadata.gz: a26decc7d2f8f81c37e6bf3a751f9b3f84acdc4be6149320869a0343c36801d6e94dc8ec43d0bd52e03599c3b1262b75c26b1f060e84f2740887e9f54d132c21
7
+ data.tar.gz: 34359e33f27d99d5be888e8c4fe641c4031adf8787b1629aa82958c0376df67fd385c3025b950368b8c690ac3af2db9bc5be17b222c0891010475a5da326b0e0
data/bitex_bot.gemspec CHANGED
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.add_dependency "bitstamp"
29
29
  spec.add_dependency "bitex", "0.2.6"
30
30
  spec.add_dependency "itbit", "0.0.6"
31
+ spec.add_dependency "bitfinex-rb", "0.0.6"
31
32
  spec.add_dependency "mail"
32
33
  spec.add_dependency "hashie"
33
34
 
@@ -0,0 +1,102 @@
1
+ require "bigdecimal"
2
+ require "bigdecimal/util"
3
+
4
+ class BitfinexApiWrapper
5
+ def self.setup(settings)
6
+ Bitfinex::Client.configure do |conf|
7
+ conf.api_key = settings.bitfinex.api_key
8
+ conf.secret = settings.bitfinex.api_secret
9
+ end
10
+ end
11
+
12
+ def self.with_retry(action, &block)
13
+ begin
14
+ block.call
15
+ rescue StandardError, Bitfinex::ClientError => e
16
+ BitexBot::Robot.logger.info("Bitfinex #{action} failed. Retrying in 5 seconds.")
17
+ sleep 5
18
+ retry
19
+ end
20
+ end
21
+
22
+ def self.transactions
23
+ with_retry 'transactions' do
24
+ Bitfinex::Client.new.trades.collect do |t|
25
+ { tid: t['tid'].to_i,
26
+ price: t['price'],
27
+ amount: t['amount'],
28
+ date: t['timestamp']
29
+ }
30
+ end
31
+ end
32
+ end
33
+
34
+ def self.order_book
35
+ with_retry 'order_book' do
36
+ book = Bitfinex::Client.new.orderbook
37
+ { 'bids' => book['bids'].collect{|b| [b['price'], b['amount']] },
38
+ 'asks' => book['asks'].collect{|a| [a['price'], a['amount']] } }
39
+ end
40
+ end
41
+
42
+ def self.balance
43
+ with_retry 'balance' do
44
+ balances = Bitfinex::Client.new.balances(type: 'exchange')
45
+ sleep 1 # Sleep to avoid sending two consecutive requests to bitfinex.
46
+ fee = Bitfinex::Client.new.account_info.first['taker_fees']
47
+ btc = balances.find{|b| b['currency'] == 'btc' } || {}
48
+ usd = balances.find{|b| b['currency'] == 'usd' } || {}
49
+ { "btc_balance" => btc['amount'].to_d,
50
+ "btc_reserved" => btc['amount'].to_d - btc['available'].to_d,
51
+ "btc_available" => btc['available'].to_d,
52
+ "usd_balance" => usd['amount'].to_d,
53
+ "usd_reserved" => usd['amount'].to_d - usd['available'].to_d,
54
+ "usd_available" => usd['available'].to_d,
55
+ "fee" => fee.to_d
56
+ }
57
+ end
58
+ end
59
+
60
+ def self.orders
61
+ with_retry 'orders' do
62
+ Bitfinex::Client.new.orders.collect{|o| BitfinexOrder.new(o) }
63
+ end
64
+ end
65
+
66
+ # We don't need to fetch the list of transactions
67
+ # for bitfinex
68
+ def self.user_transactions
69
+ []
70
+ end
71
+
72
+ def self.amount_and_quantity(order_id, transactions)
73
+ with_retry "find order #{order_id}" do
74
+ order = Bitfinex::Client.new.order_status(order_id)
75
+ [order['avg_execution_price'].to_d * order['executed_amount'].to_d, order['executed_amount'].to_d]
76
+ end
77
+ end
78
+
79
+ def self.place_order(type, price, quantity)
80
+ with_retry "place order #{type} #{price} #{quantity}" do
81
+ order_data = Bitfinex::Client.new
82
+ .new_order('btcusd', quantity, 'exchange limit', type.to_s, price)
83
+ BitfinexOrder.new(order_data)
84
+ end
85
+ end
86
+ end
87
+
88
+ class BitfinexOrder
89
+ attr_accessor :id, :amount, :price, :type, :datetime
90
+ def initialize(order_data)
91
+ self.id = order_data['id'].to_i
92
+ self.amount = order_data['original_amount'].to_d
93
+ self.price = order_data['price'].to_d
94
+ self.type = order_data['side'].to_sym
95
+ self.datetime = order_data['timestamp'].to_i
96
+ end
97
+
98
+ def cancel!
99
+ Bitfinex::Client.new.cancel_orders(id)
100
+ end
101
+ end
102
+
@@ -14,7 +14,14 @@ module BitexBot
14
14
  cattr_accessor :cooldown_until
15
15
  cattr_accessor :test_mode
16
16
  cattr_accessor :taker do
17
- Settings.taker == 'itbit' ? ItbitApiWrapper : BitstampApiWrapper
17
+ case Settings.taker
18
+ when 'itbit'
19
+ ItbitApiWrapper
20
+ when 'bitstamp'
21
+ BitstampApiWrapper
22
+ when 'bitfinex'
23
+ BitfinexApiWrapper
24
+ end
18
25
  end
19
26
  cattr_accessor :logger do
20
27
  Logger.new(Settings.log.try(:file) || STDOUT, 10, 10240000).tap do |l|
@@ -1,3 +1,3 @@
1
1
  module BitexBot
2
- VERSION = "0.2.12"
2
+ VERSION = "0.2.13"
3
3
  end
data/lib/bitex_bot.rb CHANGED
@@ -8,6 +8,7 @@ require "logger"
8
8
  require "bitex"
9
9
  require "bitstamp"
10
10
  require "itbit"
11
+ require 'bitfinex'
11
12
  require "bitex_bot/settings"
12
13
  require "bitex_bot/database"
13
14
  require "bitex_bot/models/opening_flow.rb"
data/settings.yml.sample CHANGED
@@ -17,7 +17,7 @@ time_to_live: 20
17
17
  sandbox: false
18
18
 
19
19
  # Which market to use for taking (we're always makers on bitex)
20
- # itbit or bitstamp
20
+ # itbit, bitstamp or bitfinex
21
21
  taker: bitstamp
22
22
 
23
23
  # Settings for buying on bitex and selling on bitstamp.
@@ -69,10 +69,17 @@ bitstamp:
69
69
  # These are passed in to the itbit gem:
70
70
  # see https://github.com/bitex-la/itbit for more info.
71
71
  itbit:
72
- client_key = 'the-client-key'
73
- secret = 'the-secret'
74
- user_id = 'the-user-id'
75
- default_wallet_id = 'wallet-000'
72
+ client_key: 'the-client-key'
73
+ secret: 'the-secret'
74
+ user_id: 'the-user-id'
75
+ default_wallet_id: 'wallet-000'
76
+
77
+ # These are passed in to the bitfinex gem:
78
+ # see https://github.com/bitfinexcom/bitfinex-api-rb for more info.
79
+ bitfinex:
80
+ api_key: 'your_api_key'
81
+ api_secret: 'your_api_secret'
82
+
76
83
 
77
84
  # Settings for the ActiveRecord Database to use.
78
85
  # sqlite is just fine. Check this link for more options:
@@ -26,7 +26,7 @@ describe BitexBot::BuyClosingFlow do
26
26
  open_one.reload.closing_flow.should == flow
27
27
  open_two.reload.closing_flow.should == flow
28
28
  flow.open_positions.should == [open_one, open_two]
29
- flow.desired_price.should == '310.497512437810945273631840797'.to_d
29
+ flow.desired_price.round(15).should == '310.497512437810945'.to_d
30
30
  flow.quantity.should == 2.01
31
31
  flow.btc_profit.should be_nil
32
32
  flow.usd_profit.should be_nil
@@ -10,7 +10,7 @@ describe BitexBot::BuyOpeningFlow do
10
10
  it { should validate_presence_of :price }
11
11
  it { should validate_presence_of :value_to_use }
12
12
  it { should validate_presence_of :order_id }
13
- it { should(ensure_inclusion_of(:status)
13
+ it { should(validate_inclusion_of(:status)
14
14
  .in_array(BitexBot::BuyOpeningFlow.statuses)) }
15
15
 
16
16
  describe "when creating a buying flow" do
@@ -24,7 +24,7 @@ describe BitexBot::BuyOpeningFlow do
24
24
 
25
25
  flow.value_to_use.should == 50
26
26
  flow.price.should <= flow.suggested_closing_price
27
- flow.price.should == "19.85074626865672".to_d
27
+ flow.price.round(14).should == "19.85074626865672".to_d
28
28
  flow.suggested_closing_price.should == 20
29
29
  flow.order_id.should == 12345
30
30
  end
@@ -52,7 +52,7 @@ describe BitexBot::BuyOpeningFlow do
52
52
  bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25, store)
53
53
  flow.value_to_use.should == 100
54
54
  flow.price.should <= flow.suggested_closing_price
55
- flow.price.should == "7.444029850746269".to_d
55
+ flow.price.round(15).should == "7.44402985074627".to_d
56
56
  flow.suggested_closing_price.should == 15
57
57
  flow.order_id.should == 12345
58
58
  end
@@ -95,7 +95,7 @@ describe BitexBot::BuyOpeningFlow do
95
95
  flow = BitexBot::BuyOpeningFlow.create_for_market(100,
96
96
  bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25, store)
97
97
 
98
- flow.price.should == "19.75149253731344".to_d
98
+ flow.price.round(13).should == "19.7514925373134".to_d
99
99
  end
100
100
  end
101
101
 
@@ -27,7 +27,7 @@ describe BitexBot::SellClosingFlow do
27
27
  open_one.reload.closing_flow.should == flow
28
28
  open_two.reload.closing_flow.should == flow
29
29
  flow.open_positions.should == [open_one, open_two]
30
- flow.desired_price.should == '290.497512437810945273631840797'.to_d
30
+ flow.desired_price.round(15).should == '290.497512437810945'.to_d
31
31
  flow.quantity.should == 2.01
32
32
  flow.amount.should == 604
33
33
  flow.btc_profit.should be_nil
@@ -10,7 +10,7 @@ describe BitexBot::SellOpeningFlow do
10
10
  it { should validate_presence_of :price }
11
11
  it { should validate_presence_of :value_to_use }
12
12
  it { should validate_presence_of :order_id }
13
- it { should(ensure_inclusion_of(:status)
13
+ it { should(validate_inclusion_of(:status)
14
14
  .in_array(BitexBot::SellOpeningFlow.statuses)) }
15
15
 
16
16
  describe "when creating a selling flow" do
@@ -39,7 +39,7 @@ describe BitexBot::SellOpeningFlow do
39
39
 
40
40
  flow.value_to_use.should == 4
41
41
  flow.price.should >= flow.suggested_closing_price
42
- flow.price.should == "25.18796992481203".to_d
42
+ flow.price.round(14).should == "25.18796992481203".to_d
43
43
  flow.suggested_closing_price.should == 25
44
44
  flow.order_id.should == 12345
45
45
  end
@@ -54,7 +54,7 @@ describe BitexBot::SellOpeningFlow do
54
54
 
55
55
  flow.value_to_use.should == 4
56
56
  flow.price.should >= flow.suggested_closing_price
57
- flow.price.should == "37.78195488721804".to_d
57
+ flow.price.round(14).should == "37.78195488721804".to_d
58
58
  flow.suggested_closing_price.should == 25
59
59
  flow.order_id.should == 12345
60
60
  end
@@ -97,7 +97,7 @@ describe BitexBot::SellOpeningFlow do
97
97
  flow = BitexBot::SellOpeningFlow.create_for_market(1000,
98
98
  bitstamp_order_book_stub['asks'], bitstamp_transactions_stub, 0.5, 0.25, store)
99
99
 
100
- flow.price.should == "20.25112781954887".to_d
100
+ flow.price.round(14).should == "20.25112781954887".to_d
101
101
  end
102
102
  end
103
103
 
data/spec/spec_helper.rb CHANGED
@@ -22,6 +22,8 @@ DatabaseCleaner.strategy = :truncation
22
22
 
23
23
  RSpec.configure do |config|
24
24
  config.include(FactoryGirl::Syntax::Methods)
25
+ config.include(Shoulda::Matchers::ActiveModel)
26
+ config.include(Shoulda::Matchers::ActiveRecord)
25
27
  config.mock_with :rspec do |mocks|
26
28
  mocks.yield_receiver_to_any_instance_implementation_blocks = true
27
29
  mocks.syntax = [:expect, :should]
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.2.12
4
+ version: 0.2.13
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: 2016-04-09 00:00:00.000000000 Z
12
+ date: 2016-04-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: settingslogic
@@ -109,6 +109,20 @@ dependencies:
109
109
  - - '='
110
110
  - !ruby/object:Gem::Version
111
111
  version: 0.0.6
112
+ - !ruby/object:Gem::Dependency
113
+ name: bitfinex-rb
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '='
117
+ - !ruby/object:Gem::Version
118
+ version: 0.0.6
119
+ type: :runtime
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - '='
124
+ - !ruby/object:Gem::Version
125
+ version: 0.0.6
112
126
  - !ruby/object:Gem::Dependency
113
127
  name: mail
114
128
  requirement: !ruby/object:Gem::Requirement
@@ -285,6 +299,7 @@ files:
285
299
  - bitex_bot.gemspec
286
300
  - lib/bitex_bot.rb
287
301
  - lib/bitex_bot/database.rb
302
+ - lib/bitex_bot/models/bitfinex_api_wrapper.rb
288
303
  - lib/bitex_bot/models/bitstamp_api_wrapper.rb
289
304
  - lib/bitex_bot/models/buy_closing_flow.rb
290
305
  - lib/bitex_bot/models/buy_opening_flow.rb