bitex_bot 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/bitex_bot/database.rb +3 -1
- data/lib/bitex_bot/models/buy_opening_flow.rb +4 -3
- data/lib/bitex_bot/models/opening_flow.rb +6 -1
- data/lib/bitex_bot/models/sell_opening_flow.rb +7 -2
- data/lib/bitex_bot/robot.rb +9 -5
- data/lib/bitex_bot/version.rb +1 -1
- data/spec/models/buy_opening_flow_spec.rb +19 -6
- data/spec/models/sell_opening_flow_spec.rb +19 -6
- metadata +2 -2
data/lib/bitex_bot/database.rb
CHANGED
@@ -88,7 +88,7 @@ module BitexBot
|
|
88
88
|
add_index :close_sells, :order_id
|
89
89
|
end
|
90
90
|
|
91
|
-
unless ActiveRecord::Base.connection.
|
91
|
+
unless ActiveRecord::Base.connection.column_exists?('stores', 'buying_profit')
|
92
92
|
create_table "stores", force: true do |t|
|
93
93
|
t.decimal "taker_usd", precision: 20, scale: 8
|
94
94
|
t.decimal "taker_btc", precision: 20, scale: 8
|
@@ -99,6 +99,8 @@ module BitexBot
|
|
99
99
|
t.decimal "btc_stop", precision: 20, scale: 8
|
100
100
|
t.decimal "btc_warning", precision: 20, scale: 8
|
101
101
|
t.datetime "last_warning"
|
102
|
+
t.decimal "buying_profit", precision: 20, scale: 8
|
103
|
+
t.decimal "selling_profit", precision: 20, scale: 8
|
102
104
|
t.timestamps
|
103
105
|
end
|
104
106
|
end
|
@@ -32,13 +32,14 @@ module BitexBot
|
|
32
32
|
# @param bitex_fee [BigDecimal] the transaction fee to pay on bitex.
|
33
33
|
# @param other_fee [BigDecimal] the transaction fee to pay on the other
|
34
34
|
# exchange.
|
35
|
+
# @param store [Store] An updated config for this robot, mainly to use for profit.
|
35
36
|
#
|
36
37
|
# @return [BuyOpeningFlow] The newly created flow.
|
37
38
|
# @raise [CannotCreateFlow] If there's any problem creating this flow, for
|
38
39
|
# example when you run out of USD on bitex or out of BTC on the other
|
39
40
|
# exchange.
|
40
41
|
def self.create_for_market(btc_balance, order_book, transactions,
|
41
|
-
bitex_fee, other_fee)
|
42
|
+
bitex_fee, other_fee, store)
|
42
43
|
super
|
43
44
|
end
|
44
45
|
|
@@ -63,7 +64,7 @@ module BitexBot
|
|
63
64
|
end
|
64
65
|
|
65
66
|
def self.profit
|
66
|
-
Settings.buying.profit
|
67
|
+
store.buying_profit || Settings.buying.profit
|
67
68
|
end
|
68
69
|
|
69
70
|
def self.get_safest_price(transactions, order_book, dollars_to_use)
|
@@ -76,7 +77,7 @@ module BitexBot
|
|
76
77
|
end
|
77
78
|
|
78
79
|
def self.get_bitex_price(usd_to_spend, bitcoin_to_resell)
|
79
|
-
(usd_to_spend / bitcoin_to_resell) * (1 -
|
80
|
+
(usd_to_spend / bitcoin_to_resell) * (1 - self.profit / 100.0)
|
80
81
|
end
|
81
82
|
end
|
82
83
|
end
|
@@ -4,6 +4,9 @@ module BitexBot
|
|
4
4
|
# transactions spawn from that order as Open positions.
|
5
5
|
class OpeningFlow < ActiveRecord::Base
|
6
6
|
self.abstract_class = true
|
7
|
+
|
8
|
+
# The updated config store as passed from the robot
|
9
|
+
cattr_accessor :store
|
7
10
|
|
8
11
|
def self.active
|
9
12
|
where('status != "finalised"')
|
@@ -38,7 +41,9 @@ module BitexBot
|
|
38
41
|
validates_presence_of :price, :value_to_use
|
39
42
|
|
40
43
|
def self.create_for_market(remote_balance, order_book, transactions,
|
41
|
-
bitex_fee, other_fee)
|
44
|
+
bitex_fee, other_fee, store)
|
45
|
+
|
46
|
+
self.store = store
|
42
47
|
|
43
48
|
plus_bitex = value_to_use + (value_to_use * bitex_fee / 100.0)
|
44
49
|
value_to_use_needed = plus_bitex / (1 - other_fee / 100.0)
|
@@ -32,13 +32,14 @@ module BitexBot
|
|
32
32
|
# @param bitex_fee [BigDecimal] the transaction fee to pay on bitex.
|
33
33
|
# @param other_fee [BigDecimal] the transaction fee to pay on the other
|
34
34
|
# exchange.
|
35
|
+
# @param store [Store] An updated config for this robot, mainly to use for profit.
|
35
36
|
#
|
36
37
|
# @return [SellOpeningFlow] The newly created flow.
|
37
38
|
# @raise [CannotCreateFlow] If there's any problem creating this flow, for
|
38
39
|
# example when you run out of BTC on bitex or out of USD on the other
|
39
40
|
# exchange.
|
40
41
|
def self.create_for_market(usd_balance, order_book, transactions,
|
41
|
-
bitex_fee, other_fee)
|
42
|
+
bitex_fee, other_fee, store)
|
42
43
|
super
|
43
44
|
end
|
44
45
|
|
@@ -70,9 +71,13 @@ module BitexBot
|
|
70
71
|
def self.get_remote_value_to_use(value_to_use_needed, safest_price)
|
71
72
|
value_to_use_needed * safest_price
|
72
73
|
end
|
74
|
+
|
75
|
+
def self.profit
|
76
|
+
store.selling_profit || Settings.selling.profit
|
77
|
+
end
|
73
78
|
|
74
79
|
def self.get_bitex_price(btc_to_sell, usd_to_spend_re_buying)
|
75
|
-
(usd_to_spend_re_buying / btc_to_sell) * (1 +
|
80
|
+
(usd_to_spend_re_buying / btc_to_sell) * (1 + profit / 100.0)
|
76
81
|
end
|
77
82
|
end
|
78
83
|
end
|
data/lib/bitex_bot/robot.rb
CHANGED
@@ -26,7 +26,7 @@ module BitexBot
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
cattr_accessor :current_cooldowns do 0 end
|
29
|
-
|
29
|
+
|
30
30
|
# Trade constantly respecting cooldown times so that we don't get
|
31
31
|
# banned by api clients.
|
32
32
|
def self.run!
|
@@ -34,7 +34,7 @@ module BitexBot
|
|
34
34
|
logger.info("Loading trading robot, ctrl+c *once* to exit gracefully.")
|
35
35
|
self.cooldown_until = Time.now
|
36
36
|
bot = new
|
37
|
-
|
37
|
+
|
38
38
|
while true
|
39
39
|
start_time = Time.now
|
40
40
|
next if start_time < cooldown_until
|
@@ -146,8 +146,10 @@ module BitexBot
|
|
146
146
|
total_usd = balances['usd_balance'].to_d + profile[:usd_balance]
|
147
147
|
total_btc = balances['btc_balance'].to_d + profile[:btc_balance]
|
148
148
|
|
149
|
+
last_log = `tail -n 500 #{Settings.log.try(:file)}` if Settings.log.try(:file)
|
150
|
+
|
149
151
|
store.update_attributes(taker_usd: balances['usd_balance'],
|
150
|
-
taker_btc: balances['btc_balance'])
|
152
|
+
taker_btc: balances['btc_balance'], log: last_log)
|
151
153
|
|
152
154
|
if store.last_warning.nil? || store.last_warning < 30.minutes.ago
|
153
155
|
if store.usd_warning && total_usd <= store.usd_warning
|
@@ -181,7 +183,8 @@ module BitexBot
|
|
181
183
|
order_book['bids'],
|
182
184
|
transactions,
|
183
185
|
profile[:fee],
|
184
|
-
balances['fee'].to_d
|
186
|
+
balances['fee'].to_d,
|
187
|
+
store)
|
185
188
|
end
|
186
189
|
unless recent_selling
|
187
190
|
SellOpeningFlow.create_for_market(
|
@@ -189,7 +192,8 @@ module BitexBot
|
|
189
192
|
order_book['asks'],
|
190
193
|
transactions,
|
191
194
|
profile[:fee],
|
192
|
-
balances['fee'].to_d
|
195
|
+
balances['fee'].to_d,
|
196
|
+
store)
|
193
197
|
end
|
194
198
|
end
|
195
199
|
|
data/lib/bitex_bot/version.rb
CHANGED
@@ -4,6 +4,7 @@ describe BitexBot::BuyOpeningFlow do
|
|
4
4
|
before(:each) do
|
5
5
|
Bitex.api_key = "valid_key"
|
6
6
|
end
|
7
|
+
let(:store){ BitexBot::Store.create }
|
7
8
|
|
8
9
|
it { should validate_presence_of :status }
|
9
10
|
it { should validate_presence_of :price }
|
@@ -19,7 +20,7 @@ describe BitexBot::BuyOpeningFlow do
|
|
19
20
|
buying: double(amount_to_spend_per_order: 50, profit: 0))
|
20
21
|
|
21
22
|
flow = BitexBot::BuyOpeningFlow.create_for_market(100,
|
22
|
-
bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25)
|
23
|
+
bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25, store)
|
23
24
|
|
24
25
|
flow.value_to_use.should == 50
|
25
26
|
flow.price.should <= flow.suggested_closing_price
|
@@ -34,7 +35,7 @@ describe BitexBot::BuyOpeningFlow do
|
|
34
35
|
buying: double(amount_to_spend_per_order: 100, profit: 0))
|
35
36
|
|
36
37
|
flow = BitexBot::BuyOpeningFlow.create_for_market(100000,
|
37
|
-
bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25)
|
38
|
+
bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25, store)
|
38
39
|
flow.value_to_use.should == 100
|
39
40
|
flow.price.should <= flow.suggested_closing_price
|
40
41
|
flow.price.should == "14.88805970149254".to_d
|
@@ -48,7 +49,7 @@ describe BitexBot::BuyOpeningFlow do
|
|
48
49
|
buying: double(amount_to_spend_per_order: 100, profit: 50))
|
49
50
|
|
50
51
|
flow = BitexBot::BuyOpeningFlow.create_for_market(100000,
|
51
|
-
bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25)
|
52
|
+
bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25, store)
|
52
53
|
flow.value_to_use.should == 100
|
53
54
|
flow.price.should <= flow.suggested_closing_price
|
54
55
|
flow.price.should == "7.444029850746269".to_d
|
@@ -66,7 +67,7 @@ describe BitexBot::BuyOpeningFlow do
|
|
66
67
|
|
67
68
|
expect do
|
68
69
|
flow = BitexBot::BuyOpeningFlow.create_for_market(100000,
|
69
|
-
bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25)
|
70
|
+
bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25, store)
|
70
71
|
flow.should be_nil
|
71
72
|
BitexBot::BuyOpeningFlow.count.should == 0
|
72
73
|
end.to raise_exception(BitexBot::CannotCreateFlow)
|
@@ -79,11 +80,23 @@ describe BitexBot::BuyOpeningFlow do
|
|
79
80
|
|
80
81
|
expect do
|
81
82
|
flow = BitexBot::BuyOpeningFlow.create_for_market(1,
|
82
|
-
bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25)
|
83
|
+
bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25, store)
|
83
84
|
flow.should be_nil
|
84
85
|
BitexBot::BuyOpeningFlow.count.should == 0
|
85
86
|
end.to raise_exception(BitexBot::CannotCreateFlow)
|
86
87
|
end
|
88
|
+
|
89
|
+
it 'prioritizes profit from store' do
|
90
|
+
store = BitexBot::Store.new(buying_profit: 0.5)
|
91
|
+
stub_bitex_orders
|
92
|
+
BitexBot::Settings.stub(time_to_live: 3,
|
93
|
+
buying: double(amount_to_spend_per_order: 50, profit: 0))
|
94
|
+
|
95
|
+
flow = BitexBot::BuyOpeningFlow.create_for_market(100,
|
96
|
+
bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25, store)
|
97
|
+
|
98
|
+
flow.price.should == "19.75149253731344".to_d
|
99
|
+
end
|
87
100
|
end
|
88
101
|
|
89
102
|
describe "when fetching open positions" do
|
@@ -141,7 +154,7 @@ describe BitexBot::BuyOpeningFlow do
|
|
141
154
|
buying: double(amount_to_spend_per_order: 50, profit: 0))
|
142
155
|
|
143
156
|
flow = BitexBot::BuyOpeningFlow.create_for_market(100,
|
144
|
-
bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25)
|
157
|
+
bitstamp_order_book_stub['bids'], bitstamp_transactions_stub, 0.5, 0.25, store)
|
145
158
|
|
146
159
|
flow.finalise!
|
147
160
|
flow.should be_settling
|
@@ -4,6 +4,7 @@ describe BitexBot::SellOpeningFlow do
|
|
4
4
|
before(:each) do
|
5
5
|
Bitex.api_key = "valid_key"
|
6
6
|
end
|
7
|
+
let(:store){ BitexBot::Store.create }
|
7
8
|
|
8
9
|
it { should validate_presence_of :status }
|
9
10
|
it { should validate_presence_of :price }
|
@@ -19,7 +20,7 @@ describe BitexBot::SellOpeningFlow do
|
|
19
20
|
selling: double(quantity_to_sell_per_order: 2, profit: 0))
|
20
21
|
|
21
22
|
flow = BitexBot::SellOpeningFlow.create_for_market(1000,
|
22
|
-
bitstamp_order_book_stub['asks'], bitstamp_transactions_stub, 0.5, 0.25)
|
23
|
+
bitstamp_order_book_stub['asks'], bitstamp_transactions_stub, 0.5, 0.25, store)
|
23
24
|
|
24
25
|
flow.value_to_use.should == 2
|
25
26
|
flow.price.should >= flow.suggested_closing_price
|
@@ -34,7 +35,7 @@ describe BitexBot::SellOpeningFlow do
|
|
34
35
|
selling: double(quantity_to_sell_per_order: 4, profit: 0))
|
35
36
|
|
36
37
|
flow = BitexBot::SellOpeningFlow.create_for_market(1000,
|
37
|
-
bitstamp_order_book_stub['asks'], bitstamp_transactions_stub, 0.5, 0.25)
|
38
|
+
bitstamp_order_book_stub['asks'], bitstamp_transactions_stub, 0.5, 0.25, store)
|
38
39
|
|
39
40
|
flow.value_to_use.should == 4
|
40
41
|
flow.price.should >= flow.suggested_closing_price
|
@@ -49,7 +50,7 @@ describe BitexBot::SellOpeningFlow do
|
|
49
50
|
selling: double(quantity_to_sell_per_order: 4, profit: 50))
|
50
51
|
|
51
52
|
flow = BitexBot::SellOpeningFlow.create_for_market(1000,
|
52
|
-
bitstamp_order_book_stub['asks'], bitstamp_transactions_stub, 0.5, 0.25)
|
53
|
+
bitstamp_order_book_stub['asks'], bitstamp_transactions_stub, 0.5, 0.25, store)
|
53
54
|
|
54
55
|
flow.value_to_use.should == 4
|
55
56
|
flow.price.should >= flow.suggested_closing_price
|
@@ -68,7 +69,7 @@ describe BitexBot::SellOpeningFlow do
|
|
68
69
|
|
69
70
|
expect do
|
70
71
|
flow = BitexBot::SellOpeningFlow.create_for_market(100000,
|
71
|
-
bitstamp_order_book_stub['asks'], bitstamp_transactions_stub, 0.5, 0.25)
|
72
|
+
bitstamp_order_book_stub['asks'], bitstamp_transactions_stub, 0.5, 0.25, store)
|
72
73
|
flow.should be_nil
|
73
74
|
BitexBot::SellOpeningFlow.count.should == 0
|
74
75
|
end.to raise_exception(BitexBot::CannotCreateFlow)
|
@@ -81,11 +82,23 @@ describe BitexBot::SellOpeningFlow do
|
|
81
82
|
|
82
83
|
expect do
|
83
84
|
flow = BitexBot::SellOpeningFlow.create_for_market(1,
|
84
|
-
bitstamp_order_book_stub['asks'], bitstamp_transactions_stub, 0.5, 0.25)
|
85
|
+
bitstamp_order_book_stub['asks'], bitstamp_transactions_stub, 0.5, 0.25, store)
|
85
86
|
flow.should be_nil
|
86
87
|
BitexBot::SellOpeningFlow.count.should == 0
|
87
88
|
end.to raise_exception(BitexBot::CannotCreateFlow)
|
88
89
|
end
|
90
|
+
|
91
|
+
it "Prioritizes profit from store" do
|
92
|
+
store = BitexBot::Store.new(selling_profit: 0.5)
|
93
|
+
stub_bitex_orders
|
94
|
+
BitexBot::Settings.stub(time_to_live: 3,
|
95
|
+
selling: double(quantity_to_sell_per_order: 2, profit: 0))
|
96
|
+
|
97
|
+
flow = BitexBot::SellOpeningFlow.create_for_market(1000,
|
98
|
+
bitstamp_order_book_stub['asks'], bitstamp_transactions_stub, 0.5, 0.25, store)
|
99
|
+
|
100
|
+
flow.price.should == "20.25112781954887".to_d
|
101
|
+
end
|
89
102
|
end
|
90
103
|
|
91
104
|
describe "when fetching open positions" do
|
@@ -143,7 +156,7 @@ describe BitexBot::SellOpeningFlow do
|
|
143
156
|
selling: double(quantity_to_sell_per_order: 4, profit: 50))
|
144
157
|
|
145
158
|
flow = BitexBot::SellOpeningFlow.create_for_market(1000,
|
146
|
-
bitstamp_order_book_stub['asks'], bitstamp_transactions_stub, 0.5, 0.25)
|
159
|
+
bitstamp_order_book_stub['asks'], bitstamp_transactions_stub, 0.5, 0.25, store)
|
147
160
|
|
148
161
|
flow.finalise!
|
149
162
|
flow.should be_settling
|
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.
|
4
|
+
version: 0.2.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2015-01-12 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: settingslogic
|