Log trades to csv file
This commit is contained in:
parent
f5b69badd4
commit
a0b1ee9ae1
|
@ -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:
|
||||||
|
|
|
@ -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')
|
||||||
|
|
25
crypto_seller/order_csv.py
Normal file
25
crypto_seller/order_csv.py
Normal 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__)
|
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user