1
0

Compare commits

...

2 Commits

Author SHA1 Message Date
7d2b192b34
Documentation
Some checks failed
Python Ruff Code Quality / ruff (push) Failing after 22s
Run Python tests (through Pytest) / Test (push) Failing after 30s
Verify Python project can be installed, loaded and have version checked / Test (push) Failing after 25s
2024-12-02 18:11:44 +01:00
9c5f3db41d
More flexible datastructures for double registers. 2024-11-29 11:06:43 +01:00
3 changed files with 73 additions and 27 deletions

View File

@ -1,6 +1,7 @@
"""Datastructures for `fin-depo`.""" """Datastructures for `fin-depo`."""
import abc import abc
import dataclassabc
import dataclasses import dataclasses
import datetime import datetime
from collections.abc import Iterable, Mapping from collections.abc import Iterable, Mapping
@ -107,8 +108,37 @@ class DepoFetcher(abc.ABC):
@enforce_typing.enforce_types @enforce_typing.enforce_types
@dataclasses.dataclass(frozen=True) class DoubleRegister(abc.ABC):
class TradeOrderDetails: """Information about some movement of assets."""
@property
@abc.abstractmethod
def input(self) -> AssetAmount | None:
"""How much and what kind of asset have been placed into the depository."""
raise NotImplementedError
@property
@abc.abstractmethod
def output(self) -> AssetAmount | None:
"""How much and what kind of asset have been removed from the depository."""
raise NotImplementedError
@property
@abc.abstractmethod
def fee(self) -> AssetAmount | None:
"""How much and what kind of asset was spent as a service fee."""
raise NotImplementedError
@property
@abc.abstractmethod
def executed_time(self) -> datetime.datetime:
"""The precise point in time when the asset transaction was executed."""
raise NotImplementedError
@enforce_typing.enforce_types
@dataclassabc.dataclassabc(frozen=True)
class TradeOrderDetails(DoubleRegister):
"""Information about an executed trade. """Information about an executed trade.
Includes both well-structured data about the order, and unstructured data Includes both well-structured data about the order, and unstructured data
@ -136,26 +166,52 @@ class TradeOrderDetails:
@enforce_typing.enforce_types @enforce_typing.enforce_types
@dataclasses.dataclass(frozen=True) @dataclassabc.dataclassabc(frozen=True)
class WithdrawalDetails: class WithdrawalDetails(DoubleRegister):
"""Information about a withdrawal of assets from a specific service.
Withdraw assets may appear in another depository as a `DepositDetails`, but
these cannot be automatically linked by `fin-depo`.
Includes both well-structured data about the order, and unstructured data
from the backend. The unstructured data might be needed for tax purposes.
"""
withdrawn: AssetAmount withdrawn: AssetAmount
fee: AssetAmount fee: AssetAmount
executed_time: datetime.datetime executed_time: datetime.datetime
raw_details: object raw_details: object
@property
def input(self) -> AssetAmount:
return self.withdrawn
@property
def output(self) -> None:
return None
@enforce_typing.enforce_types @enforce_typing.enforce_types
@dataclasses.dataclass(frozen=True) @dataclassabc.dataclassabc(frozen=True)
class DepositDetails: class DepositDetails(DoubleRegister):
"""Information about a deposit of assets to a specific service.
Deposited assets may appear in another depository as a `WithdrawalDetails`, but
these cannot be automatically linked by `fin-depo`.
Includes both well-structured data about the order, and unstructured data
from the backend. The unstructured data might be needed for tax purposes.
"""
deposit: AssetAmount deposit: AssetAmount
fee: AssetAmount fee: AssetAmount
executed_time: datetime.datetime executed_time: datetime.datetime
raw_details: object raw_details: object
@property
def input(self) -> None:
return None
@enforce_typing.enforce_types @property
@dataclasses.dataclass(frozen=True) def output(self) -> AssetAmount:
class DoubleRegister: return self.deposit
input: AssetAmount | None
output: AssetAmount | None
executed_time: datetime.datetime

View File

@ -247,20 +247,10 @@ class KucoinDepoFetcher(DepoFetcher):
del _weeks_back, raw_details del _weeks_back, raw_details
def _get_double_registers(self) -> list[DoubleRegister]: def _get_double_registers(self) -> list[DoubleRegister]:
deposits = self._get_deposits() double_registers: list[DoubleRegister] = []
withdrawals = self._get_withdrawals() double_registers += self._get_deposits()
spot_trades = self._get_historic_spot_orders() double_registers += self._get_withdrawals()
double_registers += self._get_historic_spot_orders()
double_registers = []
double_registers += [
DoubleRegister(d.deposit, None, d.executed_time) for d in deposits
]
double_registers += [
DoubleRegister(None, d.withdrawn, d.executed_time) for d in withdrawals
]
double_registers += [
DoubleRegister(d.input, d.output, d.executed_time) for d in spot_trades
]
double_registers.sort(key=lambda x: x.executed_time) double_registers.sort(key=lambda x: x.executed_time)
return double_registers return double_registers

View File

@ -31,7 +31,7 @@ def test_place_market_order_requires_allow_trades():
) )
with pytest.raises(PermissionError) as m: with pytest.raises(PermissionError) as m:
fetcher.place_market_order(fin_defs.MPC, Decimal(1), fin_defs.USDT) fetcher.place_market_order(fin_defs.AssetAmount(fin_defs.MPC, Decimal(1)), fin_defs.USDT)
assert 'KucoinDepoFetcher.allow_trades is not enabled: Cannot make trades' in str(m) assert 'KucoinDepoFetcher.allow_trades is not enabled: Cannot make trades' in str(m)