mtgox 0.8.2 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/README.md +10 -3
- data/bin/btc +5 -0
- data/lib/faraday/response/raise_mtgox_error.rb +4 -0
- data/lib/mtgox/ask.rb +8 -3
- data/lib/mtgox/bid.rb +8 -3
- data/lib/mtgox/client.rb +73 -41
- data/lib/mtgox/connection.rb +1 -1
- data/lib/mtgox/error.rb +2 -1
- data/lib/mtgox/offer.rb +1 -1
- data/lib/mtgox/order.rb +2 -2
- data/lib/mtgox/request.rb +5 -1
- data/lib/mtgox/ticker.rb +1 -1
- data/lib/mtgox/value.rb +53 -0
- data/lib/mtgox/version.rb +2 -2
- data/mtgox.gemspec +2 -0
- data/spec/faraday/response_spec.rb +30 -7
- data/spec/fixtures/address.json +6 -1
- data/spec/fixtures/buy.json +1 -1
- data/spec/fixtures/cancel.json +7 -1
- data/spec/fixtures/depth.json +6785 -1
- data/spec/fixtures/error.json +5 -1
- data/spec/fixtures/info.json +94 -0
- data/spec/fixtures/orders.json +67 -1
- data/spec/fixtures/sell.json +1 -1
- data/spec/fixtures/ticker.json +23 -1
- data/spec/fixtures/trades.json +56 -1
- data/spec/fixtures/unknown_error.json +4 -0
- data/spec/fixtures/withdraw.json +6 -1
- data/spec/helper.rb +15 -10
- data/spec/mtgox/client_spec.rb +86 -95
- metadata +97 -105
- metadata.gz.sig +0 -0
- data/spec/fixtures/balance.json +0 -1
data.tar.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
# Ruby wrapper for the Mt. Gox Trade API
|
2
|
+
|
2
3
|
[![Gem Version](https://badge.fury.io/rb/mtgox.png)][gem]
|
3
4
|
[![Build Status](https://secure.travis-ci.org/sferik/mtgox.png?branch=master)][travis]
|
4
5
|
[![Dependency Status](https://gemnasium.com/sferik/mtgox.png?travis)][gemnasium]
|
6
|
+
[![Code Climate](https://codeclimate.com/github/sferik/mtgox.png)][codeclimate]
|
7
|
+
[![Coverage Status](https://coveralls.io/repos/sferik/mtgox/badge.png?branch=master)][coveralls]
|
5
8
|
|
6
9
|
[gem]: https://rubygems.org/gems/mtgox
|
7
10
|
[travis]: http://travis-ci.org/sferik/mtgox
|
8
11
|
[gemnasium]: https://gemnasium.com/sferik/mtgox
|
12
|
+
[codeclimate]: https://codeclimate.com/github/sferik/mtgox
|
13
|
+
[coveralls]: https://coveralls.io/r/sferik/mtgox
|
9
14
|
|
10
15
|
Mt. Gox allows you to trade US Dollars (USD) for Bitcoins (BTC) or Bitcoins for
|
11
16
|
US Dollars.
|
@@ -23,11 +28,13 @@ Then, install the gem with the high security trust policy:
|
|
23
28
|
|
24
29
|
gem install mtgox -P HighSecurity
|
25
30
|
|
26
|
-
##
|
31
|
+
## Executable
|
27
32
|
After installing the gem, you can get the current price for 1 BTC in USD by
|
28
|
-
typing `btc` in your bash shell
|
33
|
+
typing `btc` in your bash shell:
|
34
|
+
|
35
|
+
$ btc
|
36
|
+
50.00
|
29
37
|
|
30
|
-
alias btc='ruby -r rubygems -r mtgox -e "puts MtGox.ticker.sell"'
|
31
38
|
|
32
39
|
## Documentation
|
33
40
|
[http://rdoc.info/gems/mtgox][documentation]
|
data/bin/btc
ADDED
@@ -5,6 +5,10 @@ module Faraday
|
|
5
5
|
def on_complete(env)
|
6
6
|
if 200 == env[:status] && 'MySQL error, please retry later' == env[:body]
|
7
7
|
raise MtGox::MysqlError, "MySQL error, please retry later"
|
8
|
+
elsif 403 == env[:status] && MultiJson.load(env[:body])["result"] == "error"
|
9
|
+
raise MtGox::UnauthorizedError, MultiJson.load(env[:body])["error"]
|
10
|
+
elsif 404 != env[:status] && MultiJson.load(env[:body])["result"] == "error"
|
11
|
+
raise MtGox::Error, MultiJson.load(env[:body])["error"]
|
8
12
|
end
|
9
13
|
end
|
10
14
|
end
|
data/lib/mtgox/ask.rb
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
require 'mtgox/offer'
|
2
|
+
require 'mtgox/value'
|
2
3
|
|
3
4
|
module MtGox
|
4
5
|
class Ask < Offer
|
6
|
+
include MtGox::Value
|
5
7
|
|
6
|
-
def initialize(
|
7
|
-
|
8
|
-
|
8
|
+
def initialize(hash = nil)
|
9
|
+
if hash
|
10
|
+
self.price = value_currency hash, 'price_int'
|
11
|
+
self.amount = value_bitcoin hash, 'amount_int'
|
12
|
+
self.timestamp = hash['stamp']
|
13
|
+
end
|
9
14
|
end
|
10
15
|
|
11
16
|
def eprice
|
data/lib/mtgox/bid.rb
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
require 'mtgox/offer'
|
2
|
+
require 'mtgox/value'
|
2
3
|
|
3
4
|
module MtGox
|
4
5
|
class Bid < Offer
|
6
|
+
include MtGox::Value
|
5
7
|
|
6
|
-
def initialize(
|
7
|
-
|
8
|
-
|
8
|
+
def initialize(hash = nil)
|
9
|
+
if hash
|
10
|
+
self.price = value_currency hash, 'price_int'
|
11
|
+
self.amount = value_bitcoin hash, 'amount_int'
|
12
|
+
self.timestamp = hash['stamp']
|
13
|
+
end
|
9
14
|
end
|
10
15
|
|
11
16
|
def eprice
|
data/lib/mtgox/client.rb
CHANGED
@@ -10,13 +10,15 @@ require 'mtgox/request'
|
|
10
10
|
require 'mtgox/sell'
|
11
11
|
require 'mtgox/ticker'
|
12
12
|
require 'mtgox/trade'
|
13
|
+
require 'mtgox/value'
|
13
14
|
|
14
15
|
module MtGox
|
15
16
|
class Client
|
16
17
|
include MtGox::Connection
|
17
18
|
include MtGox::Request
|
19
|
+
include MtGox::Value
|
18
20
|
|
19
|
-
ORDER_TYPES = {sell:
|
21
|
+
ORDER_TYPES = {sell: "ask", buy: "bid"}
|
20
22
|
|
21
23
|
# Fetch a deposit address
|
22
24
|
# @authenticated true
|
@@ -24,7 +26,7 @@ module MtGox
|
|
24
26
|
# @example
|
25
27
|
# MtGox.address
|
26
28
|
def address
|
27
|
-
post('/api/
|
29
|
+
post('/api/1/generic/bitcoin/address')['addr']
|
28
30
|
end
|
29
31
|
|
30
32
|
|
@@ -35,14 +37,15 @@ module MtGox
|
|
35
37
|
# @example
|
36
38
|
# MtGox.ticker
|
37
39
|
def ticker
|
38
|
-
ticker = get('/api/
|
39
|
-
Ticker.instance.buy = ticker['buy']
|
40
|
-
Ticker.instance.high = ticker['high']
|
41
|
-
Ticker.instance.price = ticker['
|
42
|
-
Ticker.instance.low = ticker['low']
|
43
|
-
Ticker.instance.sell = ticker['sell']
|
44
|
-
Ticker.instance.volume = ticker['vol']
|
45
|
-
Ticker.instance.vwap = ticker['vwap']
|
40
|
+
ticker = get('/api/1/BTCUSD/ticker')
|
41
|
+
Ticker.instance.buy = value_currency ticker['buy']
|
42
|
+
Ticker.instance.high = value_currency ticker['high']
|
43
|
+
Ticker.instance.price = value_currency ticker['last_all']
|
44
|
+
Ticker.instance.low = value_currency ticker['low']
|
45
|
+
Ticker.instance.sell = value_currency ticker['sell']
|
46
|
+
Ticker.instance.volume = value_bitcoin ticker['vol']
|
47
|
+
Ticker.instance.vwap = value_currency ticker['vwap']
|
48
|
+
Ticker.instance.avg = value_currency ticker['avg']
|
46
49
|
Ticker.instance
|
47
50
|
end
|
48
51
|
|
@@ -53,16 +56,16 @@ module MtGox
|
|
53
56
|
# @example
|
54
57
|
# MtGox.offers
|
55
58
|
def offers
|
56
|
-
offers = get('/api/
|
59
|
+
offers = get('/api/1/BTCUSD/depth/fetch')
|
57
60
|
asks = offers['asks'].sort_by do |ask|
|
58
|
-
ask[
|
61
|
+
ask['price_int'].to_i
|
59
62
|
end.map! do |ask|
|
60
|
-
Ask.new(
|
63
|
+
Ask.new(ask)
|
61
64
|
end
|
62
65
|
bids = offers['bids'].sort_by do |bid|
|
63
|
-
-bid[
|
66
|
+
-bid['price_int'].to_i
|
64
67
|
end.map! do |bid|
|
65
|
-
Bid.new(
|
68
|
+
Bid.new(bid)
|
66
69
|
end
|
67
70
|
{asks: asks, bids: bids}
|
68
71
|
end
|
@@ -120,7 +123,7 @@ module MtGox
|
|
120
123
|
# @example
|
121
124
|
# MtGox.trades
|
122
125
|
def trades
|
123
|
-
get('/api/
|
126
|
+
get('/api/1/BTCUSD/trades/fetch').sort_by{|trade| trade['date']}.map do |trade|
|
124
127
|
Trade.new(trade)
|
125
128
|
end
|
126
129
|
end
|
@@ -132,7 +135,7 @@ module MtGox
|
|
132
135
|
# @example
|
133
136
|
# MtGox.balance
|
134
137
|
def balance
|
135
|
-
parse_balance(post('/api/
|
138
|
+
parse_balance(post('/api/1/generic/info', {}))
|
136
139
|
end
|
137
140
|
|
138
141
|
# Fetch your open orders, both buys and sells, for network efficiency
|
@@ -142,7 +145,7 @@ module MtGox
|
|
142
145
|
# @example
|
143
146
|
# MtGox.orders
|
144
147
|
def orders
|
145
|
-
parse_orders
|
148
|
+
parse_orders post('/api/1/generic/orders', {})
|
146
149
|
end
|
147
150
|
|
148
151
|
# Fetch your open buys
|
@@ -170,12 +173,12 @@ module MtGox
|
|
170
173
|
# @authenticated true
|
171
174
|
# @param amount [Numeric] the number of bitcoins to purchase
|
172
175
|
# @param price [Numeric] the bid price in US dollars
|
173
|
-
# @return [
|
176
|
+
# @return [String] order ID for the buy, can be inspected using order_result
|
174
177
|
# @example
|
175
178
|
# # Buy one bitcoin for $0.011
|
176
179
|
# MtGox.buy! 1.0, 0.011
|
177
180
|
def buy!(amount, price)
|
178
|
-
|
181
|
+
addorder!(:buy, amount, price)
|
179
182
|
end
|
180
183
|
|
181
184
|
# Place a limit order to sell BTC
|
@@ -183,12 +186,26 @@ module MtGox
|
|
183
186
|
# @authenticated true
|
184
187
|
# @param amount [Numeric] the number of bitcoins to sell
|
185
188
|
# @param price [Numeric] the ask price in US dollars
|
186
|
-
# @return [
|
189
|
+
# @return [String] order ID for the sell, can be inspected using order_result
|
187
190
|
# @example
|
188
191
|
# # Sell one bitcoin for $100
|
189
192
|
# MtGox.sell! 1.0, 100.0
|
190
193
|
def sell!(amount, price)
|
191
|
-
|
194
|
+
addorder!(:sell, amount, price)
|
195
|
+
end
|
196
|
+
|
197
|
+
# Create a new order
|
198
|
+
#
|
199
|
+
# @authenticated true
|
200
|
+
# @param type [String] the type of order to create, either "buy" or "sell"
|
201
|
+
# @param amount [Numberic] the number of bitcoins to buy/sell
|
202
|
+
# @param price [Numeric] the bid/ask price in USD
|
203
|
+
# @return [String] order ID for the order, can be inspected using order_result
|
204
|
+
# @example
|
205
|
+
# # Sell one bitcoin for $123
|
206
|
+
# MtGox.addorder! :sell, 1.0, 123.0
|
207
|
+
def addorder!(type, amount, price)
|
208
|
+
post('/api/1/BTCUSD/order/add', {type: order_type(type), amount_int: intify(amount,:btc), price_int: intify(price, :usd)})
|
192
209
|
end
|
193
210
|
|
194
211
|
# Cancel an open order
|
@@ -202,25 +219,25 @@ module MtGox
|
|
202
219
|
# MtGox.cancel my_order.oid
|
203
220
|
# MtGox.cancel 1234567890
|
204
221
|
# @overload cancel(order)
|
205
|
-
# @param order [Hash] a hash-like object,
|
222
|
+
# @param order [Hash] a hash-like object, containing at least a key `oid` - the order ID of the transaction to cancel
|
206
223
|
# @return [Hash] with keys :buys and :sells, which contain arrays as described in {MtGox::Client#buys} and {MtGox::Clients#sells}
|
207
224
|
# @example
|
208
225
|
# my_order = MtGox.orders.first
|
209
226
|
# MtGox.cancel my_order
|
210
|
-
# MtGox.cancel {'oid' => '1234567890'
|
227
|
+
# MtGox.cancel {'oid' => '1234567890'}
|
211
228
|
def cancel(args)
|
212
229
|
if args.is_a?(Hash)
|
213
|
-
|
214
|
-
|
230
|
+
args = args['oid']
|
231
|
+
end
|
232
|
+
|
233
|
+
orders = post('/api/1/generic/orders', {})
|
234
|
+
order = orders.find{|order| order['oid'] == args.to_s}
|
235
|
+
if order
|
236
|
+
res = post('/api/1/BTCUSD/order/cancel', {oid: order['oid']})
|
237
|
+
orders.delete_if { |o| o['oid'] == res['oid'] }
|
238
|
+
parse_orders(orders)
|
215
239
|
else
|
216
|
-
|
217
|
-
order = orders.find{|order| order['oid'] == args.to_s}
|
218
|
-
if order
|
219
|
-
order = order.delete_if{|k, v| !['oid', 'type'].include?(k.to_s)}
|
220
|
-
parse_orders(post('/api/0/cancelOrder.php', order)['orders'])
|
221
|
-
else
|
222
|
-
raise Faraday::Error::ResourceNotFound, {status: 404, headers: {}, body: 'Order not found.'}
|
223
|
-
end
|
240
|
+
raise Faraday::Error::ResourceNotFound, {status: 404, headers: {}, body: 'Order not found.'}
|
224
241
|
end
|
225
242
|
end
|
226
243
|
|
@@ -228,21 +245,28 @@ module MtGox
|
|
228
245
|
#
|
229
246
|
# @authenticated true
|
230
247
|
# @param amount [Numeric] the number of bitcoins to withdraw
|
231
|
-
# @param
|
232
|
-
# @return [
|
248
|
+
# @param address [String] the bitcoin address to send to
|
249
|
+
# @return [String] Completed Transaction ID
|
233
250
|
# @example
|
234
251
|
# # Withdraw 1 BTC from your account
|
235
252
|
# MtGox.withdraw! 1.0, '1KxSo9bGBfPVFEtWNLpnUK1bfLNNT4q31L'
|
236
|
-
def withdraw!(amount,
|
237
|
-
|
253
|
+
def withdraw!(amount, address)
|
254
|
+
if amount >= 1000
|
255
|
+
raise FilthyRichError,
|
256
|
+
"#withdraw! take bitcoin amount as parameter (you are trying to withdraw #{amount} BTC"
|
257
|
+
else
|
258
|
+
post('/api/1/generic/bitcoin/send_simple', {amount_int: intify(amount, :btc), address: address})['trx']
|
259
|
+
end
|
238
260
|
end
|
239
261
|
|
240
262
|
private
|
241
263
|
|
242
|
-
def parse_balance(
|
264
|
+
def parse_balance(info)
|
243
265
|
balances = []
|
244
|
-
|
245
|
-
|
266
|
+
info['Wallets'].each do |currency, wallet|
|
267
|
+
value = currency == "BTC" ? value_bitcoin(wallet['Balance']) : value_currency(wallet['Balance'])
|
268
|
+
balances << Balance.new(currency, value)
|
269
|
+
end
|
246
270
|
balances
|
247
271
|
end
|
248
272
|
|
@@ -259,5 +283,13 @@ module MtGox
|
|
259
283
|
end
|
260
284
|
{buys: buys, sells: sells}
|
261
285
|
end
|
286
|
+
|
287
|
+
def order_type(type)
|
288
|
+
unless ["bid", "ask"].include?(type.to_s)
|
289
|
+
ORDER_TYPES[type.downcase.to_sym]
|
290
|
+
else
|
291
|
+
type
|
292
|
+
end
|
293
|
+
end
|
262
294
|
end
|
263
295
|
end
|
data/lib/mtgox/connection.rb
CHANGED
data/lib/mtgox/error.rb
CHANGED
data/lib/mtgox/offer.rb
CHANGED
data/lib/mtgox/order.rb
CHANGED
@@ -7,8 +7,8 @@ module MtGox
|
|
7
7
|
def initialize(order={})
|
8
8
|
self.id = order['oid']
|
9
9
|
self.date = Time.at(order['date'].to_i)
|
10
|
-
self.amount = order['amount'].to_f
|
11
|
-
self.price = order['price'].to_f
|
10
|
+
self.amount = order['amount']['value'].to_f
|
11
|
+
self.price = order['price']['value'].to_f
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
data/lib/mtgox/request.rb
CHANGED
data/lib/mtgox/ticker.rb
CHANGED
data/lib/mtgox/value.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# In the "old API", currency- and amount-values (price, volume,...)
|
2
|
+
# were given as float. These values are likely being deprecated and
|
3
|
+
# replaced by fields of the same name with "_int" as suffix. These are
|
4
|
+
# fixed-decimal, so you have to move the decimal point yourself
|
5
|
+
# (divide). The exponent differs based on the kind of the value.
|
6
|
+
|
7
|
+
module MtGox
|
8
|
+
module Value
|
9
|
+
# We assume here that any other currency than :jpy uses :usd
|
10
|
+
INT_MULTIPLIERS = {btc: 100000000, usd: 100000, jpy: 1000}
|
11
|
+
|
12
|
+
# Takes a hash return by the API and convert some value_int to a
|
13
|
+
# currency value using USD conversion rule. You can specify which
|
14
|
+
# key to convert
|
15
|
+
#
|
16
|
+
# @param value [Hash] a hash from the API
|
17
|
+
# params key [String] the key from the previous hash to convert, default to 'value_int'
|
18
|
+
# @authenticated false
|
19
|
+
# @return [Float]
|
20
|
+
def value_currency(value, key = 'value_int')
|
21
|
+
floatify(value[key].to_i, :usd)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Takes a hash return by the API and convert some value_int to
|
25
|
+
# [Float] BitCoin value . You can specify which key to convert
|
26
|
+
#
|
27
|
+
# @param value [Hash] a hash from the API
|
28
|
+
# params key [String] the key from the previous hash to convert, default to 'value_int'
|
29
|
+
# @authenticated false
|
30
|
+
# @return [Float] a float BTC value
|
31
|
+
def value_bitcoin(value, key = 'value_int')
|
32
|
+
floatify(value[key], :btc)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Convert a float value to an int using the MtGox conversion rules.
|
36
|
+
#
|
37
|
+
# param float [Float] to convert
|
38
|
+
# param currency [Symbol] currency conversion rule to use amongst [:btc, :usd, :jpy]
|
39
|
+
# return an int
|
40
|
+
def intify(float, currency)
|
41
|
+
(float * INT_MULTIPLIERS[currency]).to_i
|
42
|
+
end
|
43
|
+
|
44
|
+
# Convert an int value to a float using the MtGox conversion rules.
|
45
|
+
#
|
46
|
+
# param int [Fixnum] to convert
|
47
|
+
# param currency [Symbol] currency conversion rule to use amongst [:btc, :usd, :jpy]
|
48
|
+
# return a [Float]
|
49
|
+
def floatify(int, currency)
|
50
|
+
(int.to_f / INT_MULTIPLIERS[currency])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|