This commit is contained in:
parent
af07c75820
commit
9709c9b68a
|
@ -125,7 +125,7 @@ import datetime
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from decimal import Decimal, ROUND_DOWN
|
from decimal import ROUND_DOWN, Decimal
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import fin_defs
|
import fin_defs
|
||||||
|
@ -201,7 +201,10 @@ def sample_from_range(rng: random.Random, rang: tuple[Any, Any]) -> Any:
|
||||||
ROUND_TO_WHOLE = Decimal('1')
|
ROUND_TO_WHOLE = Decimal('1')
|
||||||
|
|
||||||
|
|
||||||
def run_auto_sell(config: AutoSellConfig, initial_rounds_to_skip:int=0) -> AutoSellRunResults:
|
def run_auto_sell(
|
||||||
|
config: AutoSellConfig,
|
||||||
|
initial_rounds_to_skip: int = 0,
|
||||||
|
) -> AutoSellRunResults:
|
||||||
"""Executes the sell-off.
|
"""Executes the sell-off.
|
||||||
|
|
||||||
Sell-offs are performed in rounds of sizes and with intervals randomly
|
Sell-offs are performed in rounds of sizes and with intervals randomly
|
||||||
|
@ -218,7 +221,11 @@ def run_auto_sell(config: AutoSellConfig, initial_rounds_to_skip:int=0) -> AutoS
|
||||||
input_amount_available = config.seller.get_depo().get_amount_of_asset(
|
input_amount_available = config.seller.get_depo().get_amount_of_asset(
|
||||||
config.input_asset,
|
config.input_asset,
|
||||||
)
|
)
|
||||||
logger.info('Currently own %s %s', input_amount_available, config.input_asset.raw_short_name())
|
logger.info(
|
||||||
|
'Currently own %s %s',
|
||||||
|
input_amount_available,
|
||||||
|
config.input_asset.raw_short_name(),
|
||||||
|
)
|
||||||
|
|
||||||
if initial_rounds_to_skip > 0:
|
if initial_rounds_to_skip > 0:
|
||||||
initial_rounds_to_skip -= 1
|
initial_rounds_to_skip -= 1
|
||||||
|
@ -226,7 +233,10 @@ def run_auto_sell(config: AutoSellConfig, initial_rounds_to_skip:int=0) -> AutoS
|
||||||
elif input_amount_available > 0:
|
elif input_amount_available > 0:
|
||||||
amount_to_sell = sample_from_range(rng, config.input_amount_range)
|
amount_to_sell = sample_from_range(rng, config.input_amount_range)
|
||||||
amount_to_sell = min(input_amount_available, amount_to_sell)
|
amount_to_sell = min(input_amount_available, amount_to_sell)
|
||||||
amount_to_sell = amount_to_sell.quantize(ROUND_TO_WHOLE, rounding=ROUND_DOWN)
|
amount_to_sell = amount_to_sell.quantize(
|
||||||
|
ROUND_TO_WHOLE,
|
||||||
|
rounding=ROUND_DOWN,
|
||||||
|
)
|
||||||
logger.info('Attempting to sell %s %s', amount_to_sell, config.input_asset)
|
logger.info('Attempting to sell %s %s', amount_to_sell, config.input_asset)
|
||||||
|
|
||||||
order_details = config.seller.place_market_order(
|
order_details = config.seller.place_market_order(
|
||||||
|
@ -271,8 +281,12 @@ def log_estimates(config: AutoSellConfig):
|
||||||
expected_num_sell_offs = current_balance / average_amount
|
expected_num_sell_offs = current_balance / average_amount
|
||||||
expected_duration = average_sleep * float(expected_num_sell_offs)
|
expected_duration = average_sleep * float(expected_num_sell_offs)
|
||||||
|
|
||||||
fastest_duration = config.interval_range[0] * float(current_balance / config.input_amount_range[1])
|
fastest_duration = config.interval_range[0] * float(
|
||||||
slowest_duration = config.interval_range[1] * float(current_balance / config.input_amount_range[0])
|
current_balance / config.input_amount_range[1],
|
||||||
|
)
|
||||||
|
slowest_duration = config.interval_range[1] * float(
|
||||||
|
current_balance / config.input_amount_range[0],
|
||||||
|
)
|
||||||
|
|
||||||
logger.info('Welcome to crypto seller!')
|
logger.info('Welcome to crypto seller!')
|
||||||
config.sleep(1)
|
config.sleep(1)
|
||||||
|
@ -283,11 +297,19 @@ def log_estimates(config: AutoSellConfig):
|
||||||
config.sleep(1)
|
config.sleep(1)
|
||||||
logger.info('')
|
logger.info('')
|
||||||
config.sleep(1)
|
config.sleep(1)
|
||||||
logger.info('- Current balance: %s %s', current_balance, config.input_asset.raw_short_name())
|
logger.info(
|
||||||
|
'- Current balance: %s %s',
|
||||||
|
current_balance,
|
||||||
|
config.input_asset.raw_short_name(),
|
||||||
|
)
|
||||||
config.sleep(1)
|
config.sleep(1)
|
||||||
logger.info('- Average sleep: %s seconds', average_sleep)
|
logger.info('- Average sleep: %s seconds', average_sleep)
|
||||||
config.sleep(1)
|
config.sleep(1)
|
||||||
logger.info('- Average amount: %s %s', average_amount, config.input_asset.raw_short_name())
|
logger.info(
|
||||||
|
'- Average amount: %s %s',
|
||||||
|
average_amount,
|
||||||
|
config.input_asset.raw_short_name(),
|
||||||
|
)
|
||||||
config.sleep(1)
|
config.sleep(1)
|
||||||
logger.info('- Expected counts: %s', expected_num_sell_offs)
|
logger.info('- Expected counts: %s', expected_num_sell_offs)
|
||||||
config.sleep(1)
|
config.sleep(1)
|
||||||
|
|
|
@ -68,6 +68,7 @@ Website : https://gitfub.space/Jmaa/crypto-seller
|
||||||
License : MIT License (see website for full text)
|
License : MIT License (see website for full text)
|
||||||
""".strip()
|
""".strip()
|
||||||
|
|
||||||
|
|
||||||
def load_config(config_path: Path) -> AutoSellConfig:
|
def load_config(config_path: Path) -> AutoSellConfig:
|
||||||
logger.info('Loading configuration')
|
logger.info('Loading configuration')
|
||||||
|
|
||||||
|
@ -102,14 +103,25 @@ def load_config(config_path: Path) -> AutoSellConfig:
|
||||||
|
|
||||||
|
|
||||||
def parse_args():
|
def parse_args():
|
||||||
parser = argparse.ArgumentParser(prog='crypto_seller',
|
parser = argparse.ArgumentParser(
|
||||||
|
prog='crypto_seller',
|
||||||
description=CLI_DESCRIPTION,
|
description=CLI_DESCRIPTION,
|
||||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
epilog=CLI_EPILOG)
|
epilog=CLI_EPILOG,
|
||||||
parser.add_argument('--config', type=Path, dest='config_file',
|
)
|
||||||
required=True, help='Trading configuration file')
|
parser.add_argument(
|
||||||
parser.add_argument('--wait-before-first', action='store_true', dest='wait_before_first',
|
'--config',
|
||||||
help='Skip the first sell-off round, and wait for the next.')
|
type=Path,
|
||||||
|
dest='config_file',
|
||||||
|
required=True,
|
||||||
|
help='Trading configuration file',
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--wait-before-first',
|
||||||
|
action='store_true',
|
||||||
|
dest='wait_before_first',
|
||||||
|
help='Skip the first sell-off round, and wait for the next.',
|
||||||
|
)
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,7 +139,10 @@ def main():
|
||||||
log_estimates(auto_sell_config)
|
log_estimates(auto_sell_config)
|
||||||
|
|
||||||
# Run auto sell
|
# Run auto sell
|
||||||
results = run_auto_sell(auto_sell_config, initial_rounds_to_skip=args.wait_before_first and 1 or 0)
|
results = run_auto_sell(
|
||||||
|
auto_sell_config,
|
||||||
|
initial_rounds_to_skip=args.wait_before_first and 1 or 0,
|
||||||
|
)
|
||||||
|
|
||||||
# Display results
|
# Display results
|
||||||
logging.info('Sell-offs complete')
|
logging.info('Sell-offs complete')
|
||||||
|
|
|
@ -8,7 +8,6 @@ import fin_depo
|
||||||
import crypto_seller
|
import crypto_seller
|
||||||
import crypto_seller.order_csv
|
import crypto_seller.order_csv
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
class SellerMock(fin_depo.data.DepoFetcher):
|
class SellerMock(fin_depo.data.DepoFetcher):
|
||||||
def __init__(self, asset: fin_defs.Asset, initial_amount: Decimal):
|
def __init__(self, asset: fin_defs.Asset, initial_amount: Decimal):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user