bitmex-api 0.0.2 → 0.0.3

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
  SHA256:
3
- metadata.gz: 06e316d8a60be97f37a23ff0f9f7055d02fd1cd743a12f84c4982feff80ea476
4
- data.tar.gz: 4868b686189f662a8b47e1305ac6c6f854922984256297b68531082571cb7afd
3
+ metadata.gz: 92b401dc2774b95aa169e7ed7406eb7c1674f4a88b5ceb1920a268f1d7a129d3
4
+ data.tar.gz: b2cd44806b551a6f8fa4cec72988975013ccd5799779b1bf58e2e796e792a0d2
5
5
  SHA512:
6
- metadata.gz: 8ad1b9fbc349b5c8a80deb584c2bf61a5a62fbe744d8d2a4ff43b2b730f4b56aabcc92aa0175df962b785e257cecedb64da3b2eefc5a7f9f253795d670b2147e
7
- data.tar.gz: 307c8ffd8cd00b41bd13c79e20533e1a64950fb7e8c229e917e1d161d8b08a63d8e470290cddeb13815768b111b2d712851b03f8555f34a583efdd9a1939ef55
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.2)
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
- Idiomatic Ruby library for [BitMEX API](https://www.bitmex.com/app/apiOverview).
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 API
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
- ### Trades
40
+ ### REST and Websocket API
40
41
 
41
42
  #### Using REST API
42
43
 
43
- Load first 15 trades after Jan 1st for XBTUSD.
44
+ Get last 10 messages in English channel:
44
45
 
45
46
  ```ruby
46
- trades = client.trade symbol: 'XBTUSD', count: 15, startTime: '2019-01-01'
47
- trades.size
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
- Listen for new trades and print the ones greater than 10 XBT.
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 if trade.homeNotional > 10
67
+ puts trade.homeNotional
68
+ end
69
+ ```
70
+
71
+ Or multiple topics at the same time.
58
72
 
59
- # when done call client.stop
60
- # client.stop
73
+ ```ruby
74
+ client.listen liquidation: 'XBTUSD', trade: 'XBTUSD' do |data|
75
+ puts data
61
76
  end
62
77
  ```
63
78
 
64
- ### Account operations
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
- Fetch user's preferences, wallet, history, events and much more.
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
- user = client.user
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
- ** order actions
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
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'bitmex'
5
+
6
+ puts 'Listening to chat message from English channel...'
7
+
8
+ client = Bitmex::Client.new
9
+ client.listen chat: 1 do |message|
10
+ puts "#{message.user}: #{message.message}"
11
+ end
@@ -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.listen trade: product do |trade|
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
- require 'bitmex/user'
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
@@ -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
@@ -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