-
-
Notifications
You must be signed in to change notification settings - Fork 14
Description
Overview
Sometimes there is a need to have custom triggers, which allows defining logic in response to off-chain events such as CEX websocket feeds, Pyth API updates, etc.
Specification
Define a new module .triggers
where we define BaseTrigger
that is inherited by all of our supported triggers, then add new method SilverbackBot.on_trigger
that accepts *triggers: BaseTrigger
defined as a handler for OR combination of all trigger
condition execution. Lastly, redefine SilverbackBot.on_
and SilverbackBot.cron
to re-map to this new class system, and simplify the internal logic of handling different operational modes for backtesting, etc.
Usage:
...
from pydantic import BaseModel
from silverback import SilverbackBot
from silverback.triggers import BaseTrigger
bot = SilverbackBot()
class CustomAPIModel(BaseModel):
pair: str
time: datetime
price_updates: list[float]
class CustomTrigger(BaseTrigger):
def __init__(self, *custom_args):
...
# NOTE: For "backtesting" use (aka historical data)
async def backfill(
self, start_time: datetime, stop_time: datetime
) -> AsyncIterator[CustomAPIModel]:
yield from map(
CustomAPIModel.model_load,
await self.api.get(
"/historical",
params=dict(start_time=str(start), stop_time=str(stop)),
).json(),
)
# NOTE: For "runtime" use
async def __aiter__(self) -> AsyncIterator[CustomAPIModel]:
async for item in self.api.get("/streaming", stream=True):
yield CustomAPIModel.model_load(item.json())
# NOTE: This allows defining OR triggers (whenever one OR the other has an update)
@bot.on_trigger(CustomTrigger("ETH/USD"), CustomTrigger("BTC/USD"), ...)
async def on_custom_trigger(value: CustomAPIModel):
... # do stuff
Using this, we can also refactor how we use the data from Ape for events logs and blocks, also how we represent cron triggers internally
Dependencies
n/a