orderbook 1.0.0 → 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cf56caee6a0354c98d4db2a50d4b19c0d31f6ca7
4
- data.tar.gz: 3da66fed2eeeb1c3e9b0171ded4bdd58d805caa1
3
+ metadata.gz: b0aa666b1b552ce4631f31e03394c802fde18ce5
4
+ data.tar.gz: 6431182407c7cdffa5b47f8db7dac9b995edd73c
5
5
  SHA512:
6
- metadata.gz: 424e6bd0efea8a60866f2688d58b5578a698415708277c88a8091f9391bedcec4bee7344d467a977f9a625ed9d5542c5a95f5351934d92cdd5975342a03ddeec
7
- data.tar.gz: 92594ee583a883d8a116701fbef362ab785e8d0f47d9768041c410acb3b5c53f4df72185d2408971f78ac0492b397de95c1ae0a1402b806da5ae26a3c11e9dc1
6
+ metadata.gz: c47317807dd3d9580218af90bd43b4f7d04ebc7d44ab543064f0ef0a2743ac89896ccce1a8f595635b66bd9d6d952e951e5db343798e79153ffb36ec0a0c8d73
7
+ data.tar.gz: b5417fbaa6ae780b2d8c6b917b29c3fab88c04d11f96b0e917b189d6b2a2fb785d623c44c694d688d805e825fa8ac699f7392a817af40d97b6a84826aeebc55a
data/.gitignore CHANGED
@@ -1,6 +1,5 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
- /Gemfile.lock
4
3
  /_yardoc/
5
4
  /coverage/
6
5
  /doc/
data/Gemfile CHANGED
@@ -2,5 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in orderbook.gemspec
4
4
  gemspec
5
- gem 'coinbase/exchange'
5
+ gem 'coinbase-exchange', :git => 'https://github.com/mikerodrigues/coinbase-exchange-ruby.git', :branch => 'orderbook'
6
6
  gem 'json'
data/Gemfile.lock ADDED
@@ -0,0 +1,49 @@
1
+ GIT
2
+ remote: https://github.com/mikerodrigues/coinbase-exchange-ruby.git
3
+ revision: 051b256d2d0e414d7aec5bdb9a69ad33bfcf7e20
4
+ branch: orderbook
5
+ specs:
6
+ coinbase-exchange (0.1.2)
7
+ bigdecimal
8
+ em-http-request
9
+ faye-websocket
10
+
11
+ PATH
12
+ remote: .
13
+ specs:
14
+ orderbook (2.0.0)
15
+
16
+ GEM
17
+ remote: https://rubygems.org/
18
+ specs:
19
+ addressable (2.3.8)
20
+ bigdecimal (1.2.7)
21
+ cookiejar (0.3.2)
22
+ em-http-request (1.1.2)
23
+ addressable (>= 2.3.4)
24
+ cookiejar
25
+ em-socksify (>= 0.3)
26
+ eventmachine (>= 1.0.3)
27
+ http_parser.rb (>= 0.6.0)
28
+ em-socksify (0.3.0)
29
+ eventmachine (>= 1.0.0.beta.4)
30
+ eventmachine (1.0.7)
31
+ faye-websocket (0.10.0)
32
+ eventmachine (>= 0.12.0)
33
+ websocket-driver (>= 0.5.1)
34
+ http_parser.rb (0.6.0)
35
+ json (1.8.3)
36
+ rake (10.4.2)
37
+ websocket-driver (0.6.2)
38
+ websocket-extensions (>= 0.1.0)
39
+ websocket-extensions (0.1.2)
40
+
41
+ PLATFORMS
42
+ ruby
43
+
44
+ DEPENDENCIES
45
+ bundler (~> 1.7)
46
+ coinbase-exchange!
47
+ json
48
+ orderbook!
49
+ rake (~> 10.0)
@@ -8,40 +8,50 @@ class Orderbook
8
8
  @asks.count
9
9
  end
10
10
 
11
+ def count
12
+ { bid: bid_count, ask: ask_count }
13
+ end
14
+
11
15
  def bid_volume
12
- @bids.map {|x| BigDecimal.new(x.fetch(1))}.inject(:+)
16
+ @bids.map {|x| x.fetch(:size)}.inject(:+)
13
17
  end
14
18
 
15
19
  def ask_volume
16
- @asks.map {|x| BigDecimal.new(x.fetch(1))}.inject(:+)
20
+ @asks.map {|x| x.fetch(:size)}.inject(:+)
21
+ end
22
+
23
+ def volume
24
+ { bid: bid_volume, ask: ask_volume }
17
25
  end
18
26
 
19
27
  def average_bid
