bitmex-api 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +36 -1
- data/README.md +104 -15
- data/TODOs.org +12 -3
- data/bin/chat.rb +11 -0
- data/bin/whales-watching.rb +2 -2
- data/bitmex.gemspec +3 -0
- data/lib/bitmex.rb +16 -1
- data/lib/bitmex/apikey.rb +45 -0
- data/lib/bitmex/base.rb +26 -0
- data/lib/bitmex/chat.rb +57 -0
- data/lib/bitmex/client.rb +186 -61
- data/lib/bitmex/instrument.rb +53 -0
- data/lib/bitmex/order.rb +78 -0
- data/lib/bitmex/position.rb +77 -0
- data/lib/bitmex/quote.rb +32 -0
- data/lib/bitmex/stats.rb +35 -0
- data/lib/bitmex/trade.rb +41 -0
- data/lib/bitmex/user.rb +37 -11
- data/lib/bitmex/version.rb +1 -1
- data/lib/bitmex/websocket.rb +67 -0
- metadata +55 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92b401dc2774b95aa169e7ed7406eb7c1674f4a88b5ceb1920a268f1d7a129d3
|
4
|
+
data.tar.gz: b2cd44806b551a6f8fa4cec72988975013ccd5799779b1bf58e2e796e792a0d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32b1eb95bfd3724338df77958076a9237c895bb32c207a0b5e0801a1283928a795a1cbf5a1e7cbcde6ddda967452b3d7615cf769140696a80594382991238f29
|
7
|
+
data.tar.gz: 6b06e1c950f1b1e82e87612f3b03deffdec2819a5043d1ec11baa67098e701cf7bf22fced940d2269f75f37177f2dac005f6e4761fb956b9fc5367e858cda83d
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,16 @@
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [0.0.3] - 2019-01-31
|
9
|
+
### Added
|
10
|
+
- Chat, instrument, apikey resources
|
11
|
+
### Changed
|
12
|
+
- Trade resource
|
13
|
+
- Stats, settlement, schema, quote, position resources
|
14
|
+
- Orderbook, order resources
|
15
|
+
- Liquidation, leaderboard, insurance, execution, user, announcement
|
16
|
+
- Make Websocket API interface generic
|
17
|
+
|
8
18
|
## [0.0.2] - 2019-01-22
|
9
19
|
### Added
|
10
20
|
- Initial Websocket API implementation
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
bitmex-api (0.0.
|
4
|
+
bitmex-api (0.0.3)
|
5
5
|
eventmachine
|
6
6
|
faye-websocket
|
7
7
|
hashie
|
@@ -10,6 +10,7 @@ PATH
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
|
+
ast (2.4.0)
|
13
14
|
bump (0.7.0)
|
14
15
|
coderay (1.1.2)
|
15
16
|
diff-lcs (1.3)
|
@@ -23,16 +24,30 @@ GEM
|
|
23
24
|
httparty (0.16.3)
|
24
25
|
mime-types (~> 3.0)
|
25
26
|
multi_xml (>= 0.5.2)
|
27
|
+
jaro_winkler (1.5.2)
|
26
28
|
json (2.1.0)
|
27
29
|
method_source (0.9.2)
|
28
30
|
mime-types (3.2.2)
|
29
31
|
mime-types-data (~> 3.2015)
|
30
32
|
mime-types-data (3.2018.0812)
|
31
33
|
multi_xml (0.6.0)
|
34
|
+
parallel (1.13.0)
|
35
|
+
parser (2.6.0.0)
|
36
|
+
ast (~> 2.4.0)
|
37
|
+
powerpack (0.1.2)
|
32
38
|
pry (0.12.2)
|
33
39
|
coderay (~> 1.1.0)
|
34
40
|
method_source (~> 0.9.0)
|
41
|
+
pry-doc (1.0.0)
|
42
|
+
pry (~> 0.11)
|
43
|
+
yard (~> 0.9.11)
|
44
|
+
rainbow (3.0.0)
|
35
45
|
rake (12.3.2)
|
46
|
+
reek (1.3.7)
|
47
|
+
rainbow
|
48
|
+
ruby2ruby (~> 2.0.8)
|
49
|
+
ruby_parser (~> 3.3)
|
50
|
+
sexp_processor
|
36
51
|
rspec (3.8.0)
|
37
52
|
rspec-core (~> 3.8.0)
|
38
53
|
rspec-expectations (~> 3.8.0)
|
@@ -46,14 +61,31 @@ GEM
|
|
46
61
|
diff-lcs (>= 1.2.0, < 2.0)
|
47
62
|
rspec-support (~> 3.8.0)
|
48
63
|
rspec-support (3.8.0)
|
64
|
+
rubocop (0.63.1)
|
65
|
+
jaro_winkler (~> 1.5.1)
|
66
|
+
parallel (~> 1.10)
|
67
|
+
parser (>= 2.5, != 2.5.1.1)
|
68
|
+
powerpack (~> 0.1)
|
69
|
+
rainbow (>= 2.2.2, < 4.0)
|
70
|
+
ruby-progressbar (~> 1.7)
|
71
|
+
unicode-display_width (~> 1.4.0)
|
72
|
+
ruby-progressbar (1.10.0)
|
73
|
+
ruby2ruby (2.0.8)
|
74
|
+
ruby_parser (~> 3.1)
|
75
|
+
sexp_processor (~> 4.0)
|
76
|
+
ruby_parser (3.12.0)
|
77
|
+
sexp_processor (~> 4.9)
|
78
|
+
sexp_processor (4.11.0)
|
49
79
|
simplecov (0.16.1)
|
50
80
|
docile (~> 1.1)
|
51
81
|
json (>= 1.8, < 3)
|
52
82
|
simplecov-html (~> 0.10.0)
|
53
83
|
simplecov-html (0.10.2)
|
84
|
+
unicode-display_width (1.4.1)
|
54
85
|
websocket-driver (0.7.0)
|
55
86
|
websocket-extensions (>= 0.1.0)
|
56
87
|
websocket-extensions (0.1.3)
|
88
|
+
yard (0.9.18)
|
57
89
|
|
58
90
|
PLATFORMS
|
59
91
|
ruby
|
@@ -64,8 +96,11 @@ DEPENDENCIES
|
|
64
96
|
bundler
|
65
97
|
dotenv
|
66
98
|
pry
|
99
|
+
pry-doc
|
67
100
|
rake
|
101
|
+
reek
|
68
102
|
rspec
|
103
|
+
rubocop
|
69
104
|
simplecov
|
70
105
|
|
71
106
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
# Bitmex
|
1
|
+
# Bitmex API
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/icostan/bitmex-api-ruby.svg?branch=master)](https://travis-ci.org/icostan/bitmex-api-ruby)
|
4
4
|
[![Maintainability](https://api.codeclimate.com/v1/badges/85c3eb58ef31dabc9159/maintainability)](https://codeclimate.com/github/icostan/bitmex-api-ruby/maintainability)
|
5
5
|
[![Test Coverage](https://api.codeclimate.com/v1/badges/85c3eb58ef31dabc9159/test_coverage)](https://codeclimate.com/github/icostan/bitmex-api-ruby/test_coverage)
|
6
6
|
[![Gem Version](https://badge.fury.io/rb/bitmex-api.svg)](https://badge.fury.io/rb/bitmex-api)
|
7
|
+
[![Inline docs](http://inch-ci.org/github/icostan/bitmex-api-ruby.svg?branch=master)](http://inch-ci.org/github/icostan/bitmex-api-ruby)
|
7
8
|
|
8
|
-
|
9
|
+
Fully featured, idiomatic Ruby library for [BitMEX API](https://www.bitmex.com/app/apiOverview).
|
9
10
|
|
10
11
|
## Installation
|
11
12
|
|
@@ -32,42 +33,130 @@ require 'bitmex-api'
|
|
32
33
|
|
33
34
|
client = Bitmex::Client.new
|
34
35
|
|
35
|
-
# or add key and secret args if you want to access private
|
36
|
+
# or add key and secret args if you want to access private APIs
|
36
37
|
client = Bitmex::Client.new api_key: 'KEY', api_secret: 'SECRET'
|
37
38
|
```
|
38
39
|
|
39
|
-
###
|
40
|
+
### REST and Websocket API
|
40
41
|
|
41
42
|
#### Using REST API
|
42
43
|
|
43
|
-
|
44
|
+
Get last 10 messages in English channel:
|
44
45
|
|
45
46
|
```ruby
|
46
|
-
|
47
|
-
|
48
|
-
trades.first
|
47
|
+
messages = client.chat.messages channel_id: 1, count: 10, reverse: true
|
48
|
+
puts messages.first.name
|
49
49
|
```
|
50
50
|
|
51
51
|
#### Using Websocket API
|
52
52
|
|
53
|
-
|
53
|
+
Generic Websocket API is implemented in `Bitmex::Client#listen` method. See the list of available [Topics](https://www.bitmex.com/app/wsAPI#Subscriptions "Topics") to subscribe to.
|
54
|
+
|
55
|
+
Listen to chat messages.
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
client.listen chat: 1 do |message|
|
59
|
+
puts "#{message.user}: #{message.message}"
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
Listen to XBTUSD trades.
|
54
64
|
|
55
65
|
```ruby
|
56
66
|
client.listen trade: 'XBTUSD' do |trade|
|
57
|
-
puts trade
|
67
|
+
puts trade.homeNotional
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
Or multiple topics at the same time.
|
58
72
|
|
59
|
-
|
60
|
-
|
73
|
+
```ruby
|
74
|
+
client.listen liquidation: 'XBTUSD', trade: 'XBTUSD' do |data|
|
75
|
+
puts data
|
61
76
|
end
|
62
77
|
```
|
63
78
|
|
64
|
-
###
|
79
|
+
### API Endpoints
|
80
|
+
|
81
|
+
#### Leaderboard
|
82
|
+
|
83
|
+
See the rock stars.
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
leaders = client.leaderboard
|
87
|
+
puts leaders.first.name
|
88
|
+
```
|
89
|
+
|
90
|
+
#### Order
|
91
|
+
|
92
|
+
Get your orders.
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
orders = client.orders.all
|
96
|
+
puts orders.size
|
97
|
+
```
|
98
|
+
|
99
|
+
Create new order, update and cancel.
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
order = client.orders.create 'XBTUSD', orderQty: 100, price: 1000, clOrdID: 'YOUR_ID'
|
103
|
+
order = client.order(clOrdID: order.clOrdID).update orderQty: qty
|
104
|
+
order = client.order(clOrdID: order.clOrdID).cancel
|
105
|
+
```
|
106
|
+
|
107
|
+
#### Orderbook
|
65
108
|
|
66
|
-
|
109
|
+
Get first bid and ask.
|
67
110
|
|
68
111
|
```ruby
|
112
|
+
orderbook = client.orderbook 'XBTUSD', depth: 1
|
113
|
+
puts orderbook.first.side
|
114
|
+
```
|
115
|
+
|
116
|
+
#### Position
|
117
|
+
|
118
|
+
Get all open positions or change leverage for an open position.
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
positions = client.positions
|
122
|
+
puts positions.size
|
123
|
+
|
124
|
+
position = client.position('XBTUSD').leverage 25
|
125
|
+
puts position.leverage
|
126
|
+
```
|
69
127
|
|
70
|
-
|
128
|
+
#### Stats
|
129
|
+
|
130
|
+
Exchange statistics.
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
history = subject.stats.history
|
134
|
+
puts history
|
135
|
+
```
|
136
|
+
|
137
|
+
#### Trade
|
138
|
+
|
139
|
+
Load first 15 trades after Jan 1st for XBTUSD.
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
trades = client.trades.all symbol: 'XBTUSD', startTime: '2019-01-01', count: 10
|
143
|
+
puts trades.first
|
144
|
+
```
|
145
|
+
|
146
|
+
Listen for new trades and print the ones greater than 10 XBT.
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
client.trades.all symbol: product do |trade|
|
150
|
+
puts "#{trade.side} #{trade.homeNotional} #{trade.symbol} @ #{trade.price}" if trade.homeNotional > 10
|
151
|
+
end
|
152
|
+
```
|
153
|
+
|
154
|
+
#### User
|
155
|
+
|
156
|
+
Fetch user's preferences, wallet, history, events, executions and much more.
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
user = client.user.firstname
|
71
160
|
puts user.firstname
|
72
161
|
|
73
162
|
wallet = client.user.wallet
|
data/TODOs.org
CHANGED
@@ -6,11 +6,20 @@
|
|
6
6
|
** DONE auth for REST-API endpoints
|
7
7
|
CLOSED: [2019-01-16 Wed] SCHEDULED: <2019-01-15 Tue> DEADLINE: <2019-01-16 Wed>
|
8
8
|
** TODO auth for private subscription topics
|
9
|
-
DEADLINE: <2019-01-25 Fri>
|
10
9
|
** move from rspec to minitest
|
11
10
|
** configure autorun
|
12
|
-
** TODO post/put rest-api endpoints
|
13
11
|
** hearbeat, ping/pong
|
14
12
|
** DONE implement user actions get/put/post
|
15
13
|
CLOSED: [2019-01-22 Tue] SCHEDULED: <2019-01-17 Thu>
|
16
|
-
**
|
14
|
+
** DONE trade resource
|
15
|
+
CLOSED: [2019-01-23] SCHEDULED: [2019-01-23 Wed]
|
16
|
+
** DONE stats, settlement, schema, quote, position resources
|
17
|
+
CLOSED: [2019-01-28 Mon] SCHEDULED: <2019-01-28 Mon>
|
18
|
+
** DONE orderbook, order resource
|
19
|
+
CLOSED: [2019-01-29 Tue] SCHEDULED: <2019-01-29 Tue>
|
20
|
+
** refactoring: use class methods when working with multiple entities
|
21
|
+
** issue: {"error":{"message":"Signature not valid.","name":"HTTPError"}} in user#executions
|
22
|
+
** DONE liquidation, leaderboard, insurance, instrument, funding, execution, chat, announcement
|
23
|
+
CLOSED: [2019-01-30 Wed] SCHEDULED: <2019-01-30 Wed>
|
24
|
+
** DONE refactoring: extract websocket common logic
|
25
|
+
CLOSED: [2019-01-31 Thu] SCHEDULED: <2019-01-31 Thu>
|
data/bin/chat.rb
ADDED
data/bin/whales-watching.rb
CHANGED
@@ -8,6 +8,6 @@ limit = (ARGV[1] || 10).to_i
|
|
8
8
|
puts "==> Filter trades > #{limit} #{product}"
|
9
9
|
|
10
10
|
client = Bitmex::Client.new
|
11
|
-
client.
|
12
|
-
puts trade if trade.homeNotional > limit
|
11
|
+
client.trades.all symbol: product do |trade|
|
12
|
+
puts "#{trade.side} #{trade.homeNotional} #{trade.symbol} @ #{trade.price}" if trade.homeNotional > limit
|
13
13
|
end
|
data/bitmex.gemspec
CHANGED
@@ -45,6 +45,9 @@ Gem::Specification.new do |spec|
|
|
45
45
|
spec.add_development_dependency 'rspec'
|
46
46
|
spec.add_development_dependency 'bump'
|
47
47
|
spec.add_development_dependency 'pry'
|
48
|
+
spec.add_development_dependency 'pry-doc'
|
48
49
|
spec.add_development_dependency 'simplecov'
|
49
50
|
spec.add_development_dependency 'dotenv'
|
51
|
+
spec.add_development_dependency 'rubocop'
|
52
|
+
spec.add_development_dependency 'reek'
|
50
53
|
end
|
data/lib/bitmex.rb
CHANGED
@@ -3,12 +3,27 @@ require 'hashie'
|
|
3
3
|
|
4
4
|
require 'bitmex/version'
|
5
5
|
require 'bitmex/mash'
|
6
|
-
|
6
|
+
|
7
|
+
require 'bitmex/base'
|
8
|
+
require 'bitmex/chat'
|
7
9
|
require 'bitmex/client'
|
10
|
+
require 'bitmex/trade'
|
11
|
+
require 'bitmex/stats'
|
12
|
+
require 'bitmex/quote'
|
13
|
+
require 'bitmex/position'
|
14
|
+
require 'bitmex/order'
|
15
|
+
require 'bitmex/instrument'
|
16
|
+
require 'bitmex/user'
|
17
|
+
require 'bitmex/apikey'
|
18
|
+
require 'bitmex/websocket'
|
8
19
|
|
20
|
+
# Bitmex module
|
9
21
|
module Bitmex
|
10
22
|
class Error < StandardError; end
|
11
23
|
|
24
|
+
TESTNET_HOST = 'testnet.bitmex.com'.freeze
|
25
|
+
MAINNET_HOST = 'www.bitmex.com'.freeze
|
26
|
+
|
12
27
|
def self.signature(api_secret, verb, path, expires, params)
|
13
28
|
params = '' if params.nil?
|
14
29
|
params = params.to_s unless params.is_a? String
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Bitmex
|
2
|
+
# Persistent API Keys for Developers
|
3
|
+
# @author Iulian Costan
|
4
|
+
class Apikey < Base
|
5
|
+
attr_reader :api_key
|
6
|
+
|
7
|
+
# Create new Apikey
|
8
|
+
# @param client [Bitmex::Client] the rest client
|
9
|
+
# @param api_key [String] public apikey
|
10
|
+
def initialize(client, api_key = nil)
|
11
|
+
super client
|
12
|
+
@api_key = api_key
|
13
|
+
end
|
14
|
+
|
15
|
+
# Get your API Keys
|
16
|
+
# @return [Array] the api keys
|
17
|
+
def all
|
18
|
+
client.get apikey_path, auth: true do |response|
|
19
|
+
response_handler response
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# NOT SUPPORTED
|
24
|
+
# #return 403 Access Denied
|
25
|
+
def enable
|
26
|
+
client.post apikey_path(:enable) do |response|
|
27
|
+
response_handler response
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# NOT SUPPORTED
|
32
|
+
# @return 403 Access Denied
|
33
|
+
def disable
|
34
|
+
client.post apikey_path(:disable) do |response|
|
35
|
+
response_handler response
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def apikey_path(action = '')
|
42
|
+
base_path :apiKey, action
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/bitmex/base.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Bitmex
|
2
|
+
# Base class for all Bitmex models
|
3
|
+
# @author Iulian Costan
|
4
|
+
class Base
|
5
|
+
attr_reader :client
|
6
|
+
|
7
|
+
# @param client [Bitmex::Client] the client object
|
8
|
+
def initialize(client)
|
9
|
+
@client = client
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def response_handler(response)
|
15
|
+
client.response_handler response
|
16
|
+
end
|
17
|
+
|
18
|
+
def requires!(arg, args)
|
19
|
+
raise ArgumentError, "argument '#{arg}' is required" unless args.include? arg
|
20
|
+
end
|
21
|
+
|
22
|
+
def base_path(resource, action)
|
23
|
+
client.base_path resource, action
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/bitmex/chat.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Bitmex
|
2
|
+
# Trollbox Data
|
3
|
+
# @author Iulian Costan
|
4
|
+
class Chat < Base
|
5
|
+
# Get chat messages
|
6
|
+
# @example Get last 10 messages for channel 1
|
7
|
+
# messages = client.chat.messages channel_id: 1, count: 10, reverse: true
|
8
|
+
# @param options [Hash] options to filter by
|
9
|
+
# @option options [Integer] :count (100) number of results to fetch.
|
10
|
+
# @option options [Integer] :start starting ID for results
|
11
|
+
# @option options [Boolean] :reverse If true, will sort results newest first
|
12
|
+
# @option options [Integer] :channelID Channel id. GET /chat/channels for ids. Leave blank for all.
|
13
|
+
# @return [Array] the messages
|
14
|
+
def messages(options = { count: 100, reverse: true })
|
15
|
+
params = {
|
16
|
+
count: options[:count], start: options[:start],
|
17
|
+
reverse: options[:reverse], channelID: options[:channel_id]
|
18
|
+
}
|
19
|
+
client.get chat_path, params: params do |response|
|
20
|
+
response_handler response
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Get available channels
|
25
|
+
# @return [Array] the available channels
|
26
|
+
def channels
|
27
|
+
client.get chat_path(:channels) do |response|
|
28
|
+
response_handler response
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Get connected users
|
33
|
+
# @return [Bitmex::Mash] an array with browser users in the first position and API users (bots) in the second position.
|
34
|
+
def stats
|
35
|
+
client.get chat_path(:connected) do |response|
|
36
|
+
response_handler response
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Send a chat message
|
41
|
+
# @param message [String] the message to send
|
42
|
+
# @param options [Hash] filter options
|
43
|
+
# @option options [Integer] :channel_id (1) channel to post to
|
44
|
+
def send(message, options = { channel_id: 1 })
|
45
|
+
params = { message: message, channelID: options[:channel_id] }
|
46
|
+
client.post chat_path, params: params do |response|
|
47
|
+
response_handler response
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def chat_path(action = '')
|
54
|
+
base_path :chat, action
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|