diff --git a/data/trades/5_trades.json b/data/trades/5_trades.json index ae65d44..a47d33b 100644 --- a/data/trades/5_trades.json +++ b/data/trades/5_trades.json @@ -1 +1,3 @@ {"timestamp": "2025-08-03 13:06:22.359621", "side": "BUY", "pair": "EURQ/USD", "quantity": 1.0074, "price": 1.1536, "total_value": 1.16213664, "account_id": 5, "base_currency": "EURQ", "quote_currency": "ZUSD", "balances_after": {"EURQ": 6.0074000000000005, "ZUSD": 48.1963899}} +{"timestamp": "2025-08-04 15:54:52.890240", "side": "BUY", "pair": "EURQ/USD", "quantity": 1.97044, "price": 1.154, "total_value": 2.2738877599999996, "account_id": 5, "base_currency": "EURQ", "quote_currency": "ZUSD", "balances_after": {"EURQ": 7.9778400000000005, "ZUSD": 45.92250214}} +{"timestamp": "2025-08-04 18:40:22.338490", "side": "BUY", "pair": "EURQ/USD", "quantity": 1.0, "price": 1.1548, "total_value": 1.1548, "account_id": 5, "base_currency": "EURQ", "quote_currency": "ZUSD", "balances_after": {"EURQ": 8.97784, "ZUSD": 44.76770214}} diff --git a/kraken_ws/kraken_ws.py b/kraken_ws/kraken_ws.py index ad61263..1f90708 100644 --- a/kraken_ws/kraken_ws.py +++ b/kraken_ws/kraken_ws.py @@ -106,6 +106,122 @@ async def subscribe_book(self, symbols: List[str], depth: int = 10, handler: Opt self.subscriptions['book'] = subscription logger.info(f"Subscribed to order book for symbols: {symbols}, depth: {depth}") + # --- Public Market Data Unsubscription Methods (v2 format) --- + + async def unsubscribe_book(self, symbols: List[str]): + """Unsubscribe from order book data using v2 format.""" + subscription = { + "method": "unsubscribe", + "params": { + "channel": "book", + "symbol": symbols + } + } + + await self._send_public_subscription(subscription) + + # Remove from stored subscriptions + if 'book' in self.subscriptions: + del self.subscriptions['book'] + + logger.info(f"Unsubscribed from order book for symbols: {symbols}") + + async def unsubscribe_trades(self, symbols: List[str]): + """Unsubscribe from trade data using v2 format.""" + subscription = { + "method": "unsubscribe", + "params": { + "channel": "trade", + "symbol": symbols + } + } + + await self._send_public_subscription(subscription) + + # Remove from stored subscriptions + if 'trade' in self.subscriptions: + del self.subscriptions['trade'] + + logger.info(f"Unsubscribed from trades for symbols: {symbols}") + + async def unsubscribe_ticker(self, symbols: List[str]): + """Unsubscribe from ticker data using v2 format.""" + subscription = { + "method": "unsubscribe", + "params": { + "channel": "ticker", + "symbol": symbols + } + } + + await self._send_public_subscription(subscription) + + # Remove from stored subscriptions + if 'ticker' in self.subscriptions: + del self.subscriptions['ticker'] + + logger.info(f"Unsubscribed from ticker for symbols: {symbols}") + + async def unsubscribe_ohlc(self, symbols: List[str], interval: int = 1): + """Unsubscribe from OHLC data using v2 format.""" + subscription = { + "method": "unsubscribe", + "params": { + "channel": "ohlc", + "symbol": symbols, + "interval": interval + } + } + + await self._send_public_subscription(subscription) + + # Remove from stored subscriptions + if 'ohlc' in self.subscriptions: + del self.subscriptions['ohlc'] + + logger.info(f"Unsubscribed from OHLC for symbols: {symbols}, interval: {interval}") + + async def unsubscribe_all_public(self): + """Unsubscribe from all public market data subscriptions.""" + channels_to_unsubscribe = list(self.subscriptions.keys()) + + for channel in channels_to_unsubscribe: + if channel in ['book', 'trade', 'ticker', 'ohlc']: + subscription_info = self.subscriptions[channel] + symbols = subscription_info['params']['symbol'] + + if channel == 'book': + await self.unsubscribe_book(symbols) + elif channel == 'trade': + await self.unsubscribe_trades(symbols) + elif channel == 'ticker': + await self.unsubscribe_ticker(symbols) + elif channel == 'ohlc': + interval = subscription_info['params'].get('interval', 1) + await self.unsubscribe_ohlc(symbols, interval) + + logger.info("Unsubscribed from all public market data subscriptions") + + def remove_handler(self, event_type: str, handler: Optional[Callable] = None): + """ + Remove a message handler for a specific data type. + If handler is None, removes all handlers for that event type. + """ + if event_type in self.handlers: + if handler is None: + # Remove all handlers for this event type + del self.handlers[event_type] + logger.info(f"Removed all handlers for {event_type}") + else: + # Remove specific handler + if handler in self.handlers[event_type]: + self.handlers[event_type].remove(handler) + logger.info(f"Removed specific handler for {event_type}") + + # If no handlers left, remove the event type + if not self.handlers[event_type]: + del self.handlers[event_type] + async def subscribe_trades(self, symbols: List[str], handler: Optional[Callable] = None): """Subscribe to trade data using v2 format.""" if handler: diff --git a/resources/data/settings/settings.yaml b/resources/data/settings/settings.yaml index ef4a27b..18df688 100644 --- a/resources/data/settings/settings.yaml +++ b/resources/data/settings/settings.yaml @@ -1,6 +1,6 @@ program: name: "TradeByte" - version: "2.2.1" + version: "2.2.2" debug: false version_notes: - Version 2.2.1 8/2/2025