20
- array = @bids.map do |price, amount, id|
21
- BigDecimal.new price
22
- end
23
- avg_bid = array.inject(:+) / array.count
24
- avg_bid
28
+ bids = @bids.map {|x| x.fetch(:price)}
29
+ bids.inject(:+) / bids.count
25
30
  end
26
31
 
27
32
  def average_ask
28
- array = @asks.map do |price, amount, id|
29
- BigDecimal.new price
30
- end
31
- avg_ask = array.inject(:+) / array.count
32
- avg_ask
33
+ asks = @asks.map {|x| x.fetch(:price)}
34
+ asks.inject(:+) / asks.count
35
+ end
36
+
37
+ def average
38
+ { bid: average_bid, ask: average_ask }
33
39
  end
34
40
 
35
41
  def best_bid
36
- BigDecimal.new @bids.sort_by {|x| BigDecimal.new(x.fetch(0))}.last.first
42
+ @bids.sort_by {|x| x.fetch(:price)}.last
37
43
  end
38
44
 
39
45
  def best_ask
40
- BigDecimal.new @asks.sort_by {|x| BigDecimal.new(x.fetch(0))}.first.first
46
+ @asks.sort_by {|x| x.fetch(:price)}.first
47
+ end
48
+
49
+ def best
50
+ { bid: best_bid, ask: best_ask }
41
51
  end
42
52
 
43
53
  def spread
44
- best_ask - best_bid
54
+ best_ask.fetch(:price) - best_bid.fetch(:price)
45
55
  end
46
56
 
47
57
  def summarize
@@ -1,10 +1,10 @@
1
- require 'bigdecimal'
2
-
1
+ require 'bigdecimal'
3
2
  class Orderbook
4
3
  # This class provides methods to apply updates to the state of the orderbook
5
4
  # as they come in as individual messages.
6
5
  #
7
6
  module BookMethods
7
+ BIGDECIMAL_KEYS = ['size', 'old_size', 'new_size', 'remaining_size', 'price', 'funds', 'old_funds', 'new_funds']
8
8
 
9
9
  # Applies a message to an Orderbook object by making relevant changes to
10
10
  # @bids, @asks, and @last_sequence.
@@ -12,6 +12,11 @@ class Orderbook
12
12
  def apply(msg)
13
13
  unless msg.fetch('sequence') <= @first_sequence
14
14
  @last_sequence = msg.fetch('sequence')
15
+ BIGDECIMAL_KEYS.each do |key|
16
+ if msg.fetch(key, false)
17
+ msg[key] = BigDecimal.new(msg.fetch(key))
18
+ end
19
+ end
15
20
  __send__(msg.fetch('type'), msg)
16
21
  end
17
22
  end
@@ -19,72 +24,63 @@ class Orderbook
19
24
  private
20
25
 
21
26
  def open(msg)
22
- order = [ msg.fetch("price"), msg.fetch("remaining_size"), msg.fetch("order_id") ]
23
- case msg.fetch("side")
24
- when "buy"
27
+ order = { price: msg.fetch('price'), size: msg.fetch('remaining_size'), order_id: msg.fetch('order_id') }
28
+ case msg.fetch('side')
29
+ when 'buy'
25
30
  @bids << order
26
- when "sell"
31
+ when 'sell'
27
32
  @asks << order
28
33
  end
29
34
  end
30
35
 
31
36
  def match(msg)
32
- match_size = BigDecimal.new(msg.fetch("size"))
33
- case msg.fetch("side")
34
- when "sell"
37
+ case msg.fetch('side')
38
+ when 'sell'
35
39
  @asks.map do |ask|
36
- if ask.include? msg.fetch("maker_order_id")
37
- old_size = BigDecimal.new(ask.fetch(1))
38
- new_size = old_size - match_size
39
- ask[1] = new_size.to_s('F')
40
+ if ask.fetch(:order_id) == msg.fetch('maker_order_id')
41
+ ask[:size] = ask[:size] - msg.fetch('size')
40
42
  end
41
43
  end
42
44
  @bids.map do |bid|
43
- if bid.include? msg.fetch("taker_order_id")
44
- old_size = BigDecimal.net(bid.fetch(1))
45
- new_size = old_size - match_size
46
- bid[1] = new_size.to_s('F')
45
+ if bid.fetch(:order_id) == msg.fetch('taker_order_id')
46
+ bid[:size] = bid[:size] - msg.fetch('size')
47
47
  end
48
48
  end
49
- when "buy"
49
+ when 'buy'
50
50
  @bids.map do |bid|
