Metadata-Version: 2.4
Name: pyfortis
Version: 0.0.1
Summary: Config-driven risk engine for trading systems
Project-URL: Homepage, https://github.com/your-org/pyfortis
Project-URL: Documentation, https://github.com/your-org/pyfortis#readme
Project-URL: Repository, https://github.com/your-org/pyfortis
Project-URL: Issues, https://github.com/your-org/pyfortis/issues
Project-URL: Changelog, https://github.com/your-org/pyfortis/blob/main/CHANGELOG.md
Author-email: StatFYI <contact@statfyi.com>
License-Expression: MIT
License-File: LICENSE
Keywords: circuit-breaker,finance,limits,pre-trade,risk,trading
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: pyyaml>=6.0
Provides-Extra: api
Requires-Dist: fastapi>=0.100; extra == 'api'
Requires-Dist: uvicorn>=0.20; extra == 'api'
Provides-Extra: db
Requires-Dist: alembic>=1.10; extra == 'db'
Requires-Dist: sqlalchemy>=2.0; extra == 'db'
Provides-Extra: dev
Requires-Dist: build>=1.0; extra == 'dev'
Requires-Dist: hypothesis>=6.80; extra == 'dev'
Requires-Dist: mypy>=1.5; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Requires-Dist: twine>=5.0; extra == 'dev'
Provides-Extra: full
Requires-Dist: alembic>=1.10; extra == 'full'
Requires-Dist: confluent-kafka>=2.0; extra == 'full'
Requires-Dist: fastapi>=0.100; extra == 'full'
Requires-Dist: numpy>=1.24; extra == 'full'
Requires-Dist: pydantic>=2.0; extra == 'full'
Requires-Dist: redis>=5.0; extra == 'full'
Requires-Dist: scipy>=1.10; extra == 'full'
Requires-Dist: sqlalchemy>=2.0; extra == 'full'
Requires-Dist: uvicorn>=0.20; extra == 'full'
Provides-Extra: kafka
Requires-Dist: confluent-kafka>=2.0; extra == 'kafka'
Provides-Extra: metrics
Requires-Dist: numpy>=1.24; extra == 'metrics'
Requires-Dist: scipy>=1.10; extra == 'metrics'
Provides-Extra: redis
Requires-Dist: redis>=5.0; extra == 'redis'
Provides-Extra: validation
Requires-Dist: pydantic>=2.0; extra == 'validation'
Description-Content-Type: text/markdown

# PyFortis

**Config-driven risk engine for trading systems.**

PyFortis lets you define limits, metrics, and circuit breakers in YAML, then validate orders and run risk checks through a simple Python API. It supports stateless validation, stateful monitors, and a full orchestrator with pluggable stores and handlers.

## Install

```bash
pip install pyfortis
```

Optional extras (install what you need):

```bash
pip install pyfortis[metrics]   # NumPy/SciPy for VaR, drawdown, etc.
pip install pyfortis[validation]  # Pydantic for schema validation
pip install pyfortis[full]     # All optional dependencies
```

| Extra        | Purpose                          |
| ------------ | --------------------------------- |
| `validation` | Pydantic-based config validation  |
| `db`         | SQLAlchemy + Alembic              |
| `api`        | FastAPI + Uvicorn                 |
| `kafka`      | Confluent Kafka                   |
| `metrics`    | NumPy/SciPy for risk metrics      |
| `redis`      | Redis client                      |
| `full`       | All of the above                  |

## Quick start

Load an engine from a YAML config, then validate orders:

```python
from pathlib import Path
from pyfortis import Order, RiskEngine, Side

engine = RiskEngine.from_yaml(Path("risk_config.yaml"))

order = Order(
    order_id="o-001",
    instrument="AAPL",
    side=Side.BUY,
    quantity=100,
    price=150.0,
    portfolio="default",
)
result = engine.validate_order(order)
print(result.verdict.value, result.message)
```

See [examples/basic_usage.py](examples/basic_usage.py) and [examples/risk_config.yaml](examples/risk_config.yaml) for a full walkthrough.

## Concepts

- **Limits** — Pre-trade checks (position size, concentration, price tolerance, notional, etc.) with configurable severity (INFO, WARNING, CRITICAL, KILL).
- **Metrics** — Post-trade or periodic risk metrics (VaR, CVaR, drawdown, volatility, etc.) with optional breach thresholds.
- **Circuit breakers** — Halt trading when conditions are met (e.g. daily PnL loss, drawdown).
- **Three layers**:
  - **Engine** — Stateless: load config, validate single orders without position context.
  - **Monitor** — Stateful: hold positions in memory, validate orders and check circuit breakers.
  - **Orchestrator** — Persistent: load/save positions and breaches via stores, run metrics, dispatch handlers (log, notify, block, etc.).

Config supports env-var substitution (e.g. `${VAR}` or `${VAR:-default}`) and a breach escalation policy per severity.

## Links

- [Changelog](CHANGELOG.md)
- [Contributing](CONTRIBUTING.md)
- [License](LICENSE)
