# SixtySix

Python SDK and CLI for building and deploying automated trading strategies on [sixtysix.pro](https://sixtysix.pro).

The **SDK** lets you write strategies and indicators in Python — they are picked up automatically by the backend, which handles data feeds, backtesting, live execution, and the charting UI.

The **CLI** manages the backend: pull the Docker image, authenticate, run backtests from the terminal, or deploy to a cloud VPS with one command.

**Full documentation:** [sixtysix.pro/docs](https://sixtysix.pro/docs)

---

## Install

```bash
pip install "sixtysix[cli]"
```

---

## Quick Start — Strategy

```python
from sixtysix import strategy, computed, param, persistent, Line

@strategy(name='sma_crossover', display_name='SMA Crossover', category='Trend Following')
class SMACrossover:
    fast = param.number(default=20, min=5, max=100)
    slow = param.number(default=50, min=10, max=200)

    @computed
    def fast_sma(self, df):
        return df['close'].rolling(self.fast).mean()

    @computed
    def slow_sma(self, df):
        return df['close'].rolling(self.slow).mean()

    def plot(self, df):
        return [
            Line(y=self.fast_sma, color='#3b82f6', legend='Fast'),
            Line(y=self.slow_sma, color='#f97316', legend='Slow'),
        ]

    def on_bar(self, df):
        if self.position.is_flat and self.ta.crossover(self.fast_sma, self.slow_sma):
            return self.buy(reason='Golden cross')
        if self.position.is_long and self.ta.crossunder(self.fast_sma, self.slow_sma):
            return self.close(reason='Death cross')
```

## Quick Start — Indicator

```python
from sixtysix import indicator, param, Line, Fill

@indicator(name='bollinger_bands', display_name='Bollinger Bands', type='overlay')
class BollingerBands:
    period = param.number(default=20, min=2, max=500)
    std    = param.number(default=2.0, min=0.1, max=5.0, step=0.1)
    color  = param.color(default='#3b82f6')

    def plot(self, df):
        mid   = df['close'].rolling(self.period).mean()
        sigma = df['close'].rolling(self.period).std()
        upper = mid + self.std * sigma
        lower = mid - self.std * sigma
        return [
            Line(y=upper, color=self.color, line_dash='dashed'),
            Line(y=mid,   color=self.color),
            Line(y=lower, color=self.color, line_dash='dashed'),
            Fill(y1=upper, y2=lower, color=self.color, alpha=0.05),
        ]
```

For the full SDK reference — parameters, `@computed`, multi-timeframe, `persistent()`, plot components, signals — see [sixtysix.pro/docs](https://sixtysix.pro/docs).

---

## CLI

### Authentication

```bash
sixtysix login
```

Opens a browser window. After sign-in the refresh token is stored at `~/.sixtysix/config.json`.

### Local Docker backend

```bash
sixtysix start          # Pull latest image and start container
sixtysix stop           # Stop and remove container (data preserved)
sixtysix restart        # Restart container
sixtysix status         # Show container status and uptime
sixtysix logs           # Tail logs  (-n 100  --follow / -f)
sixtysix update         # Pull latest image and replace container
```

### Backtesting

```bash
sixtysix backtest accounts                            # List your broker accounts and their aliases
sixtysix backtest strategies                          # List available strategies
sixtysix backtest params sma_crossover                # Show configurable params

sixtysix backtest run -s sma_crossover -S AAPL,TSLA -t 1h -a "My IBKR"
sixtysix backtest run -s sma_crossover -S SPY -t 1d -d 730 --capital 50000 -a "Alpaca Paper"
sixtysix backtest run -s ha_pullback -S AAPL -t 1h --params '{"atr_mult": 2.0}' -a 3
```

| Flag | Default | Description |
|------|---------|-------------|
| `-s` | required | Strategy name |
| `-S` | required | Comma-separated symbols |
| `-a` / `--account` | required | Account alias or numeric account ID (see `backtest accounts`) |
| `-t` | `1h` | Timeframe (`1m` `5m` `15m` `30m` `1h` `4h` `1d` `1w`) |
| `-d` | `365` | Days of historical data |
| `--capital` | `10000` | Initial capital |
| `--position-size` | `0.95` | Fraction of equity per trade |
| `--no-save` | — | Don't persist results to database |
| `--json` | — | Output results as JSON |

Results are saved to the database and visible in the UI at `/backtest`.

### Cloud deployment (Hetzner)

```bash
sixtysix cloud deploy   # Interactive wizard: creates VPS, installs Docker, starts backend
sixtysix cloud status   # Show server IP, type, and running status
sixtysix cloud logs     # Stream logs from the remote container  (-f to follow)
sixtysix cloud restart  # Restart container on remote server
sixtysix cloud update   # Pull latest image on remote server
sixtysix cloud ssh      # Open SSH session
sixtysix cloud destroy  # Delete the server (irreversible)
```
