bitmex-api 0.0.3 → 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.
@@ -6,11 +6,13 @@ module Bitmex
6
6
  #
7
7
  # @author Iulian Costan
8
8
  class User
9
- attr_reader :client
9
+ attr_reader :rest, :websocket
10
10
 
11
- # @param client [Bitmex::Client] the HTTP client
12
- def initialize(client)
13
- @client = client
11
+ # @param rest [Bitmex::Rest] the HTTP client
12
+ # @param websocket [Bitmex::Websocket] the Websocket client
13
+ def initialize(rest, websocket)
14
+ @rest = rest
15
+ @websocket = websocket
14
16
  end
15
17
 
16
18
  # Get your current affiliate/referral status.
@@ -41,7 +43,7 @@ module Bitmex
41
43
  # @return [String] the address
42
44
  def deposit_address(currency = 'XBt')
43
45
  get 'depositAddress', currency: currency do |response|
44
- fail response.body unless response.success?
46
+ raise response.body unless response.success?
45
47
 
46
48
  response.to_s
47
49
  end
@@ -106,8 +108,8 @@ module Bitmex
106
108
 
107
109
  # Get all raw executions for your account
108
110
  # @!macro bitmex.filters
109
- # @param filters [Hash] the filters to apply
110
- # @option filters [String] :symbol the instrument symbol
111
+ # @param filters [Hash] the filters to apply to mostly REST API requests with a few exceptions
112
+ # @option filters [String] :symbol the instrument symbol, this filter works in both REST and Websocket APIs
111
113
  # @option filters [String] :filter generic table filter, send key/value pairs {https://www.bitmex.com/app/restAPI#Timestamp-Filters Timestamp Filters}
112
114
  # @option filters [String] :columns array of column names to fetch; if omitted, will return all columns.
113
115
  # @option filters [Double] :count (100) number of results to fetch.
@@ -116,47 +118,33 @@ module Bitmex
116
118
  # @option filters [Datetime, String] :startTime Starting date filter for results.
117
119
  # @option filters [Datetime, String] :endTime Ending date filter for results
118
120
  # @return [Array] the raw transactions
119
- def executions(filters = {})
120
- params = filters.merge resource: :execution
121
- get '', params
121
+ # @yield [Hash] the execution
122
+ def executions(filters = {}, &ablock)
123
+ if block_given?
124
+ websocket.listen execution: filters[:symbol], &ablock
125
+ else
126
+ get '', filters.merge(resource: :execution)
127
+ end
122
128
  end
123
129
 
124
130
  private
125
131
 
126
- def method_missing(m, *args, &ablock)
127
- if @data.nil?
128
- get '' do |response|
129
- raise response.body unless response.success?
130
-
131
- @data = Bitmex::Mash.new response
132
- end
133
- end
134
- @data.send m
132
+ def method_missing(name, *_args, &_ablock)
133
+ @data = get '' if @data.nil?
134
+ @data.send name
135
135
  end
136
136
 
137
137
  def put(action, params, &ablock)
138
138
  path = user_path action
139
- client.put path, params: params, auth: true do |response|
140
- if block_given?
141
- yield response
142
- else
143
- raise response.body unless response.success?
144
-
145
- response_to_mash response
146
- end
139
+ rest.put path, params: params, auth: true do |response|
140
+ response_handler response_handler, &ablock
147
141
  end
148
142
  end
149
143
 
150
144
  def get(action, params = {}, &ablock)
151
145
  path = user_path action, params
152
- client.get path, auth: true do |response|
153
- if block_given?
154
- yield response
155
- else
156
- raise response.body unless response.success?
157
-
158
- response_to_mash response
159
- end
146
+ rest.get path, auth: true do |response|
147
+ response_handler response, &ablock
160
148
  end
161
149
  end
162
150
 
@@ -171,21 +159,11 @@ module Bitmex
171
159
  path
172
160
  end
173
161
 
174
- def response_handler(response, ablock)
175
- if ablock
162
+ def response_handler(response, &ablock)
163
+ if block_given?
176
164
  ablock.yield response
