Kucoin deposits and withdrawals
This commit is contained in:
parent
fee812a24e
commit
678390e881
|
@ -134,3 +134,30 @@ class TradeOrderDetails:
|
|||
|
||||
order_id: object
|
||||
raw_order_details: object
|
||||
|
||||
@enforce_typing.enforce_types
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class WithdrawalDetails:
|
||||
withdrawn_asset: Asset
|
||||
withdrawn_amount: Decimal
|
||||
|
||||
fee_asset: Asset
|
||||
fee_amount: Decimal
|
||||
|
||||
executed_time: datetime.datetime
|
||||
|
||||
raw_details: object
|
||||
|
||||
@enforce_typing.enforce_types
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class DepositDetails:
|
||||
deposit_asset: Asset
|
||||
deposit_amount: Decimal
|
||||
|
||||
fee_asset: Asset
|
||||
fee_amount: Decimal
|
||||
|
||||
executed_time: datetime.datetime
|
||||
|
||||
raw_details: object
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@ from decimal import Decimal
|
|||
import fin_defs
|
||||
import kucoin.client
|
||||
|
||||
from .data import DepoFetcher, DepoGroup, DepoSingle, TradeOrderDetails
|
||||
from .data import (DepoFetcher, DepoGroup, DepoSingle, TradeOrderDetails,
|
||||
WithdrawalDetails, DepositDetails)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -146,6 +147,50 @@ class KucoinDepoFetcher(DepoFetcher):
|
|||
# Determine order details
|
||||
return self._get_order_details(response['orderId'], input_asset, output_asset)
|
||||
|
||||
def _get_withdrawals(self) -> list[WithdrawalDetails]:
|
||||
raw_details = self.kucoin_client.get_withdrawals()
|
||||
|
||||
withdrawals = []
|
||||
for item in raw_details['items']:
|
||||
withdrawn_asset = parse_asset_from_ticker(item['currency'])
|
||||
withdrawn_amount = Decimal(item['amount'])
|
||||
fee_asset = withdrawn_asset # Assumed
|
||||
fee_amount = Decimal(item['fee'])
|
||||
executed_time=datetime.datetime.fromtimestamp(
|
||||
item['createdAt'] / 1000,
|
||||
tz=datetime.UTC,
|
||||
)
|
||||
|
||||
withdrawals.append(WithdrawalDetails(withdrawn_asset,
|
||||
withdrawn_amount, fee_asset,
|
||||
fee_amount, executed_time,
|
||||
item))
|
||||
del item
|
||||
|
||||
return withdrawals
|
||||
|
||||
def _get_deposits(self) -> list[WithdrawalDetails]:
|
||||
raw_details = self.kucoin_client.get_deposits()
|
||||
|
||||
deposits = []
|
||||
for item in raw_details['items']:
|
||||
deposit_asset = parse_asset_from_ticker(item['currency'])
|
||||
deposit_amount = Decimal(item['amount'])
|
||||
fee_asset = deposit_asset # Assumed
|
||||
fee_amount = Decimal(item['fee'])
|
||||
executed_time=datetime.datetime.fromtimestamp(
|
||||
item['createdAt'] / 1000,
|
||||
tz=datetime.UTC,
|
||||
)
|
||||
|
||||
deposits.append(DepositDetails(deposit_asset,
|
||||
deposit_amount, fee_asset,
|
||||
fee_amount, executed_time,
|
||||
item))
|
||||
del item
|
||||
|
||||
return deposits
|
||||
|
||||
def _get_order_details(
|
||||
self,
|
||||
order_id: str,
|
||||
|
|
|
@ -19,106 +19,30 @@ fin_depo.defi_kucoin.logger.setLevel('INFO')
|
|||
|
||||
NOW = datetime.datetime.now(tz=datetime.UTC)
|
||||
|
||||
|
||||
@needs_secrets
|
||||
def test_get_depo():
|
||||
"""Can inspect kucoin depository."""
|
||||
fetcher = fin_depo.defi_kucoin.KucoinDepoFetcher(
|
||||
def get_fetcher() -> fin_depo.defi_kucoin.KucoinDepoFetcher:
|
||||
return fin_depo.defi_kucoin.KucoinDepoFetcher(
|
||||
secrets.KUCOIN_KEY,
|
||||
secrets.KUCOIN_SECRET,
|
||||
secrets.KUCOIN_PASS,
|
||||
)
|
||||
|
||||
depo = fetcher.get_depo()
|
||||
@needs_secrets
|
||||
def test_get_depo():
|
||||
"""Can inspect kucoin depository."""
|
||||
depo = get_fetcher().get_depo()
|
||||
|
||||
assert isinstance(depo, fin_depo.data.DepoGroup)
|
||||
for nested_depo in depo.nested:
|
||||
assert isinstance(nested_depo, fin_depo.data.DepoSingle)
|
||||
|
||||
@needs_secrets
|
||||
def test_get_withdrawals():
|
||||
withdrawals = get_fetcher()._get_withdrawals()
|
||||
print(withdrawals)
|
||||
assert len(withdrawals) > 0
|
||||
|
||||
@needs_secrets
|
||||
def test_place_market_order_requires_allow_trades():
|
||||
"""Client fails if allow_trades is not enabled when doing market orders."""
|
||||
fetcher = fin_depo.defi_kucoin.KucoinDepoFetcher(
|
||||
secrets.KUCOIN_KEY,
|
||||
secrets.KUCOIN_SECRET,
|
||||
secrets.KUCOIN_PASS,
|
||||
allow_trades=False,
|
||||
)
|
||||
|
||||
with pytest.raises(PermissionError) as m:
|
||||
fetcher.place_market_order(fin_defs.MPC, Decimal(1), fin_defs.USDT)
|
||||
|
||||
assert 'KucoinDepoFetcher.allow_trades is not enabled: Cannot make trades' in str(m)
|
||||
|
||||
|
||||
@needs_secrets
|
||||
def test_place_buy_side_order():
|
||||
"""Client can place buy side market orders."""
|
||||
fetcher = fin_depo.defi_kucoin.KucoinDepoFetcher(
|
||||
secrets.KUCOIN_KEY,
|
||||
secrets.KUCOIN_SECRET,
|
||||
secrets.KUCOIN_PASS,
|
||||
allow_trades=TEST_MARKET_ORDERS,
|
||||
)
|
||||
|
||||
input_amount = Decimal('0.1')
|
||||
|
||||
order_details = fetcher.place_market_order(
|
||||
fin_defs.USDT,
|
||||
input_amount,
|
||||
fin_defs.MPC,
|
||||
)
|
||||
|
||||
assert order_details is not None
|
||||
assert order_details.order_id is not None
|
||||
assert order_details.raw_order_details is not None
|
||||
|
||||
assert order_details.input_asset == fin_defs.USDT
|
||||
assert order_details.output_asset == fin_defs.MPC
|
||||
|
||||
assert order_details.input_amount <= input_amount
|
||||
assert order_details.output_amount >= 0
|
||||
|
||||
assert order_details.input_amount != order_details.output_amount
|
||||
|
||||
assert order_details.fee_asset == fin_defs.USDT
|
||||
assert order_details.fee_amount <= Decimal('0.0002')
|
||||
|
||||
assert NOW <= order_details.executed_time <= NOW + datetime.timedelta(minutes=10)
|
||||
|
||||
|
||||
@needs_secrets
|
||||
def test_place_sell_side_order():
|
||||
"""Client can place sell side market orders."""
|
||||
fetcher = fin_depo.defi_kucoin.KucoinDepoFetcher(
|
||||
secrets.KUCOIN_KEY,
|
||||
secrets.KUCOIN_SECRET,
|
||||
secrets.KUCOIN_PASS,
|
||||
allow_trades=TEST_MARKET_ORDERS,
|
||||
)
|
||||
|
||||
input_amount = Decimal('1')
|
||||
|
||||
order_details = fetcher.place_market_order(
|
||||
fin_defs.MPC,
|
||||
input_amount,
|
||||
fin_defs.USDT,
|
||||
)
|
||||
|
||||
assert order_details is not None
|
||||
assert order_details.order_id is not None
|
||||
assert order_details.raw_order_details is not None
|
||||
|
||||
assert order_details.input_asset == fin_defs.MPC
|
||||
assert order_details.output_asset == fin_defs.USDT
|
||||
|
||||
assert order_details.input_amount <= input_amount
|
||||
assert order_details.output_amount >= 0
|
||||
|
||||
assert order_details.input_amount != order_details.output_amount
|
||||
|
||||
assert order_details.fee_asset == fin_defs.USDT
|
||||
assert order_details.fee_amount is not None
|
||||
|
||||
assert NOW <= order_details.executed_time <= NOW + datetime.timedelta(minutes=10)
|
||||
def test_get_deposits():
|
||||
deposits = get_fetcher()._get_deposits()
|
||||
print(deposits)
|
||||
assert len(deposits) > 0
|
||||
|
|
109
test/test_kucoin_trading.py
Normal file
109
test/test_kucoin_trading.py
Normal file
|
@ -0,0 +1,109 @@
|
|||
import datetime
|
||||
from decimal import Decimal
|
||||
|
||||
import fin_defs
|
||||
import pytest
|
||||
|
||||
import fin_depo
|
||||
|
||||
from . import secrets
|
||||
|
||||
TEST_MARKET_ORDERS = True
|
||||
|
||||
needs_secrets = pytest.mark.skipif(
|
||||
not secrets.KUCOIN_KEY,
|
||||
reason='Secret kucoin_USERNAME required',
|
||||
)
|
||||
|
||||
fin_depo.defi_kucoin.logger.setLevel('INFO')
|
||||
|
||||
NOW = datetime.datetime.now(tz=datetime.UTC)
|
||||
|
||||
|
||||
@needs_secrets
|
||||
def test_place_market_order_requires_allow_trades():
|
||||
"""Client fails if allow_trades is not enabled when doing market orders."""
|
||||
fetcher = fin_depo.defi_kucoin.KucoinDepoFetcher(
|
||||
secrets.KUCOIN_KEY,
|
||||
secrets.KUCOIN_SECRET,
|
||||
secrets.KUCOIN_PASS,
|
||||
allow_trades=False,
|
||||
)
|
||||
|
||||
with pytest.raises(PermissionError) as m:
|
||||
fetcher.place_market_order(fin_defs.MPC, Decimal(1), fin_defs.USDT)
|
||||
|
||||
assert 'KucoinDepoFetcher.allow_trades is not enabled: Cannot make trades' in str(m)
|
||||
|
||||
|
||||
@needs_secrets
|
||||
def test_place_buy_side_order():
|
||||
"""Client can place buy side market orders."""
|
||||
fetcher = fin_depo.defi_kucoin.KucoinDepoFetcher(
|
||||
secrets.KUCOIN_KEY,
|
||||
secrets.KUCOIN_SECRET,
|
||||
secrets.KUCOIN_PASS,
|
||||
allow_trades=TEST_MARKET_ORDERS,
|
||||
)
|
||||
|
||||
input_amount = Decimal('0.1')
|
||||
|
||||
order_details = fetcher.place_market_order(
|
||||
fin_defs.USDT,
|
||||
input_amount,
|
||||
fin_defs.MPC,
|
||||
)
|
||||
|
||||
assert order_details is not None
|
||||
assert order_details.order_id is not None
|
||||
assert order_details.raw_order_details is not None
|
||||
|
||||
assert order_details.input_asset == fin_defs.USDT
|
||||
assert order_details.output_asset == fin_defs.MPC
|
||||
|
||||
assert order_details.input_amount <= input_amount
|
||||
assert order_details.output_amount >= 0
|
||||
|
||||
assert order_details.input_amount != order_details.output_amount
|
||||
|
||||
assert order_details.fee_asset == fin_defs.USDT
|
||||
assert order_details.fee_amount <= Decimal('0.0002')
|
||||
|
||||
assert NOW <= order_details.executed_time <= NOW + datetime.timedelta(minutes=10)
|
||||
|
||||
|
||||
@needs_secrets
|
||||
def test_place_sell_side_order():
|
||||
"""Client can place sell side market orders."""
|
||||
fetcher = fin_depo.defi_kucoin.KucoinDepoFetcher(
|
||||
secrets.KUCOIN_KEY,
|
||||
secrets.KUCOIN_SECRET,
|
||||
secrets.KUCOIN_PASS,
|
||||
allow_trades=TEST_MARKET_ORDERS,
|
||||
)
|
||||
|
||||
input_amount = Decimal('1')
|
||||
|
||||
order_details = fetcher.place_market_order(
|
||||
fin_defs.MPC,
|
||||
input_amount,
|
||||
fin_defs.USDT,
|
||||
)
|
||||
|
||||
assert order_details is not None
|
||||
assert order_details.order_id is not None
|
||||
assert order_details.raw_order_details is not None
|
||||
|
||||
assert order_details.input_asset == fin_defs.MPC
|
||||
assert order_details.output_asset == fin_defs.USDT
|
||||
|
||||
assert order_details.input_amount <= input_amount
|
||||
assert order_details.output_amount >= 0
|
||||
|
||||
assert order_details.input_amount != order_details.output_amount
|
||||
|
||||
assert order_details.fee_asset == fin_defs.USDT
|
||||
assert order_details.fee_amount is not None
|
||||
|
||||
assert NOW <= order_details.executed_time <= NOW + datetime.timedelta(minutes=10)
|
||||
|
Loading…
Reference in New Issue
Block a user