cyqnt-trd 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cyqnt_trd/__init__.py +26 -0
- cyqnt_trd/backtesting/README.md +264 -0
- cyqnt_trd/backtesting/__init__.py +12 -0
- cyqnt_trd/backtesting/factor_test.py +332 -0
- cyqnt_trd/backtesting/framework.py +311 -0
- cyqnt_trd/backtesting/strategy_backtest.py +545 -0
- cyqnt_trd/diagnose_api.py +28 -0
- cyqnt_trd/get_data/__init__.py +15 -0
- cyqnt_trd/get_data/get_futures_data.py +472 -0
- cyqnt_trd/get_data/get_trending_data.py +771 -0
- cyqnt_trd/online_trading/__init__.py +13 -0
- cyqnt_trd/online_trading/realtime_price_tracker.py +1001 -0
- cyqnt_trd/test.py +119 -0
- cyqnt_trd/test_script/README.md +411 -0
- cyqnt_trd/test_script/get_network_info.py +192 -0
- cyqnt_trd/test_script/get_symbols_by_volume.py +227 -0
- cyqnt_trd/test_script/realtime_price_tracker.py +839 -0
- cyqnt_trd/test_script/test_alpha.py +261 -0
- cyqnt_trd/test_script/test_kline_data.py +479 -0
- cyqnt_trd/test_script/test_order.py +1360 -0
- cyqnt_trd/trading_signal/README.md +276 -0
- cyqnt_trd/trading_signal/__init__.py +17 -0
- cyqnt_trd/trading_signal/example_test_alpha.py +430 -0
- cyqnt_trd/trading_signal/example_usage.py +431 -0
- cyqnt_trd/trading_signal/factor/__init__.py +18 -0
- cyqnt_trd/trading_signal/factor/ma_factor.py +75 -0
- cyqnt_trd/trading_signal/factor/rsi_factor.py +56 -0
- cyqnt_trd/trading_signal/selected_alpha/__init__.py +158 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha1.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha10.py +90 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha100.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha101.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha11.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha12.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha13.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha14.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha15.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha16.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha17.py +88 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha18.py +88 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha19.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha2.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha20.py +88 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha21.py +89 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha22.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha23.py +88 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha24.py +88 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha25.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha26.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha27.py +88 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha28.py +88 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha29.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha3.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha30.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha31.py +90 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha32.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha33.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha34.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha35.py +88 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha36.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha37.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha38.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha39.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha4.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha40.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha41.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha42.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha43.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha44.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha45.py +88 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha46.py +89 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha47.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha48.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha49.py +88 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha5.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha50.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha51.py +88 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha52.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha53.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha54.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha55.py +88 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha56.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha57.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha58.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha59.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha6.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha60.py +89 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha61.py +88 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha62.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha63.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha64.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha65.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha66.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha67.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha68.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha69.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha7.py +88 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha70.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha71.py +92 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha72.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha73.py +91 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha74.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha75.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha76.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha77.py +92 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha78.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha79.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha8.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha80.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha81.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha82.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha83.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha84.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha85.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha86.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha87.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha88.py +92 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha89.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha9.py +90 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha90.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha91.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha92.py +92 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha93.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha94.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha95.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha96.py +92 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha97.py +74 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha98.py +87 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha99.py +86 -0
- cyqnt_trd/trading_signal/selected_alpha/alpha_utils.py +342 -0
- cyqnt_trd/trading_signal/selected_alpha/create_all_alphas.py +279 -0
- cyqnt_trd/trading_signal/selected_alpha/generate_alphas.py +133 -0
- cyqnt_trd/trading_signal/selected_alpha/test_alpha.py +261 -0
- cyqnt_trd/trading_signal/signal/__init__.py +20 -0
- cyqnt_trd/trading_signal/signal/factor_based_signal.py +387 -0
- cyqnt_trd/trading_signal/signal/ma_signal.py +163 -0
- cyqnt_trd/utils/__init__.py +3 -0
- cyqnt_trd/utils/set_user.py +33 -0
- cyqnt_trd-0.1.2.dist-info/METADATA +148 -0
- cyqnt_trd-0.1.2.dist-info/RECORD +147 -0
- cyqnt_trd-0.1.2.dist-info/WHEEL +5 -0
- cyqnt_trd-0.1.2.dist-info/licenses/LICENSE +21 -0
- cyqnt_trd-0.1.2.dist-info/top_level.txt +2 -0
- test/real_time_trade.py +746 -0
- test/test_example_usage.py +381 -0
- test/test_get_data.py +310 -0
- test/test_realtime_price_tracker.py +546 -0
cyqnt_trd/test.py
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# import logging
|
|
2
|
+
# from binance_common.configuration import ConfigurationRestAPI
|
|
3
|
+
# from binance_common.constants import ALGO_REST_API_PROD_URL
|
|
4
|
+
# from binance_common.errors import (
|
|
5
|
+
# ClientError,
|
|
6
|
+
# UnauthorizedError,
|
|
7
|
+
# ForbiddenError,
|
|
8
|
+
# TooManyRequestsError,
|
|
9
|
+
# RequiredError,
|
|
10
|
+
# RateLimitBanError,
|
|
11
|
+
# ServerError,
|
|
12
|
+
# NetworkError,
|
|
13
|
+
# NotFoundError,
|
|
14
|
+
# BadRequestError,
|
|
15
|
+
# )
|
|
16
|
+
# from binance_sdk_algo.algo import Algo
|
|
17
|
+
|
|
18
|
+
# logging.basicConfig(
|
|
19
|
+
# level=logging.INFO,
|
|
20
|
+
# format='%(asctime)s - %(levelname)s - %(message)s'
|
|
21
|
+
# )
|
|
22
|
+
|
|
23
|
+
# # Configuration
|
|
24
|
+
# configuration = ConfigurationRestAPI(
|
|
25
|
+
# api_key="yNCZdF58V32y7oL2EATCIUKlmn8wkQ8ywoQukGIR7w4nkXBLldUFgld68I2xN0fj",
|
|
26
|
+
# api_secret="xktvKv6fcTxcgGeLrAmC3MMpX5qcDntzvBByVTPTyHEsNThg7rHoRW48qQhUpP0k",
|
|
27
|
+
# base_path=ALGO_REST_API_PROD_URL
|
|
28
|
+
# )
|
|
29
|
+
|
|
30
|
+
# client = Algo(config_rest_api=configuration)
|
|
31
|
+
|
|
32
|
+
# try:
|
|
33
|
+
# logging.info("Attempting to query historical algo orders...")
|
|
34
|
+
# response = client.rest_api.query_historical_algo_orders_spot_algo()
|
|
35
|
+
|
|
36
|
+
# data = response.data()
|
|
37
|
+
# logging.info(f"query_historical_algo_orders_spot_algo() response: {data}")
|
|
38
|
+
# except UnauthorizedError as e:
|
|
39
|
+
# logging.error("=" * 60)
|
|
40
|
+
# logging.error("UNAUTHORIZED ERROR - Invalid API credentials")
|
|
41
|
+
# logging.error("=" * 60)
|
|
42
|
+
# logging.error(f"Error details: {e}")
|
|
43
|
+
# logging.error("\nTroubleshooting steps:")
|
|
44
|
+
# logging.error("1. Verify your API key is correct")
|
|
45
|
+
# logging.error("2. Verify your API secret is correct")
|
|
46
|
+
# logging.error("3. Check if the API key is enabled in your Binance account")
|
|
47
|
+
# logging.error("4. Ensure the API key hasn't been deleted or revoked")
|
|
48
|
+
# except ForbiddenError as e:
|
|
49
|
+
# logging.error("=" * 60)
|
|
50
|
+
# logging.error("FORBIDDEN ERROR - API key permissions or IP restrictions")
|
|
51
|
+
# logging.error("=" * 60)
|
|
52
|
+
# logging.error(f"Error details: {e}")
|
|
53
|
+
# logging.error("\nTroubleshooting steps:")
|
|
54
|
+
# logging.error("1. Check if your API key has 'Enable Reading' permission")
|
|
55
|
+
# logging.error("2. Check if your API key has 'Enable Spot & Margin Trading' permission (if needed)")
|
|
56
|
+
# logging.error("3. Verify your IP address is whitelisted (if IP restrictions are enabled)")
|
|
57
|
+
# logging.error("4. Go to Binance API Management and check:")
|
|
58
|
+
# logging.error(" - API key permissions")
|
|
59
|
+
# logging.error(" - IP access restrictions (if enabled, add your current IP)")
|
|
60
|
+
# except TooManyRequestsError as e:
|
|
61
|
+
# logging.error("=" * 60)
|
|
62
|
+
# logging.error("RATE LIMIT EXCEEDED")
|
|
63
|
+
# logging.error("=" * 60)
|
|
64
|
+
# logging.error(f"Error details: {e}")
|
|
65
|
+
# logging.error("\nPlease wait before making another request")
|
|
66
|
+
# except RateLimitBanError as e:
|
|
67
|
+
# logging.error("=" * 60)
|
|
68
|
+
# logging.error("IP ADDRESS BANNED - Excessive rate limit violations")
|
|
69
|
+
# logging.error("=" * 60)
|
|
70
|
+
# logging.error(f"Error details: {e}")
|
|
71
|
+
# logging.error("\nYour IP has been temporarily banned. Please wait before retrying.")
|
|
72
|
+
# except BadRequestError as e:
|
|
73
|
+
# logging.error("=" * 60)
|
|
74
|
+
# logging.error("BAD REQUEST - Invalid request parameters")
|
|
75
|
+
# logging.error("=" * 60)
|
|
76
|
+
# logging.error(f"Error details: {e}")
|
|
77
|
+
# except ServerError as e:
|
|
78
|
+
# logging.error("=" * 60)
|
|
79
|
+
# logging.error("SERVER ERROR - Binance server issue")
|
|
80
|
+
# logging.error("=" * 60)
|
|
81
|
+
# logging.error(f"Error details: {e}")
|
|
82
|
+
# logging.error("\nThis is a server-side issue. Please try again later.")
|
|
83
|
+
# except NetworkError as e:
|
|
84
|
+
# logging.error("=" * 60)
|
|
85
|
+
# logging.error("NETWORK ERROR - Connection issue")
|
|
86
|
+
# logging.error("=" * 60)
|
|
87
|
+
# logging.error(f"Error details: {e}")
|
|
88
|
+
# logging.error("\nCheck your internet connection and try again.")
|
|
89
|
+
# except Exception as e:
|
|
90
|
+
# logging.error("=" * 60)
|
|
91
|
+
# logging.error("UNEXPECTED ERROR")
|
|
92
|
+
# logging.error("=" * 60)
|
|
93
|
+
# logging.error(f"Error type: {type(e).__name__}")
|
|
94
|
+
# logging.error(f"Error details: {e}")
|
|
95
|
+
# logging.error(f"Full error: {str(e)}")
|
|
96
|
+
|
|
97
|
+
# # Try to get more details if available
|
|
98
|
+
# if hasattr(e, 'response'):
|
|
99
|
+
# logging.error(f"Response: {e.response}")
|
|
100
|
+
# if hasattr(e, 'status_code'):
|
|
101
|
+
# logging.error(f"Status code: {e.status_code}")
|
|
102
|
+
|
|
103
|
+
from binance_common.configuration import ConfigurationRestAPI
|
|
104
|
+
from binance_common.constants import ALGO_REST_API_PROD_URL
|
|
105
|
+
from binance_sdk_algo.algo import Algo
|
|
106
|
+
import logging
|
|
107
|
+
|
|
108
|
+
logging.basicConfig(level=logging.INFO)
|
|
109
|
+
configuration = ConfigurationRestAPI(api_key="yNCZdF58V32y7oL2EATCIUKlmn8wkQ8ywoQukGIR7w4nkXBLldUFgld68I2xN0fj", api_secret="xktvKv6fcTxcgGeLrAmC3MMpX5qcDntzvBByVTPTyHEsNThg7rHoRW48qQhUpP0k", base_path=ALGO_REST_API_PROD_URL)
|
|
110
|
+
|
|
111
|
+
client = Algo(config_rest_api=configuration)
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
response = client.rest_api.query_historical_algo_orders_spot_algo()
|
|
115
|
+
|
|
116
|
+
data = response.data()
|
|
117
|
+
logging.info(f"query_historical_algo_orders_spot_algo() response: {data}")
|
|
118
|
+
except Exception as e:
|
|
119
|
+
logging.error(f"query_historical_algo_orders_spot_algo() error: {e}")
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
# Test Script 使用说明
|
|
2
|
+
|
|
3
|
+
## get_symbols_by_volume.py
|
|
4
|
+
|
|
5
|
+
获取 Binance 所有合约和现货交易对列表,并按24小时交易量排序。
|
|
6
|
+
|
|
7
|
+
### 功能
|
|
8
|
+
|
|
9
|
+
- 获取所有现货交易对列表,按24小时交易量降序排序
|
|
10
|
+
- 获取所有合约交易对列表,按24小时交易量降序排序
|
|
11
|
+
- 在控制台显示前50个交易量最大的交易对
|
|
12
|
+
- 将结果保存为 JSON 文件到 `tmp/` 目录
|
|
13
|
+
|
|
14
|
+
### 使用方法
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# 方式1: 作为模块运行(推荐)
|
|
18
|
+
cd /Users/user/Desktop/repo/cyqnt_trd
|
|
19
|
+
python -m cyqnt_trd.test_script.get_symbols_by_volume
|
|
20
|
+
|
|
21
|
+
# 方式2: 直接运行脚本
|
|
22
|
+
cd /Users/user/Desktop/repo/cyqnt_trd
|
|
23
|
+
python cyqnt_trd/test_script/get_symbols_by_volume.py
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 输出
|
|
27
|
+
|
|
28
|
+
脚本会在控制台显示:
|
|
29
|
+
- 现货交易对列表(前50个,按交易量排序)
|
|
30
|
+
- 合约交易对列表(前50个,按交易量排序)
|
|
31
|
+
|
|
32
|
+
同时会将完整列表保存为 JSON 文件:
|
|
33
|
+
- `tmp/spot_symbols_by_volume_YYYYMMDD_HHMMSS.json` - 现货交易对列表
|
|
34
|
+
- `tmp/futures_symbols_by_volume_YYYYMMDD_HHMMSS.json` - 合约交易对列表
|
|
35
|
+
|
|
36
|
+
### JSON 文件格式
|
|
37
|
+
|
|
38
|
+
每个 JSON 文件包含一个数组,每个元素包含:
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"symbol": "BTCUSDT",
|
|
42
|
+
"volume": 1234567890.12,
|
|
43
|
+
"volume_str": "1,234,567,890.12"
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 注意事项
|
|
48
|
+
|
|
49
|
+
- 脚本使用公开 API,不需要 API Key 和 Secret(可以设置为空字符串)
|
|
50
|
+
- 交易量数据基于24小时滚动窗口
|
|
51
|
+
- 交易量以 USDT 计价(quoteVolume)
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## test_order.py
|
|
56
|
+
|
|
57
|
+
测试 Binance 下单接口,包含现货和合约的买卖功能。
|
|
58
|
+
|
|
59
|
+
### 功能
|
|
60
|
+
|
|
61
|
+
- **现货交易测试**:
|
|
62
|
+
- 市价买入/卖出
|
|
63
|
+
- 限价买入/卖出
|
|
64
|
+
|
|
65
|
+
- **合约交易测试**:
|
|
66
|
+
- 市价买入/卖出
|
|
67
|
+
- 限价买入/卖出
|
|
68
|
+
|
|
69
|
+
- **撤单功能**:
|
|
70
|
+
- 撤销现货订单(单个/批量)
|
|
71
|
+
- 撤销合约订单
|
|
72
|
+
- 查询当前挂单
|
|
73
|
+
|
|
74
|
+
### 使用方法
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# 方式1: 作为模块运行(推荐)
|
|
78
|
+
cd /Users/user/Desktop/repo/cyqnt_trd
|
|
79
|
+
python -m cyqnt_trd.test_script.test_order
|
|
80
|
+
|
|
81
|
+
# 方式2: 直接运行脚本
|
|
82
|
+
cd /Users/user/Desktop/repo/cyqnt_trd
|
|
83
|
+
python cyqnt_trd/test_script/test_order.py
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 函数说明
|
|
87
|
+
|
|
88
|
+
#### 现货交易函数
|
|
89
|
+
|
|
90
|
+
- `test_spot_buy_market(symbol, quantity)` - 现货市价买入
|
|
91
|
+
- `test_spot_sell_market(symbol, quantity)` - 现货市价卖出
|
|
92
|
+
- `test_spot_buy_limit(symbol, quantity, price)` - 现货限价买入
|
|
93
|
+
- `test_spot_sell_limit(symbol, quantity, price)` - 现货限价卖出
|
|
94
|
+
|
|
95
|
+
#### 合约交易函数
|
|
96
|
+
|
|
97
|
+
- `test_futures_buy_market(symbol, quantity)` - 合约市价买入
|
|
98
|
+
- `test_futures_sell_market(symbol, quantity)` - 合约市价卖出
|
|
99
|
+
- `test_futures_buy_limit(symbol, quantity, price)` - 合约限价买入
|
|
100
|
+
- `test_futures_sell_limit(symbol, quantity, price)` - 合约限价卖出
|
|
101
|
+
|
|
102
|
+
#### 撤单函数
|
|
103
|
+
|
|
104
|
+
- `cancel_spot_order(symbol, order_id, orig_client_order_id)` - 撤销现货订单
|
|
105
|
+
- `cancel_futures_order(symbol, order_id, orig_client_order_id)` - 撤销合约订单
|
|
106
|
+
- `cancel_all_spot_orders(symbol)` - 撤销现货某个交易对的所有挂单
|
|
107
|
+
- `get_spot_open_orders(symbol)` - 获取现货当前挂单
|
|
108
|
+
- `get_futures_open_orders(symbol)` - 获取合约当前挂单
|
|
109
|
+
- `show_spot_open_orders(symbol)` - 显示现货当前挂单(格式化输出)
|
|
110
|
+
- `show_futures_open_orders(symbol)` - 显示合约当前挂单(格式化输出)
|
|
111
|
+
|
|
112
|
+
#### 通用函数
|
|
113
|
+
|
|
114
|
+
- `test_spot_order(symbol, side, order_type, quantity, price, time_in_force)` - 现货下单通用函数
|
|
115
|
+
- `test_futures_order(symbol, side, order_type, quantity, price, time_in_force, position_side, reduce_only)` - 合约下单通用函数
|
|
116
|
+
|
|
117
|
+
### 参数说明
|
|
118
|
+
|
|
119
|
+
- `symbol`: 交易对,如 "BTCUSDT"
|
|
120
|
+
- `side`: 买卖方向,"BUY" 或 "SELL"
|
|
121
|
+
- `order_type`: 订单类型,"MARKET" 或 "LIMIT"
|
|
122
|
+
- `quantity`: 数量(必需)
|
|
123
|
+
- `price`: 价格(LIMIT 订单必需)
|
|
124
|
+
- `time_in_force`: 有效期,"GTC", "IOC", "FOK"(默认 "GTC")
|
|
125
|
+
- `position_side`: 持仓方向(仅合约),"LONG", "SHORT", "BOTH"
|
|
126
|
+
- `reduce_only`: 是否只减仓(仅合约),"true" 或 "false"
|
|
127
|
+
|
|
128
|
+
### 使用示例
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
from cyqnt_trd.test_script.test_order import (
|
|
132
|
+
test_spot_buy_market,
|
|
133
|
+
test_spot_sell_market,
|
|
134
|
+
test_futures_buy_market,
|
|
135
|
+
test_futures_sell_market
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# 现货市价买入 0.001 BTC
|
|
139
|
+
result = test_spot_buy_market("BTCUSDT", 0.001)
|
|
140
|
+
|
|
141
|
+
# 现货市价卖出 0.001 BTC
|
|
142
|
+
result = test_spot_sell_market("BTCUSDT", 0.001)
|
|
143
|
+
|
|
144
|
+
# 合约市价买入 0.001 BTC
|
|
145
|
+
result = test_futures_buy_market("BTCUSDT", 0.001)
|
|
146
|
+
|
|
147
|
+
# 合约市价卖出 0.001 BTC
|
|
148
|
+
result = test_futures_sell_market("BTCUSDT", 0.001)
|
|
149
|
+
|
|
150
|
+
# 查看当前挂单
|
|
151
|
+
from cyqnt_trd.test_script.test_order import (
|
|
152
|
+
show_spot_open_orders,
|
|
153
|
+
show_futures_open_orders
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
show_spot_open_orders("BTCUSDT") # 查看现货 BTCUSDT 的挂单
|
|
157
|
+
show_futures_open_orders() # 查看合约所有交易对的挂单
|
|
158
|
+
|
|
159
|
+
# 撤销订单
|
|
160
|
+
from cyqnt_trd.test_script.test_order import (
|
|
161
|
+
cancel_spot_order,
|
|
162
|
+
cancel_futures_order,
|
|
163
|
+
cancel_all_spot_orders
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
# 通过订单ID撤销现货订单
|
|
167
|
+
cancel_spot_order("BTCUSDT", order_id=12345678)
|
|
168
|
+
|
|
169
|
+
# 通过客户端订单ID撤销合约订单
|
|
170
|
+
cancel_futures_order("BTCUSDT", orig_client_order_id="my_order_123")
|
|
171
|
+
|
|
172
|
+
# 撤销现货某个交易对的所有挂单
|
|
173
|
+
cancel_all_spot_orders("BTCUSDT")
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### 环境变量
|
|
177
|
+
|
|
178
|
+
脚本支持通过环境变量配置 API 密钥:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
export API_KEY="your_api_key"
|
|
182
|
+
export API_SECRET="your_api_secret"
|
|
183
|
+
export BASE_PATH="https://api.binance.com" # 可选,默认使用生产环境
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 注意事项
|
|
187
|
+
|
|
188
|
+
⚠️ **重要警告**:
|
|
189
|
+
|
|
190
|
+
1. **实际下单风险**:此脚本会进行真实交易,请谨慎使用!
|
|
191
|
+
2. **测试环境**:建议先在测试网络或使用小额资金测试
|
|
192
|
+
3. **API 密钥安全**:不要将 API 密钥提交到版本控制系统
|
|
193
|
+
4. **默认参数**:脚本中的测试函数默认已注释,避免意外下单
|
|
194
|
+
5. **余额检查**:下单前请确保账户有足够的余额
|
|
195
|
+
6. **交易对验证**:确保交易对符号正确且可交易
|
|
196
|
+
7. **价格精度**:注意交易对的价格和数量精度要求
|
|
197
|
+
|
|
198
|
+
### 返回格式
|
|
199
|
+
|
|
200
|
+
函数返回字典,包含:
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
{
|
|
204
|
+
"success": True, # 是否成功
|
|
205
|
+
"rate_limits": {...}, # API 限流信息
|
|
206
|
+
"order": {...} # 订单详情
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
如果失败:
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
{
|
|
214
|
+
"success": False,
|
|
215
|
+
"error": "错误信息",
|
|
216
|
+
"traceback": "错误堆栈"
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## realtime_price_tracker.py
|
|
223
|
+
|
|
224
|
+
实时价格跟踪脚本,通过 WebSocket 实时跟踪当前价格数据,并向前追溯 n 个周期,为实时计算 signal 和计算 strategy 做准备。
|
|
225
|
+
|
|
226
|
+
### 功能
|
|
227
|
+
|
|
228
|
+
- **实时价格跟踪**:通过 WebSocket 实时接收 K 线数据
|
|
229
|
+
- **历史数据加载**:自动加载历史 n 个周期的数据
|
|
230
|
+
- **数据管理**:维护一个包含历史数据的 DataFrame,格式与回测框架兼容
|
|
231
|
+
- **回调机制**:支持注册回调函数,在新 K 线到达或数据更新时触发
|
|
232
|
+
- **自动数据更新**:当新的 K 线关闭时,自动更新 DataFrame
|
|
233
|
+
|
|
234
|
+
### 使用方法
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# 方式1: 作为模块运行(推荐)
|
|
238
|
+
cd /Users/user/Desktop/repo/cyqnt_trd
|
|
239
|
+
python -m cyqnt_trd.test_script.realtime_price_tracker
|
|
240
|
+
|
|
241
|
+
# 方式2: 直接运行脚本
|
|
242
|
+
cd /Users/user/Desktop/repo/cyqnt_trd
|
|
243
|
+
python cyqnt_trd/test_script/realtime_price_tracker.py
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### 基本用法
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
import asyncio
|
|
250
|
+
from cyqnt_trd.test_script.realtime_price_tracker import RealtimePriceTracker
|
|
251
|
+
|
|
252
|
+
async def main():
|
|
253
|
+
# 创建跟踪器
|
|
254
|
+
tracker = RealtimePriceTracker(
|
|
255
|
+
symbol="BTCUSDT",
|
|
256
|
+
interval="1m", # 1分钟K线
|
|
257
|
+
lookback_periods=100 # 向前追溯100个周期
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
# 注册回调函数
|
|
261
|
+
def on_new_kline(kline_dict, data_df):
|
|
262
|
+
print(f"新 K 线: {kline_dict['open_time_str']}, 价格: {kline_dict['close_price']}")
|
|
263
|
+
print(f"当前数据量: {len(data_df)} 条")
|
|
264
|
+
|
|
265
|
+
tracker.register_on_new_kline(on_new_kline)
|
|
266
|
+
|
|
267
|
+
# 运行跟踪器
|
|
268
|
+
await tracker.run_forever()
|
|
269
|
+
|
|
270
|
+
asyncio.run(main())
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### 高级用法:结合 Signal 和 Strategy 计算
|
|
274
|
+
|
|
275
|
+
```python
|
|
276
|
+
import asyncio
|
|
277
|
+
from cyqnt_trd.test_script.realtime_price_tracker import RealtimePriceTracker
|
|
278
|
+
from cyqnt_trd.trading_signal.signal.ma_signal import ma_signal
|
|
279
|
+
|
|
280
|
+
async def main():
|
|
281
|
+
tracker = RealtimePriceTracker(
|
|
282
|
+
symbol="BTCUSDT",
|
|
283
|
+
interval="1m",
|
|
284
|
+
lookback_periods=100
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
def calculate_signal(kline_dict, data_df):
|
|
288
|
+
"""在新 K 线到达时计算交易信号"""
|
|
289
|
+
if len(data_df) < 10: # 确保有足够的数据
|
|
290
|
+
return
|
|
291
|
+
|
|
292
|
+
# 使用最后一行作为当前数据点
|
|
293
|
+
current_slice = data_df.iloc[-10:] # 使用最近10条数据
|
|
294
|
+
|
|
295
|
+
# 计算信号(假设没有持仓)
|
|
296
|
+
signal = ma_signal(
|
|
297
|
+
data_slice=current_slice,
|
|
298
|
+
position=0.0, # 当前持仓
|
|
299
|
+
entry_price=0.0, # 入场价格
|
|
300
|
+
entry_index=-1, # 入场索引
|
|
301
|
+
take_profit=0.1, # 止盈10%
|
|
302
|
+
stop_loss=0.05, # 止损5%
|
|
303
|
+
period=5 # MA周期
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
print(f"时间: {kline_dict['open_time_str']}, 价格: {kline_dict['close_price']}, 信号: {signal}")
|
|
307
|
+
|
|
308
|
+
tracker.register_on_new_kline(calculate_signal)
|
|
309
|
+
await tracker.run_forever()
|
|
310
|
+
|
|
311
|
+
asyncio.run(main())
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### API 说明
|
|
315
|
+
|
|
316
|
+
#### RealtimePriceTracker 类
|
|
317
|
+
|
|
318
|
+
**初始化参数:**
|
|
319
|
+
|
|
320
|
+
- `symbol` (str): 交易对符号,例如 'BTCUSDT', 'ETHUSDT'
|
|
321
|
+
- `interval` (str): 时间间隔,例如 '1m', '5m', '1h', '1d'
|
|
322
|
+
- 可选值: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M
|
|
323
|
+
- `lookback_periods` (int): 向前追溯的周期数(默认100)
|
|
324
|
+
- `market_type` (str): 市场类型,'futures' 或 'spot'(默认 'futures',目前只支持期货)
|
|
325
|
+
|
|
326
|
+
**主要方法:**
|
|
327
|
+
|
|
328
|
+
- `load_historical_data()`: 加载历史数据(异步)
|
|
329
|
+
- `start()`: 启动实时跟踪(异步)
|
|
330
|
+
- `stop()`: 停止实时跟踪(异步)
|
|
331
|
+
- `run_forever()`: 运行实时跟踪直到中断(异步)
|
|
332
|
+
- `get_data()`: 获取当前的数据 DataFrame
|
|
333
|
+
- `get_latest_price()`: 获取最新价格
|
|
334
|
+
- `register_on_new_kline(callback)`: 注册新 K 线回调函数
|
|
335
|
+
- `register_on_data_updated(callback)`: 注册数据更新回调函数
|
|
336
|
+
|
|
337
|
+
**回调函数签名:**
|
|
338
|
+
|
|
339
|
+
- `on_new_kline(kline_dict: Dict[str, Any], data_df: pd.DataFrame) -> None`
|
|
340
|
+
- 当新的 K 线关闭时调用
|
|
341
|
+
- `kline_dict`: 新 K 线的字典数据
|
|
342
|
+
- `data_df`: 更新后的完整数据 DataFrame
|
|
343
|
+
|
|
344
|
+
- `on_data_updated(data_df: pd.DataFrame) -> None`
|
|
345
|
+
- 当数据更新时调用
|
|
346
|
+
- `data_df`: 更新后的完整数据 DataFrame
|
|
347
|
+
|
|
348
|
+
### 数据格式
|
|
349
|
+
|
|
350
|
+
跟踪器维护的 DataFrame 包含以下列:
|
|
351
|
+
|
|
352
|
+
- `datetime`: 时间(pandas Timestamp)
|
|
353
|
+
- `open_time`: 开盘时间(毫秒时间戳)
|
|
354
|
+
- `open_time_str`: 开盘时间(字符串格式)
|
|
355
|
+
- `open_price`: 开盘价
|
|
356
|
+
- `high_price`: 最高价
|
|
357
|
+
- `low_price`: 最低价
|
|
358
|
+
- `close_price`: 收盘价
|
|
359
|
+
- `volume`: 成交量
|
|
360
|
+
- `close_time`: 收盘时间(毫秒时间戳)
|
|
361
|
+
- `close_time_str`: 收盘时间(字符串格式)
|
|
362
|
+
- `quote_volume`: 成交额
|
|
363
|
+
- `trades`: 成交笔数
|
|
364
|
+
- `taker_buy_base_volume`: 主动买入成交量
|
|
365
|
+
- `taker_buy_quote_volume`: 主动买入成交额
|
|
366
|
+
- `ignore`: 忽略字段
|
|
367
|
+
|
|
368
|
+
该格式与回测框架兼容,可以直接用于 signal 和 strategy 计算。
|
|
369
|
+
|
|
370
|
+
### 注意事项
|
|
371
|
+
|
|
372
|
+
1. **数据量限制**:`lookback_periods` 参数控制维护的历史数据量,数据会自动滚动更新
|
|
373
|
+
2. **K 线关闭**:只有关闭的 K 线(`is_closed = True`)才会添加到 DataFrame,未关闭的 K 线只更新 `latest_kline`
|
|
374
|
+
3. **异步操作**:所有网络操作都是异步的,需要使用 `asyncio` 运行
|
|
375
|
+
4. **错误处理**:脚本包含错误处理和日志记录,便于调试
|
|
376
|
+
5. **API 密钥**:WebSocket streams 不需要 API 密钥,但 REST API 可能需要(用于加载历史数据)
|
|
377
|
+
6. **SSL 证书验证**:如果遇到 SSL 证书验证错误(如 `CERTIFICATE_VERIFY_FAILED`),可以在初始化时设置 `ssl_verify=False`(仅用于开发/测试环境)
|
|
378
|
+
|
|
379
|
+
### 处理 SSL 证书验证错误
|
|
380
|
+
|
|
381
|
+
如果遇到 SSL 证书验证错误,可以按以下方式处理:
|
|
382
|
+
|
|
383
|
+
```python
|
|
384
|
+
# 方式1: 在初始化时禁用 SSL 验证(仅用于开发/测试)
|
|
385
|
+
tracker = RealtimePriceTracker(
|
|
386
|
+
symbol="BTCUSDT",
|
|
387
|
+
interval="1m",
|
|
388
|
+
lookback_periods=100,
|
|
389
|
+
ssl_verify=False # 禁用 SSL 证书验证
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
# 方式2: 修复系统 SSL 证书(推荐用于生产环境)
|
|
393
|
+
# macOS: 运行以下命令安装证书
|
|
394
|
+
# /Applications/Python\ 3.x/Install\ Certificates.command
|
|
395
|
+
# 或者手动安装证书到系统
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
**警告**:禁用 SSL 验证会降低安全性,仅应在开发/测试环境中使用。生产环境应修复 SSL 证书问题。
|
|
399
|
+
|
|
400
|
+
### 环境变量
|
|
401
|
+
|
|
402
|
+
脚本支持通过环境变量配置:
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
export API_KEY="your_api_key" # 可选,用于 REST API
|
|
406
|
+
export API_SECRET="your_api_secret" # 可选,用于 REST API
|
|
407
|
+
export BASE_PATH="https://fapi.binance.com" # 可选,默认使用生产环境
|
|
408
|
+
export STREAM_URL="wss://fstream.binance.com" # 可选,默认使用生产环境
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
|