bitfinex-rb 0.0.11 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fda3167655ffc1362d2f7f96c6003850591aa48c
4
- data.tar.gz: 8498e0b0d8b77f0a0395c8754370608649af2af5
3
+ metadata.gz: b1b2e7fdeb41e8d0de71ff3ab3a8c8f65b438f74
4
+ data.tar.gz: 5ee463c95bed54185d0ad7b0bd99c75c2ad461ee
5
5
  SHA512:
6
- metadata.gz: 51db71bbf791120c209e0ab4ad9f8f14a39f7f5497ed1a714e4aeb71b90a7224c87934dba09225df06532da52da48d326ed61181c411471812007d7cc7312333
7
- data.tar.gz: c97e21f78af8f0eb027f9699ef1b394584756314e6bdf7b8f09b0006c4afd0091cf89d18e19b6252c64e288fe3f441e96b17e0fd352b1f23014a11cdcbcdd07d
6
+ metadata.gz: a393e8688103054bd93c9b73799c96a8ff6a921155ad1064f12de83332d82c32c7e244153b0ffea1390232b9454761c323aebc35523715f02fd6318ae5f28932
7
+ data.tar.gz: d33751ff047447639cf5f2e7034e14e96b7dcf414984a1e72dde42a40e07c05aa2156ac0287653651f4b33c7452e8e27c485d30a8a5d5e2f590566fb17a75568
@@ -0,0 +1 @@
1
+ require_relative "./bitfinex.rb"
@@ -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/ticker'
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
+
@@ -0,0 +1,7 @@
1
+ module Bitfinex
2
+ # API logic for Version 1
3
+ module V1; end
4
+
5
+ # API logic for Version 2
6
+ module V2; end
7
+ end
@@ -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
- payload = build_payload("/v1/#{url}", options[:params])
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
- req.headers['X-BFX-PAYLOAD'] = payload
16
- req.headers['X-BFX-SIGNATURE'] = sign(payload)
17
- req.headers['X-BFX-APIKEY'] = config.api_key
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'] = (Time.now.to_f * 10_000).to_i.to_s
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
@@ -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
 
@@ -4,12 +4,14 @@ module Bitfinex
4
4
  module RestConnection
5
5
  private
6
6
  # Make an HTTP GET request
7
- def get(url, options={})
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
- req.params = options[:params] if options.has_key?(:params) && !options[:params].empty?
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
@@ -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,5 +1,6 @@
1
1
  module Bitfinex
2
- module DepositClient
2
+ module V1::DepositClient
3
+
3
4
  # Return your deposit address to make a new deposit.
4
5
  #
5
6
  # @param method [string] Method of deposit (methods accepted: “bitcoin”, “litecoin”, “darkcoin”, “mastercoin” (tethers)).
@@ -1,5 +1,5 @@
1
1
  module Bitfinex
2
- module FundingBookClient
2
+ module V1::FundingBookClient
3
3
 
4
4
  # Get the full margin funding book
5
5
 
@@ -1,5 +1,5 @@
1
1
  module Bitfinex
2
- module HistoricalDataClient
2
+ module V1::HistoricalDataClient
3
3
 
4
4
  # View all of your balance ledger entries.
5
5
  #
@@ -1,5 +1,5 @@
1
1
  module Bitfinex
2
- module LendsClient
2
+ module V1::LendsClient
3
3
 
4
4
  # Get a list of the most recent funding data for the given currency: total amount provided and Flash Return Rate (in % by 365 days) over time.
5
5
  #
@@ -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. Set to 0 for FRR).
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.to_s
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,5 +1,5 @@
1
1
  module Bitfinex
2
- module PositionsClient
2
+ module V1::PositionsClient
3
3
 
4
4
  # View your active positions.
5
5
  #
@@ -1,5 +1,5 @@
1
1
  module Bitfinex
2
- module StatsClient
2
+ module V1::StatsClient
3
3
 
4
4
  # Various statistics about the requested pair.
5
5
  #
@@ -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: params).body
14
+ get("trades/#{symbol}", params).body
15
15
  end
16
16
 
17
17
  # Listen to the trades using websocket.
@@ -1,5 +1,5 @@
1
1
  module Bitfinex
2
- module WalletClient
2
+ module V1::WalletClient
3
3
 
4
4
  # See your balances.
5
5
  #
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Bitfinex
2
- VERSION = "0.0.11"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -16,23 +16,38 @@ module Bitfinex
16
16
  end
17
17
 
18
18
  def ws_close_all
19
- ws_client.close!
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
- payload = 'AUTH' + (Time.now.to_f * 10_000).to_i.to_s
27
- signature = sign(payload)
28
- add_callback(:auth, &block)
29
- save_channel_id(:auth, 0)
30
- ws_safe_send({
31
- apiKey: config.api_key,
32
- authSig: sign(payload),
33
- authPayload: payload,
34
- event: 'auth'
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(channel, &block)
78
- callbacks[channel] = { block: block, chan_id: nil }
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(fingerprint(msg),&block)
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(fingerprint(msg),&block)
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(fingerprint(msg), msg["chanId"])
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(chan,id)
120
- callbacks[chan][:chan_id] = id
121
- chan_ids[id.to_i] = chan
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
- return unless @reconnect
202
- EM.add_timer(@reconnect_after){ connect! } unless @stop
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
- fail event
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.11
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-02-09 00:00:00.000000000 Z
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/account_info.rb
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/funding_book.rb
144
- - lib/bitfinex/historical_data.rb
145
- - lib/bitfinex/lends.rb
146
- - lib/bitfinex/margin_funding.rb
147
- - lib/bitfinex/orderbook.rb
148
- - lib/bitfinex/orders.rb
149
- - lib/bitfinex/positions.rb
150
- - lib/bitfinex/stats.rb
151
- - lib/bitfinex/symbols.rb
152
- - lib/bitfinex/ticker.rb
153
- - lib/bitfinex/trades.rb
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.6.8
185
+ rubygems_version: 2.4.5.1
178
186
  signing_key:
179
187
  specification_version: 4
180
188
  summary: Bitfinex API Wrapper