Metadata-Version: 2.4
Name: autobrain-sim
Version: 1.0.0
Summary: Python client for the WorldQuant Brain API
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-mock; extra == "dev"
Dynamic: license-file

# AutoBrain Sim

A lightweight Python client library for interacting with the [WorldQuant Brain](https://platform.worldquantbrain.com) platform API. Supports authentication, alpha simulation submission, and result retrieval.

## Features

- Multiple authentication methods (direct, credentials file, interactive prompt)
- Submit alpha expressions for simulation
- Poll for simulation completion automatically
- Retrieve alpha details and PnL record sets

## Install

```bash
pip install autobrain-sim
```

## Requirements

- Python 3.7+
- `requests`

Install the dependency:

```bash
pip install requests
```

## Files

| File | Description |
|------|-------------|
| `brain_client.py` | Core client library (`BrainClient`, `SimulationResult`) |
| `example.py` | Standalone usage example |
| `main.ipynb` | Jupyter notebook walkthrough |

## Quick Start

### Authentication

**Method 1 — Direct credentials**
```python
from brain_client import BrainClient

client = BrainClient(email="your@email.com", password="yourpassword")
client.authenticate()
```

**Method 2 — One-liner login**
```python
client = BrainClient.login("your@email.com", "yourpassword")
```

**Method 3 — Interactive prompt** (asks at runtime if no credentials are found)
```python
client = BrainClient()
client.authenticate()
```

**Method 4 — Credentials file**

Create `~/.brain_credentials` (or any path) as a JSON array:
```json
["your@email.com", "yourpassword"]
```

Then load it:
```python
client = BrainClient(credentials_file="~/.brain_credentials")
client.authenticate()
```

> Credentials priority: direct args → `credentials_file` → `~/.brain_credentials` → interactive prompt.

---

### Simulate an Alpha

```python
sim = client.simulate(
    expression="close / ts_mean(close, 20) - 1",
    settings={
        "region": "USA",
        "universe": "TOP3000",
        "neutralization": "SUBINDUSTRY",
    }
)

result = sim.wait(verbose=True)   # blocks until done
print("Alpha ID:", sim.alpha_id)
```

### Retrieve Results

```python
alpha = sim.get_alpha()
print("Sharpe:", alpha["is"]["sharpe"])
print("Fitness:", alpha["is"]["fitness"])

pnl = sim.get_pnl()
print(pnl)
```

---

## API Reference

### `BrainClient`

| Method | Description |
|--------|-------------|
| `__init__(email, password, credentials_file)` | Initialize client with credentials |
| `BrainClient.login(email, password)` | Create client and authenticate in one step |
| `authenticate()` | Sign in and obtain a session token |
| `simulate(expression, settings, ...)` | Submit an alpha for simulation; returns `SimulationResult` |
| `get_alpha(alpha_id)` | Fetch alpha details by ID |
| `get_pnl(alpha_id)` | Fetch PnL record set for an alpha |
| `get_recordset(alpha_id, record_set_name)` | Fetch any named record set |

#### Default Simulation Settings

```python
{
    "instrumentType": "EQUITY",
    "region": "USA",
    "universe": "TOP3000",
    "delay": 1,
    "decay": 15,
    "neutralization": "SUBINDUSTRY",
    "truncation": 0.08,
    "maxTrade": "ON",
    "pasteurization": "ON",
    "testPeriod": "P1Y6M",
    "unitHandling": "VERIFY",
    "nanHandling": "OFF",
    "language": "FASTEXPR",
}
```

Any key passed via `settings` overrides the default.

---

### `SimulationResult`

Returned by `client.simulate()`.

| Method | Description |
|--------|-------------|
| `wait(verbose=True)` | Poll until simulation completes; returns result JSON |
| `get_alpha()` | Fetch full alpha details (call after `wait()`) |
| `get_pnl(poll_interval)` | Fetch PnL record set (call after `wait()`) |

| Attribute | Description |
|-----------|-------------|
| `alpha_id` | Alpha ID string (available after `wait()`) |
| `progress_url` | URL used to poll simulation progress |

---

## Example

```python
from brain_client import BrainClient

client = BrainClient.login()  # interactive prompt

sim = client.simulate("close / ts_mean(close, 20) - 1")
result = sim.wait(verbose=True)

alpha = sim.get_alpha()
print(f"Alpha ID : {sim.alpha_id}")
print(f"Sharpe   : {alpha['is']['sharpe']}")
print(f"Fitness  : {alpha['is']['fitness']}")
```

## Notes

- The client uses HTTP Basic Auth to obtain a session token from the `/authentication` endpoint.
- Polling respects the `Retry-After` response header returned by the Brain API.
- Never commit your credentials to version control. Use `~/.brain_credentials` or environment variables instead.
