bitfinex-rb 0.0.11 → 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/lib/bitfinex-rb.rb +1 -0
- data/lib/bitfinex.rb +25 -14
- data/lib/bitfinex/api_versions.rb +7 -0
- data/lib/bitfinex/authenticated_rest.rb +26 -6
- data/lib/bitfinex/client.rb +30 -14
- data/lib/bitfinex/configurable.rb +9 -0
- data/lib/bitfinex/connection.rb +4 -2
- data/lib/bitfinex/errors.rb +5 -4
- data/lib/bitfinex/{account_info.rb → v1/account_info.rb} +11 -2
- data/lib/bitfinex/{deposit.rb → v1/deposit.rb} +2 -1
- data/lib/bitfinex/{funding_book.rb → v1/funding_book.rb} +1 -1
- data/lib/bitfinex/{historical_data.rb → v1/historical_data.rb} +1 -1
- data/lib/bitfinex/{lends.rb → v1/lends.rb} +1 -1
- data/lib/bitfinex/{margin_funding.rb → v1/margin_funding.rb} +7 -4
- data/lib/bitfinex/{orderbook.rb → v1/orderbook.rb} +4 -4
- data/lib/bitfinex/{orders.rb → v1/orders.rb} +3 -4
- data/lib/bitfinex/{positions.rb → v1/positions.rb} +1 -1
- data/lib/bitfinex/{stats.rb → v1/stats.rb} +1 -1
- data/lib/bitfinex/{symbols.rb → v1/symbols.rb} +3 -3
- data/lib/bitfinex/{ticker.rb → v1/ticker.rb} +2 -2
- data/lib/bitfinex/{trades.rb → v1/trades.rb} +3 -3
- data/lib/bitfinex/{wallet.rb → v1/wallet.rb} +1 -1
- data/lib/bitfinex/v2/margin.rb +34 -0
- data/lib/bitfinex/v2/personal.rb +94 -0
- data/lib/bitfinex/v2/stats.rb +27 -0
- data/lib/bitfinex/v2/ticker.rb +58 -0
- data/lib/bitfinex/v2/trading.rb +146 -0
- data/lib/bitfinex/v2/utils.rb +27 -0
- data/lib/bitfinex/version.rb +1 -1
- data/lib/bitfinex/websocket_connection.rb +49 -28
- metadata +25 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1b2e7fdeb41e8d0de71ff3ab3a8c8f65b438f74
|
4
|
+
data.tar.gz: 5ee463c95bed54185d0ad7b0bd99c75c2ad461ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a393e8688103054bd93c9b73799c96a8ff6a921155ad1064f12de83332d82c32c7e244153b0ffea1390232b9454761c323aebc35523715f02fd6318ae5f28932
|
7
|
+
data.tar.gz: d33751ff047447639cf5f2e7034e14e96b7dcf414984a1e72dde42a40e07c05aa2156ac0287653651f4b33c7452e8e27c485d30a8a5d5e2f590566fb17a75568
|
data/lib/bitfinex-rb.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative "./bitfinex.rb"
|
data/lib/bitfinex.rb
CHANGED
@@ -9,19 +9,30 @@ require 'bitfinex/errors'
|
|
9
9
|
require 'bitfinex/connection'
|
10
10
|
require 'bitfinex/websocket_connection'
|
11
11
|
require 'bitfinex/authenticated_rest'
|
12
|
-
require 'bitfinex/
|
13
|
-
require 'bitfinex/trades'
|
14
|
-
require 'bitfinex/funding_book'
|
15
|
-
require 'bitfinex/orderbook'
|
16
|
-
require 'bitfinex/lends'
|
17
|
-
require 'bitfinex/symbols'
|
18
|
-
require 'bitfinex/stats'
|
19
|
-
require 'bitfinex/account_info'
|
20
|
-
require 'bitfinex/deposit'
|
21
|
-
require 'bitfinex/orders'
|
22
|
-
require 'bitfinex/wallet'
|
23
|
-
require 'bitfinex/positions'
|
24
|
-
require 'bitfinex/historical_data'
|
25
|
-
require 'bitfinex/margin_funding'
|
12
|
+
require 'bitfinex/api_versions'
|
26
13
|
require 'bitfinex/client'
|
27
14
|
|
15
|
+
# API Version 1
|
16
|
+
require 'bitfinex/v1/ticker'
|
17
|
+
require 'bitfinex/v1/trades'
|
18
|
+
require 'bitfinex/v1/funding_book'
|
19
|
+
require 'bitfinex/v1/orderbook'
|
20
|
+
require 'bitfinex/v1/lends'
|
21
|
+
require 'bitfinex/v1/symbols'
|
22
|
+
require 'bitfinex/v1/stats'
|
23
|
+
require 'bitfinex/v1/account_info'
|
24
|
+
require 'bitfinex/v1/deposit'
|
25
|
+
require 'bitfinex/v1/orders'
|
26
|
+
require 'bitfinex/v1/wallet'
|
27
|
+
require 'bitfinex/v1/positions'
|
28
|
+
require 'bitfinex/v1/historical_data'
|
29
|
+
require 'bitfinex/v1/margin_funding'
|
30
|
+
|
31
|
+
# API Version 2
|
32
|
+
require 'bitfinex/v2/stats'
|
33
|
+
require 'bitfinex/v2/ticker'
|
34
|
+
require 'bitfinex/v2/utils'
|
35
|
+
require 'bitfinex/v2/personal'
|
36
|
+
require 'bitfinex/v2/trading'
|
37
|
+
require 'bitfinex/v2/margin'
|
38
|
+
|
@@ -5,27 +5,47 @@ module Bitfinex
|
|
5
5
|
def authenticated_post(url, options = {})
|
6
6
|
raise Bitfinex::InvalidAuthKeyError unless valid_key?
|
7
7
|
complete_url = build_url(url)
|
8
|
-
|
8
|
+
body = options[:params] || {}
|
9
|
+
nonce = new_nonce
|
10
|
+
|
11
|
+
payload = if config.api_version == 1
|
12
|
+
build_payload("/v1/#{url}", options[:params], nonce)
|
13
|
+
else
|
14
|
+
"/api#{complete_url}#{nonce}#{body.to_json}"
|
15
|
+
end
|
16
|
+
|
9
17
|
response = rest_connection.post do |req|
|
10
18
|
req.url complete_url
|
19
|
+
req.body = body.to_json
|
11
20
|
req.options.timeout = config.rest_timeout
|
12
21
|
req.options.open_timeout = config.rest_open_timeout
|
13
22
|
req.headers['Content-Type'] = 'application/json'
|
14
23
|
req.headers['Accept'] = 'application/json'
|
15
|
-
|
16
|
-
|
17
|
-
|
24
|
+
|
25
|
+
if config.api_version == 1
|
26
|
+
req.headers['X-BFX-PAYLOAD'] = payload
|
27
|
+
req.headers['X-BFX-SIGNATURE'] = sign(payload)
|
28
|
+
req.headers['X-BFX-APIKEY'] = config.api_key
|
29
|
+
else
|
30
|
+
req.headers['bfx-nonce'] = nonce
|
31
|
+
req.headers['bfx-signature'] = sign(payload)
|
32
|
+
req.headers['bfx-apikey'] = config.api_key
|
33
|
+
end
|
18
34
|
end
|
19
35
|
end
|
20
36
|
|
21
|
-
def build_payload(url, params = {})
|
37
|
+
def build_payload(url, params = {}, nonce)
|
22
38
|
payload = {}
|
23
|
-
payload['nonce'] =
|
39
|
+
payload['nonce'] = nonce
|
24
40
|
payload['request'] = url
|
25
41
|
payload.merge!(params) if params
|
26
42
|
Base64.strict_encode64(payload.to_json)
|
27
43
|
end
|
28
44
|
|
45
|
+
def new_nonce
|
46
|
+
(Time.now.to_f * 10_000).to_i.to_s
|
47
|
+
end
|
48
|
+
|
29
49
|
def sign(payload)
|
30
50
|
OpenSSL::HMAC.hexdigest('sha384', config.secret, payload)
|
31
51
|
end
|
data/lib/bitfinex/client.rb
CHANGED
@@ -3,20 +3,36 @@ module Bitfinex
|
|
3
3
|
include Bitfinex::RestConnection
|
4
4
|
include Bitfinex::WebsocketConnection
|
5
5
|
include Bitfinex::AuthenticatedConnection
|
6
|
-
include Bitfinex::TickerClient
|
7
|
-
include Bitfinex::TradesClient
|
8
|
-
include Bitfinex::FundingBookClient
|
9
|
-
include Bitfinex::OrderbookClient
|
10
|
-
include Bitfinex::StatsClient
|
11
|
-
include Bitfinex::LendsClient
|
12
|
-
include Bitfinex::SymbolsClient
|
13
|
-
include Bitfinex::AccountInfoClient
|
14
|
-
include Bitfinex::DepositClient
|
15
|
-
include Bitfinex::OrdersClient
|
16
|
-
include Bitfinex::PositionsClient
|
17
|
-
include Bitfinex::HistoricalDataClient
|
18
|
-
include Bitfinex::MarginFundingClient
|
19
|
-
include Bitfinex::WalletClient
|
20
6
|
include Bitfinex::Configurable
|
7
|
+
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
if config.api_version == 1
|
11
|
+
extend Bitfinex::V1::TickerClient
|
12
|
+
extend Bitfinex::V1::TradesClient
|
13
|
+
extend Bitfinex::V1::FundingBookClient
|
14
|
+
extend Bitfinex::V1::OrderbookClient
|
15
|
+
extend Bitfinex::V1::StatsClient
|
16
|
+
extend Bitfinex::V1::LendsClient
|
17
|
+
extend Bitfinex::V1::SymbolsClient
|
18
|
+
extend Bitfinex::V1::AccountInfoClient
|
19
|
+
extend Bitfinex::V1::DepositClient
|
20
|
+
extend Bitfinex::V1::OrdersClient
|
21
|
+
extend Bitfinex::V1::PositionsClient
|
22
|
+
extend Bitfinex::V1::HistoricalDataClient
|
23
|
+
extend Bitfinex::V1::MarginFundingClient
|
24
|
+
extend Bitfinex::V1::WalletClient
|
25
|
+
else
|
26
|
+
extend Bitfinex::V2::TickerClient
|
27
|
+
extend Bitfinex::V2::StatsClient
|
28
|
+
extend Bitfinex::V2::UtilsClient
|
29
|
+
extend Bitfinex::V2::PersonalClient
|
30
|
+
extend Bitfinex::V2::TradingClient
|
31
|
+
extend Bitfinex::V2::MarginClient
|
32
|
+
end
|
33
|
+
|
34
|
+
@mutex = Mutex.new
|
35
|
+
@c_counter = 1
|
36
|
+
end
|
21
37
|
end
|
22
38
|
end
|
@@ -23,6 +23,7 @@ module Bitfinex
|
|
23
23
|
attr_accessor :api_endpoint, :debug, :debug_connection, :secret
|
24
24
|
attr_accessor :api_key, :websocket_api_endpoint, :rest_timeout
|
25
25
|
attr_accessor :reconnect, :reconnect_after, :rest_open_timeout
|
26
|
+
attr_accessor :api_version
|
26
27
|
|
27
28
|
def initialize
|
28
29
|
self.api_endpoint = "https://api.bitfinex.com/v1/"
|
@@ -33,6 +34,14 @@ module Bitfinex
|
|
33
34
|
self.rest_timeout = 30
|
34
35
|
self.rest_open_timeout = 30
|
35
36
|
self.debug_connection = false
|
37
|
+
self.api_version = 1
|
38
|
+
end
|
39
|
+
|
40
|
+
# Helper that configure to version 2
|
41
|
+
def use_api_v2
|
42
|
+
self.api_version = 2
|
43
|
+
self.api_endpoint = "https://api.bitfinex.com/v2/"
|
44
|
+
self.websocket_api_endpoint = "wss://api.bitfinex.com/ws/2/"
|
36
45
|
end
|
37
46
|
end
|
38
47
|
|
data/lib/bitfinex/connection.rb
CHANGED
@@ -4,12 +4,14 @@ module Bitfinex
|
|
4
4
|
module RestConnection
|
5
5
|
private
|
6
6
|
# Make an HTTP GET request
|
7
|
-
def get(url,
|
7
|
+
def get(url, params={})
|
8
8
|
rest_connection.get do |req|
|
9
9
|
req.url build_url(url)
|
10
10
|
req.headers['Content-Type'] = 'application/json'
|
11
11
|
req.headers['Accept'] = 'application/json'
|
12
|
-
|
12
|
+
params.each do |k,v|
|
13
|
+
req.params[k] = v
|
14
|
+
end
|
13
15
|
req.options.timeout = config.rest_timeout
|
14
16
|
req.options.open_timeout = config.rest_open_timeout
|
15
17
|
end
|
data/lib/bitfinex/errors.rb
CHANGED
@@ -12,6 +12,7 @@ module Bitfinex
|
|
12
12
|
class ForbiddenError < ServerError; end
|
13
13
|
class UnauthorizedError < ServerError; end
|
14
14
|
class InternalServerError < ServerError; end
|
15
|
+
class WebsocketError < ServerError; end
|
15
16
|
|
16
17
|
class CustomErrors < Faraday::Response::Middleware
|
17
18
|
def on_complete(env)
|
@@ -19,13 +20,13 @@ module Bitfinex
|
|
19
20
|
when 400
|
20
21
|
raise BadRequestError, env.body['message']
|
21
22
|
when 401
|
22
|
-
raise UnauthorizedError
|
23
|
+
raise UnauthorizedError, env.body['message']
|
23
24
|
when 403
|
24
|
-
raise ForbiddenError
|
25
|
+
raise ForbiddenError, env.body['message']
|
25
26
|
when 404
|
26
|
-
raise NotFoundError
|
27
|
+
raise NotFoundError, env.body['message']
|
27
28
|
when 500
|
28
|
-
raise InternalServerError
|
29
|
+
raise InternalServerError, env.body['message']
|
29
30
|
else
|
30
31
|
super
|
31
32
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Bitfinex
|
2
|
-
|
3
|
-
module AccountInfoClient
|
2
|
+
module V1::AccountInfoClient
|
4
3
|
|
5
4
|
# Get account information
|
6
5
|
#
|
@@ -24,6 +23,16 @@ module Bitfinex
|
|
24
23
|
raise BlockMissingError unless block_given?
|
25
24
|
ws_auth(&block)
|
26
25
|
end
|
26
|
+
|
27
|
+
# See the fees applied to your withdrawals
|
28
|
+
#
|
29
|
+
# @return [Hash]
|
30
|
+
# @example:
|
31
|
+
# client.fees
|
32
|
+
def fees
|
33
|
+
resp = authenticated_post("fees")
|
34
|
+
resp.body
|
35
|
+
end
|
27
36
|
end
|
28
37
|
|
29
38
|
end
|
@@ -1,23 +1,26 @@
|
|
1
1
|
module Bitfinex
|
2
|
-
module MarginFundingClient
|
2
|
+
module V1::MarginFundingClient
|
3
3
|
|
4
4
|
# Submit a new offer
|
5
5
|
#
|
6
6
|
# @param currency [string] The name of the currency, es: 'USD'
|
7
7
|
# @param amount [decimal] Offer size: how much to lend or borrow
|
8
|
-
# @param rate [decimal] Rate to lend or borrow at. In percentage per 365 days.
|
8
|
+
# @param rate [decimal] Rate to lend or borrow at. In percentage per 365 days.
|
9
|
+
# Set to 0 for FRR, ±delta for FRR±delta.
|
9
10
|
# @param period [integer] Number of days of the funding contract (in days)
|
10
11
|
# @param direction [string] Either “lend” or “loan”
|
12
|
+
# @param frrdelta [bool] If true, the rate represents ±delta to FRR.
|
11
13
|
# @return [Hash]
|
12
14
|
# @example:
|
13
15
|
# client.new_offer("btc", 10.0, 20, 365, "lend")
|
14
|
-
def new_offer(currency, amount, rate, period, direction)
|
16
|
+
def new_offer(currency, amount, rate, period, direction, frrdelta=false)
|
15
17
|
params = {
|
16
18
|
currency: currency,
|
17
19
|
amount: amount.to_s,
|
18
20
|
rate: rate.to_s,
|
19
21
|
period: period.to_i,
|
20
|
-
direction: direction
|
22
|
+
direction: direction,
|
23
|
+
frrdelta: !!frrdelta
|
21
24
|
}
|
22
25
|
authenticated_post("offer/new", params: params).body
|
23
26
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
module Bitfinex
|
3
|
-
module OrderbookClient
|
3
|
+
module V1::OrderbookClient
|
4
4
|
|
5
5
|
# Get the full order book
|
6
6
|
#
|
7
|
-
# @param symbol [string]
|
7
|
+
# @param symbol [string]
|
8
8
|
# @param params :limit_bids [int] (optional) Limit the number of bids returned. May be 0 in which case the array of bids is empty. Default 50.
|
9
9
|
# @param params :limit_asks [int] (optional) Limit the number of asks returned. May be 0 in which case the array of asks is empty. Default 50.
|
10
10
|
# @param params :group [0/1] (optional) If 1, orders are grouped by price in the orderbook. If 0, orders are not grouped and sorted individually. Default 1
|
@@ -18,8 +18,8 @@ module Bitfinex
|
|
18
18
|
|
19
19
|
|
20
20
|
# Get the order book changes using websocket
|
21
|
-
#
|
22
|
-
# @param pair [string]
|
21
|
+
#
|
22
|
+
# @param pair [string]
|
23
23
|
# @param prec [string] Level of price aggregation (P0, P1, P2, P3). The default is P0.
|
24
24
|
# @param freq [string] Frequency of updates (F0, F1, F2, F3). F0=realtime / F1=2sec / F2=5sec / F3=10sec
|
25
25
|
# @param len [int] Number of price points (“25”, “100”) [default=“25”]
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Bitfinex
|
2
|
-
|
3
|
-
module OrdersClient
|
2
|
+
module V1::OrdersClient
|
4
3
|
|
5
4
|
# Submit a new order
|
6
5
|
# @param symbol [string] The name of the symbol (see `#symbols`)
|
@@ -27,7 +26,7 @@ module Bitfinex
|
|
27
26
|
type: type,
|
28
27
|
side: side,
|
29
28
|
exchange: 'bitfinex',
|
30
|
-
price: price.
|
29
|
+
price: "%.10f" % price.to_f.round(10) # Decimalize float price (necessary for small numbers)
|
31
30
|
})
|
32
31
|
authenticated_post("order/new", params: params).body
|
33
32
|
end
|
@@ -45,7 +44,7 @@ module Bitfinex
|
|
45
44
|
# @example:
|
46
45
|
# client.multiple_orders([{symbol: "usdbtc", amount: 10, price: 0, exchange: "bitfinex", side: "buy", type: "market"}])
|
47
46
|
def multiple_orders(orders)
|
48
|
-
authenticated_post("order/new/multi", params: orders).body
|
47
|
+
authenticated_post("order/new/multi", params: {orders: orders}).body
|
49
48
|
end
|
50
49
|
|
51
50
|
# Cancel an order
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Bitfinex
|
2
|
-
module SymbolsClient
|
3
|
-
|
2
|
+
module V1::SymbolsClient
|
3
|
+
|
4
4
|
# Get a list of valid symbol IDs.
|
5
5
|
#
|
6
6
|
# @return [Array]
|
@@ -17,6 +17,6 @@ module Bitfinex
|
|
17
17
|
# client.symbols_details
|
18
18
|
def symbols_details
|
19
19
|
get("symbols_details").body
|
20
|
-
end
|
20
|
+
end
|
21
21
|
end
|
22
22
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Bitfinex
|
2
|
-
module TickerClient
|
2
|
+
module V1::TickerClient
|
3
3
|
|
4
4
|
# Gives innermost bid and asks and information on the most recent trade, as well as high, low and volume of the last 24 hours.
|
5
5
|
#
|
@@ -14,7 +14,7 @@ module Bitfinex
|
|
14
14
|
# Call the specified block passing tickers, it uses websocket
|
15
15
|
#
|
16
16
|
# @param pair [string]
|
17
|
-
# @param block [Block] The code to be executed when a new ticker is sent by the server
|
17
|
+
# @param block [Block] The code to be executed when a new ticker is sent by the server
|
18
18
|
# @example:
|
19
19
|
# client.listen_ticker do |tick|
|
20
20
|
# puts tick.inspect
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Bitfinex
|
2
|
-
module TradesClient
|
2
|
+
module V1::TradesClient
|
3
3
|
|
4
4
|
# Get a list of the most recent trades for the given symbol.
|
5
5
|
#
|
@@ -7,11 +7,11 @@ module Bitfinex
|
|
7
7
|
# @param params :timestamp [time] Only show trades at or after this timestamp.
|
8
8
|
# @param params :limit_trades [int] Limit the number of trades returned. Must be >= 1.
|
9
9
|
# @return [Array]
|
10
|
-
# @example:
|
10
|
+
# @example:
|
11
11
|
# client.trades
|
12
12
|
def trades(symbol="btcusd", params={})
|
13
13
|
check_params(params, %i{timestamp limit_trades})
|
14
|
-
get("trades/#{symbol}", params
|
14
|
+
get("trades/#{symbol}", params).body
|
15
15
|
end
|
16
16
|
|
17
17
|
# Listen to the trades using websocket.
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Bitfinex
|
2
|
+
module V2::MarginClient
|
3
|
+
|
4
|
+
# Get active offers
|
5
|
+
#
|
6
|
+
# @example:
|
7
|
+
# client.offers
|
8
|
+
def offers
|
9
|
+
authenticated_post("auth/r/offers").body
|
10
|
+
end
|
11
|
+
|
12
|
+
# Get account margin info
|
13
|
+
# - if symbol is not specified return everything
|
14
|
+
#
|
15
|
+
# @param symbol [string] (optional)
|
16
|
+
#
|
17
|
+
# @example:
|
18
|
+
# client.margin_info("tBTCUSD")
|
19
|
+
def margin_info(symbol = "base")
|
20
|
+
authenticated_post("auth/r/margin/#{symbol}").body
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
# Get account funding info
|
25
|
+
#
|
26
|
+
# @param symbol [string] default fUSD
|
27
|
+
#
|
28
|
+
# @example:
|
29
|
+
# client.funding_info
|
30
|
+
def funding_info(symbol = "fUSD")
|
31
|
+
authenticated_post("auth/r/funding/#{symbol}").body
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Bitfinex
|
2
|
+
module V2::PersonalClient
|
3
|
+
|
4
|
+
# Get account wallets
|
5
|
+
#
|
6
|
+
# @example:
|
7
|
+
# client.wallets
|
8
|
+
def wallets
|
9
|
+
authenticated_post("auth/r/wallets").body
|
10
|
+
end
|
11
|
+
|
12
|
+
# Get account historical daily performance
|
13
|
+
#
|
14
|
+
# @example:
|
15
|
+
# client.performance
|
16
|
+
def performance
|
17
|
+
authenticated_post("auth/r/stats/perf:1D/hist")
|
18
|
+
end
|
19
|
+
|
20
|
+
# Get the list of alerts
|
21
|
+
#
|
22
|
+
# @example:
|
23
|
+
# client.alerts
|
24
|
+
def alerts(type = 'price')
|
25
|
+
authenticated_post("auth/r/alerts", params: {type: type}).body
|
26
|
+
end
|
27
|
+
|
28
|
+
# Set a new alert
|
29
|
+
#
|
30
|
+
# @param price
|
31
|
+
# @param symbol
|
32
|
+
# @param type
|
33
|
+
#
|
34
|
+
# @example:
|
35
|
+
# client.alert(3000, "tBTCUSD")
|
36
|
+
def alert(price, symbol = "tBTCUSD", type = "price")
|
37
|
+
params = {
|
38
|
+
type: type,
|
39
|
+
price: price,
|
40
|
+
symbol: symbol
|
41
|
+
}
|
42
|
+
authenticated_post("auth/w/alert/set", params: params).body
|
43
|
+
end
|
44
|
+
|
45
|
+
# Delete an existing alert
|
46
|
+
#
|
47
|
+
# @param price
|
48
|
+
# @param symbol
|
49
|
+
#
|
50
|
+
# @example:
|
51
|
+
# client.delete_alert(3000, "tBTCUSD")
|
52
|
+
def delete_alert(price, symbol = "tBTCUSD")
|
53
|
+
authenticated_post("auth/w/alert/price:#{symbol}:#{price}/del").body
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
# Calculate available balance for order/offer
|
58
|
+
#
|
59
|
+
# @param rate [int] Rate of the order/offer
|
60
|
+
# @param dir [int] direction of the order/offer
|
61
|
+
# (orders: > 0 buy, < 0 sell | offers:
|
62
|
+
# > 0 sell, < 0 buy)
|
63
|
+
# @param type [string] Type of the order/offer
|
64
|
+
# EXCHANGE or MARGIN
|
65
|
+
# @param symbol [string]
|
66
|
+
|
67
|
+
# @example:
|
68
|
+
# client.available_balance(800, 1, 'EXCHANGE', 'tBTCUSD')
|
69
|
+
def available_balance(rate, dir, type, symbol)
|
70
|
+
params = {
|
71
|
+
symbol: symbol,
|
72
|
+
dir: dir,
|
73
|
+
type: type,
|
74
|
+
rate: rate
|
75
|
+
}
|
76
|
+
authenticated_post("auth/calc/order/avail", params: params).body
|
77
|
+
end
|
78
|
+
|
79
|
+
# Listen to authenticated channel
|
80
|
+
#
|
81
|
+
# Documentation:
|
82
|
+
# https://docs.bitfinex.com/v2/reference#account-info
|
83
|
+
#
|
84
|
+
# example:
|
85
|
+
# client.listen_account do |account|
|
86
|
+
# puts account
|
87
|
+
# end
|
88
|
+
def listen_account(&block)
|
89
|
+
raise BlockMissingError unless block_given?
|
90
|
+
ws_auth(&block)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Bitfinex
|
4
|
+
module V2::StatsClient
|
5
|
+
|
6
|
+
# Various statistics about the requested pair.
|
7
|
+
#
|
8
|
+
# @param symbol [string] The symbol you want information about.
|
9
|
+
# @param key [string] Allowed values: "funding.size",
|
10
|
+
# "credits.size", "credits.size.sym", "pos.size"
|
11
|
+
# @param side [string] Available values: "long", "short"
|
12
|
+
# @param section [string] Available values: "last", "hist"
|
13
|
+
# @param size [string] Available values: '1m'
|
14
|
+
# @param params :sort [int32] if = 1 it sorts results
|
15
|
+
# returned with old > new
|
16
|
+
#
|
17
|
+
# @return [Array]
|
18
|
+
#
|
19
|
+
# @example:
|
20
|
+
# client.stats('fUSD', 'pos.size')
|
21
|
+
def stats(symbol = 'fUSD', key = 'funding.size', side = "long", section = "last", size = '1m', params = {})
|
22
|
+
check_params(params, %i{sort})
|
23
|
+
get("stats1/#{key}:#{size}:#{symbol}:#{side}/#{section}").body
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Bitfinex
|
4
|
+
module V2::TickerClient
|
5
|
+
|
6
|
+
# Gives innermost bid and asks and information on
|
7
|
+
# the most recent trade, as well as high, low and
|
8
|
+
# volume of the last 24 hours.
|
9
|
+
#
|
10
|
+
# @param symbols a list of symbols
|
11
|
+
# @return [Hash]
|
12
|
+
# @example:
|
13
|
+
# client.ticker("tBTCUSD","tLTCUSD","fUSD")
|
14
|
+
def ticker(*symbols)
|
15
|
+
if symbols.size == 1
|
16
|
+
get("ticker/#{symbols.first}").body
|
17
|
+
else
|
18
|
+
get("tickers", symbols: "#{symbols.flatten.join(",")}").body
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Call the specified block passing tickers, it uses websocket
|
23
|
+
#
|
24
|
+
# @param pair [string]
|
25
|
+
# @param block [Block] The code to be executed when a new ticker is sent by the server
|
26
|
+
#
|
27
|
+
# Documentation:
|
28
|
+
# https://docs.bitfinex.com/v2/reference#ws-public-ticker
|
29
|
+
#
|
30
|
+
# @example:
|
31
|
+
# client.listen_ticker do |tick|
|
32
|
+
# puts tick.inspect
|
33
|
+
# end
|
34
|
+
def listen_ticker(pair="tBTCUSD", &block)
|
35
|
+
raise BlockMissingError unless block_given?
|
36
|
+
register_channel pair: pair, channel: "ticker", &block
|
37
|
+
end
|
38
|
+
|
39
|
+
# Provides a way to access charting candle info
|
40
|
+
#
|
41
|
+
# @param symbol [string]
|
42
|
+
# @param time_frame [string] default '1m' - see doc for list of options
|
43
|
+
#
|
44
|
+
# Documentation:
|
45
|
+
# https://docs.bitfinex.com/v2/reference#ws-public-candle
|
46
|
+
#
|
47
|
+
# @example:
|
48
|
+
# client.listen_candles("tBTCUSD","1m") do |candle|
|
49
|
+
# puts "high #{candle[1][8]} | low #{candle[1][9]}"
|
50
|
+
# end
|
51
|
+
def listen_candles(symbol="tBTCUSD", time_frame="1m", &block)
|
52
|
+
raise BlockMissingError unless block_given?
|
53
|
+
key = "trade:#{time_frame}:#{symbol}"
|
54
|
+
register_channel key: key, channel: 'candles', &block
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module Bitfinex
|
2
|
+
module V2::TradingClient
|
3
|
+
|
4
|
+
# Provides a way to access charting candle info
|
5
|
+
#
|
6
|
+
# @param symbol [string] The symbol you want information about.
|
7
|
+
# @param timeframe [string] Available values: '1m', '5m', '15m',
|
8
|
+
# '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D', '1M'
|
9
|
+
# @param section [string] Available values: "last", "hist"
|
10
|
+
# @param params :limit [int32] Number of candles requested
|
11
|
+
# @param params :start [int32] Filter start (ms)
|
12
|
+
# @param params :end [int32] Filter end (ms)
|
13
|
+
# @param params :sort [int32] if = 1 it sorts
|
14
|
+
# results returned with old > new
|
15
|
+
#
|
16
|
+
# @return [Array]
|
17
|
+
#
|
18
|
+
# @example:
|
19
|
+
# client.candles('tBTCUSD')
|
20
|
+
def candles(symbol = 'tBTCUSD', timeframe = '1m', section = "last", params = {})
|
21
|
+
check_params(params, %i{limit start end sort})
|
22
|
+
get("candles/trade:#{timeframe}:#{symbol}/#{section}", params).body
|
23
|
+
end
|
24
|
+
|
25
|
+
# The Order Books channel allow you to keep track
|
26
|
+
# of the state of the Bitfinex order book.
|
27
|
+
# It is provided on a price aggregated basis,
|
28
|
+
# with customizable precision.
|
29
|
+
#
|
30
|
+
#
|
31
|
+
# @param symbol [string] The symbol you want
|
32
|
+
# information about. You can find the list of
|
33
|
+
# valid symbols by calling the /symbols
|
34
|
+
# endpoint.
|
35
|
+
# @param precision [string] Level of price
|
36
|
+
# aggregation (P0, P1, P2, P3, R0)
|
37
|
+
# @param params :len [int32] Number of price
|
38
|
+
# points ("25", "100")
|
39
|
+
#
|
40
|
+
# @return [Hash] :bids [Array], :asks [Array]
|
41
|
+
#
|
42
|
+
# @example:
|
43
|
+
# client.orderbook("btcusd")
|
44
|
+
def books(symbol="btcusd", precision="P0", params = {})
|
45
|
+
check_params(params, %i{len})
|
46
|
+
get("book/#{symbol}/#{precision}", params: params).body
|
47
|
+
end
|
48
|
+
|
49
|
+
# Trades endpoint includes all the pertinent details
|
50
|
+
# of the trade, such as price, size and time.
|
51
|
+
#
|
52
|
+
# @param symbol [string] the name of the symbol
|
53
|
+
# @param params :limit [int32] Number of records
|
54
|
+
# @param params :start [int32] Millisecond start time
|
55
|
+
# @param params :end [int32] Millisecond end time
|
56
|
+
# @param params :sort [int32] if = 1 it sorts
|
57
|
+
# results returned with old > new
|
58
|
+
#
|
59
|
+
# @return [Array]
|
60
|
+
#
|
61
|
+
# @example:
|
62
|
+
# client.trades("tETHUSD")
|
63
|
+
def trades(symbol="tBTCUSD", params={})
|
64
|
+
check_params(params, %i{limit start end sort})
|
65
|
+
get("trades/#{symbol}", params).body
|
66
|
+
end
|
67
|
+
|
68
|
+
# Get active orders
|
69
|
+
#
|
70
|
+
# example:
|
71
|
+
# client.orders
|
72
|
+
def orders
|
73
|
+
authenticated_post("auth/r/orders").body
|
74
|
+
end
|
75
|
+
|
76
|
+
# Get Trades generated by an Order
|
77
|
+
#
|
78
|
+
# @param order_id [int32] Id of the order
|
79
|
+
# @param symbol [string] symbol used for the order
|
80
|
+
#
|
81
|
+
# @return [Array]
|
82
|
+
#
|
83
|
+
# @example:
|
84
|
+
# client.order_trades 10010, "tBTCUSD"
|
85
|
+
#
|
86
|
+
def order_trades(order_id, symbol="tBTCUSD")
|
87
|
+
authenticated_post("auth/r/order/#{symbol}:#{order_id}/trades").body
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
# Get active positions
|
92
|
+
#
|
93
|
+
# return [Array]
|
94
|
+
#
|
95
|
+
# @example:
|
96
|
+
# client.active_positions
|
97
|
+
def active_positions
|
98
|
+
authenticated_post("auth/positions").body
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
# This channel sends a trade message whenever a trade occurs at Bitfinex.
|
103
|
+
# It includes all the pertinent details of the trade, such as price, size and time.
|
104
|
+
#
|
105
|
+
# @param symbol [string]
|
106
|
+
# @param block [Block] The code to be executed when a new ticker is sent by the server
|
107
|
+
#
|
108
|
+
# Documentation:
|
109
|
+
# https://docs.bitfinex.com/v2/reference#ws-public-trades
|
110
|
+
#
|
111
|
+
# @example:
|
112
|
+
# client.listen_trades("tBTCUSD") do |trade|
|
113
|
+
# puts "traded #{trade[2][2]} BTC for #{trade[2][3]} USD"
|
114
|
+
# end
|
115
|
+
def listen_trades(symbol="tBTCUSD", &block)
|
116
|
+
raise BlockMissingError unless block_given?
|
117
|
+
register_channel symbol: symbol, channel: "trades", &block
|
118
|
+
end
|
119
|
+
|
120
|
+
# The Order Books channel allow you to keep track of the state of the Bitfinex order book.
|
121
|
+
# It is provided on a price aggregated basis, with customizable precision.
|
122
|
+
# After receiving the response, you will receive a snapshot of the book,
|
123
|
+
# followed by updates upon any changes to the book.
|
124
|
+
#
|
125
|
+
# @param symbol [string]
|
126
|
+
# @param precision [string] Level of price aggregation (P0, P1, P2, P3, R0).
|
127
|
+
# (default P0) R0 is raw books - These are the most granular books.
|
128
|
+
# @param frequency [string] Frequency of updates (F0, F1, F2, F3).
|
129
|
+
# F0=realtime / F1=2sec / F2=5sec / F3=10sec (default F0)
|
130
|
+
# @param length [int] Number of price points ("25", "100") [default="25"]
|
131
|
+
#
|
132
|
+
# Documentation:
|
133
|
+
# https://docs.bitfinex.com/v2/reference#ws-public-order-books
|
134
|
+
# https://docs.bitfinex.com/v2/reference#ws-public-raw-order-books
|
135
|
+
#
|
136
|
+
# @example:
|
137
|
+
# client.listen_book("tBTCUSD") do |trade|
|
138
|
+
# puts "traded #{trade[2][2]} BTC for #{trade[2][3]} USD"
|
139
|
+
# end
|
140
|
+
def listen_book(symbol="tBTCUSD", frequency="F0", length=25, precision="P0", &block)
|
141
|
+
raise BlockMissingError unless block_given?
|
142
|
+
register_channel symbol: symbol, channel: "book", prec: precision, freq: frequency, len: length, &block
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Bitfinex
|
4
|
+
module V2::UtilsClient
|
5
|
+
|
6
|
+
# Calculate the average execution rate for Trading or Margin funding.
|
7
|
+
#
|
8
|
+
# @param symbol [string] The symbol you want information about.
|
9
|
+
# @param amount [string] Amount. Positive for buy, negative for sell (ex. "1.123")
|
10
|
+
# @param period [string] (optional) Maximum period for Margin Funding
|
11
|
+
# @param rate_limit [string] Limit rate/price (ex. "1000.5")
|
12
|
+
#
|
13
|
+
# @return [Array]
|
14
|
+
#
|
15
|
+
# @example:
|
16
|
+
# client.calc_avg_price('tBTCUSD', 1000, 1000)
|
17
|
+
def calc_avg_price(symbol = 'tBTCUSD', amount = 0, period = 0, rate_limit = nil)
|
18
|
+
params = {
|
19
|
+
symbol: symbol,
|
20
|
+
amount: amount.to_s,
|
21
|
+
period: period.to_s
|
22
|
+
}
|
23
|
+
params[:rateLimit] = rate_limit.to_s unless rate_limit.nil?
|
24
|
+
get("calc/trade/avg",params)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/bitfinex/version.rb
CHANGED
@@ -16,23 +16,38 @@ module Bitfinex
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def ws_close_all
|
19
|
-
ws_client.
|
19
|
+
ws_client.stop!
|
20
20
|
@ws_open = false
|
21
21
|
ws_reset_channels
|
22
22
|
end
|
23
23
|
|
24
24
|
def ws_auth(&block)
|
25
25
|
unless @ws_auth
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
26
|
+
nonce = (Time.now.to_f * 10_000).to_i.to_s
|
27
|
+
sub_id = add_callback(&block)
|
28
|
+
save_channel_id(sub_id,0)
|
29
|
+
if config.api_version == 1
|
30
|
+
payload = 'AUTH' + nonce
|
31
|
+
signature = sign(payload)
|
32
|
+
ws_safe_send({
|
33
|
+
apiKey: config.api_key,
|
34
|
+
authSig: sign(payload),
|
35
|
+
authPayload: payload,
|
36
|
+
subId: sub_id.to_s,
|
37
|
+
event: 'auth'
|
38
|
+
})
|
39
|
+
else
|
40
|
+
payload = 'AUTH' + nonce + nonce
|
41
|
+
signature = sign(payload)
|
42
|
+
ws_safe_send({
|
43
|
+
apiKey: config.api_key,
|
44
|
+
authSig: sign(payload),
|
45
|
+
authPayload: payload,
|
46
|
+
authNonce: nonce,
|
47
|
+
subId: sub_id.to_s,
|
48
|
+
event: 'auth'
|
49
|
+
})
|
50
|
+
end
|
36
51
|
@ws_auth = true
|
37
52
|
end
|
38
53
|
end
|
@@ -71,15 +86,22 @@ module Bitfinex
|
|
71
86
|
end
|
72
87
|
|
73
88
|
def callbacks
|
74
|
-
@callbacks ||=
|
89
|
+
@callbacks ||= []
|
75
90
|
end
|
76
91
|
|
77
|
-
def add_callback(
|
78
|
-
|
92
|
+
def add_callback(&block)
|
93
|
+
id = 0
|
94
|
+
@mutex.synchronize do
|
95
|
+
callbacks[@c_counter] = { block: block, chan_id: nil }
|
96
|
+
id = @c_counter
|
97
|
+
@c_counter += 1
|
98
|
+
end
|
99
|
+
id
|
79
100
|
end
|
80
101
|
|
81
102
|
def register_authenticated_channel(msg, &block)
|
82
|
-
add_callback(
|
103
|
+
sub_id = add_callback(&block)
|
104
|
+
msg.merge!(subId: sub_id.to_s)
|
83
105
|
ws_safe_send(msg.merge(event:'subscribe'))
|
84
106
|
end
|
85
107
|
|
@@ -92,7 +114,8 @@ module Bitfinex
|
|
92
114
|
end
|
93
115
|
|
94
116
|
def register_channel(msg, &block)
|
95
|
-
add_callback(
|
117
|
+
sub_id = add_callback(&block)
|
118
|
+
msg.merge!(subId: sub_id.to_s)
|
96
119
|
if ws_open
|
97
120
|
ws_client.send msg.merge(event: 'subscribe')
|
98
121
|
else
|
@@ -100,25 +123,20 @@ module Bitfinex
|
|
100
123
|
end
|
101
124
|
end
|
102
125
|
|
103
|
-
def fingerprint(msg)
|
104
|
-
msg.reject{|k,v| [:event,'chanId','event'].include?(k) }.
|
105
|
-
inject({}){|h, (k,v)| h[k.to_sym]=v.to_s; h}
|
106
|
-
end
|
107
|
-
|
108
126
|
def listen
|
109
127
|
ws_client.on(:message) do |rmsg|
|
110
128
|
msg = JSON.parse(rmsg)
|
111
129
|
if msg.kind_of?(Hash) && msg["event"] == "subscribed"
|
112
|
-
save_channel_id(
|
130
|
+
save_channel_id(msg["subId"],msg["chanId"])
|
113
131
|
elsif msg.kind_of?(Array)
|
114
132
|
exec_callback_for(msg)
|
115
133
|
end
|
116
134
|
end
|
117
135
|
end
|
118
136
|
|
119
|
-
def save_channel_id(
|
120
|
-
callbacks[
|
121
|
-
chan_ids[
|
137
|
+
def save_channel_id(sub_id,chan_id)
|
138
|
+
callbacks[sub_id.to_i][:chan_id] = chan_id
|
139
|
+
chan_ids[chan_id] = sub_id.to_i
|
122
140
|
end
|
123
141
|
|
124
142
|
def exec_callback_for(msg)
|
@@ -198,12 +216,15 @@ module Bitfinex
|
|
198
216
|
end
|
199
217
|
|
200
218
|
def ws_closed(event)
|
201
|
-
|
202
|
-
|
219
|
+
if @stop
|
220
|
+
EM.stop
|
221
|
+
elsif @reconnect
|
222
|
+
EM.add_timer(@reconnect_after){ connect! }
|
223
|
+
end
|
203
224
|
end
|
204
225
|
|
205
226
|
def ws_error(event)
|
206
|
-
|
227
|
+
raise WebsocketError, event.message
|
207
228
|
end
|
208
229
|
end
|
209
230
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitfinex-rb
|
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
|
- Bitfinex
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -132,27 +132,35 @@ extensions: []
|
|
132
132
|
extra_rdoc_files: []
|
133
133
|
files:
|
134
134
|
- lib/bitfinex-api-rb.rb
|
135
|
+
- lib/bitfinex-rb.rb
|
135
136
|
- lib/bitfinex.rb
|
136
|
-
- lib/bitfinex/
|
137
|
+
- lib/bitfinex/api_versions.rb
|
137
138
|
- lib/bitfinex/authenticated_rest.rb
|
138
139
|
- lib/bitfinex/client.rb
|
139
140
|
- lib/bitfinex/configurable.rb
|
140
141
|
- lib/bitfinex/connection.rb
|
141
|
-
- lib/bitfinex/deposit.rb
|
142
142
|
- lib/bitfinex/errors.rb
|
143
|
-
- lib/bitfinex/
|
144
|
-
- lib/bitfinex/
|
145
|
-
- lib/bitfinex/
|
146
|
-
- lib/bitfinex/
|
147
|
-
- lib/bitfinex/
|
148
|
-
- lib/bitfinex/
|
149
|
-
- lib/bitfinex/
|
150
|
-
- lib/bitfinex/
|
151
|
-
- lib/bitfinex/
|
152
|
-
- lib/bitfinex/
|
153
|
-
- lib/bitfinex/
|
143
|
+
- lib/bitfinex/v1/account_info.rb
|
144
|
+
- lib/bitfinex/v1/deposit.rb
|
145
|
+
- lib/bitfinex/v1/funding_book.rb
|
146
|
+
- lib/bitfinex/v1/historical_data.rb
|
147
|
+
- lib/bitfinex/v1/lends.rb
|
148
|
+
- lib/bitfinex/v1/margin_funding.rb
|
149
|
+
- lib/bitfinex/v1/orderbook.rb
|
150
|
+
- lib/bitfinex/v1/orders.rb
|
151
|
+
- lib/bitfinex/v1/positions.rb
|
152
|
+
- lib/bitfinex/v1/stats.rb
|
153
|
+
- lib/bitfinex/v1/symbols.rb
|
154
|
+
- lib/bitfinex/v1/ticker.rb
|
155
|
+
- lib/bitfinex/v1/trades.rb
|
156
|
+
- lib/bitfinex/v1/wallet.rb
|
157
|
+
- lib/bitfinex/v2/margin.rb
|
158
|
+
- lib/bitfinex/v2/personal.rb
|
159
|
+
- lib/bitfinex/v2/stats.rb
|
160
|
+
- lib/bitfinex/v2/ticker.rb
|
161
|
+
- lib/bitfinex/v2/trading.rb
|
162
|
+
- lib/bitfinex/v2/utils.rb
|
154
163
|
- lib/bitfinex/version.rb
|
155
|
-
- lib/bitfinex/wallet.rb
|
156
164
|
- lib/bitfinex/websocket_connection.rb
|
157
165
|
homepage: https://www.bitfinex.com/
|
158
166
|
licenses:
|
@@ -174,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
182
|
version: '0'
|
175
183
|
requirements: []
|
176
184
|
rubyforge_project:
|
177
|
-
rubygems_version: 2.
|
185
|
+
rubygems_version: 2.4.5.1
|
178
186
|
signing_key:
|
179
187
|
specification_version: 4
|
180
188
|
summary: Bitfinex API Wrapper
|