Ruff
This commit is contained in:
parent
5c6c0d5df1
commit
bb2ac019ab
|
@ -51,7 +51,7 @@ The most relevant libraries for auditing are:
|
||||||
- [`python-kucoin`](https://python-kucoin.readthedocs.io/en/latest/) is used by
|
- [`python-kucoin`](https://python-kucoin.readthedocs.io/en/latest/) is used by
|
||||||
`fin_depo` for providing KuCoin support.
|
`fin_depo` for providing KuCoin support.
|
||||||
|
|
||||||
Todo
|
TODO
|
||||||
|
|
||||||
## Taxation
|
## Taxation
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ the trades file (`output/trades.csv`).
|
||||||
To help with tax reporting, it might be useful to sign up to tax oriented
|
To help with tax reporting, it might be useful to sign up to tax oriented
|
||||||
websites. For example, [CryptoSkat](https://cryptoskat.dk/) seems to be the
|
websites. For example, [CryptoSkat](https://cryptoskat.dk/) seems to be the
|
||||||
most mature on the danish market, and does support KuCoin.
|
most mature on the danish market, and does support KuCoin.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__all__ = ['__version__', 'run_auto_sell']
|
__all__ = ['__version__', 'run_auto_sell']
|
||||||
|
@ -74,9 +75,10 @@ import datetime
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
|
from collections.abc import Callable
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any,Callable
|
from typing import Any
|
||||||
|
|
||||||
import fin_defs
|
import fin_defs
|
||||||
import fin_depo
|
import fin_depo
|
||||||
|
@ -96,28 +98,32 @@ PATH_TRADES_FILE = PATH_OUTPUT / 'trades.csv'
|
||||||
# Main code #
|
# Main code #
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(frozen = True)
|
@dataclasses.dataclass(frozen=True)
|
||||||
class AutoSellConfig:
|
class AutoSellConfig:
|
||||||
interval_range: tuple[datetime.timedelta, datetime.timedelta]
|
interval_range: tuple[datetime.timedelta, datetime.timedelta]
|
||||||
input_asset: fin_defs.Asset
|
input_asset: fin_defs.Asset
|
||||||
input_amount_range: tuple[Decimal, Decimal]
|
input_amount_range: tuple[Decimal, Decimal]
|
||||||
output_asset: fin_defs.Asset
|
output_asset: fin_defs.Asset
|
||||||
seller: fin_depo.defi_kucoin.KucoinDepoFetcher
|
seller: fin_depo.defi_kucoin.KucoinDepoFetcher
|
||||||
sleep: Callable[[float],None]
|
sleep: Callable[[float], None]
|
||||||
exit_when_empty: bool = True
|
exit_when_empty: bool = True
|
||||||
|
|
||||||
|
|
||||||
def sample_from_range(rng: random.Random, range: tuple[Any, Any]) -> Any:
|
def sample_from_range(rng: random.Random, range: tuple[Any, Any]) -> Any:
|
||||||
multiplier = rng.random()
|
multiplier = rng.random()
|
||||||
if isinstance(range[0], Decimal):
|
if isinstance(range[0], Decimal):
|
||||||
multiplier = Decimal(multiplier)
|
multiplier = Decimal(multiplier)
|
||||||
return range[0] + (range[1] - range[0]) * multiplier
|
return range[0] + (range[1] - range[0]) * multiplier
|
||||||
|
|
||||||
|
|
||||||
def run_auto_sell(config: AutoSellConfig):
|
def run_auto_sell(config: AutoSellConfig):
|
||||||
rng = random.SystemRandom()
|
rng = random.SystemRandom()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# Check that account has tokens.
|
# Check that account has tokens.
|
||||||
input_amount_available = config.seller.get_depo().get_amount_of_asset(config.input_asset)
|
input_amount_available = config.seller.get_depo().get_amount_of_asset(
|
||||||
|
config.input_asset,
|
||||||
|
)
|
||||||
logger.info('Currently own %s %s', input_amount_available, config.input_asset)
|
logger.info('Currently own %s %s', input_amount_available, config.input_asset)
|
||||||
|
|
||||||
if input_amount_available > 0:
|
if input_amount_available > 0:
|
||||||
|
@ -125,8 +131,9 @@ def run_auto_sell(config: AutoSellConfig):
|
||||||
amount_to_sell = min(input_amount_available, amount_to_sell)
|
amount_to_sell = min(input_amount_available, amount_to_sell)
|
||||||
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(
|
||||||
config.input_asset, amount_to_sell, config.output_asset)
|
config.input_asset, amount_to_sell, config.output_asset,
|
||||||
|
)
|
||||||
|
|
||||||
print(order_details)
|
print(order_details)
|
||||||
# TODO: Write order details to file.
|
# TODO: Write order details to file.
|
||||||
|
|
|
@ -1,23 +1,24 @@
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
from decimal import Decimal
|
|
||||||
import time
|
import time
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
import fin_defs
|
import fin_defs
|
||||||
|
|
||||||
from . import config
|
from . import PATH_LOG_FILE, AutoSellConfig, config, run_auto_sell
|
||||||
from . import PATH_LOG_FILE, AutoSellConfig, run_auto_sell
|
|
||||||
from . import logger as module_logger
|
from . import logger as module_logger
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def setup_logging():
|
def setup_logging():
|
||||||
PATH_LOG_FILE.parent.mkdir(parents=True, exist_ok=True)
|
PATH_LOG_FILE.parent.mkdir(parents=True, exist_ok=True)
|
||||||
file_handler = logging.handlers.WatchedFileHandler(filename=PATH_LOG_FILE)
|
file_handler = logging.handlers.WatchedFileHandler(filename=PATH_LOG_FILE)
|
||||||
file_handler.setFormatter(
|
file_handler.setFormatter(
|
||||||
logging.Formatter(
|
logging.Formatter(
|
||||||
'%(levelname)s:%(asctime)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S',
|
'%(levelname)s:%(asctime)s: %(message)s',
|
||||||
|
datefmt='%Y-%m-%d %H:%M:%S',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,6 +27,7 @@ def setup_logging():
|
||||||
logger.setLevel('INFO')
|
logger.setLevel('INFO')
|
||||||
module_logger.setLevel('INFO')
|
module_logger.setLevel('INFO')
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
setup_logging()
|
setup_logging()
|
||||||
logger.info('Initializing crypto_seller')
|
logger.info('Initializing crypto_seller')
|
||||||
|
@ -42,8 +44,8 @@ def main():
|
||||||
input_asset=fin_defs.MPC,
|
input_asset=fin_defs.MPC,
|
||||||
output_asset=fin_defs.USDT,
|
output_asset=fin_defs.USDT,
|
||||||
exit_when_empty=True,
|
exit_when_empty=True,
|
||||||
seller = seller_backend,
|
seller=seller_backend,
|
||||||
sleep = time.sleep
|
sleep=time.sleep,
|
||||||
)
|
)
|
||||||
run_auto_sell(auto_sell_config)
|
run_auto_sell(auto_sell_config)
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,30 @@
|
||||||
|
import datetime
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
import fin_defs
|
import fin_defs
|
||||||
from decimal import Decimal
|
|
||||||
import fin_depo
|
import fin_depo
|
||||||
import datetime
|
|
||||||
|
|
||||||
import crypto_seller
|
import crypto_seller
|
||||||
|
|
||||||
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):
|
||||||
self.asset = asset
|
self.asset = asset
|
||||||
self.amount_left = initial_amount
|
self.amount_left = initial_amount
|
||||||
|
|
||||||
def get_depo(self) -> fin_depo.data.Depo:
|
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})
|
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:
|
def place_market_order(
|
||||||
Decimal, output_asset: fin_defs.Asset) -> fin_depo.data.Depo:
|
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'
|
assert input_amount <= self.amount_left, 'Attempt to sell too much'
|
||||||
self.amount_left -= input_amount
|
self.amount_left -= input_amount
|
||||||
|
|
||||||
|
@ -24,7 +32,7 @@ class SellerMock(fin_depo.data.DepoFetcher):
|
||||||
input_asset=input_asset,
|
input_asset=input_asset,
|
||||||
input_amount=input_amount,
|
input_amount=input_amount,
|
||||||
output_asset=output_asset,
|
output_asset=output_asset,
|
||||||
output_amount=input_amount, # TODO?
|
output_amount=input_amount, # TODO?
|
||||||
fee_asset=input_asset,
|
fee_asset=input_asset,
|
||||||
fee_amount=Decimal(0),
|
fee_amount=Decimal(0),
|
||||||
order_id=10000000 - self.amount_left,
|
order_id=10000000 - self.amount_left,
|
||||||
|
@ -33,15 +41,14 @@ class SellerMock(fin_depo.data.DepoFetcher):
|
||||||
|
|
||||||
|
|
||||||
class SleepMock:
|
class SleepMock:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.time_slept = 0.0
|
self.time_slept = 0.0
|
||||||
|
|
||||||
def __call__(self, amount: float):
|
def __call__(self, amount: float):
|
||||||
self.time_slept = self.time_slept + amount
|
self.time_slept = self.time_slept + amount
|
||||||
|
|
||||||
def test_auto_run():
|
|
||||||
|
|
||||||
|
def test_auto_run():
|
||||||
sleep_mock = SleepMock()
|
sleep_mock = SleepMock()
|
||||||
seller_mock = SellerMock(fin_defs.USDT, Decimal('1000'))
|
seller_mock = SellerMock(fin_defs.USDT, Decimal('1000'))
|
||||||
|
|
||||||
|
@ -51,12 +58,11 @@ def test_auto_run():
|
||||||
input_asset=fin_defs.USDT,
|
input_asset=fin_defs.USDT,
|
||||||
output_asset=fin_defs.USD,
|
output_asset=fin_defs.USD,
|
||||||
exit_when_empty=True,
|
exit_when_empty=True,
|
||||||
seller = seller_mock,
|
seller=seller_mock,
|
||||||
sleep = sleep_mock ,
|
sleep=sleep_mock,
|
||||||
)
|
)
|
||||||
|
|
||||||
crypto_seller.run_auto_sell(config)
|
crypto_seller.run_auto_sell(config)
|
||||||
|
|
||||||
assert seller_mock.amount_left == 0
|
assert seller_mock.amount_left == 0
|
||||||
assert sleep_mock.time_slept == 1000
|
assert sleep_mock.time_slept == 1000
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user