rtcbx 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +6 -3
- data/Rakefile +5 -3
- data/lib/rtcbx.rb +7 -5
- data/lib/rtcbx/candles.rb +24 -25
- data/lib/rtcbx/candles/candle.rb +14 -13
- data/lib/rtcbx/orderbook.rb +8 -8
- data/lib/rtcbx/orderbook/book_analysis.rb +10 -10
- data/lib/rtcbx/orderbook/book_methods.rb +9 -8
- data/lib/rtcbx/trader.rb +2 -1
- data/lib/rtcbx/version.rb +3 -1
- data/rtcbx.gemspec +9 -7
- metadata +14 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a37a1edb1f28968d8bf6bdb6a3300d47553f816239e8b4c665be09e0288f51e7
|
4
|
+
data.tar.gz: b0e002cfaaa5eabf6266b4ba98000b4306197528983c2b4c0243701cdaea3452
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4088bfa8b66f2bbeb8ac463ad25331d298aa53ff51bdd6b576d26add9ba66c4bf26bdf6c8c65595f989c2434eb371474b0adad69814aed92a1997e3345f294a9
|
7
|
+
data.tar.gz: 32fd07f117c43cacd387cbe7305e9353ac52111c6d47b1dab4a455cb12af85bbcf3b3af7b3e10933d7dcae8ec8439a30c17d196a71d245def053602e5e0869ff
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# RTCBX
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/rtcbx.svg)](https://badge.fury.io/rb/rtcbx)
|
2
3
|
|
3
|
-
RTCBX uses the Coinbase (
|
4
|
+
RTCBX uses the Coinbase Pro (formerly GDAX and Coinbase Exchange) Exchange websocket feed to provide immediate access to
|
4
5
|
the current state of the exchange without repeatedly polling parts of the
|
5
6
|
RESTful API. It can:
|
6
7
|
* Keep a synchronized copy of the entire orderbook - `RTCBX::Orderbook`
|
@@ -37,7 +38,7 @@ RTCBX objects share a common interface:
|
|
37
38
|
```ruby
|
38
39
|
#
|
39
40
|
# :product_id
|
40
|
-
# sets the currency (defaults to 'BTC-USD)
|
41
|
+
# sets the currency (defaults to 'BTC-USD')
|
41
42
|
#
|
42
43
|
# :start
|
43
44
|
# run #start! at creation? (defaults to true)
|
@@ -57,7 +58,7 @@ rtcbx.reset! # Calls #stop! then calls #start!.
|
|
57
58
|
|
58
59
|
|
59
60
|
|
60
|
-
|
61
|
+
### Orderbooks
|
61
62
|
* Create a live updating Orderbook:
|
62
63
|
```ruby
|
63
64
|
ob = RTCBX::Orderbook.new
|
@@ -144,6 +145,8 @@ ob.aggregate_asks(10)
|
|
144
145
|
# Will perform the aggregation on each call. Avoid abusing this function since it may degrade performance.
|
145
146
|
ob.aggregate(10)
|
146
147
|
```
|
148
|
+
### Candles
|
149
|
+
### Trader
|
147
150
|
|
148
151
|
## Contributing
|
149
152
|
|
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rake/testtask'
|
2
4
|
require 'bundler'
|
3
5
|
require_relative './lib/rtcbx/version.rb'
|
@@ -6,7 +8,7 @@ task :build do
|
|
6
8
|
begin
|
7
9
|
puts 'building gem...'
|
8
10
|
`gem build rtcbx.gemspec`
|
9
|
-
rescue
|
11
|
+
rescue StandardError
|
10
12
|
puts 'build failed.'
|
11
13
|
end
|
12
14
|
end
|
@@ -15,7 +17,7 @@ task :install do
|
|
15
17
|
begin
|
16
18
|
puts 'installing gem...'
|
17
19
|
`gem install --local rtcbx`
|
18
|
-
rescue
|
20
|
+
rescue StandardError
|
19
21
|
puts 'install failed.'
|
20
22
|
end
|
21
23
|
end
|
@@ -27,7 +29,7 @@ task :console do
|
|
27
29
|
PRY.start
|
28
30
|
end
|
29
31
|
|
30
|
-
task default: %w
|
32
|
+
task default: %w[build install]
|
31
33
|
|
32
34
|
Rake::TestTask.new do |t|
|
33
35
|
t.libs << 'test'
|
data/lib/rtcbx.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'coinbase/exchange'
|
2
4
|
require 'rtcbx/orderbook'
|
3
5
|
require 'rtcbx/candles'
|
@@ -10,7 +12,7 @@ class RTCBX
|
|
10
12
|
#
|
11
13
|
PING_INTERVAL = 2
|
12
14
|
|
13
|
-
# The
|
15
|
+
# The Coinbase Pro product being tracked (eg. "BTC-USD")
|
14
16
|
attr_reader :product_id
|
15
17
|
|
16
18
|
# Boolean, whether the orderbook goes live on creation or not
|
@@ -27,7 +29,7 @@ class RTCBX
|
|
27
29
|
# The Websocket object
|
28
30
|
attr_reader :websocket
|
29
31
|
|
30
|
-
# The
|
32
|
+
# The Coinbase Pro Client object
|
31
33
|
# You can use this if you need to make API calls
|
32
34
|
attr_reader :client
|
33
35
|
|
@@ -35,7 +37,7 @@ class RTCBX
|
|
35
37
|
# The +websocket_thread+ processes this queue
|
36
38
|
attr_reader :queue
|
37
39
|
|
38
|
-
# Epoch time indicating the last time we received a pong from
|
40
|
+
# Epoch time indicating the last time we received a pong from Coinbase Pro in response
|
39
41
|
# to one of our pings
|
40
42
|
attr_reader :last_pong
|
41
43
|
|
@@ -103,7 +105,7 @@ class RTCBX
|
|
103
105
|
def setup_websocket_callback
|
104
106
|
websocket.message do |message|
|
105
107
|
queue.push(message)
|
106
|
-
message_callbacks.each { |b| b
|
108
|
+
message_callbacks.each { |b| b&.call(message) }
|
107
109
|
end
|
108
110
|
end
|
109
111
|
|
@@ -119,7 +121,7 @@ class RTCBX
|
|
119
121
|
end
|
120
122
|
end
|
121
123
|
|
122
|
-
# Configures the websocket to periodically ping
|
124
|
+
# Configures the websocket to periodically ping Coinbase Pro and confirm connection
|
123
125
|
def setup_ping_timer
|
124
126
|
EM.add_periodic_timer(PING_INTERVAL) do
|
125
127
|
websocket.ping do
|
data/lib/rtcbx/candles.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rtcbx/candles/candle'
|
2
4
|
|
3
5
|
class RTCBX
|
4
6
|
class Candles < RTCBX
|
5
|
-
|
6
7
|
# A hash of buckets
|
7
8
|
# Each key is an epoch which stores every +match+ message for that minute
|
8
9
|
# (The epoch plus 60 seconds)
|
@@ -10,7 +11,6 @@ class RTCBX
|
|
10
11
|
# +Candle+
|
11
12
|
attr_reader :buckets
|
12
13
|
|
13
|
-
|
14
14
|
# This thread monitors the websocket object and puts each +match+ object
|
15
15
|
# into the proper bucket. This thread maintains the +buckets+ object.
|
16
16
|
attr_reader :bucket_thread
|
@@ -38,7 +38,6 @@ class RTCBX
|
|
38
38
|
# Mutex to allow our two threads to produce and consume +buckets+
|
39
39
|
attr_reader :buckets_lock
|
40
40
|
|
41
|
-
|
42
41
|
# Create a new +Candles+ object to start and track candles
|
43
42
|
# Pass a block to run a block whenever a candle is created.
|
44
43
|
#
|
@@ -72,19 +71,19 @@ class RTCBX
|
|
72
71
|
|
73
72
|
loop do
|
74
73
|
message = queue.pop
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
74
|
+
next unless message.fetch('type') == 'match'
|
75
|
+
|
76
|
+
next unless Time.parse(message.fetch('time')) >= Time.at(first_bucket)
|
77
|
+
|
78
|
+
timestamp = Time.parse(message.fetch('time'))
|
79
|
+
message_bucket = timestamp.to_i - timestamp.sec
|
80
|
+
@buckets_lock.synchronize do
|
81
|
+
if message_bucket >= current_bucket
|
82
|
+
@current_bucket = message_bucket
|
83
|
+
@buckets[current_bucket.to_i] = []
|
84
|
+
@buckets[current_bucket.to_i] << message
|
85
|
+
else
|
86
|
+
@buckets[current_bucket.to_i] << message
|
88
87
|
end
|
89
88
|
end
|
90
89
|
end
|
@@ -98,15 +97,15 @@ class RTCBX
|
|
98
97
|
sleep(60 - Time.now.sec)
|
99
98
|
loop do
|
100
99
|
buckets.keys.each do |key|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
100
|
+
next unless key + 60 <= Time.now.to_i
|
101
|
+
|
102
|
+
@buckets_lock.synchronize do
|
103
|
+
candle = Candle.new(key, buckets[key]) unless buckets[key].empty?
|
104
|
+
@candles << candle
|
105
|
+
# Run candle callback
|
106
|
+
#
|
107
|
+
@message_callbacks.each { |c| c.call(candle) }
|
108
|
+
buckets.delete(key)
|
110
109
|
end
|
111
110
|
end
|
112
111
|
|
data/lib/rtcbx/candles/candle.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class RTCBX
|
2
4
|
class Candles < RTCBX
|
3
5
|
class Candle
|
4
|
-
|
5
6
|
# Candle values, this is standard
|
6
7
|
attr_reader :time, :low, :high, :open, :close, :volume
|
7
8
|
|
@@ -9,22 +10,22 @@ class RTCBX
|
|
9
10
|
# the interval of the candle
|
10
11
|
def initialize(epoch, matches)
|
11
12
|
@time = Time.at(epoch)
|
12
|
-
@low = matches.map {|message| BigDecimal
|
13
|
-
@high = matches.map {|message| BigDecimal
|
14
|
-
@open = BigDecimal
|
15
|
-
@close = BigDecimal
|
16
|
-
@volume = matches.reduce(BigDecimal(0)) {|sum, message| sum + BigDecimal
|
13
|
+
@low = matches.map { |message| BigDecimal(message.fetch('price')) }.min
|
14
|
+
@high = matches.map { |message| BigDecimal(message.fetch('price')) }.max
|
15
|
+
@open = BigDecimal(matches.first.fetch('price'))
|
16
|
+
@close = BigDecimal(matches.last.fetch('price'))
|
17
|
+
@volume = matches.reduce(BigDecimal(0)) { |sum, message| sum + BigDecimal(message.fetch('size')) }
|
17
18
|
end
|
18
19
|
|
19
20
|
# Return a +Hash+ representation of the +Candle+
|
20
21
|
def to_h
|
21
22
|
{
|
22
|
-
start:
|
23
|
-
low:
|
24
|
-
high:
|
25
|
-
open:
|
26
|
-
close:
|
27
|
-
volume: @volume.to_s(
|
23
|
+
start: Time.at(@time),
|
24
|
+
low: @low.to_s('F'),
|
25
|
+
high: @high.to_s('F'),
|
26
|
+
open: @open.to_s('F'),
|
27
|
+
close: @close.to_s('F'),
|
28
|
+
volume: @volume.to_s('F')
|
28
29
|
}
|
29
30
|
end
|
30
31
|
end
|
data/lib/rtcbx/orderbook.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rtcbx/orderbook/book_methods'
|
2
4
|
require 'rtcbx/orderbook/book_analysis'
|
3
5
|
|
@@ -34,7 +36,7 @@ class RTCBX
|
|
34
36
|
#
|
35
37
|
# If a +block+ is given it is passed each message as it is received.
|
36
38
|
#
|
37
|
-
def initialize(options={}, &block)
|
39
|
+
def initialize(options = {}, &block)
|
38
40
|
@bids = []
|
39
41
|
@asks = []
|
40
42
|
@snapshot_sequence = 0
|
@@ -64,10 +66,9 @@ class RTCBX
|
|
64
66
|
# Converts an order array from the API into a hash.
|
65
67
|
#
|
66
68
|
def order_to_hash(price, size, order_id)
|
67
|
-
{ price:
|
68
|
-
size:
|
69
|
-
order_id: order_id
|
70
|
-
}
|
69
|
+
{ price: BigDecimal(price),
|
70
|
+
size: BigDecimal(size),
|
71
|
+
order_id: order_id }
|
71
72
|
end
|
72
73
|
|
73
74
|
# Fetch orderbook snapshot from API and convert order arrays to hashes.
|
@@ -81,7 +82,7 @@ class RTCBX
|
|
81
82
|
end
|
82
83
|
end
|
83
84
|
|
84
|
-
# Private method to actually start the thread that reads from the
|
85
|
+
# Private method to actually start the thread that reads from the queue and
|
85
86
|
# updates the Orderbook state
|
86
87
|
def start_update_thread
|
87
88
|
@update_thread = Thread.new do
|
@@ -90,8 +91,7 @@ class RTCBX
|
|
90
91
|
message = queue.pop
|
91
92
|
apply(message)
|
92
93
|
end
|
93
|
-
|
94
|
-
rescue => e
|
94
|
+
rescue StandardError => e
|
95
95
|
puts e
|
96
96
|
end
|
97
97
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class RTCBX
|
2
4
|
class Orderbook < RTCBX
|
3
5
|
# Simple collection of commands to get info about the orderbook. Add our own
|
@@ -53,12 +55,12 @@ class RTCBX
|
|
53
55
|
|
54
56
|
# The price of the best current bid
|
55
57
|
def best_bid
|
56
|
-
@bids.
|
58
|
+
@bids.max_by { |x| x.fetch(:price) }
|
57
59
|
end
|
58
60
|
|
59
61
|
# The price of the best current ask
|
60
62
|
def best_ask
|
61
|
-
@asks.
|
63
|
+
@asks.min_by { |x| x.fetch(:price) }
|
62
64
|
end
|
63
65
|
|
64
66
|
# The prices of the best current bid and ask
|
@@ -72,7 +74,7 @@ class RTCBX
|
|
72
74
|
end
|
73
75
|
|
74
76
|
# Aggregates the +top_n+ current bids. Pass `50` and you'll get the same
|
75
|
-
# thing tht
|
77
|
+
# thing tht Coinbase Pro calls a "Level 2 Orderbook"
|
76
78
|
def aggregate_bids(top_n = nil)
|
77
79
|
aggregate = {}
|
78
80
|
@bids.each do |bid|
|
@@ -84,13 +86,12 @@ class RTCBX
|
|
84
86
|
aggregate.keys.sort.reverse.first(top_n).map do |price|
|
85
87
|
{ price: price,
|
86
88
|
size: aggregate[price][:size],
|
87
|
-
num_orders: aggregate[price][:num_orders]
|
88
|
-
}
|
89
|
+
num_orders: aggregate[price][:num_orders] }
|
89
90
|
end
|
90
91
|
end
|
91
92
|
|
92
93
|
# Aggregates the +top_n+ current asks. Pass `50` and you'll get the same
|
93
|
-
# thing tht
|
94
|
+
# thing tht Coinbase Pro calls a "Level 2 Orderbook"
|
94
95
|
def aggregate_asks(top_n = nil)
|
95
96
|
aggregate = {}
|
96
97
|
@asks.each do |ask|
|
@@ -102,13 +103,12 @@ class RTCBX
|
|
102
103
|
aggregate.keys.sort.first(top_n).map do |price|
|
103
104
|
{ price: price,
|
104
105
|
size: aggregate[price][:size],
|
105
|
-
num_orders: aggregate[price][:num_orders]
|
106
|
-
}
|
106
|
+
num_orders: aggregate[price][:num_orders] }
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
110
|
# Aggregates the +top_n+ current asks and bids. Pass `50` and you'll get the same
|
111
|
-
# thing tht
|
111
|
+
# thing tht Coinbase Pro calls a "Level 2 Orderbook"
|
112
112
|
def aggregate(top_n = nil)
|
113
113
|
{ bids: aggregate_bids(top_n), asks: aggregate_asks(top_n) }
|
114
114
|
end
|
@@ -122,7 +122,7 @@ class RTCBX
|
|
122
122
|
private
|
123
123
|
|
124
124
|
def aggregate_base
|
125
|
-
{ size: BigDecimal
|
125
|
+
{ size: BigDecimal(0), num_orders: 0 }
|
126
126
|
end
|
127
127
|
end
|
128
128
|
end
|
@@ -1,28 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'bigdecimal'
|
2
4
|
class RTCBX
|
3
5
|
class Orderbook < RTCBX
|
4
|
-
|
5
6
|
# This class provides methods to apply updates to the state of the orderbook
|
6
7
|
# as they are received by the websocket.
|
7
8
|
#
|
8
9
|
module BookMethods
|
9
|
-
|
10
10
|
# Names of attributes that should be converted to +BigDecimal+
|
11
|
-
BIGDECIMAL_KEYS = %w
|
11
|
+
BIGDECIMAL_KEYS = %w[size old_size new_size remaining_size price].freeze
|
12
12
|
|
13
13
|
# Applies a message to an Orderbook object by making relevant changes to
|
14
14
|
# @bids, @asks, and @last_sequence.
|
15
15
|
#
|
16
16
|
def apply(msg)
|
17
17
|
return if msg.fetch('sequence') != @last_sequence + 1
|
18
|
-
|
18
|
+
|
19
|
+
# if msg.fetch('sequence') != @last_sequence + 1
|
19
20
|
# puts "Expected #{@last_sequence + 1}, got #{msg.fetch('sequence')}"
|
20
21
|
# @websocket.stop!
|
21
|
-
#end
|
22
|
+
# end
|
22
23
|
|
23
24
|
@last_sequence = msg.fetch('sequence')
|
24
25
|
BIGDECIMAL_KEYS.each do |key|
|
25
|
-
msg[key] = BigDecimal
|
26
|
+
msg[key] = BigDecimal(msg.fetch(key)) if msg.fetch(key, false)
|
26
27
|
end
|
27
28
|
|
28
29
|
__send__(msg.fetch('type'), msg)
|
@@ -32,8 +33,8 @@ class RTCBX
|
|
32
33
|
|
33
34
|
def open(msg)
|
34
35
|
order = {
|
35
|
-
price:
|
36
|
-
size:
|
36
|
+
price: msg.fetch('price'),
|
37
|
+
size: msg.fetch('remaining_size'),
|
37
38
|
order_id: msg.fetch('order_id')
|
38
39
|
}
|
39
40
|
|
data/lib/rtcbx/trader.rb
CHANGED
data/lib/rtcbx/version.rb
CHANGED
data/rtcbx.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'rtcbx/version'
|
5
6
|
|
@@ -8,10 +9,11 @@ Gem::Specification.new do |spec|
|
|
8
9
|
spec.version = RTCBX::VERSION
|
9
10
|
spec.authors = ['Michael Rodrigues']
|
10
11
|
spec.email = ['mikebrodrigues@gmail.com']
|
11
|
-
spec.summary =
|
12
|
-
|
12
|
+
spec.summary = 'Maintains an real-time copy of the Coinbase Pro (formerly GDAX,
|
13
|
+
formerly Coinbase Exchange) Exchange order book.'
|
14
|
+
spec.description = 'Uses the Coinbase Pro (formerly GDAX, formerly Coinbase Exchange) Exchange Websocket stream
|
13
15
|
to maintain a real-time copy of the order book, place and track orders,
|
14
|
-
and calculate historic rates by the minute in real-time.
|
16
|
+
and calculate historic rates by the minute in real-time.'
|
15
17
|
spec.homepage = 'https://github.com/mikerodrigues/rtcbx'
|
16
18
|
spec.license = 'MIT'
|
17
19
|
|
@@ -23,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
23
25
|
spec.add_runtime_dependency 'coinbase-exchange', '~> 0.2', '>= 0.2.0'
|
24
26
|
spec.add_runtime_dependency 'eventmachine', '~> 1.0'
|
25
27
|
spec.add_runtime_dependency 'json', '~> 2.0'
|
26
|
-
|
28
|
+
|
27
29
|
spec.add_development_dependency 'bundler', '~> 1.7'
|
28
|
-
spec.add_development_dependency 'rake', '~>
|
30
|
+
spec.add_development_dependency 'rake', '~> 12.3'
|
29
31
|
end
|
metadata
CHANGED
@@ -1,35 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rtcbx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Rodrigues
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: coinbase-exchange
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0.2'
|
20
17
|
- - ">="
|
21
18
|
- !ruby/object:Gem::Version
|
22
19
|
version: 0.2.0
|
20
|
+
- - "~>"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0.2'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- - "~>"
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0.2'
|
30
27
|
- - ">="
|
31
28
|
- !ruby/object:Gem::Version
|
32
29
|
version: 0.2.0
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0.2'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: eventmachine
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,16 +78,16 @@ dependencies:
|
|
78
78
|
requirements:
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
81
|
+
version: '12.3'
|
82
82
|
type: :development
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
88
|
+
version: '12.3'
|
89
89
|
description: |-
|
90
|
-
Uses the GDAX
|
90
|
+
Uses the Coinbase Pro (formerly GDAX, formerly Coinbase Exchange) Exchange Websocket stream
|
91
91
|
to maintain a real-time copy of the order book, place and track orders,
|
92
92
|
and calculate historic rates by the minute in real-time.
|
93
93
|
email:
|
@@ -128,10 +128,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
128
|
- !ruby/object:Gem::Version
|
129
129
|
version: '0'
|
130
130
|
requirements: []
|
131
|
-
|
132
|
-
rubygems_version: 2.4.6
|
131
|
+
rubygems_version: 3.0.3
|
133
132
|
signing_key:
|
134
133
|
specification_version: 4
|
135
|
-
summary: Maintains an real-time copy of the
|
134
|
+
summary: Maintains an real-time copy of the Coinbase Pro (formerly GDAX, formerly
|
135
|
+
Coinbase Exchange) Exchange order book.
|
136
136
|
test_files: []
|
137
|
-
has_rdoc:
|