51
- if bid.include? msg.fetch("maker_order_id")
52
- old_size = BigDecimal.new(bid.fetch(1))
53
- new_size = old_size - match_size
54
- bid[1] = new_size.to_s('F')
51
+ if bid.fetch(:order_id) == msg.fetch('maker_order_id')
52
+ bid[:size] = bid[:size] - msg.fetch('size')
55
53
  end
56
54
  end
57
55
  @asks.map do |ask|
58
- if ask.include? msg.fetch("taker_order_id")
59
- old_size = BigDecimal.new(ask.fetch(1))
60
- new_size = old_size - match_size
61
- ask[1] = new_size.to_s('F')
56
+ if ask.fetch(:order_id) == msg.fetch('taker_order_id')
57
+ ask[:size] = ask[:size] - msg.fetch('size')
62
58
  end
63
59
  end
64
60
  end
65
61
  end
66
62
 
67
63
  def done(msg)
68
- case msg.fetch("side")
69
- when "sell"
70
- @asks.reject! {|a| a.include? msg.fetch("order_id")}
71
- when "buy"
72
- @bids.reject! {|a| a.include? msg.fetch("order_id")}
64
+ case msg.fetch('side')
65
+ when 'sell'
66
+ @asks.reject! {|a| a.fetch(:order_id) == msg['order_id']}
67
+ when 'buy'
68
+ @bids.reject! {|b| b.fetch(:order_id) == msg['order_id']}
73
69
  end
74
70
  end
75
71
 
76
72
  def change(msg)
77
- case msg.fetch("side")
78
- when "sell"
73
+ case msg.fetch('side')
74
+ when 'sell'
79
75
  @asks.map do |a|
80
- if a.include? msg.fetch("order_id")
81
- a[1] = msg.fetch("new_size")
76
+ if a.fetch(:order_id) == msg.fetch('order_id')
77
+ a[:size] = msg.fetch('new_size')
82
78
  end
83
79
  end
84
- when "buy"
80
+ when 'buy'
85
81
  @bids.map do |b|
86
- if b.include? msg.fetch("order_id")
87
- b[1] = msg.fetch("new_size")
82
+ if b.fetch(:order_id) == msg.fetch('order_id')
83
+ b[:size] = msg.fetch('new_size')
88
84
  end
89
85
  end
90
86
  end
@@ -1,3 +1,3 @@
1
1
  class Orderbook
2
- VERSION = "1.0.0"
2
+ VERSION = "2.0.0"
3
3
  end
data/lib/orderbook.rb CHANGED
@@ -55,8 +55,8 @@ class Orderbook
55
55
  # If a +block+ is given it is passed each message as it is received.
56
56
  #
57
57
  def initialize(live = true, &block)
58
- @bids = [[nil, nil]]
59
- @asks = [[nil, nil]]
58
+ @bids = [{price: nil, size: nil, order_id: nil}]
59
+ @asks = [{price: nil, size: nil, order_id: nil}]
60
60
  @first_sequence = 0
61
61
  @last_sequence = 0
62
62
  @websocket = Coinbase::Exchange::Websocket.new(keepalive: true)
@@ -84,8 +84,20 @@ class Orderbook
84
84
 
85
85
  def fetch_current_orderbook
86
86
  @client.orderbook(level: 3) do |resp|
87
- @bids = resp['bids']
88
- @asks = resp['asks']
87
+ @bids = resp['bids'].map do |price, size, order_id|
88
+ {
89
+ price: BigDecimal.new(price),
90
+ size: BigDecimal.new(size),
91
+ order_id: order_id
92
+ }
93
+ end
94
+ @asks = resp['asks'].map do |price, size, order_id|
95
+ {
96
+ price: BigDecimal.new(price),
97
+ size: BigDecimal.new(size),
98
+ order_id: order_id
99
+ }
100
+ end
89
101
  @first_sequence = resp['sequence']
90
102
  end
91
103
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orderbook
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Rodrigues
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-28 00:00:00.000000000 Z
11
+ date: 2015-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -50,6 +50,7 @@ extra_rdoc_files: []
50
50
  files:
51
51
  - ".gitignore"
52
52
  - Gemfile
53
+ - Gemfile.lock
53
54
  - LICENSE.txt
54
55
  - README.md
55
56
  - Rakefile
@@ -79,9 +80,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
80
  version: '0'
80
81
  requirements: []
81
82
  rubyforge_project:
82
- rubygems_version: 2.2.2
83
+ rubygems_version: 2.4.6
83
84
  signing_key:
84
85
  specification_version: 4
85
86
  summary: Maintains an real-time copy of the Coinbase Exchange order book.
86
87
  test_files: []
87
- has_rdoc: