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 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
- ## Alias
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 simply by setting the following alias:
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
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'mtgox'
4
+
5
+ puts MtGox.ticker.sell
@@ -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
@@ -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(price=nil, amount=nil)
7
- self.price = price.to_f
8
- self.amount = amount.to_f
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
@@ -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(price=nil, amount=nil)
7
- self.price = price.to_f
8
- self.amount = amount.to_f
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
@@ -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: 1, buy: 2}
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/0/btcAddress.php')['addr']
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/0/data/ticker.php')['ticker']
39
- Ticker.instance.buy = ticker['buy'].to_f
40
- Ticker.instance.high = ticker['high'].to_f
41
- Ticker.instance.price = ticker['last'].to_f
42
- Ticker.instance.low = ticker['low'].to_f
43
- Ticker.instance.sell = ticker['sell'].to_f
44
- Ticker.instance.volume = ticker['vol'].to_f
45
- Ticker.instance.vwap = ticker['vwap'].to_f
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/0/data/getDepth.php')
59
+ offers = get('/api/1/BTCUSD/depth/fetch')
57
60
  asks = offers['asks'].sort_by do |ask|
58
- ask[0].to_f
61
+ ask['price_int'].to_i
59
62
  end.map! do |ask|
60
- Ask.new(*ask)
63
+ Ask.new(ask)
61
64
  end
62
65
  bids = offers['bids'].sort_by do |bid|
63
- -bid[0].to_f
66
+ -bid['price_int'].to_i
64
67
  end.map! do |bid|
65
- Bid.new(*bid)
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/0/data/getTrades.php').sort_by{|trade| trade['date']}.map do |trade|
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/0/getFunds.php', {}))
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(post('/api/0/getOrders.php', {})['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 [Hash] with keys :buys and :sells, which contain arrays as described in {MtGox::Client#buys} and {MtGox::Clients#sells}
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
- parse_orders(post('/api/0/buyBTC.php', {amount: amount, price: price})['orders'])
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 [Hash] with keys :buys and :sells, which contain arrays as described in {MtGox::Client#buys} and {MtGox::Clients#sells}
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
- parse_orders(post('/api/0/sellBTC.php', {amount: amount, price: price})['orders'])
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, with keys `oid` - the order ID of the transaction to cancel and `type` - the type of order to cancel (`1` for sell or `2` for buy)
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', 'type' => 2}
227
+ # MtGox.cancel {'oid' => '1234567890'}
211
228
  def cancel(args)
212
229
  if args.is_a?(Hash)
213
- order = args.delete_if{|k, v| !['oid', 'type'].include?(k.to_s)}
214
- parse_orders(post('/api/0/cancelOrder.php', order)['orders'])
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
- orders = post('/api/0/getOrders.php', {})['orders']
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 btca [String] the bitcoin address to send to
232
- # @return [Array<MtGox::Balance>]
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, btca)
237
- parse_balance(post('/api/0/withdraw.php', {group1: 'BTC', amount: amount, btca: btca}))
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(balance)
264
+ def parse_balance(info)
243
265
  balances = []
244
- balances << Balance.new('BTC', balance['btcs'])
245
- balances << Balance.new('USD', balance['usds'])
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
@@ -15,7 +15,7 @@ module MtGox
15
15
  accept: 'application/json',
16
16
  user_agent: "mtgox gem #{MtGox::Version}",
17
17
  },
18
- url: 'https://mtgox.com',
18
+ url: 'https://data.mtgox.com',
19
19
  }
20
20
 
21
21
  Faraday.new(options) do |connection|
@@ -1,7 +1,8 @@
1
1
  module MtGox
2
2
  # Custom error class for rescuing from all MtGox errors
3
3
  class Error < StandardError; end
4
-
5
4
  class MysqlError < Error; end
5
+ class UnauthorizedError < Error; end
6
+ class FilthyRichError < Error; end
6
7
  end
7
8
 
@@ -1,5 +1,5 @@
1
1
  module MtGox
2
2
  class Offer
3
- attr_accessor :amount, :price
3
+ attr_accessor :amount, :price, :timestamp
4
4
  end
5
5
  end
@@ -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
@@ -23,7 +23,11 @@ module MtGox
23
23
  request.headers = headers(request.body)
24
24
  end
25
25
  end
26
- response.body
26
+ if response.body['result'] && response.body['result'] == 'success'
27
+ response.body['return']
28
+ else
29
+ response.body
30
+ end
27
31
  end
28
32
 
29
33
  def headers(request)
@@ -5,6 +5,6 @@ module MtGox
5
5
  class Ticker
6
6
  include Singleton
7
7
  include PriceTicker
8
- attr_accessor :buy, :sell, :high, :low, :volume, :vwap
8
+ attr_accessor :buy, :sell, :high, :low, :volume, :vwap, :avg
9
9
  end
10
10
  end
@@ -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
@@ -8,12 +8,12 @@ module MtGox
8
8
 
9
9
  # @return [Integer]
10
10
  def self.minor
11
- 8
11
+ 9
12
12
  end
13
13
 
14
14
  # @return [Integer]
15
15
  def self.patch
16
- 2
16
+ 0
17
17
  end
18
18
 
19
19
  # @return [String, NilClass]