diff --git a/crypto_seller/__init__.py b/crypto_seller/__init__.py index 2705d42..6e82c98 100644 --- a/crypto_seller/__init__.py +++ b/crypto_seller/__init__.py @@ -76,7 +76,6 @@ import dataclasses import datetime import logging import random -import time from collections.abc import Callable from decimal import Decimal from pathlib import Path @@ -102,6 +101,22 @@ PATH_TRADES_FILE = PATH_OUTPUT / 'trades.csv' @dataclasses.dataclass(frozen=True) class AutoSellConfig: + """Configuration for `run_auto_sell`. + + Fields: + + - `interval_range`: The range to determine sell-off intervals from. After + each sell-off it will sleep an amount of time uniformly sampled from this + range. + - `input_asset`: Asset to sell. + - `input_amount_range`: Range to uniformly sample sell-off sizes from. + - `output_asset`: Asset to "buy". + - `seller`: Depository seller to use. + - `sleep`: Sleep method to use. + - `exit_when_empty`: Whether the system should stop once there is nothing + more to sell. Recommended. + """ + interval_range: tuple[datetime.timedelta, datetime.timedelta] input_asset: fin_defs.Asset input_amount_range: tuple[Decimal, Decimal] @@ -113,25 +128,41 @@ class AutoSellConfig: @dataclasses.dataclass(frozen=True) class AutoSellRunResults: + """Result information after `run_auto_sell`. + + Fields: + - `order_details`: The list of order details. + - `total_duration`: Total duration of the run. + - `total_sleep_duration`: Amount of time spent waiting between sell-offs. + """ + order_details: list[fin_depo.data.TradeOrderDetails] total_duration: datetime.timedelta total_sleep_duration: datetime.timedelta def total_input_amount(self) -> Decimal: + """Total amount of assets sold.""" return sum(o.input_amount for o in self.order_details) def total_output_amount(self) -> Decimal: + """Total amount of assets "bought".""" return sum(o.output_amount for o in self.order_details) def sample_from_range(rng: random.Random, range: tuple[Any, Any]) -> Any: - multiplier = rng.random() + """Samples uniformly from the given range.""" + multiplier: float | Decimal = rng.random() if isinstance(range[0], Decimal): multiplier = Decimal(multiplier) return range[0] + (range[1] - range[0]) * multiplier def run_auto_sell(config: AutoSellConfig) -> AutoSellRunResults: + """Executes the sell-off. + + Sell-offs are performed in rounds of sizes and with intervals randomly + based on the given configuration. + """ rng = random.SystemRandom() time_start = datetime.datetime.now(tz=datetime.UTC)