bquant 0.0.0__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 (49) hide show
  1. bquant/__init__.py +31 -0
  2. bquant/analysis/__init__.py +297 -0
  3. bquant/analysis/candlestick/__init__.py +100 -0
  4. bquant/analysis/chart/__init__.py +98 -0
  5. bquant/analysis/statistical/__init__.py +414 -0
  6. bquant/analysis/statistical/hypothesis_testing.py +657 -0
  7. bquant/analysis/technical/__init__.py +98 -0
  8. bquant/analysis/timeseries/__init__.py +102 -0
  9. bquant/analysis/zones/__init__.py +547 -0
  10. bquant/analysis/zones/sequence_analysis.py +661 -0
  11. bquant/analysis/zones/zone_features.py +520 -0
  12. bquant/cli.py +160 -0
  13. bquant/core/__init__.py +112 -0
  14. bquant/core/cache.py +534 -0
  15. bquant/core/config.py +328 -0
  16. bquant/core/exceptions.py +351 -0
  17. bquant/core/logging_config.py +368 -0
  18. bquant/core/numpy_fix.py +99 -0
  19. bquant/core/performance.py +554 -0
  20. bquant/core/utils.py +327 -0
  21. bquant/data/__init__.py +85 -0
  22. bquant/data/loader.py +436 -0
  23. bquant/data/processor.py +644 -0
  24. bquant/data/samples/__init__.py +442 -0
  25. bquant/data/samples/datasets.py +246 -0
  26. bquant/data/samples/embedded/__init__.py +16 -0
  27. bquant/data/samples/embedded/mt_xauusd_m15.py +9018 -0
  28. bquant/data/samples/embedded/tv_xauusd_1h.py +17018 -0
  29. bquant/data/samples/utils.py +393 -0
  30. bquant/data/schemas.py +285 -0
  31. bquant/data/validator.py +498 -0
  32. bquant/indicators/__init__.py +115 -0
  33. bquant/indicators/base.py +487 -0
  34. bquant/indicators/calculators.py +404 -0
  35. bquant/indicators/library.py +514 -0
  36. bquant/indicators/loaders.py +413 -0
  37. bquant/indicators/macd.py +754 -0
  38. bquant/ml/__init__.py +19 -0
  39. bquant/visualization/__init__.py +316 -0
  40. bquant/visualization/charts.py +616 -0
  41. bquant/visualization/statistical.py +812 -0
  42. bquant/visualization/themes.py +599 -0
  43. bquant/visualization/zones.py +775 -0
  44. bquant-0.0.0.dist-info/METADATA +167 -0
  45. bquant-0.0.0.dist-info/RECORD +49 -0
  46. bquant-0.0.0.dist-info/WHEEL +5 -0
  47. bquant-0.0.0.dist-info/entry_points.txt +2 -0
  48. bquant-0.0.0.dist-info/licenses/LICENSE +21 -0
  49. bquant-0.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,404 @@
