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 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