From 64fadefd1b945d5eb3fce1c30ea3459cbfa02a2d Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Fri, 22 Jan 2021 18:55:19 +0100 Subject: [PATCH 01/22] Implemented PULSE endpoints (rest) --- bfxapi/rest/bfx_rest.py | 100 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index f937188..d1424fb 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -143,7 +143,7 @@ class BfxRest: @param precision string: level of price aggregation (P0, P1, P2, P3, P4, R0) @param length int: number of price points ("25", "100") @return Array [ PRICE, COUNT, AMOUNT ] - """ + https://docs.bitfinex.com/reference#rest-public-pulse-hist """ endpoint = "book/{}/{}".format(symbol, precision) params = "?len={}".format(length) books = await self.fetch(endpoint, params) @@ -204,6 +204,38 @@ class BfxRest: status = await self.fetch(endpoint) return status + async def get_public_pulse_hist(self, end, limit=15): + """ + View the latest pulse messages. You can specify an end timestamp to view older messages. + + # Attributes + @param end int: millisecond end time + @param limit int: max number of items in response (MAX: 100) + @return Array [ PID, MTS, _PLACEHOLDER, PUID, _PLACEHOLDER, TITLE, CONTENT, + _PLACEHOLDER, _PLACEHOLDER, IS_PIN, IS_PUBLIC, COMMENTS_DISABLED, TAGS, + META, LIKES, _PLACEHOLDER, _PLACEHOLDER, [ PUID, MTS, _PLACEHOLDER, + NICKNAME, PLACEHOLDER, PICTURE, TEXT, _PLACEHOLDER, _PLACEHOLDER, TWITTER_HANDLE, + _PLACEHOLDER, FOLLOWERS, FOLLOWING, _PLACEHOLDER, _PLACEHOLDER, _PLACEHOLDER, + TIPPING_STATUS ] ], COMMENTS, _PLACEHOLDER, _PLACEHOLDER ] + """ + endpoint = f"pulse/hist?limit={limit}&end={end}" + hist = await self.fetch(endpoint) + return hist + + async def get_public_pulse_profile(self, nickname='Bitfinex'): + """ + This endpoint shows details for a specific Pulse profile + + # Attributes + @param nickname string + @return Array [ PUID, MTS, _PLACEHOLDER, NICKNAME, _PLACEHOLDER, PICTURE, + TEXT, _PLACEHOLDER, _PLACEHOLDER, TWITTER_HANDLE, _PLACEHOLDER, FOLLOWERS, + FOLLOWING, _PLACEHOLDER, _PLACEHOLDER, _PLACEHOLDER, TIPPING_STATUS] + """ + endpoint = f"pulse/profile/{nickname}" + profile = await self.fetch(endpoint) + return profile + ################################################## # Authenticated Data # ################################################## @@ -630,6 +662,72 @@ class BfxRest: raw_notification = await self.post(endpoint, payload) return Notification.from_raw_notification(raw_notification) + async def get_auth_pulse_hist(self, is_public=None): + """ + Allows you to retrieve your private pulse history or the public pulse history with an additional UID_LIKED field. + + # Attributes + @param is_public int: allows you to receive the public pulse history with the UID_LIKED field + @return Array [ PID, MTS, _PLACEHOLDER, PUID, _PLACEHOLDER, TITLE, + CONTENT, _PLACEHOLDER, _PLACEHOLDER, IS_PIN, IS_PUBLIC, COMMENTS_DISABLED, + TAGS, META,LIKES, UID_LIKED, _PLACEHOLDER, [ PUID, MTS, _PLACEHOLDER, NICKNAME, + _PLACEHOLDER, PICTURE, TEXT, _PLACEHOLDER, _PLACEHOLDER, TWITTER_HANDLE, _PLACEHOLDER, + FOLLOWERS, FOLLOWING, _PLACEHOLDER, _PLACEHOLDER, _PLACEHOLDER, TIPPING_STATUS ], COMMENTS, + _PLACEHOLDER, _PLACEHOLDER ] + """ + endpoint = f"auth/r/pulse/hist" + if is_public: + endpoint += f'?isPublic={is_public}' + hist = await self.post(endpoint) + return hist + + async def pulse_add(self, title, content, parent=None, is_pin=False, + attachments=[], disable_comments=False, is_public=True): + """ + Allows you to write Pulse messages + + # Attributes + @param title str: title of the message (min 16, max 120 characters) + @param content str: content of the message + @param parent str: Pulse Message ID (PID) of parent post + @param is_pin boolean: is message pinned? + @param attachments list of str: base64 format + @param disable_comments boolean: are comments disabled? + @param is_public boolean: is a public message? + @return Array [ PID, MTS, _PLACEHOLDER, PUID, _PLACEHOLDER, TITLE, + CONTENT, _PLACEHOLDER, _PLACEHOLDER, IS_PIN, IS_PUBLIC, COMMENTS_DISABLED, + TAGS // This inner array contains zero or more tag strings ATTACHMENTS, _PLACEHOLDER, + LIKES, UID_LIKED, _PLACEHOLDER, [], ... ] + """ + endpoint = f"auth/w/pulse/add" + payload = { + 'title': title, + 'content': content, + 'isPin': 1 if is_pin else 0, + 'attachments': attachments, + 'disableComments': 1 if disable_comments else 0, + 'isPublic': 1 if is_public else 0 + } + if parent: + payload['parent'] = parent + print(payload) + message = await self.post(endpoint, payload) + return message + + async def pulse_delete(self, pid): + """ + Allows you to delete your Pulse messages + + # Attributes + @param pid str: ID of the pulse message that you want to delete + @return Array [1] or [0] + """ + endpoint = f"auth/w/pulse/del" + payload = { + 'pid': pid + } + message = await self.post(endpoint, payload) + return message ################################################## # Derivatives # From 20d87ea4b7d0e3ab52a57da728547da971655c3b Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Fri, 22 Jan 2021 18:56:46 +0100 Subject: [PATCH 02/22] removed wrong comment --- bfxapi/rest/bfx_rest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index d1424fb..9965673 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -143,7 +143,7 @@ class BfxRest: @param precision string: level of price aggregation (P0, P1, P2, P3, P4, R0) @param length int: number of price points ("25", "100") @return Array [ PRICE, COUNT, AMOUNT ] - https://docs.bitfinex.com/reference#rest-public-pulse-hist """ + """ endpoint = "book/{}/{}".format(symbol, precision) params = "?len={}".format(length) books = await self.fetch(endpoint, params) From d7ec7bcb95ed1a54c8ee0ea80f172a088ef9404c Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Fri, 22 Jan 2021 18:59:57 +0100 Subject: [PATCH 03/22] Implemented PULSE endpoints (rest) --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 7aa0ee3..8f62675 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,5 @@ 1.1.9 +- Implemented PULSE endpoints (rest) - Updated pyee and changed deprecated class EventEmitter() -> AsyncIOEventEmitter() to make it work with all Python 3.X versions 1.1.8 From 29f50fccb0c10be1ceb45ae61287fea0de505f56 Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Sun, 24 Jan 2021 17:20:02 +0100 Subject: [PATCH 04/22] Implemented additional REST endpoints - Foreign exchange rate - Market average price - Generate invoice - Keep funding - Cancel order multi --- bfxapi/rest/bfx_rest.py | 133 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 126 insertions(+), 7 deletions(-) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index 9965673..90cfc90 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -236,6 +236,51 @@ class BfxRest: profile = await self.fetch(endpoint) return profile + async def get_market_average_price(self, symbol, amount=None, period=None, rate_limit=None): + """ + Calculate the average execution price for Trading or rate for Margin funding. + + # Attributes + @param symbol str: the symbol you want information about + @param amount str: amount. Positive for buy, negative for sell + @param period int: maximum period for Margin Funding + @param rate_limit string: limit rate/price (ex. "1000.5") + + @return Array + For exchange trading + [PRICE_AVG, AMOUNT] + + For funding + [RATE_AVG, AMOUNT] + """ + endpoint = f"calc/trade/avg" + payload = { + "symbol": symbol, + "amount": amount, + "period": period, + "rate_limit": rate_limit + } + message = await self.post(endpoint, payload) + return message + + async def get_foreign_exchange_rate(self, ccy1, ccy2): + """ + Calculate the average execution price for Trading or rate for Margin funding. + + # Attributes + @param ccy1 str: base currency + @param ccy2 str: quote currency + + @return Array [ CURRENT_RATE ] + """ + endpoint = f"calc/fx" + payload = { + "ccy1": ccy1, + "ccy2": ccy2 + } + message = await self.post(endpoint, payload) + return message + ################################################## # Authenticated Data # ################################################## @@ -417,7 +462,7 @@ class BfxRest: if symbol else "auth/r/ledgers/hist") params = "?start={}&end={}&limit={}".format(start, end, limit) if (category): - payload = { "category": category , } + payload = {"category": category, } raw_ledgers = await self.post(endpoint, payload, params=params) else: raw_ledgers = await self.post(endpoint, params=params) @@ -456,7 +501,23 @@ class BfxRest: @param fundingId int: the id of the funding offer """ endpoint = "auth/w/funding/offer/cancel" - raw_notification = await self.post(endpoint, { 'id': fundingId }) + raw_notification = await self.post(endpoint, {'id': fundingId}) + return Notification.from_raw_notification(raw_notification) + + async def keep_funding(self, type, id): + """ + Toggle to keep funding taken. Specify loan for unused funding and credit for used funding. + + # Attributes + @param type string: funding type ('credit' or 'loan') + @param id int: loan or credit identifier + """ + endpoint = "auth/w/funding/keep" + payload = { + "type": type, + "id": id + } + raw_notification = await self.post(endpoint, payload) return Notification.from_raw_notification(raw_notification) async def submit_wallet_transfer(self, from_wallet, to_wallet, from_currency, to_currency, amount): @@ -478,7 +539,7 @@ class BfxRest: "currency_to": to_currency, "amount": str(amount), } - raw_transfer = await self.post(endpoint, payload) + raw_transfer = await self.post(endpoint, payload) return Notification.from_raw_notification(raw_transfer) async def get_wallet_deposit_address(self, wallet, method, renew=0): @@ -615,12 +676,44 @@ class BfxRest: @param orderId: the id of the order that you want to update """ endpoint = "auth/w/order/cancel" - raw_notification = await self.post(endpoint, { 'id': orderId }) + raw_notification = await self.post(endpoint, {'id': orderId}) + return Notification.from_raw_notification(raw_notification) + + async def submit_cancel_order_multi(self, ids=None, cids=None, gids=None, all=None): + """ + Cancel multiple orders simultaneously. Orders can be canceled based on the Order ID, + the combination of Client Order ID and Client Order Date, or the Group Order ID. + Alternatively, the body param 'all' can be used with a value of 1 to cancel all orders. + + # Attributes + @param id array of int: orders ids + [1234, 1235, ...] + + @param cids array of arrays: client orders ids + [[234, "2016-12-05"], ...] + + @param gids array of int: group orders id + [11, ...] + + @param all int: cancel all open orders if value is set to 1 + """ + endpoint = "auth/w/order/cancel/multi" + payload = {} + if ids != None: + payload["id"] = ids + if cids != None: + payload["cid"] = cids + if gids != None: + payload["gid"] = gids + if all != None: + payload["all"] = all + print(payload) + raw_notification = await self.post(endpoint, payload) return Notification.from_raw_notification(raw_notification) async def submit_update_order(self, orderId, price=None, amount=None, delta=None, price_aux_limit=None, - price_trailing=None, hidden=False, close=False, reduce_only=False, - post_only=False, time_in_force=None, leverage=None): + price_trailing=None, hidden=False, close=False, reduce_only=False, + post_only=False, time_in_force=None, leverage=None): """ Update an existing order @@ -682,7 +775,7 @@ class BfxRest: return hist async def pulse_add(self, title, content, parent=None, is_pin=False, - attachments=[], disable_comments=False, is_public=True): + attachments=[], disable_comments=False, is_public=True): """ Allows you to write Pulse messages @@ -729,6 +822,32 @@ class BfxRest: message = await self.post(endpoint, payload) return message + async def generate_invoice(self, wallet='exchange', currency='LNX', amount='0.02'): + """ + Generates a Lightning Network deposit invoice + + # Attributes + @param wallet str: Select the wallet that will receive the invoice payment + Currently only 'exchange' is available + @param currency str: Select the currency for which you wish to generate an invoice + Currently only LNX (Bitcoin Lightning Network) is available. + @param amount str: Amount that you wish to deposit (in BTC; min 0.000001, max 0.02) + + @return Array [INVOICE_HASH, INVOICE, PLACEHOLDER, PLACEHOLDER, AMOUNT] + + If this is the first time you are generating an LNX invoice on your account, + you will first need to create a deposit address. To do this, call + self.get_wallet_deposit_address(method='LNX', wallet='exchange') + """ + endpoint = f"auth/w/deposit/invoice" + payload = { + 'wallet': wallet, + 'currency': currency, + 'amount': amount + } + message = await self.post(endpoint, payload) + return message + ################################################## # Derivatives # ################################################## From f01deb5540542c82b49c1b5d6db7dddb6be01aa7 Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Sun, 24 Jan 2021 17:20:59 +0100 Subject: [PATCH 05/22] Implemented additional REST endpoints - Foreign exchange rate - Market average price - Generate invoice - Keep funding - Cancel order multi --- CHANGELOG | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 8f62675..4f03dcd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,11 @@ 1.1.9 - Implemented PULSE endpoints (rest) - Updated pyee and changed deprecated class EventEmitter() -> AsyncIOEventEmitter() to make it work with all Python 3.X versions +- Implemented Foreign exchange rate endpoint (rest) +- Implemented Market average price endpoint (rest) +- Implemented Generate invoice endpoint (rest) +- Implemented Keep funding endpoint (rest) +- Implemented Cancel order multi endpoint (rest) 1.1.8 - Adds support for websocket events pu, pn and pu From 6d39059503f050f853e073f0bd4835b4e7374cb0 Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Mon, 25 Jan 2021 16:58:57 +0100 Subject: [PATCH 06/22] removed debug prints --- bfxapi/rest/bfx_rest.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index 90cfc90..7281fe5 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -707,7 +707,6 @@ class BfxRest: payload["gid"] = gids if all != None: payload["all"] = all - print(payload) raw_notification = await self.post(endpoint, payload) return Notification.from_raw_notification(raw_notification) @@ -803,7 +802,6 @@ class BfxRest: } if parent: payload['parent'] = parent - print(payload) message = await self.post(endpoint, payload) return message From 409d9ca5956fd310198b36389b00f0770ddc402b Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Mon, 25 Jan 2021 17:30:19 +0100 Subject: [PATCH 07/22] get_public_pulse_hist() -> end should be optional --- bfxapi/rest/bfx_rest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index 7281fe5..3121aa9 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -204,7 +204,7 @@ class BfxRest: status = await self.fetch(endpoint) return status - async def get_public_pulse_hist(self, end, limit=15): + async def get_public_pulse_hist(self, end=None, limit=100): """ View the latest pulse messages. You can specify an end timestamp to view older messages. From 6a6545eecc225fb380b9354aad88e7567c51c1b5 Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Mon, 25 Jan 2021 17:31:40 +0100 Subject: [PATCH 08/22] removed redundant brackets --- bfxapi/rest/bfx_rest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index 3121aa9..4584bee 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -461,8 +461,8 @@ class BfxRest: endpoint = ("auth/r/ledgers/{}/hist".format(symbol) if symbol else "auth/r/ledgers/hist") params = "?start={}&end={}&limit={}".format(start, end, limit) - if (category): - payload = {"category": category, } + if category: + payload = {"category": category} raw_ledgers = await self.post(endpoint, payload, params=params) else: raw_ledgers = await self.post(endpoint, params=params) From a3225491429c321022917e497ee01fb46f6d7396 Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Mon, 25 Jan 2021 17:34:57 +0100 Subject: [PATCH 09/22] better rewriting --- bfxapi/rest/bfx_rest.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index 4584bee..27fe912 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -218,7 +218,9 @@ class BfxRest: _PLACEHOLDER, FOLLOWERS, FOLLOWING, _PLACEHOLDER, _PLACEHOLDER, _PLACEHOLDER, TIPPING_STATUS ] ], COMMENTS, _PLACEHOLDER, _PLACEHOLDER ] """ - endpoint = f"pulse/hist?limit={limit}&end={end}" + endpoint = f"pulse/hist?limit={limit}" + if end: + endpoint += f'&end={end}' hist = await self.fetch(endpoint) return hist From a212fa03d982097c092b82eabcde13368ff88a78 Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Mon, 25 Jan 2021 17:36:19 +0100 Subject: [PATCH 10/22] limit = 100 as default would be better, but there is an issue with large response ( failed with status 500 - ["error",10001,"ERR_REQUEST_GENERIC: ESOCKETTIMEDOUT"] ) --- bfxapi/rest/bfx_rest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index 27fe912..cd4c4e7 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -204,7 +204,7 @@ class BfxRest: status = await self.fetch(endpoint) return status - async def get_public_pulse_hist(self, end=None, limit=100): + async def get_public_pulse_hist(self, end=None, limit=25): """ View the latest pulse messages. You can specify an end timestamp to view older messages. From 1a835ee086c649b130e2e728006c3f88c64eed2b Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Wed, 27 Jan 2021 21:01:36 +0100 Subject: [PATCH 11/22] added https://docs.bitfinex.com/reference#rest-public-stats1 endpoint (get_public_stats) --- bfxapi/rest/bfx_rest.py | 59 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index cd4c4e7..a4f1b89 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -283,6 +283,58 @@ class BfxRest: message = await self.post(endpoint, payload) return message + async def get_public_stats(self, key, size, symbol, section, side=None, + sort=None, start=None, end=None, limit=None): + """ + The Stats endpoint provides various statistics on a specified trading pair or funding currency. + + # Attributes + @param key str + Available values -> "funding.size", "credits.size", "credits.size.sym", + "pos.size", "vol.1d", "vol.7d", "vol.30d", "vwap" + + @param size str + Available values -> "30m", "1d", '1m' + + @param symbol str: the symbol you want information about + (e.g. tBTCUSD, tETHUSD, fUSD, fBTC) + + @param section str + Available values -> "last", "hist" + + @param side str: only for non-funding queries + Available values -> "long", "short" + + @param sort int: if = 1 it sorts results returned with old > new + + @param start str: millisecond start time + + @param end str: millisecond end time + + @param limit int: number of records (max 10000) + + @return + Array [MTS, VALUE] with Section = "last" + Array [[MTS, VALUE], ...] with Section = "hist" + """ + if key != 'funding.size' and not side: + raise Exception('side is compulsory for non funding queries') + endpoint = f"stats1/{key}:{size}:{symbol}" + if side: + endpoint += f":{side}" + if section: + endpoint += f"/{section}" + endpoint += '?' + if sort: + endpoint += f"sort={sort}&" + if start: + endpoint += f"start={start}&" + if end: + endpoint += f"end={end}&" + if limit: + endpoint += f"limit={limit}" + message = await self.fetch(endpoint) + return message ################################################## # Authenticated Data # ################################################## @@ -822,7 +874,7 @@ class BfxRest: message = await self.post(endpoint, payload) return message - async def generate_invoice(self, wallet='exchange', currency='LNX', amount='0.02'): + async def generate_invoice(self, wallet='exchange', currency='LNX', amount=None): """ Generates a Lightning Network deposit invoice @@ -841,9 +893,8 @@ class BfxRest: """ endpoint = f"auth/w/deposit/invoice" payload = { - 'wallet': wallet, - 'currency': currency, - 'amount': amount + "wallet": wallet, + "currency": currency, } message = await self.post(endpoint, payload) return message From 2387a652724907f35c731fccbea725fa26a777b1 Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Wed, 27 Jan 2021 21:01:57 +0100 Subject: [PATCH 12/22] updated CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 4f03dcd..5e1fb20 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,7 @@ - Implemented Generate invoice endpoint (rest) - Implemented Keep funding endpoint (rest) - Implemented Cancel order multi endpoint (rest) +- Implemented Public Stats endpoint (rest) 1.1.8 - Adds support for websocket events pu, pn and pu From a813eb3b4b5749e83c9ab4ed9ecbc10ba8c5499d Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Wed, 27 Jan 2021 21:33:30 +0100 Subject: [PATCH 13/22] fixed generate_invoice() --- bfxapi/rest/bfx_rest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index a4f1b89..af9462f 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -895,6 +895,7 @@ class BfxRest: payload = { "wallet": wallet, "currency": currency, + "amount": amount } message = await self.post(endpoint, payload) return message From 7a5b0f338d700614610b3aec396bcbf2a6614f1b Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Wed, 27 Jan 2021 21:58:46 +0100 Subject: [PATCH 14/22] amount is NOT optional --- bfxapi/rest/bfx_rest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index af9462f..92f27ed 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -874,7 +874,7 @@ class BfxRest: message = await self.post(endpoint, payload) return message - async def generate_invoice(self, wallet='exchange', currency='LNX', amount=None): + async def generate_invoice(self, amount, wallet='exchange', currency='LNX'): """ Generates a Lightning Network deposit invoice From 25f4fdc3d966765168bfca64a25480949a68fd30 Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Thu, 28 Jan 2021 21:14:47 +0100 Subject: [PATCH 15/22] added endpoint rest auth order multi op (https://docs.bitfinex.com/reference#rest-auth-order-multi) --- CHANGELOG | 1 + bfxapi/rest/bfx_rest.py | 62 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 5e1fb20..ff2c371 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,7 @@ - Implemented Keep funding endpoint (rest) - Implemented Cancel order multi endpoint (rest) - Implemented Public Stats endpoint (rest) +- Implemented Order Multi OP endpoint (rest) 1.1.8 - Adds support for websocket events pu, pn and pu diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index 92f27ed..f96d3c5 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -335,6 +335,7 @@ class BfxRest: endpoint += f"limit={limit}" message = await self.fetch(endpoint) return message + ################################################## # Authenticated Data # ################################################## @@ -808,6 +809,67 @@ class BfxRest: raw_notification = await self.post(endpoint, payload) return Notification.from_raw_notification(raw_notification) + async def submit_order_multi_op(self, orders): + """ + Send Multiple order-related operations. + Please note the sent object has only one property with a value + of an array of arrays detailing each order operation. + + https://docs.bitfinex.com/reference#rest-auth-order-multi + + Expected orders -> + [ + ["on", { // Order Submit + type: "EXCHANGE LIMIT", + symbol: "tBTCUSD", + price: "123.45", + amount: "1.2345", + flags: 0 + }], + ["oc", { ... }], + ... + ] + + @param type string + Available values -> LIMIT, EXCHANGE LIMIT, MARKET, EXCHANGE MARKET, + STOP, EXCHANGE STOP, STOP LIMIT, EXCHANGE STOP LIMIT, TRAILING STOP, + EXCHANGE TRAILING STOP, FOK, EXCHANGE FOK, IOC, EXCHANGE IOC + + @param symbol string: symbol of order + + @param price string: price of order + + @param amount string: amount of order (positive for buy, negative for sell) + + @param flags int: (optional) see https://docs.bitfinex.com/v2/docs/flag-values + + @param lev int: set the leverage for a derivative order, supported + by derivative symbol orders only. The value should be between 1 and + 100 inclusive. The field is optional, if omitted the default leverage value of 10 will be used. + + @param price_trailing string: the trailing price for a trailing stop order + + @param price_aux_limit string: auxiliary Limit price (for STOP LIMIT) + + @param price_oco_stop string: OCO stop price + + @param gid int: group order id + + @param tif string: Time-In-Force - datetime for automatic order cancellation (YYYY-MM-DD HH:MM:SS) + + @param id int: Order ID (can be retrieved by calling the Retrieve Orders endpoint) + + @param cid int: Client Order ID + + @param cid_date string: Client Order ID Date (YYYY-MM-DD) + + @param all int: cancel all open orders if value is set to 1 + """ + payload = {"ops": orders} + endpoint = "auth/w/order/multi" + raw_notification = await self.post(endpoint, payload) + return Notification.from_raw_notification(raw_notification) + async def get_auth_pulse_hist(self, is_public=None): """ Allows you to retrieve your private pulse history or the public pulse history with an additional UID_LIKED field. From 63942264cab0a4b0bb9836cc6373a7856aeb121f Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Thu, 28 Jan 2021 21:31:51 +0100 Subject: [PATCH 16/22] - added function submit_pulse_comment() - renaming --- bfxapi/rest/bfx_rest.py | 49 +++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index f96d3c5..a506f3d 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -889,7 +889,7 @@ class BfxRest: hist = await self.post(endpoint) return hist - async def pulse_add(self, title, content, parent=None, is_pin=False, + async def submit_pulse(self, title, content, parent=None, is_pin=False, attachments=[], disable_comments=False, is_public=True): """ Allows you to write Pulse messages @@ -909,19 +909,50 @@ class BfxRest: """ endpoint = f"auth/w/pulse/add" payload = { - 'title': title, - 'content': content, - 'isPin': 1 if is_pin else 0, - 'attachments': attachments, - 'disableComments': 1 if disable_comments else 0, - 'isPublic': 1 if is_public else 0 + "title": title, + "content": content, + "isPin": 1 if is_pin else 0, + "attachments": attachments, + "disableComments": 1 if disable_comments else 0, + "isPublic": 1 if is_public else 0 } if parent: - payload['parent'] = parent + payload["parent"] = parent message = await self.post(endpoint, payload) return message - async def pulse_delete(self, pid): + async def submit_pulse_comment(self, title, content, parent, is_pin=False, + attachments=[], disable_comments=False, is_public=True): + """ + Allows you to write a Pulse comment + + # Attributes + @param title str: title of the message (min 16, max 120 characters) + @param content str: content of the message + @param parent str: Pulse Message ID (PID) of parent post + @param is_pin boolean: is message pinned? + @param attachments list of str: base64 format + @param disable_comments boolean: are comments disabled? + @param is_public boolean: is a public message? + @return Array [ PID, MTS, _PLACEHOLDER, PUID, _PLACEHOLDER, TITLE, + CONTENT, _PLACEHOLDER, _PLACEHOLDER, IS_PIN, IS_PUBLIC, COMMENTS_DISABLED, + TAGS // This inner array contains zero or more tag strings ATTACHMENTS, _PLACEHOLDER, + LIKES, UID_LIKED, _PLACEHOLDER, [], ... ] + """ + endpoint = f"auth/w/pulse/add" + payload = { + "title": title, + "content": content, + "isPin": 1 if is_pin else 0, + "attachments": attachments, + "disableComments": 1 if disable_comments else 0, + "isPublic": 1 if is_public else 0, + "parent": parent + } + message = await self.post(endpoint, payload) + return message + + async def delete_pulse(self, pid): """ Allows you to delete your Pulse messages From aea663c92166be9bb58ce9b86b06d8769e103ab9 Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Thu, 28 Jan 2021 21:50:05 +0100 Subject: [PATCH 17/22] Added Public Tikers History (rest) --- bfxapi/rest/bfx_rest.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index a506f3d..5aaf512 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -163,20 +163,21 @@ class BfxRest: ticker = await self.fetch(endpoint) return ticker - async def get_public_tickers(self, symbols): + async def get_public_tickers_history(self, symbols): """ - Get tickers for the given symbols. Tickers shows you the current best bid and ask, - as well as the last trade price. + History of recent tickers. + Provides historic data of the best bid and ask at a 10-second interval. # Attributes @param symbols Array: array of symbols i.e [tBTCUSD, tETHUSD] - @return Array [ SYMBOL, BID, BID_SIZE, ASK, ASK_SIZE, DAILY_CHANGE, DAILY_CHANGE_PERC, - LAST_PRICE, VOLUME, HIGH, LOW ] + @return Array [[ SYMBOL, BID, PLACEHOLDER, ASK, PLACEHOLDER, PLACEHOLDER, + PLACEHOLDER, PLACEHOLDER, PLACEHOLDER, PLACEHOLDER, PLACEHOLDER, PLACEHOLDER, MTS ], ...] """ - endpoint = "tickers/?symbols={}".format(','.join(symbols)) + endpoint = "tickers/hist?symbols={}".format(','.join(symbols)) ticker = await self.fetch(endpoint) return ticker + async def get_derivative_status(self, symbol): """ Gets platform information for derivative symbol. From 438cc2ef2c42f04bfc92bf900b11558966acf922 Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Thu, 28 Jan 2021 21:50:10 +0100 Subject: [PATCH 18/22] Added Public Tikers History (rest) --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index ff2c371..acc62f4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,7 @@ - Implemented Cancel order multi endpoint (rest) - Implemented Public Stats endpoint (rest) - Implemented Order Multi OP endpoint (rest) +- Implemented Public Tickers History (rest) 1.1.8 - Adds support for websocket events pu, pn and pu From 0c9299184d7f13d5fd0f426f8497cc5566b9bf51 Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Thu, 28 Jan 2021 22:12:20 +0100 Subject: [PATCH 19/22] Added Public Funding Stats (rest) --- CHANGELOG | 1 + bfxapi/rest/bfx_rest.py | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index acc62f4..be45220 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -9,6 +9,7 @@ - Implemented Public Stats endpoint (rest) - Implemented Order Multi OP endpoint (rest) - Implemented Public Tickers History (rest) +- Implemented Public Funding Stats (rest) 1.1.8 - Adds support for websocket events pu, pn and pu diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index 5aaf512..70991b3 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -337,6 +337,26 @@ class BfxRest: message = await self.fetch(endpoint) return message + + async def get_public_funding_stats(self, symbol): + """ + Get a list of the most recent funding data for the given currency + (FRR, average period, total amount provided, total amount used) + + # Attributes + @param limit int: number of results (max 250) + @param start str: millisecond start time + @param end str: millisecond end time + + @return Array + [[ TIMESTAMP, PLACEHOLDER, PLACEHOLDER, FRR, AVG_PERIOD, PLACEHOLDER, + PLACEHOLDER, FUNDING_AMOUNT, FUNDING_AMOUNT_USED ], ...] + """ + endpoint = f"funding/stats/{symbol}/hist" + stats = await self.fetch(endpoint) + return stats + + ################################################## # Authenticated Data # ################################################## From 026cd639296c5ec0b20db89d4e1c1074b0c1b61b Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Fri, 29 Jan 2021 15:19:30 +0100 Subject: [PATCH 20/22] Update dependencies in setup.py --- CHANGELOG | 1 + setup.py | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index be45220..d994ee7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,6 +10,7 @@ - Implemented Order Multi OP endpoint (rest) - Implemented Public Tickers History (rest) - Implemented Public Funding Stats (rest) +- Updated dependencies in setup.py 1.1.8 - Adds support for websocket events pu, pn and pu diff --git a/setup.py b/setup.py index 17efd88..a58a2f1 100644 --- a/setup.py +++ b/setup.py @@ -45,7 +45,17 @@ setup( # Python versions (enforced) python_requires='>=3.0.0, <4', # deps installed by pip - install_requires=['eventemitter', 'asyncio', 'websockets', 'pylint', 'six', 'pyee', 'aiohttp'], + install_requires=[ + 'eventemitter==0.2.0', + 'asyncio==3.4.3', + 'websockets==7.0', + 'pylint==2.3.0', + 'pytest-asyncio==0.10.0', + 'six==1.12.0', + 'pyee==8.0.1', + 'aiohttp==3.4.4', + 'isort==4.3.21' + ], project_urls={ 'Bug Reports': 'https://github.com/bitfinexcom/bitfinex-api-py/issues', 'Source': 'https://github.com/bitfinexcom/bitfinex-api-py', From d172bf620bedc14a2d9d6604e4cd709fb22083af Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Fri, 29 Jan 2021 15:48:38 +0100 Subject: [PATCH 21/22] Readded get_public_tickers() (I accidentally removed it) --- bfxapi/rest/bfx_rest.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index 70991b3..0b72c95 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -163,6 +163,19 @@ class BfxRest: ticker = await self.fetch(endpoint) return ticker + async def get_public_tickers(self, symbols): + """ + Get tickers for the given symbols. Tickers shows you the current best bid and ask, + as well as the last trade price. + # Attributes + @param symbols Array: array of symbols i.e [tBTCUSD, tETHUSD] + @return Array [ SYMBOL, BID, BID_SIZE, ASK, ASK_SIZE, DAILY_CHANGE, DAILY_CHANGE_PERC, + LAST_PRICE, VOLUME, HIGH, LOW ] + """ + endpoint = "tickers/?symbols={}".format(','.join(symbols)) + ticker = await self.fetch(endpoint) + return ticker + async def get_public_tickers_history(self, symbols): """ History of recent tickers. @@ -177,7 +190,6 @@ class BfxRest: ticker = await self.fetch(endpoint) return ticker - async def get_derivative_status(self, symbol): """ Gets platform information for derivative symbol. From cae37ccf4c1b930c86aa4b511c13c8b32756bd6a Mon Sep 17 00:00:00 2001 From: Dario Moceri Date: Fri, 29 Jan 2021 15:49:09 +0100 Subject: [PATCH 22/22] Readded get_public_tickers() (I accidentally removed it) --- bfxapi/rest/bfx_rest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bfxapi/rest/bfx_rest.py b/bfxapi/rest/bfx_rest.py index 0b72c95..8dbafc5 100644 --- a/bfxapi/rest/bfx_rest.py +++ b/bfxapi/rest/bfx_rest.py @@ -167,6 +167,7 @@ class BfxRest: """ Get tickers for the given symbols. Tickers shows you the current best bid and ask, as well as the last trade price. + # Attributes @param symbols Array: array of symbols i.e [tBTCUSD, tETHUSD] @return Array [ SYMBOL, BID, BID_SIZE, ASK, ASK_SIZE, DAILY_CHANGE, DAILY_CHANGE_PERC,