Metadata-Version: 2.4
Name: quantzone
Version: 0.4.3
Summary: 宽舟科技量化数据平台 Python SDK
License-Expression: MIT
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: httpx<2.0,>=0.27
Requires-Dist: pandas>=2.0
Requires-Dist: pyarrow>=14.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: respx>=0.21; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"

# quantzone

宽舟科技量化数据平台 Python SDK。

## 安装

```bash
pip install quantzone
```

## Supported Platforms

| OS | Architecture | Python |
|----|--------------|--------|
| Linux (glibc, e.g. Ubuntu/Debian/CentOS) | x86_64, aarch64 | 3.11, 3.12, 3.13, 3.14 |
| Linux (musl, e.g. Alpine) | x86_64, aarch64 | 3.11, 3.12, 3.13, 3.14 |
| macOS | Intel (10.9+), Apple Silicon (11.0+) | 3.11, 3.12, 3.13, 3.14 |
| Windows | AMD64 (Windows 10/11) | 3.11, 3.12, 3.13, 3.14 |

Other platforms (32-bit Linux/Windows, FreeBSD, ppc64le, s390x, RISC-V, Python <= 3.10) are not supported.
If `pip install quantzone` reports `No matching distribution found`, your platform/Python version is not in the supported matrix.

## 快速开始

```python
# 方式 1:实例化客户端
from quantzone import QuantZone

# base_url 必须显式传入(SDK 不内置默认服务端地址)
client = QuantZone(
    access_key="AKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    sign_secret="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    base_url="https://your-api.example.com",
)

# 方式 2:模块级单例(推荐用 `as qz` 简写)
import quantzone as qz

qz.init(
    access_key="AKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    sign_secret="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    base_url="https://your-api.example.com",
)
df = qz.get_factors(factor="alpha1", start_date="2024-01-01", end_date="2024-12-31")
```

## API

### 因子查询

```python
# 查询因子数据 → 窄表 DataFrame,列:date / order_book_id / value / factor
# 4 个参数都可省略,服务端按缺省维度展开:
#   factor 空           → 全部因子
#   order_book_ids 空   → 全市场
df = client.get_factors(
    factor=["alpha1", "alpha2", "vwap"],
    order_book_ids=["000001.SZ", "000002.SZ"],
    start_date="2024-01-01",
    end_date="2024-12-31",
)

# order_book_ids 支持纯 6 位或带交易所后缀(.SZ / .SH / .BJ 等),两种等价
df = client.get_factors(order_book_ids=["000001", "600036"], factor=["alpha1"])

# 因子元信息(含 name / description / category)
factors = client.list_factors()
```

### 合约元信息

```python
df = client.list_stocks(exchange="SZ")             # 全量合约 → DataFrame
df = client.instruments(["000001.SZ", "600000.SH"]) # 指定合约 → DataFrame
```

### 交易日历

```python
client.get_trading_dates("2024-01-01", "2024-01-31")  # list[date]
client.get_previous_trading_date("2024-01-15", n=1)   # date
client.get_next_trading_date("2024-01-15", n=1)       # date
client.is_trading_date("2024-01-01")                  # bool
```

### 配额查询

```python
quota = client.get_quota()
# {daily_quota_bytes, daily_used_bytes, extra_quota_bytes,
#  available_bytes, remaining_days, license_type}
# extra_quota_bytes 是扩容包剩余余量(默认 0,买后永久有效)
```

### Context Manager

```python
with QuantZone(access_key="AK...", sign_secret="...", base_url="https://your-api.example.com") as client:
    df = client.get_factors(factor=["alpha1"])
```

### 大查询超时

```python
# 全市场全因子单日 ~12M 数据点,默认 60s 超时会被打断 → 显式调到 600s+
client = QuantZone(
    access_key="AK...", sign_secret="...",
    base_url="https://your-api.example.com",
    timeout=600,
)
```

### 数据本地存储

**所有下载的 Arrow 文件都会持久化保留**,SDK 不主动删除。

```python
# 默认:落到 ~/.quantzone/downloads/factors_<timestamp>_<short>.arrow
client = QuantZone(
    access_key="AK...", sign_secret="...",
    base_url="https://your-api.example.com",
)
df = client.get_factors(factor=["alpha1"])

# 全局指定下载目录
client = QuantZone(
    access_key="AK...", sign_secret="...",
    base_url="https://your-api.example.com",
    download_dir="~/data/quantzone",
)

# 单次指定文件名(落到 download_dir/<filename>)
df = client.get_factors(factor=["alpha1"], filename="alpha1_2024.arrow")
```

每次下载都会通过 logger 打印落盘位置,默认输出到 stderr:
```
[quantzone] 下载文件(temp): /Users/me/.quantzone/downloads/temp/abc123.arrow
[quantzone] 已保存到: /Users/me/.quantzone/downloads/factors_20240115_120000_abc123.arrow (1024 bytes)
```

历史文件由用户自行管理(SDK 不做任何 GC)。

## 特性

- **请求签名**:每个请求自动带 HMAC-SHA256 签名
- **流式下载**:Arrow IPC 边收边写临时文件,完毕后原子重命名为最终文件并加载为 DataFrame
- **凭证安全存储**:通过 keyring 自动读取系统密钥环(`QuantZone()` 不传 AK/SK 时生效)
- **不自动重试**:量化接口非幂等(消耗配额、跑昂贵查询),SDK 不内置重试。需要重试请用 `tenacity` / `backoff` 装饰 `client.get_factors`,自定义退避策略

## 异常处理

```python
from quantzone import QuantZone, AuthError, QuotaExceededError, NetworkError

try:
    df = client.get_factors(factor=["alpha1"])
except AuthError:
    print("API Key 无效")
except QuotaExceededError as e:
    print(f"配额不足:剩余 {e.remaining},需要 {e.required}")
except NetworkError:
    print("网络连接失败")
```

## 开发

```bash
cd quant-sdk
uv sync --dev
uv run pytest tests/ -v
uv run ruff check src/ --fix && uv run ruff format src/
```
