bitex_bot 0.2.12 → 0.2.13

Sign up to get free protection for your applications and to get access to all the features.
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