qe-connector


Nameqe-connector JSON
Version 1.0.6 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-09-14 17:58:25
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、POV 等算法)
- ✅ 订单查询和成交明细
- ✅ ListenKey 创建与管理
- ✅ 交易对信息查询
- ✅ 服务器连通性测试
- ✅ 服务器时间同步
- ✅ 安全的 HMAC-SHA256 签名认证
- ✅ 支持生产环境和测试环境
- ✅ 链式调用 API 设计
- ✅ 完整的错误处理

## 安装

```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"
)
```

### 使用枚举类型(推荐)

SDK 提供了枚举类型来确保类型安全和代码提示。推荐使用枚举而不是字符串:

```python
# 导入枚举类型
from qe.lib import Algorithm, Exchange, MarketType, OrderSide, StrategyType, MarginType

# 可用的枚举值
print("算法类型:", [algo.value for algo in Algorithm])           # ['TWAP', 'VWAP', 'POV']
print("交易所:", [exchange.value for exchange in Exchange])     # ['Binance']
print("市场类型:", [market.value for market in MarketType])     # ['SPOT', 'PERP']
print("订单方向:", [side.value for side in OrderSide])         # ['buy', 'sell']
print("策略类型:", [strategy.value for strategy in StrategyType]) # ['TWAP_1', 'POV']
print("保证金类型:", [margin.value for margin in MarginType])   # ['U']

# 使用枚举创建订单(推荐)
response = client.create_master_order(
    algorithm=Algorithm.TWAP,        # 而不是 "TWAP"
    exchange=Exchange.BINANCE,       # 而不是 "Binance"
    marketType=MarketType.SPOT,      # 而不是 "SPOT"
    side=OrderSide.BUY,             # 而不是 "buy"
    # ... 其他参数
)
```

## API 参考

### 公共接口

#### 服务器连通性测试

##### Ping 服务器

测试与 Quantum Execute 服务器的连通性。

**请求参数:**

| 参数名 | 类型 | 是否必传 | 描述 |
|--------|------|----------|------|
| 无需参数 | - | - | - |

**响应:**

成功时无返回内容,失败时返回错误信息。

**示例代码:**

```python
from qe.status import Status as StatusClient

# 创建状态客户端(无需认证)
status_client = StatusClient()

# 测试服务器连通性
try:
    status_client.ping()
    print("服务器连接正常")
except Exception as e:
    print(f"服务器连接失败: {e}")
```

#### 获取服务器时间

##### 查询服务器时间戳

获取 Quantum Execute 服务器的当前时间戳(毫秒)。

**请求参数:**

| 参数名 | 类型 | 是否必传 | 描述 |
|--------|------|----------|------|
| 无需参数 | - | - | - |

**响应字段:**

| 字段名 | 类型 | 描述 |
|--------|------|------|
| serverTimeMilli | int | 服务器时间戳(毫秒) |

**示例代码:**

```python
from qe.status import Status as StatusClient
import datetime

# 创建状态客户端
status_client = StatusClient()

# 获取服务器时间戳
try:
    timestamp = status_client.timestamp()
    print(f"服务器时间戳: {timestamp}")
    
    # 转换为可读时间格式
    readable_time = datetime.datetime.fromtimestamp(timestamp / 1000)
    print(f"服务器时间: {readable_time}")
except Exception as e:
    print(f"获取时间戳失败: {e}")
```

#### 交易对管理

##### 查询交易对列表

获取支持的交易对信息,包括现货和合约交易对。

**请求参数:**

| 参数名 | 类型 | 是否必传 | 描述 |
|--------|------|----------|------|
| page | int | 否 | 页码 |
| pageSize | int | 否 | 每页数量 |
| exchange | str | 否 | 交易所名称筛选 |
| marketType | str/TradingPairMarketType | 否 | 市场类型筛选,可选值:SPOT(现货)、FUTURES(合约) |
| isCoin | bool | 否 | 是否为币种筛选 |

**响应字段:**

| 字段名 | 类型 | 描述 |
|--------|------|------|
| items | array | 交易对列表 |
| ├─ id | int | 交易对 ID |
| ├─ symbol | string | 交易对符号(如:BTCUSDT) |
| ├─ baseAsset | string | 基础币种(如:BTC) |
| ├─ quoteAsset | string | 计价币种(如:USDT) |
| ├─ exchange | string | 交易所名称 |
| ├─ marketType | string | 市场类型(SPOT/FUTURES) |
| ├─ contractType | string | 合约类型(仅合约交易对) |
| ├─ deliveryDate | string | 交割日期(仅合约交易对) |
| ├─ status | string | 交易对状态 |
| ├─ createdAt | string | 创建时间 |
| ├─ updatedAt | string | 更新时间 |
| page | int | 当前页码 |
| pageSize | int | 每页数量 |
| total | string | 总数 |

**示例代码:**

```python
from qe.pub import Pub as PubClient
from qe.lib import TradingPairMarketType

# 创建公共客户端(无需认证)
pub_client = PubClient()

# 获取所有交易对
try:
    pairs = pub_client.trading_pairs()
    print(f"总交易对数量: {pairs.get('total', 0)}")
    
    # 打印前几个交易对信息
    for pair in pairs.get('items', [])[:5]:
        print(f"""
交易对信息:
    符号: {pair['symbol']}
    基础币种: {pair['baseAsset']}
    计价币种: {pair['quoteAsset']}
    交易所: {pair['exchange']}
    市场类型: {pair['marketType']}
    状态: {pair['status']}
    创建时间: {pair['createdAt']}
        """)
        
        # 如果是合约交易对,显示额外信息
        if pair['marketType'] == 'FUTURES':
            print(f"    合约类型: {pair.get('contractType', 'N/A')}")
            if pair.get('deliveryDate'):
                print(f"    交割日期: {pair['deliveryDate']}")
                
except Exception as e:
    print(f"获取交易对失败: {e}")

# 使用枚举类型筛选(推荐)
try:
    # 获取币安现货交易对
    spot_pairs = pub_client.trading_pairs(
        exchange="Binance",
        marketType=TradingPairMarketType.SPOT,  # 使用枚举
        page=1,
        pageSize=10
    )
    print(f"币安现货交易对数量: {len(spot_pairs.get('items', []))}")
    
    # 获取合约交易对
    futures_pairs = pub_client.trading_pairs(
        marketType=TradingPairMarketType.FUTURES,  # 使用枚举
        page=1,
        pageSize=20
    )
    print(f"合约交易对数量: {len(futures_pairs.get('items', []))}")
    
    # 获取币种交易对
    coin_pairs = pub_client.trading_pairs(isCoin=True)
    print(f"币种交易对数量: {len(coin_pairs.get('items', []))}")
    
except Exception as e:
    print(f"筛选交易对失败: {e}")

# 使用字符串筛选(向后兼容)
try:
    # 使用字符串参数
    spot_pairs = pub_client.trading_pairs(
        exchange="Binance",
        marketType="SPOT",  # 使用字符串
        page=1,
        pageSize=5
    )
    print(f"现货交易对数量: {len(spot_pairs.get('items', []))}")
    
except Exception as e:
    print(f"获取现货交易对失败: {e}")
```

### 交易所 API 管理

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

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

**请求参数:**

| 参数名 | 类型 | 是否必传 | 描述 |
|--------|------|----------|------|
| page | int | 否 | 页码 |
| pageSize | int | 否 | 每页数量 |
| exchange | str | 否 | 交易所名称筛选 |

**响应字段:**

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

**示例代码:**

```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"
)
```

### 交易订单管理

#### 创建主订单

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

**请求参数:**

| 参数名 | 类型 | 是否必传 | 描述 |
|--------|------|------|------|
| **基础参数** |
| strategyType | string/StrategyType | 是    | 策略类型,可选值:TWAP-1、POV |
| algorithm | string/Algorithm | 是    | 交易算法。strategyType=TWAP-1时,可选值:TWAP、VWAP;strategyType=POV时,可选值:POV |
| exchange | string/Exchange | 是    | 交易所名称,可选值:Binance |
| symbol | string | 是    | 交易对符号(如:BTCUSDT)(可用交易对查询) |
| marketType | string/MarketType | 是    | 可选值:SPOT(现货)、PERP(永续合约) |
| side | string/OrderSide | 是    | 1.如果isTargetPosition=False:side代表交易方向,可选值:buy(买入)、sell(卖出);合约交易时可与reduceOnly组合,reduceOnly=True时:buy代表买入平空,sell代表卖出平多。2.如果isTargetPosition=True:side代表仓位方向,可选值:buy(多头)、sell(空头)。【仅合约交易时需传入】 |
| apiKeyId | string | 是    | 指定使用的 API Key ID,这将决定您本次下单使用哪个交易所账户执行 |
| **数量参数(二选一)** |
| totalQuantity | float64 | 否*   | 要交易的总数量,支持字符串表示以避免精度问题,与 orderNotional 二选一,输入范围:>0 |
| orderNotional | float64 | 否*   | 按价值下单时的金额,以计价币种为单位(如ETHUSDT为USDT数量),与 totalQuantity 二选一,输入范围:>0 |
| **下单模式参数** |
| isTargetPosition | bool | 否    | 是否为目标仓位下单,默认为 false |
| **时间参数** |
| startTime | string | 否    | 交易执行的启动时间,传入格式:ISO 8601(2025-09-03T01:30:00+08:00),若不传入,则立即执行 |
| executionDuration | int32 | 否    | 订单最大执行时长,分钟,范围>=1 |
| **TWAP/VWAP 算法参数** |
| mustComplete | bool | 否    | 是否一定要在executionDuration之内执行完毕,选false则不会追赶进度,默认:true |
| makerRateLimit | float64 | 否    | 要求maker占比超过该值,输入范围:0-1(输入0.1代表10%),默认:-1(算法智能计算推荐值执行) |
| povLimit | string | 否    | 占市场成交量比例上限,优先级低于mustComplete,输入范围:0-1(输入0.1代表10%),默认:0.8 |
| limitPrice | float64 | 否    | 最高/低允许交易的价格,买入时该字段象征最高买入价,卖出时该字段象征最低卖出价,若市价超出范围则停止交易,范围:>0,默认:-1,代表无限制 |
| upTolerance | string | 否    | 允许超出目标进度的最大容忍度,比如0.1就是执行过程中允许比目标进度超出母单数量的10%,范围:0-1(不含0、1),默认:-1(即无容忍) |
| lowTolerance | string | 否    | 允许落后目标进度的最大容忍度,比如0.1就是执行过程中允许比目标进度落后母单数量的10%,范围:0-1(不含0、1),默认:-1(即无容忍) |
| strictUpBound | bool | 否    | 表达是否追求严格小于uptolerance,开启后可能会把很小的母单也拆的很细,不建议开启,默认:false |
| tailOrderProtection | bool | 否    | 订单余量小于交易所最小发单量时,是否必须taker扫完,如果false,则订单余量小于交易所最小发单量时,订单结束执行;如果true,则订单余量随最近一笔下单全额执行(可能会提高Taker率),默认:true |
| **POV 算法参数** |
| makerRateLimit | float64 | 否    | 要求maker占比超过该值,输入范围:0-1(输入0.1代表10%),默认:-1(算法智能计算推荐值执行) |
| povLimit | string | 否    | 占市场成交量比例上限,输入范围:0-0.5(povMinLimit < max(povLimit-0.01,0)),默认:0 |
| povMinLimit | float64 | 否    | 占市场成交量比例下限,范围:小于max(POVLimit-0.01,0),默认:0(即无下限) |
| limitPrice | float64 | 否    | 最高/低允许交易的价格,买入时该字段象征最高买入价,卖出时该字段象征最低卖出价,若市价超出范围则停止交易,范围:>0,默认:-1,代表无限制 |
| strictUpBound | bool | 否    | 是否追求严格小于povLimit,开启后可能会把很小的母单也拆的很细,比如50u拆成10个5u,不建议开启,算法的每个order会权衡盘口流动性,默认:false |
| tailOrderProtection | bool | 否    | 订单余量小于交易所最小发单量时,是否必须taker扫完,如果false,则订单余量小于交易所最小发单量时,订单结束执行;如果true,则订单余量随最近一笔下单全额执行(可能会提高Taker率),默认:true |
| **其他参数** |
| reduceOnly | bool | 否    | 合约交易时是否仅减仓,默认值:false |
| marginType | string/MarginType | 否    | 合约交易保证金类型,可选值:U(U本位),默认:U(暂时只支持U本位永续合约) |
| notes | string | 否    | 订单备注 |

*注:totalQuantity 和 orderNotional 必须传其中一个,但当 isTargetPosition 为 true 时,totalQuantity 必填代表目标仓位数量且 orderNotional 不可填  

**响应字段:**

| 字段名 | 类型 | 描述 |
|--------|------|------|
| masterOrderId | string | 创建成功的主订单 ID |
| success | bool | 创建是否成功 |
| message | string | 创建结果消息 |

**示例代码:**

```python
# 导入枚举类型(推荐方式)
from qe.lib import Algorithm, Exchange, MarketType, OrderSide, StrategyType, MarginType

# TWAP 订单示例 - 使用枚举创建订单(推荐)
response = client.create_master_order(
    algorithm=Algorithm.TWAP,                      # 使用算法枚举
    exchange=Exchange.BINANCE,                     # 使用交易所枚举
    symbol="BTCUSDT",
    marketType=MarketType.SPOT,                    # 使用市场类型枚举
    side=OrderSide.BUY,                           # 使用订单方向枚举
    apiKeyId="your-api-key-id",                   # 从 list_exchange_apis 获取
    orderNotional="200",                          # $200 名义价值
    strategyType=StrategyType.TWAP_1,             # 使用策略类型枚举
    startTime="2025-09-02T19:54:34+08:00",
    endTime="2025-09-03T01:44:35+08:00",
    executionDuration="5",                        # 5 秒间隔
    mustComplete=True,                            # 必须完成全部订单
    worstPrice=-1,                               # -1 表示无价格限制
    upTolerance="-1",                            # 允许超出容忍度
    lowTolerance="-1",                           # 允许落后容忍度
    tailOrderProtection=True,                    # 尾单保护
    notes="测试 TWAP 订单"                       # 订单备注
)

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

**目标仓位下单示例:**

```python
# 目标仓位下单示例 - 买入 1.5 BTC 到目标仓位
response = client.create_master_order(
    algorithm=Algorithm.TWAP,                      # 使用算法枚举
    exchange=Exchange.BINANCE,                     # 使用交易所枚举
    symbol="BTCUSDT",
    marketType=MarketType.SPOT,                    # 使用市场类型枚举
    side=OrderSide.BUY,                           # 使用订单方向枚举
    apiKeyId="your-api-key-id",                   # 从 list_exchange_apis 获取
    totalQuantity="1.5",                          # 目标数量 1.5 BTC
    isTargetPosition=True,                        # 启用目标仓位模式
    strategyType=StrategyType.TWAP_1,             # 使用策略类型枚举
    startTime="2025-09-02T19:54:34+08:00",
    endTime="2025-09-03T01:44:35+08:00",
    executionDuration=60,                         # 60 分钟
    mustComplete=True,                            # 必须完成全部订单
    limitPrice="65000",                           # 最高价格 $65,000
    upTolerance="0.1",                            # 允许超出 10%
    lowTolerance="0.1",                           # 允许落后 10%
    tailOrderProtection=True,                     # 尾单保护
    notes="目标仓位订单示例"                      # 订单备注
)

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

**POV 合约订单示例:**

```python
# POV 合约订单示例 - 使用枚举
response = client.create_master_order(
    algorithm=Algorithm.POV,                       # POV 算法
    exchange=Exchange.BINANCE,
    symbol="BTCUSDT",
    marketType=MarketType.PERP,                    # 合约市场
    side=OrderSide.SELL,                          # 卖出
    apiKeyId="your-api-key-id",
    orderNotional="1000",                         # $1000 名义价值
    strategyType=StrategyType.POV,                # POV 策略
    startTime="2025-09-02T19:54:34+08:00",
    endTime="2025-09-03T01:44:35+08:00",
    povLimit=0.2,                                 # 占市场成交量 20%
    povMinLimit=0.05,                             # 最低占市场成交量 5%
    marginType=MarginType.U,                      # U本位保证金
    reduceOnly=False,
    mustComplete=True,
    notes="POV 合约订单示例"
)

if response.get('success'):
    print(f"POV 订单创建成功,ID: {response['masterOrderId']}")
```

#### 查询主订单列表

获取用户的主订单列表。

**请求参数:**

| 参数名 | 类型 | 是否必传 | 描述 |
|--------|------|----------|------|
| page | int32 | 否 | 页码 |
| pageSize | int32 | 否 | 每页数量 |
| status | string | 否 | 订单状态筛选,可选值:NEW(执行中)、COMPLETED(已完成) |
| exchange | string | 否 | 交易所名称筛选 |
| symbol | string | 否 | 交易对筛选 |
| startTime | string | 否 | 开始时间筛选 |
| endTime | string | 否 | 结束时间筛选 |

**响应字段:**

