deltafq 0.1.0__tar.gz → 0.1.2__tar.gz

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.

Potentially problematic release.


This version of deltafq might be problematic. Click here for more details.

Files changed (87) hide show
  1. {deltafq-0.1.0 → deltafq-0.1.2}/LICENSE +21 -22
  2. deltafq-0.1.2/PKG-INFO +89 -0
  3. deltafq-0.1.2/README.md +50 -0
  4. deltafq-0.1.2/deltafq/__init__.py +30 -0
  5. deltafq-0.1.2/deltafq/backtest/__init__.py +17 -0
  6. deltafq-0.1.2/deltafq/backtest/engine.py +99 -0
  7. deltafq-0.1.2/deltafq/backtest/metrics.py +113 -0
  8. deltafq-0.1.2/deltafq/backtest/performance.py +81 -0
  9. deltafq-0.1.2/deltafq/backtest/reporter.py +91 -0
  10. deltafq-0.1.2/deltafq/core/__init__.py +19 -0
  11. deltafq-0.1.2/deltafq/core/base.py +37 -0
  12. deltafq-0.1.2/deltafq/core/config.py +63 -0
  13. deltafq-0.1.2/deltafq/core/exceptions.py +35 -0
  14. deltafq-0.1.2/deltafq/core/logger.py +46 -0
  15. deltafq-0.1.2/deltafq/data/__init__.py +17 -0
  16. deltafq-0.1.2/deltafq/data/cleaner.py +41 -0
  17. deltafq-0.1.2/deltafq/data/fetcher.py +52 -0
  18. deltafq-0.1.2/deltafq/data/storage.py +56 -0
  19. deltafq-0.1.2/deltafq/data/validator.py +52 -0
  20. deltafq-0.1.2/deltafq/indicators/__init__.py +17 -0
  21. deltafq-0.1.2/deltafq/indicators/momentum.py +56 -0
  22. deltafq-0.1.2/deltafq/indicators/technical.py +59 -0
  23. deltafq-0.1.2/deltafq/indicators/trend.py +129 -0
  24. deltafq-0.1.2/deltafq/indicators/volatility.py +67 -0
  25. deltafq-0.1.2/deltafq/live/__init__.py +17 -0
  26. deltafq-0.1.2/deltafq/live/connection.py +235 -0
  27. deltafq-0.1.2/deltafq/live/data_feed.py +159 -0
  28. deltafq-0.1.2/deltafq/live/monitoring.py +192 -0
  29. deltafq-0.1.2/deltafq/live/risk_control.py +193 -0
  30. deltafq-0.1.2/deltafq/strategy/__init__.py +17 -0
  31. deltafq-0.1.2/deltafq/strategy/base_strategy.py +53 -0
  32. deltafq-0.1.2/deltafq/strategy/portfolio.py +82 -0
  33. deltafq-0.1.2/deltafq/strategy/risk_manager.py +64 -0
  34. deltafq-0.1.2/deltafq/strategy/signal_generator.py +52 -0
  35. deltafq-0.1.2/deltafq/trading/__init__.py +19 -0
  36. deltafq-0.1.2/deltafq/trading/broker.py +119 -0
  37. deltafq-0.1.2/deltafq/trading/execution.py +176 -0
  38. deltafq-0.1.2/deltafq/trading/order_manager.py +111 -0
  39. deltafq-0.1.2/deltafq/trading/position_manager.py +157 -0
  40. deltafq-0.1.2/deltafq/trading/simulator.py +150 -0
  41. deltafq-0.1.2/deltafq.egg-info/PKG-INFO +89 -0
  42. deltafq-0.1.2/deltafq.egg-info/SOURCES.txt +48 -0
  43. deltafq-0.1.2/deltafq.egg-info/entry_points.txt +2 -0
  44. deltafq-0.1.2/deltafq.egg-info/requires.txt +15 -0
  45. deltafq-0.1.2/pyproject.toml +104 -0
  46. deltafq-0.1.2/setup.py +10 -0
  47. deltafq-0.1.2/test/test_basic.py +169 -0
  48. deltafq-0.1.0/MANIFEST.in +0 -7
  49. deltafq-0.1.0/PKG-INFO +0 -195
  50. deltafq-0.1.0/README.md +0 -156
  51. deltafq-0.1.0/deltafq/__init__.py +0 -31
  52. deltafq-0.1.0/deltafq/backtest/__init__.py +0 -7
  53. deltafq-0.1.0/deltafq/backtest/engine.py +0 -52
  54. deltafq-0.1.0/deltafq/backtest/result.py +0 -45
  55. deltafq-0.1.0/deltafq/data/__init__.py +0 -7
  56. deltafq-0.1.0/deltafq/data/base.py +0 -30
  57. deltafq-0.1.0/deltafq/data/loader.py +0 -63
  58. deltafq-0.1.0/deltafq/indicators/__init__.py +0 -8
  59. deltafq-0.1.0/deltafq/indicators/momentum.py +0 -23
  60. deltafq-0.1.0/deltafq/indicators/trend.py +0 -61
  61. deltafq-0.1.0/deltafq/indicators/volatility.py +0 -27
  62. deltafq-0.1.0/deltafq/optimization/__init__.py +0 -6
  63. deltafq-0.1.0/deltafq/optimization/grid_search.py +0 -41
  64. deltafq-0.1.0/deltafq/performance/__init__.py +0 -6
  65. deltafq-0.1.0/deltafq/performance/metrics.py +0 -37
  66. deltafq-0.1.0/deltafq/risk/__init__.py +0 -7
  67. deltafq-0.1.0/deltafq/risk/metrics.py +0 -33
  68. deltafq-0.1.0/deltafq/risk/position.py +0 -39
  69. deltafq-0.1.0/deltafq/strategy/__init__.py +0 -6
  70. deltafq-0.1.0/deltafq/strategy/base.py +0 -44
  71. deltafq-0.1.0/deltafq/trade/__init__.py +0 -6
  72. deltafq-0.1.0/deltafq/trade/broker.py +0 -40
  73. deltafq-0.1.0/deltafq/utils/__init__.py +0 -6
  74. deltafq-0.1.0/deltafq/utils/time.py +0 -32
  75. deltafq-0.1.0/deltafq.egg-info/PKG-INFO +0 -195
  76. deltafq-0.1.0/deltafq.egg-info/SOURCES.txt +0 -39
  77. deltafq-0.1.0/deltafq.egg-info/requires.txt +0 -15
  78. deltafq-0.1.0/pyproject.toml +0 -74
  79. deltafq-0.1.0/setup.py +0 -12
  80. deltafq-0.1.0/tests/test_backtest.py +0 -54
  81. deltafq-0.1.0/tests/test_data.py +0 -27
  82. deltafq-0.1.0/tests/test_full_workflow.py +0 -158
  83. deltafq-0.1.0/tests/test_indicators.py +0 -55
  84. deltafq-0.1.0/tests/test_strategy.py +0 -49
  85. {deltafq-0.1.0 → deltafq-0.1.2}/deltafq.egg-info/dependency_links.txt +0 -0
  86. {deltafq-0.1.0 → deltafq-0.1.2}/deltafq.egg-info/top_level.txt +0 -0
  87. {deltafq-0.1.0 → deltafq-0.1.2}/setup.cfg +0 -0
