itbit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: