cryptoexchange 0.10.4 → 0.11.0
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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +27 -0
- data/README.md +25 -3
- data/lib/cryptoexchange/client.rb +42 -0
- data/lib/cryptoexchange/exchanges/bitcoin_indonesia/bitcoin_indonesia.yml +15 -4
- data/lib/cryptoexchange/exchanges/ether_delta/market.rb +1 -1
- data/lib/cryptoexchange/exchanges/ether_delta/services/market.rb +0 -1
- data/lib/cryptoexchange/exchanges/ether_delta/services/pairs.rb +6 -3
- data/lib/cryptoexchange/exchanges/gemini/services/order_book.rb +40 -0
- data/lib/cryptoexchange/exchanges/luno/market.rb +8 -0
- data/lib/cryptoexchange/exchanges/luno/services/market.rb +49 -0
- data/lib/cryptoexchange/exchanges/luno/services/pairs.rb +27 -0
- data/lib/cryptoexchange/models/order_book.rb +26 -0
- data/lib/cryptoexchange/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b047ac150f961ed2f5b074d5ae4c1b243f30e3f
|
4
|
+
data.tar.gz: cf2e4e5bc58c295589eb814a761b6aea187cbb11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b89a3703b7e3d5a559bb1ac87eabab2f7f8e9b7164dfb98c12660ec9b34d4bde5b06c906d6f75a612f59fbf40c0e820095d4b76e8f9361746f5493ac3314e569
|
7
|
+
data.tar.gz: 6c6bc775d4b8a2416facb85be32409c1058369946ddf370febb99c9c47aba347707388f5d5fc31156902525e019f7f2e80a6a4165ce4f88d63221a69375f9e00
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Introduction
|
2
|
+
|
3
|
+
###
|
4
|
+
|
5
|
+
First of all, thank you for your interest to contribute to the Cryptoexchange project.
|
6
|
+
|
7
|
+
There are many ways to contribute! Our documentation surely has room for improvement, bug hunting, bug fixing, writing better walkthrough tutorials for our users, and even feature implementations (new exchange, new APIs).
|
8
|
+
|
9
|
+
# Ground Rules
|
10
|
+
* Write specs (even though our integration test is currently brittle, passing specs for your implementation is highly recommended)
|
11
|
+
* Verify that the data attribute assignment from the API response is correct (ie. base, target, volume is selected correctly)
|
12
|
+
* Be welcoming to newcomers and encourage diverse new contributors from all backgrounds.
|
13
|
+
* Keep changes as small as possible, one branch one feature
|
14
|
+
* Create issues for any major changes and enhancements that you wish to make. Discuss things transparently and get community feedback.
|
15
|
+
|
16
|
+
# Getting started
|
17
|
+
1. Create a fork of this repository on Github
|
18
|
+
2. You may create a new branch within your fork (name the branch according to the implementation)
|
19
|
+
3. If you like the change and think the project could use it:
|
20
|
+
* Be sure you have followed the code style for the project.
|
21
|
+
* Send a pull request indicating that you have a CLA on file.
|
22
|
+
|
23
|
+
# How to suggest a feature or enhancement
|
24
|
+
If you have any suggestion on how we can make this gem better, feel free to open an issue for discussion.
|
25
|
+
|
26
|
+
# Community
|
27
|
+
You can chat with the core team member or other participating in this repository chat on [https://gitter.im/cryptoexchange-api/Lobby/~chat#](https://gitter.im/cryptoexchange-api/Lobby/~chat#)
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# Cryptoexchange
|
4
4
|
|
5
|
-
Cryptoexchange is a rubygem for ruby developers to interact with
|
5
|
+
Cryptoexchange is a rubygem for ruby developers to interact with over 40+ cryptocurrency exchange market data APIs in a single library.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
@@ -51,7 +51,7 @@ Or install it yourself as:
|
|
51
51
|
| EtherDelta | Y | | | | Y |
|
52
52
|
| Gatecoin | Y | | | | Y |
|
53
53
|
| GDAX | Y | | | | Y |
|
54
|
-
| Gemini | Y |
|
54
|
+
| Gemini | Y | Y | | | Y |
|
55
55
|
| HitBTC | Y | | | | Y |
|
56
56
|
| Huobi | Y | | | | Y |
|
57
57
|
| Itbit | | | | | |
|
@@ -61,7 +61,7 @@ Or install it yourself as:
|
|
61
61
|
| LakeBTC | Y | | | | Y |
|
62
62
|
| Liqui | Y | | | | Y |
|
63
63
|
| Livecoin | Y | | | | Y |
|
64
|
-
| Luno |
|
64
|
+
| Luno | Y | | | | Y |
|
65
65
|
| MercadoBitcoin | Y | | | | User-Defined|
|
66
66
|
| Nova Exchange | Y | | | | Y |
|
67
67
|
| OKCoin | Y | | | | User-Defined|
|
@@ -84,6 +84,13 @@ Or install it yourself as:
|
|
84
84
|
pairs = client.pairs('bitflyer')
|
85
85
|
```
|
86
86
|
|
87
|
+
### List exchange services for certain currency
|
88
|
+
```
|
89
|
+
client.exchange_for('btc')
|
90
|
+
|
91
|
+
# ['anx', 'bianance', ...]
|
92
|
+
```
|
93
|
+
|
87
94
|
### Query the Ticker API
|
88
95
|
```
|
89
96
|
pair = client.pairs('bitflyer').first
|
@@ -93,6 +100,17 @@ Or install it yourself as:
|
|
93
100
|
ticker.last
|
94
101
|
```
|
95
102
|
|
103
|
+
### Query the OrderBook API
|
104
|
+
```
|
105
|
+
# Check if exchange has support for OrderBook
|
106
|
+
pair = client.pairs('bitflyer').first
|
107
|
+
order_book = client.order_book(pairs.last)
|
108
|
+
order_book.base
|
109
|
+
order_book.target
|
110
|
+
order_book.bids
|
111
|
+
order_book.asks
|
112
|
+
```
|
113
|
+
|
96
114
|
### Market List
|
97
115
|
Some exchange API do not support market pair listings. For those exchanges, we included
|
98
116
|
a custom YML file to define the list of market pairs supported by that exchange.
|
@@ -124,6 +142,10 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
124
142
|
|
125
143
|
Bug reports and pull requests are welcome on GitHub at https://github.com/coingecko/cryptoexchange. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
126
144
|
|
145
|
+
The [contributing guide](https://github.com/coingecko/cryptoexchange/blob/master/CONTRIBUTING.md) may also be useful to you.
|
146
|
+
|
147
|
+
You can chat with the core team member or other participating in this repository chat on [https://gitter.im/cryptoexchange-api/Lobby/~chat#](https://gitter.im/cryptoexchange-api/Lobby/~chat#)
|
148
|
+
|
127
149
|
## License
|
128
150
|
|
129
151
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
@@ -8,6 +8,8 @@ module Cryptoexchange
|
|
8
8
|
def pairs(exchange)
|
9
9
|
pairs_classname = "Cryptoexchange::Exchanges::#{StringHelper.camelize(exchange)}::Services::Pairs"
|
10
10
|
Object.const_get(pairs_classname).new.fetch
|
11
|
+
rescue HTTP::ConnectionError, HTTP::TimeoutError, JSON::ParserError
|
12
|
+
return { error: "#{exchange}'s service is temporarily unavailable." }
|
11
13
|
end
|
12
14
|
|
13
15
|
def ticker(market_pair)
|
@@ -24,6 +26,46 @@ module Cryptoexchange
|
|
24
26
|
t.base == market_pair.base && t.target == market_pair.target
|
25
27
|
end
|
26
28
|
end
|
29
|
+
rescue HTTP::ConnectionError, HTTP::TimeoutError, JSON::ParserError
|
30
|
+
return { error: "#{exchange}'s service is temporarily unavailable." }
|
31
|
+
end
|
32
|
+
|
33
|
+
def available_exchanges
|
34
|
+
folder_names = Dir[File.join(File.dirname(__dir__), 'cryptoexchange', 'exchanges', '**')]
|
35
|
+
folder_names.map do |folder_name|
|
36
|
+
folder_name.split('/').last
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def exchange_for(currency)
|
41
|
+
exchanges = []
|
42
|
+
available_exchanges.each do |exchange|
|
43
|
+
pairs = pairs(exchange)
|
44
|
+
next if pairs.is_a?(Hash) && !pairs[:error].empty?
|
45
|
+
pairs.each do |pair|
|
46
|
+
if [pair.base, pair.target].include?(currency.upcase)
|
47
|
+
exchanges << exchange
|
48
|
+
break
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
exchanges.uniq.sort
|
53
|
+
end
|
54
|
+
|
55
|
+
def order_book(market_pair)
|
56
|
+
exchange = market_pair.market
|
57
|
+
market_classname = "Cryptoexchange::Exchanges::#{StringHelper.camelize(exchange)}::Services::OrderBook"
|
58
|
+
market_class = Object.const_get(market_classname)
|
59
|
+
order_book = market_class.new
|
60
|
+
|
61
|
+
if market_class.supports_individual_ticker_query?
|
62
|
+
order_book.fetch(market_pair)
|
63
|
+
else
|
64
|
+
order_books = order_book.fetch
|
65
|
+
order_books.find do |o|
|
66
|
+
o.base == market_pair.base && o.target == market_pair.target
|
67
|
+
end
|
68
|
+
end
|
27
69
|
end
|
28
70
|
end
|
29
71
|
end
|
@@ -1,19 +1,30 @@
|
|
1
1
|
:pairs:
|
2
2
|
- :base: BTC
|
3
3
|
:target: IDR
|
4
|
+
- :base: BCH
|
5
|
+
:target: IDR
|
4
6
|
- :base: ETH
|
7
|
+
:target: IDR
|
8
|
+
- :base: ETC
|
9
|
+
:target: IDR
|
10
|
+
- :base: XRP
|
11
|
+
:target: IDR
|
12
|
+
- :base: XZC
|
13
|
+
:target: IDR
|
14
|
+
- :base: BTS
|
5
15
|
:target: BTC
|
6
16
|
- :base: DOGE
|
7
17
|
:target: BTC
|
8
|
-
- :base:
|
18
|
+
- :base: ETH
|
9
19
|
:target: BTC
|
10
20
|
- :base: LTC
|
11
21
|
:target: BTC
|
12
|
-
- :base: STR
|
13
|
-
:target: BTC
|
14
22
|
- :base: NXT
|
15
23
|
:target: BTC
|
16
|
-
- :base:
|
24
|
+
- :base: STR
|
17
25
|
:target: BTC
|
18
26
|
- :base: NEM
|
19
27
|
:target: BTC
|
28
|
+
- :base: XRP
|
29
|
+
:target: BTC
|
30
|
+
|
@@ -22,7 +22,6 @@ module Cryptoexchange::Exchanges
|
|
22
22
|
def adapt(output, market_pair)
|
23
23
|
name = "#{market_pair.target}_#{market_pair.base}"
|
24
24
|
market = output[name]
|
25
|
-
|
26
25
|
ticker = Cryptoexchange::Models::Ticker.new
|
27
26
|
ticker.base = market_pair.base
|
28
27
|
ticker.target = market_pair.target
|
@@ -10,17 +10,20 @@ module Cryptoexchange::Exchanges
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def adapt(output)
|
13
|
-
|
13
|
+
pairs = []
|
14
|
+
output.keys.each do |pair|
|
14
15
|
# format example: ETH_ZRX
|
15
16
|
# ETH is the Target, ZRX is the Base
|
16
17
|
target, base = pair.split('_')
|
17
|
-
|
18
|
-
|
18
|
+
# Ignore non-standard BASE
|
19
|
+
next if base =~ /\s/ || base =~ /0x/
|
20
|
+
pairs << Cryptoexchange::Models::MarketPair.new({
|
19
21
|
base: base,
|
20
22
|
target: target,
|
21
23
|
market: EtherDelta::Market::NAME
|
22
24
|
})
|
23
25
|
end
|
26
|
+
pairs
|
24
27
|
end
|
25
28
|
end
|
26
29
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Cryptoexchange::Exchanges
|
2
|
+
module Gemini
|
3
|
+
module Services
|
4
|
+
class OrderBook < Cryptoexchange::Services::Market
|
5
|
+
class << self
|
6
|
+
def supports_individual_ticker_query?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch(market_pair)
|
12
|
+
output = super(ticker_url(market_pair))
|
13
|
+
adapt(output, market_pair)
|
14
|
+
end
|
15
|
+
|
16
|
+
def ticker_url(market_pair)
|
17
|
+
"#{Cryptoexchange::Exchanges::Gemini::Market::API_URL}/book/#{market_pair.base}#{market_pair.target}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def adapt(output, market_pair)
|
21
|
+
order_book = Cryptoexchange::Models::OrderBook.new
|
22
|
+
|
23
|
+
order_book.base = market_pair.base
|
24
|
+
order_book.target = market_pair.target
|
25
|
+
order_book.market = Gemini::Market::NAME
|
26
|
+
order_book.asks = adapt_orders output['asks']
|
27
|
+
order_book.bids = adapt_orders output['bids']
|
28
|
+
order_book.timestamp = Time.now.to_i
|
29
|
+
order_book.payload = output
|
30
|
+
order_book
|
31
|
+
end
|
32
|
+
|
33
|
+
def adapt_orders(orders)
|
34
|
+
# Format as: [price, amount, timestamp]
|
35
|
+
orders.collect { |order_entry| order_entry.values }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Cryptoexchange::Exchanges
|
2
|
+
module Luno
|
3
|
+
module Services
|
4
|
+
class Market < Cryptoexchange::Services::Market
|
5
|
+
class << self
|
6
|
+
def supports_individual_ticker_query?
|
7
|
+
false
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch
|
12
|
+
output = super(ticker_url)
|
13
|
+
adapt_all(output)
|
14
|
+
end
|
15
|
+
|
16
|
+
def ticker_url
|
17
|
+
"#{Cryptoexchange::Exchanges::Luno::Market::API_URL}/tickers"
|
18
|
+
end
|
19
|
+
|
20
|
+
def adapt_all(output)
|
21
|
+
output['tickers'].map do |ticker|
|
22
|
+
base = ticker['pair'][0..2]
|
23
|
+
target = ticker['pair'][3..5]
|
24
|
+
market_pair = Cryptoexchange::Models::MarketPair.new(
|
25
|
+
base: base,
|
26
|
+
target: target,
|
27
|
+
market: Luno::Market::NAME
|
28
|
+
)
|
29
|
+
adapt(ticker, market_pair)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def adapt(output, market_pair)
|
34
|
+
ticker = Cryptoexchange::Models::Ticker.new
|
35
|
+
ticker.base = market_pair.base
|
36
|
+
ticker.target = market_pair.target
|
37
|
+
ticker.market = Luno::Market::NAME
|
38
|
+
ticker.ask = NumericHelper.to_d(output['ask'])
|
39
|
+
ticker.bid = NumericHelper.to_d(output['bid'])
|
40
|
+
ticker.last = NumericHelper.to_d(output['last_trade'])
|
41
|
+
ticker.volume = NumericHelper.to_d(output['rolling_24_hour_volume'])
|
42
|
+
ticker.timestamp = output['timestamp'].to_i / 1000
|
43
|
+
ticker.payload = output
|
44
|
+
ticker
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Cryptoexchange::Exchanges
|
2
|
+
module Luno
|
3
|
+
module Services
|
4
|
+
class Pairs < Cryptoexchange::Services::Pairs
|
5
|
+
PAIRS_URL = "#{Cryptoexchange::Exchanges::Luno::Market::API_URL}/tickers"
|
6
|
+
|
7
|
+
def fetch
|
8
|
+
output = super
|
9
|
+
adapt(output)
|
10
|
+
end
|
11
|
+
|
12
|
+
def adapt(output)
|
13
|
+
output['tickers'].map do |ticker|
|
14
|
+
base = ticker['pair'][0..2]
|
15
|
+
target = ticker['pair'][3..5]
|
16
|
+
|
17
|
+
Cryptoexchange::Models::MarketPair.new({
|
18
|
+
base: base,
|
19
|
+
target: target,
|
20
|
+
market: Luno::Market::NAME
|
21
|
+
})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Cryptoexchange
|
2
|
+
module Models
|
3
|
+
class OrderBook
|
4
|
+
attr_accessor :base, :target, :market, :bids,
|
5
|
+
:asks, :timestamp, :payload
|
6
|
+
|
7
|
+
def initialize(params = {})
|
8
|
+
@base = params[:base]
|
9
|
+
@target = params[:target]
|
10
|
+
@market = params[:market]
|
11
|
+
@bids = params[:bids]
|
12
|
+
@asks = params[:asks]
|
13
|
+
@timestamp = params[:timestamp]
|
14
|
+
@payload = params[:payload]
|
15
|
+
end
|
16
|
+
|
17
|
+
def base
|
18
|
+
@base.upcase
|
19
|
+
end
|
20
|
+
|
21
|
+
def target
|
22
|
+
@target.upcase
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cryptoexchange
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TM Lee
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- ".rspec"
|
120
120
|
- ".travis.yml"
|
121
121
|
- CODE_OF_CONDUCT.md
|
122
|
+
- CONTRIBUTING.md
|
122
123
|
- Gemfile
|
123
124
|
- LICENSE.txt
|
124
125
|
- PULL_REQUEST_TEMPLATE
|
@@ -204,6 +205,7 @@ files:
|
|
204
205
|
- lib/cryptoexchange/exchanges/gdax/services/pairs.rb
|
205
206
|
- lib/cryptoexchange/exchanges/gemini/market.rb
|
206
207
|
- lib/cryptoexchange/exchanges/gemini/services/market.rb
|
208
|
+
- lib/cryptoexchange/exchanges/gemini/services/order_book.rb
|
207
209
|
- lib/cryptoexchange/exchanges/gemini/services/pairs.rb
|
208
210
|
- lib/cryptoexchange/exchanges/hitbtc/market.rb
|
209
211
|
- lib/cryptoexchange/exchanges/hitbtc/services/market.rb
|
@@ -230,6 +232,9 @@ files:
|
|
230
232
|
- lib/cryptoexchange/exchanges/livecoin/market.rb
|
231
233
|
- lib/cryptoexchange/exchanges/livecoin/services/market.rb
|
232
234
|
- lib/cryptoexchange/exchanges/livecoin/services/pairs.rb
|
235
|
+
- lib/cryptoexchange/exchanges/luno/market.rb
|
236
|
+
- lib/cryptoexchange/exchanges/luno/services/market.rb
|
237
|
+
- lib/cryptoexchange/exchanges/luno/services/pairs.rb
|
233
238
|
- lib/cryptoexchange/exchanges/mercado_bitcoin/market.rb
|
234
239
|
- lib/cryptoexchange/exchanges/mercado_bitcoin/mercado_bitcoin.yml
|
235
240
|
- lib/cryptoexchange/exchanges/mercado_bitcoin/services/market.rb
|
@@ -276,6 +281,7 @@ files:
|
|
276
281
|
- lib/cryptoexchange/helpers/string_helper.rb
|
277
282
|
- lib/cryptoexchange/lru_ttl_cache.rb
|
278
283
|
- lib/cryptoexchange/models/market_pair.rb
|
284
|
+
- lib/cryptoexchange/models/order_book.rb
|
279
285
|
- lib/cryptoexchange/models/ticker.rb
|
280
286
|
- lib/cryptoexchange/services/market.rb
|
281
287
|
- lib/cryptoexchange/services/pairs.rb
|