itbit 0.0.1

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.
@@ -0,0 +1,3 @@
1
+ .DS_Store
2
+ *.swp
3
+ *.swo
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in itbit.gemspec
4
+ gemspec
@@ -0,0 +1,70 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ itbit (0.0.1)
5
+ activesupport
6
+ rest_client
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (4.1.2)
12
+ i18n (~> 0.6, >= 0.6.9)
13
+ json (~> 1.7, >= 1.7.7)
14
+ minitest (~> 5.1)
15
+ thread_safe (~> 0.1)
16
+ tzinfo (~> 1.1)
17
+ addressable (2.3.6)
18
+ columnize (0.8.9)
19
+ crack (0.4.2)
20
+ safe_yaml (~> 1.0.0)
21
+ debugger (1.6.8)
22
+ columnize (>= 0.3.1)
23
+ debugger-linecache (~> 1.2.0)
24
+ debugger-ruby_core_source (~> 1.3.5)
25
+ debugger-linecache (1.2.0)
26
+ debugger-ruby_core_source (1.3.5)
27
+ diff-lcs (1.2.5)
28
+ i18n (0.6.9)
29
+ json (1.8.1)
30
+ minitest (5.3.5)
31
+ netrc (0.7.9)
32
+ rake (10.3.2)
33
+ rest_client (1.8.1)
34
+ netrc (~> 0.7.7)
35
+ rspec (3.0.0)
36
+ rspec-core (~> 3.0.0)
37
+ rspec-expectations (~> 3.0.0)
38
+ rspec-mocks (~> 3.0.0)
39
+ rspec-core (3.0.2)
40
+ rspec-support (~> 3.0.0)
41
+ rspec-expectations (3.0.2)
42
+ diff-lcs (>= 1.2.0, < 2.0)
43
+ rspec-support (~> 3.0.0)
44
+ rspec-mocks (3.0.2)
45
+ rspec-support (~> 3.0.0)
46
+ rspec-support (3.0.2)
47
+ safe_yaml (1.0.3)
48
+ shoulda-matchers (2.6.1)
49
+ activesupport (>= 3.0.0)
50
+ thread_safe (0.3.4)
51
+ timecop (0.7.1)
52
+ tzinfo (1.2.1)
53
+ thread_safe (~> 0.1)
54
+ webmock (1.18.0)
55
+ addressable (>= 2.3.6)
56
+ crack (>= 0.3.2)
57
+
58
+ PLATFORMS
59
+ ruby
60
+
61
+ DEPENDENCIES
62
+ bundler (~> 1.3)
63
+ debugger
64
+ itbit!
65
+ rake
66
+ rspec
67
+ rspec-mocks
68
+ shoulda-matchers
69
+ timecop
70
+ webmock
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Nubis
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,146 @@
1
+ # ItBit
2
+
3
+ [ItBit](https://www.itbit.com) API Client library.
4
+
5
+ Does some minimal type de-serializations from stringified numbers into
6
+ BigDecimals, camelcased strings into underscored symbols, and times into integer
7
+ timestamps.
8
+
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'itbit'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install itbit
23
+
24
+
25
+ ## Use Public Market Data
26
+
27
+ Itbit::XBTUSDMarketData, Itbit::XBTSGDMarketData, Itbit::XBTEURMarketData classes have methods for
28
+ fetching all public market data available.
29
+
30
+ ### Ticker
31
+
32
+ ruby > Itbit::XBTUSDMarketData.ticker
33
+ => {ask: 641.29,
34
+ ask_amt: 0.5,
35
+ bid: 622,
36
+ bid_amt: 0.0006,
37
+ high24h: 618.00000000,
38
+ high_today: 618.00000000,
39
+ last_amt: 0.00040000,
40
+ last_price: 618.00000000,
41
+ low24h: 618.00000000,
42
+ low_today: 618.00000000,
43
+ open_today: 618.00000000,
44
+ pair: symbol.to_s.upcase,
45
+ servertime_utc: 2014-06-24 20:42:35,
46
+ volume24h: 0.00040000,
47
+ volume_today: 0.00040000,
48
+ vwap24h: 618.00000000,
49
+ vwap_today: 618.00000000
50
+ }
51
+
52
+ ### Order Book
53
+
54
+ ruby > Itbit::XBTUSDMarketData.orders
55
+ => {bids: [[632.0, 38.910443037975], [630.87, 1.8], ...],
56
+ asks: [[634.9, 0.95], [648.0, 0.4809267], ...]}
57
+
58
+ ### Trades
59
+
60
+ ruby > Itbit::XBTUSDMarketData.transactions
61
+ => [ {date: unix_timestamp, price: 123.5, amount: 1.97, tid: 98375},
62
+ {date: unix_timestamp, price: 123.5, amount: 1.97, tid: 98376},
63
+ ...]
64
+
65
+ ## Use for Private Trading
66
+
67
+ ### Authentication and default wallet
68
+ You should request your credentials to api@itbit.com, once you've got them
69
+ you can configure the gem like this:
70
+
71
+ Itbit.client_key = 'your_client_key'
72
+ Itbit.secret = 'your_secret_key'
73
+ Itbit.user_id = 'your_user_id'
74
+
75
+ You can point the gem to itbit's sandbox like this:
76
+
77
+ Itbit.sandbox = true
78
+
79
+ Itbit gives you more than one 'wallet', which is a set of btc, usd, eur and sgd
80
+ balances to use. Most of the time you'll probably end up using just one wallet,
81
+ which can be configured like this:
82
+
83
+ Itbit.default_wallet_id = 'the-wallet-id-you-want-to-use'
84
+
85
+ All api calls that need a wallet accept one as an optional argument as well.
86
+
87
+ ### Get your wallets
88
+
89
+ ruby > Itbit::Wallet.all
90
+ => { id: "3F2504E0-4F89-41D3-9A0C-0305E82C3301",
91
+ name: "Wallet",
92
+ balances: [
93
+ { balance: "10203.25",
94
+ currency_code: :usd,
95
+ trading_balance: "10003.25"
96
+ },
97
+ { balance: "402.110",
98
+ currency_code: :xbt,
99
+ trading_balance: "402.110"
100
+ },
101
+ { balance: "0.00",
102
+ currency_code: :eur,
103
+ trading_balance: "0.00"
104
+ }
105
+ ]
106
+ }
107
+
108
+ ### Create a new wallet
109
+
110
+ ruby > Itbit::Wallet.create!('wallet_name')
111
+
112
+ ### Place Bids and Asks
113
+ You can also pass in a has of keyword arguments at the end, for
114
+ sending metadata and your own order identifiers (which must be unique)
115
+ Check the spec/order_spec.rb for more examples.
116
+
117
+ ruby > Itbit::Order.create!(:buy, :xbtusd, 1.5, 500.0)
118
+ ruby > Itbit::Order.create!(:sell, :xbtsgd, 1.5, 500.0)
119
+
120
+ ### List your pending or recently active orders
121
+ Orders can also be filtered and paginated by passing in keyword arguments,
122
+ Check spec/order_spec.rb for more examples.
123
+
124
+ ruby > Itbit::Order.all
125
+
126
+ ### Find an order
127
+
128
+ ruby > Itbit::Order.find('some-order-id')
129
+
130
+ ### Cancel an order
131
+
132
+ ruby > Itbit::Order.find('some-order-id').cancel!
133
+
134
+ ### List your trades
135
+ Trades can also be filtered by date and paginated by passing in keyword arguments,
136
+ Check spec/trade_spec.rb for more examples.
137
+
138
+ ruby > Itbit::Trade.all
139
+
140
+ ## Contributing
141
+
142
+ 1. Fork it
143
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
144
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
145
+ 4. Push to the branch (`git push origin my-new-feature`)
146
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'itbit/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "itbit"
8
+ spec.version = Itbit::VERSION
9
+ spec.authors = ["Nubis", "Eromirou"]
10
+ spec.email = ["nb@bitex.la", "tr@bitex.la"]
11
+ spec.description = %q{API client library for itbit.com. Fetch public market
12
+ data and build trading robots}
13
+ spec.summary = "API client library for itbit.com"
14
+ spec.homepage = "http://github.com/bitex-la/itbit"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "activesupport"
23
+ spec.add_dependency "rest_client"
24
+
25
+ spec.required_ruby_version = '>= 1.9.3'
26
+ spec.add_development_dependency "bundler", "~> 1.3"
27
+ spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "rspec"
29
+ spec.add_development_dependency "rspec-mocks"
30
+ spec.add_development_dependency "timecop"
31
+ spec.add_development_dependency "webmock"
32
+ spec.add_development_dependency "shoulda-matchers"
33
+ end
@@ -0,0 +1,16 @@
1
+ require 'active_support/core_ext'
2
+ require 'json'
3
+ require 'rest_client'
4
+ require 'bigdecimal'
5
+ require 'active_support'
6
+ require 'digest/sha2'
7
+ require 'base64'
8
+ Dir[File.expand_path("../itbit/*.rb", __FILE__)].each {|f| require f}
9
+
10
+ module Itbit
11
+ mattr_accessor :client_key
12
+ mattr_accessor :secret
13
+ mattr_accessor :user_id
14
+ mattr_accessor :default_wallet_id
15
+ mattr_accessor :sandbox
16
+ end
@@ -0,0 +1,33 @@
1
+ require 'rest_client'
2
+
3
+ module Itbit
4
+ class ApiError < StandardError; end
5
+ class Api
6
+ def self.request(verb, path, options = { })
7
+ timestamp = (Time.now.to_f * 1000).round.to_s
8
+ nonce = timestamp
9
+ prefix = Itbit.sandbox ? 'beta-api' : 'api'
10
+ payload = options.empty? || verb == :get ? nil : JSON.dump(options)
11
+ query = options.any? && verb == :get ? "?#{options.to_query}" : ''
12
+ url = "https://#{prefix}.itbit.com/v1#{path}#{query}"
13
+
14
+ signature = sign_message(verb, url, payload, nonce, timestamp)
15
+ headers = {
16
+ authorization: "#{Itbit.client_key}:#{signature}",
17
+ x_auth_timestamp: timestamp,
18
+ x_auth_nonce: nonce,
19
+ content_type: 'application/json'
20
+ }
21
+ response = RestClient::Request
22
+ .execute(:method => verb, :url => url, :payload => payload, :headers => headers)
23
+ JSON.parse(response.to_str) if response.to_str.presence
24
+ end
25
+
26
+ def self.sign_message(verb, url, json_body, nonce, timestamp)
27
+ message = JSON.dump([verb.upcase, url, json_body || '', nonce, timestamp])
28
+ hash_digest = OpenSSL::Digest::SHA256.digest(nonce + message)
29
+ hmac_digest = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA512.new, Itbit.secret, url + hash_digest)
30
+ Base64.strict_encode64(hmac_digest)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,70 @@
1
+ module Itbit
2
+ # Public market data for a pair, do not use directly, use
3
+ # {XBTUSDMarketData}, {XBTSGDMarketData} and {XBTEURMarketData} instead.
4
+ # @see http://api-portal.anypoint.mulesoft.com/itbit/api/itbit-exchange#raml-console
5
+ class MarketData
6
+
7
+ # The symbol ticker conveniently formatted as a ruby Hash with
8
+ # symbolized keys.
9
+ def self.ticker
10
+ raw_ticker = Api.request(:get, "/markets/#{self.symbol}/ticker")
11
+ raw_ticker.reduce({}) do |ticker, pair|
12
+ key = pair.first.underscore.to_sym
13
+ value = case key
14
+ when :pair then pair[1].underscore.to_sym
15
+ when :servertime_utc then Time.parse(pair[1]).to_i
16
+ else pair[1].to_d
17
+ end
18
+ ticker[key] = value
19
+ ticker
20
+ end
21
+ end
22
+
23
+ # The symbol order book as a Hash with two keys: bids and asks.
24
+ # Each of them is a list of list consisting of [price, quantity]
25
+ def self.orders
26
+ order_book = old_request("/markets/#{self.symbol.upcase}/orders").symbolize_keys
27
+ order_book.each do |key, value|
28
+ order_book[key] = value.collect { |tuple| tuple.collect(&:to_d) }
29
+ end
30
+ end
31
+
32
+ # The symbol trades since tid (transaction id) as a list of hashes
33
+ # that look like {date: unix_timestamp, price: 123.5, amount: 1.97, tid: 98375}
34
+ def self.trades(tid = 0)
35
+ trades = old_request("/markets/#{symbol.upcase}/trades", since: tid)
36
+ trades.collect do |t|
37
+ t.merge(price: t['price'].to_d, amount: t['amount'].to_d)
38
+ .with_indifferent_access
39
+ end
40
+ end
41
+
42
+ # @visibility private
43
+ def self.old_request(path, options = { })
44
+ url = "https://www.itbit.com/api/v2#{path}"
45
+ url << "?#{options.to_query}" if options.any?
46
+ JSON.parse(RestClient.get(url))
47
+ end
48
+ end
49
+
50
+ # A {MarketData} for the Bitcoin-USD pair.
51
+ class XBTUSDMarketData < MarketData
52
+ def self.symbol
53
+ 'xbtusd'
54
+ end
55
+ end
56
+
57
+ # A {MarketData} for the Bitcoin-SGD pair.
58
+ class XBTSGDMarketData < MarketData
59
+ def self.symbol
60
+ 'xbtsgd'
61
+ end
62
+ end
63
+
64
+ # A {MarketData} for the Bitcoin-EUR pair.
65
+ class XBTEURMarketData < MarketData
66
+ def self.symbol
67
+ 'xbteur'
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,113 @@
1
+ module Itbit
2
+ # A limit buy or sell order, translated from itbit api to a more
3
+ # suitable ruby style. Field names are underscored. Values
4
+ # for side, instrument, currency, type and status are
5
+ # underscored and symbolized.
6
+ class Order
7
+ attr_accessor :id, :wallet_id, :side, :instrument,
8
+ :currency, :type, :amount, :price, :amount_filled,
9
+ :volume_weighted_average_price, :created_time, :status,
10
+ :display_amount, :metadata, :client_order_identifier
11
+
12
+ def initialize(attrs)
13
+ attrs.each{|k, v| send("#{k.underscore}=", v)}
14
+ end
15
+
16
+ %w(side instrument currency type status).each do |attr|
17
+ define_method("#{attr}=") do |value|
18
+ instance_variable_set("@#{attr}", value.to_s.underscore.to_sym)
19
+ end
20
+ end
21
+
22
+ %w(amount price amount_filled volume_weighted_average_price
23
+ display_amount).each do |attr|
24
+ define_method("#{attr}=") do |value|
25
+ instance_variable_set("@#{attr}", value.to_d)
26
+ end
27
+ end
28
+
29
+ def created_time=(value)
30
+ @created_time = value.is_a?(String) ? Time.parse(value).to_i : value
31
+ end
32
+
33
+ # Lists all orders for a wallet.
34
+ # Results can be filtered and paginated by passing in these options.
35
+ # wallet_id: String, defaults to Itbit.default_wallet_id
36
+ # instrument: Symbol, either :xbtusd, :xbteur, :xbtsgd
37
+ # page: Integer, starting page for pagination.
38
+ # per_page: Integer, how many to show per page.
39
+ # status: Symbol, either :submitted, :open, :filled, :cancelled, :rejected
40
+ # @return [Array<Itbit::Order>]
41
+ def self.all(opts = {})
42
+ wallet_id = opts[:wallet_id] || Itbit.default_wallet_id
43
+ params = {}
44
+ params[:instrument] = opts[:instrument].upcase if opts[:instrument]
45
+ params[:page] = opts[:page].to_i if opts[:page]
46
+ params[:perPage] = opts[:per_page].to_i if opts[:per_page]
47
+ params[:status] = opts[:status] if opts[:status]
48
+ Api.request(:get, "/wallets/#{wallet_id}/orders", params)
49
+ .collect{|o| Order.new(o) }
50
+ end
51
+
52
+ # Finds an order by id in a given wallet.
53
+ # @param id [String] The order's uuid
54
+ # @param wallet_id [String] Optional wallet's uuid, defaults to
55
+ # Itbit.default_wallet_id
56
+ def self.find(id, wallet_id = Itbit.default_wallet_id)
57
+ Order.new Api.request(:get, "/wallets/#{wallet_id}/orders/#{id}")
58
+ end
59
+
60
+ # Creates a new order
61
+ # @param side [Symbol] :buy or :sell
62
+ # @param instrument [Symbol] :xbtusd, :xbteur or :xbtsgd
63
+ # @param amount [BigDecimal] Quantity to buy or sell
64
+ # @param price [BigDecimal] Maximum price to pay when buying
65
+ # or minimum price to charge when selling.
66
+ # @param options [Hash] Optional arguments
67
+ # wallet_id: [String] The wallet to use for placing this order
68
+ # defaults to Itbit.default_wallet_id
69
+ # wait: [Boolean] Block the process and wait until this
70
+ # order moves out of the :submitted state, defaults to false.
71
+ # type: Order type, only :limit is supported at the moment
72
+ # currency: Always :xbt, but left for compatibility.
73
+ # metadata: Arbitrary JSON data for your use.
74
+ # client_order_identifier: If you have your own ID for this
75
+ # order you can pass it in this field, *Make sure it's unique!*
76
+ def self.create!(side, instrument, amount, price, options = {})
77
+ wallet_id = options[:wallet_id] || Itbit.default_wallet_id
78
+ params = {
79
+ side: side,
80
+ instrument: instrument.to_s.upcase,
81
+ amount: amount.to_d.to_s('F'),
82
+ price: price.to_d.to_s('F'),
83
+ type: options[:type] || :limit,
84
+ currency: options[:currency].try(:upcase) || 'XBT'
85
+ }
86
+ %w(metadata client_order_identifier).each do |a|
87
+ params[a.camelize(:lower)] = options[a.to_sym] if options[a.to_sym]
88
+ end
89
+
90
+ order = Order.new Api.request(:post, "/wallets/#{wallet_id}/orders", params)
91
+ retries = 0
92
+ while options[:wait] && order.status == :submitted
93
+ sleep 0.2
94
+ order = find(order.id)
95
+ retries += 1
96
+ if retries > 5000 # Wait 15 minutes for the order to be accepted.
97
+ raise StandardError.new(
98
+ "Timed out waiting for #{base_path} ##{order.id}")
99
+ end
100
+ end
101
+ return order
102
+ end
103
+
104
+ # Cancel this order
105
+ def cancel!
106
+ Api.request(:delete, "/wallets/#{wallet_id}/orders/#{id}")
107
+ self.status = :cancelling
108
+ return self
109
+ rescue RestClient::UnprocessableEntity
110
+ return nil
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,55 @@
1
+ module Itbit
2
+ # List the full trading history for a given wallet
3
+ class Trade
4
+ attr_accessor :order_id, :direction, :commission_paid, :timestamp,
5
+ :rebates_applied, :currency2, :instrument, :rate, :currency1,
6
+ :rebate_currency, :currency1_amount, :currency2_amount,
7
+ :commission_currency
8
+
9
+ def initialize(attrs)
10
+ attrs.each{|k, v| send("#{k.underscore}=", v)}
11
+ end
12
+
13
+ %w(direction instrument currency1 currency2
14
+ rebate_currency commission_currency).each do |attr|
15
+ define_method("#{attr}=") do |value|
16
+ instance_variable_set("@#{attr}", value.to_s.underscore.to_sym)
17
+ end
18
+ end
19
+
20
+ %w(commission_paid rebates_applied rate
21
+ currency1_amount currency2_amount).each do |attr|
22
+ define_method("#{attr}=") do |value|
23
+ instance_variable_set("@#{attr}", value.to_d)
24
+ end
25
+ end
26
+
27
+ def timestamp=(value)
28
+ @timestamp = value.is_a?(String) ? Time.parse(value).to_i : value
29
+ end
30
+
31
+ # Lists all trades for a wallet
32
+ # Results can be filtered and paginated by passing in these options.
33
+ # wallet_id: String, defaults to Itbit.default_wallet_id
34
+ # page: Integer, starting page for pagination.
35
+ # per_page: Integer, how many to show per page.
36
+ # range_start: Integer timestamp, start showing at this date.
37
+ # range_end: Integer timestamp, stop showing at this date.
38
+ # @return [Array<Itbit::Trade>]
39
+ def self.all(opts = {})
40
+ wallet_id = opts[:wallet_id] || Itbit.default_wallet_id
41
+ params = {}
42
+ %w(range_start range_end page per_page).each do |a|
43
+ params[a.camelize(:lower)] = opts[a.to_sym].to_i if opts[a.to_sym]
44
+ end
45
+ response = Api.request(:get, "/wallets/#{wallet_id}/trades", params)
46
+ {
47
+ total_number_of_records: response['totalNumberOfRecords'].to_i,
48
+ current_page_number: response['currentPageNumber'].to_i,
49
+ latest_execution_id: response['latestExecutionId'].to_i,
50
+ records_per_page: response['recordsPerPage'].to_i,
51
+ trading_history: response['tradingHistory'].collect{|x| new(x) }
52
+ }
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,3 @@
1
+ module Itbit
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,30 @@
1
+ module Itbit
2
+ # Your ItBit wallets, translated from itbit api to a more
3
+ # suitable ruby style. Field names are underscored.
4
+ # Values for balance and trading_balance are
5
+ # converted to BigDecimal
6
+ class Wallet
7
+ # Lists all wallets.
8
+ def self.all
9
+ Api.request(:get, "/wallets", userId: Itbit.user_id)
10
+ .collect { |wallet| translate_wallet(wallet) }
11
+ end
12
+
13
+ # Creates a new order
14
+ # @param name [String] The name for the new wallet.
15
+ def self.create!(name)
16
+ translate_wallet(Api.request(:post, "/wallets", name: name, userId: Itbit.user_id))
17
+ end
18
+
19
+ def self.translate_wallet(wallet)
20
+ wallet.symbolize_keys!
21
+ wallet[:balances] = wallet[:balances].dup.collect do |b|
22
+ { balance: b['balance'].to_d,
23
+ currency_code: b['currencyCode'].downcase.to_sym,
24
+ trading_balance: b['tradingBalance'].to_d
25
+ }
26
+ end
27
+ wallet
28
+ end
29
+ end
30
+ end
@@ -0,0 +1 @@
1
+ {"pair":"XBTEUR","bid":"622","bidAmt":"0.0006","ask":"641.29","askAmt":"0.5","lastPrice":"618.00000000","lastAmt":"0.00040000","volume24h":"0.00040000","volumeToday":"0.00040000","high24h":"618.00000000","low24h":"618.00000000","highToday":"618.00000000","lowToday":"618.00000000","openToday":"618.00000000","vwapToday":"618.00000000","vwap24h":"618.00000000","servertimeUTC":"2014-06-24T20:42:35.6160000Z"}
@@ -0,0 +1 @@
1
+ {"pair":"XBTSGD","bid":"622","bidAmt":"0.0006","ask":"641.29","askAmt":"0.5","lastPrice":"618.00000000","lastAmt":"0.00040000","volume24h":"0.00040000","volumeToday":"0.00040000","high24h":"618.00000000","low24h":"618.00000000","highToday":"618.00000000","lowToday":"618.00000000","openToday":"618.00000000","vwapToday":"618.00000000","vwap24h":"618.00000000","servertimeUTC":"2014-06-24T20:42:35.6160000Z"}
@@ -0,0 +1 @@
1
+ {"pair":"XBTUSD","bid":"622","bidAmt":"0.0006","ask":"641.29","askAmt":"0.5","lastPrice":"618.00000000","lastAmt":"0.00040000","volume24h":"0.00040000","volumeToday":"0.00040000","high24h":"618.00000000","low24h":"618.00000000","highToday":"618.00000000","lowToday":"618.00000000","openToday":"618.00000000","vwapToday":"618.00000000","vwap24h":"618.00000000","servertimeUTC":"2014-06-24T20:42:35.6160000Z"}
@@ -0,0 +1 @@
1
+ {"id":"8fd820d3-baff-4d6f-9439-ff03d816c7ce","walletId":"wallet-000","side":"buy","instrument":"XBTUSD","type":"limit","amount":"1.00500000","displayAmount":"1.00500000","price":"100.00000000","volumeWeightedAveragePrice":"0","amountFilled":"0","createdTime":"2014-11-06T16:09:47.6800000Z","status":"open","metadata":{"foo":"bar"},"clientOrderIdentifier":"o"}
@@ -0,0 +1 @@
1
+ {"id":"8fd820d3-baff-4d6f-9439-ff03d816c7ce","walletId":"b440efce-a83c-4873-8833-802a1022b476","side":"buy","instrument":"XBTUSD","type":"limit","amount":"1.00500000","displayAmount":"1.00500000","price":"100.00000000","volumeWeightedAveragePrice":"0","amountFilled":"0","createdTime":"2014-11-06T16:09:47.6800000Z","status":"submitted","metadata":{"foo":"bar"},"clientOrderIdentifier":"o"}
@@ -0,0 +1 @@
1
+ {"bids":[["639.21","1.95"],["637.0","0.47"],["630.0","1.58"]],"asks":[["642.4","0.4"],["643.3","0.95"],["644.3","0.25"]]}
@@ -0,0 +1 @@
1
+ [{"id":"8fd820d3-baff-4d6f-9439-ff03d816c7ce","walletId":"b440efce-a83c-4873-8833-802a1022b476","side":"buy","instrument":"XBTUSD","type":"limit","amount":"1.00500000","displayAmount":"1.00500000","price":"100.00000000","volumeWeightedAveragePrice":"0","amountFilled":"0","createdTime":"2014-11-06T16:09:47.6800000Z","status":"open","metadata":{"foo":"bar"},"clientOrderIdentifier":"o"},{"id":"8fd820d3-baff-4d6f-9439-ff03d816c7FF","walletId":"b440efce-a83c-4873-8833-802a1022b476","side":"sell","instrument":"XBTUSD","type":"limit","amount":"1.00500000","displayAmount":"1.00500000","price":"100.00000000","volumeWeightedAveragePrice":"0","amountFilled":"0","createdTime":"2014-11-06T16:09:47.6800000Z","status":"submitted","metadata":{"foo":"bar"},"clientOrderIdentifier":"o"}]
@@ -0,0 +1 @@
1
+ [{"date":1415218064,"price":"340.00000000","amount":"1.97180000","tid":98375},{"date":1415218064,"price":"340.00000000","amount":"1.44730000","tid":98374},{"date":1415217474,"price":"339.75000000","amount":"1.93820000","tid":98373},{"date":1415217473,"price":"339.75000000","amount":"1.62210000","tid":98372},{"date":1415217455,"price":"339.75000000","amount":"1.31850000","tid":98371},{"date":1415217454,"price":"339.75000000","amount":"1.96260000","tid":98370}]
@@ -0,0 +1 @@
1
+ {"totalNumberOfRecords":"6","currentPageNumber":"1","latestExecutionId":"332","recordsPerPage":"50","tradingHistory":[{"orderId":"c78363f9-1169-4dbb-b256-0756880dc625","direction":"Buy","commissionPaid":"0.40250000","timestamp":"2014-03-04T16:02:28.0070000Z","rebatesApplied":"0","currency2":"USD","instrument":"XBTUSD","rate":"575.00000000","currency1":"XBT","rebateCurrency":"USD","currency1Amount":"0.10000000","currency2Amount":"57.5000000000000000","commissionCurrency":"USD"},{"orderId":"685868a7-911e-4271-b580-6b307b3fc1af","direction":"Buy","commissionPaid":"0.40250000","timestamp":"2014-03-04T16:02:07.3530000Z","rebatesApplied":"0","currency2":"USD","instrument":"XBTUSD","rate":"575.00000000","currency1":"XBT","rebateCurrency":"USD","currency1Amount":"0.10000000","currency2Amount":"57.5000000000000000","commissionCurrency":"USD"}]}
@@ -0,0 +1 @@
1
+ {"id":"3F2504E0-4F89-41D3-9A0C-0305E82C3301","name":"Wallet","balances":[{"balance":"10203.25","currencyCode":"USD","tradingBalance":"10003.25"},{"balance":"402.110","currencyCode":"XBT","tradingBalance":"402.110"},{"balance":"0.00","currencyCode":"EUR","tradingBalance":"0.00"}]}
@@ -0,0 +1 @@
1
+ [{"id":"3F2504E0-4F89-41D3-9A0C-0305E82C3301","name":"Wallet","balances":[{"balance":"10203.25","currencyCode":"USD","tradingBalance":"10003.25"},{"balance":"402.110","currencyCode":"XBT","tradingBalance":"402.110"},{"balance":"0.00","currencyCode":"EUR","tradingBalance":"0.00"}]},{"id":"093DA2D8-12D8-408E-B59D-D4730E5F189D","name":"Trading","balances":[{"balance":"0","currencyCode":"USD","tradingBalance":"0"},{"balance":"0.00","currencyCode":"XBT","tradingBalance":"0.00"},{"balance":"0.00","currencyCode":"EUR","tradingBalance":"0.00"}]}]
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Itbit::MarketData do
4
+
5
+ { xbtusd: Itbit::XBTUSDMarketData,
6
+ xbtsgd: Itbit::XBTSGDMarketData,
7
+ xbteur: Itbit::XBTEURMarketData
8
+ }.each do |symbol, market_data|
9
+ describe "when getting #{symbol} market data" do
10
+ it "gets the ticker" do
11
+ stub_get("/markets/#{symbol}/ticker", "market_ticker_#{symbol}")
12
+ market_data.ticker.should == {
13
+ ask: "641.29".to_d,
14
+ ask_amt: "0.5".to_d,
15
+ bid: "622".to_d,
16
+ bid_amt: "0.0006".to_d,
17
+ high24h: "618.00000000".to_d,
18
+ high_today: "618.00000000".to_d,
19
+ last_amt: "0.00040000".to_d,
20
+ last_price: "618.00000000".to_d,
21
+ low24h: "618.00000000".to_d,
22
+ low_today: "618.00000000".to_d,
23
+ open_today: "618.00000000".to_d,
24
+ pair: symbol,
25
+ servertime_utc: Time.parse("2014-06-24T20:42:35.6160000Z").to_i,
26
+ volume24h: "0.00040000".to_d,
27
+ volume_today: "0.00040000".to_d,
28
+ vwap24h: "618.00000000".to_d,
29
+ vwap_today: "618.00000000".to_d,
30
+ }
31
+ end
32
+
33
+ it "gets the order book" do
34
+ stub_old("/markets/#{symbol.upcase}/orders", 'order_book')
35
+ market_data.orders.should == {
36
+ bids: [[639.21,1.95],[637.0,0.47],[630.0,1.58]],
37
+ asks: [[642.4,0.4],[643.3,0.95],[644.3,0.25]]
38
+ }
39
+ end
40
+
41
+ it "gets the trades" do
42
+ stub_old("/markets/#{symbol.upcase}/trades", 'trades', since: 0)
43
+ trades = market_data.trades
44
+ trades.size.should == 6
45
+ trades.first.tap do |t|
46
+ t[:date].should == 1415218064
47
+ t[:price].should == 340.0
48
+ t[:amount].should == 1.9718
49
+ t[:tid].should == 98375
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
2
+
3
+ describe Itbit::Order do
4
+ it 'lists all' do
5
+ stub_get("/wallets/wallet-000/orders", 'orders')
6
+ orders = Itbit::Order.all
7
+ orders.size.should == 2
8
+ orders.each{|o| o.should be_an Itbit::Order}
9
+ orders.first.side.should == :buy
10
+ orders.last.side.should == :sell
11
+ orders.first.tap do |order|
12
+ order.id.should == "8fd820d3-baff-4d6f-9439-ff03d816c7ce"
13
+ order.wallet_id.should == "b440efce-a83c-4873-8833-802a1022b476"
14
+ order.side.should == :buy
15
+ order.instrument.should == :xbtusd
16
+ order.type.should == :limit
17
+ order.amount.should == "1.005".to_d
18
+ order.price.should == "100".to_d
19
+ order.amount_filled.should == "0".to_d
20
+ order.volume_weighted_average_price.should == '0'.to_d
21
+ order.created_time.should == 1415290187
22
+ order.status.should == :open
23
+ order.metadata.should == {"foo" => "bar"}
24
+ order.client_order_identifier.should == "o"
25
+ order.display_amount = "1.0050000".to_d
26
+ end
27
+ end
28
+
29
+ it 'Accepts filtering by instrument, status and pagination' do
30
+ stub_get("/wallets/wallet-001/orders", 'orders',
31
+ instrument: 'XBTUSD',
32
+ status: 'open',
33
+ page: '1',
34
+ perPage: '200')
35
+ orders = Itbit::Order.all(
36
+ wallet_id: 'wallet-001',
37
+ instrument: :xbtusd,
38
+ status: :open,
39
+ page: 1,
40
+ per_page: 200)
41
+ orders.size.should == 2
42
+ end
43
+
44
+ it 'Finds an order' do
45
+ stub_get("/wallets/wallet-000/orders/8fd820d3-baff-4d6f-9439-ff03d816c7ce", 'order')
46
+ order = Itbit::Order.find("8fd820d3-baff-4d6f-9439-ff03d816c7ce")
47
+ order.should be_an Itbit::Order
48
+ order.id.should == "8fd820d3-baff-4d6f-9439-ff03d816c7ce"
49
+ end
50
+
51
+ it 'Places an order' do
52
+ stub_post("/wallets/wallet-000/orders", 'order',
53
+ side: 'buy',
54
+ instrument: 'XBTUSD',
55
+ amount: '1.0005',
56
+ price: '100.0',
57
+ type: 'limit',
58
+ currency: 'XBT'
59
+ )
60
+ order = Itbit::Order.create!(:buy, :xbtusd, 1.0005, 100.0)
61
+ order.should be_an Itbit::Order
62
+ order.status.should == :submitted
63
+ end
64
+
65
+ it 'Places an order with optional arguments' do
66
+ stub_post("/wallets/wallet-000/orders", 'order', {
67
+ side: 'buy',
68
+ instrument: 'XBTUSD',
69
+ amount: '1.0005',
70
+ price: '100.0',
71
+ type: 'limit',
72
+ currency: 'XBT',
73
+ metadata: {"foo" => "bar"},
74
+ clientOrderIdentifier: 'unique_yet_optional'
75
+ })
76
+ order = Itbit::Order.create!(:buy, :xbtusd, 1.0005, 100.0,
77
+ type: :limit,
78
+ metadata: {"foo" => "bar"},
79
+ client_order_identifier: 'unique_yet_optional')
80
+ order.should be_an Itbit::Order
81
+ order.status.should == :submitted
82
+ end
83
+
84
+ it 'places for btc and waits until processed by the matching engine' do
85
+ stub_post("/wallets/wallet-000/orders", 'order',
86
+ side: 'buy',
87
+ instrument: 'XBTUSD',
88
+ amount: '1.0005',
89
+ price: '100.0',
90
+ type: 'limit',
91
+ currency: 'XBT'
92
+ )
93
+ stub_get("/wallets/wallet-000/orders/8fd820d3-baff-4d6f-9439-ff03d816c7ce",
94
+ 'open_order')
95
+ order = Itbit::Order.create!(:buy, :xbtusd, 1.0005, 100.0, wait: true)
96
+ order.should be_an Itbit::Order
97
+ order.status.should == :open
98
+ end
99
+
100
+ it 'cancels one' do
101
+ url = "/wallets/wallet-000/orders/8fd820d3-baff-4d6f-9439-ff03d816c7ce"
102
+ stub_delete(url, nil)
103
+ stub_get(url, 'open_order')
104
+ order = Itbit::Order.find("8fd820d3-baff-4d6f-9439-ff03d816c7ce")
105
+ order.cancel!
106
+ order.status.should == :cancelling
107
+ end
108
+ end
@@ -0,0 +1,35 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'itbit'
5
+ require 'webmock/rspec'
6
+ require 'shoulda/matchers'
7
+ require 'timecop'
8
+
9
+ Dir[File.expand_path("../support/**/*.rb", __FILE__)].each {|f| require f}
10
+
11
+ RSpec.configure do |config|
12
+ config.include RequestStubs
13
+
14
+ config.mock_with :rspec do |mocks|
15
+ mocks.yield_receiver_to_any_instance_implementation_blocks = true
16
+ mocks.syntax = [:expect, :should]
17
+ end
18
+ config.expect_with :rspec do |c|
19
+ c.syntax = [:expect, :should]
20
+ end
21
+
22
+ config.after(:each) do
23
+ Timecop.return
24
+ end
25
+
26
+ config.before :each do
27
+ Itbit.client_key = 'the-client-key'
28
+ Itbit.secret = 'the-secret'
29
+ Itbit.user_id = 'the-user-id'
30
+ Itbit.default_wallet_id = 'wallet-000'
31
+ end
32
+
33
+ config.order = "random"
34
+ end
35
+
@@ -0,0 +1,29 @@
1
+ require 'open-uri'
2
+ module RequestStubs
3
+ %w(get post delete).each do |verb|
4
+ define_method("stub_#{verb}") do |path, fixture, options = {}|
5
+ stub_api(verb.to_sym, "https://api.itbit.com/v1#{path}", fixture, options)
6
+ end
7
+ end
8
+
9
+ def stub_old(path, fixture, options = { })
10
+ stub_api(:get, "https://www.itbit.com/api/v2#{path}", fixture, options)
11
+ end
12
+
13
+ def stub_api(method, url, fixture, options)
14
+ response_body = if fixture
15
+ File.read(File.expand_path("../../fixtures/#{fixture}.json", __FILE__))
16
+ else
17
+ ''
18
+ end
19
+ with = if options.empty?
20
+ {}
21
+ elsif method == :get
22
+ {query: options}
23
+ else
24
+ {body: options.to_json}
25
+ end
26
+ stub_request(method, url)
27
+ .with(with).to_return(status: 200, body: response_body)
28
+ end
29
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Itbit::Trade do
4
+ it 'lists all' do
5
+ stub_get("/wallets/wallet-000/trades", 'user_trades')
6
+ trades = Itbit::Trade.all
7
+ trades[:trading_history].size.should == 2
8
+ trades[:trading_history].each{|o| o.should be_an Itbit::Trade}
9
+ trades[:trading_history].first.tap do |trade|
10
+ trade.order_id.should == "c78363f9-1169-4dbb-b256-0756880dc625"
11
+ trade.direction.should == :buy
12
+ trade.commission_paid.should == "0.40250000".to_d
13
+ trade.timestamp.should == Time.parse("2014-03-04T16:02:28.0070000Z").to_i
14
+ trade.rebates_applied.should == 0
15
+ trade.currency2.should == :usd
16
+ trade.instrument.should == :xbtusd
17
+ trade.rate.should == "575.00000000".to_d
18
+ trade.currency1.should == :xbt
19
+ trade.rebate_currency.should == :usd
20
+ trade.currency1_amount.should == "0.10000000".to_d
21
+ trade.currency2_amount.should == "57.5000000000000000".to_d
22
+ trade.commission_currency.should == :usd
23
+ end
24
+ end
25
+
26
+ it 'Accepts filtering by instrument, status and pagination' do
27
+ stub_get("/wallets/wallet-001/trades", 'user_trades',
28
+ rangeStart: 0,
29
+ rangeEnd: 100000,
30
+ page: '1',
31
+ perPage: '200')
32
+ trades = Itbit::Trade.all(
33
+ wallet_id: 'wallet-001',
34
+ range_start: 0,
35
+ range_end: 100000,
36
+ page: 1,
37
+ per_page: 200)
38
+ trades[:trading_history].size.should == 2
39
+ trades[:trading_history].each{|o| o.should be_an Itbit::Trade}
40
+ end
41
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Itbit::Wallet do
4
+ it 'lists all' do
5
+ stub_get("/wallets", 'wallets', userId: Itbit.user_id)
6
+ wallets = Itbit::Wallet.all
7
+ wallets.size.should == 2
8
+ wallets.first.should == {
9
+ id: "3F2504E0-4F89-41D3-9A0C-0305E82C3301",
10
+ name: "Wallet",
11
+ balances: [
12
+ { balance: "10203.25".to_d,
13
+ currency_code: :usd,
14
+ trading_balance: "10003.25".to_d
15
+ },
16
+ { balance: "402.110".to_d,
17
+ currency_code: :xbt,
18
+ trading_balance: "402.110".to_d
19
+ },
20
+ { balance: "0.00".to_d,
21
+ currency_code: :eur,
22
+ trading_balance: "0.00".to_d
23
+ }
24
+ ]
25
+ }
26
+ end
27
+
28
+ it 'creates a wallet' do
29
+ stub_post("/wallets", 'wallet', name: 'Wallet', userId: Itbit.user_id)
30
+ wallet = Itbit::Wallet.create!('Wallet')
31
+ wallet[:id].should == "3F2504E0-4F89-41D3-9A0C-0305E82C3301"
32
+ end
33
+ end
metadata ADDED
@@ -0,0 +1,243 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: itbit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nubis
9
+ - Eromirou
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2014-11-07 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: rest_client
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: '1.3'
63
+ - !ruby/object:Gem::Dependency
64
+ name: rake
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ - !ruby/object:Gem::Dependency
80
+ name: rspec
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: rspec-mocks
97
+ requirement: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: timecop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ - !ruby/object:Gem::Dependency
128
+ name: webmock
129
+ requirement: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ! '>='
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ type: :development
136
+ prerelease: false
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ - !ruby/object:Gem::Dependency
144
+ name: shoulda-matchers
145
+ requirement: !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ! '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ type: :development
152
+ prerelease: false
153
+ version_requirements: !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - ! '>='
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ description: ! "API client library for itbit.com. Fetch public market\n data
160
+ and build trading robots"
161
+ email:
162
+ - nb@bitex.la
163
+ - tr@bitex.la
164
+ executables: []
165
+ extensions: []
166
+ extra_rdoc_files: []
167
+ files:
168
+ - .gitignore
169
+ - .rspec
170
+ - Gemfile
171
+ - Gemfile.lock
172
+ - LICENSE.txt
173
+ - README.md
174
+ - Rakefile
175
+ - itbit.gemspec
176
+ - lib/itbit.rb
177
+ - lib/itbit/api.rb
178
+ - lib/itbit/market.rb
179
+ - lib/itbit/order.rb
180
+ - lib/itbit/trade.rb
181
+ - lib/itbit/version.rb
182
+ - lib/itbit/wallet.rb
183
+ - spec/fixtures/market_ticker_xbteur.json
184
+ - spec/fixtures/market_ticker_xbtsgd.json
185
+ - spec/fixtures/market_ticker_xbtusd.json
186
+ - spec/fixtures/open_order.json
187
+ - spec/fixtures/order.json
188
+ - spec/fixtures/order_book.json
189
+ - spec/fixtures/orders.json
190
+ - spec/fixtures/trades.json
191
+ - spec/fixtures/user_trades.json
192
+ - spec/fixtures/wallet.json
193
+ - spec/fixtures/wallets.json
194
+ - spec/market_spec.rb
195
+ - spec/order_spec.rb
196
+ - spec/spec_helper.rb
197
+ - spec/support/request_stubs.rb
198
+ - spec/trade_spec.rb
199
+ - spec/wallet_spec.rb
200
+ homepage: http://github.com/bitex-la/itbit
201
+ licenses:
202
+ - MIT
203
+ post_install_message:
204
+ rdoc_options: []
205
+ require_paths:
206
+ - lib
207
+ required_ruby_version: !ruby/object:Gem::Requirement
208
+ none: false
209
+ requirements:
210
+ - - ! '>='
211
+ - !ruby/object:Gem::Version
212
+ version: 1.9.3
213
+ required_rubygems_version: !ruby/object:Gem::Requirement
214
+ none: false
215
+ requirements:
216
+ - - ! '>='
217
+ - !ruby/object:Gem::Version
218
+ version: '0'
219
+ requirements: []
220
+ rubyforge_project:
221
+ rubygems_version: 1.8.23
222
+ signing_key:
223
+ specification_version: 3
224
+ summary: API client library for itbit.com
225
+ test_files:
226
+ - spec/fixtures/market_ticker_xbteur.json
227
+ - spec/fixtures/market_ticker_xbtsgd.json
228
+ - spec/fixtures/market_ticker_xbtusd.json
229
+ - spec/fixtures/open_order.json
230
+ - spec/fixtures/order.json
231
+ - spec/fixtures/order_book.json
232
+ - spec/fixtures/orders.json
233
+ - spec/fixtures/trades.json
234
+ - spec/fixtures/user_trades.json
235
+ - spec/fixtures/wallet.json
236
+ - spec/fixtures/wallets.json
237
+ - spec/market_spec.rb
238
+ - spec/order_spec.rb
239
+ - spec/spec_helper.rb
240
+ - spec/support/request_stubs.rb
241
+ - spec/trade_spec.rb
242
+ - spec/wallet_spec.rb
243
+ has_rdoc: