Added changes from PR, fixed orders copy, increased timeout

api-breakage
Morty Space 6 years ago
parent b339ac5351
commit aee70f3dd3
  1. 2
      src/cryptocom/exchange/__init__.py
  2. 8
      src/cryptocom/exchange/api.py
  3. 43
      src/cryptocom/exchange/private.py
  4. 17
      src/cryptocom/exchange/structs.py
  5. 18
      tests/test_private.py

@ -13,4 +13,4 @@ __all__ = [
'ApiError', 'ApiProvider' 'ApiError', 'ApiProvider'
] ]
__version__ = '0.5.1' __version__ = '0.6'

@ -22,7 +22,7 @@ class ApiProvider:
"""Provides HTTP-api requests and websocket requests.""" """Provides HTTP-api requests and websocket requests."""
def __init__( def __init__(
self, *, api_key='', api_secret='', from_env=False, self, *, api_key='', api_secret='', from_env=False,
auth_required=True, timeout=3, retries=20, auth_required=True, timeout=120, retries=3,
root_url='https://api.crypto.com/v2/', root_url='https://api.crypto.com/v2/',
ws_root_url='wss://stream.crypto.com/v2/'): ws_root_url='wss://stream.crypto.com/v2/'):
self.api_key = api_key self.api_key = api_key
@ -103,11 +103,11 @@ class ApiProvider:
f"Code: {resp.status}. Data: {data}" f"Code: {resp.status}. Data: {data}"
) )
await asyncio.sleep(0.1) await asyncio.sleep(0.5)
continue continue
except ContentTypeError: except ContentTypeError:
if resp.status == 429: if resp.status == 429:
await asyncio.sleep(0.1) await asyncio.sleep(0.5)
continue continue
text = await resp.text() text = await resp.text()
raise ApiError( raise ApiError(
@ -125,7 +125,7 @@ class ApiProvider:
f"Data: {data}" f"Data: {data}"
) )
await asyncio.sleep(0.1) await asyncio.sleep(0.5)
continue continue
async def get(self, path, params=None, sign=False): async def get(self, path, params=None, sign=False):

@ -35,48 +35,41 @@ class Account:
} }
async def get_orders_history( async def get_orders_history(
self, pair: Pair, page: int = 0, self, pair: Pair = None, page: int = 0,
page_size: int = 200) -> List[Order]: page_size: int = 200) -> List[Order]:
"""Return all history orders.""" """Return all history orders."""
data = await self.api.post('private/get-order-history', { params = {'page_size': page_size, 'page': page}
'params': { if pair:
'instrument_name': pair.value, params['instrument_name'] = pair.value
'page_size': page_size, data = await self.api.post(
'page': page 'private/get-order-history', {'params': params})
}
})
return [ return [
Order.create_from_api(order) Order.create_from_api(order)
for order in data.get('order_list') or [] for order in data.get('order_list') or []
] ]
async def get_open_orders( async def get_open_orders(
self, pair: Pair, page: int = 0, self, pair: Pair = None, page: int = 0,
page_size: int = 200) -> List[Order]: page_size: int = 200) -> List[Order]:
"""Return open orders.""" """Return open orders."""
data = await self.api.post('private/get-open-orders', { params = {'page_size': page_size, 'page': page}
'params': { if pair:
'instrument_name': pair.value, params['instrument_name'] = pair.value
'page_size': page_size, data = await self.api.post(
'page': page 'private/get-open-orders', {'params': params})
}
})
return [ return [
Order.create_from_api(order) Order.create_from_api(order)
for order in data.get('order_list') or [] for order in data.get('order_list') or []
] ]
async def get_trades( async def get_trades(
self, pair: Pair, page: int = 0, self, pair: Pair = None, page: int = 0,
page_size: int = 200) -> List[PrivateTrade]: page_size: int = 200) -> List[PrivateTrade]:
"""Return trades.""" """Return trades."""
data = await self.api.post('private/get-trades', { params = {'page_size': page_size, 'page': page}
'params': { if pair:
'instrument_name': pair.value, params['instrument_name'] = pair.value
'page_size': page_size, data = await self.api.post('private/get-trades', {'params': params})
'page': page
}
})
return [ return [
PrivateTrade.create_from_api(trade) PrivateTrade.create_from_api(trade)
for trade in data.get('trade_list') or [] for trade in data.get('trade_list') or []
@ -199,7 +192,7 @@ class Account:
async def cancel_open_orders(self, pair: Pair) -> None: async def cancel_open_orders(self, pair: Pair) -> None:
"""Cancel all open orders.""" """Cancel all open orders."""
return await self.api.post('private/cancel-all-orders', { await self.api.post('private/cancel-all-orders', {
'params': {'instrument_name': pair.value} 'params': {'instrument_name': pair.value}
}) })

@ -209,6 +209,10 @@ class Balance:
class OrderType(str, enum.Enum): class OrderType(str, enum.Enum):
LIMIT = 'LIMIT' LIMIT = 'LIMIT'
MARKET = 'MARKET' MARKET = 'MARKET'
STOP_LOSS = 'STOP_LOSS'
STOP_LIMIT = 'STOP_LIMIT'
TAKE_PROFIT = 'TAKE_PROFIT'
TAKE_PROFIT_LIMIT = 'TAKE_PROFIT_LIMIT'
class OrderStatus(str, enum.Enum): class OrderStatus(str, enum.Enum):
@ -217,6 +221,7 @@ class OrderStatus(str, enum.Enum):
CANCELED = 'CANCELED' CANCELED = 'CANCELED'
REJECTED = 'REJECTED' REJECTED = 'REJECTED'
EXPIRED = 'EXPIRED' EXPIRED = 'EXPIRED'
PENDING = 'PENDING'
class OrderExecType(str, enum.Enum): class OrderExecType(str, enum.Enum):
@ -245,6 +250,8 @@ class Order:
filled_price: float filled_price: float
fees_coin: Coin fees_coin: Coin
force_type: OrderForceType force_type: OrderForceType
filled_value: float
trigger_price: float
@cached_property @cached_property
def is_buy(self): def is_buy(self):
@ -256,7 +263,7 @@ class Order:
@cached_property @cached_property
def is_active(self): def is_active(self):
return self.side == OrderStatus.ACTIVE return self.status == OrderStatus.ACTIVE
@cached_property @cached_property
def is_canceled(self): def is_canceled(self):
@ -274,6 +281,10 @@ class Order:
def is_filled(self): def is_filled(self):
return self.status == OrderStatus.FILLED return self.status == OrderStatus.FILLED
@cached_property
def is_pending(self):
return self.status == OrderStatus.PENDING
@cached_property @cached_property
def volume(self): def volume(self):
return self.price * self.quantity return self.price * self.quantity
@ -310,7 +321,9 @@ class Order:
filled_quantity=data['cumulative_quantity'], filled_quantity=data['cumulative_quantity'],
filled_price=data['avg_price'], filled_price=data['avg_price'],
fees_coin=fees_coin, fees_coin=fees_coin,
force_type=OrderForceType(data['time_in_force']) force_type=OrderForceType(data['time_in_force']),
filled_value=data['cumulative_value'],
trigger_price=data.get('trigger_price')
) )

@ -8,8 +8,8 @@ import cryptocom.exchange as cro
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_account_get_balance(account: cro.Account): async def test_account_get_balance(account: cro.Account):
balances = await account.get_balance() balances = await account.get_balance()
assert balances[cro.Coin.CRO].available > 0.5 assert balances[cro.Coin.CRO].available > 0.2
assert balances[cro.Coin.USDT].available > 0.5 assert balances[cro.Coin.USDT].available > 0.2
for coin in cro.Coin: for coin in cro.Coin:
assert coin.value in balances assert coin.value in balances
@ -18,12 +18,13 @@ async def test_account_get_balance(account: cro.Account):
async def test_no_dublicated_mass_limit_orders( async def test_no_dublicated_mass_limit_orders(
exchange: cro.Exchange, account: cro.Account): exchange: cro.Exchange, account: cro.Account):
buy_price = round(await exchange.get_price(cro.Pair.CRO_USDT) / 2, 4) buy_price = round(await exchange.get_price(cro.Pair.CRO_USDT) / 2, 4)
orders_count = 185
order_ids = await asyncio.gather(*[ order_ids = await asyncio.gather(*[
account.buy_limit( account.buy_limit(
cro.Pair.CRO_USDT, 0.001, cro.Pair.CRO_USDT, 0.001,
round(buy_price / 1000 + i / 10000.0, 4) round(buy_price / 1000 + i / 10000.0, 4)
) )
for i in range(100) for i in range(orders_count)
]) ])
real_orders = await asyncio.gather(*[ real_orders = await asyncio.gather(*[
@ -31,13 +32,12 @@ async def test_no_dublicated_mass_limit_orders(
for id_ in order_ids for id_ in order_ids
]) ])
for order in real_orders: for order in real_orders:
assert order.status == cro.OrderStatus.ACTIVE, order assert order.is_active, order
# wait till open orders will be updated
await asyncio.sleep(1)
open_orders = await account.get_open_orders(cro.Pair.CRO_USDT) open_orders = await account.get_open_orders(cro.Pair.CRO_USDT)
assert len(real_orders) == len(open_orders) == 100 open_order_ids = sorted(o.id for o in open_orders if o.is_active)
assert sorted(o.id for o in open_orders) == sorted(order_ids) assert len(real_orders) == len(open_order_ids) == orders_count
assert open_order_ids == sorted(order_ids)
@pytest.mark.asyncio @pytest.mark.asyncio
@ -65,7 +65,7 @@ async def test_account_limit_orders(
open_orders = [ open_orders = [
order order
for order in await account.get_open_orders(cro.Pair.CRO_USDT) for order in await account.get_open_orders()
if order.id in order_ids if order.id in order_ids
] ]
assert not open_orders assert not open_orders

Loading…
Cancel
Save