> ## Documentation Index
> Fetch the complete documentation index at: https://mathematicalcompany.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> Environment variables, exchange credentials, hot-reload parameters, and logging configuration.

Horizon reads credentials and configuration from environment variables as a fallback when not passed explicitly to constructors.

## Horizon API Key

| Variable          | Description                         |
| ----------------- | ----------------------------------- |
| `HORIZON_API_KEY` | Your Horizon SDK API key (required) |

```bash theme={null}
export HORIZON_API_KEY="hz_live_abc123..."
```

Get your key at [api.mathematicalcompany.com](https://api.mathematicalcompany.com). See the [Authentication](/authentication) page for details.

## Polymarket

| Variable                    | Description                                             |
| --------------------------- | ------------------------------------------------------- |
| `POLYMARKET_PRIVATE_KEY`    | Ethereum private key (hex, with or without `0x` prefix) |
| `POLYMARKET_API_KEY`        | CLOB API key                                            |
| `POLYMARKET_API_SECRET`     | CLOB API secret                                         |
| `POLYMARKET_API_PASSPHRASE` | CLOB API passphrase                                     |

```bash theme={null}
export POLYMARKET_PRIVATE_KEY="0x..."
export POLYMARKET_API_KEY="..."
export POLYMARKET_API_SECRET="..."
export POLYMARKET_API_PASSPHRASE="..."
```

```python theme={null}
hz.Polymarket()  # reads from env automatically
```

## Kalshi

| Variable          | Description                                     |
| ----------------- | ----------------------------------------------- |
| `KALSHI_EMAIL`    | Kalshi account email                            |
| `KALSHI_PASSWORD` | Kalshi account password                         |
| `KALSHI_API_KEY`  | Kalshi API key                                  |
| `KALSHI_API_URL`  | Kalshi API base URL (override for demo/staging) |

```bash theme={null}
export KALSHI_API_KEY="..."
# or
export KALSHI_EMAIL="..."
export KALSHI_PASSWORD="..."
```

```python theme={null}
hz.Kalshi()  # reads from env automatically
```

## Database

| Variable     | Description          | Default                |
| ------------ | -------------------- | ---------------------- |
| `HORIZON_DB` | SQLite database path | `./{strategy_name}.db` |

```bash theme={null}
export HORIZON_DB="/data/horizon.db"
```

## Logging

| Variable      | Description               | Default |
| ------------- | ------------------------- | ------- |
| `HORIZON_LOG` | Rust tracing filter level | `warn`  |

Valid levels: `debug`, `info`, `warn`, `error`

### Python Logging

Horizon uses Python's `logging` module for the Python layer:

```python theme={null}
import logging
logging.basicConfig(level=logging.DEBUG)
```

### Rust Logging

Set the Rust tracing level via environment variable:

```bash theme={null}
HORIZON_LOG=debug python my_strategy.py
```

### CLI Log Level

The `--log-level` flag sets both Python logging and the `HORIZON_LOG` environment variable:

```bash theme={null}
python -m horizon run strategy.py --log-level=debug
```

## Credential Resolution Order

Both `Polymarket` and `Kalshi` resolve credentials in this order:

<Steps>
  <Step title="Explicit constructor arguments">
    ```python theme={null}
    hz.Polymarket(private_key="0x...", api_key="...")
    ```
  </Step>

  <Step title="Environment variables">
    ```python theme={null}
    hz.Polymarket()  # reads POLYMARKET_PRIVATE_KEY, etc.
    ```
  </Step>
</Steps>

Explicit arguments always take priority over environment variables.

## Hot-Reload Parameters

Update strategy parameters at runtime without restarting. Three approaches: pipeline function, standalone `ParamReloader`, or engine runtime params.

### Pipeline Function

Drop `hz.hot_reload()` into your pipeline to inject parameters into `ctx.params` every cycle.

**File-based:**

```python theme={null}
import horizon as hz

hz.run(
    pipeline=[
        hz.hot_reload(source="params.json"),
        my_strategy,  # access via ctx.params["spread"]
    ],
    ...
)
```

Write new parameters (takes effect next cycle):

```python theme={null}
hz.write_params("params.json", {"spread": 0.05, "gamma": 0.3})
```

**Dict-based:**

```python theme={null}
live_params = {"spread": 0.04}
hz.run(
    pipeline=[
        hz.hot_reload(source=live_params),
        my_strategy,
    ],
    ...
)
# Update at runtime:
live_params["spread"] = 0.06  # Takes effect next cycle
```

### ParamReloader

Standalone class for watching a JSON parameter file. Useful outside of `hz.run()`.

```python theme={null}
import horizon as hz

reloader = hz.ParamReloader(
    path="params.json",     # Path to JSON file
    poll_interval=1.0,      # Seconds between file stat checks (default: 1.0)
)

# Get initial parameters (always returns a dict, never None)
params = reloader.current()
print(params)  # {"spread": 0.04, "gamma": 0.3}

# Check for updates (returns new dict if file changed, None otherwise)
updated = reloader.check()
if updated is not None:
    print(f"Params changed: {updated}")
```

| Method      | Returns                    | Description                                  |
| ----------- | -------------------------- | -------------------------------------------- |
| `current()` | `dict[str, float]`         | Most recently loaded parameters (never None) |
| `check()`   | `dict[str, float] or None` | New params if file changed, else None        |

<Note>
  `check()` returns `None` on the first call if the file hasn't changed since construction. Use `current()` to get the initial values.
</Note>

### Engine Runtime Params

Set and retrieve parameters directly on the Engine.

```python theme={null}
engine = hz.Engine()
engine.update_param("spread", 0.05)
engine.update_params_batch({"spread": 0.05, "gamma": 0.3})
params = engine.get_all_params()  # {"spread": 0.05, "gamma": 0.3}
val = engine.get_param("spread")  # 0.05
engine.remove_param("gamma")
```

These are injected into `ctx.params` every cycle when using `hz.run()`.