177
165
  else
178
- raise response.body unless response.success?
179
-
180
- response_to_mash response
181
- end
182
- end
183
-
184
- def response_to_mash(response)
185
- if response.parsed_response.is_a? Array
186
- response.to_a.map { |s| Bitmex::Mash.new s }
187
- else
188
- Bitmex::Mash.new response
166
+ rest.response_handler response
189
167
  end
190
168
  end
191
169
  end
@@ -1,3 +1,3 @@
1
1
  module Bitmex
2
- VERSION = '0.0.3'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -1,43 +1,29 @@
1
+ require 'faye/websocket'
2
+ require 'eventmachine'
3
+
1
4
  module Bitmex
2
- # Websocket API
5
+ # Websocket API support
3
6
  # https://www.bitmex.com/app/wsAPI
4
7
  class Websocket
8
+ attr_reader :host, :api_key, :api_secret
9
+
5
10
  # Create new websocket instance
6
- # @param url the URL to connect to
7
- # @return new websocket instance
8
- def initialize(url)
9
- @callbacks = {}
10
- @faye = Faye::WebSocket::Client.new url
11
- @faye.on :open do |event|
12
- # puts [:open, event]
13
- end
14
- @faye.on :error do |event|
15
- raise [:error, event.data]
16
- end
17
- @faye.on :close do |event|
18
- # puts [:close, event.reason]
19
- @faye = nil
20
- end
21
- @faye.on :message do |event|
22
- json = JSON.parse event.data
23
- topic = json['table']
24
- data = json['data']
11
+ # @param host [String] the underlying host to connect to
12
+ # @param api_key [String] the api key
13
+ # @param api_secret [String] the api secret
14
+ # @return [Bitmex::Websocket] new websocket instance
15
+ def initialize(host, api_key: nil, api_secret: nil)
16
+ @host = host
17
+ @api_key = api_key
18
+ @api_secret = api_secret
25
19
 
26
- callback = @callbacks[topic]
27
- if callback
28
- data&.each do |payload|
29
- callback.yield Bitmex::Mash.new(payload)
30
- end
31
- else
32
- puts "==> #{event.data}"
33
- end
34
- end
35
20
  end
36
21
 
37
22
  # Subscribe to a specific topic and optionally filter by symbol
38
23
  # @param topic [String] topic to subscribe to e.g. 'trade'
39
24
  # @param symbol [String] symbol to filter by e.g. 'XBTUSD'
40
- def subscribe(topic, symbol = nil, &callback)
25
+ # @yield [Array] data payload
26
+ def subscribe(topic, symbol = nil, auth: false, &callback)
41
27
  raise 'callback block is required' unless block_given?
42
28
 
43
29
  @callbacks[topic.to_s] = callback
@@ -56,12 +42,76 @@ module Bitmex
56
42
  @faye.send payload.to_json.to_s
57
43
  end
58
44
 
45
+ # Listen to generic topics
46
+ # @param topics [Hash] topics to listen to e.g. { trade: "XBTUSD" }
47
+ # @yield [data] data pushed via websocket
48
+ def listen(topics, &ablock)
49
+ EM.run do
50
+ connect
51
+
52
+ topics.each do |topic, symbol|
53
+ subscribe topic, symbol, &ablock
54
+ end
55
+ end
56
+ end
57
+
58
+ # Stop websocket listener
59
+ def stop
60
+ EM.stop_event_loop
61
+ end
62
+
59
63
  private
60
64
 
