Files
Celes Renata 4ffde8cc06 feat: autonomous trading engine — full implementation
- Database migration 018 with 13 tables for trading engine state
- Trading engine service (services/trading/) with 12 pure computation modules:
  position sizer, stop-loss manager, reserve pool, circuit breaker,
  risk tier controller, correlation matrix, tax lots, trading window,
  gradual entry, notifications, micro-trading, backtester
- Core TradingEngine with pre-trade evaluation pipeline and integration wiring
- FastAPI HTTP service with 14 endpoints (health, config, decisions, metrics, backtest)
- Performance tracker with Sharpe ratio, drawdown, profit factor computation
- 194 Python tests (165 property-based + 29 integration)
- Frontend: 13 TanStack Query hooks, 7 dashboard panels, tabbed Trading Engine page
- Helm chart entry, network policy, nginx proxy, ingress for trading-engine
- Shared infrastructure: enums, Redis keys, TradingConfig in AppConfig
2026-04-15 16:12:22 +00:00

82 lines
2.5 KiB
Python

"""Gradual entry logic for the autonomous trading engine.
Pure computation module that determines whether an order should be split
into multiple tranches and performs the splitting. The
``GradualEntryManager`` class (which tracks pending tranches at runtime
and re-evaluates conditions) is intentionally left as a thin wrapper
here — the core logic is in the pure functions below.
"""
from __future__ import annotations
from dataclasses import dataclass
# ---------------------------------------------------------------------------
# Tranche dataclass
# ---------------------------------------------------------------------------
@dataclass
class Tranche:
"""A single tranche within a gradual-entry order sequence."""
tranche_index: int
quantity: int
parent_decision_id: str
status: str = "pending"
# ---------------------------------------------------------------------------
# Pure computation helpers
# ---------------------------------------------------------------------------
def should_use_gradual_entry(
position_size_dollars: float,
active_pool: float,
threshold_dollars: float = 30.0,
) -> bool:
"""Return True when the position size exceeds the gradual-entry threshold.
The effective threshold is ``min(threshold_dollars, 5% of active_pool)``.
"""
effective_threshold = min(threshold_dollars, 0.05 * active_pool)
return position_size_dollars > effective_threshold
def split_into_tranches(total_quantity: int, num_tranches: int = 3) -> list[int]:
"""Split *total_quantity* into *num_tranches* approximately equal parts.
The remainder is distributed one unit at a time to the first tranches
so that:
* ``sum(result) == total_quantity``
* All values differ by at most 1
"""
if num_tranches <= 0:
return []
if total_quantity <= 0:
return [0] * num_tranches
base, remainder = divmod(total_quantity, num_tranches)
return [base + (1 if i < remainder else 0) for i in range(num_tranches)]
def create_tranches(
total_quantity: int,
parent_decision_id: str,
num_tranches: int = 3,
) -> list[Tranche]:
"""Create :class:`Tranche` objects linked to *parent_decision_id*.
Uses :func:`split_into_tranches` for the quantity distribution.
"""
quantities = split_into_tranches(total_quantity, num_tranches)
return [
Tranche(
tranche_index=i,
quantity=q,
parent_decision_id=parent_decision_id,
)
for i, q in enumerate(quantities)
]