Skip to content

Commit 1c8482c

Browse files
committed
Merge branch '0.39/connector-altmarkets' into 0.39-altmarkets
2 parents b2936d8 + b24e568 commit 1c8482c

29 files changed

+3085
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ We created hummingbot to promote **decentralized market-making**: enabling membe
5454
| <img src="assets/okex_logo.png" alt="OKEx" width="90" /> | okex | [OKEx](https://www.okex.com/) | 3 | [API](https://www.okex.com/docs/en/) |![YELLOW](https://via.placeholder.com/15/ffff00/?text=+) |
5555
| <img src="assets/probit_global_logo.png" alt="Probit Global" width="90" /> | probit | [Probit Global](https://www.probit.com/en-us/) | 1 | [API](https://docs-en.probit.com/docs) |![YELLOW](https://via.placeholder.com/15/ffff00/?text=+) |
5656
| <img src="assets/probit_korea_logo.png" alt="Probit Korea" width="90" /> | probit_kr | [Probit Korea](https://www.probit.kr/en-us/) | 1 | [API](https://docs-en.probit.com/docs) |![YELLOW](https://via.placeholder.com/15/ffff00/?text=+) |
57+
| <img src="assets/altmarkets_logo1.png" alt="AltMarkets.io" width="90" /> | altmarkets | [AltMarkets.io](https://altmarkets.io/) | 2 | [API](https://altmarkets.io/) |![GREEN](https://via.placeholder.com/15/008000/?text=+) |
5758

5859

5960
## Supported decentralized exchanges

assets/altmarkets_logo1.png

7.38 KB
Loading

conf/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@
113113
coinzoom_secret_key = os.getenv("COINZOOM_SECRET_KEY")
114114
coinzoom_username = os.getenv("COINZOOM_USERNAME")
115115
116+
# AltMarkets.io Test
117+
altmarkets_api_key = os.getenv("ALTMARKETS_API_KEY")
118+
altmarkets_secret_key = os.getenv("ALTMARKETS_SECRET_KEY")
119+
116120
# Wallet Tests
117121
test_erc20_token_address = os.getenv("TEST_ERC20_TOKEN_ADDRESS")
118122
web3_test_private_key_a = os.getenv("TEST_WALLET_PRIVATE_KEY_A")

hummingbot/connector/connector_status.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python
22

33
connector_status = {
4+
'altmarkets': 'green',
45
'ascend_ex': 'yellow',
56
'balancer': 'green',
67
'beaxy': 'green',

hummingbot/connector/exchange/altmarkets/__init__.py

Whitespace-only changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# distutils: language=c++
2+
cimport numpy as np
3+
4+
cdef class AltmarketsActiveOrderTracker:
5+
cdef dict _active_bids
6+
cdef dict _active_asks
7+
8+
cdef tuple c_convert_diff_message_to_np_arrays(self, object message)
9+
cdef tuple c_convert_snapshot_message_to_np_arrays(self, object message)
10+
cdef np.ndarray[np.float64_t, ndim=1] c_convert_trade_message_to_np_array(self, object message)
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# distutils: language=c++
2+
# distutils: sources=hummingbot/core/cpp/OrderBookEntry.cpp
3+
4+
import logging
5+
import numpy as np
6+
7+
from decimal import Decimal
8+
from typing import Dict
9+
from hummingbot.logger import HummingbotLogger
10+
from hummingbot.core.data_type.order_book_row import OrderBookRow
11+
12+
_logger = None
13+
s_empty_diff = np.ndarray(shape=(0, 4), dtype="float64")
14+
AltmarketsOrderBookTrackingDictionary = Dict[Decimal, Dict[str, Dict[str, any]]]
15+
16+
cdef class AltmarketsActiveOrderTracker:
17+
def __init__(self,
18+
active_asks: AltmarketsOrderBookTrackingDictionary = None,
19+
active_bids: AltmarketsOrderBookTrackingDictionary = None):
20+
super().__init__()
21+
self._active_asks = active_asks or {}
22+
self._active_bids = active_bids or {}
23+
24+
@classmethod
25+
def logger(cls) -> HummingbotLogger:
26+
global _logger
27+
if _logger is None:
28+
_logger = logging.getLogger(__name__)
29+
return _logger
30+
31+
@property
32+
def active_asks(self) -> AltmarketsOrderBookTrackingDictionary:
33+
return self._active_asks
34+
35+
@property
36+
def active_bids(self) -> AltmarketsOrderBookTrackingDictionary:
37+
return self._active_bids
38+
39+
# TODO: research this more
40+
def volume_for_ask_price(self, price) -> float:
41+
return NotImplementedError
42+
43+
# TODO: research this more
44+
def volume_for_bid_price(self, price) -> float:
45+
return NotImplementedError
46+
47+
def get_rates_and_quantities(self, entry) -> tuple:
48+
# price, quantity
49+
amount = float(entry[1]) if len(entry[1].replace('.', '')) > 0 else 0.0
50+
return float(entry[0]), amount
51+
52+
cdef tuple c_convert_diff_message_to_np_arrays(self, object message):
53+
cdef:
54+
dict content = message.content
55+
list content_keys = list(content.keys())
56+
list bid_entry = []
57+
list ask_entry = []
58+
str order_id
59+
str order_side
60+
str price_raw
61+
object price
62+
dict order_dict
63+
double timestamp = message.timestamp
64+
double amount = 0
65+
66+
if "bids" in content_keys:
67+
bid_entry = content["bids"]
68+
if "asks" in content_keys:
69+
ask_entry = content["asks"]
70+
71+
bids = s_empty_diff
72+
asks = s_empty_diff
73+
74+
if len(bid_entry) > 0:
75+
bids = np.array(
76+
[[timestamp,
77+
price,
78+
amount,
79+
message.update_id]
80+
for price, amount in [self.get_rates_and_quantities(bid_entry)]],
81+
dtype="float64",
82+
ndmin=2
83+
)
84+
85+
if len(ask_entry) > 0:
86+
asks = np.array(
87+
[[timestamp,
88+
price,
89+
amount,
90+
message.update_id]
91+
for price, amount in [self.get_rates_and_quantities(ask_entry)]],
92+
dtype="float64",
93+
ndmin=2
94+
)
95+
96+
return bids, asks
97+
98+
cdef tuple c_convert_snapshot_message_to_np_arrays(self, object message):
99+
cdef:
100+
float price
101+
float amount
102+
str order_id
103+
dict order_dict
104+
105+
# Refresh all order tracking.
106+
self._active_bids.clear()
107+
self._active_asks.clear()
108+
timestamp = message.timestamp
109+
content = message.content
110+
111+
for snapshot_orders, active_orders in [(content["bids"], self._active_bids), (content["asks"], self._active_asks)]:
112+
for entry in snapshot_orders:
113+
price, amount = self.get_rates_and_quantities(entry)
114+
active_orders[price] = amount
115+
116+
# Return the sorted snapshot tables.
117+
cdef:
118+
np.ndarray[np.float64_t, ndim=2] bids = np.array(
119+
[[message.timestamp,
120+
float(price),
121+
float(self._active_bids[price]),
122+
message.update_id]
123+
for price in sorted(self._active_bids.keys())], dtype='float64', ndmin=2)
124+
np.ndarray[np.float64_t, ndim=2] asks = np.array(
125+
[[message.timestamp,
126+
float(price),
127+
float(self._active_asks[price]),
128+
message.update_id]
129+
for price in sorted(self._active_asks.keys(), reverse=True)], dtype='float64', ndmin=2)
130+
131+
if bids.shape[1] != 4:
132+
bids = bids.reshape((0, 4))
133+
if asks.shape[1] != 4:
134+
asks = asks.reshape((0, 4))
135+
136+
return bids, asks
137+
138+
cdef np.ndarray[np.float64_t, ndim=1] c_convert_trade_message_to_np_array(self, object message):
139+
cdef:
140+
double trade_type_value = 1.0 if message.content["taker_type"] == "buy" else 2.0
141+
142+
timestamp = message.timestamp
143+
content = message.content
144+
145+
return np.array(
146+
[timestamp, trade_type_value, float(content["price"]), float(content["amount"])],
147+
dtype="float64"
148+
)
149+
150+
def convert_diff_message_to_order_book_row(self, message):
151+
np_bids, np_asks = self.c_convert_diff_message_to_np_arrays(message)
152+
bids_row = [OrderBookRow(price, qty, update_id) for ts, price, qty, update_id in np_bids]
153+
asks_row = [OrderBookRow(price, qty, update_id) for ts, price, qty, update_id in np_asks]
154+
return bids_row, asks_row
155+
156+
def convert_snapshot_message_to_order_book_row(self, message):
157+
np_bids, np_asks = self.c_convert_snapshot_message_to_np_arrays(message)
158+
bids_row = [OrderBookRow(price, qty, update_id) for ts, price, qty, update_id in np_bids]
159+
asks_row = [OrderBookRow(price, qty, update_id) for ts, price, qty, update_id in np_asks]
160+
return bids_row, asks_row

0 commit comments

Comments
 (0)