65
+ def connect
66
+ @faye = Faye::WebSocket::Client.new realtime_url, [], headers: headers
67
+ @callbacks = {}
68
+ @faye.on :open do |_event|
69
+ # puts [:open, event.data]
70
+ end
71
+ @faye.on :error do |event|
72
+ raise event.message
73
+ end
74
+ @faye.on :close do |_event|
75
+ # puts [:close, event.reason]
76
+ @faye = nil
77
+ end
78
+ @faye.on :message do |event|
79
+ json = JSON.parse event.data
80
+ topic = json['table']
81
+ data = json['data']
82
+
83
+ callback = @callbacks[topic]
84
+ if callback
85
+ data&.each do |payload|
86
+ callback.yield Bitmex::Mash.new(payload)
87
+ end
88
+ else
89
+ puts "==> #{event.data}"
90
+ end
91
+ end
92
+ end
93
+
94
+ def headers
95
+ Bitmex.headers api_key, api_secret, 'GET', '/realtime', ''
96
+ end
97
+
98
+ # def authenticate
99
+ # if api_key && api_secret
100
+ # expires = Time.now.utc.to_i + 60
101
+ # signature = Bitmex.signature(api_secret, 'GET', '/realtime', expires, '')
102
+ # authentication = { op: :authKeyExpires, args: [api_key, expires, signature] }
103
+ # @faye.send authentication.to_json.to_s
104
+ # end
105
+ # end
106
+
61
107
  def subscription(topic, symbol)
62
108
  subscription = topic.to_s
63
109
  subscription += ":#{symbol}" if symbol
64
110
  subscription
65
111
  end
112
+
113
+ def realtime_url
114
+ "wss://#{host}/realtime"
115
+ end
66
116
  end
67
117
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitmex-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Iulian Costan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-31 00:00:00.000000000 Z
11
+ date: 2019-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: httparty
14
+ name: eventmachine
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: hashie
28
+ name: faye-websocket
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: faye-websocket
42
+ name: hashie
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: eventmachine
56
+ name: httparty
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: bundler
70
+ name: bump
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rake
84
+ name: bundler
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: rspec
98
+ name: dotenv
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
@@ -109,7 +109,7 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: bump
112
+ name: pry
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - ">="
@@ -123,7 +123,7 @@ dependencies:
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
- name: pry
126
+ name: pry-doc
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ">="
@@ -137,7 +137,7 @@ dependencies:
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
- name: pry-doc
140
+ name: rake
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - ">="
@@ -151,7 +151,7 @@ dependencies:
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
- name: simplecov
154
+ name: reek
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - ">="
@@ -165,7 +165,7 @@ dependencies:
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
167
  - !ruby/object:Gem::Dependency
168
- name: dotenv
168
+ name: rspec
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
171
  - - ">="
@@ -193,7 +193,7 @@ dependencies:
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
195
  - !ruby/object:Gem::Dependency
196
- name: reek
196
+ name: simplecov
197
197
  requirement: !ruby/object:Gem::Requirement
198
198
  requirements:
199
199
  - - ">="
@@ -206,7 +206,7 @@ dependencies:
206
206
  - - ">="
207
207
  - !ruby/object:Gem::Version
208
208
  version: '0'
209
- description: Ruby library for BitMEX API
209
+ description: Fully-featured, idiomatic Ruby library for BitMEX API
210
210
  email:
211
211
  - iulian.costan@gmail.com
212
212
  executables: []
@@ -221,6 +221,7 @@ files:
221
221
  - CODE_OF_CONDUCT.md
222
222
  - Gemfile
223
223
  - Gemfile.lock
224
+ - LICENSE
224
225
  - README.md
225
226
  - Rakefile
226
227
  - TODOs.org
@@ -240,6 +241,7 @@ files:
240
241
  - lib/bitmex/order.rb
241
242
  - lib/bitmex/position.rb
242
243
  - lib/bitmex/quote.rb
244
+ - lib/bitmex/rest.rb
243
245
  - lib/bitmex/stats.rb
244
246
  - lib/bitmex/trade.rb
245
247
  - lib/bitmex/user.rb
@@ -271,5 +273,5 @@ rubyforge_project:
271
273
  rubygems_version: 2.7.6
272
274
  signing_key:
273
275
  specification_version: 4
274
- summary: Ruby library for BitMEX API
276
+ summary: Fully-featured, idiomatic Ruby library for BitMEX API
275
277
  test_files: []