| 字段名 | 类型 | 描述 |
|--------|------|------|
| items | array | 主订单列表 |
| ├─ masterOrderId | string | 主订单 ID |
| ├─ algorithm | string | 算法 |
| ├─ algorithmType | string | 算法类型 |
| ├─ exchange | string | 交易所 |
| ├─ symbol | string | 交易对 |
| ├─ marketType | string | 市场类型 |
| ├─ side | string | 买卖方向 |
| ├─ totalQuantity | string | 总数量 |
| ├─ filledQuantity | string | 已成交数量 |
| ├─ averagePrice | float64 | 平均成交价 |
| ├─ status | string | 状态:NEW(创建,未执行)、WAITING(等待中)、PROCESSING(执行中,且未完成)、PAUSED(已暂停)、CANCEL(取消中)、CANCELLED(已取消)、COMPLETED(已完成)、REJECTED(已拒绝)、EXPIRED(已过期)、CANCEL_REJECT(取消被拒绝) |
| ├─ executionDuration | int32 | 执行时长(分钟) |
| ├─ priceLimit | float64 | 价格限制 |
| ├─ startTime | string | 开始时间 |
| ├─ endTime | string | 结束时间 |
| ├─ createdAt | string | 创建时间 |
| ├─ updatedAt | string | 更新时间 |
| ├─ notes | string | 备注 |
| ├─ marginType | string | 保证金类型(U:U本位) |
| ├─ reduceOnly | bool | 是否仅减仓 |
| ├─ strategyType | string | 策略类型 |
| ├─ orderNotional | string | 订单金额(USDT) |
| ├─ mustComplete | bool | 是否必须完成 |
| ├─ makerRateLimit | string | 最低 Maker 率 |
| ├─ povLimit | string | 最大市场成交量占比 |
| ├─ clientId | string | 客户端 ID |
| ├─ date | string | 发单日期(格式:YYYYMMDD) |
| ├─ ticktimeInt | string | 发单时间(格式:093000000 表示 9:30:00.000) |
| ├─ limitPriceString | string | 限价(字符串) |
| ├─ upTolerance | string | 上容忍度 |
| ├─ lowTolerance | string | 下容忍度 |
| ├─ strictUpBound | bool | 严格上界 |
| ├─ ticktimeMs | int64 | 发单时间戳(epoch 毫秒) |
| ├─ category | string | 交易品种(spot 或 perp) |
| ├─ filledAmount | float64 | 成交金额 |
| ├─ totalValue | float64 | 成交总值 |
| ├─ base | string | 基础币种 |
| ├─ quote | string | 计价币种 |
| ├─ completionProgress | float64 | 完成进度(0-1) |
| ├─ reason | string | 原因(如取消原因) |
| total | int32 | 总数 |
| page | int32 | 当前页码 |
| pageSize | int32 | 每页数量 |

**示例代码:**

```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']} / {order['totalQuantity']}
    成交金额: ${order.get('filledAmount', 0):.2f}
    创建时间: {order['createdAt']}
    发单日期: {order.get('date', 'N/A')}
    上容忍度: {order.get('upTolerance', 'N/A')}
    下容忍度: {order.get('lowTolerance', 'N/A')}
    """)
```

#### 查询成交记录

获取用户的成交记录。

**请求参数:**

| 参数名 | 类型 | 是否必传 | 描述 |
|--------|------|----------|------|
| page | int32 | 否 | 页码 |
| pageSize | int32 | 否 | 每页数量 |
| masterOrderId | string | 否 | 主订单 ID 筛选 |
| subOrderId | string | 否 | 子订单 ID 筛选 |
| symbol | string | 否 | 交易对筛选 |
| startTime | string | 否 | 开始时间筛选 |
| endTime | string | 否 | 结束时间筛选 |

**响应字段:**

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

**示例代码:**

```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
for fill in fills['items']:
    print(f"""
成交详情:
    时间: {fill['orderCreatedTime']}
    交易对: {fill['symbol']}
    方向: {fill['side']}
    成交价格: ${fill['price']:.2f}
    成交数量: {fill['filledQuantity']}
    成交金额: ${fill['filledValue']:.2f}
    手续费: ${fill['fee']:.4f}
    账户: {fill['tradingAccount']}
    类型: {fill.get('type', 'N/A')}
    """)
    total_value += fill['filledValue']
    total_fee += fill['fee']

print(f"总成交额: ${total_value:.2f}, 总手续费: ${total_fee:.2f}")
```

#### 取消主订单

取消指定的主订单。

**请求参数:**

| 参数名 | 类型 | 是否必传 | 描述 |
|--------|------|----------|------|
| masterOrderId | string | 是 | 要取消的主订单 ID |
| reason | string | 否 | 取消原因 |

**响应字段:**

| 字段名 | 类型 | 描述 |
|--------|------|------|
| success | bool | 取消是否成功 |
| message | string | 取消结果消息 |

**示例代码:**

```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
```

#### 创建 ListenKey

创建一个随机的UUID作为ListenKey,绑定当前用户信息,有效期24小时。ListenKey用于WebSocket连接,可以实时接收用户相关的交易数据推送。

**请求参数:**

| 参数名 | 类型 | 是否必传 | 描述 |
|--------|------|----------|------|
| 无需参数 | - | - | - |

**响应字段:**

| 字段名 | 类型 | 描述 |
|--------|------|------|
| listenKey | string | 生成的ListenKey |
| expireAt | string | ListenKey过期时间戳(秒) |
| success | bool | 创建是否成功 |
| message | string | 创建结果消息 |

**示例代码:**

```python
# 创建 ListenKey
result = client.create_listen_key()

if result.get('success'):
    print(f"ListenKey创建成功:")
    print(f"ListenKey: {result['listenKey']}")
    print(f"过期时间: {result['expireAt']}")
    
    # 使用 ListenKey 建立 WebSocket 连接
    # ws_url = f"wss://api.quantumexecute.com/ws/{result['listenKey']}"
else:
    print(f"ListenKey创建失败:{result.get('message')}")
```

**注意事项:**
- ListenKey 有效期为 24 小时,过期后需要重新创建
- 每个用户同时只能有一个有效的 ListenKey
- ListenKey 用于 WebSocket 连接,可以实时接收交易数据推送
- 建议在应用启动时创建 ListenKey,并在接近过期时重新创建

## 错误处理

SDK 提供了详细的错误信息,包括 API 错误和网络错误:

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

response = client.create_master_order(
    # ... 设置参数
)

if 'error' in response:
    # 检查是否为 API 错误
    error = response['error']
    if isinstance(error, dict) and 'code' in error:
        print(f"API 错误 - 代码: {error['code']}, 原因: {error.get('reason')}, 消息: {error.get('message')}")
        print(f"TraceID: {error.get('trace_id')}")
        
        # 根据错误代码处理
        if error['code'] == 400:
            print("请求参数错误")
        elif error['code'] == 401:
            print("认证失败")
        elif error['code'] == 403:
            print("权限不足")
        elif error['code'] == 429:
            print("请求过于频繁")
        else:
            print(f"其他错误: {error}")
    else:
        print(f"网络或其他错误: {error}")
```

## 高级配置

### 自定义 HTTP 客户端

```python
import requests
import time

# 创建自定义 HTTP 客户端
session = requests.Session()
session.timeout = 30  # 30 秒超时
session.headers.update({
    'User-Agent': 'QE-Python-SDK/1.0.0'
})

client = Client("your-api-key", "your-api-secret")
client.session = session
```

### 使用代理

```python
import requests

proxies = {
    'https': 'http://proxy.example.com:8080'
}

client = Client("your-api-key", "your-api-secret")
client.session.proxies.update(proxies)
```

### 时间偏移调整

如果遇到时间戳错误,可以调整客户端的时间偏移:

```python
# 设置时间偏移(毫秒)
client.time_offset = 1000  # 客户端时间比服务器快 1 秒
```

### 请求重试

```python
import time
import math

# 实现简单的重试逻辑
def retry_request(func, max_retries=3):
    """重试请求函数"""
    for i in range(max_retries):
        try:
            return func()
        except Exception as e:
            if i == max_retries - 1:
                raise e
            
            # 检查是否应该重试
            if hasattr(e, 'code') and 400 <= e.code < 500:
                raise e  # 不重试客户端错误
            
            # 指数退避
            wait_time = math.pow(2, i)
            print(f"请求失败,{wait_time}秒后重试...")
            time.sleep(wait_time)

# 使用重试
def create_order_with_retry():
    return client.create_master_order(
        # ... 设置参数
    )

result = retry_request(create_order_with_retry, max_retries=3)
```

## 最佳实践

### 1. API 密钥管理

```python
# 定期检查 API 密钥状态
def check_api_key_status(client):
    apis = client.list_exchange_apis()
    if not apis.get('items'):
        print("获取 API 列表失败")
        return
    
    for api in apis['items']:
        if not api['isValid']:
            print(f"警告: API {api['id']} ({api['accountName']}) 状态异常")
        if api['balance'] < 100:
            print(f"警告: 账户 {api['accountName']} 余额不足 (${api['balance']:.2f})")
```

### 2. 订单监控

```python
# 监控订单执行状态
def monitor_order(client, master_order_id):
    import time
    
    while True:
        orders = client.get_master_orders(page=1, pageSize=1)
        
        if not orders['items']:
            print("订单不存在")
            return
        
        order = orders['items'][0]
        print(f"订单进度: {order['completionProgress']*100:.2f}%, 状态: {order['status']}")
        
        if order['status'] == "COMPLETED":
            print(f"订单已结束,最终状态: {order['status']}")
            return
        
        time.sleep(10)  # 每 10 秒检查一次
```

### 3. 批量处理

```python
# 批量获取所有订单
def get_all_orders(client):
    all_orders = []
    page = 1
    page_size = 100
    
    while True:
        result = client.get_master_orders(page=page, pageSize=page_size)
        all_orders.extend(result['items'])
        
        # 检查是否还有更多数据
        if len(result['items']) < page_size:
            break
        page += 1
    
    return all_orders
```

### 4. ListenKey 管理

```python
import time
from datetime import datetime

# ListenKey 管理器
class ListenKeyManager:
    def __init__(self, client):
        self.client = client
        self.listen_key = None
        self.expire_at = None
    
    def create_listen_key(self):
        """创建或刷新 ListenKey"""
        result = self.client.create_listen_key()
        
        if not result.get('success'):
            raise Exception(f"创建 ListenKey 失败: {result.get('message')}")
        
        self.listen_key = result['listenKey']
        self.expire_at = int(result['expireAt'])
        
        print(f"ListenKey 创建成功: {self.listen_key}, 过期时间: {self.expire_at}")
        return self.listen_key
    
    def is_expired(self):
        """检查 ListenKey 是否即将过期"""
        if not self.expire_at:
            return True
        # 提前1小时刷新
        return time.time() > self.expire_at - 3600
    
    def auto_refresh(self):
        """自动刷新 ListenKey"""
        if self.is_expired():
            print("ListenKey 即将过期,开始刷新...")
            self.create_listen_key()

# 使用示例
manager = ListenKeyManager(client)
listen_key = manager.create_listen_key()

# 定期检查并刷新
while True:
    manager.auto_refresh()
    time.sleep(1800)  # 每30分钟检查一次
```

### 5. WebSocket 实时数据推送

SDK 提供了完整的 WebSocket 服务,可以实时接收交易数据推送,包括主订单状态更新、子订单变化、成交明细等。

#### 创建 WebSocket 服务

```python
import logging
import time
from qe import API, WebSocketService, WebSocketEventHandlers, MasterOrderMessage, OrderMessage, FillMessage

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def on_connected():
    """连接成功回调"""
    logger.info("WebSocket连接成功")

def on_disconnected():
    """断开连接回调"""
    logger.info("WebSocket连接断开")

def on_error(error):
    """错误回调"""
    logger.error(f"WebSocket错误: {error}")

def on_status(data):
    """状态消息回调"""
    logger.info(f"收到状态消息: {data}")

def on_master_order(message: MasterOrderMessage):
    """主订单消息回调"""
    logger.info(f"收到主订单消息:")
    logger.info(f"  主订单ID: {message.master_order_id}")
    logger.info(f"  客户端ID: {message.client_id}")
    logger.info(f"  策略: {message.strategy}")
    logger.info(f"  交易对: {message.symbol}")
    logger.info(f"  方向: {message.side}")
    logger.info(f"  数量: {message.qty}")
    logger.info(f"  状态: {message.status}")
    logger.info(f"  时间戳: {message.timestamp}")

def on_order(message: OrderMessage):
    """订单消息回调"""
    logger.info(f"收到订单消息:")
    logger.info(f"  主订单ID: {message.master_order_id}")
    logger.info(f"  订单ID: {message.order_id}")
    logger.info(f"  交易对: {message.symbol}")
    logger.info(f"  方向: {message.side}")
    logger.info(f"  价格: {message.price}")
    logger.info(f"  数量: {message.quantity}")
    logger.info(f"  状态: {message.status}")
    logger.info(f"  已成交数量: {message.fill_qty}")
    logger.info(f"  剩余数量: {message.quantity_remaining}")

def on_fill(message: FillMessage):
    """成交消息回调"""
    logger.info(f"收到成交消息:")
    logger.info(f"  主订单ID: {message.master_order_id}")
    logger.info(f"  订单ID: {message.order_id}")
    logger.info(f"  交易对: {message.symbol}")
    logger.info(f"  方向: {message.side}")
    logger.info(f"  成交价格: {message.fill_price}")
    logger.info(f"  成交数量: {message.filled_qty}")
    logger.info(f"  成交时间: {message.fill_time}")

def on_raw_message(message):
    """原始消息回调"""
    logger.debug(f"收到原始消息: {message.type} - {message.data}")

def main():
    """主函数"""
    # 创建API客户端
    api = API(
        api_key="your_api_key",
        api_secret="your_api_secret",
        base_url="https://test.quantumexecute.com"
    )
    
    # 创建WebSocket事件处理器
    handlers = WebSocketEventHandlers(
        on_connected=on_connected,
        on_disconnected=on_disconnected,
        on_error=on_error,
        on_status=on_status,
        on_master_order=on_master_order,
        on_order=on_order,
        on_fill=on_fill,
        on_raw_message=on_raw_message
    )
    
    # 创建WebSocket服务
    ws_service = WebSocketService(api)
    ws_service.set_handlers(handlers)
    
    # 设置连接参数
    ws_service.set_reconnect_delay(5.0)  # 重连延迟5秒
    ws_service.set_ping_interval(30.0)   # 心跳间隔30秒
    ws_service.set_pong_timeout(10.0)    # Pong超时10秒
    
    try:
        # 获取listen_key
        listen_key_result = api.create_listen_key()
        if not listen_key_result.get('success'):
            logger.error(f"创建ListenKey失败: {listen_key_result.get('message')}")
            return
        
        listen_key = listen_key_result['listenKey']
        
        # 连接WebSocket
        logger.info("正在连接WebSocket...")
        ws_service.connect(listen_key)
        
        # 等待连接建立
        time.sleep(2)
        
        if ws_service.is_connected():
            logger.info("WebSocket连接已建立,开始接收消息...")
            
            # 保持连接运行
            try:
                while True:
                    time.sleep(1)
            except KeyboardInterrupt:
                logger.info("收到中断信号,正在关闭连接...")
        else:
            logger.error("WebSocket连接失败")
    
    except Exception as e:
        logger.error(f"发生错误: {e}")
    
    finally:
        # 关闭WebSocket连接
        ws_service.close()
        logger.info("WebSocket连接已关闭")

if __name__ == "__main__":
    main()
```

#### 消息类型说明

**客户端推送消息类型:**

| 消息类型 | 描述 |
|----------|------|
| data | 数据消息 |
| status | 状态消息 |
| error | 错误消息 |
| master_data | 主订单数据 |
| order_data | 订单数据 |

**第三方消息类型:**

| 消息类型 | 描述 |
|----------|------|
| master_order | 主订单消息 |
| order | 子订单消息 |
| fill | 成交消息 |

#### 配置选项

```python
# 设置重连延迟
ws_service.set_reconnect_delay(10.0)  # 10秒

# 设置心跳间隔
ws_service.set_ping_interval(2.0)     # 2秒

# 设置Pong超时时间
ws_service.set_pong_timeout(15.0)     # 15秒

# 设置日志记录器
import logging
logger = logging.getLogger("websocket")
ws_service.set_logger(logger)
```

#### 连接状态管理

```python
# 检查连接状态
if ws_service.is_connected():
    print("WebSocket 已连接")
else:
    print("WebSocket 未连接")

# 手动重连
if not ws_service.is_connected():
    listen_key = "your-listen-key"
    ws_service.connect(listen_key)
```

#### 错误处理

```python
def on_error(error):
    """错误回调"""
    logger.error(f"WebSocket 错误: {error}")
    
    # 根据错误类型进行处理
    if "connection refused" in str(error).lower():
        logger.error("连接被拒绝,可能是服务器不可用")
    elif "authentication failed" in str(error).lower():
        logger.error("认证失败,请检查 ListenKey 是否有效")
    elif "timeout" in str(error).lower():
        logger.error("连接超时,请检查网络连接")
