trading/services/kevin_signal_bridge/config.py
Viktor Barzin adbd7f3c65
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
feat(kevin_bridge): main orchestrator with dependency injection
Composable: cursor/aggregator/strategy/publisher/audit_writer/broker
all injected. Master kill-switch (kevin_enable_trading=false) routes to
audit-only path. Cursor advances ONLY after XADD succeeds (race fix).
Concrete collaborators wired in subsequent tasks.

Also extends TradeSignal + SignalDirection.EXIT with the optional
fields Kevin paths need (strategy_id, target_dollars, stop_loss_pct,
take_profit_pct).
2026-05-24 00:59:56 +00:00

63 lines
1.7 KiB
Python

"""KevinBridgeConfig — env-var settings for the Kevin signal bridge service.
All env vars use the TRADING_ prefix consumed by shared.config.BaseConfig.
"""
from __future__ import annotations
import json
from typing import Any
from pydantic import field_validator
from shared.config import BaseConfig
class KevinBridgeConfig(BaseConfig):
"""Env-var driven settings for the bridge service."""
# Signal translation
kevin_min_conviction: float = 0.60
kevin_max_mention_age_hours: int = 48
kevin_hold_days: dict[str, int] = {
"days": 3,
"weeks": 10,
"months": 45,
"long_term": 90,
"unspecified": 10,
}
# Sizing
kevin_base_position_pct: float = 0.04
kevin_min_trade_usd: float = 500.0
kevin_max_trade_usd: float = 5000.0
kevin_max_per_ticker_usd: float = 7500.0
# Exits
kevin_stop_loss_pct: float = 0.08
kevin_take_profit_pct: float = 0.20
kevin_avoid_closes_longs: bool = True
kevin_avoid_blocks_days: int = 7
# Aggregation
kevin_mention_boost_per_repeat: float = 0.05
kevin_max_mention_boost: float = 0.20
# Risk
kevin_max_position_pct: float = 0.075
kevin_daily_trade_cap: int = 5
kevin_daily_alloc_cap_usd: float = 15000.0
kevin_daily_loss_circuit_pct: float = 0.03
kevin_equity_drawdown_halt_pct: float = 0.80
# Plumbing
kevin_bridge_poll_interval_seconds: int = 60
kevin_bridge_exit_scan_cron: str = "35 9 * * 1-5"
kevin_enable_trading: bool = False # master kill-switch
@field_validator("kevin_hold_days", mode="before")
@classmethod
def _parse_hold_days(cls, v: Any) -> Any:
if isinstance(v, str):
return json.loads(v)
return v