bitmex-api 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/Gemfile.lock +28 -13
- data/LICENSE +21 -0
- data/README.md +201 -24
- data/TODOs.org +10 -2
- data/bin/chat.rb +1 -1
- data/bitmex.gemspec +22 -23
- data/lib/bitmex.rb +15 -0
- data/lib/bitmex/apikey.rb +6 -6
- data/lib/bitmex/base.rb +13 -7
- data/lib/bitmex/chat.rb +18 -20
- data/lib/bitmex/client.rb +67 -196
- data/lib/bitmex/instrument.rb +10 -15
- data/lib/bitmex/order.rb +12 -13
- data/lib/bitmex/position.rb +20 -11
- data/lib/bitmex/quote.rb +19 -10
- data/lib/bitmex/rest.rb +103 -0
- data/lib/bitmex/stats.rb +4 -4
- data/lib/bitmex/trade.rb +24 -13
- data/lib/bitmex/user.rb +26 -48
- data/lib/bitmex/version.rb +1 -1
- data/lib/bitmex/websocket.rb +80 -30
- metadata +19 -17
data/lib/bitmex/user.rb
CHANGED
@@ -6,11 +6,13 @@ module Bitmex
|
|
6
6
|
#
|
7
7
|
# @author Iulian Costan
|
8
8
|
class User
|
9
|
-
attr_reader :
|
9
|
+
attr_reader :rest, :websocket
|
10
10
|
|
11
|
-
# @param
|
12
|
-
|
13
|
-
|
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
|
-
|
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
|
-
|
120
|
-
|
121
|
-
|
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(
|
127
|
-
if @data.nil?
|
128
|
-
|
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
|
-
|
140
|
-
|
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
|
-
|
153
|
-
|
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
|
162
|
+
def response_handler(response, &ablock)
|
163
|
+
if block_given?
|
176
164
|
ablock.yield response
|
177
165
|
else
|
178
|
-
|
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
|
data/lib/bitmex/version.rb
CHANGED
data/lib/bitmex/websocket.rb
CHANGED
@@ -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
|
7
|
-
# @
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@
|
12
|
-
|
13
|
-
|
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
|
-
|
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
|
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-
|
11
|
+
date: 2019-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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: []
|