bitx 0.0.1 → 0.2.2
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 +4 -4
- data/README.md +92 -5
- data/Rakefile +7 -0
- data/bitx.gemspec +7 -4
- data/lib/bitx.rb +42 -54
- data/lib/bitx_connection.rb +0 -0
- data/lib/private_api.rb +289 -0
- data/lib/public_api.rb +77 -0
- data/lib/version.rb +9 -0
- data/test/balance_test.rb +58 -0
- data/test/order_test.rb +116 -0
- data/test/public_test.rb +224 -0
- data/test/quotes_test.rb +163 -0
- data/test/receive_address_test.rb +101 -0
- data/test/send_test.rb +40 -0
- data/test/withdrawal_test.rb +108 -0
- metadata +39 -5
data/lib/public_api.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
module PublicApi
|
2
|
+
|
3
|
+
def ticker(pair)
|
4
|
+
t = self.get('/api/1/ticker', {pair: pair})
|
5
|
+
{
|
6
|
+
pair: pair,
|
7
|
+
timestamp: Time.at(t['timestamp'].to_i/1000),
|
8
|
+
ask: BigDecimal(t['ask']),
|
9
|
+
bid: BigDecimal(t['bid']),
|
10
|
+
last: BigDecimal(t['last_trade']),
|
11
|
+
volume: t['rolling_24_hour_volume']
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def tickers
|
16
|
+
tickers = []
|
17
|
+
self.get('/api/1/tickers')['tickers'].each do |t|
|
18
|
+
tickers << {
|
19
|
+
pair: t['pair'],
|
20
|
+
timestamp: Time.at(t['timestamp'].to_i/1000),
|
21
|
+
ask: BigDecimal(t['ask']),
|
22
|
+
bid: BigDecimal(t['bid']),
|
23
|
+
last: BigDecimal(t['last_trade']),
|
24
|
+
volume: t['rolling_24_hour_volume']
|
25
|
+
}
|
26
|
+
end
|
27
|
+
tickers
|
28
|
+
end
|
29
|
+
|
30
|
+
def orderbook(pair)
|
31
|
+
t = self.get('/api/1/orderbook', {pair: pair})
|
32
|
+
|
33
|
+
bids = []
|
34
|
+
t['bids'].each do |o|
|
35
|
+
bids << {
|
36
|
+
price: BigDecimal(o['price']),
|
37
|
+
volume: BigDecimal(o['volume'])
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
asks = []
|
42
|
+
t['asks'].each do |o|
|
43
|
+
asks << {
|
44
|
+
price: BigDecimal(o['price']),
|
45
|
+
volume: BigDecimal(o['volume'])
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
{bids: bids, asks: asks, timestamp: Time.at(t['timestamp'].to_i/1000)}
|
50
|
+
end
|
51
|
+
|
52
|
+
def trades(pair)
|
53
|
+
t = self.get('/api/1/trades', {pair: pair})
|
54
|
+
trades = []
|
55
|
+
t['trades'].each do |trade|
|
56
|
+
trades << {
|
57
|
+
timestamp: Time.at(trade['timestamp'].to_i/1000),
|
58
|
+
price: BigDecimal(trade['price']),
|
59
|
+
volume: BigDecimal(trade['volume'])
|
60
|
+
}
|
61
|
+
end
|
62
|
+
trades
|
63
|
+
end
|
64
|
+
|
65
|
+
def get(url, params=nil)
|
66
|
+
r = self.conn.get(url, params)
|
67
|
+
if r.status != 200
|
68
|
+
raise ::BitX::Error.new("BitX error: #{r.status}")
|
69
|
+
end
|
70
|
+
t = JSON.parse r.body
|
71
|
+
if t['error']
|
72
|
+
raise ::BitX::Error.new('BitX error: ' + t['error'])
|
73
|
+
end
|
74
|
+
t
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
data/lib/version.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require "minitest/pride"
|
2
|
+
require "minitest/autorun"
|
3
|
+
require_relative "../lib/bitx.rb"
|
4
|
+
|
5
|
+
module BalanceStubs
|
6
|
+
def self.conn
|
7
|
+
stubs = Faraday::Adapter::Test::Stubs.new do |stub|
|
8
|
+
|
9
|
+
stub.get('/api/1/balance') {[ 200, {},
|
10
|
+
'{
|
11
|
+
"balance": [
|
12
|
+
{
|
13
|
+
"account_id": "1224342323",
|
14
|
+
"asset": "XBT",
|
15
|
+
"balance": "1.012423",
|
16
|
+
"reserved": "0.01",
|
17
|
+
"unconfirmed": "0.421"
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"account_id": "2997473",
|
21
|
+
"asset": "ZAR",
|
22
|
+
"balance": "1000.00",
|
23
|
+
"reserved": "0.00",
|
24
|
+
"unconfirmed": "0.00"
|
25
|
+
}
|
26
|
+
]
|
27
|
+
}']}
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
Faraday.new do |faraday|
|
32
|
+
faraday.adapter :test, stubs
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class TestBalance < Minitest::Test
|
38
|
+
|
39
|
+
def test_balance
|
40
|
+
BitX.set_conn(BalanceStubs.conn)
|
41
|
+
|
42
|
+
r = BitX.balance
|
43
|
+
assert_equal r.first[:reserved], 0.01
|
44
|
+
assert_equal r.first[:available], r.first[:balance] - r.first[:reserved]
|
45
|
+
assert_equal r.first[:unconfirmed], 0.421
|
46
|
+
assert_equal r.first[:asset], 'XBT'
|
47
|
+
assert_equal r.last[:account_id], '2997473'
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_connection_balance
|
51
|
+
r = BitX::Connection.new(BalanceStubs.conn).balance
|
52
|
+
assert_equal r.first[:reserved], 0.01
|
53
|
+
assert_equal r.first[:available], r.first[:balance] - r.first[:reserved]
|
54
|
+
assert_equal r.first[:unconfirmed], 0.421
|
55
|
+
assert_equal r.first[:asset], 'XBT'
|
56
|
+
assert_equal r.last[:account_id], '2997473'
|
57
|
+
end
|
58
|
+
end
|
data/test/order_test.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
require "minitest/pride"
|
2
|
+
require "minitest/autorun"
|
3
|
+
require_relative "../lib/bitx.rb"
|
4
|
+
|
5
|
+
module OrderStubs
|
6
|
+
def self.conn
|
7
|
+
stubs = Faraday::Adapter::Test::Stubs.new do |stub|
|
8
|
+
|
9
|
+
stub.get('/api/1/listorders?pair=XBTZAR') {[ 200, {},
|
10
|
+
'{
|
11
|
+
"orders": [
|
12
|
+
{
|
13
|
+
"fee_counter": "0.00",
|
14
|
+
"order_id": "BXMC2CJ7HNB88U4",
|
15
|
+
"creation_timestamp": 1367849297609,
|
16
|
+
"counter": "0.00",
|
17
|
+
"limit_volume": "0.80",
|
18
|
+
"limit_price": "1000.00",
|
19
|
+
"state": "PENDING",
|
20
|
+
"base": "0.00",
|
21
|
+
"fee_base": "0.00",
|
22
|
+
"type": "ASK",
|
23
|
+
"expiration_timestamp": 1367935697609
|
24
|
+
}
|
25
|
+
]
|
26
|
+
}']}
|
27
|
+
|
28
|
+
|
29
|
+
stub.post('/api/1/postorder', {pair:'XBTZAR', type: 'BID', volume: '0.1', price: '1000.0'}) {[ 200, {},
|
30
|
+
'{
|
31
|
+
"order_id": "BXRANDOMORDERID23"
|
32
|
+
}']}
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
stub.get('/api/1/orders/BXHW6PFRRXKFSB4') {[ 200, {},
|
37
|
+
'{
|
38
|
+
"order_id": "BXHW6PFRRXKFSB4",
|
39
|
+
"creation_timestamp": 1402866878367,
|
40
|
+
"expiration_timestamp": 0,
|
41
|
+
"type": "ASK",
|
42
|
+
"state": "PENDING",
|
43
|
+
"limit_price": "6500.00",
|
44
|
+
"limit_volume": "0.02",
|
45
|
+
"base": "0.00",
|
46
|
+
"counter": "0.00",
|
47
|
+
"fee_base":"0.00",
|
48
|
+
"fee_counter":"0.00"
|
49
|
+
}']}
|
50
|
+
|
51
|
+
stub.post('/api/1/stoporder', {order_id: 'BXMC2CJ7HNB88U4'}) {[ 200, {},
|
52
|
+
'{
|
53
|
+
"success": true
|
54
|
+
}']}
|
55
|
+
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
Faraday.new do |faraday|
|
60
|
+
faraday.adapter :test, stubs
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class TestOrders < Minitest::Test
|
66
|
+
|
67
|
+
def setup_module
|
68
|
+
BitX.set_conn(OrderStubs.conn)
|
69
|
+
end
|
70
|
+
def setup_connection
|
71
|
+
BitX::Connection.new(OrderStubs.conn)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_connection_list
|
75
|
+
r = setup_connection.list_orders('XBTZAR')
|
76
|
+
assert_equal r.size, 1
|
77
|
+
end
|
78
|
+
def test_list
|
79
|
+
setup_module
|
80
|
+
r = BitX.list_orders('XBTZAR')
|
81
|
+
assert_equal r.size, 1
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
def test_connection_post_order
|
86
|
+
r = setup_connection.post_order('BID', 0.1, 1000, 'XBTZAR')
|
87
|
+
assert_equal r[:order_id], 'BXRANDOMORDERID23'
|
88
|
+
end
|
89
|
+
def test_post_order
|
90
|
+
setup_module
|
91
|
+
r = BitX.post_order('BID', 0.1, 1000, 'XBTZAR')
|
92
|
+
assert_equal r[:order_id], 'BXRANDOMORDERID23'
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_connection_get_order
|
96
|
+
r = setup_connection.get_order('BXHW6PFRRXKFSB4')
|
97
|
+
assert_equal r[:order_id], 'BXHW6PFRRXKFSB4'
|
98
|
+
end
|
99
|
+
def test_get_order
|
100
|
+
setup_module
|
101
|
+
r = BitX.get_order('BXHW6PFRRXKFSB4')
|
102
|
+
assert_equal r[:order_id], 'BXHW6PFRRXKFSB4'
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_connection_stop_order
|
106
|
+
r = setup_connection.stop_order('BXMC2CJ7HNB88U4')
|
107
|
+
assert_equal r[:success], true
|
108
|
+
end
|
109
|
+
def test_stop_order
|
110
|
+
setup_module
|
111
|
+
r = BitX.stop_order('BXMC2CJ7HNB88U4')
|
112
|
+
assert_equal r[:success], true
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
end
|
data/test/public_test.rb
ADDED
@@ -0,0 +1,224 @@
|
|
1
|
+
require_relative "../lib/bitx.rb"
|
2
|
+
|
3
|
+
module PublicStubs
|
4
|
+
|
5
|
+
def self.conn
|
6
|
+
stubs = Faraday::Adapter::Test::Stubs.new do |stub|
|
7
|
+
# ticker
|
8
|
+
stub.get('/api/1/ticker?pair=XBTZAR') {[200, {}, '{
|
9
|
+
"ask": "1050.00",
|
10
|
+
"timestamp": 1366224386716,
|
11
|
+
"bid": "924.00",
|
12
|
+
"rolling_24_hour_volume": "12.52",
|
13
|
+
"last_trade": "950.00"
|
14
|
+
}']}
|
15
|
+
stub.get('/api/1/ticker?pair=XBTXRP') {[200, {}, '{
|
16
|
+
"error": "Invalid currency pair.",
|
17
|
+
"error_code": "ErrInvalidPair"
|
18
|
+
}']}
|
19
|
+
stub.get('/api/1/ticker?pair=xbtzar') {[200, {}, '{
|
20
|
+
"error": "Invalid currency pair.",
|
21
|
+
"error_code": "ErrInvalidPair"
|
22
|
+
}']}
|
23
|
+
stub.get('/api/1/ticker?pair=ZARXBT') {[200, {}, '{
|
24
|
+
"error": "Invalid currency pair.",
|
25
|
+
"error_code": "ErrInvalidPair"
|
26
|
+
}']}
|
27
|
+
|
28
|
+
|
29
|
+
# tickers
|
30
|
+
stub.get('/api/1/tickers') {[200, {}, '{
|
31
|
+
"tickers": [
|
32
|
+
{
|
33
|
+
"timestamp": 1405413955793,
|
34
|
+
"bid": "6801.00",
|
35
|
+
"ask": "6900.00",
|
36
|
+
"last_trade": "6900.00",
|
37
|
+
"rolling_24_hour_volume": "12.455579",
|
38
|
+
"pair":"XBTZAR"
|
39
|
+
},
|
40
|
+
{
|
41
|
+
"timestamp": 1405413955337,
|
42
|
+
"bid": "5000.00",
|
43
|
+
"ask":"6968.00",
|
44
|
+
"last_trade": "6830.00",
|
45
|
+
"rolling_24_hour_volume": "0.00",
|
46
|
+
"pair":"XBTNAD"
|
47
|
+
}
|
48
|
+
]
|
49
|
+
}']}
|
50
|
+
|
51
|
+
# orderbook
|
52
|
+
stub.get('/api/1/orderbook?pair=XBTZAR') {[200, {}, '{
|
53
|
+
"asks": [
|
54
|
+
{
|
55
|
+
"volume": "0.10",
|
56
|
+
"price": "1180.00"
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"volume": "0.15",
|
60
|
+
"price": "2000.00"
|
61
|
+
}
|
62
|
+
],
|
63
|
+
"bids": [
|
64
|
+
{
|
65
|
+
"volume": "0.10",
|
66
|
+
"price": "1100.00"
|
67
|
+
},
|
68
|
+
{
|
69
|
+
"volume": "0.10",
|
70
|
+
"price": "1000.00"
|
71
|
+
},
|
72
|
+
{
|
73
|
+
"volume": "0.10",
|
74
|
+
"price": "900.00"
|
75
|
+
}
|
76
|
+
],
|
77
|
+
"timestamp": 1366305398592,
|
78
|
+
"currency": "ZAR"
|
79
|
+
|
80
|
+
}']}
|
81
|
+
|
82
|
+
# trades
|
83
|
+
stub.get('/api/1/trades?pair=XBTZAR') {[200, {}, '{
|
84
|
+
"trades": [
|
85
|
+
{
|
86
|
+
"volume": "0.10",
|
87
|
+
"timestamp": 1366052621774,
|
88
|
+
"price": "1000.00"
|
89
|
+
},
|
90
|
+
{
|
91
|
+
"volume": "1.20",
|
92
|
+
"timestamp": 1366052620770,
|
93
|
+
"price": "1020.50"
|
94
|
+
}
|
95
|
+
]
|
96
|
+
}']}
|
97
|
+
end
|
98
|
+
|
99
|
+
Faraday.new do |faraday|
|
100
|
+
faraday.adapter :test, stubs
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
require "minitest/pride"
|
110
|
+
require "minitest/autorun"
|
111
|
+
|
112
|
+
class TestPublic < Minitest::Test
|
113
|
+
|
114
|
+
def setup_module
|
115
|
+
BitX.set_conn(PublicStubs.conn)
|
116
|
+
end
|
117
|
+
|
118
|
+
def setup_connection
|
119
|
+
BitX::Connection.new(PublicStubs.conn)
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_ticker
|
123
|
+
setup_module
|
124
|
+
ticker = BitX.ticker('XBTZAR')
|
125
|
+
assert_equal ticker[:volume], '12.52'
|
126
|
+
|
127
|
+
err = assert_raises(BitX::Error) {
|
128
|
+
BitX.ticker('XBTXRP')
|
129
|
+
}
|
130
|
+
assert_equal err.message, 'BitX error: Invalid currency pair.'
|
131
|
+
|
132
|
+
err = assert_raises(BitX::Error) {
|
133
|
+
BitX.ticker('xbtzar')
|
134
|
+
}
|
135
|
+
assert_equal err.message, 'BitX error: Invalid currency pair.'
|
136
|
+
|
137
|
+
err = assert_raises(BitX::Error) {
|
138
|
+
BitX.ticker('ZARXBT')
|
139
|
+
}
|
140
|
+
assert_equal err.message, 'BitX error: Invalid currency pair.'
|
141
|
+
end
|
142
|
+
def test_connection_ticker
|
143
|
+
cnx = setup_connection
|
144
|
+
ticker = cnx.ticker('XBTZAR')
|
145
|
+
assert_equal ticker[:volume], '12.52'
|
146
|
+
|
147
|
+
err = assert_raises(BitX::Error) {
|
148
|
+
cnx.ticker('XBTXRP')
|
149
|
+
}
|
150
|
+
assert_equal err.message, 'BitX error: Invalid currency pair.'
|
151
|
+
|
152
|
+
err = assert_raises(BitX::Error) {
|
153
|
+
cnx.ticker('xbtzar')
|
154
|
+
}
|
155
|
+
assert_equal err.message, 'BitX error: Invalid currency pair.'
|
156
|
+
|
157
|
+
err = assert_raises(BitX::Error) {
|
158
|
+
cnx.ticker('ZARXBT')
|
159
|
+
}
|
160
|
+
assert_equal err.message, 'BitX error: Invalid currency pair.'
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_tickers
|
164
|
+
setup_module
|
165
|
+
tickers = BitX.tickers
|
166
|
+
assert_equal tickers.size, 2
|
167
|
+
assert_equal tickers.first[:pair], 'XBTZAR'
|
168
|
+
assert_equal tickers.first[:ask], 6900.00
|
169
|
+
assert_equal tickers.first[:volume], "12.455579"
|
170
|
+
|
171
|
+
assert_equal tickers.last[:volume], "0.00"
|
172
|
+
assert_equal tickers.last[:bid], 5000
|
173
|
+
end
|
174
|
+
def test_connection_tickers
|
175
|
+
tickers = setup_connection.tickers
|
176
|
+
assert_equal tickers.size, 2
|
177
|
+
assert_equal tickers.first[:pair], 'XBTZAR'
|
178
|
+
assert_equal tickers.first[:ask], 6900.00
|
179
|
+
assert_equal tickers.first[:volume], "12.455579"
|
180
|
+
|
181
|
+
assert_equal tickers.last[:volume], "0.00"
|
182
|
+
assert_equal tickers.last[:bid], 5000
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_orderbook
|
186
|
+
setup_module
|
187
|
+
ob = BitX.orderbook('XBTZAR')
|
188
|
+
assert_equal ob[:bids].size, 3
|
189
|
+
assert_equal ob[:bids].first[:price], 1100
|
190
|
+
|
191
|
+
assert_equal ob[:asks].size, 2
|
192
|
+
assert_equal ob[:asks].last[:volume], 0.15
|
193
|
+
assert_equal ob[:timestamp], Time.at(1366305398)
|
194
|
+
end
|
195
|
+
def test_connection_orderbook
|
196
|
+
ob = setup_connection.orderbook('XBTZAR')
|
197
|
+
assert_equal ob[:bids].size, 3
|
198
|
+
assert_equal ob[:bids].first[:price], 1100
|
199
|
+
|
200
|
+
assert_equal ob[:asks].size, 2
|
201
|
+
assert_equal ob[:asks].last[:volume], 0.15
|
202
|
+
assert_equal ob[:timestamp], Time.at(1366305398)
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_trades
|
206
|
+
setup_module
|
207
|
+
trades = BitX.trades('XBTZAR')
|
208
|
+
assert_equal trades.size, 2
|
209
|
+
assert_equal trades.first[:timestamp], Time.at(1366052621)
|
210
|
+
assert_equal trades.last[:volume], 1.2
|
211
|
+
assert_equal trades.last[:price], 1020.5
|
212
|
+
assert_operator trades.first[:timestamp], :>=, trades.last[:timestamp]
|
213
|
+
end
|
214
|
+
def test_connection_trades
|
215
|
+
setup_module
|
216
|
+
trades = setup_connection.trades('XBTZAR')
|
217
|
+
assert_equal trades.size, 2
|
218
|
+
assert_equal trades.first[:timestamp], Time.at(1366052621)
|
219
|
+
assert_equal trades.last[:volume], 1.2
|
220
|
+
assert_equal trades.last[:price], 1020.5
|
221
|
+
assert_operator trades.first[:timestamp], :>=, trades.last[:timestamp]
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|