Skip to content

Commit

Permalink
Merge pull request hummingbot#3050 from TheHolyRoger/feat/connector-h…
Browse files Browse the repository at this point in the history
…itbtc

Feat / Add Connector for HitBTC
  • Loading branch information
dennisocana authored Mar 26, 2021
2 parents 50d5762 + e419bd8 commit f4167b1
Show file tree
Hide file tree
Showing 29 changed files with 2,963 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ We created hummingbot to promote **decentralized market-making**: enabling membe
| <img src="assets/cryptocom_logo.png" alt="Crypto.com" width="90" /> | crypto_com | [Crypto.com](https://crypto.com/exchange) | 2 | [API](https://exchange-docs.crypto.com/#introduction) |![YELLOW](https://via.placeholder.com/15/ffff00/?text=+) |
| <img src="assets/dydx_logo.png" alt="DyDx" width="90" /> | dydx | [dy/dx](https://dydx.exchange/) | 1 | [API](https://docs.dydx.exchange/) |![GREEN](https://via.placeholder.com/15/008000/?text=+) |
| <img src="assets/eterbase_logo.png" alt="Eterbase" width="90" /> | eterbase | [Eterbase](https://www.eterbase.com/) | * | [API](https://developers.eterbase.exchange/?version=latest) |![RED](https://via.placeholder.com/15/f03c15/?text=+) |
| <img src="assets/hitbtc_logo.png" alt="HitBTC" width="90" /> | hitbtc | [HitBTC](https://hitbtc.com/) | 2 | [API](https://api.hitbtc.com/) | ![YELLOW](https://via.placeholder.com/15/ffff00/?text=+) |
|<img src="assets/huobi_logo.png" alt="Huobi Global" width="90" />| huobi | [Huobi Global](https://www.hbg.com) | 1 | [API](https://huobiapi.github.io/docs/spot/v1/en/) |![GREEN](https://via.placeholder.com/15/008000/?text=+) |
| <img src="assets/kucoin_logo.png" alt="KuCoin" width="90" /> | kucoin | [KuCoin](https://www.kucoin.com/) | 1 | [API](https://docs.kucoin.com/#general) |![GREEN](https://via.placeholder.com/15/008000/?text=+) |
| <img src="assets/kraken_logo.png" alt="Kraken" width="90" /> | kraken | [Kraken](https://www.kraken.com/) | 1 | [API](https://www.kraken.com/features/api) |![GREEN](https://via.placeholder.com/15/008000/?text=+) |
Expand Down
Binary file added assets/hitbtc_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions conf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@
crypto_com_api_key = os.getenv("CRYPTO_COM_API_KEY")
crypto_com_secret_key = os.getenv("CRYPTO_COM_SECRET_KEY")
# HitBTC Tests
hitbtc_api_key = os.getenv("HITBTC_API_KEY")
hitbtc_secret_key = os.getenv("HITBTC_SECRET_KEY")
# Wallet Tests
test_erc20_token_address = os.getenv("TEST_ERC20_TOKEN_ADDRESS")
web3_test_private_key_a = os.getenv("TEST_WALLET_PRIVATE_KEY_A")
Expand Down
1 change: 1 addition & 0 deletions hummingbot/connector/connector_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
'dydx': 'green',
'eterbase': 'red',
'ethereum': 'red',
'hitbtc': 'yellow',
'huobi': 'green',
'kraken': 'green',
'kucoin': 'green',
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# distutils: language=c++
cimport numpy as np

cdef class HitbtcActiveOrderTracker:
cdef dict _active_bids
cdef dict _active_asks

cdef tuple c_convert_diff_message_to_np_arrays(self, object message)
cdef tuple c_convert_snapshot_message_to_np_arrays(self, object message)
# This method doesn't seem to be used anywhere at all
# cdef np.ndarray[np.float64_t, ndim=1] c_convert_trade_message_to_np_array(self, object message)
155 changes: 155 additions & 0 deletions hummingbot/connector/exchange/hitbtc/hitbtc_active_order_tracker.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# distutils: language=c++
# distutils: sources=hummingbot/core/cpp/OrderBookEntry.cpp
import logging
import numpy as np
from decimal import Decimal
from typing import Dict
from hummingbot.logger import HummingbotLogger
from hummingbot.core.data_type.order_book_row import OrderBookRow

_logger = None
s_empty_diff = np.ndarray(shape=(0, 4), dtype="float64")
HitbtcOrderBookTrackingDictionary = Dict[Decimal, Dict[str, Dict[str, any]]]

cdef class HitbtcActiveOrderTracker:
def __init__(self,
active_asks: HitbtcOrderBookTrackingDictionary = None,
active_bids: HitbtcOrderBookTrackingDictionary = None):
super().__init__()
self._active_asks = active_asks or {}
self._active_bids = active_bids or {}

@classmethod
def logger(cls) -> HummingbotLogger:
global _logger
if _logger is None:
_logger = logging.getLogger(__name__)
return _logger

@property
def active_asks(self) -> HitbtcOrderBookTrackingDictionary:
return self._active_asks

@property
def active_bids(self) -> HitbtcOrderBookTrackingDictionary:
return self._active_bids

# TODO: research this more
def volume_for_ask_price(self, price) -> float:
return NotImplementedError

# TODO: research this more
def volume_for_bid_price(self, price) -> float:
return NotImplementedError

def get_rates_and_quantities(self, entry) -> tuple:
# price, quantity
return float(entry["price"]), float(entry["size"])

cdef tuple c_convert_diff_message_to_np_arrays(self, object message):
cdef:
dict content = message.content
list content_keys = list(content.keys())
list bid_entries = []
list ask_entries = []
str order_id
str order_side
str price_raw
object price
dict order_dict
double timestamp = message.timestamp
double amount = 0

if "bid" in content_keys:
bid_entries = content["bid"]
if "ask" in content_keys:
ask_entries = content["ask"]

bids = s_empty_diff
asks = s_empty_diff

if len(bid_entries) > 0:
bids = np.array(
[[timestamp,
price,
amount,
message.update_id]
for price, amount in [self.get_rates_and_quantities(entry) for entry in bid_entries]],
dtype="float64",
ndmin=2
)

if len(ask_entries) > 0:
asks = np.array(
[[timestamp,
price,
amount,
message.update_id]
for price, amount in [self.get_rates_and_quantities(entry) for entry in ask_entries]],
dtype="float64",
ndmin=2
)

return bids, asks

cdef tuple c_convert_snapshot_message_to_np_arrays(self, object message):
cdef:
float price
float amount
str order_id
dict order_dict

# Refresh all order tracking.
self._active_bids.clear()
self._active_asks.clear()
timestamp = message.timestamp
content = message.content

for snapshot_orders, active_orders in [(content["bid"], self._active_bids), (content["ask"], self._active_asks)]:
for entry in snapshot_orders:
price, amount = self.get_rates_and_quantities(entry)
active_orders[price] = amount

# Return the sorted snapshot tables.
cdef:
np.ndarray[np.float64_t, ndim=2] bids = np.array(
[[message.timestamp,
float(price),
float(self._active_bids[price]),
message.update_id]
for price in sorted(self._active_bids.keys())], dtype='float64', ndmin=2)
np.ndarray[np.float64_t, ndim=2] asks = np.array(
[[message.timestamp,
float(price),
float(self._active_asks[price]),
message.update_id]
for price in sorted(self._active_asks.keys(), reverse=True)], dtype='float64', ndmin=2)

if bids.shape[1] != 4:
bids = bids.reshape((0, 4))
if asks.shape[1] != 4:
asks = asks.reshape((0, 4))

return bids, asks

# This method doesn't seem to be used anywhere at all
# cdef np.ndarray[np.float64_t, ndim=1] c_convert_trade_message_to_np_array(self, object message):
# cdef:
# double trade_type_value = 1.0 if message.content["side"] == "buy" else 2.0
# list content = message.content
# return np.array(
# [message.timestamp, trade_type_value, float(content["price"]), float(content["quantity"])],
# dtype="float64"
# )

def convert_diff_message_to_order_book_row(self, message):
np_bids, np_asks = self.c_convert_diff_message_to_np_arrays(message)
bids_row = [OrderBookRow(price, qty, update_id) for ts, price, qty, update_id in np_bids]
asks_row = [OrderBookRow(price, qty, update_id) for ts, price, qty, update_id in np_asks]
return bids_row, asks_row

def convert_snapshot_message_to_order_book_row(self, message):
np_bids, np_asks = self.c_convert_snapshot_message_to_np_arrays(message)
bids_row = [OrderBookRow(price, qty, update_id) for ts, price, qty, update_id in np_bids]
asks_row = [OrderBookRow(price, qty, update_id) for ts, price, qty, update_id in np_asks]
return bids_row, asks_row
Loading

0 comments on commit f4167b1

Please sign in to comment.