BaseClock¶
Module: chronopype.clocks.base
Abstract base class for all clock implementations. Inherits from AsyncContextManager and MultiPublisher (from eventspype).
Events¶
start_publication: EventPublication # emits ClockStartEvent
tick_publication: EventPublication # emits ClockTickEvent
stop_publication: EventPublication # emits ClockStopEvent
Event Dataclasses¶
@dataclass
class ClockStartEvent:
timestamp: float
mode: ClockMode
tick_size: float
@dataclass
class ClockTickEvent:
timestamp: float
tick_counter: int
processors: list[TickProcessor]
@dataclass
class ClockStopEvent:
timestamp: float
total_ticks: int
final_states: dict[TickProcessor, ProcessorState]
Constructor¶
BaseClock(
config: ClockConfig,
error_callback: Callable[[TickProcessor, Exception], None] | None = None
)
| Parameter | Description |
|---|---|
config |
Clock configuration |
error_callback |
Optional callback invoked when a processor fails after all retries |
Properties¶
| Property | Type | Description |
|---|---|---|
config |
ClockConfig |
The clock configuration |
clock_mode |
ClockMode |
Current mode (REALTIME or BACKTEST) |
start_time |
float |
Configured start time |
end_time |
float |
Configured end time |
tick_size |
float |
Interval between ticks |
processors |
list[TickProcessor] |
All registered processors |
current_timestamp |
float |
Current clock timestamp |
tick_counter |
int |
Number of ticks processed |
processor_states |
dict[TickProcessor, ProcessorState] |
Copy of all processor states |
is_in_context |
bool |
Whether the clock is currently inside an async context |
Processor Management¶
add_processor(processor)¶
Add a processor to the clock. If the clock is already in context, start() is called on the processor immediately.
Raises: ClockError if the processor is already registered, already belongs to another clock, or fails to start.
remove_processor(processor)¶
Remove a processor from the clock. Calls stop() on the processor.
Raises: ClockError if the processor is not registered or fails to stop.
pause_processor(processor)¶
Pause a processor. It remains registered but is skipped during tick execution. Calls processor.pause() to allow processors with background tasks (e.g., NetworkProcessor) to suspend them.
Raises: ClockError if the processor is not registered.
resume_processor(processor)¶
Resume a paused processor. Calls processor.resume() to allow processors with background tasks to restart them.
Raises: ClockError if the processor is not registered.
get_processor_state(processor)¶
Returns the ProcessorState for a processor, or None if not registered.
get_active_processors()¶
Returns a list of all processors currently marked as active.
get_lagging_processors(threshold)¶
Returns processors whose average execution time exceeds threshold seconds.
Execution¶
run() (abstract)¶
Run the clock. Implementation-specific behavior:
RealtimeClock: runs indefinitely until cancelledBacktestClock: runs fromstart_timetoend_time
run_til(target_time) (abstract)¶
Run the clock until target_time is reached.
Raises: ClockError if the clock is already running.
shutdown(timeout=None)¶
Shutdown the clock and stop all processors. Awaits async cleanup for processors that support it (e.g., NetworkProcessor).
Note
The timeout parameter is accepted but currently unused.
Performance¶
get_processor_performance(processor)¶
Returns a tuple (avg_time, std_dev, p95) for the processor's execution times.
get_processor_stats(processor)¶
Returns a ProcessorStats typed dictionary with detailed statistics, or None if the processor is not registered. See Performance Monitoring for the full list of keys.
Context Manager¶
async with clock as c:
# __aenter__: starts all processors, emits ClockStartEvent
...
# __aexit__: stops all processors, emits ClockStopEvent
Raises: ClockContextError if already in context or running.