orderbook 0.0.1 → 0.1.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: 4d48c6675dc85211b04b4387110bf495e5636a5f
4
- data.tar.gz: 86ac1793072aeed4649702743695292ca281e553
3
+ metadata.gz: 84269d46b54589bbc0b4ef3cc68427ea1f41160d
4
+ data.tar.gz: 355f66f391af0c02d0eea84d9edbcff19c9761ae
5
5
  SHA512:
6
- metadata.gz: 1fa8666c2db60b162c798ce35caa47d409eda86652d9110912de86ada6f7e8787db5e348c489674909c5907dc2943c57351d7c82fba7b18ed5685b6e685fb17e
7
- data.tar.gz: f2fa544dfb48aac647e4d0a1e1314821927c6546c5ed718bf50504ec657c1f1ac7f2b8afe44874c30d23113cdd1cf55660045bb7031d865bbaca862ed952447f
6
+ metadata.gz: 978af2908c7c1c0be124d3fff39fb1f43cb0bb3d980b4252842e50d1059617c82ffeeab34997e3d30513eb14c1ddb89992d4730f98761d6660cd9608172634b5
7
+ data.tar.gz: 5540ecd2f5cd99f9d68648d934d8d4b226aa4f66f7646294b72d6673c9f41a71a3f3c536b3af364af4d22fa1020eb0840674f0fd2641eac03198ee189d1a28c9
data/README.md CHANGED
@@ -31,6 +31,14 @@ rtb = Orderbook::RealTimeBook.new
31
31
  rtb.bids # Returns an array of bids.
32
32
 
33
33
  rtb.asks # Returns an array of asks.
34
+
35
+ # Setup a callback that runs after the message is applied to the book. Each
36
+ message received on the WebSocket is passed to this block. Running this method
37
+ again will redefine the callback.
38
+
39
+ rtb.set_callback do |msg|
40
+ puts msg.fetch('type')
41
+ end
34
42
  ```
35
43
 
36
44
  ## Contributing
@@ -3,36 +3,114 @@ require 'orderbook/book_analysis'
3
3
 
4
4
  module Orderbook
5
5
  class RealTimeBook
6
+ include BookMethods
7
+ include BookAnalysis
8
+
9
+ # Time to wait until considering skipped messages lost.
10
+ #
11
+ LOST_TIMEOUT = 5
12
+
13
+ # Array of bids
14
+ #
6
15
  attr_reader :bids
16
+
17
+ # Array of asks
18
+ #
7
19
  attr_reader :asks
20
+
21
+ # Sequence number of snapshot
22
+ #
8
23
  attr_reader :sequence
9
24
 
10
- include BookMethods
11
- include BookAnalysis
12
- def initialize()
13
- @cb = ::CoinbaseExchange.new
25
+ # Most recently processed sequence
26
+ #
27
+ attr_reader :last_sequence
28
+
29
+ # Hash of missing sequence numbers and their timeout threads.
30
+ #
31
+ attr_reader :missing
32
+
33
+ # CoinbaseExchange::Feed object
34
+ #
35
+ attr_reader :feed
36
+
37
+ # Queue of messages to be processed
38
+ #
39
+ attr_reader :queue
40
+
41
+ def initialize(&block)
42
+ if block_given?
43
+ @callback = block
44
+ end
45
+ subscribe
46
+ snapshot
47
+ process_queue
48
+ end
49
+
50
+ def set_callback(&block)
51
+ @callback = block
52
+ end
53
+
54
+ def refresh_snapshot
55
+ @thread.kill
56
+ snapshot
57
+ process_queue
58
+ end
59
+
60
+ private
61
+
62
+ def subscribe
14
63
  @queue = Queue.new
64
+ @missing = {}
15
65
  on_msg = lambda {|msg| @queue << msg}
16
66
  on_close = lambda {|close| puts close}
17
67
  on_err = lambda {|err| puts err}
18
68
  @feed = ::CoinbaseExchange::Feed.new(on_msg, on_close, on_err)
69
+ end
70
+
71
+ def snapshot
72
+ @cb || @cb = ::CoinbaseExchange.new
19
73
  @snapshot = @cb.orderbook(3, 'BTC-USD')
20
- @sequence = @snapshot.fetch('sequence').to_f
74
+ @sequence = @snapshot.fetch('sequence').to_i
21
75
  @bids = @snapshot.fetch('bids')
22
76
  @asks = @snapshot.fetch('asks')
23
- @update_thread = Thread.new do
77
+ end
78
+
79
+ def timeout(sequence)
80
+ warn "Missing sequence #{sequence} timed out. Refreshingn snapshot."
81
+ refresh_snapshot
82
+ end
83
+
84
+ def process_queue
85
+ @thread && @thread.kill
86
+ @thread = Thread.new do
87
+ @last_sequence = 'start'
24
88
  loop do
25
89
  msg = @queue.shift
26
- unless msg.fetch("sequence").to_f <= @sequence
90
+ sequence = msg.fetch('sequence').to_i
91
+ if sequence > @sequence
92
+ unless @last_sequence == 'start'
93
+ expected_sequence = @last_sequence + 1
94
+ if sequence != expected_sequence
95
+ if @missing.keys.include? (expected_sequence)
96
+ @missing.fetch(expected_sequence).kill
97
+ @missing.delete(expected_sequence)
98
+ else
99
+ @missing[expected_sequence] = Thread.new do
100
+ sleep LOST_TIMEOUT
101
+ timeout expected_sequence
102
+ end
103
+ end
104
+ @missing < expected_sequence
105
+ end
106
+ end
27
107
  apply(msg)
28
108
  @callback && @callback.call(msg)
29
109
  end
110
+ @last_sequence = sequence
30
111
  end
31
112
  end
32
113
  end
33
-
34
- def set_callback(&block)
35
- @callback = block
36
- end
37
114
  end
38
115
  end
116
+
@@ -1,3 +1,3 @@
1
1
  module Orderbook
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orderbook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Rodrigues