rtcbx 0.0.5 → 0.0.6
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 +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
|
+
[](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:
|