```

#### 生产环境使用建议

1. **自动重连机制**:SDK 已内置自动重连功能,无需手动实现
2. **ListenKey 管理**:定期检查 ListenKey 有效性,接近过期时主动刷新
3. **错误监控**:实现完善的错误日志记录和监控
4. **负载均衡**:考虑使用多个 WebSocket 连接分散负载
5. **消息去重**:根据 `messageId` 实现消息去重处理

#### 高级用法示例

```python
class TradingBot:
    def __init__(self, api_key, api_secret):
        self.api = API(api_key, api_secret)
        self.ws_service = None
        self.listen_key = None
        
    def start_websocket(self):
        """启动WebSocket连接"""
        # 创建ListenKey
        result = self.api.create_listen_key()
        if not result.get('success'):
            raise Exception(f"创建ListenKey失败: {result.get('message')}")
        
        self.listen_key = result['listenKey']
        
        # 创建事件处理器
        handlers = WebSocketEventHandlers(
            on_connected=self._on_connected,
            on_disconnected=self._on_disconnected,
            on_error=self._on_error,
            on_master_order=self._on_master_order,
            on_order=self._on_order,
            on_fill=self._on_fill
        )
        
        # 创建WebSocket服务
        self.ws_service = WebSocketService(self.api)
        self.ws_service.set_handlers(handlers)
        
        # 连接
        self.ws_service.connect(self.listen_key)
        
    def _on_connected(self):
        print("交易机器人已连接")
        
    def _on_disconnected(self):
        print("交易机器人连接断开")
        
    def _on_error(self, error):
        print(f"交易机器人错误: {error}")
        
    def _on_master_order(self, message):
        print(f"主订单更新: {message.master_order_id} - {message.status}")
        
    def _on_order(self, message):
        print(f"子订单更新: {message.order_id} - {message.status}")
        
    def _on_fill(self, message):
        print(f"成交通知: {message.order_id} - {message.filled_qty} @ {message.fill_price}")
        
    def stop(self):
        """停止WebSocket连接"""
        if self.ws_service:
            self.ws_service.close()

# 使用示例
bot = TradingBot("your-api-key", "your-api-secret")
bot.start_websocket()

# 保持运行
try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    print("正在停止...")
    bot.stop()
```

## 常见问题

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

请登录 Quantum Execute 平台,在用户设置中创建 API 密钥。

### 2. 如何处理时间格式?

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

### 3. 订单类型说明

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

### 4. 枚举值说明

**算法类型 (Algorithm):**

| 枚举值 | 描述 |
|--------|------|
| TWAP | TWAP算法 |
| VWAP | VWAP算法 |
| POV | POV算法 |

**市场类型 (MarketType):**

| 枚举值 | 描述 |
|--------|------|
| SPOT | 现货市场 |
| PERP | 合约市场 |

**订单方向 (OrderSide):**

| 枚举值 | 描述 |
|--------|------|
| buy | 买入 |
| sell | 卖出 |

**交易所 (Exchange):**

| 枚举值 | 描述 |
|--------|------|
| Binance | 币安 |

**保证金类型 (MarginType):**

| 枚举值 | 描述 |
|--------|------|
| U | U本位 |

**母单状态 (MasterOrderStatus):**

| 枚举值 | 描述 |
|--------|------|
| NEW | 执行中 |
| COMPLETED | 已完成 |

**交易对市场类型 (TradingPairMarketType):**

| 枚举值 | 描述 |
|--------|------|
| SPOT | 现货品种 |
| FUTURES | 期货品种 |

### 5. 公共接口使用说明

**Status 接口(无需认证):**
- `ping()`: 测试服务器连通性
- `timestamp()`: 获取服务器时间戳

**Pub 接口(无需认证):**
- `trading_pairs()`: 获取交易对列表,支持各种筛选条件

**User 接口(需要认证):**
- 所有交易相关功能都需要有效的 API 密钥

### 6. 枚举类型使用建议

推荐使用枚举类型而不是字符串,这样可以获得:
- 类型安全:编译时检查参数正确性
- 代码提示:IDE 可以提供自动补全
- 避免拼写错误:减少因字符串拼写错误导致的错误

```python
# 推荐使用枚举
from qe.lib import TradingPairMarketType

# 使用枚举
pairs = pub_client.trading_pairs(marketType=TradingPairMarketType.SPOT)

# 不推荐使用字符串
pairs = pub_client.trading_pairs(marketType="SPOT")
```

### 7. WebSocket 相关说明

**WebSocket 连接地址:**
- `wss://test.quantumexecute.com/api/ws?listen_key={listenKey}`

**支持的消息类型:**
- 主订单状态更新(`master_order`)
- 子订单变化(`order`)
- 成交明细(`fill`)
- 系统状态消息(`status`)
- 错误消息(`error`)

**连接管理:**
- SDK 自动处理心跳检测和重连
- 支持自定义重连延迟、心跳间隔等参数
- 提供连接状态查询接口

**消息处理:**
- 支持结构化消息解析
- 提供原始消息访问接口
- 支持自定义错误处理逻辑

**性能优化建议:**
- 避免在消息处理器中执行耗时操作
- 使用异步处理消息,避免阻塞主连接
- 合理设置心跳参数,平衡实时性和资源消耗

**WebSocket 使用示例:**

```python
from qe import API, WebSocketService, WebSocketEventHandlers

# 创建API客户端
api = API("your-api-key", "your-api-secret")

# 创建WebSocket服务
ws_service = WebSocketService(api)

# 设置事件处理器
handlers = WebSocketEventHandlers(
    on_connected=lambda: print("连接成功"),
    on_disconnected=lambda: print("连接断开"),
    on_error=lambda e: print(f"错误: {e}"),
    on_master_order=lambda msg: print(f"主订单: {msg.master_order_id}"),
    on_order=lambda msg: print(f"子订单: {msg.order_id}"),
    on_fill=lambda msg: print(f"成交: {msg.filled_qty}")
)

ws_service.set_handlers(handlers)

# 获取ListenKey并连接
listen_key = api.create_listen_key()['listenKey']
ws_service.connect(listen_key)

# 保持连接
import time
try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    ws_service.close()
```

## 贡献指南

欢迎提交 Issue 和 Pull Request!

## 联系我们

