# Polyhush

[![PyPI version](https://badge.fury.io/py/polyhush.svg)](https://badge.fury.io/py/polyhush)
[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**Polyhush** is a Python SDK for trading on prediction markets through the Polyhush API. It provides a simple, Pythonic interface for placing orders, managing positions, and tracking your portfolio.

## Features

- **Simple Trading Interface** – Buy and sell with intuitive methods
- **Real-time Position Tracking** – Monitor positions with P&L information
- **Automatic Settlements** – Winnings credited automatically when markets resolve
- **Order Syncing** – Keep order status in sync with the exchange
- **Multiple Order Types** – Support for limit orders (GTC), fill-or-kill (FOK), and market orders (FAK)

## Installation

```bash
pip install polyhush
```

Or with Poetry:

```bash
poetry add polyhush
```

## Quick Start

```python
from polyhush import PolyhushClient

# Initialize the client
client = PolyhushClient(api_key="your-api-key")

# Check your balance
balance = client.get_balance()
print(f"Available: ${balance['available_balance']:.2f}")

# Place a limit buy order
result = client.buy(
    token_id="your-token-id",
    shares=10,
    price=0.55
)
print(f"Order placed: {result['order_id']}")
```

## Configuration

### API Key

You can provide your API key in two ways:

```python
# Option 1: Pass directly
client = PolyhushClient(api_key="your-api-key")

# Option 2: Environment variable
# Set POLYHUSH_API_KEY in your environment
client = PolyhushClient()
```

## API Reference

#### Get Balance

```python
# Basic balance info
balance = client.get_balance()
# Returns: balance, available_balance, reserved_balance

# Full portfolio summary
summary = client.get_balance(include_summary=True)
# Also returns: total_position_value, total_value, open_orders_count, positions_count
```

#### Get Positions

```python
# Basic positions
positions = client.get_positions()

# Detailed with P&L
positions = client.get_positions(detailed=True)
for pos in positions:
    print(f"{pos['market_question']}: {pos['unrealized_pnl_pct']:.1f}%")
```

#### Get CLOB Balance

```python
# Get actual on-chain balance for a token
clob = client.get_clob_balance(token_id="...")
print(f"CLOB balance: {clob['clob_balance']} shares")
```

### Orders

#### Buy Orders

```python
# Limit order: buy 100 shares at $0.45
client.buy(token_id="...", shares=100, price=0.45)

# Market order: spend $50 at market price
client.buy(token_id="...", usdc_amount=50, order_type="FAK")

# Market order: buy 100 shares at market price
client.buy(token_id="...", shares=100, order_type="FAK")
```

#### Sell Orders

```python
# Limit order: sell 100 shares at $0.55
client.sell(token_id="...", shares=100, price=0.55)

# Market order: sell 50 shares at market price
client.sell(token_id="...", shares=50, order_type="FAK")

# Market order: sell $100 worth at market price
client.sell(token_id="...", usdc_amount=100, order_type="FAK")
```

#### Cancel Orders

```python
# Cancel a specific order
client.cancel_orders(order_id="abc123")

# Cancel ALL open orders
result = client.cancel_orders()
print(f"Cancelled {result['cancelled']} orders, refunded ${result['total_refund']}")
```

#### Sync Orders

```python
# Sync a specific order
client.sync_orders(order_id="abc123")

# Sync all pending orders
result = client.sync_orders()
print(f"Synced {result['synced']} of {result['total']} orders")
```

### Market Data

#### Get Ticker

```python
ticker = client.get_ticker(token_id="...")
print(f"Last price: ${ticker['last_price']}")
print(f"Bid: ${ticker['best_bid']} / Ask: ${ticker['best_ask']}")
```

## Order Types

Polyhush supports three order types:

| Type | Name | Description |
|------|------|-------------|
| `GTC` | Good Till Cancelled | Limit order that sits on the order book until filled or cancelled |
| `FOK` | Fill Or Kill | Must be fully filled immediately or the entire order is cancelled |
| `FAK` | Fill And Kill | Market order that fills immediately; any unfilled portion is cancelled |

```python
# Using order type constants
from polyhush import PolyhushClient

client = PolyhushClient(api_key="...")

# These are equivalent
client.buy(token_id="...", shares=10, price=0.50, order_type="GTC")
client.buy(token_id="...", shares=10, price=0.50, order_type=client.GTC)
```

## Error Handling

The SDK raises `PolyhushAPIError` for API errors:

```python
from polyhush import PolyhushClient, PolyhushAPIError

client = PolyhushClient(api_key="your-api-key")

try:
    result = client.buy(token_id="...", shares=100, price=0.50)
except PolyhushAPIError as e:
    print(f"Error: {e.message}")
    print(f"Status code: {e.status_code}")
    print(f"Response: {e.response}")
```

## Environment Variables

| Variable | Description |
|----------|-------------|
| `POLYHUSH_API_KEY` | Your Polyhush API key |

## Examples

### Basic Trading Bot

```python
from polyhush import PolyhushClient, PolyhushAPIError
import time

client = PolyhushClient()

def simple_trading_loop(token_id: str):
    while True:
        try:
            # Get current price
            ticker = client.get_ticker(token_id)
            mid = ticker['midpoint']
            
            # Place limit orders around midpoint
            client.buy(token_id, shares=10, price=round(mid - 0.02, 2))
            client.sell(token_id, shares=10, price=round(mid + 0.02, 2))
            
            # Wait and sync
            time.sleep(60)
            client.sync_orders()
            
        except PolyhushAPIError as e:
            print(f"Error: {e.message}")
            time.sleep(10)
```

### Position Monitor

```python
from polyhush import PolyhushClient

client = PolyhushClient()

def show_portfolio():
    # Get balance with summary
    summary = client.get_balance(include_summary=True)
    print(f"Total Value: ${summary['total_value']:.2f}")
    print(f"   Cash: ${summary['available_balance']:.2f}")
    print(f"   Positions: ${summary['total_position_value']:.2f}")
    print()
    
    # Show detailed positions
    positions = client.get_positions(detailed=True)
    for pos in positions:
        pnl = pos['unrealized_pnl']
        pnl_pct = pos['unrealized_pnl_pct']
        print(f"{pos['market_question'][:50]}...")
        print(f"   {pos['size']} shares @ ${pos['average_price']:.2f}")
        print(f"   P&L: ${pnl:.2f} ({pnl_pct:+.1f}%)")
        print()

show_portfolio()
```

## Documentation

For complete documentation, visit [docs.polyhush.com](https://docs.polyhush.com)

- [Quickstart Guide](https://docs.polyhush.com/quickstart)
- [SDK Reference](https://docs.polyhush.com/sdk-reference/overview)
- [API Reference](https://docs.polyhush.com/api-reference/overview)
- [Trading Examples](https://docs.polyhush.com/examples/basic-trading)

## Requirements

- Python 3.8+
- `requests >= 2.28.0`

## License

MIT License - see [LICENSE](LICENSE) for details.

## Support

- [Documentation](https://docs.polyhush.com)
- [support@polyhush.com](mailto:support@hush.so)

