bittrex-pro 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +58 -0
- data/.gitignore +28 -0
- data/.ruby-version +1 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +53 -0
- data/Rakefile +11 -0
- data/bittrex-pro.gemspec +30 -0
- data/config/application.yml.example +2 -0
- data/lib/bittrex.rb +32 -0
- data/lib/bittrex/client.rb +46 -0
- data/lib/bittrex/configuration.rb +33 -0
- data/lib/bittrex/currency.rb +27 -0
- data/lib/bittrex/deposit.rb +29 -0
- data/lib/bittrex/helpers.rb +10 -0
- data/lib/bittrex/market.rb +31 -0
- data/lib/bittrex/order.rb +94 -0
- data/lib/bittrex/quote.rb +26 -0
- data/lib/bittrex/summary.rb +38 -0
- data/lib/bittrex/version.rb +3 -0
- data/lib/bittrex/wallet.rb +32 -0
- data/lib/bittrex/withdrawal.rb +42 -0
- data/spec/fixtures/currency.json +7 -0
- data/spec/fixtures/deposit.json +9 -0
- data/spec/fixtures/market.json +12 -0
- data/spec/fixtures/open_order.json +17 -0
- data/spec/fixtures/order.json +16 -0
- data/spec/fixtures/quote.json +5 -0
- data/spec/fixtures/summary.json +16 -0
- data/spec/fixtures/wallet.json +9 -0
- data/spec/fixtures/withdrawal.json +13 -0
- data/spec/models/configuration_spec.rb +27 -0
- data/spec/models/currency_spec.rb +14 -0
- data/spec/models/deposit_spec.rb +16 -0
- data/spec/models/helper_spec.rb +36 -0
- data/spec/models/market_spec.rb +17 -0
- data/spec/models/order_spec.rb +45 -0
- data/spec/models/quote_spec.rb +13 -0
- data/spec/models/summary_spec.rb +22 -0
- data/spec/models/wallet_spec.rb +16 -0
- data/spec/models/withdrawal_spec.rb +20 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/support/api_helper.rb +9 -0
- metadata +220 -0
@@ -0,0 +1,94 @@
|
|
1
|
+
module Bittrex
|
2
|
+
class Order
|
3
|
+
include Helpers
|
4
|
+
|
5
|
+
attr_reader :type, :id, :limit, :opened_at, :closed_at,
|
6
|
+
:exchange, :price, :quantity, :remaining, :commission,
|
7
|
+
:total, :fill, :executed_at, :raw
|
8
|
+
|
9
|
+
def initialize(attrs = {})
|
10
|
+
@id = attrs['Id'] || attrs['OrderUuid']
|
11
|
+
@type = (attrs['Type'] || attrs['OrderType']).to_s.capitalize
|
12
|
+
@exchange = attrs['Exchange']
|
13
|
+
@quantity = attrs['Quantity']
|
14
|
+
@remaining = attrs['QuantityRemaining']
|
15
|
+
@price = attrs['Rate'] || attrs['Price']
|
16
|
+
@total = attrs['Total']
|
17
|
+
@fill = attrs['FillType']
|
18
|
+
@limit = attrs['Limit']
|
19
|
+
@commission = (attrs['Commission'] || attrs['CommissionPaid']).to_f
|
20
|
+
@raw = attrs
|
21
|
+
@opened_at = extract_timestamp(attrs['Opened'])
|
22
|
+
@executed_at = extract_timestamp(attrs['TimeStamp'])
|
23
|
+
@closed_at = extract_timestamp(attrs['Closed'])
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.book(market, type, depth = 50)
|
27
|
+
orders = []
|
28
|
+
|
29
|
+
if type.to_sym == :both
|
30
|
+
orderbook(market, type.downcase, depth).each_pair do |type, values|
|
31
|
+
values.each do |data|
|
32
|
+
orders << new(data.merge('Type' => type))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
else
|
36
|
+
orderbook(market, type.downcase, depth).each do |data|
|
37
|
+
orders << new(data.merge('Type' => type))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
orders
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.buy_limit(market, amount, price)
|
45
|
+
client.get('market/buylimit', {
|
46
|
+
market: market,
|
47
|
+
quantity: amount,
|
48
|
+
rate: price
|
49
|
+
})
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.sell_limit(market, amount, price)
|
53
|
+
client.get('market/selllimit', {
|
54
|
+
market: market,
|
55
|
+
quantity: amount,
|
56
|
+
rate: price
|
57
|
+
})
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.info(order_id)
|
61
|
+
client.get('account/getorder', {
|
62
|
+
uuid: order_id
|
63
|
+
})
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.cancel(order_id)
|
67
|
+
client.get('market/cancel', {
|
68
|
+
uuid: order_id
|
69
|
+
})
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.open
|
73
|
+
client.get('market/getopenorders').map{|data| new(data) }
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.history
|
77
|
+
client.get('account/getorderhistory').map{|data| new(data) }
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def self.orderbook(market, type, depth)
|
83
|
+
client.get('public/getorderbook', {
|
84
|
+
market: market,
|
85
|
+
type: type,
|
86
|
+
depth: depth
|
87
|
+
})
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.client
|
91
|
+
@client ||= Bittrex.client
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Bittrex
|
2
|
+
class Quote
|
3
|
+
attr_reader :market, :bid, :ask, :last, :raw
|
4
|
+
|
5
|
+
def initialize(market, attrs = {})
|
6
|
+
@market = market
|
7
|
+
return if attrs.nil?
|
8
|
+
@bid = attrs['Bid']
|
9
|
+
@ask = attrs['Ask']
|
10
|
+
@last = attrs['Last']
|
11
|
+
@raw = attrs
|
12
|
+
end
|
13
|
+
|
14
|
+
# Example:
|
15
|
+
# BiitrexPro::Quote.current('BTC-HPY')
|
16
|
+
def self.current(market)
|
17
|
+
new(market, client.get('public/getticker', market: market))
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def self.client
|
23
|
+
@client ||= Bittrex.client
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Bittrex
|
2
|
+
class Summary
|
3
|
+
include Helpers
|
4
|
+
|
5
|
+
attr_reader :name, :high, :low, :volume, :last, :base_volume, :raw, :created_at
|
6
|
+
attr_reader :bid, :ask, :open_buy_orders, :open_sell_orders, :previous_day, :updated_at
|
7
|
+
|
8
|
+
alias_method :vol, :volume
|
9
|
+
alias_method :base_vol, :base_volume
|
10
|
+
|
11
|
+
def initialize(attrs = {})
|
12
|
+
@name = attrs['MarketName']
|
13
|
+
@high = attrs['High']
|
14
|
+
@low = attrs['Low']
|
15
|
+
@volume = attrs['Volume']
|
16
|
+
@last = attrs['Last']
|
17
|
+
@base_volume = attrs['BaseVolume']
|
18
|
+
@bid = attrs['Bid']
|
19
|
+
@ask = attrs['Ask']
|
20
|
+
@open_buy_orders = attrs['OpenBuyOrders']
|
21
|
+
@open_sell_orders = attrs['OpenSellOrders']
|
22
|
+
@previous_day = attrs['PrevDay']
|
23
|
+
@updated_at = extract_timestamp(attrs['TimeStamp'])
|
24
|
+
@created_at = extract_timestamp(attrs['Created'])
|
25
|
+
@raw = attrs
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.all
|
29
|
+
client.get('public/getmarketsummaries').map{|data| new(data) }
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def self.client
|
35
|
+
@client ||= Bittrex.client
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Bittrex
|
2
|
+
class Wallet
|
3
|
+
attr_reader :id, :currency, :balance, :available, :pending, :address, :requested, :raw
|
4
|
+
|
5
|
+
def initialize(attrs = {})
|
6
|
+
@id = attrs['Uuid'].to_s
|
7
|
+
@address = attrs['CryptoAddress']
|
8
|
+
@currency = attrs['Currency']
|
9
|
+
@balance = attrs['Balance']
|
10
|
+
@available = attrs['Available']
|
11
|
+
@pending = attrs['Pending']
|
12
|
+
@raw = attrs
|
13
|
+
@requested = attrs['Requested']
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.all
|
17
|
+
client.get('account/getbalances').map{|data| new(data) }
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.balance(currency)
|
21
|
+
client.get('account/getbalance', {
|
22
|
+
currency: currency
|
23
|
+
})
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def self.client
|
29
|
+
@client ||= Bittrex.client
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Bittrex
|
2
|
+
class Withdrawal
|
3
|
+
include Helpers
|
4
|
+
|
5
|
+
attr_reader :id, :currency, :quantity, :address, :authorized,
|
6
|
+
:pending, :canceled, :invalid_address,
|
7
|
+
:transaction_cost, :transaction_id, :executed_at, :raw
|
8
|
+
|
9
|
+
def initialize(attrs = {})
|
10
|
+
@id = attrs['PaymentUuid']
|
11
|
+
@currency = attrs['Currency']
|
12
|
+
@quantity = attrs['Amount']
|
13
|
+
@address = attrs['Address']
|
14
|
+
@authorized = attrs['Authorized']
|
15
|
+
@pending = attrs['PendingPayment']
|
16
|
+
@canceled = attrs['Canceled']
|
17
|
+
@invalid_address = attrs['Canceled']
|
18
|
+
@transaction_cost = attrs['TxCost']
|
19
|
+
@transaction_id = attrs['TxId']
|
20
|
+
@executed_at = extract_timestamp(attrs['Opened'])
|
21
|
+
@raw = attrs
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.all
|
25
|
+
client.get('account/getwithdrawalhistory').map{|data| new(data) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.single(currency, quantity, address)
|
29
|
+
client.get('account/withdraw', {
|
30
|
+
currency: currency,
|
31
|
+
quantity: quantity,
|
32
|
+
address: address
|
33
|
+
})
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def self.client
|
39
|
+
@client ||= Bittrex.client
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
{
|
2
|
+
"Id": 2045339,
|
3
|
+
"Amount": 0.31074098,
|
4
|
+
"Currency": "BTC",
|
5
|
+
"Confirmations": 2,
|
6
|
+
"LastUpdated": "2014-06-16T22:57:17.457",
|
7
|
+
"TxId": "416ba84218c178e7befbe22b23bf1123a23ec2bc68678586a27cebdxxxb6",
|
8
|
+
"CryptoAddress": "17m3mcA3wo5kk637TgEysxxx2c89SDCRZDB"
|
9
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
{
|
2
|
+
"MarketCurrency": "LTC",
|
3
|
+
"BaseCurrency": "BTC",
|
4
|
+
"MarketCurrencyLong": "Litecoin",
|
5
|
+
"BaseCurrencyLong": "Bitcoin",
|
6
|
+
"MinTradeSize": 0.01,
|
7
|
+
"MarketName": "BTC-LTC",
|
8
|
+
"IsActive": true,
|
9
|
+
"Created": "2014-02-13T00:00:00",
|
10
|
+
"DisplayMarketCurrency": null,
|
11
|
+
"DisplayMarketName": null
|
12
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
{
|
2
|
+
"OrderUuid": "1af0399d-e845-4xxx-9d85-aa332d831e95",
|
3
|
+
"Exchange": "BTC-HPY",
|
4
|
+
"Opened": "2014-06-21T04:08:08.75",
|
5
|
+
"Closed": "2014-06-22T04:08:08.75",
|
6
|
+
"OrderType": "LIMIT_SELL",
|
7
|
+
"Limit": 1.6E-7,
|
8
|
+
"Quantity": 371810.26006413,
|
9
|
+
"QuantityRemaining": 371810.26006413,
|
10
|
+
"Price": 0.0,
|
11
|
+
"PricePerUnit": null,
|
12
|
+
"CancelInitiated": false,
|
13
|
+
"IsConditional": false,
|
14
|
+
"Condition": "NONE",
|
15
|
+
"ConditionTarget": null,
|
16
|
+
"ImmediateOrCancel": false
|
17
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"OrderUuid": "1af0399d-e845-4xxx-9d85-aa332d831e95",
|
3
|
+
"Exchange": "BTC-HPY",
|
4
|
+
"TimeStamp": "2014-06-21T04:08:08.75",
|
5
|
+
"OrderType": "LIMIT_SELL",
|
6
|
+
"Limit": 1.6E-7,
|
7
|
+
"Quantity": 371810.26006413,
|
8
|
+
"QuantityRemaining": 371810.26006413,
|
9
|
+
"Price": 0.0,
|
10
|
+
"PricePerUnit": null,
|
11
|
+
"CancelInitiated": false,
|
12
|
+
"IsConditional": false,
|
13
|
+
"Condition": "NONE",
|
14
|
+
"ConditionTarget": null,
|
15
|
+
"ImmediateOrCancel": false
|
16
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"MarketName": "LTC-ZEIT",
|
3
|
+
"High": 2.3E-7,
|
4
|
+
"Low": 2.0E-7,
|
5
|
+
"Volume": 1406611.43827056,
|
6
|
+
"Last": 2.0E-7,
|
7
|
+
"BaseVolume": 0.30179011,
|
8
|
+
"TimeStamp": "2014-06-26T05:22:57.673",
|
9
|
+
"Bid": 2.0E-7,
|
10
|
+
"Ask": 2.3E-7,
|
11
|
+
"OpenBuyOrders": 7,
|
12
|
+
"OpenSellOrders": 8,
|
13
|
+
"PrevDay": 2.2E-7,
|
14
|
+
"Created": "2014-03-01T21:00:00",
|
15
|
+
"DisplayMarketName": null
|
16
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"PaymentUuid": "c7f7b806-36cf-4xxx-b198-fcdeb1220762",
|
3
|
+
"Currency": "BTC",
|
4
|
+
"Amount": 0.0098,
|
5
|
+
"Address": "14UKkY9xxxvk79X7u1zYpxxxRUEQ8F7Lh5",
|
6
|
+
"Opened": "2014-06-26T05:37:55.083",
|
7
|
+
"Authorized": true,
|
8
|
+
"PendingPayment": false,
|
9
|
+
"TxCost": 0.0002,
|
10
|
+
"TxId": "0b34fc4xxx102d0f80efddafexxx6b77c6ce170100b2a579ab5b5f493a383392",
|
11
|
+
"Canceled": false,
|
12
|
+
"InvalidAddress": false
|
13
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bittrex::Configuration do
|
4
|
+
context 'defaults' do
|
5
|
+
it 'is a hash of default configuration' do
|
6
|
+
expect(Bittrex::Configuration.defaults).to be_kind_of(Hash)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'access' do
|
11
|
+
it 'is callable from .config' do
|
12
|
+
Bittrex.config do |c|
|
13
|
+
expect(c).to be_kind_of(Bittrex::Configuration)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'options' do
|
18
|
+
let(:map) { { 'user' => { a: 1 } } }
|
19
|
+
let(:api_key) { 'my_special_key' }
|
20
|
+
|
21
|
+
it 'is able to set the options_key' do
|
22
|
+
Bittrex.config { |config| config.key = api_key }
|
23
|
+
expect(Bittrex.configuration.key).to eq(api_key)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bittrex::Currency do
|
4
|
+
let(:data){ fixture(:currency) }
|
5
|
+
let(:subject){ Bittrex::Currency.new(data) }
|
6
|
+
|
7
|
+
describe '#initialization' do
|
8
|
+
it { should_assign_attribute(subject, :name, 'Bitcoin') }
|
9
|
+
it { should_assign_attribute(subject, :abbreviation, 'BTC') }
|
10
|
+
it { should_assign_attribute(subject, :transaction_fee, 0.00000008) }
|
11
|
+
it { should_assign_attribute(subject, :minimum_confirmation, 5) }
|
12
|
+
it { should_assign_attribute(subject, :active, true) }
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bittrex::Deposit do
|
4
|
+
let(:data){ fixture(:deposit) }
|
5
|
+
let(:subject){ Bittrex::Deposit.new(data) }
|
6
|
+
|
7
|
+
describe '#initialization' do
|
8
|
+
it { should_assign_attribute(subject, :id, 2045339) }
|
9
|
+
it { should_assign_attribute(subject, :currency, 'BTC') }
|
10
|
+
it { should_assign_attribute(subject, :quantity, 0.31074098) }
|
11
|
+
it { should_assign_attribute(subject, :address, '17m3mcA3wo5kk637TgEysxxx2c89SDCRZDB') }
|
12
|
+
it { should_assign_attribute(subject, :transaction_id, '416ba84218c178e7befbe22b23bf1123a23ec2bc68678586a27cebdxxxb6') }
|
13
|
+
it { should_assign_attribute(subject, :confirmations, 2) }
|
14
|
+
it { should_assign_attribute(subject, :executed_at, DateTime.parse('2014-06-16T22:57:17.457')) }
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bittrex::Helpers do
|
4
|
+
include Bittrex::Helpers
|
5
|
+
describe '#extract_timestamp' do
|
6
|
+
context 'when the argument is empty' do
|
7
|
+
it 'returns nil' do
|
8
|
+
expect(extract_timestamp(nil)).to be(nil)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when the argument is an empty string' do
|
13
|
+
it 'returns nil' do
|
14
|
+
expect(extract_timestamp('')).to be(nil)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when the argument is a string of spaces' do
|
19
|
+
it 'returns nil' do
|
20
|
+
expect(extract_timestamp(' ')).to be(nil)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when the argument is datetime string' do
|
25
|
+
it 'returns a datetime object' do
|
26
|
+
expected_time_object = DateTime.now
|
27
|
+
time_string = expected_time_object.to_s
|
28
|
+
strftime_format = '%B %d, %Y %H %M %S'
|
29
|
+
expect(extract_timestamp(time_string).class).to eql(DateTime)
|
30
|
+
expect(
|
31
|
+
extract_timestamp(time_string).strftime(strftime_format)
|
32
|
+
).to eql(expected_time_object.strftime(strftime_format))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|