From 3fb2d001ad0c01c66a6947b25758a2fffcaebf7d Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Mon, 22 Jul 2024 13:21:41 +0200 Subject: [PATCH] Test --- crypto_seller/__init__.py | 51 ++++++++------------------------------- crypto_seller/__main__.py | 16 +++++++++--- test/__init__.py | 0 test/test_auto_sell.py | 48 ++++++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 45 deletions(-) create mode 100644 test/__init__.py create mode 100644 test/test_auto_sell.py diff --git a/crypto_seller/__init__.py b/crypto_seller/__init__.py index 1b6c1e4..1a21e76 100644 --- a/crypto_seller/__init__.py +++ b/crypto_seller/__init__.py @@ -1,9 +1,9 @@ """# Automatic Crypto Seller. -This is a system for automatically trading individual financial assets a single -way, by using repeated trades over a period. +This is a wrapper about [`fin_depo`] for automatically individual financial +assets a one way, by using repeated trades over a period. -The primary motivation is for trading low-volume crypto assets without +The primary motivation is for trading low-volume crypto assets slowly without affecting the price too much. Supported sites: @@ -22,8 +22,8 @@ pip install -r requirements.txt Configure the sell rate: -Todo: ----- +TODO + Run using from the top directory: ```shell @@ -39,8 +39,6 @@ The log will both be displayed in the shell, and be placed in a log file file, with as much information as possible. Keep both of these for tax purposes, if relevant. -Todo: ----- ## Auditing information The most relevant libraries for auditing are: @@ -83,7 +81,6 @@ from typing import Any import fin_defs import fin_depo -from . import config from ._version import __version__ logger = logging.getLogger(__name__) @@ -114,40 +111,12 @@ def sample_from_range(rng: random.Random, range: tuple[Any, Any]) -> Any: multiplier = Decimal(multiplier) return range[0] + (range[1] - range[0]) * multiplier - -SELLER = fin_depo.defi_kucoin.KucoinDepoFetcher( - kucoin_secret=config.KUCOIN_SECRET, - kucoin_key=config.KUCOIN_KEY, - kucoin_pass=config.KUCOIN_PASS, -) - - -def determine_available_tokens(token: fin_defs.Asset) -> Decimal: - return SELLER.get_depo().get_amount_of_asset(token) - - -def sell_tokens( - input_asset: fin_defs.Asset, input_amount: Decimal, output_asset: fin_defs.Asset, -) -> fin_depo.data.TradeOrderDetails: - # return SELLER.place_market_order(input_asset, input_amount, output_asset) - return fin_depo.data.TradeOrderDetails( - input_asset=input_asset, - input_amount=input_amount, - output_asset=output_asset, - output_amount=input_amount, - fee_asset=input_asset, - fee_amount=input_amount, - order_id=10001, - raw_order_details={'TEST': 1, 'DATA': 2}, - ) - - -def run_auto_sell(config: AutoSellConfig): +def run_auto_sell(seller: fin_depo.defi_kucoin.KucoinDepoFetcher, config: AutoSellConfig): rng = random.SystemRandom() while True: # Check that account has tokens. - input_amount_available = determine_available_tokens(config.input_asset) + input_amount_available = seller.get_depo().get_amount_of_asset(config.input_asset) logger.info('Currently own %s %s', input_amount_available, config.input_asset) if input_amount_available > 0: @@ -155,9 +124,9 @@ def run_auto_sell(config: AutoSellConfig): amount_to_sell = min(input_amount_available, amount_to_sell) logger.info('Attempting to sell %s %s', amount_to_sell, config.input_asset) - order_details = sell_tokens( - config.input_asset, amount_to_sell, config.output_asset, - ) + order_details = seller.place_market_order( + config.input_asset, amount_to_sell, config.output_asset) + print(order_details) # TODO: Write order details to file. diff --git a/crypto_seller/__main__.py b/crypto_seller/__main__.py index 5d6dcee..0f119bc 100644 --- a/crypto_seller/__main__.py +++ b/crypto_seller/__main__.py @@ -5,13 +5,13 @@ from decimal import Decimal import fin_defs +from . import config from . import PATH_LOG_FILE, AutoSellConfig, run_auto_sell from . import logger as module_logger logger = logging.getLogger(__name__) - -def main(): +def setup_logging(): PATH_LOG_FILE.parent.mkdir(parents=True, exist_ok=True) file_handler = logging.handlers.WatchedFileHandler(filename=PATH_LOG_FILE) file_handler.setFormatter( @@ -25,16 +25,24 @@ def main(): logger.setLevel('INFO') module_logger.setLevel('INFO') +def main(): + setup_logging() logger.info('Initializing crypto_seller') - config = AutoSellConfig( + seller_backend = fin_depo.defi_kucoin.KucoinDepoFetcher( + kucoin_secret=config.KUCOIN_SECRET, + kucoin_key=config.KUCOIN_KEY, + kucoin_pass=config.KUCOIN_PASS, + ) + + auto_sell_config = AutoSellConfig( input_amount_range=(Decimal('0.5'), Decimal('1')), interval_range=(datetime.timedelta(seconds=2), datetime.timedelta(seconds=6)), input_asset=fin_defs.MPC, output_asset=fin_defs.USDT, exit_when_empty=True, ) - run_auto_sell(config) + run_auto_sell(seller_backend, auto_sell_config) if __name__ == '__main__': diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/test_auto_sell.py b/test/test_auto_sell.py new file mode 100644 index 0000000..5271cc3 --- /dev/null +++ b/test/test_auto_sell.py @@ -0,0 +1,48 @@ + +import fin_defs +from decimal import Decimal +import fin_depo +import datetime + +import crypto_seller + +class SellerMock(fin_depo.data.DepoFetcher): + + def __init__(self, asset: fin_defs.Asset, initial_amount: Decimal): + self.asset = asset + self.amount_left = initial_amount + + def get_depo(self) -> fin_depo.data.Depo: + return fin_depo.data.DepoSingle('TestDepo', datetime.datetime.now(tz=datetime.UTC), {self.asset:self.amount_left}) + + def place_market_order(self, input_asset: fin_defs.Asset, input_amount: + Decimal, output_asset: fin_defs.Asset) -> fin_depo.data.Depo: + assert input_amount <= self.amount_left, 'Attempt to sell too much' + self.amount_left -= input_amount + + return fin_depo.data.TradeOrderDetails( + input_asset=input_asset, + input_amount=input_amount, + output_asset=output_asset, + output_amount=input_amount, # TODO? + fee_asset=input_asset, + fee_amount=Decimal(0), + order_id=10000000 - self.amount_left, + raw_order_details={'TEST': 1, 'DATA': 2}, + ) + + +def test_auto_run(): + config = crypto_seller.AutoSellConfig( + input_amount_range=(Decimal('1'), Decimal('1')), + interval_range=(datetime.timedelta(seconds=0), datetime.timedelta(seconds=0)), + input_asset=fin_defs.USDT, + output_asset=fin_defs.USD, + exit_when_empty=True, + ) + seller = SellerMock(fin_defs.USDT, Decimal('1000')) + + crypto_seller.run_auto_sell(seller, config) + + assert seller.amount_left == 0 +