cyqnt-trd 0.1.2__py3-none-any.whl → 0.1.7__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.
Files changed (40) hide show
  1. cyqnt_trd/CHANGELOG_0.1.7.md +111 -0
  2. cyqnt_trd/__init__.py +1 -1
  3. cyqnt_trd/backtesting/factor_test.py +3 -2
  4. cyqnt_trd/get_data/__init__.py +16 -1
  5. cyqnt_trd/get_data/get_futures_data.py +3 -3
  6. cyqnt_trd/get_data/get_kline_with_factor.py +808 -0
  7. cyqnt_trd/get_data/get_web3_trending_data.py +389 -0
  8. cyqnt_trd/online_trading/__init__.py +1 -0
  9. cyqnt_trd/online_trading/realtime_price_tracker.py +142 -2
  10. cyqnt_trd/trading_signal/example_usage.py +123 -7
  11. cyqnt_trd/trading_signal/factor/__init__.py +23 -0
  12. cyqnt_trd/trading_signal/factor/adx_factor.py +116 -0
  13. cyqnt_trd/trading_signal/factor/ao_factor.py +66 -0
  14. cyqnt_trd/trading_signal/factor/bbp_factor.py +68 -0
  15. cyqnt_trd/trading_signal/factor/cci_factor.py +65 -0
  16. cyqnt_trd/trading_signal/factor/ema_factor.py +102 -0
  17. cyqnt_trd/trading_signal/factor/macd_factor.py +97 -0
  18. cyqnt_trd/trading_signal/factor/momentum_factor.py +44 -0
  19. cyqnt_trd/trading_signal/factor/stochastic_factor.py +76 -0
  20. cyqnt_trd/trading_signal/factor/stochastic_tsi_factor.py +129 -0
  21. cyqnt_trd/trading_signal/factor/uo_factor.py +92 -0
  22. cyqnt_trd/trading_signal/factor/williams_r_factor.py +60 -0
  23. cyqnt_trd/trading_signal/factor_details.json +107 -0
  24. cyqnt_trd/trading_signal/selected_alpha/alpha1.py +4 -2
  25. cyqnt_trd/trading_signal/selected_alpha/alpha15.py +4 -2
  26. cyqnt_trd/trading_signal/selected_alpha/generate_alphas.py +1 -0
  27. {cyqnt_trd-0.1.2.dist-info → cyqnt_trd-0.1.7.dist-info}/METADATA +16 -12
  28. {cyqnt_trd-0.1.2.dist-info → cyqnt_trd-0.1.7.dist-info}/RECORD +34 -23
  29. {cyqnt_trd-0.1.2.dist-info → cyqnt_trd-0.1.7.dist-info}/WHEEL +1 -1
  30. test/real_time_trade.py +467 -10
  31. test/test_now_factor.py +1082 -0
  32. test/track_k_line_continue.py +372 -0
  33. cyqnt_trd/test_script/get_symbols_by_volume.py +0 -227
  34. cyqnt_trd/test_script/test_alpha.py +0 -261
  35. cyqnt_trd/test_script/test_kline_data.py +0 -479
  36. test/test_example_usage.py +0 -381
  37. test/test_get_data.py +0 -310
  38. test/test_realtime_price_tracker.py +0 -546
  39. {cyqnt_trd-0.1.2.dist-info → cyqnt_trd-0.1.7.dist-info}/licenses/LICENSE +0 -0
  40. {cyqnt_trd-0.1.2.dist-info → cyqnt_trd-0.1.7.dist-info}/top_level.txt +0 -0
