Metadata-Version: 2.4
Name: pyactuator
Version: 0.0.3
Summary: Thin broker-agnostic execution layer for trading: order submission, status, and fills
Author-email: StatFYI <contact@statfyi.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/statfyi/pyactuator
Project-URL: Documentation, https://github.com/statfyi/pyactuator#readme
Project-URL: Repository, https://github.com/statfyi/pyactuator
Project-URL: Issues, https://github.com/statfyi/pyactuator/issues
Project-URL: Changelog, https://github.com/statfyi/pyactuator/blob/main/CHANGELOG.md
Keywords: trading,execution,broker,alpaca,order,finance
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
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: Typing :: Typed
Classifier: Topic :: Office/Business :: Financial
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Provides-Extra: alpaca
Requires-Dist: alpaca-py>=0.14.0; extra == "alpaca"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff>=0.4.0; extra == "dev"
Requires-Dist: mypy>=1.5; extra == "dev"
Requires-Dist: pre-commit>=3.0; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"

# pyactuator

Thin broker-agnostic execution layer for trading systems: submit orders, poll status, cancel, and (optionally) subscribe to fills. Designed to sit between your FSM/OMS (e.g. pystator) and broker APIs (Alpaca, future IB/crypto).

## Features

- **Normalized types**: `OrderRequest`, `OrderResponse`, `OrderStatus`, `Fill` — your stack stays broker-agnostic.
- **ExecutionClient protocol**: One interface (`submit`, `get_status`, `cancel`, optional `subscribe_fills`) implemented per broker.
- **Adapters**: Alpaca (via alpaca-py), Mock (in-memory for tests and paper).
- **Optional helpers**: Retry policy, idempotency key handling, timeout wrapper.

## Installation

```bash
# Core only (types, protocol, mock adapter)
pip install pyactuator

# With Alpaca broker support
pip install pyactuator[alpaca]

# Development
pip install -e ".[dev]"
```

## Quick start

```python
from decimal import Decimal
from pyactuator import ExecutionClient, OrderRequest, Side, OrderType, TimeInForce
from pyactuator.adapters.mock import MockExecutionClient

# Use mock for tests or paper
client: ExecutionClient = MockExecutionClient()

order = OrderRequest(
    client_order_id="my-order-001",
    symbol="AAPL",
    side=Side.BUY,
    quantity=Decimal("10"),
    order_type=OrderType.MARKET,
    time_in_force=TimeInForce.DAY,
)
response = await client.submit(order)
print(response.success, response.external_order_id)

status = await client.get_status(response.external_order_id)
await client.close()
```

With Alpaca (requires `pip install pyactuator[alpaca]`):

```python
from pyactuator.adapters.alpaca import AlpacaExecutionClient

client = AlpacaExecutionClient(
    api_key="...",
    api_secret="...",
    paper=True,
)
# Same OrderRequest / submit / get_status / cancel
```

Optional retry wrapper and idempotency helpers:

```python
from pyactuator.helpers import RetryExecutionClient, generate_client_order_id
from pyactuator.adapters.alpaca import AlpacaExecutionClient

client = AlpacaExecutionClient(api_key="...", api_secret="...", paper=True)
client = RetryExecutionClient(client, max_attempts=3)
order_id = generate_client_order_id(prefix="pa", order_id="my-internal-id")
order = OrderRequest(client_order_id=order_id, symbol="AAPL", side=Side.BUY, quantity=Decimal("10"), ...)
```

## Integration with pystator

Your FSM or OrderManager receives an `ExecutionClient` (injected or constructed). When the FSM triggers "submit" (e.g. after risk approval via pyfortis), call `await client.submit(order_request)`. pystator stays broker-agnostic; execution is behind this single interface.

## License

MIT.
