Skip to content

Commit

Permalink
Merge branch 'master' into dependabot/github_actions/actions/upload-a…
Browse files Browse the repository at this point in the history
…rtifact-4.6.0
  • Loading branch information
btschwertfeger authored Jan 13, 2025
2 parents 367ecd2 + d3dcb0a commit a0a3975
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dependabot_auto_merge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
if: ${{ github.actor == 'dependabot[bot]' }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
uses: step-security/harden-runner@c95a14d0e5bab51a9f56296a4eb0e416910cd350 # v2.10.3
with:
disable-sudo: true
egress-policy: block
Expand Down
1 change: 0 additions & 1 deletion src/kraken_infinity_grid/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,6 @@ def run(ctx: Context, **kwargs: dict) -> None:
ctx.obj |= kwargs

if ctx.obj["sqlite_file"]:
# FIXME: Maybe use in_memory for dry-run?
db_config = {"sqlite_file": ctx.obj["sqlite_file"]}
else:
db_config = {
Expand Down
76 changes: 57 additions & 19 deletions src/kraken_infinity_grid/gridbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,19 @@
import asyncio
import sys
import traceback
from contextlib import suppress
from datetime import datetime, timedelta
from decimal import Decimal
from logging import getLogger
from time import sleep
from types import SimpleNamespace
from typing import Iterable, Optional, Self

from kraken.exceptions import KrakenAuthenticationError
from kraken.exceptions import (
KrakenAuthenticationError,
KrakenInvalidOrderError,
KrakenPermissionDeniedError,
)
from kraken.spot import Market, SpotWSClient, Trade, User
from sqlalchemy.engine.result import MappingResult

Expand Down Expand Up @@ -103,22 +108,22 @@ class KrakenInfinityGridBot(SpotWSClient):
New execution message - new order:
- If the init is not done yet, the algorithm ignores the message. FIXME
- If the init is not done yet, the algorithm ignores the message.
- The algorithm ties to assign the new order to the orderbook. In some cases
this fails, as newly placed orders may not be fetchable via REST API for
some time. For this reason, there are some retries implemented.
New execution message - filled order:
- If the init is not done yet, the algorithm ignores the message. FIXME
- If the init is not done yet, the algorithm ignores the message.
- If the filled order was a buy order (depending on the strategy), the
algorithm places a sell order and updates the local orderbook.
- If the filled order was a sell order (depending on the strategy), the
algorithm places a buy order and updates the local orderbook.
New execution message - cancelled order:
- If the init is not done yet, the algorithm ignores the message. FIXME
- If the init is not done yet, the algorithm ignores the message.
- The algorithm removes the order from the local orderbook and ensures that
in case of a partly filled order, the remaining volume is saved and placed
as sell order somewhen later (if it was a buy order). Sell orders usually
Expand Down Expand Up @@ -307,7 +312,6 @@ async def on_message( # noqa: C901,PLR0912,PLR0911
)

except Exception as exc: # noqa: BLE001
# FIXME: this is not a beauty
LOG.error(msg="Exception while processing message.", exc_info=exc)
self.save_exit(reason=traceback.format_exc())

Expand All @@ -323,7 +327,19 @@ async def run(self: Self) -> None:
# Try to connect to the Kraken API and validate credentials
##
self.__check_kraken_status()
self.__check_credentials()

try:
self.__check_api_keys()
except (KrakenAuthenticationError, KrakenPermissionDeniedError) as exc:
await self.stop() # Stops the websocket connections
await self.async_close() # Stops the aiohttp session
self.save_exit(
(
"Passed API keys are invalid!"
if isinstance(exc, KrakenAuthenticationError)
else "Passed API keys are missing permissions!"
),
)

# ======================================================================
# Create the event loop to run the main
Expand Down Expand Up @@ -444,20 +460,44 @@ def __check_kraken_status(self: Self, tries: int = 0) -> None:
sleep(3)
self.__check_kraken_status(tries=tries + 1)

def __check_credentials(self: Self) -> None:
def __check_api_keys(self: Self) -> None:
"""
Checks if the credentials are valid by accessing a private endpoint.
Checks if the credentials are valid by accessing private endpoints.
"""
try:
self.user.get_account_balance()
LOG.info("- Passed API keys are valid.")
except KrakenAuthenticationError as exc:
LOG.debug(
"Exception while checking Kraken availability {exc} {traceback}",
extra={"exc": exc, "traceback": traceback.format_exc()},
LOG.info("- Checking permissions of API keys...")

LOG.info(" - Checking if 'Query Funds' permission set...")
self.user.get_account_balance()

LOG.info(" - Checking if 'Query open order & trades' permission set...")
self.user.get_open_orders(trades=True)

LOG.info(" - Checking if 'Query closed order & trades' permission set...")
self.user.get_closed_orders(trades=True)

LOG.info(" - Checking if 'Create & modify orders' permission set...")
self.trade.create_order(
pair=self.symbol,
side="buy",
ordertype="market",
volume="0.0001",
price="1",
validate=True,
)
LOG.info(" - Checking if 'Cancel & close orders' permission set...")
with suppress(KrakenInvalidOrderError):
self.trade.cancel_order(
txid="",
extra_params={"cl_ord_id": "kraken_infinity_grid_internal"},
)
LOG.error("- Passed API keys are invalid!")
sys.exit(1)

LOG.info(" - Checking if 'Websocket interface' permission set...")
self.trade.request(
method="POST",
uri="/0/private/GetWebSocketsToken",
)

LOG.info(" - Passed API keys and permissions are valid!")

# ======================================================================
# Helper Functions
Expand All @@ -466,8 +506,6 @@ def get_balances(self: Self) -> dict[str, float]:
"""
Returns the available and overall balances of the quote and base
currency.
! Hier aufpassen, denn wenn base_available falsch verwendet wird, werden
! gehaltene Währungen verkauft.
"""
LOG.debug("Retrieving the user's balances...")

Expand Down
4 changes: 2 additions & 2 deletions src/kraken_infinity_grid/order_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ def check_price_range(self: OrderManager) -> None:
LOG.debug("Check conditions for upgrading the grid...")

if self.__check_pending_txids():
# FIXME: This should not return here, but need to be checked first.
LOG.debug("Not checking price range because of pending txids.")
return

Expand Down Expand Up @@ -755,7 +754,8 @@ def cancel_all_open_buy_orders(self: OrderManager) -> None:

self.__s.orderbook.remove(filters={"side": "buy"})
except Exception: # noqa: BLE001
# FIXME: Check if this can still happen.
# FIXME: Check if this can still happen. Can't remember why this
# was added.
self.__s.save_exit(
str(
f"❌ Error in function >cancelAllOpenBuyOrders < \n"
Expand Down

0 comments on commit a0a3975

Please sign in to comment.