Add Supertrend strategy and Risk Engine (Phase 2 Milestones 2.2, 2.3)
- Implement SupertrendStrategy with pandas-ta indicator, ATR-based stops - Add RiskEngine with position sizing, risk limits, portfolio heat tracking - Add comprehensive tests for both modules (32 new tests) - Update AGENTS.md with accurate project structure and py312 target
This commit is contained in:
72
AGENTS.md
72
AGENTS.md
@@ -6,57 +6,42 @@
|
||||
|
||||
| Task | Command |
|
||||
|------|---------|
|
||||
| Install | `pip install -e ".[dev]"` or `uv pip install -e ".[dev]"` |
|
||||
| Run all tests | `pytest` |
|
||||
| Run single test | `pytest tests/test_config.py::TestOrderRequest::test_valid_limit_order -v` |
|
||||
| Run test file | `pytest tests/test_config.py -v` |
|
||||
| Install | `uv pip install -e ".[dev]"` (or `pip install -e ".[dev]"`) |
|
||||
| All tests | `pytest` |
|
||||
| Single test | `pytest tests/test_config.py::TestOrderRequest::test_valid_limit_order -v` |
|
||||
| Test file | `pytest tests/test_config.py -v` |
|
||||
| Test by keyword | `pytest -k "test_valid" -v` |
|
||||
| Lint | `ruff check .` |
|
||||
| Lint fix | `ruff check . --fix` |
|
||||
| Format | `ruff format .` |
|
||||
| Type check | `mypy src/` |
|
||||
| Full check | `ruff check . && ruff format --check . && mypy src/ && pytest` |
|
||||
|
||||
---
|
||||
|
||||
## Build & Environment
|
||||
|
||||
- **Python**: 3.12+ required (3.12, 3.13 supported) - pandas-ta requires 3.12+
|
||||
- **Build system**: `hatchling` with `pyproject.toml`
|
||||
- **Prefer `uv`** for faster installs: `uv pip install -e ".[dev]"`
|
||||
- **Python**: 3.12+ required (pandas-ta requires 3.12+)
|
||||
- **Build**: `hatchling` via `pyproject.toml`
|
||||
- **Prefer `uv`**: 10-100x faster than pip
|
||||
|
||||
```bash
|
||||
# Setup
|
||||
uv venv .venv --python 3.12 && source .venv/bin/activate
|
||||
uv pip install -e ".[dev]"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing (pytest + pytest-asyncio)
|
||||
|
||||
```bash
|
||||
pytest # All tests with coverage
|
||||
pytest tests/test_config.py -v # Single file
|
||||
pytest tests/test_config.py::TestOrderRequest::test_valid_limit_order -v # Single test
|
||||
pytest -k "test_valid" -v # By keyword
|
||||
```
|
||||
## Testing
|
||||
|
||||
- `asyncio_mode = "auto"` - no `@pytest.mark.asyncio` needed
|
||||
- Test files: `tests/test_*.py`
|
||||
- Type hints required: `def test_xxx(self) -> None:`
|
||||
|
||||
---
|
||||
- Integration tests marked with `@pytest.mark.integration` (require testnet API keys)
|
||||
|
||||
## Linting & Type Checking
|
||||
|
||||
**Ruff** (line-length: 100, target: py311):
|
||||
- Rules: `E`, `W`, `F`, `I`, `B`, `C4`, `UP` (pycodestyle, pyflakes, isort, bugbear, comprehensions, pyupgrade)
|
||||
**Ruff** (line-length: 100, target: py312):
|
||||
- Rules: `E`, `W`, `F`, `I`, `B`, `C4`, `UP`
|
||||
|
||||
**MyPy**: `strict = true`, uses `pydantic.mypy` plugin
|
||||
|
||||
---
|
||||
|
||||
## Code Style Guidelines
|
||||
## Code Style
|
||||
|
||||
### Imports (isort-ordered)
|
||||
```python
|
||||
@@ -64,7 +49,6 @@ from abc import ABC, abstractmethod # 1. stdlib
|
||||
from decimal import Decimal
|
||||
|
||||
import httpx # 2. third-party
|
||||
import structlog
|
||||
|
||||
from tradefinder.adapters.types import Order # 3. first-party
|
||||
```
|
||||
@@ -72,11 +56,9 @@ from tradefinder.adapters.types import Order # 3. first-party
|
||||
### Type Hints (Required - strict mypy)
|
||||
```python
|
||||
async def get_balance(self, asset: str = "USDT") -> AccountBalance: ...
|
||||
|
||||
# Use | for unions, built-in generics
|
||||
def cancel_order(self, order_id: str | None = None) -> Order: ...
|
||||
list[str] # Not List[str]
|
||||
dict[str, Any] # Not Dict[str, Any]
|
||||
list[str] # NOT List[str]
|
||||
dict[str, Any] # NOT Dict[str, Any]
|
||||
```
|
||||
|
||||
### Numeric Values - Always Decimal
|
||||
@@ -93,8 +75,7 @@ class Position:
|
||||
quantity: Decimal
|
||||
raw: dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
# Pydantic for config/validation only
|
||||
class Settings(BaseSettings): ...
|
||||
class Settings(BaseSettings): ... # Pydantic for config/validation only
|
||||
```
|
||||
|
||||
### Enums
|
||||
@@ -103,14 +84,14 @@ class Side(str, Enum):
|
||||
BUY = "BUY"
|
||||
SELL = "SELL"
|
||||
|
||||
params["side"] = request.side.value # Use .value for API
|
||||
params["side"] = request.side.value # Use .value for API calls
|
||||
```
|
||||
|
||||
### Logging (structlog)
|
||||
```python
|
||||
logger = structlog.get_logger(__name__)
|
||||
logger.info("Order created", order_id=order.id, symbol=symbol)
|
||||
# NEVER log secrets: logger.info(f"API Key: {api_key}")
|
||||
# NEVER: logger.info(f"API Key: {api_key}") # No secrets in logs!
|
||||
```
|
||||
|
||||
### Async Patterns
|
||||
@@ -121,7 +102,6 @@ async def connect(self) -> None:
|
||||
async def disconnect(self) -> None:
|
||||
if self._client:
|
||||
await self._client.aclose()
|
||||
self._client = None
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
@@ -144,23 +124,19 @@ except httpx.RequestError as e:
|
||||
| Constants | UPPER_SNAKE | `MAX_LEVERAGE` |
|
||||
| Private | leading underscore | `_client`, `_sign()` |
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
src/tradefinder/
|
||||
adapters/ # Exchange connectivity (base.py, binance_usdm.py, types.py)
|
||||
core/ # Core engine (config.py)
|
||||
data/ # Market data (TODO)
|
||||
strategies/ # Trading strategies (TODO)
|
||||
ui/ # Streamlit dashboard (TODO)
|
||||
adapters/ # Exchange connectivity (base.py, binance_usdm.py, binance_spot.py, types.py)
|
||||
core/ # Core engine (config.py, regime.py)
|
||||
data/ # Market data (fetcher.py, storage.py, streamer.py, validator.py, schemas.py)
|
||||
strategies/ # Trading strategies (base.py, signals.py)
|
||||
ui/ # Streamlit dashboard
|
||||
tests/
|
||||
test_*.py # Test files
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security Rules (CRITICAL)
|
||||
|
||||
1. **NEVER commit `.env` or secrets** - `.gitignore` enforces this
|
||||
@@ -169,8 +145,6 @@ tests/
|
||||
4. **Use `Decimal`** for all financial values - never `float`
|
||||
5. **Validate trading mode** before any exchange operations
|
||||
|
||||
---
|
||||
|
||||
## Common Patterns
|
||||
|
||||
```python
|
||||
|
||||
Reference in New Issue
Block a user