@@ -1,22 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 DeltaFQ Team
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
22
-
1
+ MIT License
2
+
3
+ Copyright (c) 2025 DeltaF
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
deltafq-0.1.2/PKG-INFO ADDED
@@ -0,0 +1,89 @@
1
+ Metadata-Version: 2.4
2
+ Name: deltafq
3
+ Version: 0.1.2
4
+ Summary: A comprehensive Python quantitative finance library
5
+ Author-email: DeltaF <leek_li@outlook.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Delta-F/deltafq
8
+ Project-URL: Repository, https://github.com/Delta-F/deltafq
9
+ Project-URL: Issues, https://github.com/Delta-F/deltafq/issues
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Financial and Insurance Industry
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Topic :: Office/Business :: Financial :: Investment
20
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
21
+ Requires-Python: >=3.8
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: numpy>=1.21.0
25
+ Requires-Dist: pandas>=1.3.0
26
+ Requires-Dist: scipy>=1.7.0
27
+ Requires-Dist: matplotlib>=3.4.0
28
+ Requires-Dist: seaborn>=0.11.0
29
+ Requires-Dist: plotly>=5.0.0
30
+ Requires-Dist: yfinance>=0.1.70
31
+ Requires-Dist: requests>=2.25.0
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest>=6.2.0; extra == "dev"
34
+ Requires-Dist: pytest-cov>=2.12.0; extra == "dev"
35
+ Requires-Dist: black>=21.0.0; extra == "dev"
36
+ Requires-Dist: flake8>=3.9.0; extra == "dev"
37
+ Requires-Dist: sphinx>=4.0.0; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # DeltaFQ
41
+
42
+ A comprehensive Python quantitative finance library for strategy development, backtesting, and live trading.
43
+
44
+ ## Features
45
+
46
+ - **Data Management**: Efficient data fetching, cleaning, and storage
47
+ - **Strategy Framework**: Flexible strategy development framework
48
+ - **Backtesting**: High-performance historical data backtesting
49
+ - **Paper Trading**: Risk-free strategy testing with simulated trading
50
+ - **Live Trading**: Real-time trading with broker integration
51
+ - **Technical Indicators**: Rich library of technical analysis indicators
52
+ - **Risk Management**: Built-in risk control modules
53
+
54
+ ## Installation
55
+
56
+ ```bash
57
+ pip install deltafq
58
+ ```
59
+
60
+ ## Quick Start
61
+
62
+ ```python
63
+ import deltafq as dfq
64
+
65
+ # Fetch market data
66
+ data = dfq.data.fetch_stock_data('AAPL', start='2023-01-01')
67
+
68
+ # Create and test a strategy
69
+ strategy = dfq.strategy.MovingAverageStrategy(fast_period=10, slow_period=20)
70
+ results = dfq.backtest.run_backtest(strategy, data)
71
+
72
+ # Run paper trading
73
+ simulator = dfq.trading.PaperTradingSimulator(initial_capital=100000)
74
+ simulator.run_strategy(strategy, data)
75
+ ```
76
+
77
+ ## Documentation
78
+
79
+ - [API Reference](docs/api_reference/)
80
+ - [Tutorials](docs/tutorials/)
81
+ - [Examples](examples/)
82
+
83
+ ## Contributing
84
+
85
+ Please read our [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
86
+
87
+ ## License
88
+
89
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,50 @@
1
+ # DeltaFQ
2
+
3
+ A comprehensive Python quantitative finance library for strategy development, backtesting, and live trading.
4
+
5
+ ## Features
6
+
7
+ - **Data Management**: Efficient data fetching, cleaning, and storage
8
+ - **Strategy Framework**: Flexible strategy development framework
9
+ - **Backtesting**: High-performance historical data backtesting
10
+ - **Paper Trading**: Risk-free strategy testing with simulated trading
11
+ - **Live Trading**: Real-time trading with broker integration
12
+ - **Technical Indicators**: Rich library of technical analysis indicators
13
+ - **Risk Management**: Built-in risk control modules
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pip install deltafq
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ```python
24
+ import deltafq as dfq
25
+
26
+ # Fetch market data
27
+ data = dfq.data.fetch_stock_data('AAPL', start='2023-01-01')
28
+
29
+ # Create and test a strategy
30
+ strategy = dfq.strategy.MovingAverageStrategy(fast_period=10, slow_period=20)
31
+ results = dfq.backtest.run_backtest(strategy, data)
32
+
33
+ # Run paper trading
34
+ simulator = dfq.trading.PaperTradingSimulator(initial_capital=100000)
35
+ simulator.run_strategy(strategy, data)
36
+ ```
37
+
38
+ ## Documentation
39
+
40
+ - [API Reference](docs/api_reference/)
41
+ - [Tutorials](docs/tutorials/)
42
+ - [Examples](examples/)
43
+
44
+ ## Contributing
45
+
46
+ Please read our [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
47
+
48
+ ## License
49
+
50
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,30 @@
1
+ """
2
+ DeltaFQ - A comprehensive Python quantitative finance library.
3
+
4
+ This library provides tools for strategy development, backtesting,
5
+ paper trading, and live trading.
6
+ """
7
+
8
+ __version__ = "0.1.0"
9
+ __author__ = "DeltaF"
10
+
11
+ # Import core modules
12
+ from . import core
13
+ from . import data
14
+ from . import strategy
15
+ from . import backtest
16
+ from . import indicators
17
+ from . import trading
18
+ from . import live
19
+
20
+ __all__ = [
21
+ "core",
22
+ "data",
23
+ "strategy",
24
+ "backtest",
25
+ "indicators",
26
+ "trading",
27
+ "live"
28
+ ]
29
+
30
+
@@ -0,0 +1,17 @@
1
+ """
2
+ Backtesting module for DeltaFQ.
3
+ """
4
+
5
+ from .engine import BacktestEngine
6
+ from .performance import PerformanceAnalyzer
7
+ from .metrics import MetricsCalculator
8
+ from .reporter import BacktestReporter
9
+
10
+ __all__ = [
11
+ "BacktestEngine",
12
+ "PerformanceAnalyzer",
13
+ "MetricsCalculator",
14
+ "BacktestReporter"
15
+ ]
16
+
17
+
@@ -0,0 +1,99 @@
1
+ """
2
+ Backtesting engine for DeltaFQ.
3
+ """
4
+
5
+ import pandas as pd
6
+ from typing import Dict, Any, Optional
7
+ from ..core.base import BaseComponent
8
+ from ..core.exceptions import BacktestError
9
+
10
+
11
+ class BacktestEngine(BaseComponent):
12
+ """Backtesting engine for strategy testing."""
13
+
14
+ def __init__(self, initial_capital: float = 100000, commission: float = 0.001, **kwargs):
15
+ """Initialize backtest engine."""
16
+ super().__init__(**kwargs)
17
+ self.initial_capital = initial_capital
18
+ self.commission = commission
19
+ self.results = None
20
+
21
+ def initialize(self) -> bool:
22
+ """Initialize backtest engine."""
23
+ self.logger.info(f"Initializing backtest engine with capital: {self.initial_capital}")
24
+ return True
25
+
26
+ def run_backtest(self, strategy, data: pd.DataFrame) -> Dict[str, Any]:
27
+ """Run backtest for given strategy and data."""
28
+ try:
29
+ self.logger.info("Starting backtest")
30
+
31
+ # Initialize portfolio
32
+ cash = self.initial_capital
33
+ positions = {}
34
+ trades = []
35
+
36
+ # Run strategy on data
37
+ for i, (date, row) in enumerate(data.iterrows()):
38
+ # Get signals from strategy
39
+ signals = strategy.generate_signals(data.iloc[:i+1])
40
+
41
+ if not signals.empty and i > 0:
42
+ signal = signals.iloc[-1]
43
+
44
+ # Execute trades based on signals
45
+ if signal != 0: # Buy or sell signal
46
+ symbol = 'STOCK' # Simplified for single asset
47
+ price = row['close']
48
+ quantity = int(signal * cash * 0.1 / price) # Use 10% of cash
49
+
50
+ if quantity > 0 and quantity * price <= cash:
51
+ # Buy
52
+ cost = quantity * price * (1 + self.commission)
53
+ cash -= cost
54
+ positions[symbol] = positions.get(symbol, 0) + quantity
55
+ trades.append({
56
+ 'date': date,
57
+ 'symbol': symbol,
58
+ 'quantity': quantity,
59
+ 'price': price,
60
+ 'type': 'buy'
61
+ })
62
+ elif quantity < 0 and positions.get(symbol, 0) >= abs(quantity):
63
+ # Sell
64
+ quantity = abs(quantity)
65
+ proceeds = quantity * price * (1 - self.commission)
66
+ cash += proceeds
67
+ positions[symbol] -= quantity
68
+ trades.append({
69
+ 'date': date,
70
+ 'symbol': symbol,
71
+ 'quantity': -quantity,
72
+ 'price': price,
73
+ 'type': 'sell'
74
+ })
75
+
76
+ # Calculate final portfolio value
77
+ final_price = data['close'].iloc[-1]
78
+ final_value = cash + sum(positions.values()) * final_price
79
+
80
+ self.results = {
81
+ 'initial_capital': self.initial_capital,
82
+ 'final_value': final_value,
83
+ 'total_return': (final_value - self.initial_capital) / self.initial_capital,
84
+ 'trades': trades,
85
+ 'final_positions': positions,
86
+ 'final_cash': cash
87
+ }
88
+
89
+ self.logger.info(f"Backtest completed. Total return: {self.results['total_return']:.2%}")
90
+ return self.results
91
+
92
+ except Exception as e:
93
+ raise BacktestError(f"Backtest failed: {str(e)}")
94
+
95
+ def get_results(self) -> Optional[Dict[str, Any]]:
96
+ """Get backtest results."""
97
+ return self.results
98
+
99
+
@@ -0,0 +1,113 @@
1
+ """
2
+ Backtest metrics calculation.
3
+ """
4
+
5
+ import pandas as pd
6
+ import numpy as np
7
+ from typing import Dict, Any
8
+ from ..core.base import BaseComponent
9
+
10
+
11
+ class MetricsCalculator(BaseComponent):
12
+ """Calculate various backtest metrics."""
13
+
14
+ def initialize(self) -> bool:
15
+ """Initialize metrics calculator."""
16
+ self.logger.info("Initializing metrics calculator")
17
+ return True
18
+
19
+ def calculate_trade_metrics(self, trades: list) -> Dict[str, Any]:
20
+ """Calculate trade-based metrics."""
21
+ if not trades:
22
+ return {}
23
+
24
+ trade_df = pd.DataFrame(trades)
25
+
26
+ # Separate buy and sell trades
27
+ buy_trades = trade_df[trade_df['type'] == 'buy']
28
+ sell_trades = trade_df[trade_df['type'] == 'sell']
29
+
30
+ # Calculate P&L for each trade (simplified)
31
+ pnl = []
32
+ for _, sell_trade in sell_trades.iterrows():
33
+ # Find corresponding buy trade
34
+ buy_trade = buy_trades[buy_trades['symbol'] == sell_trade['symbol']].iloc[0]
35
+ trade_pnl = (sell_trade['price'] - buy_trade['price']) * sell_trade['quantity']
36
+ pnl.append(trade_pnl)
37
+
38
+ if pnl:
39
+ pnl_series = pd.Series(pnl)
40
+ return {
41
+ 'total_trades': len(pnl),
42
+ 'winning_trades': (pnl_series > 0).sum(),
43
+ 'losing_trades': (pnl_series < 0).sum(),
44
+ 'win_rate': (pnl_series > 0).mean(),
45
+ 'avg_win': pnl_series[pnl_series > 0].mean() if (pnl_series > 0).any() else 0,
46
+ 'avg_loss': pnl_series[pnl_series < 0].mean() if (pnl_series < 0).any() else 0,
47
+ 'total_pnl': pnl_series.sum()
48
+ }
49
+
50
+ return {}
51
+
52
+ def calculate_risk_metrics(self, returns: pd.Series) -> Dict[str, float]:
53
+ """Calculate risk-related metrics."""
54
+ if len(returns) == 0:
55
+ return {}
56
+
57
+ # Value at Risk (VaR)
58
+ var_95 = np.percentile(returns, 5)
59
+ var_99 = np.percentile(returns, 1)
60
+
61
+ # Conditional Value at Risk (CVaR)
62
+ cvar_95 = returns[returns <= var_95].mean()
63
+ cvar_99 = returns[returns <= var_99].mean()
64
+
65
+ # Skewness and Kurtosis
66
+ skewness = returns.skew()
67
+ kurtosis = returns.kurtosis()
68
+
69
+ return {
70
+ 'var_95': var_95,
71
+ 'var_99': var_99,
72
+ 'cvar_95': cvar_95,
73
+ 'cvar_99': cvar_99,
74
+ 'skewness': skewness,
75
+ 'kurtosis': kurtosis
76
+ }
77
+
78
+ def calculate_portfolio_metrics(self, portfolio_values: pd.Series) -> Dict[str, float]:
79
+ """Calculate portfolio-level metrics."""
80
+ if len(portfolio_values) < 2:
81
+ return {}
82
+
83
+ returns = portfolio_values.pct_change().dropna()
84
+
85
+ # Rolling metrics
86
+ rolling_returns = returns.rolling(window=252) # Annual window
87
+
88
+ return {
89
+ 'total_return': (portfolio_values.iloc[-1] / portfolio_values.iloc[0]) - 1,
90
+ 'annualized_return': (1 + returns.mean()) ** 252 - 1,
91
+ 'volatility': returns.std() * np.sqrt(252),
92
+ 'sharpe_ratio': returns.mean() / returns.std() * np.sqrt(252) if returns.std() > 0 else 0,
93
+ 'max_drawdown': self._calculate_max_drawdown(portfolio_values),
94
+ 'calmar_ratio': self._calculate_calmar_ratio(returns)
95
+ }
96
+
97
+ def _calculate_max_drawdown(self, values: pd.Series) -> float:
98
+ """Calculate maximum drawdown."""
99
+ peak = values.expanding().max()
100
+ drawdown = (values - peak) / peak
101
+ return drawdown.min()
102
+
103
+ def _calculate_calmar_ratio(self, returns: pd.Series) -> float:
104
+ """Calculate Calmar ratio."""
105
+ annual_return = (1 + returns.mean()) ** 252 - 1
106
+ max_dd = abs(self._calculate_max_drawdown((1 + returns).cumprod()))
107
+
108
+ if max_dd == 0:
109
+ return float('inf') if annual_return > 0 else 0.0
110
+
111
+ return annual_return / max_dd
112
+
113
+
@@ -0,0 +1,81 @@
1
+ """
2
+ Performance analysis for backtests.
3
+ """
4
+
5
+ import pandas as pd
6
+ import numpy as np
7
+ from typing import Dict, List, Any
8
+ from ..core.base import BaseComponent
9
+
10
+
11
+ class PerformanceAnalyzer(BaseComponent):
12
+ """Analyze backtest performance."""
13
+
14
+ def initialize(self) -> bool:
15
+ """Initialize performance analyzer."""
16
+ self.logger.info("Initializing performance analyzer")
17
+ return True
18
+
19
+ def calculate_returns(self, prices: pd.Series) -> pd.Series:
20
+ """Calculate returns from price series."""
21
+ return prices.pct_change().dropna()
22
+
23
+ def calculate_sharpe_ratio(self, returns: pd.Series, risk_free_rate: float = 0.02) -> float:
24
+ """Calculate Sharpe ratio."""
25
+ if len(returns) == 0 or returns.std() == 0:
26
+ return 0.0
27
+
28
+ excess_returns = returns - risk_free_rate / 252 # Daily risk-free rate
29
+ return excess_returns.mean() / returns.std() * np.sqrt(252)
30
+
31
+ def calculate_max_drawdown(self, returns: pd.Series) -> float:
32
+ """Calculate maximum drawdown."""
33
+ cumulative = (1 + returns).cumprod()
34
+ running_max = cumulative.expanding().max()
35
+ drawdown = (cumulative - running_max) / running_max
36
+ return drawdown.min()
37
+
38
+ def calculate_volatility(self, returns: pd.Series) -> float:
39
+ """Calculate annualized volatility."""
40
+ return returns.std() * np.sqrt(252)
41
+
42
+ def analyze_performance(self, returns: pd.Series, benchmark_returns: pd.Series = None) -> Dict[str, float]:
43
+ """Comprehensive performance analysis."""
44
+ analysis = {
45
+ 'total_return': (1 + returns).prod() - 1,
46
+ 'annualized_return': (1 + returns).prod() ** (252 / len(returns)) - 1,
47
+ 'volatility': self.calculate_volatility(returns),
48
+ 'sharpe_ratio': self.calculate_sharpe_ratio(returns),
49
+ 'max_drawdown': self.calculate_max_drawdown(returns),
50
+ 'win_rate': (returns > 0).mean(),
51
+ 'profit_factor': self._calculate_profit_factor(returns)
52
+ }
53
+
54
+ if benchmark_returns is not None:
55
+ analysis['alpha'] = self._calculate_alpha(returns, benchmark_returns)
56
+ analysis['beta'] = self._calculate_beta(returns, benchmark_returns)
57
+
58
+ return analysis
59
+
60
+ def _calculate_profit_factor(self, returns: pd.Series) -> float:
61
+ """Calculate profit factor."""
62
+ positive_returns = returns[returns > 0].sum()
63
+ negative_returns = abs(returns[returns < 0].sum())
64
+
65
+ if negative_returns == 0:
66
+ return float('inf') if positive_returns > 0 else 0.0
67
+
68
+ return positive_returns / negative_returns
69
+
70
+ def _calculate_alpha(self, returns: pd.Series, benchmark_returns: pd.Series) -> float:
71
+ """Calculate alpha."""
72
+ # Simplified calculation
73
+ return returns.mean() - benchmark_returns.mean()
74
+
75
+ def _calculate_beta(self, returns: pd.Series, benchmark_returns: pd.Series) -> float:
76
+ """Calculate beta."""
77
+ if benchmark_returns.var() == 0:
78
+ return 0.0
79
+ return returns.cov(benchmark_returns) / benchmark_returns.var()
80
+
81
+
@@ -0,0 +1,91 @@
1
+ """
2
+ Backtest report generation.
3
+ """
4
+
5
+ import pandas as pd
6
+ from typing import Dict, Any, Optional
7
+ from ..core.base import BaseComponent
8
+
9
+
10
+ class BacktestReporter(BaseComponent):
11
+ """Generate backtest reports."""
12
+
13
+ def initialize(self) -> bool:
14
+ """Initialize backtest reporter."""
15
+ self.logger.info("Initializing backtest reporter")
16
+ return True
17
+
18
+ def generate_summary_report(self, results: Dict[str, Any]) -> str:
19
+ """Generate a summary report."""
20
+ report = f"""
21
+ === Backtest Summary Report ===
22
+
23
+ Initial Capital: ${results.get('initial_capital', 0):,.2f}
24
+ Final Value: ${results.get('final_value', 0):,.2f}
25
+ Total Return: {results.get('total_return', 0):.2%}
26
+
27
+ Trades:
28
+ - Total Trades: {len(results.get('trades', []))}
29
+ - Final Cash: ${results.get('final_cash', 0):,.2f}
30
+ - Final Positions: {results.get('final_positions', {})}
31
+
32
+ === End of Report ===
33
+ """
34
+ return report
35
+
36
+ def generate_detailed_report(self, results: Dict[str, Any], performance_metrics: Dict[str, float]) -> str:
37
+ """Generate detailed report with performance metrics."""
38
+ report = f"""
39
+ === Detailed Backtest Report ===
40
+
41
+ PORTFOLIO PERFORMANCE
42
+ ====================
43
+ Initial Capital: ${results.get('initial_capital', 0):,.2f}
44
+ Final Value: ${results.get('final_value', 0):,.2f}
45
+ Total Return: {results.get('total_return', 0):.2%}
46
+
47
+ PERFORMANCE METRICS
48
+ ==================
49
+ Annualized Return: {performance_metrics.get('annualized_return', 0):.2%}
50
+ Volatility: {performance_metrics.get('volatility', 0):.2%}
51
+ Sharpe Ratio: {performance_metrics.get('sharpe_ratio', 0):.2f}
52
+ Maximum Drawdown: {performance_metrics.get('max_drawdown', 0):.2%}
53
+ Calmar Ratio: {performance_metrics.get('calmar_ratio', 0):.2f}
54
+
55
+ TRADING METRICS
56
+ ===============
57
+ Total Trades: {len(results.get('trades', []))}
58
+ Final Cash: ${results.get('final_cash', 0):,.2f}
59
+ Final Positions: {results.get('final_positions', {})}
60
+
61
+ === End of Detailed Report ===
62
+ """
63
+ return report
64
+
65
+ def save_report(self, report: str, filename: str) -> bool:
66
+ """Save report to file."""
67
+ try:
68
+ with open(filename, 'w') as f:
69
+ f.write(report)
70
+ self.logger.info(f"Report saved to: {filename}")
71
+ return True
72
+ except Exception as e:
73
+ self.logger.error(f"Failed to save report: {str(e)}")
74
+ return False
75
+
76
+ def export_trades_to_csv(self, trades: list, filename: str) -> bool:
77
+ """Export trades to CSV file."""
78
+ try:
79
+ if trades:
80
+ trade_df = pd.DataFrame(trades)
81
+ trade_df.to_csv(filename, index=False)
82
+ self.logger.info(f"Trades exported to: {filename}")
83
+ return True
84
+ else:
85
+ self.logger.warning("No trades to export")
86
+ return False
87
+ except Exception as e:
88
+ self.logger.error(f"Failed to export trades: {str(e)}")
89
+ return False
90
+
91
+
@@ -0,0 +1,19 @@
1
+ """
2
+ Core functionality for DeltaFQ.
3
+ """
4
+
5
+ from .config import Config
6
+ from .logger import Logger
7
+ from .exceptions import DeltaFQError, DataError, TradingError
8
+ from .base import BaseComponent
9
+
10
+ __all__ = [
11
+ "Config",
12
+ "Logger",
13
+ "DeltaFQError",
14
+ "DataError",
15
+ "TradingError",
16
+ "BaseComponent"
17
+ ]
18
+
19
+
@@ -0,0 +1,37 @@
1
+ """
2
+ Base classes for DeltaFQ components.
3
+ """
4
+
5
+ from abc import ABC, abstractmethod
6
+ from typing import Any, Dict
7
+ from .logger import Logger
8
+ from .config import Config
9
+
10
+
11
+ class BaseComponent(ABC):
12
+ """Base class for all DeltaFQ components."""
13
+
14
+ def __init__(self, name: str = None, config: Config = None):
15
+ """Initialize base component."""
16
+ self.name = name or self.__class__.__name__
17
+ self.config = config or Config()
18
+ self.logger = Logger(self.name)
19
+
20
+ @abstractmethod
21
+ def initialize(self) -> bool:
22
+ """Initialize the component."""
23
+ pass
24
+
25
+ def cleanup(self):
26
+ """Cleanup resources."""
27
+ pass
28
+
29
+ def get_info(self) -> Dict[str, Any]:
30
+ """Get component information."""
31
+ return {
32
+ "name": self.name,
33
+ "class": self.__class__.__name__,
34
+ "config": self.config.config
35
+ }
36
+
37
+