import datetime from decimal import Decimal from pathlib import Path import fin_defs import fin_depo import crypto_seller import crypto_seller.order_csv 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.TradeOrderDetails: assert input_amount <= self.amount_left, 'Attempt to sell too much' self.amount_left -= input_amount executed_time = datetime.datetime.now(tz=datetime.UTC) return fin_depo.data.TradeOrderDetails( executed_time=executed_time, input_asset=input_asset, input_amount=input_amount, output_asset=output_asset, output_amount=input_amount, fee_asset=input_asset, fee_amount=Decimal(0), order_id=Decimal(10000000 - self.amount_left), raw_order_details={'TEST': 1, 'DATA': 2}, ) class SleepMock: def __init__(self): self.time_slept = 0.0 def __call__(self, amount: float): self.time_slept = self.time_slept + amount def test_auto_run(): sleep_mock = SleepMock() seller_mock = SellerMock(fin_defs.USDT, Decimal('1000')) config = crypto_seller.AutoSellConfig( input_amount_range=(Decimal('1'), Decimal('1')), interval_range=(datetime.timedelta(seconds=1), datetime.timedelta(seconds=1)), input_asset=fin_defs.USDT, output_asset=fin_defs.USD, exit_when_empty=True, seller=seller_mock, log_order_to_csv=crypto_seller.order_csv.CsvFileLogger( Path('output/test-trades.csv'), ), sleep=sleep_mock, ) results = crypto_seller.run_auto_sell(config) # Check results assert len(results.order_details) == 1000 assert results.total_sleep_duration == datetime.timedelta(seconds=1000) assert results.total_input_amount() == 1000 assert results.total_output_amount() == 1000 # Check mocks agree assert seller_mock.amount_left == 0 assert sleep_mock.time_slept == 1000