trading/services/kevin_signal_bridge/config.py

64 lines
1.7 KiB
Python
Raw Normal View History

"""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