- 官网:[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/79/fa/3adabd3eb42aeb3f0b538c1913b72564ffdd085f52991df9f7106f4565ff/qe-connector-1.0.6.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\u3001POV \u7b49\u7b97\u6cd5\uff09\r\n- \u2705 \u8ba2\u5355\u67e5\u8be2\u548c\u6210\u4ea4\u660e\u7ec6\r\n- \u2705 ListenKey \u521b\u5efa\u4e0e\u7ba1\u7406\r\n- \u2705 \u4ea4\u6613\u5bf9\u4fe1\u606f\u67e5\u8be2\r\n- \u2705 \u670d\u52a1\u5668\u8fde\u901a\u6027\u6d4b\u8bd5\r\n- \u2705 \u670d\u52a1\u5668\u65f6\u95f4\u540c\u6b65\r\n- \u2705 \u5b89\u5168\u7684 HMAC-SHA256 \u7b7e\u540d\u8ba4\u8bc1\r\n- \u2705 \u652f\u6301\u751f\u4ea7\u73af\u5883\u548c\u6d4b\u8bd5\u73af\u5883\r\n- \u2705 \u94fe\u5f0f\u8c03\u7528 API \u8bbe\u8ba1\r\n- \u2705 \u5b8c\u6574\u7684\u9519\u8bef\u5904\u7406\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### \u4f7f\u7528\u679a\u4e3e\u7c7b\u578b\uff08\u63a8\u8350\uff09\r\n\r\nSDK \u63d0\u4f9b\u4e86\u679a\u4e3e\u7c7b\u578b\u6765\u786e\u4fdd\u7c7b\u578b\u5b89\u5168\u548c\u4ee3\u7801\u63d0\u793a\u3002\u63a8\u8350\u4f7f\u7528\u679a\u4e3e\u800c\u4e0d\u662f\u5b57\u7b26\u4e32\uff1a\r\n\r\n```python\r\n# \u5bfc\u5165\u679a\u4e3e\u7c7b\u578b\r\nfrom qe.lib import Algorithm, Exchange, MarketType, OrderSide, StrategyType, MarginType\r\n\r\n# \u53ef\u7528\u7684\u679a\u4e3e\u503c\r\nprint(\"\u7b97\u6cd5\u7c7b\u578b:\", [algo.value for algo in Algorithm])           # ['TWAP', 'VWAP', 'POV']\r\nprint(\"\u4ea4\u6613\u6240:\", [exchange.value for exchange in Exchange])     # ['Binance']\r\nprint(\"\u5e02\u573a\u7c7b\u578b:\", [market.value for market in MarketType])     # ['SPOT', 'PERP']\r\nprint(\"\u8ba2\u5355\u65b9\u5411:\", [side.value for side in OrderSide])         # ['buy', 'sell']\r\nprint(\"\u7b56\u7565\u7c7b\u578b:\", [strategy.value for strategy in StrategyType]) # ['TWAP_1', 'POV']\r\nprint(\"\u4fdd\u8bc1\u91d1\u7c7b\u578b:\", [margin.value for margin in MarginType])   # ['U']\r\n\r\n# \u4f7f\u7528\u679a\u4e3e\u521b\u5efa\u8ba2\u5355\uff08\u63a8\u8350\uff09\r\nresponse = client.create_master_order(\r\n    algorithm=Algorithm.TWAP,        # \u800c\u4e0d\u662f \"TWAP\"\r\n    exchange=Exchange.BINANCE,       # \u800c\u4e0d\u662f \"Binance\"\r\n    marketType=MarketType.SPOT,      # \u800c\u4e0d\u662f \"SPOT\"\r\n    side=OrderSide.BUY,             # \u800c\u4e0d\u662f \"buy\"\r\n    # ... \u5176\u4ed6\u53c2\u6570\r\n)\r\n```\r\n\r\n## API \u53c2\u8003\r\n\r\n### \u516c\u5171\u63a5\u53e3\r\n\r\n#### \u670d\u52a1\u5668\u8fde\u901a\u6027\u6d4b\u8bd5\r\n\r\n##### Ping \u670d\u52a1\u5668\r\n\r\n\u6d4b\u8bd5\u4e0e Quantum Execute \u670d\u52a1\u5668\u7684\u8fde\u901a\u6027\u3002\r\n\r\n**\u8bf7\u6c42\u53c2\u6570\uff1a**\r\n\r\n| \u53c2\u6570\u540d | \u7c7b\u578b | \u662f\u5426\u5fc5\u4f20 | \u63cf\u8ff0 |\r\n|--------|------|----------|------|\r\n| \u65e0\u9700\u53c2\u6570 | - | - | - |\r\n\r\n**\u54cd\u5e94\uff1a**\r\n\r\n\u6210\u529f\u65f6\u65e0\u8fd4\u56de\u5185\u5bb9\uff0c\u5931\u8d25\u65f6\u8fd4\u56de\u9519\u8bef\u4fe1\u606f\u3002\r\n\r\n**\u793a\u4f8b\u4ee3\u7801\uff1a**\r\n\r\n```python\r\nfrom qe.status import Status as StatusClient\r\n\r\n# \u521b\u5efa\u72b6\u6001\u5ba2\u6237\u7aef\uff08\u65e0\u9700\u8ba4\u8bc1\uff09\r\nstatus_client = StatusClient()\r\n\r\n# \u6d4b\u8bd5\u670d\u52a1\u5668\u8fde\u901a\u6027\r\ntry:\r\n    status_client.ping()\r\n    print(\"\u670d\u52a1\u5668\u8fde\u63a5\u6b63\u5e38\")\r\nexcept Exception as e:\r\n    print(f\"\u670d\u52a1\u5668\u8fde\u63a5\u5931\u8d25: {e}\")\r\n```\r\n\r\n#### \u83b7\u53d6\u670d\u52a1\u5668\u65f6\u95f4\r\n\r\n##### \u67e5\u8be2\u670d\u52a1\u5668\u65f6\u95f4\u6233\r\n\r\n\u83b7\u53d6 Quantum Execute \u670d\u52a1\u5668\u7684\u5f53\u524d\u65f6\u95f4\u6233\uff08\u6beb\u79d2\uff09\u3002\r\n\r\n**\u8bf7\u6c42\u53c2\u6570\uff1a**\r\n\r\n| \u53c2\u6570\u540d | \u7c7b\u578b | \u662f\u5426\u5fc5\u4f20 | \u63cf\u8ff0 |\r\n|--------|------|----------|------|\r\n| \u65e0\u9700\u53c2\u6570 | - | - | - |\r\n\r\n**\u54cd\u5e94\u5b57\u6bb5\uff1a**\r\n\r\n| \u5b57\u6bb5\u540d | \u7c7b\u578b | \u63cf\u8ff0 |\r\n|--------|------|------|\r\n| serverTimeMilli | int | \u670d\u52a1\u5668\u65f6\u95f4\u6233\uff08\u6beb\u79d2\uff09 |\r\n\r\n**\u793a\u4f8b\u4ee3\u7801\uff1a**\r\n\r\n```python\r\nfrom qe.status import Status as StatusClient\r\nimport datetime\r\n\r\n# \u521b\u5efa\u72b6\u6001\u5ba2\u6237\u7aef\r\nstatus_client = StatusClient()\r\n\r\n# \u83b7\u53d6\u670d\u52a1\u5668\u65f6\u95f4\u6233\r\ntry:\r\n    timestamp = status_client.timestamp()\r\n    print(f\"\u670d\u52a1\u5668\u65f6\u95f4\u6233: {timestamp}\")\r\n    \r\n    # \u8f6c\u6362\u4e3a\u53ef\u8bfb\u65f6\u95f4\u683c\u5f0f\r\n    readable_time = datetime.datetime.fromtimestamp(timestamp / 1000)\r\n    print(f\"\u670d\u52a1\u5668\u65f6\u95f4: {readable_time}\")\r\nexcept Exception as e:\r\n    print(f\"\u83b7\u53d6\u65f6\u95f4\u6233\u5931\u8d25: {e}\")\r\n```\r\n\r\n#### \u4ea4\u6613\u5bf9\u7ba1\u7406\r\n\r\n##### \u67e5\u8be2\u4ea4\u6613\u5bf9\u5217\u8868\r\n\r\n\u83b7\u53d6\u652f\u6301\u7684\u4ea4\u6613\u5bf9\u4fe1\u606f\uff0c\u5305\u62ec\u73b0\u8d27\u548c\u5408\u7ea6\u4ea4\u6613\u5bf9\u3002\r\n\r\n**\u8bf7\u6c42\u53c2\u6570\uff1a**\r\n\r\n| \u53c2\u6570\u540d | \u7c7b\u578b | \u662f\u5426\u5fc5\u4f20 | \u63cf\u8ff0 |\r\n|--------|------|----------|------|\r\n| page | int | \u5426 | \u9875\u7801 |\r\n| pageSize | int | \u5426 | \u6bcf\u9875\u6570\u91cf |\r\n| exchange | str | \u5426 | \u4ea4\u6613\u6240\u540d\u79f0\u7b5b\u9009 |\r\n| marketType | str/TradingPairMarketType | \u5426 | \u5e02\u573a\u7c7b\u578b\u7b5b\u9009\uff0c\u53ef\u9009\u503c\uff1aSPOT\uff08\u73b0\u8d27\uff09\u3001FUTURES\uff08\u5408\u7ea6\uff09 |\r\n| isCoin | bool | \u5426 | \u662f\u5426\u4e3a\u5e01\u79cd\u7b5b\u9009 |\r\n\r\n**\u54cd\u5e94\u5b57\u6bb5\uff1a**\r\n\r\n| \u5b57\u6bb5\u540d | \u7c7b\u578b | \u63cf\u8ff0 |\r\n|--------|------|------|\r\n| items | array | \u4ea4\u6613\u5bf9\u5217\u8868 |\r\n| \u251c\u2500 id | int | \u4ea4\u6613\u5bf9 ID |\r\n| \u251c\u2500 symbol | string | \u4ea4\u6613\u5bf9\u7b26\u53f7\uff08\u5982\uff1aBTCUSDT\uff09 |\r\n| \u251c\u2500 baseAsset | string | \u57fa\u7840\u5e01\u79cd\uff08\u5982\uff1aBTC\uff09 |\r\n| \u251c\u2500 quoteAsset | string | \u8ba1\u4ef7\u5e01\u79cd\uff08\u5982\uff1aUSDT\uff09 |\r\n| \u251c\u2500 exchange | string | \u4ea4\u6613\u6240\u540d\u79f0 |\r\n| \u251c\u2500 marketType | string | \u5e02\u573a\u7c7b\u578b\uff08SPOT/FUTURES\uff09 |\r\n| \u251c\u2500 contractType | string | \u5408\u7ea6\u7c7b\u578b\uff08\u4ec5\u5408\u7ea6\u4ea4\u6613\u5bf9\uff09 |\r\n| \u251c\u2500 deliveryDate | string | \u4ea4\u5272\u65e5\u671f\uff08\u4ec5\u5408\u7ea6\u4ea4\u6613\u5bf9\uff09 |\r\n| \u251c\u2500 status | string | \u4ea4\u6613\u5bf9\u72b6\u6001 |\r\n| \u251c\u2500 createdAt | string | \u521b\u5efa\u65f6\u95f4 |\r\n| \u251c\u2500 updatedAt | string | \u66f4\u65b0\u65f6\u95f4 |\r\n| page | int | \u5f53\u524d\u9875\u7801 |\r\n| pageSize | int | \u6bcf\u9875\u6570\u91cf |\r\n| total | string | \u603b\u6570 |\r\n\r\n**\u793a\u4f8b\u4ee3\u7801\uff1a**\r\n\r\n```python\r\nfrom qe.pub import Pub as PubClient\r\nfrom qe.lib import TradingPairMarketType\r\n\r\n# \u521b\u5efa\u516c\u5171\u5ba2\u6237\u7aef\uff08\u65e0\u9700\u8ba4\u8bc1\uff09\r\npub_client = PubClient()\r\n\r\n# \u83b7\u53d6\u6240\u6709\u4ea4\u6613\u5bf9\r\ntry:\r\n    pairs = pub_client.trading_pairs()\r\n    print(f\"\u603b\u4ea4\u6613\u5bf9\u6570\u91cf: {pairs.get('total', 0)}\")\r\n    \r\n    # \u6253\u5370\u524d\u51e0\u4e2a\u4ea4\u6613\u5bf9\u4fe1\u606f\r\n    for pair in pairs.get('items', [])[:5]:\r\n        print(f\"\"\"\r\n\u4ea4\u6613\u5bf9\u4fe1\u606f\uff1a\r\n    \u7b26\u53f7: {pair['symbol']}\r\n    \u57fa\u7840\u5e01\u79cd: {pair['baseAsset']}\r\n    \u8ba1\u4ef7\u5e01\u79cd: {pair['quoteAsset']}\r\n    \u4ea4\u6613\u6240: {pair['exchange']}\r\n    \u5e02\u573a\u7c7b\u578b: {pair['marketType']}\r\n    \u72b6\u6001: {pair['status']}\r\n    \u521b\u5efa\u65f6\u95f4: {pair['createdAt']}\r\n        \"\"\")\r\n        \r\n        # \u5982\u679c\u662f\u5408\u7ea6\u4ea4\u6613\u5bf9\uff0c\u663e\u793a\u989d\u5916\u4fe1\u606f\r\n        if pair['marketType'] == 'FUTURES':\r\n            print(f\"    \u5408\u7ea6\u7c7b\u578b: {pair.get('contractType', 'N/A')}\")\r\n            if pair.get('deliveryDate'):\r\n                print(f\"    \u4ea4\u5272\u65e5\u671f: {pair['deliveryDate']}\")\r\n                \r\nexcept Exception as e:\r\n    print(f\"\u83b7\u53d6\u4ea4\u6613\u5bf9\u5931\u8d25: {e}\")\r\n\r\n# \u4f7f\u7528\u679a\u4e3e\u7c7b\u578b\u7b5b\u9009\uff08\u63a8\u8350\uff09\r\ntry:\r\n    # \u83b7\u53d6\u5e01\u5b89\u73b0\u8d27\u4ea4\u6613\u5bf9\r\n    spot_pairs = pub_client.trading_pairs(\r\n        exchange=\"Binance\",\r\n        marketType=TradingPairMarketType.SPOT,  # \u4f7f\u7528\u679a\u4e3e\r\n        page=1,\r\n        pageSize=10\r\n    )\r\n    print(f\"\u5e01\u5b89\u73b0\u8d27\u4ea4\u6613\u5bf9\u6570\u91cf: {len(spot_pairs.get('items', []))}\")\r\n    \r\n    # \u83b7\u53d6\u5408\u7ea6\u4ea4\u6613\u5bf9\r\n    futures_pairs = pub_client.trading_pairs(\r\n        marketType=TradingPairMarketType.FUTURES,  # \u4f7f\u7528\u679a\u4e3e\r\n        page=1,\r\n        pageSize=20\r\n    )\r\n    print(f\"\u5408\u7ea6\u4ea4\u6613\u5bf9\u6570\u91cf: {len(futures_pairs.get('items', []))}\")\r\n    \r\n    # \u83b7\u53d6\u5e01\u79cd\u4ea4\u6613\u5bf9\r\n    coin_pairs = pub_client.trading_pairs(isCoin=True)\r\n    print(f\"\u5e01\u79cd\u4ea4\u6613\u5bf9\u6570\u91cf: {len(coin_pairs.get('items', []))}\")\r\n    \r\nexcept Exception as e:\r\n    print(f\"\u7b5b\u9009\u4ea4\u6613\u5bf9\u5931\u8d25: {e}\")\r\n\r\n# \u4f7f\u7528\u5b57\u7b26\u4e32\u7b5b\u9009\uff08\u5411\u540e\u517c\u5bb9\uff09\r\ntry:\r\n    # \u4f7f\u7528\u5b57\u7b26\u4e32\u53c2\u6570\r\n    spot_pairs = pub_client.trading_pairs(\r\n        exchange=\"Binance\",\r\n        marketType=\"SPOT\",  # \u4f7f\u7528\u5b57\u7b26\u4e32\r\n        page=1,\r\n        pageSize=5\r\n    )\r\n    print(f\"\u73b0\u8d27\u4ea4\u6613\u5bf9\u6570\u91cf: {len(spot_pairs.get('items', []))}\")\r\n    \r\nexcept Exception as e:\r\n    print(f\"\u83b7\u53d6\u73b0\u8d27\u4ea4\u6613\u5bf9\u5931\u8d25: {e}\")\r\n```\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\r\n| \u53c2\u6570\u540d | \u7c7b\u578b | \u662f\u5426\u5fc5\u4f20 | \u63cf\u8ff0 |\r\n|--------|------|----------|------|\r\n| page | int | \u5426 | \u9875\u7801 |\r\n| pageSize | int | \u5426 | \u6bcf\u9875\u6570\u91cf |\r\n| exchange | str | \u5426 | \u4ea4\u6613\u6240\u540d\u79f0\u7b5b\u9009 |\r\n\r\n**\u54cd\u5e94\u5b57\u6bb5\uff1a**\r\n\r\n| \u5b57\u6bb5\u540d | \u7c7b\u578b | \u63cf\u8ff0 |\r\n|--------|------|------|\r\n| items | array | API \u5217\u8868 |\r\n| \u251c\u2500 id | string | API \u8bb0\u5f55\u7684\u552f\u4e00\u6807\u8bc6 |\r\n| \u251c\u2500 createdAt | string | API \u6dfb\u52a0\u65f6\u95f4 |\r\n| \u251c\u2500 accountName | string | \u8d26\u6237\u540d\u79f0\uff08\u5982\uff1a\u8d26\u62371\u3001\u8d26\u62372\uff09 |\r\n| \u251c\u2500 exchange | string | \u4ea4\u6613\u6240\u540d\u79f0\uff08\u5982\uff1aBinance\u3001OKX\u3001Bybit\uff09 |\r\n| \u251c\u2500 apiKey | string | \u4ea4\u6613\u6240 API Key\uff08\u90e8\u5206\u9690\u85cf\uff09 |\r\n| \u251c\u2500 verificationMethod | string | API \u9a8c\u8bc1\u65b9\u5f0f\uff08\u5982\uff1aOAuth\u3001API\uff09 |\r\n| \u251c\u2500 balance | float | \u8d26\u6237\u4f59\u989d\uff08\u7f8e\u5143\uff09 |\r\n| \u251c\u2500 status | string | API \u72b6\u6001\uff1a\u6b63\u5e38\u3001\u5f02\u5e38\uff08\u4e0d\u53ef\u7528\uff09 |\r\n| \u251c\u2500 isValid | bool | API \u662f\u5426\u6709\u6548 |\r\n| \u251c\u2500 isTradingEnabled | bool | \u662f\u5426\u5f00\u542f\u4ea4\u6613\u6743\u9650 |\r\n| \u251c\u2500 isDefault | bool | \u662f\u5426\u4e3a\u8be5\u4ea4\u6613\u6240\u7684\u9ed8\u8ba4\u8d26\u6237 |\r\n| \u251c\u2500 isPm | bool | \u662f\u5426\u4e3a Pm \u8d26\u6237 |\r\n| total | int | API \u603b\u6570 |\r\n| page | int | \u5f53\u524d\u9875\u7801 |\r\n| pageSize | int | \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### \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\r\n| \u53c2\u6570\u540d | \u7c7b\u578b | \u662f\u5426\u5fc5\u4f20 | \u63cf\u8ff0 |\r\n|--------|------|------|------|\r\n| **\u57fa\u7840\u53c2\u6570** |\r\n| strategyType | string/StrategyType | \u662f    | \u7b56\u7565\u7c7b\u578b\uff0c\u53ef\u9009\u503c\uff1aTWAP-1\u3001POV |\r\n| algorithm | string/Algorithm | \u662f    | \u4ea4\u6613\u7b97\u6cd5\u3002strategyType=TWAP-1\u65f6\uff0c\u53ef\u9009\u503c\uff1aTWAP\u3001VWAP\uff1bstrategyType=POV\u65f6\uff0c\u53ef\u9009\u503c\uff1aPOV |\r\n| exchange | string/Exchange | \u662f    | \u4ea4\u6613\u6240\u540d\u79f0\uff0c\u53ef\u9009\u503c\uff1aBinance |\r\n| symbol | string | \u662f    | \u4ea4\u6613\u5bf9\u7b26\u53f7\uff08\u5982\uff1aBTCUSDT\uff09\uff08\u53ef\u7528\u4ea4\u6613\u5bf9\u67e5\u8be2\uff09 |\r\n| marketType | string/MarketType | \u662f    | \u53ef\u9009\u503c\uff1aSPOT\uff08\u73b0\u8d27\uff09\u3001PERP\uff08\u6c38\u7eed\u5408\u7ea6\uff09 |\r\n| side | string/OrderSide | \u662f    | 1.\u5982\u679cisTargetPosition=False\uff1aside\u4ee3\u8868\u4ea4\u6613\u65b9\u5411\uff0c\u53ef\u9009\u503c\uff1abuy\uff08\u4e70\u5165\uff09\u3001sell\uff08\u5356\u51fa\uff09\uff1b\u5408\u7ea6\u4ea4\u6613\u65f6\u53ef\u4e0ereduceOnly\u7ec4\u5408\uff0creduceOnly=True\u65f6\uff1abuy\u4ee3\u8868\u4e70\u5165\u5e73\u7a7a\uff0csell\u4ee3\u8868\u5356\u51fa\u5e73\u591a\u30022.\u5982\u679cisTargetPosition=True\uff1aside\u4ee3\u8868\u4ed3\u4f4d\u65b9\u5411\uff0c\u53ef\u9009\u503c\uff1abuy\uff08\u591a\u5934\uff09\u3001sell\uff08\u7a7a\u5934\uff09\u3002\u3010\u4ec5\u5408\u7ea6\u4ea4\u6613\u65f6\u9700\u4f20\u5165\u3011 |\r\n| apiKeyId | string | \u662f    | \u6307\u5b9a\u4f7f\u7528\u7684 API Key ID\uff0c\u8fd9\u5c06\u51b3\u5b9a\u60a8\u672c\u6b21\u4e0b\u5355\u4f7f\u7528\u54ea\u4e2a\u4ea4\u6613\u6240\u8d26\u6237\u6267\u884c |\r\n| **\u6570\u91cf\u53c2\u6570\uff08\u4e8c\u9009\u4e00\uff09** |\r\n| totalQuantity | float64 | \u5426*   | \u8981\u4ea4\u6613\u7684\u603b\u6570\u91cf\uff0c\u652f\u6301\u5b57\u7b26\u4e32\u8868\u793a\u4ee5\u907f\u514d\u7cbe\u5ea6\u95ee\u9898\uff0c\u4e0e orderNotional \u4e8c\u9009\u4e00\uff0c\u8f93\u5165\u8303\u56f4\uff1a>0 |\r\n| orderNotional | float64 | \u5426*   | \u6309\u4ef7\u503c\u4e0b\u5355\u65f6\u7684\u91d1\u989d\uff0c\u4ee5\u8ba1\u4ef7\u5e01\u79cd\u4e3a\u5355\u4f4d\uff08\u5982ETHUSDT\u4e3aUSDT\u6570\u91cf\uff09\uff0c\u4e0e totalQuantity \u4e8c\u9009\u4e00\uff0c\u8f93\u5165\u8303\u56f4\uff1a>0 |\r\n| **\u4e0b\u5355\u6a21\u5f0f\u53c2\u6570** |\r\n| isTargetPosition | bool | \u5426    | \u662f\u5426\u4e3a\u76ee\u6807\u4ed3\u4f4d\u4e0b\u5355\uff0c\u9ed8\u8ba4\u4e3a false |\r\n| **\u65f6\u95f4\u53c2\u6570** |\r\n| startTime | string | \u5426    | \u4ea4\u6613\u6267\u884c\u7684\u542f\u52a8\u65f6\u95f4\uff0c\u4f20\u5165\u683c\u5f0f\uff1aISO 8601(2025-09-03T01:30:00+08:00)\uff0c\u82e5\u4e0d\u4f20\u5165\uff0c\u5219\u7acb\u5373\u6267\u884c |\r\n| executionDuration | int32 | \u5426    | \u8ba2\u5355\u6700\u5927\u6267\u884c\u65f6\u957f\uff0c\u5206\u949f\uff0c\u8303\u56f4>=1 |\r\n| **TWAP/VWAP \u7b97\u6cd5\u53c2\u6570** |\r\n| mustComplete | bool | \u5426    | \u662f\u5426\u4e00\u5b9a\u8981\u5728executionDuration\u4e4b\u5185\u6267\u884c\u5b8c\u6bd5\uff0c\u9009false\u5219\u4e0d\u4f1a\u8ffd\u8d76\u8fdb\u5ea6\uff0c\u9ed8\u8ba4\uff1atrue |\r\n| makerRateLimit | float64 | \u5426    | \u8981\u6c42maker\u5360\u6bd4\u8d85\u8fc7\u8be5\u503c\uff0c\u8f93\u5165\u8303\u56f4\uff1a0-1\uff08\u8f93\u51650.1\u4ee3\u886810%\uff09\uff0c\u9ed8\u8ba4\uff1a-1(\u7b97\u6cd5\u667a\u80fd\u8ba1\u7b97\u63a8\u8350\u503c\u6267\u884c) |\r\n| povLimit | string | \u5426    | \u5360\u5e02\u573a\u6210\u4ea4\u91cf\u6bd4\u4f8b\u4e0a\u9650\uff0c\u4f18\u5148\u7ea7\u4f4e\u4e8emustComplete\uff0c\u8f93\u5165\u8303\u56f4\uff1a0-1\uff08\u8f93\u51650.1\u4ee3\u886810%\uff09\uff0c\u9ed8\u8ba4\uff1a0.8 |\r\n| limitPrice | float64 | \u5426    | \u6700\u9ad8/\u4f4e\u5141\u8bb8\u4ea4\u6613\u7684\u4ef7\u683c\uff0c\u4e70\u5165\u65f6\u8be5\u5b57\u6bb5\u8c61\u5f81\u6700\u9ad8\u4e70\u5165\u4ef7\uff0c\u5356\u51fa\u65f6\u8be5\u5b57\u6bb5\u8c61\u5f81\u6700\u4f4e\u5356\u51fa\u4ef7\uff0c\u82e5\u5e02\u4ef7\u8d85\u51fa\u8303\u56f4\u5219\u505c\u6b62\u4ea4\u6613\uff0c\u8303\u56f4\uff1a>0\uff0c\u9ed8\u8ba4\uff1a-1\uff0c\u4ee3\u8868\u65e0\u9650\u5236 |\r\n| upTolerance | string | \u5426    | \u5141\u8bb8\u8d85\u51fa\u76ee\u6807\u8fdb\u5ea6\u7684\u6700\u5927\u5bb9\u5fcd\u5ea6\uff0c\u6bd4\u59820.1\u5c31\u662f\u6267\u884c\u8fc7\u7a0b\u4e2d\u5141\u8bb8\u6bd4\u76ee\u6807\u8fdb\u5ea6\u8d85\u51fa\u6bcd\u5355\u6570\u91cf\u768410%\uff0c\u8303\u56f4\uff1a0-1\uff08\u4e0d\u542b0\u30011\uff09\uff0c\u9ed8\u8ba4\uff1a-1\uff08\u5373\u65e0\u5bb9\u5fcd\uff09 |\r\n| lowTolerance | string | \u5426    | \u5141\u8bb8\u843d\u540e\u76ee\u6807\u8fdb\u5ea6\u7684\u6700\u5927\u5bb9\u5fcd\u5ea6\uff0c\u6bd4\u59820.1\u5c31\u662f\u6267\u884c\u8fc7\u7a0b\u4e2d\u5141\u8bb8\u6bd4\u76ee\u6807\u8fdb\u5ea6\u843d\u540e\u6bcd\u5355\u6570\u91cf\u768410%\uff0c\u8303\u56f4\uff1a0-1\uff08\u4e0d\u542b0\u30011\uff09\uff0c\u9ed8\u8ba4\uff1a-1\uff08\u5373\u65e0\u5bb9\u5fcd\uff09 |\r\n| strictUpBound | bool | \u5426    | \u8868\u8fbe\u662f\u5426\u8ffd\u6c42\u4e25\u683c\u5c0f\u4e8euptolerance\uff0c\u5f00\u542f\u540e\u53ef\u80fd\u4f1a\u628a\u5f88\u5c0f\u7684\u6bcd\u5355\u4e5f\u62c6\u7684\u5f88\u7ec6\uff0c\u4e0d\u5efa\u8bae\u5f00\u542f\uff0c\u9ed8\u8ba4\uff1afalse |\r\n| tailOrderProtection | bool | \u5426    | \u8ba2\u5355\u4f59\u91cf\u5c0f\u4e8e\u4ea4\u6613\u6240\u6700\u5c0f\u53d1\u5355\u91cf\u65f6\uff0c\u662f\u5426\u5fc5\u987btaker\u626b\u5b8c\uff0c\u5982\u679cfalse\uff0c\u5219\u8ba2\u5355\u4f59\u91cf\u5c0f\u4e8e\u4ea4\u6613\u6240\u6700\u5c0f\u53d1\u5355\u91cf\u65f6\uff0c\u8ba2\u5355\u7ed3\u675f\u6267\u884c\uff1b\u5982\u679ctrue\uff0c\u5219\u8ba2\u5355\u4f59\u91cf\u968f\u6700\u8fd1\u4e00\u7b14\u4e0b\u5355\u5168\u989d\u6267\u884c\uff08\u53ef\u80fd\u4f1a\u63d0\u9ad8Taker\u7387\uff09\uff0c\u9ed8\u8ba4\uff1atrue |\r\n| **POV \u7b97\u6cd5\u53c2\u6570** |\r\n| makerRateLimit | float64 | \u5426    | \u8981\u6c42maker\u5360\u6bd4\u8d85\u8fc7\u8be5\u503c\uff0c\u8f93\u5165\u8303\u56f4\uff1a0-1\uff08\u8f93\u51650.1\u4ee3\u886810%\uff09\uff0c\u9ed8\u8ba4\uff1a-1(\u7b97\u6cd5\u667a\u80fd\u8ba1\u7b97\u63a8\u8350\u503c\u6267\u884c) |\r\n| povLimit | string | \u5426    | \u5360\u5e02\u573a\u6210\u4ea4\u91cf\u6bd4\u4f8b\u4e0a\u9650\uff0c\u8f93\u5165\u8303\u56f4\uff1a0-0.5\uff08povMinLimit < max(povLimit-0.01,0)\uff09\uff0c\u9ed8\u8ba4\uff1a0 |\r\n| povMinLimit | float64 | \u5426    | \u5360\u5e02\u573a\u6210\u4ea4\u91cf\u6bd4\u4f8b\u4e0b\u9650\uff0c\u8303\u56f4\uff1a\u5c0f\u4e8emax(POVLimit-0.01,0)\uff0c\u9ed8\u8ba4\uff1a0\uff08\u5373\u65e0\u4e0b\u9650\uff09 |\r\n| limitPrice | float64 | \u5426    | \u6700\u9ad8/\u4f4e\u5141\u8bb8\u4ea4\u6613\u7684\u4ef7\u683c\uff0c\u4e70\u5165\u65f6\u8be5\u5b57\u6bb5\u8c61\u5f81\u6700\u9ad8\u4e70\u5165\u4ef7\uff0c\u5356\u51fa\u65f6\u8be5\u5b57\u6bb5\u8c61\u5f81\u6700\u4f4e\u5356\u51fa\u4ef7\uff0c\u82e5\u5e02\u4ef7\u8d85\u51fa\u8303\u56f4\u5219\u505c\u6b62\u4ea4\u6613\uff0c\u8303\u56f4\uff1a>0\uff0c\u9ed8\u8ba4\uff1a-1\uff0c\u4ee3\u8868\u65e0\u9650\u5236 |\r\n| strictUpBound | bool | \u5426    | \u662f\u5426\u8ffd\u6c42\u4e25\u683c\u5c0f\u4e8epovLimit\uff0c\u5f00\u542f\u540e\u53ef\u80fd\u4f1a\u628a\u5f88\u5c0f\u7684\u6bcd\u5355\u4e5f\u62c6\u7684\u5f88\u7ec6\uff0c\u6bd4\u598250u\u62c6\u621010\u4e2a5u\uff0c\u4e0d\u5efa\u8bae\u5f00\u542f\uff0c\u7b97\u6cd5\u7684\u6bcf\u4e2aorder\u4f1a\u6743\u8861\u76d8\u53e3\u6d41\u52a8\u6027\uff0c\u9ed8\u8ba4\uff1afalse |\r\n| tailOrderProtection | bool | \u5426    | \u8ba2\u5355\u4f59\u91cf\u5c0f\u4e8e\u4ea4\u6613\u6240\u6700\u5c0f\u53d1\u5355\u91cf\u65f6\uff0c\u662f\u5426\u5fc5\u987btaker\u626b\u5b8c\uff0c\u5982\u679cfalse\uff0c\u5219\u8ba2\u5355\u4f59\u91cf\u5c0f\u4e8e\u4ea4\u6613\u6240\u6700\u5c0f\u53d1\u5355\u91cf\u65f6\uff0c\u8ba2\u5355\u7ed3\u675f\u6267\u884c\uff1b\u5982\u679ctrue\uff0c\u5219\u8ba2\u5355\u4f59\u91cf\u968f\u6700\u8fd1\u4e00\u7b14\u4e0b\u5355\u5168\u989d\u6267\u884c\uff08\u53ef\u80fd\u4f1a\u63d0\u9ad8Taker\u7387\uff09\uff0c\u9ed8\u8ba4\uff1atrue |\r\n| **\u5176\u4ed6\u53c2\u6570** |\r\n| reduceOnly | bool | \u5426    | \u5408\u7ea6\u4ea4\u6613\u65f6\u662f\u5426\u4ec5\u51cf\u4ed3\uff0c\u9ed8\u8ba4\u503c\uff1afalse |\r\n| marginType | string/MarginType | \u5426    | \u5408\u7ea6\u4ea4\u6613\u4fdd\u8bc1\u91d1\u7c7b\u578b\uff0c\u53ef\u9009\u503c\uff1aU\uff08U\u672c\u4f4d\uff09\uff0c\u9ed8\u8ba4\uff1aU\uff08\u6682\u65f6\u53ea\u652f\u6301U\u672c\u4f4d\u6c38\u7eed\u5408\u7ea6\uff09 |\r\n| notes | string | \u5426    | \u8ba2\u5355\u5907\u6ce8 |\r\n\r\n*\u6ce8\uff1atotalQuantity \u548c orderNotional \u5fc5\u987b\u4f20\u5176\u4e2d\u4e00\u4e2a\uff0c\u4f46\u5f53 isTargetPosition \u4e3a true \u65f6\uff0ctotalQuantity \u5fc5\u586b\u4ee3\u8868\u76ee\u6807\u4ed3\u4f4d\u6570\u91cf\u4e14 orderNotional \u4e0d\u53ef\u586b  \r\n\r\n**\u54cd\u5e94\u5b57\u6bb5\uff1a**\r\n\r\n| \u5b57\u6bb5\u540d | \u7c7b\u578b | \u63cf\u8ff0 |\r\n|--------|------|------|\r\n| masterOrderId | string | \u521b\u5efa\u6210\u529f\u7684\u4e3b\u8ba2\u5355 ID |\r\n| success | bool | \u521b\u5efa\u662f\u5426\u6210\u529f |\r\n| message | string | \u521b\u5efa\u7ed3\u679c\u6d88\u606f |\r\n\r\n**\u793a\u4f8b\u4ee3\u7801\uff1a**\r\n\r\n```python\r\n# \u5bfc\u5165\u679a\u4e3e\u7c7b\u578b\uff08\u63a8\u8350\u65b9\u5f0f\uff09\r\nfrom qe.lib import Algorithm, Exchange, MarketType, OrderSide, StrategyType, MarginType\r\n\r\n# TWAP \u8ba2\u5355\u793a\u4f8b - \u4f7f\u7528\u679a\u4e3e\u521b\u5efa\u8ba2\u5355\uff08\u63a8\u8350\uff09\r\nresponse = client.create_master_order(\r\n    algorithm=Algorithm.TWAP,                      # \u4f7f\u7528\u7b97\u6cd5\u679a\u4e3e\r\n    exchange=Exchange.BINANCE,                     # \u4f7f\u7528\u4ea4\u6613\u6240\u679a\u4e3e\r\n    symbol=\"BTCUSDT\",\r\n    marketType=MarketType.SPOT,                    # \u4f7f\u7528\u5e02\u573a\u7c7b\u578b\u679a\u4e3e\r\n    side=OrderSide.BUY,                           # \u4f7f\u7528\u8ba2\u5355\u65b9\u5411\u679a\u4e3e\r\n    apiKeyId=\"your-api-key-id\",                   # \u4ece list_exchange_apis \u83b7\u53d6\r\n    orderNotional=\"200\",                          # $200 \u540d\u4e49\u4ef7\u503c\r\n    strategyType=StrategyType.TWAP_1,             # \u4f7f\u7528\u7b56\u7565\u7c7b\u578b\u679a\u4e3e\r\n    startTime=\"2025-09-02T19:54:34+08:00\",\r\n    endTime=\"2025-09-03T01:44:35+08:00\",\r\n    executionDuration=\"5\",                        # 5 \u79d2\u95f4\u9694\r\n    mustComplete=True,                            # \u5fc5\u987b\u5b8c\u6210\u5168\u90e8\u8ba2\u5355\r\n    worstPrice=-1,                               # -1 \u8868\u793a\u65e0\u4ef7\u683c\u9650\u5236\r\n    upTolerance=\"-1\",                            # \u5141\u8bb8\u8d85\u51fa\u5bb9\u5fcd\u5ea6\r\n    lowTolerance=\"-1\",                           # \u5141\u8bb8\u843d\u540e\u5bb9\u5fcd\u5ea6\r\n    tailOrderProtection=True,                    # \u5c3e\u5355\u4fdd\u62a4\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**\u76ee\u6807\u4ed3\u4f4d\u4e0b\u5355\u793a\u4f8b\uff1a**\r\n\r\n```python\r\n# \u76ee\u6807\u4ed3\u4f4d\u4e0b\u5355\u793a\u4f8b - \u4e70\u5165 1.5 BTC \u5230\u76ee\u6807\u4ed3\u4f4d\r\nresponse = client.create_master_order(\r\n    algorithm=Algorithm.TWAP,                      # \u4f7f\u7528\u7b97\u6cd5\u679a\u4e3e\r\n    exchange=Exchange.BINANCE,                     # \u4f7f\u7528\u4ea4\u6613\u6240\u679a\u4e3e\r\n    symbol=\"BTCUSDT\",\r\n    marketType=MarketType.SPOT,                    # \u4f7f\u7528\u5e02\u573a\u7c7b\u578b\u679a\u4e3e\r\n    side=OrderSide.BUY,                           # \u4f7f\u7528\u8ba2\u5355\u65b9\u5411\u679a\u4e3e\r\n    apiKeyId=\"your-api-key-id\",                   # \u4ece list_exchange_apis \u83b7\u53d6\r\n    totalQuantity=\"1.5\",                          # \u76ee\u6807\u6570\u91cf 1.5 BTC\r\n    isTargetPosition=True,                        # \u542f\u7528\u76ee\u6807\u4ed3\u4f4d\u6a21\u5f0f\r\n    strategyType=StrategyType.TWAP_1,             # \u4f7f\u7528\u7b56\u7565\u7c7b\u578b\u679a\u4e3e\r\n    startTime=\"2025-09-02T19:54:34+08:00\",\r\n    endTime=\"2025-09-03T01:44:35+08:00\",\r\n    executionDuration=60,                         # 60 \u5206\u949f\r\n    mustComplete=True,                            # \u5fc5\u987b\u5b8c\u6210\u5168\u90e8\u8ba2\u5355\r\n    limitPrice=\"65000\",                           # \u6700\u9ad8\u4ef7\u683c $65,000\r\n    upTolerance=\"0.1\",                            # \u5141\u8bb8\u8d85\u51fa 10%\r\n    lowTolerance=\"0.1\",                           # \u5141\u8bb8\u843d\u540e 10%\r\n    tailOrderProtection=True,                     # \u5c3e\u5355\u4fdd\u62a4\r\n    notes=\"\u76ee\u6807\u4ed3\u4f4d\u8ba2\u5355\u793a\u4f8b\"                      # \u8ba2\u5355\u5907\u6ce8\r\n)\r\n\r\nif response.get('success'):\r\n    print(f\"\u76ee\u6807\u4ed3\u4f4d\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**POV \u5408\u7ea6\u8ba2\u5355\u793a\u4f8b\uff1a**\r\n\r\n```python\r\n# POV \u5408\u7ea6\u8ba2\u5355\u793a\u4f8b - \u4f7f\u7528\u679a\u4e3e\r\nresponse = client.create_master_order(\r\n    algorithm=Algorithm.POV,                       # POV \u7b97\u6cd5\r\n    exchange=Exchange.BINANCE,\r\n    symbol=\"BTCUSDT\",\r\n    marketType=MarketType.PERP,                    # \u5408\u7ea6\u5e02\u573a\r\n    side=OrderSide.SELL,                          # \u5356\u51fa\r\n    apiKeyId=\"your-api-key-id\",\r\n    orderNotional=\"1000\",                         # $1000 \u540d\u4e49\u4ef7\u503c\r\n    strategyType=StrategyType.POV,                # POV \u7b56\u7565\r\n    startTime=\"2025-09-02T19:54:34+08:00\",\r\n    endTime=\"2025-09-03T01:44:35+08:00\",\r\n    povLimit=0.2,                                 # \u5360\u5e02\u573a\u6210\u4ea4\u91cf 20%\r\n    povMinLimit=0.05,                             # \u6700\u4f4e\u5360\u5e02\u573a\u6210\u4ea4\u91cf 5%\r\n    marginType=MarginType.U,                      # U\u672c\u4f4d\u4fdd\u8bc1\u91d1\r\n    reduceOnly=False,\r\n    mustComplete=True,\r\n    notes=\"POV \u5408\u7ea6\u8ba2\u5355\u793a\u4f8b\"\r\n)\r\n\r\nif response.get('success'):\r\n    print(f\"POV \u8ba2\u5355\u521b\u5efa\u6210\u529f\uff0cID: {response['masterOrderId']}\")\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\r\n| \u53c2\u6570\u540d | \u7c7b\u578b | \u662f\u5426\u5fc5\u4f20 | \u63cf\u8ff0 |\r\n|--------|------|----------|------|\r\n| page | int32 | \u5426 | \u9875\u7801 |\r\n| pageSize | int32 | \u5426 | \u6bcf\u9875\u6570\u91cf |\r\n| status | string | \u5426 | \u8ba2\u5355\u72b6\u6001\u7b5b\u9009\uff0c\u53ef\u9009\u503c\uff1aNEW\uff08\u6267\u884c\u4e2d\uff09\u3001COMPLETED\uff08\u5df2\u5b8c\u6210\uff09 |\r\n| exchange | string | \u5426 | \u4ea4\u6613\u6240\u540d\u79f0\u7b5b\u9009 |\r\n| symbol | string | \u5426 | \u4ea4\u6613\u5bf9\u7b5b\u9009 |\r\n| startTime | string | \u5426 | \u5f00\u59cb\u65f6\u95f4\u7b5b\u9009 |\r\n| endTime | string | \u5426 | \u7ed3\u675f\u65f6\u95f4\u7b5b\u9009 |\r\n\r\n**\u54cd\u5e94\u5b57\u6bb5\uff1a**\r\n\r\n| \u5b57\u6bb5\u540d | \u7c7b\u578b | \u63cf\u8ff0 |\r\n|--------|------|------|\r\n| items | array | \u4e3b\u8ba2\u5355\u5217\u8868 |\r\n| \u251c\u2500 masterOrderId | string | \u4e3b\u8ba2\u5355 ID |\r\n| \u251c\u2500 algorithm | string | \u7b97\u6cd5 |\r\n| \u251c\u2500 algorithmType | string | \u7b97\u6cd5\u7c7b\u578b |\r\n| \u251c\u2500 exchange | string | \u4ea4\u6613\u6240 |\r\n| \u251c\u2500 symbol | string | \u4ea4\u6613\u5bf9 |\r\n| \u251c\u2500 marketType | string | \u5e02\u573a\u7c7b\u578b |\r\n| \u251c\u2500 side | string | \u4e70\u5356\u65b9\u5411 |\r\n| \u251c\u2500 totalQuantity | string | \u603b\u6570\u91cf |\r\n| \u251c\u2500 filledQuantity | string | \u5df2\u6210\u4ea4\u6570\u91cf |\r\n| \u251c\u2500 averagePrice | float64 | \u5e73\u5747\u6210\u4ea4\u4ef7 |\r\n| \u251c\u2500 status | string | \u72b6\u6001\uff1aNEW\uff08\u521b\u5efa\uff0c\u672a\u6267\u884c\uff09\u3001WAITING\uff08\u7b49\u5f85\u4e2d\uff09\u3001PROCESSING\uff08\u6267\u884c\u4e2d\uff0c\u4e14\u672a\u5b8c\u6210\uff09\u3001PAUSED\uff08\u5df2\u6682\u505c\uff09\u3001CANCEL\uff08\u53d6\u6d88\u4e2d\uff09\u3001CANCELLED\uff08\u5df2\u53d6\u6d88\uff09\u3001COMPLETED\uff08\u5df2\u5b8c\u6210\uff09\u3001REJECTED\uff08\u5df2\u62d2\u7edd\uff09\u3001EXPIRED\uff08\u5df2\u8fc7\u671f\uff09\u3001CANCEL_REJECT\uff08\u53d6\u6d88\u88ab\u62d2\u7edd\uff09 |\r\n| \u251c\u2500 executionDuration | int32 | \u6267\u884c\u65f6\u957f\uff08\u5206\u949f\uff09 |\r\n| \u251c\u2500 priceLimit | float64 | \u4ef7\u683c\u9650\u5236 |\r\n| \u251c\u2500 startTime | string | \u5f00\u59cb\u65f6\u95f4 |\r\n| \u251c\u2500 endTime | string | \u7ed3\u675f\u65f6\u95f4 |\r\n| \u251c\u2500 createdAt | string | \u521b\u5efa\u65f6\u95f4 |\r\n| \u251c\u2500 updatedAt | string | \u66f4\u65b0\u65f6\u95f4 |\r\n| \u251c\u2500 notes | string | \u5907\u6ce8 |\r\n| \u251c\u2500 marginType | string | \u4fdd\u8bc1\u91d1\u7c7b\u578b\uff08U:U\u672c\u4f4d\uff09 |\r\n| \u251c\u2500 reduceOnly | bool | \u662f\u5426\u4ec5\u51cf\u4ed3 |\r\n| \u251c\u2500 strategyType | string | \u7b56\u7565\u7c7b\u578b |\r\n| \u251c\u2500 orderNotional | string | \u8ba2\u5355\u91d1\u989d\uff08USDT\uff09 |\r\n| \u251c\u2500 mustComplete | bool | \u662f\u5426\u5fc5\u987b\u5b8c\u6210 |\r\n| \u251c\u2500 makerRateLimit | string | \u6700\u4f4e Maker \u7387 |\r\n| \u251c\u2500 povLimit | string | \u6700\u5927\u5e02\u573a\u6210\u4ea4\u91cf\u5360\u6bd4 |\r\n| \u251c\u2500 clientId | string | \u5ba2\u6237\u7aef ID |\r\n| \u251c\u2500 date | string | \u53d1\u5355\u65e5\u671f\uff08\u683c\u5f0f\uff1aYYYYMMDD\uff09 |\r\n| \u251c\u2500 ticktimeInt | string | \u53d1\u5355\u65f6\u95f4\uff08\u683c\u5f0f\uff1a093000000 \u8868\u793a 9:30:00.000\uff09 |\r\n| \u251c\u2500 limitPriceString | string | \u9650\u4ef7\uff08\u5b57\u7b26\u4e32\uff09 |\r\n| \u251c\u2500 upTolerance | string | \u4e0a\u5bb9\u5fcd\u5ea6 |\r\n| \u251c\u2500 lowTolerance | string | \u4e0b\u5bb9\u5fcd\u5ea6 |\r\n| \u251c\u2500 strictUpBound | bool | \u4e25\u683c\u4e0a\u754c |\r\n| \u251c\u2500 ticktimeMs | int64 | \u53d1\u5355\u65f6\u95f4\u6233\uff08epoch \u6beb\u79d2\uff09 |\r\n| \u251c\u2500 category | string | \u4ea4\u6613\u54c1\u79cd\uff08spot \u6216 perp\uff09 |\r\n| \u251c\u2500 filledAmount | float64 | \u6210\u4ea4\u91d1\u989d |\r\n| \u251c\u2500 totalValue | float64 | \u6210\u4ea4\u603b\u503c |\r\n| \u251c\u2500 base | string | \u57fa\u7840\u5e01\u79cd |\r\n| \u251c\u2500 quote | string | \u8ba1\u4ef7\u5e01\u79cd |\r\n| \u251c\u2500 completionProgress | float64 | \u5b8c\u6210\u8fdb\u5ea6\uff080-1\uff09 |\r\n| \u251c\u2500 reason | string | \u539f\u56e0\uff08\u5982\u53d6\u6d88\u539f\u56e0\uff09 |\r\n| total | int32 | \u603b\u6570 |\r\n| page | int32 | \u5f53\u524d\u9875\u7801 |\r\n| pageSize | int32 | \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\",              # \u6267\u884c\u4e2d\u7684\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\u4fe1\u606f\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']} / {order['totalQuantity']}\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    \u4e0a\u5bb9\u5fcd\u5ea6: {order.get('upTolerance', 'N/A')}\r\n    \u4e0b\u5bb9\u5fcd\u5ea6: {order.get('lowTolerance', 'N/A')}\r\n    \"\"\")\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\r\n| \u53c2\u6570\u540d | \u7c7b\u578b | \u662f\u5426\u5fc5\u4f20 | \u63cf\u8ff0 |\r\n|--------|------|----------|------|\r\n| page | int32 | \u5426 | \u9875\u7801 |\r\n| pageSize | int32 | \u5426 | \u6bcf\u9875\u6570\u91cf |\r\n| masterOrderId | string | \u5426 | \u4e3b\u8ba2\u5355 ID \u7b5b\u9009 |\r\n| subOrderId | string | \u5426 | \u5b50\u8ba2\u5355 ID \u7b5b\u9009 |\r\n| symbol | string | \u5426 | \u4ea4\u6613\u5bf9\u7b5b\u9009 |\r\n| startTime | string | \u5426 | \u5f00\u59cb\u65f6\u95f4\u7b5b\u9009 |\r\n| endTime | string | \u5426 | \u7ed3\u675f\u65f6\u95f4\u7b5b\u9009 |\r\n\r\n**\u54cd\u5e94\u5b57\u6bb5\uff1a**\r\n\r\n| \u5b57\u6bb5\u540d | \u7c7b\u578b | \u63cf\u8ff0 |\r\n|--------|------|------|\r\n| items | array | \u6210\u4ea4\u8bb0\u5f55\u5217\u8868 |\r\n| \u251c\u2500 id | string | \u8bb0\u5f55 ID |\r\n| \u251c\u2500 orderCreatedTime | string | \u8ba2\u5355\u521b\u5efa\u65f6\u95f4 |\r\n| \u251c\u2500 masterOrderId | string | \u4e3b\u8ba2\u5355 ID |\r\n| \u251c\u2500 exchange | string | \u4ea4\u6613\u6240 |\r\n| \u251c\u2500 category | string | \u5e02\u573a\u7c7b\u578b |\r\n| \u251c\u2500 symbol | string | \u4ea4\u6613\u5bf9 |\r\n| \u251c\u2500 side | string | \u65b9\u5411 |\r\n| \u251c\u2500 filledValue | float64 | \u6210\u4ea4\u4ef7\u503c |\r\n| \u251c\u2500 filledQuantity | string | \u6210\u4ea4\u6570\u91cf |\r\n| \u251c\u2500 avgPrice | float64 | \u5e73\u5747\u4ef7\u683c |\r\n| \u251c\u2500 price | float64 | \u6210\u4ea4\u4ef7\u683c |\r\n| \u251c\u2500 fee | float64 | \u624b\u7eed\u8d39 |\r\n| \u251c\u2500 tradingAccount | string | \u4ea4\u6613\u8d26\u6237 |\r\n| \u251c\u2500 status | string | \u72b6\u6001 |\r\n| \u251c\u2500 rejectReason | string | \u62d2\u7edd\u539f\u56e0 |\r\n| \u251c\u2500 base | string | \u57fa\u7840\u5e01\u79cd |\r\n| \u251c\u2500 quote | string | \u8ba1\u4ef7\u5e01\u79cd |\r\n| \u251c\u2500 type | string | \u8ba2\u5355\u7c7b\u578b |\r\n| total | int32 | \u603b\u6570 |\r\n| page | int32 | \u5f53\u524d\u9875\u7801 |\r\n| pageSize | int32 | \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# \u7edf\u8ba1\u6210\u4ea4\u4fe1\u606f\r\ntotal_value = 0\r\ntotal_fee = 0\r\nfor fill in fills['items']:\r\n    print(f\"\"\"\r\n\u6210\u4ea4\u8be6\u60c5\uff1a\r\n    \u65f6\u95f4: {fill['orderCreatedTime']}\r\n    \u4ea4\u6613\u5bf9: {fill['symbol']}\r\n    \u65b9\u5411: {fill['side']}\r\n    \u6210\u4ea4\u4ef7\u683c: ${fill['price']:.2f}\r\n    \u6210\u4ea4\u6570\u91cf: {fill['filledQuantity']}\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    \"\"\")\r\n    total_value += fill['filledValue']\r\n    total_fee += fill['fee']\r\n\r\nprint(f\"\u603b\u6210\u4ea4\u989d: ${total_value:.2f}, \u603b\u624b\u7eed\u8d39: ${total_fee:.2f}\")\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\r\n| \u53c2\u6570\u540d | \u7c7b\u578b | \u662f\u5426\u5fc5\u4f20 | \u63cf\u8ff0 |\r\n|--------|------|----------|------|\r\n| masterOrderId | string | \u662f | \u8981\u53d6\u6d88\u7684\u4e3b\u8ba2\u5355 ID |\r\n| reason | string | \u5426 | \u53d6\u6d88\u539f\u56e0 |\r\n\r\n**\u54cd\u5e94\u5b57\u6bb5\uff1a**\r\n\r\n| \u5b57\u6bb5\u540d | \u7c7b\u578b | \u63cf\u8ff0 |\r\n|--------|------|------|\r\n| success | bool | \u53d6\u6d88\u662f\u5426\u6210\u529f |\r\n| message | string | \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#### \u521b\u5efa ListenKey\r\n\r\n\u521b\u5efa\u4e00\u4e2a\u968f\u673a\u7684UUID\u4f5c\u4e3aListenKey\uff0c\u7ed1\u5b9a\u5f53\u524d\u7528\u6237\u4fe1\u606f\uff0c\u6709\u6548\u671f24\u5c0f\u65f6\u3002ListenKey\u7528\u4e8eWebSocket\u8fde\u63a5\uff0c\u53ef\u4ee5\u5b9e\u65f6\u63a5\u6536\u7528\u6237\u76f8\u5173\u7684\u4ea4\u6613\u6570\u636e\u63a8\u9001\u3002\r\n\r\n**\u8bf7\u6c42\u53c2\u6570\uff1a**\r\n\r\n| \u53c2\u6570\u540d | \u7c7b\u578b | \u662f\u5426\u5fc5\u4f20 | \u63cf\u8ff0 |\r\n|--------|------|----------|------|\r\n| \u65e0\u9700\u53c2\u6570 | - | - | - |\r\n\r\n**\u54cd\u5e94\u5b57\u6bb5\uff1a**\r\n\r\n| \u5b57\u6bb5\u540d | \u7c7b\u578b | \u63cf\u8ff0 |\r\n|--------|------|------|\r\n| listenKey | string | \u751f\u6210\u7684ListenKey |\r\n| expireAt | string | ListenKey\u8fc7\u671f\u65f6\u95f4\u6233\uff08\u79d2\uff09 |\r\n| success | bool | \u521b\u5efa\u662f\u5426\u6210\u529f |\r\n| message | string | \u521b\u5efa\u7ed3\u679c\u6d88\u606f |\r\n\r\n**\u793a\u4f8b\u4ee3\u7801\uff1a**\r\n\r\n```python\r\n# \u521b\u5efa ListenKey\r\nresult = client.create_listen_key()\r\n\r\nif result.get('success'):\r\n    print(f\"ListenKey\u521b\u5efa\u6210\u529f:\")\r\n    print(f\"ListenKey: {result['listenKey']}\")\r\n    print(f\"\u8fc7\u671f\u65f6\u95f4: {result['expireAt']}\")\r\n    \r\n    # \u4f7f\u7528 ListenKey \u5efa\u7acb WebSocket \u8fde\u63a5\r\n    # ws_url = f\"wss://api.quantumexecute.com/ws/{result['listenKey']}\"\r\nelse:\r\n    print(f\"ListenKey\u521b\u5efa\u5931\u8d25\uff1a{result.get('message')}\")\r\n```\r\n\r\n**\u6ce8\u610f\u4e8b\u9879\uff1a**\r\n- ListenKey \u6709\u6548\u671f\u4e3a 24 \u5c0f\u65f6\uff0c\u8fc7\u671f\u540e\u9700\u8981\u91cd\u65b0\u521b\u5efa\r\n- \u6bcf\u4e2a\u7528\u6237\u540c\u65f6\u53ea\u80fd\u6709\u4e00\u4e2a\u6709\u6548\u7684 ListenKey\r\n- ListenKey \u7528\u4e8e WebSocket \u8fde\u63a5\uff0c\u53ef\u4ee5\u5b9e\u65f6\u63a5\u6536\u4ea4\u6613\u6570\u636e\u63a8\u9001\r\n- \u5efa\u8bae\u5728\u5e94\u7528\u542f\u52a8\u65f6\u521b\u5efa ListenKey\uff0c\u5e76\u5728\u63a5\u8fd1\u8fc7\u671f\u65f6\u91cd\u65b0\u521b\u5efa\r\n\r\n## \u9519\u8bef\u5904\u7406\r\n\r\nSDK \u63d0\u4f9b\u4e86\u8be6\u7ec6\u7684\u9519\u8bef\u4fe1\u606f\uff0c\u5305\u62ec API \u9519\u8bef\u548c\u7f51\u7edc\u9519\u8bef\uff1a\r\n\r\n```python\r\nfrom qe.error import ClientError, APIError\r\n\r\nresponse = client.create_master_order(\r\n    # ... \u8bbe\u7f6e\u53c2\u6570\r\n)\r\n\r\nif 'error' in response:\r\n    # \u68c0\u67e5\u662f\u5426\u4e3a API \u9519\u8bef\r\n    error = response['error']\r\n    if isinstance(error, dict) and 'code' in error:\r\n        print(f\"API \u9519\u8bef - \u4ee3\u7801: {error['code']}, \u539f\u56e0: {error.get('reason')}, \u6d88\u606f: {error.get('message')}\")\r\n        print(f\"TraceID: {error.get('trace_id')}\")\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\")\r\n        elif error['code'] == 401:\r\n            print(\"\u8ba4\u8bc1\u5931\u8d25\")\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\")\r\n        else:\r\n            print(f\"\u5176\u4ed6\u9519\u8bef: {error}\")\r\n    else:\r\n        print(f\"\u7f51\u7edc\u6216\u5176\u4ed6\u9519\u8bef: {error}\")\r\n```\r\n\r\n## \u9ad8\u7ea7\u914d\u7f6e\r\n\r\n### \u81ea\u5b9a\u4e49 HTTP \u5ba2\u6237\u7aef\r\n\r\n```python\r\nimport requests\r\nimport time\r\n\r\n# \u521b\u5efa\u81ea\u5b9a\u4e49 HTTP \u5ba2\u6237\u7aef\r\nsession = requests.Session()\r\nsession.timeout = 30  # 30 \u79d2\u8d85\u65f6\r\nsession.headers.update({\r\n    'User-Agent': 'QE-Python-SDK/1.0.0'\r\n})\r\n\r\nclient = Client(\"your-api-key\", \"your-api-secret\")\r\nclient.session = session\r\n```\r\n\r\n### \u4f7f\u7528\u4ee3\u7406\r\n\r\n```python\r\nimport requests\r\n\r\nproxies = {\r\n    'https': 'http://proxy.example.com:8080'\r\n}\r\n\r\nclient = Client(\"your-api-key\", \"your-api-secret\")\r\nclient.session.proxies.update(proxies)\r\n```\r\n\r\n### \u65f6\u95f4\u504f\u79fb\u8c03\u6574\r\n\r\n\u5982\u679c\u9047\u5230\u65f6\u95f4\u6233\u9519\u8bef\uff0c\u53ef\u4ee5\u8c03\u6574\u5ba2\u6237\u7aef\u7684\u65f6\u95f4\u504f\u79fb\uff1a\r\n\r\n```python\r\n# \u8bbe\u7f6e\u65f6\u95f4\u504f\u79fb\uff08\u6beb\u79d2\uff09\r\nclient.time_offset = 1000  # \u5ba2\u6237\u7aef\u65f6\u95f4\u6bd4\u670d\u52a1\u5668\u5feb 1 \u79d2\r\n```\r\n\r\n### \u8bf7\u6c42\u91cd\u8bd5\r\n\r\n```python\r\nimport time\r\nimport math\r\n\r\n# \u5b9e\u73b0\u7b80\u5355\u7684\u91cd\u8bd5\u903b\u8f91\r\ndef retry_request(func, max_retries=3):\r\n    \"\"\"\u91cd\u8bd5\u8bf7\u6c42\u51fd\u6570\"\"\"\r\n    for i in range(max_retries):\r\n        try:\r\n            return func()\r\n        except Exception as e:\r\n            if i == max_retries - 1:\r\n                raise e\r\n            \r\n            # \u68c0\u67e5\u662f\u5426\u5e94\u8be5\u91cd\u8bd5\r\n            if hasattr(e, 'code') and 400 <= e.code < 500:\r\n                raise e  # \u4e0d\u91cd\u8bd5\u5ba2\u6237\u7aef\u9519\u8bef\r\n            \r\n            # \u6307\u6570\u9000\u907f\r\n            wait_time = math.pow(2, i)\r\n            print(f\"\u8bf7\u6c42\u5931\u8d25\uff0c{wait_time}\u79d2\u540e\u91cd\u8bd5...\")\r\n            time.sleep(wait_time)\r\n\r\n# \u4f7f\u7528\u91cd\u8bd5\r\ndef create_order_with_retry():\r\n    return client.create_master_order(\r\n        # ... \u8bbe\u7f6e\u53c2\u6570\r\n    )\r\n\r\nresult = retry_request(create_order_with_retry, max_retries=3)\r\n```\r\n\r\n## \u6700\u4f73\u5b9e\u8df5\r\n\r\n### 1. API \u5bc6\u94a5\u7ba1\u7406\r\n\r\n```python\r\n# \u5b9a\u671f\u68c0\u67e5 API \u5bc6\u94a5\u72b6\u6001\r\ndef check_api_key_status(client):\r\n    apis = client.list_exchange_apis()\r\n    if not apis.get('items'):\r\n        print(\"\u83b7\u53d6 API \u5217\u8868\u5931\u8d25\")\r\n        return\r\n    \r\n    for api in apis['items']:\r\n        if not api['isValid']:\r\n            print(f\"\u8b66\u544a: API {api['id']} ({api['accountName']}) \u72b6\u6001\u5f02\u5e38\")\r\n        if api['balance'] < 100:\r\n            print(f\"\u8b66\u544a: \u8d26\u6237 {api['accountName']} \u4f59\u989d\u4e0d\u8db3 (${api['balance']:.2f})\")\r\n```\r\n\r\n### 2. \u8ba2\u5355\u76d1\u63a7\r\n\r\n```python\r\n# \u76d1\u63a7\u8ba2\u5355\u6267\u884c\u72b6\u6001\r\ndef monitor_order(client, master_order_id):\r\n    import time\r\n    \r\n    while True:\r\n        orders = client.get_master_orders(page=1, pageSize=1)\r\n        \r\n        if not orders['items']:\r\n            print(\"\u8ba2\u5355\u4e0d\u5b58\u5728\")\r\n            return\r\n        \r\n        order = orders['items'][0]\r\n        print(f\"\u8ba2\u5355\u8fdb\u5ea6: {order['completionProgress']*100:.2f}%, \u72b6\u6001: {order['status']}\")\r\n        \r\n        if order['status'] == \"COMPLETED\":\r\n            print(f\"\u8ba2\u5355\u5df2\u7ed3\u675f\uff0c\u6700\u7ec8\u72b6\u6001: {order['status']}\")\r\n            return\r\n        \r\n        time.sleep(10)  # \u6bcf 10 \u79d2\u68c0\u67e5\u4e00\u6b21\r\n```\r\n\r\n### 3. \u6279\u91cf\u5904\u7406\r\n\r\n```python\r\n# \u6279\u91cf\u83b7\u53d6\u6240\u6709\u8ba2\u5355\r\ndef get_all_orders(client):\r\n    all_orders = []\r\n    page = 1\r\n    page_size = 100\r\n    \r\n    while True:\r\n        result = client.get_master_orders(page=page, pageSize=page_size)\r\n        all_orders.extend(result['items'])\r\n        \r\n        # \u68c0\u67e5\u662f\u5426\u8fd8\u6709\u66f4\u591a\u6570\u636e\r\n        if len(result['items']) < page_size:\r\n            break\r\n        page += 1\r\n    \r\n    return all_orders\r\n```\r\n\r\n### 4. ListenKey \u7ba1\u7406\r\n\r\n```python\r\nimport time\r\nfrom datetime import datetime\r\n\r\n# ListenKey \u7ba1\u7406\u5668\r\nclass ListenKeyManager:\r\n    def __init__(self, client):\r\n        self.client = client\r\n        self.listen_key = None\r\n        self.expire_at = None\r\n    \r\n    def create_listen_key(self):\r\n        \"\"\"\u521b\u5efa\u6216\u5237\u65b0 ListenKey\"\"\"\r\n        result = self.client.create_listen_key()\r\n        \r\n        if not result.get('success'):\r\n            raise Exception(f\"\u521b\u5efa ListenKey \u5931\u8d25: {result.get('message')}\")\r\n        \r\n        self.listen_key = result['listenKey']\r\n        self.expire_at = int(result['expireAt'])\r\n        \r\n        print(f\"ListenKey \u521b\u5efa\u6210\u529f: {self.listen_key}, \u8fc7\u671f\u65f6\u95f4: {self.expire_at}\")\r\n        return self.listen_key\r\n    \r\n    def is_expired(self):\r\n        \"\"\"\u68c0\u67e5 ListenKey \u662f\u5426\u5373\u5c06\u8fc7\u671f\"\"\"\r\n        if not self.expire_at:\r\n            return True\r\n        # \u63d0\u524d1\u5c0f\u65f6\u5237\u65b0\r\n        return time.time() > self.expire_at - 3600\r\n    \r\n    def auto_refresh(self):\r\n        \"\"\"\u81ea\u52a8\u5237\u65b0 ListenKey\"\"\"\r\n        if self.is_expired():\r\n            print(\"ListenKey \u5373\u5c06\u8fc7\u671f\uff0c\u5f00\u59cb\u5237\u65b0...\")\r\n            self.create_listen_key()\r\n\r\n# \u4f7f\u7528\u793a\u4f8b\r\nmanager = ListenKeyManager(client)\r\nlisten_key = manager.create_listen_key()\r\n\r\n# \u5b9a\u671f\u68c0\u67e5\u5e76\u5237\u65b0\r\nwhile True:\r\n    manager.auto_refresh()\r\n    time.sleep(1800)  # \u6bcf30\u5206\u949f\u68c0\u67e5\u4e00\u6b21\r\n```\r\n\r\n### 5. WebSocket \u5b9e\u65f6\u6570\u636e\u63a8\u9001\r\n\r\nSDK \u63d0\u4f9b\u4e86\u5b8c\u6574\u7684 WebSocket \u670d\u52a1\uff0c\u53ef\u4ee5\u5b9e\u65f6\u63a5\u6536\u4ea4\u6613\u6570\u636e\u63a8\u9001\uff0c\u5305\u62ec\u4e3b\u8ba2\u5355\u72b6\u6001\u66f4\u65b0\u3001\u5b50\u8ba2\u5355\u53d8\u5316\u3001\u6210\u4ea4\u660e\u7ec6\u7b49\u3002\r\n\r\n#### \u521b\u5efa WebSocket \u670d\u52a1\r\n\r\n```python\r\nimport logging\r\nimport time\r\nfrom qe import API, WebSocketService, WebSocketEventHandlers, MasterOrderMessage, OrderMessage, FillMessage\r\n\r\n# \u914d\u7f6e\u65e5\u5fd7\r\nlogging.basicConfig(level=logging.INFO)\r\nlogger = logging.getLogger(__name__)\r\n\r\ndef on_connected():\r\n    \"\"\"\u8fde\u63a5\u6210\u529f\u56de\u8c03\"\"\"\r\n    logger.info(\"WebSocket\u8fde\u63a5\u6210\u529f\")\r\n\r\ndef on_disconnected():\r\n    \"\"\"\u65ad\u5f00\u8fde\u63a5\u56de\u8c03\"\"\"\r\n    logger.info(\"WebSocket\u8fde\u63a5\u65ad\u5f00\")\r\n\r\ndef on_error(error):\r\n    \"\"\"\u9519\u8bef\u56de\u8c03\"\"\"\r\n    logger.error(f\"WebSocket\u9519\u8bef: {error}\")\r\n\r\ndef on_status(data):\r\n    \"\"\"\u72b6\u6001\u6d88\u606f\u56de\u8c03\"\"\"\r\n    logger.info(f\"\u6536\u5230\u72b6\u6001\u6d88\u606f: {data}\")\r\n\r\ndef on_master_order(message: MasterOrderMessage):\r\n    \"\"\"\u4e3b\u8ba2\u5355\u6d88\u606f\u56de\u8c03\"\"\"\r\n    logger.info(f\"\u6536\u5230\u4e3b\u8ba2\u5355\u6d88\u606f:\")\r\n    logger.info(f\"  \u4e3b\u8ba2\u5355ID: {message.master_order_id}\")\r\n    logger.info(f\"  \u5ba2\u6237\u7aefID: {message.client_id}\")\r\n    logger.info(f\"  \u7b56\u7565: {message.strategy}\")\r\n    logger.info(f\"  \u4ea4\u6613\u5bf9: {message.symbol}\")\r\n    logger.info(f\"  \u65b9\u5411: {message.side}\")\r\n    logger.info(f\"  \u6570\u91cf: {message.qty}\")\r\n    logger.info(f\"  \u72b6\u6001: {message.status}\")\r\n    logger.info(f\"  \u65f6\u95f4\u6233: {message.timestamp}\")\r\n\r\ndef on_order(message: OrderMessage):\r\n    \"\"\"\u8ba2\u5355\u6d88\u606f\u56de\u8c03\"\"\"\r\n    logger.info(f\"\u6536\u5230\u8ba2\u5355\u6d88\u606f:\")\r\n    logger.info(f\"  \u4e3b\u8ba2\u5355ID: {message.master_order_id}\")\r\n    logger.info(f\"  \u8ba2\u5355ID: {message.order_id}\")\r\n    logger.info(f\"  \u4ea4\u6613\u5bf9: {message.symbol}\")\r\n    logger.info(f\"  \u65b9\u5411: {message.side}\")\r\n    logger.info(f\"  \u4ef7\u683c: {message.price}\")\r\n    logger.info(f\"  \u6570\u91cf: {message.quantity}\")\r\n    logger.info(f\"  \u72b6\u6001: {message.status}\")\r\n    logger.info(f\"  \u5df2\u6210\u4ea4\u6570\u91cf: {message.fill_qty}\")\r\n    logger.info(f\"  \u5269\u4f59\u6570\u91cf: {message.quantity_remaining}\")\r\n\r\ndef on_fill(message: FillMessage):\r\n    \"\"\"\u6210\u4ea4\u6d88\u606f\u56de\u8c03\"\"\"\r\n    logger.info(f\"\u6536\u5230\u6210\u4ea4\u6d88\u606f:\")\r\n    logger.info(f\"  \u4e3b\u8ba2\u5355ID: {message.master_order_id}\")\r\n    logger.info(f\"  \u8ba2\u5355ID: {message.order_id}\")\r\n    logger.info(f\"  \u4ea4\u6613\u5bf9: {message.symbol}\")\r\n    logger.info(f\"  \u65b9\u5411: {message.side}\")\r\n    logger.info(f\"  \u6210\u4ea4\u4ef7\u683c: {message.fill_price}\")\r\n    logger.info(f\"  \u6210\u4ea4\u6570\u91cf: {message.filled_qty}\")\r\n    logger.info(f\"  \u6210\u4ea4\u65f6\u95f4: {message.fill_time}\")\r\n\r\ndef on_raw_message(message):\r\n    \"\"\"\u539f\u59cb\u6d88\u606f\u56de\u8c03\"\"\"\r\n    logger.debug(f\"\u6536\u5230\u539f\u59cb\u6d88\u606f: {message.type} - {message.data}\")\r\n\r\ndef main():\r\n    \"\"\"\u4e3b\u51fd\u6570\"\"\"\r\n    # \u521b\u5efaAPI\u5ba2\u6237\u7aef\r\n    api = API(\r\n        api_key=\"your_api_key\",\r\n        api_secret=\"your_api_secret\",\r\n        base_url=\"https://test.quantumexecute.com\"\r\n    )\r\n    \r\n    # \u521b\u5efaWebSocket\u4e8b\u4ef6\u5904\u7406\u5668\r\n    handlers = WebSocketEventHandlers(\r\n        on_connected=on_connected,\r\n        on_disconnected=on_disconnected,\r\n        on_error=on_error,\r\n        on_status=on_status,\r\n        on_master_order=on_master_order,\r\n        on_order=on_order,\r\n        on_fill=on_fill,\r\n        on_raw_message=on_raw_message\r\n    )\r\n    \r\n    # \u521b\u5efaWebSocket\u670d\u52a1\r\n    ws_service = WebSocketService(api)\r\n    ws_service.set_handlers(handlers)\r\n    \r\n    # \u8bbe\u7f6e\u8fde\u63a5\u53c2\u6570\r\n    ws_service.set_reconnect_delay(5.0)  # \u91cd\u8fde\u5ef6\u8fdf5\u79d2\r\n    ws_service.set_ping_interval(30.0)   # \u5fc3\u8df3\u95f4\u969430\u79d2\r\n    ws_service.set_pong_timeout(10.0)    # Pong\u8d85\u65f610\u79d2\r\n    \r\n    try:\r\n        # \u83b7\u53d6listen_key\r\n        listen_key_result = api.create_listen_key()\r\n        if not listen_key_result.get('success'):\r\n            logger.error(f\"\u521b\u5efaListenKey\u5931\u8d25: {listen_key_result.get('message')}\")\r\n            return\r\n        \r\n        listen_key = listen_key_result['listenKey']\r\n        \r\n        # \u8fde\u63a5WebSocket\r\n        logger.info(\"\u6b63\u5728\u8fde\u63a5WebSocket...\")\r\n        ws_service.connect(listen_key)\r\n        \r\n        # \u7b49\u5f85\u8fde\u63a5\u5efa\u7acb\r\n        time.sleep(2)\r\n        \r\n        if ws_service.is_connected():\r\n            logger.info(\"WebSocket\u8fde\u63a5\u5df2\u5efa\u7acb\uff0c\u5f00\u59cb\u63a5\u6536\u6d88\u606f...\")\r\n            \r\n            # \u4fdd\u6301\u8fde\u63a5\u8fd0\u884c\r\n            try:\r\n                while True:\r\n                    time.sleep(1)\r\n            except KeyboardInterrupt:\r\n                logger.info(\"\u6536\u5230\u4e2d\u65ad\u4fe1\u53f7\uff0c\u6b63\u5728\u5173\u95ed\u8fde\u63a5...\")\r\n        else:\r\n            logger.error(\"WebSocket\u8fde\u63a5\u5931\u8d25\")\r\n    \r\n    except Exception as e:\r\n        logger.error(f\"\u53d1\u751f\u9519\u8bef: {e}\")\r\n    \r\n    finally:\r\n        # \u5173\u95edWebSocket\u8fde\u63a5\r\n        ws_service.close()\r\n        logger.info(\"WebSocket\u8fde\u63a5\u5df2\u5173\u95ed\")\r\n\r\nif __name__ == \"__main__\":\r\n    main()\r\n```\r\n\r\n#### \u6d88\u606f\u7c7b\u578b\u8bf4\u660e\r\n\r\n**\u5ba2\u6237\u7aef\u63a8\u9001\u6d88\u606f\u7c7b\u578b\uff1a**\r\n\r\n| \u6d88\u606f\u7c7b\u578b | \u63cf\u8ff0 |\r\n|----------|------|\r\n| data | \u6570\u636e\u6d88\u606f |\r\n| status | \u72b6\u6001\u6d88\u606f |\r\n| error | \u9519\u8bef\u6d88\u606f |\r\n| master_data | \u4e3b\u8ba2\u5355\u6570\u636e |\r\n| order_data | \u8ba2\u5355\u6570\u636e |\r\n\r\n**\u7b2c\u4e09\u65b9\u6d88\u606f\u7c7b\u578b\uff1a**\r\n\r\n| \u6d88\u606f\u7c7b\u578b | \u63cf\u8ff0 |\r\n|----------|------|\r\n| master_order | \u4e3b\u8ba2\u5355\u6d88\u606f |\r\n| order | \u5b50\u8ba2\u5355\u6d88\u606f |\r\n| fill | \u6210\u4ea4\u6d88\u606f |\r\n\r\n#### \u914d\u7f6e\u9009\u9879\r\n\r\n```python\r\n# \u8bbe\u7f6e\u91cd\u8fde\u5ef6\u8fdf\r\nws_service.set_reconnect_delay(10.0)  # 10\u79d2\r\n\r\n# \u8bbe\u7f6e\u5fc3\u8df3\u95f4\u9694\r\nws_service.set_ping_interval(2.0)     # 2\u79d2\r\n\r\n# \u8bbe\u7f6ePong\u8d85\u65f6\u65f6\u95f4\r\nws_service.set_pong_timeout(15.0)     # 15\u79d2\r\n\r\n# \u8bbe\u7f6e\u65e5\u5fd7\u8bb0\u5f55\u5668\r\nimport logging\r\nlogger = logging.getLogger(\"websocket\")\r\nws_service.set_logger(logger)\r\n```\r\n\r\n#### \u8fde\u63a5\u72b6\u6001\u7ba1\u7406\r\n\r\n```python\r\n# \u68c0\u67e5\u8fde\u63a5\u72b6\u6001\r\nif ws_service.is_connected():\r\n    print(\"WebSocket \u5df2\u8fde\u63a5\")\r\nelse:\r\n    print(\"WebSocket \u672a\u8fde\u63a5\")\r\n\r\n# \u624b\u52a8\u91cd\u8fde\r\nif not ws_service.is_connected():\r\n    listen_key = \"your-listen-key\"\r\n    ws_service.connect(listen_key)\r\n```\r\n\r\n#### \u9519\u8bef\u5904\u7406\r\n\r\n```python\r\ndef on_error(error):\r\n    \"\"\"\u9519\u8bef\u56de\u8c03\"\"\"\r\n    logger.error(f\"WebSocket \u9519\u8bef: {error}\")\r\n    \r\n    # \u6839\u636e\u9519\u8bef\u7c7b\u578b\u8fdb\u884c\u5904\u7406\r\n    if \"connection refused\" in str(error).lower():\r\n        logger.error(\"\u8fde\u63a5\u88ab\u62d2\u7edd\uff0c\u53ef\u80fd\u662f\u670d\u52a1\u5668\u4e0d\u53ef\u7528\")\r\n    elif \"authentication failed\" in str(error).lower():\r\n        logger.error(\"\u8ba4\u8bc1\u5931\u8d25\uff0c\u8bf7\u68c0\u67e5 ListenKey \u662f\u5426\u6709\u6548\")\r\n    elif \"timeout\" in str(error).lower():\r\n        logger.error(\"\u8fde\u63a5\u8d85\u65f6\uff0c\u8bf7\u68c0\u67e5\u7f51\u7edc\u8fde\u63a5\")\r\n```\r\n\r\n#### \u751f\u4ea7\u73af\u5883\u4f7f\u7528\u5efa\u8bae\r\n\r\n1. **\u81ea\u52a8\u91cd\u8fde\u673a\u5236**\uff1aSDK \u5df2\u5185\u7f6e\u81ea\u52a8\u91cd\u8fde\u529f\u80fd\uff0c\u65e0\u9700\u624b\u52a8\u5b9e\u73b0\r\n2. **ListenKey \u7ba1\u7406**\uff1a\u5b9a\u671f\u68c0\u67e5 ListenKey \u6709\u6548\u6027\uff0c\u63a5\u8fd1\u8fc7\u671f\u65f6\u4e3b\u52a8\u5237\u65b0\r\n3. **\u9519\u8bef\u76d1\u63a7**\uff1a\u5b9e\u73b0\u5b8c\u5584\u7684\u9519\u8bef\u65e5\u5fd7\u8bb0\u5f55\u548c\u76d1\u63a7\r\n4. **\u8d1f\u8f7d\u5747\u8861**\uff1a\u8003\u8651\u4f7f\u7528\u591a\u4e2a WebSocket \u8fde\u63a5\u5206\u6563\u8d1f\u8f7d\r\n5. **\u6d88\u606f\u53bb\u91cd**\uff1a\u6839\u636e `messageId` \u5b9e\u73b0\u6d88\u606f\u53bb\u91cd\u5904\u7406\r\n\r\n#### \u9ad8\u7ea7\u7528\u6cd5\u793a\u4f8b\r\n\r\n```python\r\nclass TradingBot:\r\n    def __init__(self, api_key, api_secret):\r\n        self.api = API(api_key, api_secret)\r\n        self.ws_service = None\r\n        self.listen_key = None\r\n        \r\n    def start_websocket(self):\r\n        \"\"\"\u542f\u52a8WebSocket\u8fde\u63a5\"\"\"\r\n        # \u521b\u5efaListenKey\r\n        result = self.api.create_listen_key()\r\n        if not result.get('success'):\r\n            raise Exception(f\"\u521b\u5efaListenKey\u5931\u8d25: {result.get('message')}\")\r\n        \r\n        self.listen_key = result['listenKey']\r\n        \r\n        # \u521b\u5efa\u4e8b\u4ef6\u5904\u7406\u5668\r\n        handlers = WebSocketEventHandlers(\r\n            on_connected=self._on_connected,\r\n            on_disconnected=self._on_disconnected,\r\n            on_error=self._on_error,\r\n            on_master_order=self._on_master_order,\r\n            on_order=self._on_order,\r\n            on_fill=self._on_fill\r\n        )\r\n        \r\n        # \u521b\u5efaWebSocket\u670d\u52a1\r\n        self.ws_service = WebSocketService(self.api)\r\n        self.ws_service.set_handlers(handlers)\r\n        \r\n        # \u8fde\u63a5\r\n        self.ws_service.connect(self.listen_key)\r\n        \r\n    def _on_connected(self):\r\n        print(\"\u4ea4\u6613\u673a\u5668\u4eba\u5df2\u8fde\u63a5\")\r\n        \r\n    def _on_disconnected(self):\r\n        print(\"\u4ea4\u6613\u673a\u5668\u4eba\u8fde\u63a5\u65ad\u5f00\")\r\n        \r\n    def _on_error(self, error):\r\n        print(f\"\u4ea4\u6613\u673a\u5668\u4eba\u9519\u8bef: {error}\")\r\n        \r\n    def _on_master_order(self, message):\r\n        print(f\"\u4e3b\u8ba2\u5355\u66f4\u65b0: {message.master_order_id} - {message.status}\")\r\n        \r\n    def _on_order(self, message):\r\n        print(f\"\u5b50\u8ba2\u5355\u66f4\u65b0: {message.order_id} - {message.status}\")\r\n        \r\n    def _on_fill(self, message):\r\n        print(f\"\u6210\u4ea4\u901a\u77e5: {message.order_id} - {message.filled_qty} @ {message.fill_price}\")\r\n        \r\n    def stop(self):\r\n        \"\"\"\u505c\u6b62WebSocket\u8fde\u63a5\"\"\"\r\n        if self.ws_service:\r\n            self.ws_service.close()\r\n\r\n# \u4f7f\u7528\u793a\u4f8b\r\nbot = TradingBot(\"your-api-key\", \"your-api-secret\")\r\nbot.start_websocket()\r\n\r\n# \u4fdd\u6301\u8fd0\u884c\r\ntry:\r\n    while True:\r\n        time.sleep(1)\r\nexcept KeyboardInterrupt:\r\n    print(\"\u6b63\u5728\u505c\u6b62...\")\r\n    bot.stop()\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\r\n\r\n### 2. \u5982\u4f55\u5904\u7406\u65f6\u95f4\u683c\u5f0f\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### 3. \u8ba2\u5355\u7c7b\u578b\u8bf4\u660e\r\n\r\n- **TWAP (Time Weighted Average Price)**\uff1a\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)**\uff1a\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)**\uff1a\u6210\u4ea4\u91cf\u767e\u5206\u6bd4\u7b97\u6cd5\uff0c\u4fdd\u6301\u5360\u5e02\u573a\u6210\u4ea4\u91cf\u7684\u56fa\u5b9a\u6bd4\u4f8b\r\n\r\n### 4. \u679a\u4e3e\u503c\u8bf4\u660e\r\n\r\n**\u7b97\u6cd5\u7c7b\u578b (Algorithm)\uff1a**\r\n\r\n| \u679a\u4e3e\u503c | \u63cf\u8ff0 |\r\n|--------|------|\r\n| TWAP | TWAP\u7b97\u6cd5 |\r\n| VWAP | VWAP\u7b97\u6cd5 |\r\n| POV | POV\u7b97\u6cd5 |\r\n\r\n**\u5e02\u573a\u7c7b\u578b (MarketType)\uff1a**\r\n\r\n| \u679a\u4e3e\u503c | \u63cf\u8ff0 |\r\n|--------|------|\r\n| SPOT | \u73b0\u8d27\u5e02\u573a |\r\n| PERP | \u5408\u7ea6\u5e02\u573a |\r\n\r\n**\u8ba2\u5355\u65b9\u5411 (OrderSide)\uff1a**\r\n\r\n| \u679a\u4e3e\u503c | \u63cf\u8ff0 |\r\n|--------|------|\r\n| buy | \u4e70\u5165 |\r\n| sell | \u5356\u51fa |\r\n\r\n**\u4ea4\u6613\u6240 (Exchange)\uff1a**\r\n\r\n| \u679a\u4e3e\u503c | \u63cf\u8ff0 |\r\n|--------|------|\r\n| Binance | \u5e01\u5b89 |\r\n\r\n**\u4fdd\u8bc1\u91d1\u7c7b\u578b (MarginType)\uff1a**\r\n\r\n| \u679a\u4e3e\u503c | \u63cf\u8ff0 |\r\n|--------|------|\r\n| U | U\u672c\u4f4d |\r\n\r\n**\u6bcd\u5355\u72b6\u6001 (MasterOrderStatus)\uff1a**\r\n\r\n| \u679a\u4e3e\u503c | \u63cf\u8ff0 |\r\n|--------|------|\r\n| NEW | \u6267\u884c\u4e2d |\r\n| COMPLETED | \u5df2\u5b8c\u6210 |\r\n\r\n**\u4ea4\u6613\u5bf9\u5e02\u573a\u7c7b\u578b (TradingPairMarketType)\uff1a**\r\n\r\n| \u679a\u4e3e\u503c | \u63cf\u8ff0 |\r\n|--------|------|\r\n| SPOT | \u73b0\u8d27\u54c1\u79cd |\r\n| FUTURES | \u671f\u8d27\u54c1\u79cd |\r\n\r\n### 5. \u516c\u5171\u63a5\u53e3\u4f7f\u7528\u8bf4\u660e\r\n\r\n**Status \u63a5\u53e3\uff08\u65e0\u9700\u8ba4\u8bc1\uff09\uff1a**\r\n- `ping()`: \u6d4b\u8bd5\u670d\u52a1\u5668\u8fde\u901a\u6027\r\n- `timestamp()`: \u83b7\u53d6\u670d\u52a1\u5668\u65f6\u95f4\u6233\r\n\r\n**Pub \u63a5\u53e3\uff08\u65e0\u9700\u8ba4\u8bc1\uff09\uff1a**\r\n- `trading_pairs()`: \u83b7\u53d6\u4ea4\u6613\u5bf9\u5217\u8868\uff0c\u652f\u6301\u5404\u79cd\u7b5b\u9009\u6761\u4ef6\r\n\r\n**User \u63a5\u53e3\uff08\u9700\u8981\u8ba4\u8bc1\uff09\uff1a**\r\n- \u6240\u6709\u4ea4\u6613\u76f8\u5173\u529f\u80fd\u90fd\u9700\u8981\u6709\u6548\u7684 API \u5bc6\u94a5\r\n\r\n### 6. \u679a\u4e3e\u7c7b\u578b\u4f7f\u7528\u5efa\u8bae\r\n\r\n\u63a8\u8350\u4f7f\u7528\u679a\u4e3e\u7c7b\u578b\u800c\u4e0d\u662f\u5b57\u7b26\u4e32\uff0c\u8fd9\u6837\u53ef\u4ee5\u83b7\u5f97\uff1a\r\n- \u7c7b\u578b\u5b89\u5168\uff1a\u7f16\u8bd1\u65f6\u68c0\u67e5\u53c2\u6570\u6b63\u786e\u6027\r\n- \u4ee3\u7801\u63d0\u793a\uff1aIDE \u53ef\u4ee5\u63d0\u4f9b\u81ea\u52a8\u8865\u5168\r\n- \u907f\u514d\u62fc\u5199\u9519\u8bef\uff1a\u51cf\u5c11\u56e0\u5b57\u7b26\u4e32\u62fc\u5199\u9519\u8bef\u5bfc\u81f4\u7684\u9519\u8bef\r\n\r\n```python\r\n# \u63a8\u8350\u4f7f\u7528\u679a\u4e3e\r\nfrom qe.lib import TradingPairMarketType\r\n\r\n# \u4f7f\u7528\u679a\u4e3e\r\npairs = pub_client.trading_pairs(marketType=TradingPairMarketType.SPOT)\r\n\r\n# \u4e0d\u63a8\u8350\u4f7f\u7528\u5b57\u7b26\u4e32\r\npairs = pub_client.trading_pairs(marketType=\"SPOT\")\r\n```\r\n\r\n### 7. WebSocket \u76f8\u5173\u8bf4\u660e\r\n\r\n**WebSocket \u8fde\u63a5\u5730\u5740\uff1a**\r\n- `wss://test.quantumexecute.com/api/ws?listen_key={listenKey}`\r\n\r\n**\u652f\u6301\u7684\u6d88\u606f\u7c7b\u578b\uff1a**\r\n- \u4e3b\u8ba2\u5355\u72b6\u6001\u66f4\u65b0\uff08`master_order`\uff09\r\n- \u5b50\u8ba2\u5355\u53d8\u5316\uff08`order`\uff09\r\n- \u6210\u4ea4\u660e\u7ec6\uff08`fill`\uff09\r\n- \u7cfb\u7edf\u72b6\u6001\u6d88\u606f\uff08`status`\uff09\r\n- \u9519\u8bef\u6d88\u606f\uff08`error`\uff09\r\n\r\n**\u8fde\u63a5\u7ba1\u7406\uff1a**\r\n- SDK \u81ea\u52a8\u5904\u7406\u5fc3\u8df3\u68c0\u6d4b\u548c\u91cd\u8fde\r\n- \u652f\u6301\u81ea\u5b9a\u4e49\u91cd\u8fde\u5ef6\u8fdf\u3001\u5fc3\u8df3\u95f4\u9694\u7b49\u53c2\u6570\r\n- \u63d0\u4f9b\u8fde\u63a5\u72b6\u6001\u67e5\u8be2\u63a5\u53e3\r\n\r\n**\u6d88\u606f\u5904\u7406\uff1a**\r\n- \u652f\u6301\u7ed3\u6784\u5316\u6d88\u606f\u89e3\u6790\r\n- \u63d0\u4f9b\u539f\u59cb\u6d88\u606f\u8bbf\u95ee\u63a5\u53e3\r\n- \u652f\u6301\u81ea\u5b9a\u4e49\u9519\u8bef\u5904\u7406\u903b\u8f91\r\n\r\n**\u6027\u80fd\u4f18\u5316\u5efa\u8bae\uff1a**\r\n- \u907f\u514d\u5728\u6d88\u606f\u5904\u7406\u5668\u4e2d\u6267\u884c\u8017\u65f6\u64cd\u4f5c\r\n- \u4f7f\u7528\u5f02\u6b65\u5904\u7406\u6d88\u606f\uff0c\u907f\u514d\u963b\u585e\u4e3b\u8fde\u63a5\r\n- \u5408\u7406\u8bbe\u7f6e\u5fc3\u8df3\u53c2\u6570\uff0c\u5e73\u8861\u5b9e\u65f6\u6027\u548c\u8d44\u6e90\u6d88\u8017\r\n\r\n**WebSocket \u4f7f\u7528\u793a\u4f8b\uff1a**\r\n\r\n```python\r\nfrom qe import API, WebSocketService, WebSocketEventHandlers\r\n\r\n# \u521b\u5efaAPI\u5ba2\u6237\u7aef\r\napi = API(\"your-api-key\", \"your-api-secret\")\r\n\r\n# \u521b\u5efaWebSocket\u670d\u52a1\r\nws_service = WebSocketService(api)\r\n\r\n# \u8bbe\u7f6e\u4e8b\u4ef6\u5904\u7406\u5668\r\nhandlers = WebSocketEventHandlers(\r\n    on_connected=lambda: print(\"\u8fde\u63a5\u6210\u529f\"),\r\n    on_disconnected=lambda: print(\"\u8fde\u63a5\u65ad\u5f00\"),\r\n    on_error=lambda e: print(f\"\u9519\u8bef: {e}\"),\r\n    on_master_order=lambda msg: print(f\"\u4e3b\u8ba2\u5355: {msg.master_order_id}\"),\r\n    on_order=lambda msg: print(f\"\u5b50\u8ba2\u5355: {msg.order_id}\"),\r\n    on_fill=lambda msg: print(f\"\u6210\u4ea4: {msg.filled_qty}\")\r\n)\r\n\r\nws_service.set_handlers(handlers)\r\n\r\n# \u83b7\u53d6ListenKey\u5e76\u8fde\u63a5\r\nlisten_key = api.create_listen_key()['listenKey']\r\nws_service.connect(listen_key)\r\n\r\n# \u4fdd\u6301\u8fde\u63a5\r\nimport time\r\ntry:\r\n    while True:\r\n        time.sleep(1)\r\nexcept KeyboardInterrupt:\r\n    ws_service.close()\r\n```\r\n\r\n## \u8d21\u732e\u6307\u5357\r\n\r\n\u6b22\u8fce\u63d0\u4ea4 Issue \u548c Pull Request\uff01\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.6",
    "project_urls": {
        "Homepage": "https://github.com/Quantum-Execute/qe-connector-python"
    },
    "split_keywords": [
        "quantum-execute",
        " public api"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "f5def8435540984fdb3a0c67f3c12c7257f32da7e9683dcfb74b99812ebf75d7",
                "md5": "942772801b1e06fb1025441f357487db",
                "sha256": "2d324166b485b525710469b6cd0f564b5fbd08b69ac69c08aa4c427f4faefd14"
            },
            "downloads": -1,
            "filename": "qe_connector-1.0.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "942772801b1e06fb1025441f357487db",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 37784,
            "upload_time": "2025-09-14T17:58:23",
            "upload_time_iso_8601": "2025-09-14T17:58:23.593514Z",
            "url": "https://files.pythonhosted.org/packages/f5/de/f8435540984fdb3a0c67f3c12c7257f32da7e9683dcfb74b99812ebf75d7/qe_connector-1.0.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "79fa3adabd3eb42aeb3f0b538c1913b72564ffdd085f52991df9f7106f4565ff",
                "md5": "bd64aec36ddad62724c4f725ded4fc6f",
                "sha256": "5dbf962fae11fb2535eb55525e4f41ca9ea7ebfd16e9b8a807d0d0f8279970f6"
            },
            "downloads": -1,
            "filename": "qe-connector-1.0.6.tar.gz",
            "has_sig": false,
            "md5_digest": "bd64aec36ddad62724c4f725ded4fc6f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 56723,
            "upload_time": "2025-09-14T17:58:25",
            "upload_time_iso_8601": "2025-09-14T17:58:25.391799Z",
            "url": "https://files.pythonhosted.org/packages/79/fa/3adabd3eb42aeb3f0b538c1913b72564ffdd085f52991df9f7106f4565ff/qe-connector-1.0.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-14 17:58:25",
    "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.33406s