qe-connector


Nameqe-connector JSON
Version 1.0.1 PyPI version JSON
download
home_pagehttps://github.com/Quantum-Execute/qe-connector-python
SummaryThis is a lightweight library that works as a connector to Quantum Execute public API.
upload_time2025-08-17 13:01:33
maintainerNone
docs_urlNone
authorQuantum-Execute
requires_python>=3.8
licenseMIT
keywords quantum-execute public api
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Quantum Execute Python SDK

[![Python Version](https://img.shields.io/pypi/pyversions/qe-connector)](https://pypi.org/project/qe-connector/)
[![PyPI Version](https://img.shields.io/pypi/v/qe-connector)](https://pypi.org/project/qe-connector/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

这是 Quantum Execute 公共 API 的官方 Python SDK,为开发者提供了一个轻量级、易于使用的接口来访问 Quantum Execute 的交易服务。

## 功能特性

- ✅ 完整的 Quantum Execute API 支持
- ✅ 交易所 API 密钥管理
- ✅ 主订单创建与管理(TWAP、VWAP 等算法)
- ✅ 订单查询和成交明细
- ✅ 多种认证方式支持(HMAC、RSA、Ed25519)
- ✅ 支持生产环境和测试环境
- ✅ 异步和同步调用支持
- ✅ 完善的错误处理和日志记录

## 安装

```bash
pip install qe-connector
```

或者从源码安装:

```bash
git clone https://github.com/Quantum-Execute/qe-connector-python.git
cd qe-connector-python
pip install -e .
```

## 快速开始

### 初始化客户端

```python
from qe.user import User as Client
import logging

# 配置日志(可选)
logging.basicConfig(level=logging.INFO)

# 创建生产环境客户端
client = Client(
    api_key="your-api-key",
    api_secret="your-api-secret"
)

# 创建测试环境客户端
client = Client(
    api_key="your-api-key",
    api_secret="your-api-secret",
    base_url="https://testapi.quantumexecute.com"
)
```

## API 参考

### 交易所 API 管理

#### 查询交易所 API 列表

查询当前用户绑定的所有交易所 API 账户。

**请求参数:**
- `page` (int) - 页码,可选
- `pageSize` (int) - 每页数量,可选
- `exchange` (str) - 交易所名称筛选,可选

**响应字段:**
- `items` - API 列表,每个 API 包含以下字段:
  - `id` - API 记录的唯一标识
  - `createdAt` - API 添加时间
  - `accountName` - 账户名称(如:账户1、账户2)
  - `exchange` - 交易所名称(如:Binance、OKX、Bybit)
  - `apiKey` - 交易所 API Key(部分隐藏)
  - `verificationMethod` - API 验证方式(如:OAuth、API)
  - `balance` - 账户余额(美元)
  - `status` - API 状态:正常、异常(不可用)
  - `isValid` - API 是否有效
  - `isTradingEnabled` - 是否开启交易权限
  - `isDefault` - 是否为该交易所的默认账户
  - `isPm` - 是否为 Pm 账户
- `total` - API 总数
- `page` - 当前页码
- `pageSize` - 每页显示数量

**示例代码:**

```python
# 获取所有交易所 API 密钥
apis = client.list_exchange_apis()
print(f"共有 {apis['total']} 个 API 密钥")

# 打印每个 API 的详细信息
for api in apis['items']:
    print(f"""
API 信息:
    账户: {api['accountName']}
    交易所: {api['exchange']}
    状态: {api['status']}
    余额: ${api['balance']:.2f}
    交易权限: {'开启' if api['isTradingEnabled'] else '关闭'}
    是否默认: {'是' if api['isDefault'] else '否'}
    是否PM账户: {'是' if api['isPm'] else '否'}
    添加时间: {api['createdAt']}
    """)

# 带分页和过滤
apis = client.list_exchange_apis(
    page=1,
    pageSize=10,
    exchange="binance"
)
```

#### 添加交易所 API

添加新的交易所 API 账户。

**请求参数:**
- `accountName` (str) - 账户名称,必填
- `exchange` (str) - 交易所名称(如:Binance、OKX、Bybit),必填
- `apiKey` (str) - 交易所 API Key,必填
- `apiSecret` (str) - 交易所 API Secret,必填
- `passphrase` (str) - API 密码短语(部分交易所需要),可选
- `verificationMethod` (str) - API 验证方式(如:OAuth、API),可选
- `enableTrading` (bool) - 是否开启交易权限,可选

**响应字段:**
- `id` - 新创建的 API ID
- `success` - 添加是否成功
- `message` - 操作结果消息

**示例代码:**

```python
# 添加币安 API
result = client.add_exchange_api(
    accountName="我的币安账户",
    exchange="binance",
    apiKey="your-exchange-api-key",
    apiSecret="your-exchange-api-secret",
    enableTrading=True  # 启用交易权限
)

if result['success']:
    print(f"API Key 添加成功,ID: {result['id']}")
else:
    print(f"API Key 添加失败:{result['message']}")

# 添加 OKX API(需要 passphrase)
result = client.add_exchange_api(
    accountName="我的 OKX 账户",
    exchange="okx",
    apiKey="your-okx-api-key",
    apiSecret="your-okx-api-secret",
    passphrase="your-okx-passphrase",
    verificationMethod="API",
    enableTrading=True
)
```

### 交易订单管理

#### 创建主订单

创建新的主订单并提交到算法侧执行。

**请求参数:**
- `algorithm` (str) - 交易算法(如:VWAP、TWAP),必填
- `algorithmType` (str) - 算法分类,暂时固定传 "TIME_WEIGHTED",必填
- `exchange` (str) - 交易所名称(如:Binance、OKX),必填
- `symbol` (str) - 交易对符号(如:BTCUSDT),必填
- `marketType` (str) - 市场类型(SPOT:现货, FUTURES:合约),必填
- `side` (str) - 买卖方向(BUY:买入, SELL:卖出),必填
- `apiKeyId` (str) - 指定使用的 API 密钥 ID,必填
- `totalQuantity` (float) - 要交易的总数量(按币值时使用),与 orderNotional 二选一
- `orderNotional` (float) - 按价值下单时的金额(USDT),与 totalQuantity 二选一
- `strategyType` (str) - 策略类型(如:AGGRESSIVE、PASSIVE),可选
- `startTime` (str) - 开始执行时间(ISO 8601格式),可选
- `endTime` (str) - 结束时间(ISO 8601格式),TWAP-2 时必填
- `executionDuration` (int) - 执行时长(秒),TWAP-1 时必填
- `worstPrice` (float) - 最差成交价,必须完成为 true 时可选
- `limitPriceString` (str) - 限价字符串,超出范围停止交易,填 "-1" 不限制
- `upTolerance` (str) - 允许超出 schedule 的容忍度(如 "0.1" 表示 10%)
- `lowTolerance` (str) - 允许落后 schedule 的容忍度
- `strictUpBound` (bool) - 是否严格小于 upTolerance,不建议开启
- `mustComplete` (bool) - 是否必须在 duration 内执行完,默认 true
- `makerRateLimit` (float) - 要求 maker 占比超过该值(0-1)
- `povLimit` (float) - 占市场成交量比例限制(0-1)
- `marginType` (str) - 合约交易保证金类型(CROSS:全仓, ISOLATED:逐仓)
- `reduceOnly` (bool) - 合约交易时是否仅减仓,默认 false
- `notes` (str) - 订单备注,可选
- `clientId` (str) - 客户端唯一标识符,可选

**响应字段:**
- `masterOrderId` - 创建成功的主订单 ID
- `success` - 创建是否成功
- `message` - 创建结果消息

**示例代码:**

```python
# TWAP 订单示例 - 在 30 分钟内分批买入价值 $10,000 的 BTC
response = client.create_master_order(
    algorithm="TWAP",
    algorithmType="TIME_WEIGHTED",
    exchange="binance",
    symbol="BTCUSDT",
    marketType="SPOT",
    side="BUY",
    apiKeyId="your-api-key-id",  # 从 list_exchange_apis 获取
    orderNotional=10000,          # $10,000 名义价值
    startTime="2024-01-01T10:00:00Z",
    endTime="2024-01-01T10:30:00Z",
    executionDuration="1800",     # 30 分钟 = 1800 秒
    mustComplete=True,            # 必须完成全部订单
    worstPrice=60000,            # 最差价格 $60,000
    upTolerance="0.1",           # 允许超出 10%
    lowTolerance="0.1",          # 允许落后 10%
    strictUpBound=False,         # 不严格限制上界
    clientId="my-order-001",     # 自定义订单 ID
    notes="测试 TWAP 订单"       # 订单备注
)

if response.get('success'):
    print(f"主订单创建成功,ID: {response['masterOrderId']}")
else:
    print(f"创建失败:{response.get('message')}")


# 使用限价字符串的示例
response = client.create_master_order(
    algorithm="TWAP",
    algorithmType="TIME_WEIGHTED",
    exchange="binance",
    symbol="BTCUSDT",
    marketType="SPOT",
    side="BUY",
    apiKeyId="your-api-key-id",
    orderNotional=5000,
    executionDuration="1800",
    limitPriceString="50000",    # 限价 $50,000(字符串格式)
    upTolerance="0.05",          # 允许超出 5%
    lowTolerance="0.1",          # 允许落后 10%
    strictUpBound=False,         # 关闭严格上界限制
    mustComplete=True
)
```

#### 查询主订单列表

获取用户的主订单列表。

**请求参数:**
- `page` (int) - 页码,可选
- `pageSize` (int) - 每页数量,可选
- `status` (str) - 订单状态筛选,可选
- `exchange` (str) - 交易所名称筛选,可选
- `symbol` (str) - 交易对筛选,可选
- `startTime` (str) - 开始时间筛选,可选
- `endTime` (str) - 结束时间筛选,可选

**响应字段:**
- `items` - 主订单列表,每个订单包含:
  - `masterOrderId` - 主订单 ID
  - `algorithm` - 算法
  - `algorithmType` - 算法类型
  - `exchange` - 交易所
  - `symbol` - 交易对
  - `marketType` - 市场类型
  - `side` - 买卖方向
  - `totalQuantity` - 总数量
  - `filledQuantity` - 已成交数量
  - `averagePrice` - 平均成交价
  - `status` - 状态
  - `executionDuration` - 执行时长(秒)
  - `priceLimit` - 价格限制
  - `startTime` - 开始时间
  - `endTime` - 结束时间
  - `createdAt` - 创建时间
  - `updatedAt` - 更新时间
  - `notes` - 备注
  - `marginType` - 保证金类型(U:U本位, C:币本位)
  - `reduceOnly` - 是否仅减仓
  - `strategyType` - 策略类型
  - `orderNotional` - 订单金额(USDT)
  - `mustComplete` - 是否必须完成
  - `makerRateLimit` - 最低 Maker 率
  - `povLimit` - 最大市场成交量占比
  - `clientId` - 客户端 ID
  - `date` - 发单日期(格式:YYYYMMDD)
  - `ticktimeInt` - 发单时间(格式:093000000 表示 9:30:00.000)
  - `limitPriceString` - 限价(字符串)
  - `upTolerance` - 上容忍度
  - `lowTolerance` - 下容忍度
  - `strictUpBound` - 严格上界
  - `ticktimeMs` - 发单时间戳(epoch 毫秒)
  - `category` - 交易品种(spot 或 perp)
  - `filledAmount` - 成交金额
  - `totalValue` - 成交总值
  - `base` - 基础币种
  - `quote` - 计价币种
  - `completionProgress` - 完成进度(0-1)
  - `reason` - 原因(如取消原因)
- `total` - 总数
- `page` - 当前页码
- `pageSize` - 每页数量

**示例代码:**

```python
# 查询所有主订单
orders = client.get_master_orders()

# 带过滤条件查询
orders = client.get_master_orders(
    page=1,
    pageSize=20,
    status="NEW",              # 活跃订单
    symbol="BTCUSDT",
    startTime="2024-01-01T00:00:00Z",
    endTime="2024-01-31T23:59:59Z"
)

# 打印订单详细信息
for order in orders['items']:
    print(f"""
订单详情:
    ID: {order['masterOrderId']}
    算法: {order['algorithm']} ({order.get('strategyType', 'N/A')})
    交易对: {order['symbol']} ({order['marketType']})
    方向: {order['side']}
    状态: {order['status']}
    完成度: {order['completionProgress'] * 100:.2f}%
    平均价格: ${order.get('averagePrice', 0):.2f}
    已成交: {order['filledQuantity']:.4f} / {order['totalQuantity']:.4f}
    成交金额: ${order.get('filledAmount', 0):.2f}
    创建时间: {order['createdAt']}
    发单日期: {order.get('date', 'N/A')}
    限价: {order.get('limitPriceString', '-1')}
    上容忍度: {order.get('upTolerance', 'N/A')}
    下容忍度: {order.get('lowTolerance', 'N/A')}
    严格上界: {order.get('strictUpBound', False)}
    客户端ID: {order.get('clientId', 'N/A')}
    备注: {order.get('notes', '')}
    """)

# 统计信息
total_orders = len(orders['items'])
active_orders = sum(1 for o in orders['items'] if o['status'] == 'ACTIVE')
completed_orders = sum(1 for o in orders['items'] if o['status'] == 'COMPLETED')
print(f"\n统计:总订单 {total_orders},活跃 {active_orders},已完成 {completed_orders}")
```

#### 查询成交记录

获取用户的成交记录。

**请求参数:**
- `page` (int) - 页码,可选
- `pageSize` (int) - 每页数量,可选
- `masterOrderId` (str) - 主订单 ID 筛选,可选
- `subOrderId` (str) - 子订单 ID 筛选,可选
- `symbol` (str) - 交易对筛选,可选
- `startTime` (str) - 开始时间筛选,可选
- `endTime` (str) - 结束时间筛选,可选

**响应字段:**
- `items` - 成交记录列表,每条记录包含:
  - `id` - 记录 ID
  - `orderCreatedTime` - 订单创建时间
  - `masterOrderId` - 主订单 ID
  - `exchange` - 交易所
  - `category` - 市场类型
  - `symbol` - 交易对
  - `side` - 方向
  - `filledValue` - 成交价值
  - `filledQuantity` - 成交数量
  - `avgPrice` - 平均价格
  - `price` - 成交价格
  - `fee` - 手续费
  - `tradingAccount` - 交易账户
  - `status` - 状态
  - `rejectReason` - 拒绝原因
  - `base` - 基础币种
  - `quote` - 计价币种
  - `type` - 订单类型
- `total` - 总数
- `page` - 当前页码
- `pageSize` - 每页数量

**示例代码:**

```python
# 查询特定主订单的成交明细
fills = client.get_order_fills(
    masterOrderId="your-master-order-id",
    page=1,
    pageSize=50
)

# 查询所有成交
fills = client.get_order_fills(
    symbol="BTCUSDT",
    startTime="2024-01-01T00:00:00Z",
    endTime="2024-01-01T23:59:59Z"
)

# 分析成交数据
total_value = 0
total_fee = 0
fill_types = {}

for fill in fills['items']:
    print(f"""
成交记录:
    时间: {fill['orderCreatedTime']}
    交易对: {fill['symbol']} ({fill['category']})
    方向: {fill['side']}
    成交价格: ${fill['price']:.2f}
    成交数量: {fill['filledQuantity']:.6f}
    成交金额: ${fill['filledValue']:.2f}
    手续费: ${fill['fee']:.4f}
    账户: {fill['tradingAccount']}
    类型: {fill.get('type', 'N/A')}
    状态: {fill['status']}
    """)
    
    total_value += fill['filledValue']
    total_fee += fill['fee']
    
    # 统计订单类型
    order_type = fill.get('type', 'Unknown')
    fill_types[order_type] = fill_types.get(order_type, 0) + 1

print(f"\n成交统计:")
print(f"总成交额: ${total_value:.2f}")
print(f"总手续费: ${total_fee:.2f}")
print(f"手续费率: {(total_fee/total_value*100):.3f}%")
print(f"订单类型分布: {fill_types}")
```

#### 取消主订单

取消指定的主订单。

**请求参数:**
- `masterOrderId` (str) - 要取消的主订单 ID,必填
- `reason` (str) - 取消原因,可选

**响应字段:**
- `success` - 取消是否成功
- `message` - 取消结果消息

**示例代码:**

```python
# 取消订单
response = client.cancel_master_order(
    masterOrderId="your-master-order-id",
    reason="用户手动取消"  # 可选的取消原因
)

if response.get('success'):
    print("订单取消成功")
else:
    print(f"订单取消失败: {response.get('message')}")

# 批量取消示例
def cancel_all_active_orders(client):
    """取消所有活跃订单"""
    orders = client.get_master_orders(status="ACTIVE")
    cancelled_count = 0
    
    for order in orders['items']:
        try:
            response = client.cancel_master_order(
                masterOrderId=order['masterOrderId'],
                reason="批量取消活跃订单"
            )
            if response.get('success'):
                cancelled_count += 1
                print(f"已取消订单: {order['masterOrderId']}")
            else:
                print(f"取消失败: {order['masterOrderId']} - {response.get('message')}")
        except Exception as e:
            print(f"取消异常: {order['masterOrderId']} - {str(e)}")
    
    print(f"\n总计取消 {cancelled_count} 个订单")
    return cancelled_count
```

## 错误处理

SDK 提供了详细的错误类型,方便进行精确的错误处理:

```python
from qe.error import ClientError, APIError

try:
    response = client.create_master_order(
        # ... 订单参数
    )
except APIError as error:
    # API 返回的业务错误
    print(f"API 错误 - 代码: {error.code}, 原因: {error.reason}, 消息: {error.message}")
    print(f"追踪 ID: {error.trace_id}")  # 用于技术支持
    
    # 根据错误代码处理
    if error.code == 400:
        print("请求参数错误,请检查输入")
    elif error.code == 401:
        print("认证失败,请检查 API 密钥")
    elif error.code == 403:
        print("权限不足")
    elif error.code == 429:
        print("请求过于频繁,请稍后重试")
        
except ClientError as error:
    # 客户端错误(如参数错误、网络错误等)
    print(f"客户端错误 - 状态码: {error.status_code}, 错误消息: {error.error_message}")
    
except Exception as error:
    # 其他未预期的错误
    print(f"未知错误: {error}")
```

## 高级配置

### 配置超时和代理

```python
client = Client(
    api_key="your-api-key",
    api_secret="your-api-secret",
    timeout=30,  # 30 秒超时
    proxies={
        'https': 'http://proxy.example.com:8080'
    }
)
```

### 使用 RSA 或 Ed25519 签名

```python
# 使用 RSA 私钥
with open('private_key.pem', 'r') as f:
    private_key = f.read()

client = Client(
    api_key="your-api-key",
    private_key=private_key,
    private_key_pass="your-password"  # 如果私钥有密码
)

# 使用 Ed25519 私钥
with open('ed25519_key.pem', 'r') as f:
    ed25519_key = f.read()

client = Client(
    api_key="your-api-key",
    private_key=ed25519_key
)
```

### 显示请求限制使用情况

```python
client = Client(
    api_key="your-api-key",
    api_secret="your-api-secret",
    show_limit_usage=True,
    show_header=True
)

# API 响应将包含限制信息
response = client.get_master_orders()
if isinstance(response, dict) and 'limit_usage' in response:
    print(f"限制使用情况: {response['limit_usage']}")
    print(f"实际数据: {response['data']}")
```

### 配置日志

```python
import logging
from qe.lib.utils import config_logging

# 配置详细日志
config_logging(logging, logging.DEBUG)

# 只记录警告和错误
config_logging(logging, logging.WARNING)
```

## 完整示例

### 完整的交易流程示例

```python
import logging
from qe.user import User as Client
from qe.error import ClientError, APIError
from qe.lib.utils import config_logging
import time
from datetime import datetime, timedelta

# 配置日志
config_logging(logging, logging.INFO)
logger = logging.getLogger(__name__)

# 初始化客户端
client = Client("your-api-key", "your-api-secret")

try:
    # 1. 获取可用的 API 密钥
    apis = client.list_exchange_apis(exchange="binance")
    if not apis['items']:
        logger.error("没有找到可用的币安 API 密钥")
        exit(1)
    
    # 选择余额最高的账户
    api_info = max(apis['items'], key=lambda x: x.get('balance', 0))
    api_key_id = api_info['id']
    logger.info(f"使用 API 密钥: {api_key_id}, 账户: {api_info['accountName']}, 余额: ${api_info['balance']:.2f}")
    
    # 2. 创建 TWAP 订单
    start_time = datetime.utcnow().isoformat() + 'Z'
    end_time = (datetime.utcnow() + timedelta(minutes=10)).isoformat() + 'Z'
    
    order_response = client.create_master_order(
        algorithm="TWAP",
        algorithmType="TIME_WEIGHTED",
        exchange="binance",
        symbol="BTCUSDT",
        marketType="SPOT",
        side="BUY",
        apiKeyId=api_key_id,
        orderNotional=1000,           # $1000
        startTime=start_time,
        endTime=end_time,
        executionDuration="30",       # 每 30 秒执行一次
        mustComplete=True,
        worstPrice=70000,            # 最差价格 $70,000
        upTolerance="0.05",          # 允许超出 5%
        lowTolerance="0.05",         # 允许落后 5%
        strictUpBound=False,
        clientId=f"test_order_{int(time.time())}",
        notes="Python SDK 测试订单"
    )
    
    if not order_response.get('success'):
        logger.error(f"创建订单失败: {order_response.get('message')}")
        exit(1)
    
    master_order_id = order_response['masterOrderId']
    logger.info(f"订单创建成功,ID: {master_order_id}")
    
    # 3. 监控订单状态
    previous_progress = 0
    while True:
        orders = client.get_master_orders(
            page=1,
            pageSize=1,
            status="ACTIVE"
        )
        
        if not orders['items']:
            logger.info("订单已完成或取消")
            break
        
        order = orders['items'][0]
        current_progress = order['completionProgress'] * 100
        
        # 只在进度变化时打印
        if current_progress != previous_progress:
            logger.info(f"订单进度: {current_progress:.2f}%, "
                       f"已成交: {order['filledQuantity']:.6f}/{order['totalQuantity']:.6f}, "
                       f"平均价格: ${order.get('averagePrice', 0):.2f}")
            previous_progress = current_progress
        
        # 检查是否需要取消(演示用)
        if current_progress > 50:  # 完成超过 50%
            logger.info("演示:取消订单")
            cancel_response = client.cancel_master_order(
                masterOrderId=master_order_id,
                reason="演示取消"
            )
            if cancel_response.get('success'):
                logger.info("订单已取消")
            break
        
        time.sleep(10)  # 每 10 秒检查一次
    
    # 4. 获取最终成交明细
    fills = client.get_order_fills(masterOrderId=master_order_id)
    logger.info(f"总成交笔数: {fills['total']}")
    
    total_value = 0
    total_fee = 0
    for fill in fills['items']:
        logger.info(f"成交: {fill['side']} {fill['filledQuantity']:.6f} {fill['symbol']} "
                   f"@ ${fill['price']:.2f}, 手续费: ${fill['fee']:.4f}")
        total_value += fill['filledValue']
        total_fee += fill['fee']
    
    if total_value > 0:
        logger.info(f"\n成交总结:")
        logger.info(f"总成交额: ${total_value:.2f}")
        logger.info(f"总手续费: ${total_fee:.2f}")
        logger.info(f"手续费率: {(total_fee/total_value*100):.3f}%")

except APIError as error:
    logger.error(f"API 错误: {error}")
except ClientError as error:
    logger.error(f"客户端错误: {error}")
except Exception as error:
    logger.error(f"未知错误: {error}")
```

### 策略执行示例

```python
def execute_vwap_strategy(client, symbol, amount_usd, duration_hours=8):
    """执行 VWAP 策略"""
    logger = logging.getLogger(__name__)
    
    try:
        # 获取默认 API
        apis = client.list_exchange_apis(exchange="binance")
        default_api = next((api for api in apis['items'] if api.get('isDefault')), None)
        
        if not default_api:
            raise ValueError("没有找到默认的币安 API")
        
        # 创建 VWAP 订单
        start_time = datetime.utcnow().isoformat() + 'Z'
        end_time = (datetime.utcnow() + timedelta(hours=duration_hours)).isoformat() + 'Z'
        
        response = client.create_master_order(
            algorithm="VWAP",
            algorithmType="VOLUME_WEIGHTED",
            exchange="binance",
            symbol=symbol,
            marketType="SPOT",
            side="BUY",
            apiKeyId=default_api['id'],
            orderNotional=amount_usd,
            startTime=start_time,
            endTime=end_time,
            strategyType="PASSIVE",      # 被动策略,减少市场影响
            makerRateLimit=0.5,          # 50% Maker 订单
            povLimit=0.05,               # 最多占市场成交量 5%
            mustComplete=False,          # 不强制完成,避免滑点
            upTolerance="0.02",          # 2% 容忍度
            lowTolerance="0.05",         # 5% 容忍度
            notes=f"VWAP 策略 - {symbol}"
        )
        
        if response.get('success'):
            logger.info(f"VWAP 订单创建成功: {response['masterOrderId']}")
            return response['masterOrderId']
        else:
            raise ValueError(f"订单创建失败: {response.get('message')}")
            
    except Exception as e:
        logger.error(f"执行 VWAP 策略失败: {str(e)}")
        raise

# 使用示例
master_order_id = execute_vwap_strategy(
    client,
    symbol="ETHUSDT",
    amount_usd=5000,
    duration_hours=6
)
```

## API 文档

完整的 API 文档请参考 [Quantum Execute API 文档](https://docs.quantumexecute.com)

## 支持的算法类型

- **TWAP (Time Weighted Average Price)**: 时间加权平均价格算法,在指定时间段内平均分配订单
- **VWAP (Volume Weighted Average Price)**: 成交量加权平均价格算法,根据市场成交量分布执行订单
- **POV (Percentage of Volume)**: 成交量百分比算法,保持占市场成交量的固定比例
- **IMPLEMENTATION_SHORTFALL**: 执行缺口算法,最小化执行成本

## 最佳实践

### 1. API 密钥管理

```python
def check_api_health(client):
    """检查 API 密钥健康状态"""
    apis = client.list_exchange_apis()
    
    for api in apis['items']:
        if not api['isValid']:
            print(f"⚠️  警告: API '{api['accountName']}' 状态异常")
        
        if api['balance'] < 100:
            print(f"⚠️  警告: 账户 '{api['accountName']}' 余额不足 (${api['balance']:.2f})")
        
        if not api['isTradingEnabled']:
            print(f"ℹ️  提示: API '{api['accountName']}' 未开启交易权限")
```

### 2. 订单参数验证

```python
def validate_order_params(params):
    """验证订单参数"""
    errors = []
    
    # 必填参数检查
    required = ['algorithm', 'exchange', 'symbol', 'marketType', 'side', 'apiKeyId']
    for field in required:
        if not params.get(field):
            errors.append(f"缺少必填参数: {field}")
    
    # 数量验证
    if not params.get('totalQuantity') and not params.get('orderNotional'):
        errors.append("必须指定 totalQuantity 或 orderNotional")
    
    # 时间验证
    if params.get('startTime') and params.get('endTime'):
        start = datetime.fromisoformat(params['startTime'].rstrip('Z'))
        end = datetime.fromisoformat(params['endTime'].rstrip('Z'))
        if start >= end:
            errors.append("开始时间必须早于结束时间")
    
    # 容忍度验证
    for field in ['upTolerance', 'lowTolerance']:
        if field in params:
            try:
                val = float(params[field])
                if val < 0 or val > 1:
                    errors.append(f"{field} 必须在 0-1 之间")
            except ValueError:
                errors.append(f"{field} 必须是有效的数字")
    
    return errors
```

### 3. 重试机制

```python
import time
from functools import wraps

def retry_on_error(max_retries=3, delay=1):
    """装饰器:自动重试失败的请求"""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            last_error = None
            for attempt in range(max_retries):
                try:
                    return func(*args, **kwargs)
                except APIError as e:
                    last_error = e
                    # 不重试客户端错误
                    if 400 <= e.code < 500:
                        raise
                    # 服务器错误,等待后重试
                    if attempt < max_retries - 1:
                        wait_time = delay * (2 ** attempt)  # 指数退避
                        logger.warning(f"请求失败,{wait_time}秒后重试...")
                        time.sleep(wait_time)
                except Exception as e:
                    last_error = e
                    if attempt < max_retries - 1:
                        time.sleep(delay)
            
            raise last_error
        return wrapper
    return decorator

# 使用示例
@retry_on_error(max_retries=3, delay=2)
def create_order_with_retry(client, **params):
    return client.create_master_order(**params)
```

## 常见问题

### 1. 如何获取 API 密钥?

请登录 Quantum Execute 平台,在用户设置中创建 API 密钥。确保保管好您的密钥,不要将其提交到版本控制系统中。

### 2. 时间戳错误怎么处理?

如果遇到时间戳相关的错误,可能是您的系统时间与服务器时间不同步。请确保系统时间准确。

### 3. 如何处理大量数据的分页?

```python
def get_all_data(fetch_func, **params):
    """通用的分页数据获取函数"""
    all_items = []
    page = 1
    page_size = 100
    
    while True:
        result = fetch_func(page=page, pageSize=page_size, **params)
        all_items.extend(result['items'])
        
        if len(result['items']) < page_size:
            break
        page += 1
    
    return all_items

# 使用示例
all_orders = get_all_data(client.get_master_orders, status="COMPLETED")
all_fills = get_all_data(client.get_order_fills, symbol="BTCUSDT")
```

### 4. 如何设置订单的时间?

时间格式使用 ISO 8601 标准,例如:
- UTC 时间:`2024-01-01T10:00:00Z`
- 带时区:`2024-01-01T18:00:00+08:00`

```python
from datetime import datetime, timezone

# 获取当前 UTC 时间
now_utc = datetime.now(timezone.utc).isoformat()

# 转换本地时间到 UTC
local_time = datetime.now()
utc_time = local_time.astimezone(timezone.utc).isoformat()
```

### 5. 容忍度参数说明

- `upTolerance`:允许超出计划进度的容忍度,如 "0.1" 表示允许超出 10%
- `lowTolerance`:允许落后计划进度的容忍度
- `strictUpBound`:是否严格限制在 upTolerance 以内,开启后可能导致小订单被过度拆分

## 示例代码

更多示例代码请参考 [examples](./examples) 目录:

- [添加交易所 API](examples/user/add_exchange_api.py)
- [创建主订单](examples/user/create_master_order.py)
- [取消主订单](examples/user/cancel_master_order.py)
- [查询订单列表](examples/user/get_master_orders.py)
- [查询成交明细](examples/user/get_order_fills.py)

## 开发和测试

### 安装开发依赖

```bash
pip install -r requirements/requirements-dev.txt
```

### 运行测试

```bash
python -m pytest tests/
```

### 代码格式化

```bash
black qe/
flake8 qe/
```

## 贡献指南

欢迎提交 Issue 和 Pull Request!请确保:

1. 代码符合 PEP 8 规范
2. 添加适当的测试
3. 更新相关文档

## 更新日志

### v1.0.0 (2024-01-01)
- 初始版本发布
- 支持完整的 Quantum Execute API
- 支持多种认证方式
- 完善的错误处理

## 许可证

本项目采用 MIT 许可证 - 详见 [LICENSE](LICENSE) 文件。

## 联系我们

- 官网:[https://test.quantumexecute.com](https://test.quantumexecute.com)
- 邮箱:support@quantumexecute.com
- GitHub:[https://github.com/Quantum-Execute/qe-connector-python](https://github.com/Quantum-Execute/qe-connector-python)

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Quantum-Execute/qe-connector-python",
    "name": "qe-connector",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "Quantum-Execute, Public API",
    "author": "Quantum-Execute",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/88/da/debe587b57bd0815994dc86e4f5c0a05159bb2b8658b353d33b0fb030caf/qe-connector-1.0.1.tar.gz",
    "platform": null,
    "description": "# Quantum Execute Python SDK\r\n\r\n[![Python Version](https://img.shields.io/pypi/pyversions/qe-connector)](https://pypi.org/project/qe-connector/)\r\n[![PyPI Version](https://img.shields.io/pypi/v/qe-connector)](https://pypi.org/project/qe-connector/)\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\r\n\r\n\u8fd9\u662f Quantum Execute \u516c\u5171 API \u7684\u5b98\u65b9 Python SDK\uff0c\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e86\u4e00\u4e2a\u8f7b\u91cf\u7ea7\u3001\u6613\u4e8e\u4f7f\u7528\u7684\u63a5\u53e3\u6765\u8bbf\u95ee Quantum Execute \u7684\u4ea4\u6613\u670d\u52a1\u3002\r\n\r\n## \u529f\u80fd\u7279\u6027\r\n\r\n- \u2705 \u5b8c\u6574\u7684 Quantum Execute API \u652f\u6301\r\n- \u2705 \u4ea4\u6613\u6240 API \u5bc6\u94a5\u7ba1\u7406\r\n- \u2705 \u4e3b\u8ba2\u5355\u521b\u5efa\u4e0e\u7ba1\u7406\uff08TWAP\u3001VWAP \u7b49\u7b97\u6cd5\uff09\r\n- \u2705 \u8ba2\u5355\u67e5\u8be2\u548c\u6210\u4ea4\u660e\u7ec6\r\n- \u2705 \u591a\u79cd\u8ba4\u8bc1\u65b9\u5f0f\u652f\u6301\uff08HMAC\u3001RSA\u3001Ed25519\uff09\r\n- \u2705 \u652f\u6301\u751f\u4ea7\u73af\u5883\u548c\u6d4b\u8bd5\u73af\u5883\r\n- \u2705 \u5f02\u6b65\u548c\u540c\u6b65\u8c03\u7528\u652f\u6301\r\n- \u2705 \u5b8c\u5584\u7684\u9519\u8bef\u5904\u7406\u548c\u65e5\u5fd7\u8bb0\u5f55\r\n\r\n## \u5b89\u88c5\r\n\r\n```bash\r\npip install qe-connector\r\n```\r\n\r\n\u6216\u8005\u4ece\u6e90\u7801\u5b89\u88c5\uff1a\r\n\r\n```bash\r\ngit clone https://github.com/Quantum-Execute/qe-connector-python.git\r\ncd qe-connector-python\r\npip install -e .\r\n```\r\n\r\n## \u5feb\u901f\u5f00\u59cb\r\n\r\n### \u521d\u59cb\u5316\u5ba2\u6237\u7aef\r\n\r\n```python\r\nfrom qe.user import User as Client\r\nimport logging\r\n\r\n# \u914d\u7f6e\u65e5\u5fd7\uff08\u53ef\u9009\uff09\r\nlogging.basicConfig(level=logging.INFO)\r\n\r\n# \u521b\u5efa\u751f\u4ea7\u73af\u5883\u5ba2\u6237\u7aef\r\nclient = Client(\r\n    api_key=\"your-api-key\",\r\n    api_secret=\"your-api-secret\"\r\n)\r\n\r\n# \u521b\u5efa\u6d4b\u8bd5\u73af\u5883\u5ba2\u6237\u7aef\r\nclient = Client(\r\n    api_key=\"your-api-key\",\r\n    api_secret=\"your-api-secret\",\r\n    base_url=\"https://testapi.quantumexecute.com\"\r\n)\r\n```\r\n\r\n## API \u53c2\u8003\r\n\r\n### \u4ea4\u6613\u6240 API \u7ba1\u7406\r\n\r\n#### \u67e5\u8be2\u4ea4\u6613\u6240 API \u5217\u8868\r\n\r\n\u67e5\u8be2\u5f53\u524d\u7528\u6237\u7ed1\u5b9a\u7684\u6240\u6709\u4ea4\u6613\u6240 API \u8d26\u6237\u3002\r\n\r\n**\u8bf7\u6c42\u53c2\u6570\uff1a**\r\n- `page` (int) - \u9875\u7801\uff0c\u53ef\u9009\r\n- `pageSize` (int) - \u6bcf\u9875\u6570\u91cf\uff0c\u53ef\u9009\r\n- `exchange` (str) - \u4ea4\u6613\u6240\u540d\u79f0\u7b5b\u9009\uff0c\u53ef\u9009\r\n\r\n**\u54cd\u5e94\u5b57\u6bb5\uff1a**\r\n- `items` - API \u5217\u8868\uff0c\u6bcf\u4e2a API \u5305\u542b\u4ee5\u4e0b\u5b57\u6bb5\uff1a\r\n  - `id` - API \u8bb0\u5f55\u7684\u552f\u4e00\u6807\u8bc6\r\n  - `createdAt` - API \u6dfb\u52a0\u65f6\u95f4\r\n  - `accountName` - \u8d26\u6237\u540d\u79f0\uff08\u5982\uff1a\u8d26\u62371\u3001\u8d26\u62372\uff09\r\n  - `exchange` - \u4ea4\u6613\u6240\u540d\u79f0\uff08\u5982\uff1aBinance\u3001OKX\u3001Bybit\uff09\r\n  - `apiKey` - \u4ea4\u6613\u6240 API Key\uff08\u90e8\u5206\u9690\u85cf\uff09\r\n  - `verificationMethod` - API \u9a8c\u8bc1\u65b9\u5f0f\uff08\u5982\uff1aOAuth\u3001API\uff09\r\n  - `balance` - \u8d26\u6237\u4f59\u989d\uff08\u7f8e\u5143\uff09\r\n  - `status` - API \u72b6\u6001\uff1a\u6b63\u5e38\u3001\u5f02\u5e38\uff08\u4e0d\u53ef\u7528\uff09\r\n  - `isValid` - API \u662f\u5426\u6709\u6548\r\n  - `isTradingEnabled` - \u662f\u5426\u5f00\u542f\u4ea4\u6613\u6743\u9650\r\n  - `isDefault` - \u662f\u5426\u4e3a\u8be5\u4ea4\u6613\u6240\u7684\u9ed8\u8ba4\u8d26\u6237\r\n  - `isPm` - \u662f\u5426\u4e3a Pm \u8d26\u6237\r\n- `total` - API \u603b\u6570\r\n- `page` - \u5f53\u524d\u9875\u7801\r\n- `pageSize` - \u6bcf\u9875\u663e\u793a\u6570\u91cf\r\n\r\n**\u793a\u4f8b\u4ee3\u7801\uff1a**\r\n\r\n```python\r\n# \u83b7\u53d6\u6240\u6709\u4ea4\u6613\u6240 API \u5bc6\u94a5\r\napis = client.list_exchange_apis()\r\nprint(f\"\u5171\u6709 {apis['total']} \u4e2a API \u5bc6\u94a5\")\r\n\r\n# \u6253\u5370\u6bcf\u4e2a API \u7684\u8be6\u7ec6\u4fe1\u606f\r\nfor api in apis['items']:\r\n    print(f\"\"\"\r\nAPI \u4fe1\u606f\uff1a\r\n    \u8d26\u6237: {api['accountName']}\r\n    \u4ea4\u6613\u6240: {api['exchange']}\r\n    \u72b6\u6001: {api['status']}\r\n    \u4f59\u989d: ${api['balance']:.2f}\r\n    \u4ea4\u6613\u6743\u9650: {'\u5f00\u542f' if api['isTradingEnabled'] else '\u5173\u95ed'}\r\n    \u662f\u5426\u9ed8\u8ba4: {'\u662f' if api['isDefault'] else '\u5426'}\r\n    \u662f\u5426PM\u8d26\u6237: {'\u662f' if api['isPm'] else '\u5426'}\r\n    \u6dfb\u52a0\u65f6\u95f4: {api['createdAt']}\r\n    \"\"\")\r\n\r\n# \u5e26\u5206\u9875\u548c\u8fc7\u6ee4\r\napis = client.list_exchange_apis(\r\n    page=1,\r\n    pageSize=10,\r\n    exchange=\"binance\"\r\n)\r\n```\r\n\r\n#### \u6dfb\u52a0\u4ea4\u6613\u6240 API\r\n\r\n\u6dfb\u52a0\u65b0\u7684\u4ea4\u6613\u6240 API \u8d26\u6237\u3002\r\n\r\n**\u8bf7\u6c42\u53c2\u6570\uff1a**\r\n- `accountName` (str) - \u8d26\u6237\u540d\u79f0\uff0c\u5fc5\u586b\r\n- `exchange` (str) - \u4ea4\u6613\u6240\u540d\u79f0\uff08\u5982\uff1aBinance\u3001OKX\u3001Bybit\uff09\uff0c\u5fc5\u586b\r\n- `apiKey` (str) - \u4ea4\u6613\u6240 API Key\uff0c\u5fc5\u586b\r\n- `apiSecret` (str) - \u4ea4\u6613\u6240 API Secret\uff0c\u5fc5\u586b\r\n- `passphrase` (str) - API \u5bc6\u7801\u77ed\u8bed\uff08\u90e8\u5206\u4ea4\u6613\u6240\u9700\u8981\uff09\uff0c\u53ef\u9009\r\n- `verificationMethod` (str) - API \u9a8c\u8bc1\u65b9\u5f0f\uff08\u5982\uff1aOAuth\u3001API\uff09\uff0c\u53ef\u9009\r\n- `enableTrading` (bool) - \u662f\u5426\u5f00\u542f\u4ea4\u6613\u6743\u9650\uff0c\u53ef\u9009\r\n\r\n**\u54cd\u5e94\u5b57\u6bb5\uff1a**\r\n- `id` - \u65b0\u521b\u5efa\u7684 API ID\r\n- `success` - \u6dfb\u52a0\u662f\u5426\u6210\u529f\r\n- `message` - \u64cd\u4f5c\u7ed3\u679c\u6d88\u606f\r\n\r\n**\u793a\u4f8b\u4ee3\u7801\uff1a**\r\n\r\n```python\r\n# \u6dfb\u52a0\u5e01\u5b89 API\r\nresult = client.add_exchange_api(\r\n    accountName=\"\u6211\u7684\u5e01\u5b89\u8d26\u6237\",\r\n    exchange=\"binance\",\r\n    apiKey=\"your-exchange-api-key\",\r\n    apiSecret=\"your-exchange-api-secret\",\r\n    enableTrading=True  # \u542f\u7528\u4ea4\u6613\u6743\u9650\r\n)\r\n\r\nif result['success']:\r\n    print(f\"API Key \u6dfb\u52a0\u6210\u529f\uff0cID: {result['id']}\")\r\nelse:\r\n    print(f\"API Key \u6dfb\u52a0\u5931\u8d25\uff1a{result['message']}\")\r\n\r\n# \u6dfb\u52a0 OKX API\uff08\u9700\u8981 passphrase\uff09\r\nresult = client.add_exchange_api(\r\n    accountName=\"\u6211\u7684 OKX \u8d26\u6237\",\r\n    exchange=\"okx\",\r\n    apiKey=\"your-okx-api-key\",\r\n    apiSecret=\"your-okx-api-secret\",\r\n    passphrase=\"your-okx-passphrase\",\r\n    verificationMethod=\"API\",\r\n    enableTrading=True\r\n)\r\n```\r\n\r\n### \u4ea4\u6613\u8ba2\u5355\u7ba1\u7406\r\n\r\n#### \u521b\u5efa\u4e3b\u8ba2\u5355\r\n\r\n\u521b\u5efa\u65b0\u7684\u4e3b\u8ba2\u5355\u5e76\u63d0\u4ea4\u5230\u7b97\u6cd5\u4fa7\u6267\u884c\u3002\r\n\r\n**\u8bf7\u6c42\u53c2\u6570\uff1a**\r\n- `algorithm` (str) - \u4ea4\u6613\u7b97\u6cd5\uff08\u5982\uff1aVWAP\u3001TWAP\uff09\uff0c\u5fc5\u586b\r\n- `algorithmType` (str) - \u7b97\u6cd5\u5206\u7c7b\uff0c\u6682\u65f6\u56fa\u5b9a\u4f20 \"TIME_WEIGHTED\"\uff0c\u5fc5\u586b\r\n- `exchange` (str) - \u4ea4\u6613\u6240\u540d\u79f0\uff08\u5982\uff1aBinance\u3001OKX\uff09\uff0c\u5fc5\u586b\r\n- `symbol` (str) - \u4ea4\u6613\u5bf9\u7b26\u53f7\uff08\u5982\uff1aBTCUSDT\uff09\uff0c\u5fc5\u586b\r\n- `marketType` (str) - \u5e02\u573a\u7c7b\u578b\uff08SPOT:\u73b0\u8d27, FUTURES:\u5408\u7ea6\uff09\uff0c\u5fc5\u586b\r\n- `side` (str) - \u4e70\u5356\u65b9\u5411\uff08BUY:\u4e70\u5165, SELL:\u5356\u51fa\uff09\uff0c\u5fc5\u586b\r\n- `apiKeyId` (str) - \u6307\u5b9a\u4f7f\u7528\u7684 API \u5bc6\u94a5 ID\uff0c\u5fc5\u586b\r\n- `totalQuantity` (float) - \u8981\u4ea4\u6613\u7684\u603b\u6570\u91cf\uff08\u6309\u5e01\u503c\u65f6\u4f7f\u7528\uff09\uff0c\u4e0e orderNotional \u4e8c\u9009\u4e00\r\n- `orderNotional` (float) - \u6309\u4ef7\u503c\u4e0b\u5355\u65f6\u7684\u91d1\u989d\uff08USDT\uff09\uff0c\u4e0e totalQuantity \u4e8c\u9009\u4e00\r\n- `strategyType` (str) - \u7b56\u7565\u7c7b\u578b\uff08\u5982\uff1aAGGRESSIVE\u3001PASSIVE\uff09\uff0c\u53ef\u9009\r\n- `startTime` (str) - \u5f00\u59cb\u6267\u884c\u65f6\u95f4\uff08ISO 8601\u683c\u5f0f\uff09\uff0c\u53ef\u9009\r\n- `endTime` (str) - \u7ed3\u675f\u65f6\u95f4\uff08ISO 8601\u683c\u5f0f\uff09\uff0cTWAP-2 \u65f6\u5fc5\u586b\r\n- `executionDuration` (int) - \u6267\u884c\u65f6\u957f\uff08\u79d2\uff09\uff0cTWAP-1 \u65f6\u5fc5\u586b\r\n- `worstPrice` (float) - \u6700\u5dee\u6210\u4ea4\u4ef7\uff0c\u5fc5\u987b\u5b8c\u6210\u4e3a true \u65f6\u53ef\u9009\r\n- `limitPriceString` (str) - \u9650\u4ef7\u5b57\u7b26\u4e32\uff0c\u8d85\u51fa\u8303\u56f4\u505c\u6b62\u4ea4\u6613\uff0c\u586b \"-1\" \u4e0d\u9650\u5236\r\n- `upTolerance` (str) - \u5141\u8bb8\u8d85\u51fa schedule \u7684\u5bb9\u5fcd\u5ea6\uff08\u5982 \"0.1\" \u8868\u793a 10%\uff09\r\n- `lowTolerance` (str) - \u5141\u8bb8\u843d\u540e schedule \u7684\u5bb9\u5fcd\u5ea6\r\n- `strictUpBound` (bool) - \u662f\u5426\u4e25\u683c\u5c0f\u4e8e upTolerance\uff0c\u4e0d\u5efa\u8bae\u5f00\u542f\r\n- `mustComplete` (bool) - \u662f\u5426\u5fc5\u987b\u5728 duration \u5185\u6267\u884c\u5b8c\uff0c\u9ed8\u8ba4 true\r\n- `makerRateLimit` (float) - \u8981\u6c42 maker \u5360\u6bd4\u8d85\u8fc7\u8be5\u503c\uff080-1\uff09\r\n- `povLimit` (float) - \u5360\u5e02\u573a\u6210\u4ea4\u91cf\u6bd4\u4f8b\u9650\u5236\uff080-1\uff09\r\n- `marginType` (str) - \u5408\u7ea6\u4ea4\u6613\u4fdd\u8bc1\u91d1\u7c7b\u578b\uff08CROSS:\u5168\u4ed3, ISOLATED:\u9010\u4ed3\uff09\r\n- `reduceOnly` (bool) - \u5408\u7ea6\u4ea4\u6613\u65f6\u662f\u5426\u4ec5\u51cf\u4ed3\uff0c\u9ed8\u8ba4 false\r\n- `notes` (str) - \u8ba2\u5355\u5907\u6ce8\uff0c\u53ef\u9009\r\n- `clientId` (str) - \u5ba2\u6237\u7aef\u552f\u4e00\u6807\u8bc6\u7b26\uff0c\u53ef\u9009\r\n\r\n**\u54cd\u5e94\u5b57\u6bb5\uff1a**\r\n- `masterOrderId` - \u521b\u5efa\u6210\u529f\u7684\u4e3b\u8ba2\u5355 ID\r\n- `success` - \u521b\u5efa\u662f\u5426\u6210\u529f\r\n- `message` - \u521b\u5efa\u7ed3\u679c\u6d88\u606f\r\n\r\n**\u793a\u4f8b\u4ee3\u7801\uff1a**\r\n\r\n```python\r\n# TWAP \u8ba2\u5355\u793a\u4f8b - \u5728 30 \u5206\u949f\u5185\u5206\u6279\u4e70\u5165\u4ef7\u503c $10,000 \u7684 BTC\r\nresponse = client.create_master_order(\r\n    algorithm=\"TWAP\",\r\n    algorithmType=\"TIME_WEIGHTED\",\r\n    exchange=\"binance\",\r\n    symbol=\"BTCUSDT\",\r\n    marketType=\"SPOT\",\r\n    side=\"BUY\",\r\n    apiKeyId=\"your-api-key-id\",  # \u4ece list_exchange_apis \u83b7\u53d6\r\n    orderNotional=10000,          # $10,000 \u540d\u4e49\u4ef7\u503c\r\n    startTime=\"2024-01-01T10:00:00Z\",\r\n    endTime=\"2024-01-01T10:30:00Z\",\r\n    executionDuration=\"1800\",     # 30 \u5206\u949f = 1800 \u79d2\r\n    mustComplete=True,            # \u5fc5\u987b\u5b8c\u6210\u5168\u90e8\u8ba2\u5355\r\n    worstPrice=60000,            # \u6700\u5dee\u4ef7\u683c $60,000\r\n    upTolerance=\"0.1\",           # \u5141\u8bb8\u8d85\u51fa 10%\r\n    lowTolerance=\"0.1\",          # \u5141\u8bb8\u843d\u540e 10%\r\n    strictUpBound=False,         # \u4e0d\u4e25\u683c\u9650\u5236\u4e0a\u754c\r\n    clientId=\"my-order-001\",     # \u81ea\u5b9a\u4e49\u8ba2\u5355 ID\r\n    notes=\"\u6d4b\u8bd5 TWAP \u8ba2\u5355\"       # \u8ba2\u5355\u5907\u6ce8\r\n)\r\n\r\nif response.get('success'):\r\n    print(f\"\u4e3b\u8ba2\u5355\u521b\u5efa\u6210\u529f\uff0cID: {response['masterOrderId']}\")\r\nelse:\r\n    print(f\"\u521b\u5efa\u5931\u8d25\uff1a{response.get('message')}\")\r\n\r\n\r\n# \u4f7f\u7528\u9650\u4ef7\u5b57\u7b26\u4e32\u7684\u793a\u4f8b\r\nresponse = client.create_master_order(\r\n    algorithm=\"TWAP\",\r\n    algorithmType=\"TIME_WEIGHTED\",\r\n    exchange=\"binance\",\r\n    symbol=\"BTCUSDT\",\r\n    marketType=\"SPOT\",\r\n    side=\"BUY\",\r\n    apiKeyId=\"your-api-key-id\",\r\n    orderNotional=5000,\r\n    executionDuration=\"1800\",\r\n    limitPriceString=\"50000\",    # \u9650\u4ef7 $50,000\uff08\u5b57\u7b26\u4e32\u683c\u5f0f\uff09\r\n    upTolerance=\"0.05\",          # \u5141\u8bb8\u8d85\u51fa 5%\r\n    lowTolerance=\"0.1\",          # \u5141\u8bb8\u843d\u540e 10%\r\n    strictUpBound=False,         # \u5173\u95ed\u4e25\u683c\u4e0a\u754c\u9650\u5236\r\n    mustComplete=True\r\n)\r\n```\r\n\r\n#### \u67e5\u8be2\u4e3b\u8ba2\u5355\u5217\u8868\r\n\r\n\u83b7\u53d6\u7528\u6237\u7684\u4e3b\u8ba2\u5355\u5217\u8868\u3002\r\n\r\n**\u8bf7\u6c42\u53c2\u6570\uff1a**\r\n- `page` (int) - \u9875\u7801\uff0c\u53ef\u9009\r\n- `pageSize` (int) - \u6bcf\u9875\u6570\u91cf\uff0c\u53ef\u9009\r\n- `status` (str) - \u8ba2\u5355\u72b6\u6001\u7b5b\u9009\uff0c\u53ef\u9009\r\n- `exchange` (str) - \u4ea4\u6613\u6240\u540d\u79f0\u7b5b\u9009\uff0c\u53ef\u9009\r\n- `symbol` (str) - \u4ea4\u6613\u5bf9\u7b5b\u9009\uff0c\u53ef\u9009\r\n- `startTime` (str) - \u5f00\u59cb\u65f6\u95f4\u7b5b\u9009\uff0c\u53ef\u9009\r\n- `endTime` (str) - \u7ed3\u675f\u65f6\u95f4\u7b5b\u9009\uff0c\u53ef\u9009\r\n\r\n**\u54cd\u5e94\u5b57\u6bb5\uff1a**\r\n- `items` - \u4e3b\u8ba2\u5355\u5217\u8868\uff0c\u6bcf\u4e2a\u8ba2\u5355\u5305\u542b\uff1a\r\n  - `masterOrderId` - \u4e3b\u8ba2\u5355 ID\r\n  - `algorithm` - \u7b97\u6cd5\r\n  - `algorithmType` - \u7b97\u6cd5\u7c7b\u578b\r\n  - `exchange` - \u4ea4\u6613\u6240\r\n  - `symbol` - \u4ea4\u6613\u5bf9\r\n  - `marketType` - \u5e02\u573a\u7c7b\u578b\r\n  - `side` - \u4e70\u5356\u65b9\u5411\r\n  - `totalQuantity` - \u603b\u6570\u91cf\r\n  - `filledQuantity` - \u5df2\u6210\u4ea4\u6570\u91cf\r\n  - `averagePrice` - \u5e73\u5747\u6210\u4ea4\u4ef7\r\n  - `status` - \u72b6\u6001\r\n  - `executionDuration` - \u6267\u884c\u65f6\u957f\uff08\u79d2\uff09\r\n  - `priceLimit` - \u4ef7\u683c\u9650\u5236\r\n  - `startTime` - \u5f00\u59cb\u65f6\u95f4\r\n  - `endTime` - \u7ed3\u675f\u65f6\u95f4\r\n  - `createdAt` - \u521b\u5efa\u65f6\u95f4\r\n  - `updatedAt` - \u66f4\u65b0\u65f6\u95f4\r\n  - `notes` - \u5907\u6ce8\r\n  - `marginType` - \u4fdd\u8bc1\u91d1\u7c7b\u578b\uff08U:U\u672c\u4f4d, C:\u5e01\u672c\u4f4d\uff09\r\n  - `reduceOnly` - \u662f\u5426\u4ec5\u51cf\u4ed3\r\n  - `strategyType` - \u7b56\u7565\u7c7b\u578b\r\n  - `orderNotional` - \u8ba2\u5355\u91d1\u989d\uff08USDT\uff09\r\n  - `mustComplete` - \u662f\u5426\u5fc5\u987b\u5b8c\u6210\r\n  - `makerRateLimit` - \u6700\u4f4e Maker \u7387\r\n  - `povLimit` - \u6700\u5927\u5e02\u573a\u6210\u4ea4\u91cf\u5360\u6bd4\r\n  - `clientId` - \u5ba2\u6237\u7aef ID\r\n  - `date` - \u53d1\u5355\u65e5\u671f\uff08\u683c\u5f0f\uff1aYYYYMMDD\uff09\r\n  - `ticktimeInt` - \u53d1\u5355\u65f6\u95f4\uff08\u683c\u5f0f\uff1a093000000 \u8868\u793a 9:30:00.000\uff09\r\n  - `limitPriceString` - \u9650\u4ef7\uff08\u5b57\u7b26\u4e32\uff09\r\n  - `upTolerance` - \u4e0a\u5bb9\u5fcd\u5ea6\r\n  - `lowTolerance` - \u4e0b\u5bb9\u5fcd\u5ea6\r\n  - `strictUpBound` - \u4e25\u683c\u4e0a\u754c\r\n  - `ticktimeMs` - \u53d1\u5355\u65f6\u95f4\u6233\uff08epoch \u6beb\u79d2\uff09\r\n  - `category` - \u4ea4\u6613\u54c1\u79cd\uff08spot \u6216 perp\uff09\r\n  - `filledAmount` - \u6210\u4ea4\u91d1\u989d\r\n  - `totalValue` - \u6210\u4ea4\u603b\u503c\r\n  - `base` - \u57fa\u7840\u5e01\u79cd\r\n  - `quote` - \u8ba1\u4ef7\u5e01\u79cd\r\n  - `completionProgress` - \u5b8c\u6210\u8fdb\u5ea6\uff080-1\uff09\r\n  - `reason` - \u539f\u56e0\uff08\u5982\u53d6\u6d88\u539f\u56e0\uff09\r\n- `total` - \u603b\u6570\r\n- `page` - \u5f53\u524d\u9875\u7801\r\n- `pageSize` - \u6bcf\u9875\u6570\u91cf\r\n\r\n**\u793a\u4f8b\u4ee3\u7801\uff1a**\r\n\r\n```python\r\n# \u67e5\u8be2\u6240\u6709\u4e3b\u8ba2\u5355\r\norders = client.get_master_orders()\r\n\r\n# \u5e26\u8fc7\u6ee4\u6761\u4ef6\u67e5\u8be2\r\norders = client.get_master_orders(\r\n    page=1,\r\n    pageSize=20,\r\n    status=\"NEW\",              # \u6d3b\u8dc3\u8ba2\u5355\r\n    symbol=\"BTCUSDT\",\r\n    startTime=\"2024-01-01T00:00:00Z\",\r\n    endTime=\"2024-01-31T23:59:59Z\"\r\n)\r\n\r\n# \u6253\u5370\u8ba2\u5355\u8be6\u7ec6\u4fe1\u606f\r\nfor order in orders['items']:\r\n    print(f\"\"\"\r\n\u8ba2\u5355\u8be6\u60c5\uff1a\r\n    ID: {order['masterOrderId']}\r\n    \u7b97\u6cd5: {order['algorithm']} ({order.get('strategyType', 'N/A')})\r\n    \u4ea4\u6613\u5bf9: {order['symbol']} ({order['marketType']})\r\n    \u65b9\u5411: {order['side']}\r\n    \u72b6\u6001: {order['status']}\r\n    \u5b8c\u6210\u5ea6: {order['completionProgress'] * 100:.2f}%\r\n    \u5e73\u5747\u4ef7\u683c: ${order.get('averagePrice', 0):.2f}\r\n    \u5df2\u6210\u4ea4: {order['filledQuantity']:.4f} / {order['totalQuantity']:.4f}\r\n    \u6210\u4ea4\u91d1\u989d: ${order.get('filledAmount', 0):.2f}\r\n    \u521b\u5efa\u65f6\u95f4: {order['createdAt']}\r\n    \u53d1\u5355\u65e5\u671f: {order.get('date', 'N/A')}\r\n    \u9650\u4ef7: {order.get('limitPriceString', '-1')}\r\n    \u4e0a\u5bb9\u5fcd\u5ea6: {order.get('upTolerance', 'N/A')}\r\n    \u4e0b\u5bb9\u5fcd\u5ea6: {order.get('lowTolerance', 'N/A')}\r\n    \u4e25\u683c\u4e0a\u754c: {order.get('strictUpBound', False)}\r\n    \u5ba2\u6237\u7aefID: {order.get('clientId', 'N/A')}\r\n    \u5907\u6ce8: {order.get('notes', '')}\r\n    \"\"\")\r\n\r\n# \u7edf\u8ba1\u4fe1\u606f\r\ntotal_orders = len(orders['items'])\r\nactive_orders = sum(1 for o in orders['items'] if o['status'] == 'ACTIVE')\r\ncompleted_orders = sum(1 for o in orders['items'] if o['status'] == 'COMPLETED')\r\nprint(f\"\\n\u7edf\u8ba1\uff1a\u603b\u8ba2\u5355 {total_orders}\uff0c\u6d3b\u8dc3 {active_orders}\uff0c\u5df2\u5b8c\u6210 {completed_orders}\")\r\n```\r\n\r\n#### \u67e5\u8be2\u6210\u4ea4\u8bb0\u5f55\r\n\r\n\u83b7\u53d6\u7528\u6237\u7684\u6210\u4ea4\u8bb0\u5f55\u3002\r\n\r\n**\u8bf7\u6c42\u53c2\u6570\uff1a**\r\n- `page` (int) - \u9875\u7801\uff0c\u53ef\u9009\r\n- `pageSize` (int) - \u6bcf\u9875\u6570\u91cf\uff0c\u53ef\u9009\r\n- `masterOrderId` (str) - \u4e3b\u8ba2\u5355 ID \u7b5b\u9009\uff0c\u53ef\u9009\r\n- `subOrderId` (str) - \u5b50\u8ba2\u5355 ID \u7b5b\u9009\uff0c\u53ef\u9009\r\n- `symbol` (str) - \u4ea4\u6613\u5bf9\u7b5b\u9009\uff0c\u53ef\u9009\r\n- `startTime` (str) - \u5f00\u59cb\u65f6\u95f4\u7b5b\u9009\uff0c\u53ef\u9009\r\n- `endTime` (str) - \u7ed3\u675f\u65f6\u95f4\u7b5b\u9009\uff0c\u53ef\u9009\r\n\r\n**\u54cd\u5e94\u5b57\u6bb5\uff1a**\r\n- `items` - \u6210\u4ea4\u8bb0\u5f55\u5217\u8868\uff0c\u6bcf\u6761\u8bb0\u5f55\u5305\u542b\uff1a\r\n  - `id` - \u8bb0\u5f55 ID\r\n  - `orderCreatedTime` - \u8ba2\u5355\u521b\u5efa\u65f6\u95f4\r\n  - `masterOrderId` - \u4e3b\u8ba2\u5355 ID\r\n  - `exchange` - \u4ea4\u6613\u6240\r\n  - `category` - \u5e02\u573a\u7c7b\u578b\r\n  - `symbol` - \u4ea4\u6613\u5bf9\r\n  - `side` - \u65b9\u5411\r\n  - `filledValue` - \u6210\u4ea4\u4ef7\u503c\r\n  - `filledQuantity` - \u6210\u4ea4\u6570\u91cf\r\n  - `avgPrice` - \u5e73\u5747\u4ef7\u683c\r\n  - `price` - \u6210\u4ea4\u4ef7\u683c\r\n  - `fee` - \u624b\u7eed\u8d39\r\n  - `tradingAccount` - \u4ea4\u6613\u8d26\u6237\r\n  - `status` - \u72b6\u6001\r\n  - `rejectReason` - \u62d2\u7edd\u539f\u56e0\r\n  - `base` - \u57fa\u7840\u5e01\u79cd\r\n  - `quote` - \u8ba1\u4ef7\u5e01\u79cd\r\n  - `type` - \u8ba2\u5355\u7c7b\u578b\r\n- `total` - \u603b\u6570\r\n- `page` - \u5f53\u524d\u9875\u7801\r\n- `pageSize` - \u6bcf\u9875\u6570\u91cf\r\n\r\n**\u793a\u4f8b\u4ee3\u7801\uff1a**\r\n\r\n```python\r\n# \u67e5\u8be2\u7279\u5b9a\u4e3b\u8ba2\u5355\u7684\u6210\u4ea4\u660e\u7ec6\r\nfills = client.get_order_fills(\r\n    masterOrderId=\"your-master-order-id\",\r\n    page=1,\r\n    pageSize=50\r\n)\r\n\r\n# \u67e5\u8be2\u6240\u6709\u6210\u4ea4\r\nfills = client.get_order_fills(\r\n    symbol=\"BTCUSDT\",\r\n    startTime=\"2024-01-01T00:00:00Z\",\r\n    endTime=\"2024-01-01T23:59:59Z\"\r\n)\r\n\r\n# \u5206\u6790\u6210\u4ea4\u6570\u636e\r\ntotal_value = 0\r\ntotal_fee = 0\r\nfill_types = {}\r\n\r\nfor fill in fills['items']:\r\n    print(f\"\"\"\r\n\u6210\u4ea4\u8bb0\u5f55\uff1a\r\n    \u65f6\u95f4: {fill['orderCreatedTime']}\r\n    \u4ea4\u6613\u5bf9: {fill['symbol']} ({fill['category']})\r\n    \u65b9\u5411: {fill['side']}\r\n    \u6210\u4ea4\u4ef7\u683c: ${fill['price']:.2f}\r\n    \u6210\u4ea4\u6570\u91cf: {fill['filledQuantity']:.6f}\r\n    \u6210\u4ea4\u91d1\u989d: ${fill['filledValue']:.2f}\r\n    \u624b\u7eed\u8d39: ${fill['fee']:.4f}\r\n    \u8d26\u6237: {fill['tradingAccount']}\r\n    \u7c7b\u578b: {fill.get('type', 'N/A')}\r\n    \u72b6\u6001: {fill['status']}\r\n    \"\"\")\r\n    \r\n    total_value += fill['filledValue']\r\n    total_fee += fill['fee']\r\n    \r\n    # \u7edf\u8ba1\u8ba2\u5355\u7c7b\u578b\r\n    order_type = fill.get('type', 'Unknown')\r\n    fill_types[order_type] = fill_types.get(order_type, 0) + 1\r\n\r\nprint(f\"\\n\u6210\u4ea4\u7edf\u8ba1\uff1a\")\r\nprint(f\"\u603b\u6210\u4ea4\u989d: ${total_value:.2f}\")\r\nprint(f\"\u603b\u624b\u7eed\u8d39: ${total_fee:.2f}\")\r\nprint(f\"\u624b\u7eed\u8d39\u7387: {(total_fee/total_value*100):.3f}%\")\r\nprint(f\"\u8ba2\u5355\u7c7b\u578b\u5206\u5e03: {fill_types}\")\r\n```\r\n\r\n#### \u53d6\u6d88\u4e3b\u8ba2\u5355\r\n\r\n\u53d6\u6d88\u6307\u5b9a\u7684\u4e3b\u8ba2\u5355\u3002\r\n\r\n**\u8bf7\u6c42\u53c2\u6570\uff1a**\r\n- `masterOrderId` (str) - \u8981\u53d6\u6d88\u7684\u4e3b\u8ba2\u5355 ID\uff0c\u5fc5\u586b\r\n- `reason` (str) - \u53d6\u6d88\u539f\u56e0\uff0c\u53ef\u9009\r\n\r\n**\u54cd\u5e94\u5b57\u6bb5\uff1a**\r\n- `success` - \u53d6\u6d88\u662f\u5426\u6210\u529f\r\n- `message` - \u53d6\u6d88\u7ed3\u679c\u6d88\u606f\r\n\r\n**\u793a\u4f8b\u4ee3\u7801\uff1a**\r\n\r\n```python\r\n# \u53d6\u6d88\u8ba2\u5355\r\nresponse = client.cancel_master_order(\r\n    masterOrderId=\"your-master-order-id\",\r\n    reason=\"\u7528\u6237\u624b\u52a8\u53d6\u6d88\"  # \u53ef\u9009\u7684\u53d6\u6d88\u539f\u56e0\r\n)\r\n\r\nif response.get('success'):\r\n    print(\"\u8ba2\u5355\u53d6\u6d88\u6210\u529f\")\r\nelse:\r\n    print(f\"\u8ba2\u5355\u53d6\u6d88\u5931\u8d25: {response.get('message')}\")\r\n\r\n# \u6279\u91cf\u53d6\u6d88\u793a\u4f8b\r\ndef cancel_all_active_orders(client):\r\n    \"\"\"\u53d6\u6d88\u6240\u6709\u6d3b\u8dc3\u8ba2\u5355\"\"\"\r\n    orders = client.get_master_orders(status=\"ACTIVE\")\r\n    cancelled_count = 0\r\n    \r\n    for order in orders['items']:\r\n        try:\r\n            response = client.cancel_master_order(\r\n                masterOrderId=order['masterOrderId'],\r\n                reason=\"\u6279\u91cf\u53d6\u6d88\u6d3b\u8dc3\u8ba2\u5355\"\r\n            )\r\n            if response.get('success'):\r\n                cancelled_count += 1\r\n                print(f\"\u5df2\u53d6\u6d88\u8ba2\u5355: {order['masterOrderId']}\")\r\n            else:\r\n                print(f\"\u53d6\u6d88\u5931\u8d25: {order['masterOrderId']} - {response.get('message')}\")\r\n        except Exception as e:\r\n            print(f\"\u53d6\u6d88\u5f02\u5e38: {order['masterOrderId']} - {str(e)}\")\r\n    \r\n    print(f\"\\n\u603b\u8ba1\u53d6\u6d88 {cancelled_count} \u4e2a\u8ba2\u5355\")\r\n    return cancelled_count\r\n```\r\n\r\n## \u9519\u8bef\u5904\u7406\r\n\r\nSDK \u63d0\u4f9b\u4e86\u8be6\u7ec6\u7684\u9519\u8bef\u7c7b\u578b\uff0c\u65b9\u4fbf\u8fdb\u884c\u7cbe\u786e\u7684\u9519\u8bef\u5904\u7406\uff1a\r\n\r\n```python\r\nfrom qe.error import ClientError, APIError\r\n\r\ntry:\r\n    response = client.create_master_order(\r\n        # ... \u8ba2\u5355\u53c2\u6570\r\n    )\r\nexcept APIError as error:\r\n    # API \u8fd4\u56de\u7684\u4e1a\u52a1\u9519\u8bef\r\n    print(f\"API \u9519\u8bef - \u4ee3\u7801: {error.code}, \u539f\u56e0: {error.reason}, \u6d88\u606f: {error.message}\")\r\n    print(f\"\u8ffd\u8e2a ID: {error.trace_id}\")  # \u7528\u4e8e\u6280\u672f\u652f\u6301\r\n    \r\n    # \u6839\u636e\u9519\u8bef\u4ee3\u7801\u5904\u7406\r\n    if error.code == 400:\r\n        print(\"\u8bf7\u6c42\u53c2\u6570\u9519\u8bef\uff0c\u8bf7\u68c0\u67e5\u8f93\u5165\")\r\n    elif error.code == 401:\r\n        print(\"\u8ba4\u8bc1\u5931\u8d25\uff0c\u8bf7\u68c0\u67e5 API \u5bc6\u94a5\")\r\n    elif error.code == 403:\r\n        print(\"\u6743\u9650\u4e0d\u8db3\")\r\n    elif error.code == 429:\r\n        print(\"\u8bf7\u6c42\u8fc7\u4e8e\u9891\u7e41\uff0c\u8bf7\u7a0d\u540e\u91cd\u8bd5\")\r\n        \r\nexcept ClientError as error:\r\n    # \u5ba2\u6237\u7aef\u9519\u8bef\uff08\u5982\u53c2\u6570\u9519\u8bef\u3001\u7f51\u7edc\u9519\u8bef\u7b49\uff09\r\n    print(f\"\u5ba2\u6237\u7aef\u9519\u8bef - \u72b6\u6001\u7801: {error.status_code}, \u9519\u8bef\u6d88\u606f: {error.error_message}\")\r\n    \r\nexcept Exception as error:\r\n    # \u5176\u4ed6\u672a\u9884\u671f\u7684\u9519\u8bef\r\n    print(f\"\u672a\u77e5\u9519\u8bef: {error}\")\r\n```\r\n\r\n## \u9ad8\u7ea7\u914d\u7f6e\r\n\r\n### \u914d\u7f6e\u8d85\u65f6\u548c\u4ee3\u7406\r\n\r\n```python\r\nclient = Client(\r\n    api_key=\"your-api-key\",\r\n    api_secret=\"your-api-secret\",\r\n    timeout=30,  # 30 \u79d2\u8d85\u65f6\r\n    proxies={\r\n        'https': 'http://proxy.example.com:8080'\r\n    }\r\n)\r\n```\r\n\r\n### \u4f7f\u7528 RSA \u6216 Ed25519 \u7b7e\u540d\r\n\r\n```python\r\n# \u4f7f\u7528 RSA \u79c1\u94a5\r\nwith open('private_key.pem', 'r') as f:\r\n    private_key = f.read()\r\n\r\nclient = Client(\r\n    api_key=\"your-api-key\",\r\n    private_key=private_key,\r\n    private_key_pass=\"your-password\"  # \u5982\u679c\u79c1\u94a5\u6709\u5bc6\u7801\r\n)\r\n\r\n# \u4f7f\u7528 Ed25519 \u79c1\u94a5\r\nwith open('ed25519_key.pem', 'r') as f:\r\n    ed25519_key = f.read()\r\n\r\nclient = Client(\r\n    api_key=\"your-api-key\",\r\n    private_key=ed25519_key\r\n)\r\n```\r\n\r\n### \u663e\u793a\u8bf7\u6c42\u9650\u5236\u4f7f\u7528\u60c5\u51b5\r\n\r\n```python\r\nclient = Client(\r\n    api_key=\"your-api-key\",\r\n    api_secret=\"your-api-secret\",\r\n    show_limit_usage=True,\r\n    show_header=True\r\n)\r\n\r\n# API \u54cd\u5e94\u5c06\u5305\u542b\u9650\u5236\u4fe1\u606f\r\nresponse = client.get_master_orders()\r\nif isinstance(response, dict) and 'limit_usage' in response:\r\n    print(f\"\u9650\u5236\u4f7f\u7528\u60c5\u51b5: {response['limit_usage']}\")\r\n    print(f\"\u5b9e\u9645\u6570\u636e: {response['data']}\")\r\n```\r\n\r\n### \u914d\u7f6e\u65e5\u5fd7\r\n\r\n```python\r\nimport logging\r\nfrom qe.lib.utils import config_logging\r\n\r\n# \u914d\u7f6e\u8be6\u7ec6\u65e5\u5fd7\r\nconfig_logging(logging, logging.DEBUG)\r\n\r\n# \u53ea\u8bb0\u5f55\u8b66\u544a\u548c\u9519\u8bef\r\nconfig_logging(logging, logging.WARNING)\r\n```\r\n\r\n## \u5b8c\u6574\u793a\u4f8b\r\n\r\n### \u5b8c\u6574\u7684\u4ea4\u6613\u6d41\u7a0b\u793a\u4f8b\r\n\r\n```python\r\nimport logging\r\nfrom qe.user import User as Client\r\nfrom qe.error import ClientError, APIError\r\nfrom qe.lib.utils import config_logging\r\nimport time\r\nfrom datetime import datetime, timedelta\r\n\r\n# \u914d\u7f6e\u65e5\u5fd7\r\nconfig_logging(logging, logging.INFO)\r\nlogger = logging.getLogger(__name__)\r\n\r\n# \u521d\u59cb\u5316\u5ba2\u6237\u7aef\r\nclient = Client(\"your-api-key\", \"your-api-secret\")\r\n\r\ntry:\r\n    # 1. \u83b7\u53d6\u53ef\u7528\u7684 API \u5bc6\u94a5\r\n    apis = client.list_exchange_apis(exchange=\"binance\")\r\n    if not apis['items']:\r\n        logger.error(\"\u6ca1\u6709\u627e\u5230\u53ef\u7528\u7684\u5e01\u5b89 API \u5bc6\u94a5\")\r\n        exit(1)\r\n    \r\n    # \u9009\u62e9\u4f59\u989d\u6700\u9ad8\u7684\u8d26\u6237\r\n    api_info = max(apis['items'], key=lambda x: x.get('balance', 0))\r\n    api_key_id = api_info['id']\r\n    logger.info(f\"\u4f7f\u7528 API \u5bc6\u94a5: {api_key_id}, \u8d26\u6237: {api_info['accountName']}, \u4f59\u989d: ${api_info['balance']:.2f}\")\r\n    \r\n    # 2. \u521b\u5efa TWAP \u8ba2\u5355\r\n    start_time = datetime.utcnow().isoformat() + 'Z'\r\n    end_time = (datetime.utcnow() + timedelta(minutes=10)).isoformat() + 'Z'\r\n    \r\n    order_response = client.create_master_order(\r\n        algorithm=\"TWAP\",\r\n        algorithmType=\"TIME_WEIGHTED\",\r\n        exchange=\"binance\",\r\n        symbol=\"BTCUSDT\",\r\n        marketType=\"SPOT\",\r\n        side=\"BUY\",\r\n        apiKeyId=api_key_id,\r\n        orderNotional=1000,           # $1000\r\n        startTime=start_time,\r\n        endTime=end_time,\r\n        executionDuration=\"30\",       # \u6bcf 30 \u79d2\u6267\u884c\u4e00\u6b21\r\n        mustComplete=True,\r\n        worstPrice=70000,            # \u6700\u5dee\u4ef7\u683c $70,000\r\n        upTolerance=\"0.05\",          # \u5141\u8bb8\u8d85\u51fa 5%\r\n        lowTolerance=\"0.05\",         # \u5141\u8bb8\u843d\u540e 5%\r\n        strictUpBound=False,\r\n        clientId=f\"test_order_{int(time.time())}\",\r\n        notes=\"Python SDK \u6d4b\u8bd5\u8ba2\u5355\"\r\n    )\r\n    \r\n    if not order_response.get('success'):\r\n        logger.error(f\"\u521b\u5efa\u8ba2\u5355\u5931\u8d25: {order_response.get('message')}\")\r\n        exit(1)\r\n    \r\n    master_order_id = order_response['masterOrderId']\r\n    logger.info(f\"\u8ba2\u5355\u521b\u5efa\u6210\u529f\uff0cID: {master_order_id}\")\r\n    \r\n    # 3. \u76d1\u63a7\u8ba2\u5355\u72b6\u6001\r\n    previous_progress = 0\r\n    while True:\r\n        orders = client.get_master_orders(\r\n            page=1,\r\n            pageSize=1,\r\n            status=\"ACTIVE\"\r\n        )\r\n        \r\n        if not orders['items']:\r\n            logger.info(\"\u8ba2\u5355\u5df2\u5b8c\u6210\u6216\u53d6\u6d88\")\r\n            break\r\n        \r\n        order = orders['items'][0]\r\n        current_progress = order['completionProgress'] * 100\r\n        \r\n        # \u53ea\u5728\u8fdb\u5ea6\u53d8\u5316\u65f6\u6253\u5370\r\n        if current_progress != previous_progress:\r\n            logger.info(f\"\u8ba2\u5355\u8fdb\u5ea6: {current_progress:.2f}%, \"\r\n                       f\"\u5df2\u6210\u4ea4: {order['filledQuantity']:.6f}/{order['totalQuantity']:.6f}, \"\r\n                       f\"\u5e73\u5747\u4ef7\u683c: ${order.get('averagePrice', 0):.2f}\")\r\n            previous_progress = current_progress\r\n        \r\n        # \u68c0\u67e5\u662f\u5426\u9700\u8981\u53d6\u6d88\uff08\u6f14\u793a\u7528\uff09\r\n        if current_progress > 50:  # \u5b8c\u6210\u8d85\u8fc7 50%\r\n            logger.info(\"\u6f14\u793a\uff1a\u53d6\u6d88\u8ba2\u5355\")\r\n            cancel_response = client.cancel_master_order(\r\n                masterOrderId=master_order_id,\r\n                reason=\"\u6f14\u793a\u53d6\u6d88\"\r\n            )\r\n            if cancel_response.get('success'):\r\n                logger.info(\"\u8ba2\u5355\u5df2\u53d6\u6d88\")\r\n            break\r\n        \r\n        time.sleep(10)  # \u6bcf 10 \u79d2\u68c0\u67e5\u4e00\u6b21\r\n    \r\n    # 4. \u83b7\u53d6\u6700\u7ec8\u6210\u4ea4\u660e\u7ec6\r\n    fills = client.get_order_fills(masterOrderId=master_order_id)\r\n    logger.info(f\"\u603b\u6210\u4ea4\u7b14\u6570: {fills['total']}\")\r\n    \r\n    total_value = 0\r\n    total_fee = 0\r\n    for fill in fills['items']:\r\n        logger.info(f\"\u6210\u4ea4: {fill['side']} {fill['filledQuantity']:.6f} {fill['symbol']} \"\r\n                   f\"@ ${fill['price']:.2f}, \u624b\u7eed\u8d39: ${fill['fee']:.4f}\")\r\n        total_value += fill['filledValue']\r\n        total_fee += fill['fee']\r\n    \r\n    if total_value > 0:\r\n        logger.info(f\"\\n\u6210\u4ea4\u603b\u7ed3\uff1a\")\r\n        logger.info(f\"\u603b\u6210\u4ea4\u989d: ${total_value:.2f}\")\r\n        logger.info(f\"\u603b\u624b\u7eed\u8d39: ${total_fee:.2f}\")\r\n        logger.info(f\"\u624b\u7eed\u8d39\u7387: {(total_fee/total_value*100):.3f}%\")\r\n\r\nexcept APIError as error:\r\n    logger.error(f\"API \u9519\u8bef: {error}\")\r\nexcept ClientError as error:\r\n    logger.error(f\"\u5ba2\u6237\u7aef\u9519\u8bef: {error}\")\r\nexcept Exception as error:\r\n    logger.error(f\"\u672a\u77e5\u9519\u8bef: {error}\")\r\n```\r\n\r\n### \u7b56\u7565\u6267\u884c\u793a\u4f8b\r\n\r\n```python\r\ndef execute_vwap_strategy(client, symbol, amount_usd, duration_hours=8):\r\n    \"\"\"\u6267\u884c VWAP \u7b56\u7565\"\"\"\r\n    logger = logging.getLogger(__name__)\r\n    \r\n    try:\r\n        # \u83b7\u53d6\u9ed8\u8ba4 API\r\n        apis = client.list_exchange_apis(exchange=\"binance\")\r\n        default_api = next((api for api in apis['items'] if api.get('isDefault')), None)\r\n        \r\n        if not default_api:\r\n            raise ValueError(\"\u6ca1\u6709\u627e\u5230\u9ed8\u8ba4\u7684\u5e01\u5b89 API\")\r\n        \r\n        # \u521b\u5efa VWAP \u8ba2\u5355\r\n        start_time = datetime.utcnow().isoformat() + 'Z'\r\n        end_time = (datetime.utcnow() + timedelta(hours=duration_hours)).isoformat() + 'Z'\r\n        \r\n        response = client.create_master_order(\r\n            algorithm=\"VWAP\",\r\n            algorithmType=\"VOLUME_WEIGHTED\",\r\n            exchange=\"binance\",\r\n            symbol=symbol,\r\n            marketType=\"SPOT\",\r\n            side=\"BUY\",\r\n            apiKeyId=default_api['id'],\r\n            orderNotional=amount_usd,\r\n            startTime=start_time,\r\n            endTime=end_time,\r\n            strategyType=\"PASSIVE\",      # \u88ab\u52a8\u7b56\u7565\uff0c\u51cf\u5c11\u5e02\u573a\u5f71\u54cd\r\n            makerRateLimit=0.5,          # 50% Maker \u8ba2\u5355\r\n            povLimit=0.05,               # \u6700\u591a\u5360\u5e02\u573a\u6210\u4ea4\u91cf 5%\r\n            mustComplete=False,          # \u4e0d\u5f3a\u5236\u5b8c\u6210\uff0c\u907f\u514d\u6ed1\u70b9\r\n            upTolerance=\"0.02\",          # 2% \u5bb9\u5fcd\u5ea6\r\n            lowTolerance=\"0.05\",         # 5% \u5bb9\u5fcd\u5ea6\r\n            notes=f\"VWAP \u7b56\u7565 - {symbol}\"\r\n        )\r\n        \r\n        if response.get('success'):\r\n            logger.info(f\"VWAP \u8ba2\u5355\u521b\u5efa\u6210\u529f: {response['masterOrderId']}\")\r\n            return response['masterOrderId']\r\n        else:\r\n            raise ValueError(f\"\u8ba2\u5355\u521b\u5efa\u5931\u8d25: {response.get('message')}\")\r\n            \r\n    except Exception as e:\r\n        logger.error(f\"\u6267\u884c VWAP \u7b56\u7565\u5931\u8d25: {str(e)}\")\r\n        raise\r\n\r\n# \u4f7f\u7528\u793a\u4f8b\r\nmaster_order_id = execute_vwap_strategy(\r\n    client,\r\n    symbol=\"ETHUSDT\",\r\n    amount_usd=5000,\r\n    duration_hours=6\r\n)\r\n```\r\n\r\n## API \u6587\u6863\r\n\r\n\u5b8c\u6574\u7684 API \u6587\u6863\u8bf7\u53c2\u8003 [Quantum Execute API \u6587\u6863](https://docs.quantumexecute.com)\r\n\r\n## \u652f\u6301\u7684\u7b97\u6cd5\u7c7b\u578b\r\n\r\n- **TWAP (Time Weighted Average Price)**: \u65f6\u95f4\u52a0\u6743\u5e73\u5747\u4ef7\u683c\u7b97\u6cd5\uff0c\u5728\u6307\u5b9a\u65f6\u95f4\u6bb5\u5185\u5e73\u5747\u5206\u914d\u8ba2\u5355\r\n- **VWAP (Volume Weighted Average Price)**: \u6210\u4ea4\u91cf\u52a0\u6743\u5e73\u5747\u4ef7\u683c\u7b97\u6cd5\uff0c\u6839\u636e\u5e02\u573a\u6210\u4ea4\u91cf\u5206\u5e03\u6267\u884c\u8ba2\u5355\r\n- **POV (Percentage of Volume)**: \u6210\u4ea4\u91cf\u767e\u5206\u6bd4\u7b97\u6cd5\uff0c\u4fdd\u6301\u5360\u5e02\u573a\u6210\u4ea4\u91cf\u7684\u56fa\u5b9a\u6bd4\u4f8b\r\n- **IMPLEMENTATION_SHORTFALL**: \u6267\u884c\u7f3a\u53e3\u7b97\u6cd5\uff0c\u6700\u5c0f\u5316\u6267\u884c\u6210\u672c\r\n\r\n## \u6700\u4f73\u5b9e\u8df5\r\n\r\n### 1. API \u5bc6\u94a5\u7ba1\u7406\r\n\r\n```python\r\ndef check_api_health(client):\r\n    \"\"\"\u68c0\u67e5 API \u5bc6\u94a5\u5065\u5eb7\u72b6\u6001\"\"\"\r\n    apis = client.list_exchange_apis()\r\n    \r\n    for api in apis['items']:\r\n        if not api['isValid']:\r\n            print(f\"\u26a0\ufe0f  \u8b66\u544a: API '{api['accountName']}' \u72b6\u6001\u5f02\u5e38\")\r\n        \r\n        if api['balance'] < 100:\r\n            print(f\"\u26a0\ufe0f  \u8b66\u544a: \u8d26\u6237 '{api['accountName']}' \u4f59\u989d\u4e0d\u8db3 (${api['balance']:.2f})\")\r\n        \r\n        if not api['isTradingEnabled']:\r\n            print(f\"\u2139\ufe0f  \u63d0\u793a: API '{api['accountName']}' \u672a\u5f00\u542f\u4ea4\u6613\u6743\u9650\")\r\n```\r\n\r\n### 2. \u8ba2\u5355\u53c2\u6570\u9a8c\u8bc1\r\n\r\n```python\r\ndef validate_order_params(params):\r\n    \"\"\"\u9a8c\u8bc1\u8ba2\u5355\u53c2\u6570\"\"\"\r\n    errors = []\r\n    \r\n    # \u5fc5\u586b\u53c2\u6570\u68c0\u67e5\r\n    required = ['algorithm', 'exchange', 'symbol', 'marketType', 'side', 'apiKeyId']\r\n    for field in required:\r\n        if not params.get(field):\r\n            errors.append(f\"\u7f3a\u5c11\u5fc5\u586b\u53c2\u6570: {field}\")\r\n    \r\n    # \u6570\u91cf\u9a8c\u8bc1\r\n    if not params.get('totalQuantity') and not params.get('orderNotional'):\r\n        errors.append(\"\u5fc5\u987b\u6307\u5b9a totalQuantity \u6216 orderNotional\")\r\n    \r\n    # \u65f6\u95f4\u9a8c\u8bc1\r\n    if params.get('startTime') and params.get('endTime'):\r\n        start = datetime.fromisoformat(params['startTime'].rstrip('Z'))\r\n        end = datetime.fromisoformat(params['endTime'].rstrip('Z'))\r\n        if start >= end:\r\n            errors.append(\"\u5f00\u59cb\u65f6\u95f4\u5fc5\u987b\u65e9\u4e8e\u7ed3\u675f\u65f6\u95f4\")\r\n    \r\n    # \u5bb9\u5fcd\u5ea6\u9a8c\u8bc1\r\n    for field in ['upTolerance', 'lowTolerance']:\r\n        if field in params:\r\n            try:\r\n                val = float(params[field])\r\n                if val < 0 or val > 1:\r\n                    errors.append(f\"{field} \u5fc5\u987b\u5728 0-1 \u4e4b\u95f4\")\r\n            except ValueError:\r\n                errors.append(f\"{field} \u5fc5\u987b\u662f\u6709\u6548\u7684\u6570\u5b57\")\r\n    \r\n    return errors\r\n```\r\n\r\n### 3. \u91cd\u8bd5\u673a\u5236\r\n\r\n```python\r\nimport time\r\nfrom functools import wraps\r\n\r\ndef retry_on_error(max_retries=3, delay=1):\r\n    \"\"\"\u88c5\u9970\u5668\uff1a\u81ea\u52a8\u91cd\u8bd5\u5931\u8d25\u7684\u8bf7\u6c42\"\"\"\r\n    def decorator(func):\r\n        @wraps(func)\r\n        def wrapper(*args, **kwargs):\r\n            last_error = None\r\n            for attempt in range(max_retries):\r\n                try:\r\n                    return func(*args, **kwargs)\r\n                except APIError as e:\r\n                    last_error = e\r\n                    # \u4e0d\u91cd\u8bd5\u5ba2\u6237\u7aef\u9519\u8bef\r\n                    if 400 <= e.code < 500:\r\n                        raise\r\n                    # \u670d\u52a1\u5668\u9519\u8bef\uff0c\u7b49\u5f85\u540e\u91cd\u8bd5\r\n                    if attempt < max_retries - 1:\r\n                        wait_time = delay * (2 ** attempt)  # \u6307\u6570\u9000\u907f\r\n                        logger.warning(f\"\u8bf7\u6c42\u5931\u8d25\uff0c{wait_time}\u79d2\u540e\u91cd\u8bd5...\")\r\n                        time.sleep(wait_time)\r\n                except Exception as e:\r\n                    last_error = e\r\n                    if attempt < max_retries - 1:\r\n                        time.sleep(delay)\r\n            \r\n            raise last_error\r\n        return wrapper\r\n    return decorator\r\n\r\n# \u4f7f\u7528\u793a\u4f8b\r\n@retry_on_error(max_retries=3, delay=2)\r\ndef create_order_with_retry(client, **params):\r\n    return client.create_master_order(**params)\r\n```\r\n\r\n## \u5e38\u89c1\u95ee\u9898\r\n\r\n### 1. \u5982\u4f55\u83b7\u53d6 API \u5bc6\u94a5\uff1f\r\n\r\n\u8bf7\u767b\u5f55 Quantum Execute \u5e73\u53f0\uff0c\u5728\u7528\u6237\u8bbe\u7f6e\u4e2d\u521b\u5efa API \u5bc6\u94a5\u3002\u786e\u4fdd\u4fdd\u7ba1\u597d\u60a8\u7684\u5bc6\u94a5\uff0c\u4e0d\u8981\u5c06\u5176\u63d0\u4ea4\u5230\u7248\u672c\u63a7\u5236\u7cfb\u7edf\u4e2d\u3002\r\n\r\n### 2. \u65f6\u95f4\u6233\u9519\u8bef\u600e\u4e48\u5904\u7406\uff1f\r\n\r\n\u5982\u679c\u9047\u5230\u65f6\u95f4\u6233\u76f8\u5173\u7684\u9519\u8bef\uff0c\u53ef\u80fd\u662f\u60a8\u7684\u7cfb\u7edf\u65f6\u95f4\u4e0e\u670d\u52a1\u5668\u65f6\u95f4\u4e0d\u540c\u6b65\u3002\u8bf7\u786e\u4fdd\u7cfb\u7edf\u65f6\u95f4\u51c6\u786e\u3002\r\n\r\n### 3. \u5982\u4f55\u5904\u7406\u5927\u91cf\u6570\u636e\u7684\u5206\u9875\uff1f\r\n\r\n```python\r\ndef get_all_data(fetch_func, **params):\r\n    \"\"\"\u901a\u7528\u7684\u5206\u9875\u6570\u636e\u83b7\u53d6\u51fd\u6570\"\"\"\r\n    all_items = []\r\n    page = 1\r\n    page_size = 100\r\n    \r\n    while True:\r\n        result = fetch_func(page=page, pageSize=page_size, **params)\r\n        all_items.extend(result['items'])\r\n        \r\n        if len(result['items']) < page_size:\r\n            break\r\n        page += 1\r\n    \r\n    return all_items\r\n\r\n# \u4f7f\u7528\u793a\u4f8b\r\nall_orders = get_all_data(client.get_master_orders, status=\"COMPLETED\")\r\nall_fills = get_all_data(client.get_order_fills, symbol=\"BTCUSDT\")\r\n```\r\n\r\n### 4. \u5982\u4f55\u8bbe\u7f6e\u8ba2\u5355\u7684\u65f6\u95f4\uff1f\r\n\r\n\u65f6\u95f4\u683c\u5f0f\u4f7f\u7528 ISO 8601 \u6807\u51c6\uff0c\u4f8b\u5982\uff1a\r\n- UTC \u65f6\u95f4\uff1a`2024-01-01T10:00:00Z`\r\n- \u5e26\u65f6\u533a\uff1a`2024-01-01T18:00:00+08:00`\r\n\r\n```python\r\nfrom datetime import datetime, timezone\r\n\r\n# \u83b7\u53d6\u5f53\u524d UTC \u65f6\u95f4\r\nnow_utc = datetime.now(timezone.utc).isoformat()\r\n\r\n# \u8f6c\u6362\u672c\u5730\u65f6\u95f4\u5230 UTC\r\nlocal_time = datetime.now()\r\nutc_time = local_time.astimezone(timezone.utc).isoformat()\r\n```\r\n\r\n### 5. \u5bb9\u5fcd\u5ea6\u53c2\u6570\u8bf4\u660e\r\n\r\n- `upTolerance`\uff1a\u5141\u8bb8\u8d85\u51fa\u8ba1\u5212\u8fdb\u5ea6\u7684\u5bb9\u5fcd\u5ea6\uff0c\u5982 \"0.1\" \u8868\u793a\u5141\u8bb8\u8d85\u51fa 10%\r\n- `lowTolerance`\uff1a\u5141\u8bb8\u843d\u540e\u8ba1\u5212\u8fdb\u5ea6\u7684\u5bb9\u5fcd\u5ea6\r\n- `strictUpBound`\uff1a\u662f\u5426\u4e25\u683c\u9650\u5236\u5728 upTolerance \u4ee5\u5185\uff0c\u5f00\u542f\u540e\u53ef\u80fd\u5bfc\u81f4\u5c0f\u8ba2\u5355\u88ab\u8fc7\u5ea6\u62c6\u5206\r\n\r\n## \u793a\u4f8b\u4ee3\u7801\r\n\r\n\u66f4\u591a\u793a\u4f8b\u4ee3\u7801\u8bf7\u53c2\u8003 [examples](./examples) \u76ee\u5f55\uff1a\r\n\r\n- [\u6dfb\u52a0\u4ea4\u6613\u6240 API](examples/user/add_exchange_api.py)\r\n- [\u521b\u5efa\u4e3b\u8ba2\u5355](examples/user/create_master_order.py)\r\n- [\u53d6\u6d88\u4e3b\u8ba2\u5355](examples/user/cancel_master_order.py)\r\n- [\u67e5\u8be2\u8ba2\u5355\u5217\u8868](examples/user/get_master_orders.py)\r\n- [\u67e5\u8be2\u6210\u4ea4\u660e\u7ec6](examples/user/get_order_fills.py)\r\n\r\n## \u5f00\u53d1\u548c\u6d4b\u8bd5\r\n\r\n### \u5b89\u88c5\u5f00\u53d1\u4f9d\u8d56\r\n\r\n```bash\r\npip install -r requirements/requirements-dev.txt\r\n```\r\n\r\n### \u8fd0\u884c\u6d4b\u8bd5\r\n\r\n```bash\r\npython -m pytest tests/\r\n```\r\n\r\n### \u4ee3\u7801\u683c\u5f0f\u5316\r\n\r\n```bash\r\nblack qe/\r\nflake8 qe/\r\n```\r\n\r\n## \u8d21\u732e\u6307\u5357\r\n\r\n\u6b22\u8fce\u63d0\u4ea4 Issue \u548c Pull Request\uff01\u8bf7\u786e\u4fdd\uff1a\r\n\r\n1. \u4ee3\u7801\u7b26\u5408 PEP 8 \u89c4\u8303\r\n2. \u6dfb\u52a0\u9002\u5f53\u7684\u6d4b\u8bd5\r\n3. \u66f4\u65b0\u76f8\u5173\u6587\u6863\r\n\r\n## \u66f4\u65b0\u65e5\u5fd7\r\n\r\n### v1.0.0 (2024-01-01)\r\n- \u521d\u59cb\u7248\u672c\u53d1\u5e03\r\n- \u652f\u6301\u5b8c\u6574\u7684 Quantum Execute API\r\n- \u652f\u6301\u591a\u79cd\u8ba4\u8bc1\u65b9\u5f0f\r\n- \u5b8c\u5584\u7684\u9519\u8bef\u5904\u7406\r\n\r\n## \u8bb8\u53ef\u8bc1\r\n\r\n\u672c\u9879\u76ee\u91c7\u7528 MIT \u8bb8\u53ef\u8bc1 - \u8be6\u89c1 [LICENSE](LICENSE) \u6587\u4ef6\u3002\r\n\r\n## \u8054\u7cfb\u6211\u4eec\r\n\r\n- \u5b98\u7f51\uff1a[https://test.quantumexecute.com](https://test.quantumexecute.com)\r\n- \u90ae\u7bb1\uff1asupport@quantumexecute.com\r\n- GitHub\uff1a[https://github.com/Quantum-Execute/qe-connector-python](https://github.com/Quantum-Execute/qe-connector-python)\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "This is a lightweight library that works as a connector to Quantum Execute public API.",
    "version": "1.0.1",
    "project_urls": {
        "Homepage": "https://github.com/Quantum-Execute/qe-connector-python"
    },
    "split_keywords": [
        "quantum-execute",
        " public api"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "bf46d5f0a99a28003254cc1ae8d02b67a75e2dc89609be8294fcab3e85a9d5a7",
                "md5": "c3331affc1b870b0d43b82d94ae2bc1c",
                "sha256": "b3f77737eab7432660e620fcd840751df8d2930a4d11e3bde46e951c51c493ca"
            },
            "downloads": -1,
            "filename": "qe_connector-1.0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c3331affc1b870b0d43b82d94ae2bc1c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 20500,
            "upload_time": "2025-08-17T13:01:30",
            "upload_time_iso_8601": "2025-08-17T13:01:30.585145Z",
            "url": "https://files.pythonhosted.org/packages/bf/46/d5f0a99a28003254cc1ae8d02b67a75e2dc89609be8294fcab3e85a9d5a7/qe_connector-1.0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "88dadebe587b57bd0815994dc86e4f5c0a05159bb2b8658b353d33b0fb030caf",
                "md5": "146a3c59bfcbb7a62198f6d148f186bf",
                "sha256": "ded6e9c89c0298964460f0ef2b7c5c5f3e578e49e0eeff023954d5c32d5aa123"
            },
            "downloads": -1,
            "filename": "qe-connector-1.0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "146a3c59bfcbb7a62198f6d148f186bf",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 36586,
            "upload_time": "2025-08-17T13:01:33",
            "upload_time_iso_8601": "2025-08-17T13:01:33.176468Z",
            "url": "https://files.pythonhosted.org/packages/88/da/debe587b57bd0815994dc86e4f5c0a05159bb2b8658b353d33b0fb030caf/qe-connector-1.0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-17 13:01:33",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Quantum-Execute",
    "github_project": "qe-connector-python",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "tox": true,
    "lcname": "qe-connector"
}
        
Elapsed time: 1.25520s