@@ -1,381 +0,0 @@
1
- """
2
- 测试 cyqnt_trd package 的使用示例
3
-
4
- 参考 cyqnt_trd.trading_signal.example_usage,使用 package 方式导入和使用
5
- """
6
-
7
- import os
8
- from pathlib import Path
9
-
10
- # 使用 package 方式导入(假设已通过 pip install -e . 安装)
11
- from cyqnt_trd.backtesting import BacktestFramework
12
- from cyqnt_trd.trading_signal.factor import ma_factor, ma_cross_factor, rsi_factor
13
- from cyqnt_trd.trading_signal.signal import (
14
- ma_signal,
15
- ma_cross_signal,
16
- factor_based_signal,
17
- multi_factor_signal
18
- )
19
- from cyqnt_trd.trading_signal.selected_alpha import alpha1_factor
20
-
21
-
22
- def get_data_path(symbol: str = "BTCUSDT", data_type: str = "current") -> str:
23
- """
24
- 获取数据文件路径
25
-
26
- Args:
27
- symbol: 交易对符号,例如 'BTCUSDT'
28
- data_type: 数据类型,'current' 或 'futures'
29
-
30
- Returns:
31
- 数据文件路径
32
- """
33
- # 获取项目根目录(data_all)
34
- project_root = Path(__file__).parent.parent
35
- data_dir = project_root / "tmp" / "data" / f"{symbol}_{data_type}"
36
-
37
- # 查找 JSON 文件
38
- json_files = list(data_dir.glob("*.json"))
39
- if json_files:
40
- # 返回最新的文件
41
- return str(sorted(json_files, key=lambda x: x.stat().st_mtime, reverse=True)[0])
42
- else:
43
- raise FileNotFoundError(f"未找到 {symbol}_{data_type} 的数据文件")
44
-
45
-
46
- def test_1_use_factor():
47
- """
48
- 测试1: 使用factor中的因子进行因子测试
49
- """
50
- print("=" * 60)
51
- print("测试1: 使用factor中的因子进行因子测试")
52
- print("=" * 60)
53
-
54
- try:
55
- data_path = get_data_path("BTCUSDT", "current")
56
- print(f"使用数据文件: {data_path}")
57
- except FileNotFoundError as e:
58
- print(f"错误: {e}")
59
- return
60
-
61
- framework = BacktestFramework(data_path=data_path)
62
-
63
- # 使用factor中的ma_factor进行测试
64
- def ma_factor_wrapper(data_slice):
65
- return ma_factor(data_slice, period=5)
66
-
67
- factor_results = framework.test_factor(
68
- factor_func=ma_factor_wrapper,
69
- forward_periods=5,
70
- min_periods=10,
71
- factor_name="MA5因子(来自factor模块)"
72
- )
73
-
74
- # 保存结果到 result 目录
75
- save_dir = str(Path(__file__).parent.parent / "result")
76
- os.makedirs(save_dir, exist_ok=True)
77
- framework.print_factor_results(
78
- factor_results,
79
- save_dir=save_dir
80
- )
81
-
82
-
83
- def test_2_use_signal():
84
- """
85
- 测试2: 使用signal中的信号策略进行回测
86
- """
87
- print("\n" + "=" * 60)
88
- print("测试2: 使用signal中的信号策略进行回测")
89
- print("=" * 60)
90
-
91
- try:
92
- data_path = get_data_path("BTCUSDT", "current")
93
- print(f"使用数据文件: {data_path}")
94
- except FileNotFoundError as e:
95
- print(f"错误: {e}")
96
- return
97
-
98
- framework = BacktestFramework(data_path=data_path)
99
-
100
- # 使用signal中的ma_signal进行回测
101
- period = 3
102
- def ma_signal_wrapper(data_slice, position, entry_price, entry_index, take_profit, stop_loss, check_periods):
103
- return ma_signal(
104
- data_slice, position, entry_price, entry_index,
105
- take_profit, stop_loss, period=period
106
- )
107
-
108
- backtest_results = framework.backtest_strategy(
109
- signal_func=ma_signal_wrapper,
110
- min_periods=10,
111
- position_size=0.2,
112
- initial_capital=10000.0,
113
- commission_rate=0.00001,
114
- take_profit=0.03,
115
- stop_loss=0.1,
116
- strategy_name="MA3策略(来自signal模块)"
117
- )
118
-
119
- framework.print_backtest_results(backtest_results)
120
-
121
- # 保存结果
122
- save_dir = str(Path(__file__).parent.parent / "result")
123
- os.makedirs(save_dir, exist_ok=True)
124
- framework.plot_backtest_results(
125
- backtest_results,
126
- save_dir=save_dir
127
- )
128
-
129
-
130
- def test_3_factor_in_signal():
131
- """
132
- 测试3: 在signal中使用factor中的因子
133
- """
134
- print("\n" + "=" * 60)
135
- print("测试3: 在signal中使用factor中的因子")
136
- print("=" * 60)
137
-
138
- try:
139
- data_path = get_data_path("BTCUSDT", "current")
140
- print(f"使用数据文件: {data_path}")
141
- except FileNotFoundError as e:
142
- print(f"错误: {e}")
143
- return
144
-
145
- framework = BacktestFramework(data_path=data_path)
146
-
147
- # 使用factor_based_signal,它内部会使用factor中的因子
148
- def factor_signal_wrapper(data_slice, position, entry_price, entry_index, take_profit, stop_loss, check_periods):
149
- # 使用factor中的ma_factor
150
- factor_func = lambda d: ma_factor(d, period=5)
151
- return factor_based_signal(
152
- data_slice, position, entry_price, entry_index,
153
- take_profit, stop_loss, check_periods,
154
- factor_func=factor_func
155
- )
156
-
157
- backtest_results = framework.backtest_strategy(
158
- signal_func=factor_signal_wrapper,
159
- min_periods=35, # 至少需要35个周期
160
- position_size=0.2,
161
- initial_capital=10000.0,
162
- commission_rate=0.00001,
163
- take_profit=0.1,
164
- stop_loss=0.5,
165
- check_periods=1,
166
- strategy_name="基于MA因子的策略"
167
- )
168
-
169
- framework.print_backtest_results(backtest_results)
170
-
171
- # 保存结果
172
- save_dir = str(Path(__file__).parent.parent / "result")
173
- os.makedirs(save_dir, exist_ok=True)
174
- framework.plot_backtest_results(
175
- backtest_results,
176
- save_dir=save_dir
177
- )
178
-
179
-
180
- def test_4_multi_factor():
181
- """
182
- 测试4: 使用多因子组合策略
183
- """
184
- print("\n" + "=" * 60)
185
- print("测试4: 使用多因子组合策略")
186
- print("=" * 60)
187
-
188
- try:
189
- data_path = get_data_path("BTCUSDT", "current")
190
- print(f"使用数据文件: {data_path}")
191
- except FileNotFoundError as e:
192
- print(f"错误: {e}")
193
- return
194
-
195
- framework = BacktestFramework(data_path=data_path)
196
-
197
- # 使用multi_factor_signal,组合多个因子
198
- def multi_factor_signal_wrapper(data_slice, position, entry_price, entry_index, take_profit, stop_loss, check_periods):
199
- # 组合ma_factor和rsi_factor
200
- factor_funcs = [
201
- lambda d: ma_factor(d, period=5),
202
- lambda d: rsi_factor(d, period=14)
203
- ]
204
- weights = [0.6, 0.4] # MA因子权重0.6,RSI因子权重0.4
205
-
206
- return multi_factor_signal(
207
- data_slice, position, entry_price, entry_index,
208
- take_profit, stop_loss, check_periods,
209
- factor_funcs=factor_funcs,
210
- weights=weights
211
- )
212
-
213
- backtest_results = framework.backtest_strategy(
214
- signal_func=multi_factor_signal_wrapper,
215
- min_periods=20, # 需要更多周期因为RSI需要14个周期
216
- position_size=0.2,
217
- initial_capital=10000.0,
218
- commission_rate=0.00001,
219
- take_profit=0.1,
220
- stop_loss=0.5,
221
- check_periods=1,
222
- strategy_name="多因子组合策略(MA+RSI)"
223
- )
224
-
225
- framework.print_backtest_results(backtest_results)
226
-
227
- # 保存结果
228
- save_dir = str(Path(__file__).parent.parent / "result")
229
- os.makedirs(save_dir, exist_ok=True)
230
- framework.plot_backtest_results(
231
- backtest_results,
232
- save_dir=save_dir
233
- )
234
-
235
-
236
- def test_5_alpha1_factor():
237
- """
238
- 测试5: 使用Alpha#1因子进行因子测试
239
- """
240
- print("\n" + "=" * 60)
241
- print("测试5: 使用Alpha#1因子进行因子测试")
242
- print("=" * 60)
243
- print("\n因子说明:")
244
- print(" - 公式: rank(Ts_ArgMax(SignedPower(((returns<0)?stddev(returns,20):close),2.),5))-0.5)")
245
- print(" - 策略逻辑:对过去5天按照收盘价最高或下行波动率最高进行排名")
246
- print(" - 下行波动率最高的一天离计算时间越近,越可以投资")
247
- print(" - 收盘价最高离计算时间越近,越可以投资")
248
- print(" - 标签:mean-reversion+momentum")
249
- print()
250
-
251
- try:
252
- data_path = get_data_path("BTCUSDT", "futures")
253
- print(f"使用数据文件: {data_path}")
254
- except FileNotFoundError as e:
255
- print(f"错误: {e}")
256
- return
257
-
258
- framework = BacktestFramework(data_path=data_path)
259
-
260
- # 使用Alpha#1因子进行测试
261
- def alpha1_wrapper(data_slice):
262
- """
263
- Alpha#1 因子包装函数
264
-
265
- 使用默认参数:lookback_days=5, stddev_period=20, power=2.0
266
- """
267
- return alpha1_factor(
268
- data_slice,
269
- lookback_days=5,
270
- stddev_period=20,
271
- power=2.0
272
- )
273
-
274
- # 测试因子
275
- print("开始测试 Alpha#1 因子...")
276
- print(f" 回看天数: 5")
277
- print(f" 标准差周期: 20")
278
- print(f" 幂次: 2.0")
279
- print(f" 向前看周期: 7")
280
- print()
281
-
282
- factor_results = framework.test_factor(
283
- factor_func=alpha1_wrapper,
284
- forward_periods=7, # 未来7个周期
285
- min_periods=30, # 至少需要30个周期(5+20+一些缓冲)
286
- factor_name="Alpha#1因子"
287
- )
288
-
289
- # 打印结果并保存
290
- save_dir = str(Path(__file__).parent.parent / "result")
291
- os.makedirs(save_dir, exist_ok=True)
292
- framework.print_factor_results(
293
- factor_results,
294
- save_dir=save_dir
295
- )
296
-
297
-
298
- def test_6_alpha1_signal():
299
- """
300
- 测试6: 使用基于Alpha#1因子的信号策略进行回测
301
- """
302
- print("\n" + "=" * 60)
303
- print("测试6: 使用基于Alpha#1因子的信号策略进行回测")
304
- print("=" * 60)
305
-
306
- try:
307
- data_path = get_data_path("BTCUSDT", "futures")
308
- print(f"使用数据文件: {data_path}")
309
- except FileNotFoundError as e:
310
- print(f"错误: {e}")
311
- return
312
-
313
- framework = BacktestFramework(data_path=data_path)
314
-
315
- # 创建使用 Alpha#1 因子的信号策略
316
- def alpha1_signal_wrapper(data_slice, position, entry_price, entry_index, take_profit, stop_loss, check_periods):
317
- """
318
- 使用 Alpha#1 因子的信号策略
319
- """
320
- # 使用 Alpha#1 因子
321
- factor_func = lambda d: alpha1_factor(d, lookback_days=5, stddev_period=20, power=2.0)
322
- return factor_based_signal(
323
- data_slice, position, entry_price, entry_index,
324
- take_profit, stop_loss, check_periods,
325
- factor_func=factor_func
326
- )
327
-
328
- # 回测策略
329
- print("开始回测基于 Alpha#1 因子的策略...")
330
- backtest_results = framework.backtest_strategy(
331
- signal_func=alpha1_signal_wrapper,
332
- min_periods=30, # 至少需要30个周期
333
- position_size=0.2, # 每次使用20%的资金
334
- initial_capital=10000.0,
335
- commission_rate=0.00001, # 0.001%手续费
336
- take_profit=0.1, # 止盈10%
337
- stop_loss=0.5, # 止损50%
338
- check_periods=1, # 只能为1,因为实际使用时无法看到未来数据
339
- strategy_name="基于Alpha#1因子的策略"
340
- )
341
-
342
- # 打印结果
343
- framework.print_backtest_results(backtest_results)
344
-
345
- # 绘制结果并保存
346
- save_dir = str(Path(__file__).parent.parent / "result")
347
- os.makedirs(save_dir, exist_ok=True)
348
- framework.plot_backtest_results(
349
- backtest_results,
350
- save_dir=save_dir
351
- )
352
-
353
-
354
- def main():
355
- """
356
- 主函数:运行所有测试
357
- """
358
- print("=" * 60)
359
- print("cyqnt_trd Package 测试脚本")
360
- print("=" * 60)
361
- print("\n注意:")
362
- print(" 1. 确保已安装 cyqnt_trd package: pip install -e /path/to/cyqnt_trd")
363
- print(" 2. 确保数据文件存在于 tmp/data/ 目录下")
364
- print(" 3. 测试结果将保存到 result/ 目录")
365
- print()
366
-
367
- # 运行测试(可以根据需要取消注释)
368
- test_1_use_factor()
369
- test_2_use_signal()
370
- # test_3_factor_in_signal()
371
- # test_4_multi_factor()
372
- # test_5_alpha1_factor()
373
- # test_6_alpha1_signal()
374
-
375
- print("\n" + "=" * 60)
376
- print("测试完成!")
377
- print("=" * 60)
378
-
379
-
380
- if __name__ == "__main__":
381
- main()
test/test_get_data.py DELETED
@@ -1,310 +0,0 @@
1
- """
2
- 测试 cyqnt_trd 包中的 get_and_save_futures_klines 和 get_and_save_klines_direct 函数
3
-
4
- 使用方法:
5
- python test_get_data.py
6
- """
7
-
8
- import os
9
- import sys
10
- from pathlib import Path
11
-
12
- # 添加项目根目录到路径(如果需要)
13
- project_root = Path(__file__).parent.parent
14
- if str(project_root) not in sys.path:
15
- sys.path.insert(0, str(project_root))
16
-
17
- # 导入 cyqnt_trd 包中的函数
18
- from cyqnt_trd.get_data import get_and_save_futures_klines, get_and_save_klines_direct
19
-
20
-
21
- def test_get_and_save_futures_klines():
22
- """
23
- 测试1: 测试 get_and_save_futures_klines 函数
24
- """
25
- print("=" * 80)
26
- print("测试1: get_and_save_futures_klines - 获取期货合约K线数据")
27
- print("=" * 80)
28
-
29
- # 测试1.1: 获取最近的数据(单次请求)
30
- print("\n测试1.1: 获取 BTCUSDT 期货最近30条1小时K线数据")
31
- try:
32
- output_dir = str(project_root / "tmp" / "data" / "test_futures")
33
- result = get_and_save_futures_klines(
34
- symbol="BTCUSDT",
35
- interval="1h",
36
- limit=24*365,
37
- output_dir=output_dir,
38
- save_json=True,
39
- save_csv=False
40
- )
41
- if result:
42
- print(f"✓ 成功获取 {len(result)} 条数据")
43
- print(f" 数据已保存到: {output_dir}")
44
- else:
45
- print("✗ 获取数据失败")
46
- except Exception as e:
47
- print(f"✗ 测试失败: {e}")
48
- import traceback
49
- traceback.print_exc()
50
-
51
- # 测试1.2: 获取指定时间范围的数据(自动分页)
52
- print("\n测试1.2: 获取 ETHUSDT 期货指定时间范围的日线数据(自动分页)")
53
- try:
54
- output_dir = str(project_root / "tmp" / "data" / "test_futures")
55
- result = get_and_save_futures_klines(
56
- symbol="ETHUSDT",
57
- interval="1d",
58
- start_time="2024-01-01 00:00:00",
59
- end_time="2024-01-31 23:59:59",
60
- limit=1000, # 每次请求的limit,实际会分页获取所有数据
61
- output_dir=output_dir,
62
- save_json=True,
63
- save_csv=False
64
- )
65
- if result:
66
- print(f"✓ 成功获取 {len(result)} 条数据")
67
- print(f" 数据已保存到: {output_dir}")
68
- else:
69
- print("✗ 获取数据失败")
70
- except Exception as e:
71
- print(f"✗ 测试失败: {e}")
72
- import traceback
73
- traceback.print_exc()
74
-
75
- # 测试1.3: 使用 datetime 对象指定时间范围
76
- print("\n测试1.3: 使用 datetime 对象获取 SOLUSDT 期货数据")
77
- try:
78
- from datetime import datetime
79
- output_dir = str(project_root / "tmp" / "data" / "test_futures")
80
- start = datetime(2024, 1, 1)
81
- end = datetime(2024, 1, 10)
82
- result = get_and_save_futures_klines(
83
- symbol="SOLUSDT",
84
- interval="3m",
85
- start_time=start,
86
- end_time=end,
87
- limit=1000,
88
- output_dir=output_dir,
89
- save_json=True,
90
- save_csv=False
91
- )
92
- if result:
93
- print(f"✓ 成功获取 {len(result)} 条数据")
94
- print(f" 数据已保存到: {output_dir}")
95
- else:
96
- print("✗ 获取数据失败")
97
- except Exception as e:
98
- print(f"✗ 测试失败: {e}")
99
- import traceback
100
- traceback.print_exc()
101
-
102
-
103
- def test_get_and_save_klines_direct():
104
- """
105
- 测试2: 测试 get_and_save_klines_direct 函数
106
- """
107
- print("\n" + "=" * 80)
108
- print("测试2: get_and_save_klines_direct - 直接HTTP请求获取现货K线数据")
109
- print("=" * 80)
110
-
111
- # 测试2.1: 获取最近的数据(单次请求)
112
- print("\n测试2.1: 获取 BTCUSDT 现货最近30条1小时K线数据")
113
- try:
114
- output_dir = str(project_root / "tmp" / "data" / "test_spot")
115
- result = get_and_save_klines_direct(
116
- symbol="BTCUSDT",
117
- interval="1h",
118
- limit=1000,
119
- output_dir=output_dir,
120
- save_json=True,
121
- save_csv=False
122
- )
123
- if result:
124
- print(f"✓ 成功获取 {len(result)} 条数据")
125
- print(f" 数据已保存到: {output_dir}")
126
- else:
127
- print("✗ 获取数据失败")
128
- except Exception as e:
129
- print(f"✗ 测试失败: {e}")
130
- import traceback
131
- traceback.print_exc()
132
-
133
- # 测试2.2: 获取指定时间范围的数据(自动分页)
134
- print("\n测试2.2: 获取 ETHUSDT 现货指定时间范围的3分钟K线数据(自动分页)")
135
- try:
136
- output_dir = str(project_root / "tmp" / "data" / "test_spot")
137
- result = get_and_save_klines_direct(
138
- symbol="ETHUSDT",
139
- interval="3m",
140
- start_time="2024-12-01 00:00:00",
141
- end_time="2024-12-07 23:59:59",
142
- limit=1000, # 每次请求的limit,实际会分页获取所有数据
143
- output_dir=output_dir,
144
- save_json=True,
145
- save_csv=False
146
- )
147
- if result:
148
- print(f"✓ 成功获取 {len(result)} 条数据")
149
- print(f" 数据已保存到: {output_dir}")
150
- else:
151
- print("✗ 获取数据失败")
152
- except Exception as e:
153
- print(f"✗ 测试失败: {e}")
154
- import traceback
155
- traceback.print_exc()
156
-
157
- # 测试2.3: 使用字符串日期格式(简化格式)
158
- print("\n测试2.3: 使用简化日期格式获取 SOLUSDT 现货数据")
159
- try:
160
- output_dir = str(project_root / "tmp" / "data" / "test_spot")
161
- result = get_and_save_klines_direct(
162
- symbol="SOLUSDT",
163
- interval="1d",
164
- start_time="2024-01-01",
165
- end_time="2024-01-31",
166
- limit=1000,
167
- output_dir=output_dir,
168
- save_json=True,
169
- save_csv=False
170
- )
171
- if result:
172
- print(f"✓ 成功获取 {len(result)} 条数据")
173
- print(f" 数据已保存到: {output_dir}")
174
- else:
175
- print("✗ 获取数据失败")
176
- except Exception as e:
177
- print(f"✗ 测试失败: {e}")
178
- import traceback
179
- traceback.print_exc()
180
-
181
- # 测试2.4: 测试不同时间间隔
182
- print("\n测试2.4: 获取 XRPUSDT 现货不同时间间隔的数据")
183
- try:
184
- output_dir = str(project_root / "tmp" / "data" / "test_spot")
185
- intervals = ["1h", "4h", "1d"]
186
- for interval in intervals:
187
- print(f" 测试间隔: {interval}")
188
- result = get_and_save_klines_direct(
189
- symbol="XRPUSDT",
190
- interval=interval,
191
- limit=10,
192
- output_dir=output_dir,
193
- save_json=False, # 不保存,只测试获取
194
- save_csv=False
195
- )
196
- if result:
197
- print(f" ✓ 成功获取 {len(result)} 条数据")
198
- else:
199
- print(f" ✗ 获取数据失败")
200
- except Exception as e:
201
- print(f"✗ 测试失败: {e}")
202
- import traceback
203
- traceback.print_exc()
204
-
205
-
206
- def test_data_validation():
207
- """
208
- 测试3: 验证获取的数据格式
209
- """
210
- print("\n" + "=" * 80)
211
- print("测试3: 验证获取的数据格式")
212
- print("=" * 80)
213
-
214
- try:
215
- output_dir = str(project_root / "tmp" / "data" / "test_validation")
216
-
217
- # 获取少量数据进行验证
218
- print("\n获取 BTCUSDT 期货数据用于验证...")
219
- result = get_and_save_futures_klines(
220
- symbol="BTCUSDT",
221
- interval="1h",
222
- limit=5,
223
- output_dir=output_dir,
224
- save_json=True,
225
- save_csv=False
226
- )
227
-
228
- if result and len(result) > 0:
229
- print(f"✓ 获取到 {len(result)} 条数据")
230
-
231
- # 验证数据格式
232
- first_kline = result[0]
233
- print(f"\n数据格式验证:")
234
- print(f" 数据类型: {type(first_kline)}")
235
- print(f" 数据长度: {len(first_kline)}")
236
- print(f" 第一条数据示例: {first_kline[:6]}...") # 显示前6个字段
237
-
238
- # 验证必需字段
239
- required_fields = [0, 1, 2, 3, 4, 5, 6] # 时间、价格、成交量等
240
- all_present = all(i < len(first_kline) for i in required_fields)
241
- if all_present:
242
- print(f" ✓ 必需字段完整")
243
- else:
244
- print(f" ✗ 必需字段缺失")
245
-
246
- # 验证保存的JSON文件
247
- json_files = list(Path(output_dir).glob("*.json"))
248
- if json_files:
249
- import json
250
- latest_file = max(json_files, key=lambda x: x.stat().st_mtime)
251
- print(f"\n验证保存的JSON文件: {latest_file.name}")
252
- with open(latest_file, 'r', encoding='utf-8') as f:
253
- data = json.load(f)
254
- if 'symbol' in data and 'data' in data:
255
- print(f" ✓ JSON文件格式正确")
256
- print(f" 交易对: {data['symbol']}")
257
- print(f" 数据条数: {data.get('data_count', len(data.get('data', [])))}")
258
- else:
259
- print(f" ✗ JSON文件格式不正确")
260
- else:
261
- print("✗ 未获取到数据,无法验证")
262
-
263
- except Exception as e:
264
- print(f"✗ 验证失败: {e}")
265
- import traceback
266
- traceback.print_exc()
267
-
268
-
269
- def main():
270
- """
271
- 主函数:运行所有测试
272
- """
273
- print("=" * 80)
274
- print("cyqnt_trd 数据获取函数测试脚本")
275
- print("=" * 80)
276
- print("\n注意:")
277
- print(" 1. 确保已安装 cyqnt_trd package: pip install -e /path/to/crypto_trading")
278
- print(" 2. 测试数据将保存到 tmp/data/ 目录")
279
- print(" 3. 部分测试需要网络连接访问 Binance API")
280
- print()
281
-
282
- # 运行测试
283
- try:
284
- # 测试1: get_and_save_futures_klines
285
- test_get_and_save_futures_klines()
286
-
287
- # 测试2: get_and_save_klines_direct
288
- test_get_and_save_klines_direct()
289
-
290
- # 测试3: 数据验证
291
- test_data_validation()
292
-
293
- print("\n" + "=" * 80)
294
- print("所有测试完成!")
295
- print("=" * 80)
296
- print("\n提示:")
297
- print(" - 可以查看 tmp/data/ 目录下的测试数据文件")
298
- print(" - JSON文件包含完整的元数据和格式化后的K线数据")
299
- print(" - 可以通过修改测试函数中的参数来测试不同的场景")
300
-
301
- except KeyboardInterrupt:
302
- print("\n\n测试被用户中断")
303
- except Exception as e:
304
- print(f"\n\n测试过程中出现错误: {e}")
305
- import traceback
306
- traceback.print_exc()
307
-
308
-
309
- if __name__ == "__main__":
310
- main()