mcoin 0.5.2 → 0.6.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 +5 -5
- data/README.md +4 -4
- data/lib/mcoin/command/ticker.rb +4 -4
- data/lib/mcoin/influx_db.rb +2 -1
- data/lib/mcoin/market.rb +12 -0
- data/lib/mcoin/market/base.rb +35 -10
- data/lib/mcoin/market/binance.rb +23 -0
- data/lib/mcoin/market/bitbank.rb +35 -0
- data/lib/mcoin/market/bitfinex.rb +9 -8
- data/lib/mcoin/market/bitflyer.rb +25 -0
- data/lib/mcoin/market/bitstamp.rb +13 -8
- data/lib/mcoin/market/bittrex.rb +37 -0
- data/lib/mcoin/market/btcbox.rb +27 -0
- data/lib/mcoin/market/coincheck.rb +27 -0
- data/lib/mcoin/market/cryptopia.rb +24 -0
- data/lib/mcoin/market/hitbtc.rb +26 -0
- data/lib/mcoin/market/huobi.rb +28 -0
- data/lib/mcoin/market/kraken.rb +15 -18
- data/lib/mcoin/market/kucoin.rb +24 -0
- data/lib/mcoin/market/okex.rb +28 -0
- data/lib/mcoin/market/zaif.rb +34 -0
- data/lib/mcoin/subscriber.rb +8 -9
- data/lib/mcoin/version.rb +1 -1
- metadata +15 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7aa6faf1e7e0002ee67e7f049e2aca84e80a0e488699e3c32d2b2042166aa809
|
4
|
+
data.tar.gz: 31a82647bccc3d60e0ded2c6cc4fd667829215a17930e6cd958dfbd58ef921c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf06cedbbe0dfea8c997230140896fb928708ceb87015480371e4cab9fae0b7112ea02930bece32f4c22e65942ca046d3685c99e05f8bb54ba63d7256364e8b5
|
7
|
+
data.tar.gz: 4119a89b1811a3c4478accfd4faae8401e204fa39ba8b20b30f49f223c292d9800294668db8428ae4d63c353230beac4828d176dd4cb84a710be21fa67329637
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Mcoin
|
2
2
|
|
3
|
-
This is a side-project for me to monitor BTC/ETH. The target is create a helpful command line tool can run as cronjob to import data to InfluxDB and
|
3
|
+
This is a side-project for me to monitor BTC/ETH. The target is to create a helpful command line tool that can run as a cronjob to import data to InfluxDB and do some analytics.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -32,7 +32,7 @@ mcoin ticker -m Bitfinex -m Kraken # Multiple
|
|
32
32
|
If you want to save it into InfluxDB, add database information.
|
33
33
|
|
34
34
|
```
|
35
|
-
mcoin ticker -m Bitfinex -d monitor -e http://
|
35
|
+
mcoin ticker -m Bitfinex -d monitor -e http://localhost:8086
|
36
36
|
```
|
37
37
|
|
38
38
|
To get more information please use `-h` option.
|
@@ -45,13 +45,13 @@ If you want to subscribe market in your project, you can use `Subscriber`
|
|
45
45
|
require 'mcoin'
|
46
46
|
|
47
47
|
# Leave blank to subscribe all available market
|
48
|
-
subscriber = Mcoin::Subscriber.new(['ETH-USD', 'BTC-USD'], [:
|
48
|
+
subscriber = Mcoin::Subscriber.new(['ETH-USD', 'BTC-USD'], [:Bitfinex])
|
49
49
|
subscriber.start do |ticker|
|
50
50
|
# Deal with Mcoin::Data::Ticker object
|
51
51
|
end
|
52
52
|
```
|
53
53
|
|
54
|
-
Please note, the ticker
|
54
|
+
Please note, the ticker pulls data asynchronously from the market, so the timestamp may not be totally same when you receive it.
|
55
55
|
|
56
56
|
## Roadmap
|
57
57
|
|
data/lib/mcoin/command/ticker.rb
CHANGED
@@ -19,7 +19,7 @@ module Mcoin
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def print
|
22
|
-
tickers = Parallel.map(markets, :fetch).compact.map(&:to_ticker)
|
22
|
+
tickers = Parallel.map(markets, :fetch).compact.map(&:to_ticker).flatten
|
23
23
|
Printer.new(tickers).print
|
24
24
|
end
|
25
25
|
|
@@ -29,11 +29,11 @@ module Mcoin
|
|
29
29
|
|
30
30
|
def markets
|
31
31
|
@markets ||= option.market.map do |name|
|
32
|
+
market = Market.pick(name).new
|
32
33
|
pairs.map do |pair|
|
33
|
-
|
34
|
-
.pick(name)
|
35
|
-
.new(*pair)
|
34
|
+
market.watch(*pair)
|
36
35
|
end
|
36
|
+
market
|
37
37
|
end.flatten
|
38
38
|
end
|
39
39
|
|
data/lib/mcoin/influx_db.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'pp'
|
4
|
+
require 'bigdecimal'
|
4
5
|
require 'net/http'
|
5
6
|
|
6
7
|
module Mcoin
|
@@ -19,7 +20,7 @@ module Mcoin
|
|
19
20
|
http.request(req)
|
20
21
|
end
|
21
22
|
|
22
|
-
pp JSON.parse(res.body) unless res.body.nil?
|
23
|
+
pp JSON.parse(res.body, decimal_class: BigDecimal) unless res.body.nil?
|
23
24
|
end
|
24
25
|
|
25
26
|
protected
|
data/lib/mcoin/market.rb
CHANGED
@@ -7,6 +7,18 @@ module Mcoin
|
|
7
7
|
autoload :Bitfinex, 'mcoin/market/bitfinex'
|
8
8
|
autoload :Bitstamp, 'mcoin/market/Bitstamp'
|
9
9
|
autoload :Kraken, 'mcoin/market/kraken'
|
10
|
+
autoload :Binance, 'mcoin/market/binance'
|
11
|
+
autoload :Bitbank, 'mcoin/market/bitbank'
|
12
|
+
autoload :Bitflyer, 'mcoin/market/bitflyer'
|
13
|
+
autoload :Bittrex, 'mcoin/market/bittrex'
|
14
|
+
autoload :Btcbox, 'mcoin/market/btcbox'
|
15
|
+
autoload :Coincheck, 'mcoin/market/coincheck'
|
16
|
+
autoload :Cryptopia, 'mcoin/market/cryptopia'
|
17
|
+
autoload :Hitbtc, 'mcoin/market/hitbtc'
|
18
|
+
autoload :Huobi, 'mcoin/market/huobi'
|
19
|
+
autoload :Kucoin, 'mcoin/market/kucoin'
|
20
|
+
autoload :Okex, 'mcoin/market/okex'
|
21
|
+
autoload :Zaif, 'mcoin/market/zaif'
|
10
22
|
|
11
23
|
def self.pick(name)
|
12
24
|
const_get(name)
|
data/lib/mcoin/market/base.rb
CHANGED
@@ -1,40 +1,65 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'pp'
|
4
|
+
require 'set'
|
4
5
|
require 'json'
|
6
|
+
require 'bigdecimal'
|
5
7
|
require 'net/http'
|
6
8
|
|
7
9
|
module Mcoin
|
8
10
|
module Market
|
9
11
|
# :nodoc:
|
10
12
|
class Base
|
11
|
-
|
12
|
-
|
13
|
-
|
13
|
+
attr_reader :results
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@pairs = Set.new
|
17
|
+
@results = []
|
14
18
|
@retries = 0
|
15
19
|
end
|
16
20
|
|
21
|
+
def watch(type, currency)
|
22
|
+
@pairs.add({ type: type.to_s.upcase, currency: currency.to_s.upcase })
|
23
|
+
end
|
24
|
+
|
17
25
|
def name
|
18
26
|
self.class.name.split('::').last
|
19
27
|
end
|
20
28
|
|
21
29
|
def fetch
|
22
|
-
@
|
30
|
+
@results = []
|
31
|
+
establish_connection do |http|
|
32
|
+
@pairs.each do |pair|
|
33
|
+
uri = URI(format(self.class.const_get(:ENDPOINT), pair))
|
34
|
+
request = Net::HTTP::Get.new(uri)
|
35
|
+
@results << [pair, JSON.parse(http.request(request)&.body)]
|
36
|
+
end
|
37
|
+
end
|
23
38
|
self
|
24
39
|
rescue JSON::ParserError
|
25
|
-
return
|
40
|
+
return self if @retries >= 3
|
26
41
|
@retries += 1
|
27
42
|
retry
|
28
43
|
end
|
29
44
|
|
30
45
|
def to_ticker
|
31
|
-
|
46
|
+
@results.map do |pair, response|
|
47
|
+
build_ticker(pair, response)
|
48
|
+
end
|
32
49
|
end
|
33
50
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
51
|
+
def establish_connection(&block)
|
52
|
+
@base_uri ||= URI(format(self.class.const_get(:ENDPOINT), type: '', currency: ''))
|
53
|
+
use_ssl = @base_uri.scheme == 'https'
|
54
|
+
Net::HTTP.start(@base_uri.host, @base_uri.port, use_ssl: use_ssl) do |http|
|
55
|
+
yield http
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def build_ticker(_pair, _response)
|
62
|
+
raise NotImplementedError
|
38
63
|
end
|
39
64
|
end
|
40
65
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mcoin
|
4
|
+
module Market
|
5
|
+
# :nodoc:
|
6
|
+
class Binance < Base
|
7
|
+
ENDPOINT = 'https://api.binance.com/api/v1/ticker/24hr?symbol=%<type>s%<currency>s'
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def build_ticker(pair, response)
|
12
|
+
Data::Ticker.new(
|
13
|
+
:Binance, pair[:type], pair[:currency],
|
14
|
+
last: response['lastPrice'],
|
15
|
+
ask: response['askPrice'], bid: response['bidPrice'],
|
16
|
+
low: response['lowPrice'], high: response['highPrice'],
|
17
|
+
volume: response['volume'],
|
18
|
+
timestamp: Time.now.to_i
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mcoin
|
4
|
+
module Market
|
5
|
+
# :nodoc:
|
6
|
+
class Bitbank < Base
|
7
|
+
ENDPOINT = 'https://public.bitbank.cc/%<type>s_%<currency>s/ticker'
|
8
|
+
|
9
|
+
def watch(type, currency)
|
10
|
+
type = swap_bch(type.to_s.downcase)
|
11
|
+
@pairs.add({ type: type, currency: currency.to_s.downcase })
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def build_ticker(pair, response)
|
17
|
+
response = response['data']
|
18
|
+
Data::Ticker.new(
|
19
|
+
:Bitbank, swap_bch(pair[:type]).upcase, pair[:currency].upcase,
|
20
|
+
last: response['last'],
|
21
|
+
ask: response['sell'], bid: response['buy'],
|
22
|
+
low: response['low'], high: response['high'],
|
23
|
+
volume: response['vol'],
|
24
|
+
timestamp: response['timestamp'].to_f / 1000
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def swap_bch(type)
|
29
|
+
return 'bcc' if type == 'bch'
|
30
|
+
return 'bch' if type == 'bcc'
|
31
|
+
type
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -6,16 +6,17 @@ module Mcoin
|
|
6
6
|
class Bitfinex < Base
|
7
7
|
ENDPOINT = 'https://api.bitfinex.com/v1/pubticker/%<type>s%<currency>s'
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
private
|
10
|
+
|
11
|
+
def build_ticker(pair, response)
|
11
12
|
Data::Ticker.new(
|
12
13
|
:Bitfinex,
|
13
|
-
|
14
|
-
last:
|
15
|
-
ask:
|
16
|
-
low:
|
17
|
-
volume:
|
18
|
-
timestamp:
|
14
|
+
pair[:type], pair[:currency],
|
15
|
+
last: response['last_price'],
|
16
|
+
ask: response['ask'], bid: response['bid'],
|
17
|
+
low: response['low'], high: response['high'],
|
18
|
+
volume: response['volume'],
|
19
|
+
timestamp: response['timestamp']
|
19
20
|
)
|
20
21
|
end
|
21
22
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module Mcoin
|
6
|
+
module Market
|
7
|
+
# :nodoc:
|
8
|
+
class Bitflyer < Base
|
9
|
+
ENDPOINT = 'https://api.bitflyer.jp/v1/getticker?product_code=%<type>s_%<currency>s'
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def build_ticker(pair, response)
|
14
|
+
Data::Ticker.new(
|
15
|
+
:Bitflyer, pair[:type], pair[:currency],
|
16
|
+
last: response['ltp'].to_s,
|
17
|
+
ask: response['best_ask'].to_s, bid: response['best_bid'].to_s,
|
18
|
+
low: response['best_bid'].to_s, high: response['best_ask'].to_s,
|
19
|
+
volume: response['volume'], # Trading volume in 24 hours
|
20
|
+
timestamp: Time.parse(response['timestamp']).to_f
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -6,16 +6,21 @@ module Mcoin
|
|
6
6
|
class Bitstamp < Base
|
7
7
|
ENDPOINT = 'https://www.bitstamp.net/api/v2/ticker/%<type>s%<currency>s/'
|
8
8
|
|
9
|
-
def
|
10
|
-
|
9
|
+
def watch(type, currency)
|
10
|
+
@pairs.add({ type: type.to_s.downcase, currency: currency.to_s.downcase })
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def build_ticker(pair, response)
|
11
16
|
Data::Ticker.new(
|
12
17
|
:Bitstamp,
|
13
|
-
|
14
|
-
last:
|
15
|
-
ask:
|
16
|
-
low:
|
17
|
-
volume:
|
18
|
-
timestamp:
|
18
|
+
pair[:type].upcase, pair[:currency].upcase,
|
19
|
+
last: response['last'],
|
20
|
+
ask: response['ask'], bid: response['bid'],
|
21
|
+
low: response['low'], high: response['high'],
|
22
|
+
volume: response['volume'],
|
23
|
+
timestamp: response['timestamp']
|
19
24
|
)
|
20
25
|
end
|
21
26
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module Mcoin
|
6
|
+
module Market
|
7
|
+
# :nodoc:
|
8
|
+
class Bittrex < Base
|
9
|
+
ENDPOINT = 'https://bittrex.com/api/v1.1/public/getmarketsummary?market=%<currency>s-%<type>s'
|
10
|
+
|
11
|
+
def watch(type, currency)
|
12
|
+
type = swap_bch(type.to_s.upcase)
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def build_ticker(pair, response)
|
19
|
+
response = response['result'][0]
|
20
|
+
Data::Ticker.new(
|
21
|
+
:Bittrex, swap_bch(pair[:type]), pair[:currency],
|
22
|
+
last: response['Last'].to_s,
|
23
|
+
ask: response['Ask'].to_s, bid: response['Bid'].to_s,
|
24
|
+
low: response['Low'].to_s, high: response['High'].to_s,
|
25
|
+
volume: response['Volume'],
|
26
|
+
timestamp: Time.parse(response['TimeStamp']).to_f
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def swap_bch(type)
|
31
|
+
return 'BCC' if type == 'BCH'
|
32
|
+
return 'BCH' if type == 'BCC'
|
33
|
+
type
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mcoin
|
4
|
+
module Market
|
5
|
+
# :nodoc:
|
6
|
+
class Btcbox < Base
|
7
|
+
ENDPOINT = 'https://www.btcbox.co.jp/api/v1/ticker?coin=%<type>s'
|
8
|
+
|
9
|
+
def watch(type, currency)
|
10
|
+
@pairs.add({ type: type.to_s.downcase, currency: currency.to_s.downcase })
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def build_ticker(pair, response)
|
16
|
+
Data::Ticker.new(
|
17
|
+
:Btcbox, pair[:type].upcase, 'JPY',
|
18
|
+
last: response['last'],
|
19
|
+
ask: response['sell'], bid: response['buy'],
|
20
|
+
low: response['low'], high: response['high'],
|
21
|
+
volume: response['vol'],
|
22
|
+
timestamp: Time.now.utc.to_i
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mcoin
|
4
|
+
module Market
|
5
|
+
# :nodoc:
|
6
|
+
class Coincheck < Base
|
7
|
+
ENDPOINT = 'https://coincheck.com/api/ticker?pair=%<type>s_%<currency>s'
|
8
|
+
|
9
|
+
def watch(type, currency)
|
10
|
+
@pairs.add({ type: type.to_s.downcase, currency: currency.to_s.downcase })
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def build_ticker(pair, response)
|
16
|
+
Data::Ticker.new(
|
17
|
+
:Coincheck, pair[:type].upcase, pair[:currency],
|
18
|
+
last: response['last'].to_s,
|
19
|
+
ask: response['ask'].to_s, bid: response['bid'].to_s,
|
20
|
+
high: response['high'].to_s, low: response['low'].to_s,
|
21
|
+
volume: response['volume'],
|
22
|
+
timestamp: response['timestamp']
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mcoin
|
4
|
+
module Market
|
5
|
+
# :nodoc:
|
6
|
+
class Cryptopia < Base
|
7
|
+
ENDPOINT = 'https://www.cryptopia.co.nz/api/GetMarket/%<type>s_%<currency>s'
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def build_ticker(pair, response)
|
12
|
+
response = response['Data']
|
13
|
+
Data::Ticker.new(
|
14
|
+
:Cryptopia, pair[:type], pair[:currency],
|
15
|
+
last: response['LastPrice'].to_s,
|
16
|
+
ask: response['AskPrice'].to_s, bid: response['BidPrice'].to_s,
|
17
|
+
high: response['High'].to_s, low: response['Low'].to_s,
|
18
|
+
volume: response['Volume'],
|
19
|
+
timestamp: Time.now.utc.to_i
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module Mcoin
|
6
|
+
module Market
|
7
|
+
# :nodoc:
|
8
|
+
class Hitbtc < Base
|
9
|
+
ENDPOINT = 'https://api.hitbtc.com/api/2/public/ticker/%<type>s%<currency>s'
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def build_ticker(pair, response)
|
14
|
+
fetch
|
15
|
+
Data::Ticker.new(
|
16
|
+
:Hitbtc, pair[:type], pair[:currency],
|
17
|
+
last: response['last'],
|
18
|
+
ask: response['ask'], bid: response['bid'],
|
19
|
+
high: response['high'], low: response['low'],
|
20
|
+
volume: response['volume'],
|
21
|
+
timestamp: Time.parse(response['timestamp']).to_f
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mcoin
|
4
|
+
module Market
|
5
|
+
# :nodoc:
|
6
|
+
class Huobi < Base
|
7
|
+
ENDPOINT = 'https://api.huobi.pro/market/detail/merged?symbol=%<type>s%<currency>s'
|
8
|
+
|
9
|
+
def watch(type, currency)
|
10
|
+
@pairs.add({ type: type.to_s.downcase, currency: currency.to_s.downcase })
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def build_ticker(pair, response)
|
16
|
+
response = response['tick']
|
17
|
+
Data::Ticker.new(
|
18
|
+
:Huobi, pair[:type].upcase, pair[:currency].upcase,
|
19
|
+
last: response['close'].to_s,
|
20
|
+
ask: response['ask'][0].to_s, bid: response['bid'][0].to_s,
|
21
|
+
low: response['low'].to_s, high: response['high'].to_s,
|
22
|
+
volume: response['vol'],
|
23
|
+
timestamp: Time.now.utc.to_i
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/mcoin/market/kraken.rb
CHANGED
@@ -7,34 +7,31 @@ module Mcoin
|
|
7
7
|
# rubocop:disable Metrics/LineLength
|
8
8
|
ENDPOINT = 'https://api.kraken.com/0/public/Ticker?pair=%<type>s%<currency>s'
|
9
9
|
|
10
|
-
def
|
11
|
-
type = swap_btc(type)
|
10
|
+
def watch(type, currency)
|
11
|
+
type = swap_btc(type.to_s.upcase)
|
12
12
|
super
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
private
|
16
|
+
|
17
|
+
def build_ticker(pair, response)
|
18
|
+
return if response['result'].nil?
|
19
|
+
|
20
|
+
response = response.dig('result', "X#{pair[:type]}Z#{pair[:currency]}")
|
17
21
|
Data::Ticker.new(
|
18
22
|
:Kraken,
|
19
|
-
swap_btc(
|
20
|
-
last:
|
21
|
-
ask:
|
22
|
-
low:
|
23
|
-
volume:
|
23
|
+
swap_btc(pair[:type]), pair[:currency],
|
24
|
+
last: response['c'][0],
|
25
|
+
ask: response['a'][0], bid: response['b'][0],
|
26
|
+
low: response['l'][1], high: response['h'][1],
|
27
|
+
volume: response['v'][1],
|
24
28
|
timestamp: Time.now.to_i
|
25
29
|
)
|
26
30
|
end
|
27
31
|
|
28
|
-
def fetch
|
29
|
-
super
|
30
|
-
return self if @data['result'].nil?
|
31
|
-
@data = @data.dig('result', "X#{@type}Z#{@currency}")
|
32
|
-
self
|
33
|
-
end
|
34
|
-
|
35
32
|
def swap_btc(type)
|
36
|
-
return
|
37
|
-
return
|
33
|
+
return 'BTC' if type == 'XBT'
|
34
|
+
return 'XBT' if type == 'BTC'
|
38
35
|
type
|
39
36
|
end
|
40
37
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mcoin
|
4
|
+
module Market
|
5
|
+
# :nodoc:
|
6
|
+
class Kucoin < Base
|
7
|
+
ENDPOINT = 'https://api.kucoin.com/v1/open/tick?symbol=%<type>s-%<currency>s'
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def build_ticker(pair, response)
|
12
|
+
response = response['data']
|
13
|
+
Data::Ticker.new(
|
14
|
+
:Kucoin, pair[:type], pair[:currency],
|
15
|
+
last: response['lastDealPrice'].to_s,
|
16
|
+
ask: response['sell'].to_s, bid: response['buy'].to_s,
|
17
|
+
low: response['low'].to_s, high: response['high'].to_s,
|
18
|
+
volume: response['vol'].to_s,
|
19
|
+
timestamp: response['datetime'] / 1000.to_f
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mcoin
|
4
|
+
module Market
|
5
|
+
# :nodoc:
|
6
|
+
class Okex < Base
|
7
|
+
ENDPOINT = 'https://www.okex.com/api/v1/ticker.do?symbol=%<type>s_%<currency>s'
|
8
|
+
|
9
|
+
def watch(type, currency)
|
10
|
+
@pairs.add({ type: type.to_s.downcase, currency: currency.to_s.downcase })
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def build_ticker(pair, response)
|
16
|
+
response = response['ticker']
|
17
|
+
Data::Ticker.new(
|
18
|
+
:Okex, pair[:type].upcase, pair[:currency].upcase,
|
19
|
+
last: response['last'],
|
20
|
+
ask: response['sell'], bid: response['buy'],
|
21
|
+
low: response['low'], high: response['high'],
|
22
|
+
volume: response['vol'],
|
23
|
+
timestamp: response['date'].to_i
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mcoin
|
4
|
+
module Market
|
5
|
+
# :nodoc:
|
6
|
+
class Zaif < Base
|
7
|
+
ENDPOINT = 'https://api.zaif.jp/api/1/ticker/%<type>s_%<currency>s'
|
8
|
+
|
9
|
+
def watch(type, currency)
|
10
|
+
type = swap_cms(type.to_s.downcase)
|
11
|
+
@pairs.add({ type: type, currency: currency.to_s.downcase })
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def build_ticker(pair, response)
|
17
|
+
Data::Ticker.new(
|
18
|
+
:Zaif, swap_cms(pair[:type]).upcase, pair[:currency].upcase,
|
19
|
+
last: response['last'].to_s,
|
20
|
+
ask: response['ask'].to_s, bid: response['bid'].to_s,
|
21
|
+
high: response['high'].to_s, low: response['low'].to_s,
|
22
|
+
volume: response['volume'],
|
23
|
+
timestamp: Time.now.to_i
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def swap_cms(type)
|
28
|
+
return 'erc20.cms' if type == 'cms'
|
29
|
+
return 'cms' if type == 'erc20.cms'
|
30
|
+
type
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/mcoin/subscriber.rb
CHANGED
@@ -6,16 +6,15 @@ module Mcoin
|
|
6
6
|
|
7
7
|
def initialize(pairs = nil, markets = Market.available)
|
8
8
|
@pairs = pairs_from(pairs)
|
9
|
-
@markets = markets
|
10
|
-
@queue = Queue.new
|
9
|
+
@markets = markets_from(markets)
|
11
10
|
end
|
12
11
|
|
13
12
|
def start(interval = 1, &block)
|
14
13
|
loop do
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
Parallel.async(@markets, :fetch) do |result|
|
15
|
+
result.to_ticker.each do |ticker|
|
16
|
+
yield ticker
|
17
|
+
end
|
19
18
|
end
|
20
19
|
|
21
20
|
sleep interval
|
@@ -32,11 +31,11 @@ module Mcoin
|
|
32
31
|
|
33
32
|
def markets_from(picked)
|
34
33
|
picked.map do |name|
|
34
|
+
market = Market.pick(name).new
|
35
35
|
pairs.map do |pair|
|
36
|
-
|
37
|
-
.pick(name)
|
38
|
-
.new(*pair)
|
36
|
+
market.watch(*pair)
|
39
37
|
end
|
38
|
+
market
|
40
39
|
end.flatten
|
41
40
|
end
|
42
41
|
end
|
data/lib/mcoin/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mcoin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 蒼時弦也
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-12-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -68,9 +68,21 @@ files:
|
|
68
68
|
- lib/mcoin/influx_db.rb
|
69
69
|
- lib/mcoin/market.rb
|
70
70
|
- lib/mcoin/market/base.rb
|
71
|
+
- lib/mcoin/market/binance.rb
|
72
|
+
- lib/mcoin/market/bitbank.rb
|
71
73
|
- lib/mcoin/market/bitfinex.rb
|
74
|
+
- lib/mcoin/market/bitflyer.rb
|
72
75
|
- lib/mcoin/market/bitstamp.rb
|
76
|
+
- lib/mcoin/market/bittrex.rb
|
77
|
+
- lib/mcoin/market/btcbox.rb
|
78
|
+
- lib/mcoin/market/coincheck.rb
|
79
|
+
- lib/mcoin/market/cryptopia.rb
|
80
|
+
- lib/mcoin/market/hitbtc.rb
|
81
|
+
- lib/mcoin/market/huobi.rb
|
73
82
|
- lib/mcoin/market/kraken.rb
|
83
|
+
- lib/mcoin/market/kucoin.rb
|
84
|
+
- lib/mcoin/market/okex.rb
|
85
|
+
- lib/mcoin/market/zaif.rb
|
74
86
|
- lib/mcoin/parallel.rb
|
75
87
|
- lib/mcoin/printer.rb
|
76
88
|
- lib/mcoin/subscriber.rb
|
@@ -95,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
107
|
version: '0'
|
96
108
|
requirements: []
|
97
109
|
rubyforge_project:
|
98
|
-
rubygems_version: 2.6
|
110
|
+
rubygems_version: 2.7.6
|
99
111
|
signing_key:
|
100
112
|
specification_version: 4
|
101
113
|
summary: The BTC market monitor tool
|