1
0

Log trades to csv file

This commit is contained in:
Jon Michael Aanes 2024-07-22 15:48:55 +02:00
parent f5b69badd4
commit a0b1ee9ae1
4 changed files with 61 additions and 15 deletions

View File

@ -62,11 +62,15 @@ most mature on the danish market, and does support KuCoin.
## TODO ## TODO
- [ ] Log all trades to CSV file.
- [ ] Parse configuration from json. - [ ] Parse configuration from json.
- [X] Collect information during the run and output after run - [ ] Ensure that a failure during selling results in a safe winding down of the system.
* Catch runtime errors when selling
* Show errors to log.
* Stop loop and exit with results, and error indicator.
- [ ] Document configuration - [ ] Document configuration
- [ ] Document auditing - [ ] Document auditing
- [X] Log all trades to CSV file.
- [X] Collect information during the run and output after run
""" """
@ -88,17 +92,9 @@ from ._version import __version__
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
################################################################################
# Constants #
PATH_OUTPUT = Path('./output').absolute()
PATH_LOG_FILE = PATH_OUTPUT / 'log.txt'
PATH_TRADES_FILE = PATH_OUTPUT / 'trades.csv'
################################################################################ ################################################################################
# Main code # # Main code #
@dataclasses.dataclass(frozen=True) @dataclasses.dataclass(frozen=True)
class AutoSellConfig: class AutoSellConfig:
"""Configuration for `run_auto_sell`. """Configuration for `run_auto_sell`.
@ -123,6 +119,7 @@ class AutoSellConfig:
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]
log_order_to_csv: Callable[[fin_depo.data.TradeOrderDetails], None]
exit_when_empty: bool = True exit_when_empty: bool = True
@ -187,9 +184,8 @@ def run_auto_sell(config: AutoSellConfig) -> AutoSellRunResults:
config.output_asset, config.output_asset,
) )
print(order_details) config.log_order_to_csv(order_details)
all_executed_orders.append(order_details) all_executed_orders.append(order_details)
# TODO: Write order details to file.
del amount_to_sell del amount_to_sell
elif config.exit_when_empty: elif config.exit_when_empty:

View File

@ -1,18 +1,34 @@
import argparse
import datetime import datetime
import logging import logging
import logging.handlers import logging.handlers
import argparse
import time import time
from decimal import Decimal from decimal import Decimal
from pathlib import Path
import fin_defs import fin_defs
import fin_depo import fin_depo
from . import PATH_LOG_FILE, AutoSellConfig, config, run_auto_sell, log_results from . import (
AutoSellConfig,
config,
log_results,
order_csv,
run_auto_sell,
)
from . import logger as module_logger from . import logger as module_logger
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
################################################################################
# Constants #
PATH_OUTPUT = Path('./output').absolute()
PATH_LOG_FILE = PATH_OUTPUT / 'log.txt'
PATH_TRADES_FILE = PATH_OUTPUT / 'trades.csv'
################################################################################
# Application Setup #
def setup_logging(): def setup_logging():
"""Enables logging for the terminal and to a log file.""" """Enables logging for the terminal and to a log file."""
@ -30,14 +46,17 @@ def setup_logging():
logger.setLevel('INFO') logger.setLevel('INFO')
module_logger.setLevel('INFO') module_logger.setLevel('INFO')
CLI_DESCRIPTION = """ CLI_DESCRIPTION = """
Sells financial assets from an online account. Sells financial assets from an online account.
""".strip() """.strip()
def parse_args(): def parse_args():
parser = argparse.ArgumentParser('crypto_seller', description = CLI_DESCRIPTION) parser = argparse.ArgumentParser('crypto_seller', description=CLI_DESCRIPTION)
return parser.parse_args() return parser.parse_args()
def main(): def main():
"""Initializes the program.""" """Initializes the program."""
setup_logging() setup_logging()
@ -60,6 +79,7 @@ def main():
exit_when_empty=True, exit_when_empty=True,
seller=seller_backend, seller=seller_backend,
sleep=time.sleep, sleep=time.sleep,
log_order_to_csv=order_csv.CsvFileLogger(PATH_TRADES_FILE),
) )
results = run_auto_sell(auto_sell_config) results = run_auto_sell(auto_sell_config)
logging.info('Sell-offs complete') logging.info('Sell-offs complete')

View File

@ -0,0 +1,25 @@
import csv
from pathlib import Path
import fin_depo
class CsvFileLogger:
def __init__(self, path: Path):
self.path = path
def __call__(self, trade_order: fin_depo.data.TradeOrderDetails):
fieldnames: list[str] = [
'input_asset',
'input_amount',
'output_asset',
'output_amount',
'fee_asset',
'fee_amount',
'order_id',
'raw_order_details',
]
with open(self.path, 'a') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writerow(trade_order.__dict__)

View File

@ -1,10 +1,12 @@
import datetime import datetime
from decimal import Decimal from decimal import Decimal
from pathlib import Path
import fin_defs import fin_defs
import fin_depo import fin_depo
import crypto_seller import crypto_seller
import crypto_seller.order_csv
class SellerMock(fin_depo.data.DepoFetcher): class SellerMock(fin_depo.data.DepoFetcher):
@ -59,6 +61,9 @@ def test_auto_run():
output_asset=fin_defs.USD, output_asset=fin_defs.USD,
exit_when_empty=True, exit_when_empty=True,
seller=seller_mock, seller=seller_mock,
log_order_to_csv=crypto_seller.order_csv.CsvFileLogger(
Path('output/test-trades.csv'),
),
sleep=sleep_mock, sleep=sleep_mock,
) )