1
0

Compare commits

..

2 Commits

Author SHA1 Message Date
cc50cba210
Retry get order because we might too fast to ask for it after placing order
All checks were successful
Test Python / Test (push) Successful in 26s
2024-07-22 22:18:17 +02:00
2738738fda
KuCoin support executed time 2024-07-22 22:01:44 +02:00
4 changed files with 42 additions and 8 deletions

View File

@ -4,6 +4,7 @@ import datetime
import logging import logging
from decimal import Decimal from decimal import Decimal
import time
import fin_defs import fin_defs
import kucoin.client import kucoin.client
@ -94,13 +95,17 @@ class KucoinDepoFetcher(DepoFetcher):
other accounts cannot be used. other accounts cannot be used.
Note: Note:
----
- A fee will be paid to Kucoin, with the rate determined by your WIP - A fee will be paid to Kucoin, with the rate determined by your WIP
level and the asset being traded. level and the asset being traded.
- The full `input_amount` may not be used. Inspect the resulting - The full `input_amount` may not be used. Inspect the resulting
`TradeOrderDetails` to see how much of the `input_amount` have been `TradeOrderDetails` to see how much of the `input_amount` have been
used. used.
References:
- POST Market Order: <https://www.kucoin.com/docs/rest/spot-trading/orders/place-order>
- GET Market Order by id: <https://www.kucoin.com/docs/rest/spot-trading/orders/get-order-details-by-orderid>
""" """
# Check requirements # Check requirements
if not self.allow_trades: if not self.allow_trades:
@ -131,8 +136,17 @@ class KucoinDepoFetcher(DepoFetcher):
del symbol, side, size, funds, input_amount del symbol, side, size, funds, input_amount
# Determine order details # Determine order details
order_id = response['orderId'] return self._get_order_details(response['orderId'], input_asset, output_asset)
order_details = self.kucoin_client.get_order(order_id)
def _get_order_details(self, order_id: str,
input_asset: fin_defs.Asset,
output_asset: fin_defs.Asset) -> TradeOrderDetails:
"""Determine the order details for the order with the given id.
Retries the order a few times, as KuCoin might not have propagated the
order through their systems.
"""
order_details = self._get_order_with_retries(order_id, num_retries=10)
# Convert from kucoin results # Convert from kucoin results
if input_asset == fin_defs.USDT: if input_asset == fin_defs.USDT:
@ -149,6 +163,22 @@ class KucoinDepoFetcher(DepoFetcher):
output_amount=output_amount_final, output_amount=output_amount_final,
fee_asset=fin_defs.WELL_KNOWN_SYMBOLS[order_details['feeCurrency']], fee_asset=fin_defs.WELL_KNOWN_SYMBOLS[order_details['feeCurrency']],
fee_amount=Decimal(order_details['fee']), fee_amount=Decimal(order_details['fee']),
executed_time=datetime.datetime.fromtimestamp(
order_details['createdAt'] / 1000, tz=datetime.UTC
),
order_id=order_id, order_id=order_id,
raw_order_details=order_details, raw_order_details=order_details,
) )
def _get_order_with_retries(self, order_id: str, *, num_retries: int, sleep_between_tries:float = 1.0) -> dict:
"""Get the order details from KuCoin backend.
Retries the order a few times, as KuCoin might not have propagated the
order through their systems since it was sent.
"""
for _ in range(num_retries):
try:
return self.kucoin_client.get_order(order_id)
except kucoin.exceptions.KucoinAPIException as e: # noqa
time.sleep(sleep_between_tries)
return self.kucoin_client.get_order(order_id)

View File

@ -15,6 +15,6 @@ NORDNET_PASSWORD = load_secret('NORDNET_PASSWORD')
KRAKEN_KEY = load_secret('KRAKEN_KEY') KRAKEN_KEY = load_secret('KRAKEN_KEY')
KRAKEN_SECRET = load_secret('KRAKEN_SECRET') KRAKEN_SECRET = load_secret('KRAKEN_SECRET')
KUCOIN_KEY = load_secret('KUCOIN_KEY') KUCOIN_KEY = load_secret('KUCOIN_KEY_TRADING')
KUCOIN_SECRET = load_secret('KUCOIN_SECRET') KUCOIN_SECRET = load_secret('KUCOIN_SECRET_TRADING')
KUCOIN_PASS = load_secret('KUCOIN_PASS') KUCOIN_PASS = load_secret('KUCOIN_PASS_TRADING')

View File

@ -13,7 +13,6 @@ needs_secrets = pytest.mark.skipif(
@needs_secrets @needs_secrets
def test_get_depo(): def test_get_depo():
session = requests.Session()
fetcher = fin_depo.defi_kraken.KrakenDepoFetcher( fetcher = fin_depo.defi_kraken.KrakenDepoFetcher(
secrets.KRAKEN_KEY, secrets.KRAKEN_KEY,
secrets.KRAKEN_SECRET, secrets.KRAKEN_SECRET,

View File

@ -2,12 +2,13 @@ from decimal import Decimal
import fin_defs import fin_defs
import pytest import pytest
import datetime
import fin_depo import fin_depo
from . import secrets from . import secrets
TEST_MARKET_ORDERS = False TEST_MARKET_ORDERS = True
needs_secrets = pytest.mark.skipif( needs_secrets = pytest.mark.skipif(
not secrets.KUCOIN_KEY, not secrets.KUCOIN_KEY,
@ -16,6 +17,7 @@ needs_secrets = pytest.mark.skipif(
fin_depo.defi_kucoin.logger.setLevel('INFO') fin_depo.defi_kucoin.logger.setLevel('INFO')
NOW = datetime.datetime.now(tz=datetime.UTC)
@needs_secrets @needs_secrets
def test_get_depo(): def test_get_depo():
@ -82,6 +84,7 @@ def test_place_buy_side_order():
assert order_details.fee_asset == fin_defs.USDT assert order_details.fee_asset == fin_defs.USDT
assert order_details.fee_amount <= Decimal('0.0002') assert order_details.fee_amount <= Decimal('0.0002')
assert NOW <= order_details.executed_time <= NOW + datetime.timedelta(minutes=10)
@needs_secrets @needs_secrets
def test_place_sell_side_order(): def test_place_sell_side_order():
@ -115,3 +118,5 @@ def test_place_sell_side_order():
assert order_details.fee_asset == fin_defs.USDT assert order_details.fee_asset == fin_defs.USDT
assert order_details.fee_amount is not None assert order_details.fee_amount is not None
assert NOW <= order_details.executed_time <= NOW + datetime.timedelta(minutes=10)