diff --git a/requirements-lock.txt b/requirements-lock.txt index d238c85..93d4b25 100644 --- a/requirements-lock.txt +++ b/requirements-lock.txt @@ -1,21 +1,24 @@ aiohappyeyeballs==2.4.3 -aiohttp==3.11.12 +aiohttp==3.11.13 aiosignal==1.3.1 -alembic==1.14.1 +alembic==1.15.1 annotated-types==0.7.0 antlr4-python3-runtime==4.9.3 asn1crypto==1.5.1 async-lru==2.0.4 attrs==23.2.0 bip-utils==2.9.3 -bitarray==3.0.0 -cachetools==5.5.1 +bitarray==3.1.1 +cachetools==5.5.2 +cattrs==24.1.2 cbor2==5.6.4 certifi==2024.2.2 cffi==1.16.0 charset-normalizer==3.4.1 ckzg==1.0.2 +click==8.1.8 coincurve==20.0.0 +coremltools==8.2 crcmod==1.7 cytoolz==0.12.3 defaultlist==1.0.0 @@ -31,39 +34,73 @@ eth-rlp==1.0.1 eth-typing==4.4.0 eth-utils==4.1.1 eth_abi==5.2.0 +filelock==3.17.0 frozenlist==1.4.1 +fsspec==2025.2.0 google-auth==2.35.0 greenlet==3.0.3 hexbytes==0.3.1 hiredis==3.0.0 idna==3.7 +imageio==2.37.0 +importlib_resources==6.5.2 +Jinja2==3.1.6 +joblib==1.4.2 jsonschema==4.21.1 jsonschema-specifications==2023.12.1 +kraken==5.3.0 kubernetes==31.0.0 +lazy_loader==0.4 +lightning==2.4.0 +lightning-utilities==0.14.0 lru-dict==1.2.0 +lxml==5.3.1 Mako==1.3.3 +markdown-it-py==3.0.0 MarkupSafe==2.1.5 +mdurl==0.1.2 +mpmath==1.3.0 msgpack-python==0.5.6 multidict==6.0.5 -numpy==2.2.2 +networkx==3.4.2 +numpy==2.0.2 +nvidia-cublas-cu12==12.1.3.1 +nvidia-cuda-cupti-cu12==12.1.105 +nvidia-cuda-nvrtc-cu12==12.1.105 +nvidia-cuda-runtime-cu12==12.1.105 +nvidia-cudnn-cu12==9.1.0.70 +nvidia-cufft-cu12==11.0.2.54 +nvidia-curand-cu12==10.3.2.106 +nvidia-cusolver-cu12==11.4.5.107 +nvidia-cusparse-cu12==12.1.0.106 +nvidia-nccl-cu12==2.20.5 +nvidia-nvjitlink-cu12==12.8.93 +nvidia-nvtx-cu12==12.1.105 oauthlib==3.2.2 omegaconf==2.3.0 orjson==3.10.15 +packaging==24.2 pagerduty==1.0.0 parsimonious==0.10.0 +pillow==11.1.0 prometheus_client==0.21.1 propcache==0.2.0 protobuf==5.26.1 psycopg2-binary==2.9.10 py-sr25519-bindings==0.2.0 +pyaml==25.1.0 +pyarrow==19.0.1 pyasn1==0.6.1 pyasn1_modules==0.4.1 pycparser==2.22 pycryptodome==3.20.0 pydantic==2.9.2 pydantic_core==2.23.4 +Pygments==2.19.1 PyNaCl==1.5.0 +python-bidi==0.6.6 python-dateutil==2.9.0.post0 +pytorch-lightning==2.5.0.post0 pytz==2025.1 pyunormalize==15.1.0 PyYAML==6.0.1 @@ -72,18 +109,32 @@ referencing==0.35.0 regex==2024.4.28 requests==2.32.3 requests-oauthlib==2.0.0 +rich==13.9.4 rlp==4.0.1 rpds-py==0.18.0 rsa==4.9 +scikit-image==0.24.0 +scikit-learn==1.5.2 +scipy==1.13.1 +setuptools==75.8.2 +shapely==2.0.7 six==1.16.0 socket.io-emitter==0.1.5.1 sortedcontainers==2.4.0 SQLAlchemy==2.0.38 +sympy==1.13.3 +threadpoolctl==3.5.0 +tifffile==2025.2.18 toolz==0.12.1 +torch==2.4.1 +torchmetrics==1.6.2 +torchvision==0.19.1 +tqdm==4.67.1 +triton==3.0.0 types-requests==2.32.0.20240914 typing_extensions==4.12.2 urllib3==2.2.1 -web3==6.20.3 +web3==6.20.4 websocket-client==1.8.0 -websockets==14.2 +websockets==13.1 yarl==1.17.2 diff --git a/requirements.txt b/requirements.txt index f769dc1..b630a04 100644 --- a/requirements.txt +++ b/requirements.txt @@ -30,3 +30,4 @@ aiohttp charset-normalizer pytz prometheus_client +krakenex diff --git a/src/dexorder/accounting/__init__.py b/src/dexorder/accounting/__init__.py new file mode 100644 index 0000000..355e700 --- /dev/null +++ b/src/dexorder/accounting/__init__.py @@ -0,0 +1 @@ +from .accounting import * diff --git a/src/dexorder/accounting.py b/src/dexorder/accounting/accounting.py similarity index 100% rename from src/dexorder/accounting.py rename to src/dexorder/accounting/accounting.py diff --git a/src/dexorder/accounting/kraken.py b/src/dexorder/accounting/kraken.py new file mode 100644 index 0000000..36536b4 --- /dev/null +++ b/src/dexorder/accounting/kraken.py @@ -0,0 +1,65 @@ +import logging +import tempfile +from dataclasses import dataclass +from typing import Optional + +import krakenex + +from dexorder import timestamp +from dexorder.bin.executable import execute + +log = logging.getLogger(__name__) + +kraken_api_key=r'HqPHnGsAHunFtaP8YZTFsyh+LauVrcgFHi/US+RseR/4DiT+NG/JpONV' +kraken_api_secret=r'4hvdMdaN5TlNlyk2PShdRCsOE/T4sFzeBrR7ZjC+LUGuAXhBehY8vvWDZSUSyna2OFeOJ9GntPvyXOhrpx70Bg==' + +kraken = krakenex.API() + + +# start and end should be timestamps or datetimes. inclusiveness is [start,end) as usual +def kraken_get_ledger(start=None, end=None): + entries = [] + offset=1 # 1-based ffs + if start: + start = timestamp(start) - 1 # kraken start is EXCLUSIVE for some reason + if end: + end = timestamp(end) - 1 # kraken end is INCLUSIVE. :/ + while True: + kl = kraken.query_private('Ledgers', {'start':start, 'end':end, 'ofs':offset}) + print(repr(kl)) + break + if kl.empty: + break + for t in kl.itertuples(): + print(t) + # noinspection PyShadowingBuiltins + offset += len(kl) + return entries + + +@dataclass +class KrakenConfig: + kraken_api_key: Optional[str] = None + kraken_api_secret: Optional[str] = None + kraken_start: Optional[str]= None # timestamp or date + kraken_end: Optional[str] = None # timestamp or date + +async def main(kconfig: KrakenConfig): + load_kraken_key(kconfig) + kraken_get_ledger() + + +def load_kraken_key(kconfig): + temp = tempfile.NamedTemporaryFile() + if not kconfig.kraken_api_key or not kconfig.kraken_api_secret: + log.error("Must set kraken_api_key= and kraken_api_secret= on the command line") + exit(1) + temp.write(kconfig.kraken_api_key.encode()) + temp.write(b'\n') + temp.write(kconfig.kraken_api_secret.encode()) + temp.write(b'\n') + kraken.load_key(temp.name) + + +if __name__ == '__main__': + execute(main, parse_args=KrakenConfig) diff --git a/src/dexorder/bin/executable.py b/src/dexorder/bin/executable.py index 3921d9d..a8ecbc7 100644 --- a/src/dexorder/bin/executable.py +++ b/src/dexorder/bin/executable.py @@ -74,12 +74,13 @@ def execute(main:Callable[...,Coroutine[Any,Any,Any]], shutdown=None, *, parse_l # NOTE: there is special command-line argument handling in config/load.py to get a config filename. # The -c/--config flag MUST BE FIRST if present. configuration.parse_args(omegaconf_args) - if callable(parse_args): - # noinspection PyUnboundLocalVariable - xconf = parse_args(regular_args) - elif isinstance(parse_args, type): + # must check for `type` before `callable`, because types are also callables + if isinstance(parse_args, type): # noinspection PyUnboundLocalVariable xconf = OmegaConf.merge(OmegaConf.structured(parse_args), OmegaConf.from_cli(regular_args)) + elif callable(parse_args): + # noinspection PyUnboundLocalVariable + xconf = parse_args(regular_args) init_alerts()