orderbook 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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