1
+ """
2
+ High-level calculators and utilities for BQuant indicators
3
+
4
+ This module provides convenient functions for calculating indicators and managing indicator workflows.
5
+ """
6
+
7
+ import pandas as pd
8
+ import numpy as np
9
+ from typing import Dict, Any, Optional, List, Union, Tuple
10
+ from datetime import datetime
11
+
12
+ from .base import IndicatorFactory, IndicatorResult, BaseIndicator
13
+ from .library import register_builtin_indicators
14
+ from .loaders import LibraryManager
15
+ from ..core.exceptions import IndicatorCalculationError
16
+ from ..core.logging_config import get_logger
17
+
18
+ logger = get_logger(__name__)
19
+
20
+
21
+ class IndicatorCalculator:
22
+ """
23
+ High-level calculator for technical indicators.
24
+
25
+ Provides convenient methods for calculating multiple indicators and managing results.
26
+ """
27
+
28
+ def __init__(self, data: pd.DataFrame, auto_load_libraries: bool = True):
29
+ """
30
+ Initialize calculator with price data.
31
+
32
+ Args:
33
+ data: DataFrame with OHLCV price data
34
+ auto_load_libraries: Whether to automatically load external libraries
35
+ """
36
+ self.data = data.copy()
37
+ self.results = {}
38
+ self.logger = get_logger(f"{__name__}.IndicatorCalculator")
39
+
40
+ # Автоматическая загрузка библиотек
41
+ if auto_load_libraries:
42
+ self._load_all_indicators()
43
+
44
+ def _load_all_indicators(self):
45
+ """Load all available indicators."""
46
+ try:
47
+ # Загружаем встроенные индикаторы
48
+ builtin_count = register_builtin_indicators()
49
+ self.logger.info(f"Loaded {builtin_count} builtin indicators")
50
+
51
+ # Загружаем внешние библиотеки
52
+ library_results = LibraryManager.load_all_libraries()
53
+ total_library = sum(library_results.values())
54
+ self.logger.info(f"Loaded {total_library} external indicators")
55
+
56
+ except Exception as e:
57
+ self.logger.warning(f"Failed to load some indicators: {e}")
58
+
59
+ def calculate(self, indicator_name: str, **kwargs) -> IndicatorResult:
60
+ """
61
+ Calculate single indicator.
62
+
63
+ Args:
64
+ indicator_name: Name of the indicator
65
+ **kwargs: Indicator parameters
66
+
67
+ Returns:
68
+ IndicatorResult with calculation results
69
+ """
70
+ try:
71
+ self.logger.info(f"Calculating indicator: {indicator_name}")
72
+
73
+ # Создаем индикатор через фабрику
74
+ indicator = IndicatorFactory.create_indicator(indicator_name, self.data, **kwargs)
75
+
76
+ # Вычисляем результат
77
+ result = indicator.calculate_with_cache(self.data, **kwargs)
78
+
79
+ # Сохраняем результат
80
+ self.results[indicator_name] = result
81
+
82
+ self.logger.info(f"Successfully calculated {indicator_name}")
83
+ return result
84
+
85
+ except Exception as e:
86
+ self.logger.error(f"Failed to calculate {indicator_name}: {e}")
87
+ raise IndicatorCalculationError(
88
+ f"Calculation failed for {indicator_name}: {e}",
89
+ {'indicator': indicator_name, 'parameters': kwargs}
90
+ )
91
+
92
+ def calculate_multiple(self, indicators: Dict[str, Dict[str, Any]]) -> Dict[str, IndicatorResult]:
93
+ """
94
+ Calculate multiple indicators.
95
+
96
+ Args:
97
+ indicators: Dictionary {indicator_name: parameters}
98
+
99
+ Returns:
100
+ Dictionary of results {indicator_name: IndicatorResult}
101
+ """
102
+ results = {}
103
+
104
+ for name, params in indicators.items():
105
+ try:
106
+ result = self.calculate(name, **params)
107
+ results[name] = result
108
+ except Exception as e:
109
+ self.logger.error(f"Failed to calculate {name}: {e}")
110
+ # Продолжаем вычисления остальных индикаторов
111
+ continue
112
+
113
+ return results
114
+
115
+ def get_result(self, indicator_name: str) -> Optional[IndicatorResult]:
116
+ """
117
+ Get cached result for indicator.
118
+
119
+ Args:
120
+ indicator_name: Name of the indicator
121
+
122
+ Returns:
123
+ IndicatorResult or None if not calculated
124
+ """
125
+ return self.results.get(indicator_name)
126
+
127
+ def get_all_results(self) -> Dict[str, IndicatorResult]:
128
+ """Get all cached results."""
129
+ return self.results.copy()
130
+
131
+ def combine_results(self, indicator_names: Optional[List[str]] = None) -> pd.DataFrame:
132
+ """
133
+ Combine multiple indicator results into single DataFrame.
134
+
135
+ Args:
136
+ indicator_names: List of indicators to include (None for all)
137
+
138
+ Returns:
139
+ Combined DataFrame with all indicator data
140
+ """
141
+ if indicator_names is None:
142
+ indicator_names = list(self.results.keys())
143
+
144
+ combined_data = self.data.copy()
145
+
146
+ for name in indicator_names:
147
+ if name in self.results:
148
+ result = self.results[name]
149
+ # Добавляем колонки с префиксом если необходимо
150
+ for col in result.data.columns:
151
+ if col not in combined_data.columns:
152
+ combined_data[col] = result.data[col]
153
+ else:
154
+ combined_data[f"{name}_{col}"] = result.data[col]
155
+
156
+ return combined_data
157
+
158
+ def clear_cache(self):
159
+ """Clear all cached results."""
160
+ self.results.clear()
161
+ self.logger.info("Cleared all cached results")
162
+
163
+
164
+ def calculate_indicator(data: pd.DataFrame, indicator_name: str, **kwargs) -> IndicatorResult:
165
+ """
166
+ Convenience function to calculate single indicator.
167
+
168
+ Args:
169
+ data: DataFrame with price data
170
+ indicator_name: Name of the indicator
171
+ **kwargs: Indicator parameters
172
+
173
+ Returns:
174
+ IndicatorResult with calculation results
175
+ """
176
+ calculator = IndicatorCalculator(data, auto_load_libraries=False)
177
+ return calculator.calculate(indicator_name, **kwargs)
178
+
179
+
180
+ def calculate_macd(data: pd.DataFrame, fast: int = 12, slow: int = 26, signal: int = 9) -> pd.DataFrame:
181
+ """
182
+ Convenience function to calculate MACD.
183
+
184
+ Args:
185
+ data: DataFrame with price data
186
+ fast: Fast EMA period
187
+ slow: Slow EMA period
188
+ signal: Signal line period
189
+
190
+ Returns:
191
+ DataFrame with MACD data
192
+ """
193
+ result = calculate_indicator(data, 'macd', fast_period=fast, slow_period=slow, signal_period=signal)
194
+ return result.data
195
+
196
+
197
+ def calculate_rsi(data: pd.DataFrame, period: int = 14) -> pd.Series:
198
+ """
199
+ Convenience function to calculate RSI.
200
+
201
+ Args:
202
+ data: DataFrame with price data
203
+ period: RSI period
204
+
205
+ Returns:
206
+ Series with RSI values
207
+ """
208
+ result = calculate_indicator(data, 'rsi', period=period)
209
+ return result.data.iloc[:, 0] # Возвращаем первую колонку как Series
210
+
211
+
212
+ def calculate_bollinger_bands(data: pd.DataFrame, period: int = 20, std_dev: float = 2.0) -> pd.DataFrame:
213
+ """
214
+ Convenience function to calculate Bollinger Bands.
215
+
216
+ Args:
217
+ data: DataFrame with price data
218
+ period: Period for calculation
219
+ std_dev: Standard deviation multiplier
220
+
221
+ Returns:
222
+ DataFrame with Bollinger Bands data
223
+ """
224
+ result = calculate_indicator(data, 'bbands', period=period, std_dev=std_dev)
225
+ return result.data
226
+
227
+
228
+ def calculate_moving_averages(data: pd.DataFrame, periods: List[int] = None) -> pd.DataFrame:
229
+ """
230
+ Calculate multiple moving averages.
231
+
232
+ Args:
233
+ data: DataFrame with price data
234
+ periods: List of periods for moving averages
235
+
236
+ Returns:
237
+ DataFrame with moving averages
238
+ """
239
+ if periods is None:
240
+ periods = [10, 20, 50, 200]
241
+
242
+ calculator = IndicatorCalculator(data, auto_load_libraries=False)
243
+
244
+ # Вычисляем SMA для каждого периода
245
+ sma_indicators = {f'sma_{period}': {'period': period} for period in periods}
246
+
247
+ # Вычисляем EMA для каждого периода
248
+ ema_indicators = {f'ema_{period}': {'period': period} for period in periods}
249
+
250
+ # Объединяем все индикаторы
251
+ all_indicators = {**sma_indicators, **ema_indicators}
252
+
253
+ results = calculator.calculate_multiple(all_indicators)
254
+
255
+ # Объединяем результаты
256
+ combined_data = pd.DataFrame(index=data.index)
257
+ for name, result in results.items():
258
+ for col in result.data.columns:
259
+ combined_data[col] = result.data[col]
260
+
261
+ return combined_data
262
+
263
+
264
+ def create_indicator_suite(data: pd.DataFrame) -> Dict[str, IndicatorResult]:
265
+ """
266
+ Calculate standard suite of technical indicators.
267
+
268
+ Args:
269
+ data: DataFrame with price data
270
+
271
+ Returns:
272
+ Dictionary with all calculated indicators
273
+ """
274
+ calculator = IndicatorCalculator(data)
275
+
276
+ # Определяем стандартный набор индикаторов
277
+ standard_indicators = {
278
+ 'sma_20': {'period': 20},
279
+ 'sma_50': {'period': 50},
280
+ 'ema_12': {'period': 12},
281
+ 'ema_26': {'period': 26},
282
+ 'rsi_14': {'period': 14},
283
+ 'macd': {'fast_period': 12, 'slow_period': 26, 'signal_period': 9},
284
+ 'bbands': {'period': 20, 'std_dev': 2.0},
285
+ }
286
+
287
+ # Вычисляем все индикаторы
288
+ results = calculator.calculate_multiple(standard_indicators)
289
+
290
+ logger.info(f"Calculated {len(results)} indicators in standard suite")
291
+ return results
292
+
293
+
294
+ def get_available_indicators() -> Dict[str, str]:
295
+ """
296
+ Get list of all available indicators.
297
+
298
+ Returns:
299
+ Dictionary {indicator_name: source}
300
+ """
301
+ # Загружаем все индикаторы
302
+ register_builtin_indicators()
303
+ LibraryManager.load_all_libraries()
304
+
305
+ return IndicatorFactory.list_indicators()
306
+
307
+
308
+ def validate_indicator_data(data: pd.DataFrame, indicator_name: str, **kwargs) -> bool:
309
+ """
310
+ Validate data for specific indicator without calculating.
311
+
312
+ Args:
313
+ data: DataFrame with price data
314
+ indicator_name: Name of the indicator
315
+ **kwargs: Indicator parameters
316
+
317
+ Returns:
318
+ True if data is valid for the indicator
319
+ """
320
+ try:
321
+ indicator = IndicatorFactory.create_indicator(indicator_name, **kwargs)
322
+ return indicator.validate_data(data)
323
+ except Exception as e:
324
+ logger.warning(f"Data validation failed for {indicator_name}: {e}")
325
+ return False
326
+
327
+
328
+ class BatchCalculator:
329
+ """
330
+ Calculator for batch processing of multiple datasets.
331
+ """
332
+
333
+ def __init__(self, datasets: Dict[str, pd.DataFrame]):
334
+ """
335
+ Initialize batch calculator.
336
+
337
+ Args:
338
+ datasets: Dictionary {dataset_name: DataFrame}
339
+ """
340
+ self.datasets = datasets
341
+ self.results = {}
342
+ self.logger = get_logger(f"{__name__}.BatchCalculator")
343
+
344
+ def calculate_for_all(self, indicator_name: str, **kwargs) -> Dict[str, IndicatorResult]:
345
+ """
346
+ Calculate indicator for all datasets.
347
+
348
+ Args:
349
+ indicator_name: Name of the indicator
350
+ **kwargs: Indicator parameters
351
+
352
+ Returns:
353
+ Dictionary {dataset_name: IndicatorResult}
354
+ """
355
+ results = {}
356
+
357
+ for dataset_name, data in self.datasets.items():
358
+ try:
359
+ calculator = IndicatorCalculator(data, auto_load_libraries=False)
360
+ result = calculator.calculate(indicator_name, **kwargs)
361
+ results[dataset_name] = result
362
+
363
+ self.logger.info(f"Calculated {indicator_name} for {dataset_name}")
364
+
365
+ except Exception as e:
366
+ self.logger.error(f"Failed to calculate {indicator_name} for {dataset_name}: {e}")
367
+
368
+ return results
369
+
370
+ def calculate_suite_for_all(self) -> Dict[str, Dict[str, IndicatorResult]]:
371
+ """
372
+ Calculate standard indicator suite for all datasets.
373
+
374
+ Returns:
375
+ Nested dictionary {dataset_name: {indicator_name: IndicatorResult}}
376
+ """
377
+ results = {}
378
+
379
+ for dataset_name, data in self.datasets.items():
380
+ try:
381
+ suite_results = create_indicator_suite(data)
382
+ results[dataset_name] = suite_results
383
+
384
+ self.logger.info(f"Calculated indicator suite for {dataset_name}")
385
+
386
+ except Exception as e:
387
+ self.logger.error(f"Failed to calculate suite for {dataset_name}: {e}")
388
+
389
+ return results
390
+
391
+
392
+ # Экспорт
393
+ __all__ = [
394
+ 'IndicatorCalculator',
395
+ 'BatchCalculator',
396
+ 'calculate_indicator',
397
+ 'calculate_macd',
398
+ 'calculate_rsi',
399
+ 'calculate_bollinger_bands',
400
+ 'calculate_moving_averages',
401
+ 'create_indicator_suite',
402
+ 'get_available_indicators',
403
+ 'validate_indicator_data'
404
+ ]