37 lines
1.1 KiB
Python
37 lines
1.1 KiB
Python
"""Redis-backed per-symbol blocklist with TTL.
|
|
|
|
Set on AVOID mentions. Subsequent BUY mention on the same symbol clears
|
|
the entry (handled by the strategy callsite, not here).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
|
|
class KevinBlocklist:
|
|
_KEY_PREFIX = "kevin:blocked:"
|
|
|
|
def __init__(self, redis: Any) -> None:
|
|
self.redis = redis
|
|
|
|
async def add(self, symbol: str, ttl_days: int) -> None:
|
|
await self.redis.set(
|
|
f"{self._KEY_PREFIX}{symbol}",
|
|
"1",
|
|
ex=ttl_days * 86400,
|
|
)
|
|
|
|
async def remove(self, symbol: str) -> None:
|
|
await self.redis.delete(f"{self._KEY_PREFIX}{symbol}")
|
|
|
|
async def is_blocked(self, symbol: str) -> bool:
|
|
return bool(await self.redis.exists(f"{self._KEY_PREFIX}{symbol}"))
|
|
|
|
async def active_set(self) -> set[str]:
|
|
keys = await self.redis.keys(f"{self._KEY_PREFIX}*")
|
|
out: set[str] = set()
|
|
for k in keys:
|
|
key_str = k.decode() if isinstance(k, bytes) else k
|
|
out.add(key_str.replace(self._KEY_PREFIX, ""))
|
|
return out
|