ml4t-backtest 0.1.0a2__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.
Files changed (81) hide show
  1. ml4t_backtest-0.1.0a2/.gitignore +36 -0
  2. ml4t_backtest-0.1.0a2/PKG-INFO +163 -0
  3. ml4t_backtest-0.1.0a2/README.md +68 -0
  4. ml4t_backtest-0.1.0a2/pyproject.toml +244 -0
  5. ml4t_backtest-0.1.0a2/src/ml4t/backtest/__init__.py +67 -0
  6. ml4t_backtest-0.1.0a2/src/ml4t/backtest/_version.py +34 -0
  7. ml4t_backtest-0.1.0a2/src/ml4t/backtest/accounting/__init__.py +27 -0
  8. ml4t_backtest-0.1.0a2/src/ml4t/backtest/accounting/account.py +219 -0
  9. ml4t_backtest-0.1.0a2/src/ml4t/backtest/accounting/gatekeeper.py +262 -0
  10. ml4t_backtest-0.1.0a2/src/ml4t/backtest/accounting/policy.py +736 -0
  11. ml4t_backtest-0.1.0a2/src/ml4t/backtest/analysis.py +414 -0
  12. ml4t_backtest-0.1.0a2/src/ml4t/backtest/analytics/__init__.py +37 -0
  13. ml4t_backtest-0.1.0a2/src/ml4t/backtest/analytics/bridge.py +139 -0
  14. ml4t_backtest-0.1.0a2/src/ml4t/backtest/analytics/equity.py +132 -0
  15. ml4t_backtest-0.1.0a2/src/ml4t/backtest/analytics/metrics.py +180 -0
  16. ml4t_backtest-0.1.0a2/src/ml4t/backtest/analytics/trades.py +463 -0
  17. ml4t_backtest-0.1.0a2/src/ml4t/backtest/broker.py +1180 -0
  18. ml4t_backtest-0.1.0a2/src/ml4t/backtest/calendar.py +773 -0
  19. ml4t_backtest-0.1.0a2/src/ml4t/backtest/config.py +554 -0
  20. ml4t_backtest-0.1.0a2/src/ml4t/backtest/datafeed.py +147 -0
  21. ml4t_backtest-0.1.0a2/src/ml4t/backtest/engine.py +471 -0
  22. ml4t_backtest-0.1.0a2/src/ml4t/backtest/execution/__init__.py +46 -0
  23. ml4t_backtest-0.1.0a2/src/ml4t/backtest/execution/fill_executor.py +461 -0
  24. ml4t_backtest-0.1.0a2/src/ml4t/backtest/execution/impact.py +185 -0
  25. ml4t_backtest-0.1.0a2/src/ml4t/backtest/execution/limits.py +186 -0
  26. ml4t_backtest-0.1.0a2/src/ml4t/backtest/execution/rebalancer.py +351 -0
  27. ml4t_backtest-0.1.0a2/src/ml4t/backtest/execution/result.py +32 -0
  28. ml4t_backtest-0.1.0a2/src/ml4t/backtest/export.py +312 -0
  29. ml4t_backtest-0.1.0a2/src/ml4t/backtest/models.py +134 -0
  30. ml4t_backtest-0.1.0a2/src/ml4t/backtest/presets/backtrader.yaml +46 -0
  31. ml4t_backtest-0.1.0a2/src/ml4t/backtest/presets/default.yaml +45 -0
  32. ml4t_backtest-0.1.0a2/src/ml4t/backtest/presets/realistic.yaml +48 -0
  33. ml4t_backtest-0.1.0a2/src/ml4t/backtest/presets/vectorbt.yaml +46 -0
  34. ml4t_backtest-0.1.0a2/src/ml4t/backtest/presets/zipline.yaml +46 -0
  35. ml4t_backtest-0.1.0a2/src/ml4t/backtest/result.py +764 -0
  36. ml4t_backtest-0.1.0a2/src/ml4t/backtest/risk/__init__.py +75 -0
  37. ml4t_backtest-0.1.0a2/src/ml4t/backtest/risk/portfolio/__init__.py +44 -0
  38. ml4t_backtest-0.1.0a2/src/ml4t/backtest/risk/portfolio/limits.py +601 -0
  39. ml4t_backtest-0.1.0a2/src/ml4t/backtest/risk/portfolio/manager.py +213 -0
  40. ml4t_backtest-0.1.0a2/src/ml4t/backtest/risk/position/__init__.py +34 -0
  41. ml4t_backtest-0.1.0a2/src/ml4t/backtest/risk/position/composite.py +103 -0
  42. ml4t_backtest-0.1.0a2/src/ml4t/backtest/risk/position/dynamic.py +345 -0
  43. ml4t_backtest-0.1.0a2/src/ml4t/backtest/risk/position/protocol.py +38 -0
  44. ml4t_backtest-0.1.0a2/src/ml4t/backtest/risk/position/signal.py +91 -0
  45. ml4t_backtest-0.1.0a2/src/ml4t/backtest/risk/position/static.py +253 -0
  46. ml4t_backtest-0.1.0a2/src/ml4t/backtest/risk/types.py +147 -0
  47. ml4t_backtest-0.1.0a2/src/ml4t/backtest/sessions.py +279 -0
  48. ml4t_backtest-0.1.0a2/src/ml4t/backtest/strategies/__init__.py +43 -0
  49. ml4t_backtest-0.1.0a2/src/ml4t/backtest/strategies/templates.py +395 -0
  50. ml4t_backtest-0.1.0a2/src/ml4t/backtest/strategy.py +28 -0
  51. ml4t_backtest-0.1.0a2/src/ml4t/backtest/types.py +377 -0
  52. ml4t_backtest-0.1.0a2/tests/__init__.py +1 -0
  53. ml4t_backtest-0.1.0a2/tests/accounting/__init__.py +1 -0
  54. ml4t_backtest-0.1.0a2/tests/accounting/test_account_state.py +361 -0
  55. ml4t_backtest-0.1.0a2/tests/accounting/test_cash_account_policy.py +470 -0
  56. ml4t_backtest-0.1.0a2/tests/accounting/test_gatekeeper.py +517 -0
  57. ml4t_backtest-0.1.0a2/tests/accounting/test_margin_account_policy.py +663 -0
  58. ml4t_backtest-0.1.0a2/tests/accounting/test_position.py +411 -0
  59. ml4t_backtest-0.1.0a2/tests/execution/__init__.py +1 -0
  60. ml4t_backtest-0.1.0a2/tests/execution/test_impact.py +247 -0
  61. ml4t_backtest-0.1.0a2/tests/execution/test_limits.py +241 -0
  62. ml4t_backtest-0.1.0a2/tests/execution/test_rebalancer.py +723 -0
  63. ml4t_backtest-0.1.0a2/tests/risk/__init__.py +1 -0
  64. ml4t_backtest-0.1.0a2/tests/risk/test_composite_rules.py +277 -0
  65. ml4t_backtest-0.1.0a2/tests/risk/test_dynamic_rules.py +567 -0
  66. ml4t_backtest-0.1.0a2/tests/risk/test_portfolio_limits.py +1006 -0
  67. ml4t_backtest-0.1.0a2/tests/risk/test_portfolio_manager.py +316 -0
  68. ml4t_backtest-0.1.0a2/tests/risk/test_signal_rules.py +221 -0
  69. ml4t_backtest-0.1.0a2/tests/risk/test_static_rules.py +465 -0
  70. ml4t_backtest-0.1.0a2/tests/test_analysis.py +623 -0
  71. ml4t_backtest-0.1.0a2/tests/test_broker.py +2464 -0
  72. ml4t_backtest-0.1.0a2/tests/test_calendar.py +500 -0
  73. ml4t_backtest-0.1.0a2/tests/test_calendar_integration.py +462 -0
  74. ml4t_backtest-0.1.0a2/tests/test_core.py +737 -0
  75. ml4t_backtest-0.1.0a2/tests/test_datafeed_memory.py +232 -0
  76. ml4t_backtest-0.1.0a2/tests/test_diagnostic_integration.py +147 -0
  77. ml4t_backtest-0.1.0a2/tests/test_export.py +410 -0
  78. ml4t_backtest-0.1.0a2/tests/test_result.py +583 -0
  79. ml4t_backtest-0.1.0a2/tests/test_sessions.py +289 -0
  80. ml4t_backtest-0.1.0a2/tests/test_strategy_templates.py +325 -0
  81. ml4t_backtest-0.1.0a2/tests/test_trade_mfe_mae.py +356 -0
@@ -0,0 +1,36 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ *.egg-info/
8
+ dist/
9
+ build/
10
+ eggs/
11
+ *.egg
12
+
13
+ # Virtual environments
14
+ .venv/
15
+ venv/
16
+ ENV/
17
+
18
+ # IDE
19
+ .idea/
20
+ .vscode/
21
+ *.swp
22
+ *.swo
23
+
24
+ # Testing
25
+ .pytest_cache/
26
+ .coverage
27
+ htmlcov/
28
+ .tox/
29
+ .nox/
30
+
31
+ # mypy
32
+ .mypy_cache/
33
+
34
+ # Jupyter
35
+ .ipynb_checkpoints/
36
+ src/ml4t/backtest/_version.py
@@ -0,0 +1,163 @@
1
+ Metadata-Version: 2.4
2
+ Name: ml4t-backtest
3
+ Version: 0.1.0a2
4
+ Summary: State-of-the-art event-driven backtesting engine for quantitative trading
5
+ Project-URL: Homepage, https://github.com/ml4t/ml4t-backtest
6
+ Project-URL: Documentation, https://ml4t-backtest.readthedocs.io
7
+ Project-URL: Repository, https://github.com/ml4t/ml4t-backtest
8
+ Project-URL: Issues, https://github.com/ml4t/ml4t-backtest/issues
9
+ Project-URL: Changelog, https://github.com/ml4t/ml4t-backtest/blob/main/CHANGELOG.md
10
+ Author-email: QuantLab Team <info@quantlab.io>
11
+ Maintainer-email: QuantLab Contributors <dev@quantlab.io>
12
+ License: MIT
13
+ Keywords: algorithmic-trading,backtesting,event-driven,execution,finance,polars,portfolio,quantitative-finance,risk-management,simulation,trading
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Financial and Insurance Industry
17
+ Classifier: Intended Audience :: Science/Research
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Office/Business :: Financial :: Investment
25
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
26
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
27
+ Classifier: Typing :: Typed
28
+ Requires-Python: >=3.11
29
+ Requires-Dist: numba>=0.57.0
30
+ Requires-Dist: numpy>=1.24.0
31
+ Requires-Dist: pandas-market-calendars>=4.0.0
32
+ Requires-Dist: pandas>=2.0.0
33
+ Requires-Dist: polars>=0.20.0
34
+ Requires-Dist: pyarrow>=14.0.0
35
+ Requires-Dist: pydantic<3.0.0,>=1.10.0
36
+ Requires-Dist: python-dateutil>=2.8.0
37
+ Requires-Dist: pyyaml>=6.0.0
38
+ Requires-Dist: sortedcontainers>=2.4.0
39
+ Requires-Dist: structlog>=23.0.0
40
+ Requires-Dist: tables>=3.8.0
41
+ Provides-Extra: advanced
42
+ Requires-Dist: cvxpy>=1.3.0; extra == 'advanced'
43
+ Requires-Dist: networkx>=3.0; extra == 'advanced'
44
+ Provides-Extra: all
45
+ Requires-Dist: cvxpy>=1.3.0; extra == 'all'
46
+ Requires-Dist: dash>=2.11.0; extra == 'all'
47
+ Requires-Dist: hypothesis>=6.80.0; extra == 'all'
48
+ Requires-Dist: ipdb>=0.13.0; extra == 'all'
49
+ Requires-Dist: ipython>=8.14.0; extra == 'all'
50
+ Requires-Dist: matplotlib>=3.7.0; extra == 'all'
51
+ Requires-Dist: mypy>=1.5.0; extra == 'all'
52
+ Requires-Dist: myst-parser>=2.0.0; extra == 'all'
53
+ Requires-Dist: nbsphinx>=0.9.0; extra == 'all'
54
+ Requires-Dist: networkx>=3.0; extra == 'all'
55
+ Requires-Dist: plotly>=5.15.0; extra == 'all'
56
+ Requires-Dist: pre-commit>=3.3.0; extra == 'all'
57
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'all'
58
+ Requires-Dist: pytest-benchmark>=4.0.0; extra == 'all'
59
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'all'
60
+ Requires-Dist: pytest-timeout>=2.1.0; extra == 'all'
61
+ Requires-Dist: pytest-xdist>=3.3.0; extra == 'all'
62
+ Requires-Dist: pytest>=7.4.0; extra == 'all'
63
+ Requires-Dist: ruff>=0.1.0; extra == 'all'
64
+ Requires-Dist: sphinx-autodoc-typehints>=1.24.0; extra == 'all'
65
+ Requires-Dist: sphinx-rtd-theme>=1.3.0; extra == 'all'
66
+ Requires-Dist: sphinx>=7.0.0; extra == 'all'
67
+ Provides-Extra: comparison
68
+ Requires-Dist: backtrader>=1.9.0; extra == 'comparison'
69
+ Requires-Dist: vectorbt>=0.24.0; extra == 'comparison'
70
+ Requires-Dist: zipline-reloaded>=2.4.0; extra == 'comparison'
71
+ Provides-Extra: dev
72
+ Requires-Dist: hypothesis>=6.80.0; extra == 'dev'
73
+ Requires-Dist: ipdb>=0.13.0; extra == 'dev'
74
+ Requires-Dist: ipython>=8.14.0; extra == 'dev'
75
+ Requires-Dist: mypy>=1.5.0; extra == 'dev'
76
+ Requires-Dist: pre-commit>=3.3.0; extra == 'dev'
77
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
78
+ Requires-Dist: pytest-benchmark>=4.0.0; extra == 'dev'
79
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
80
+ Requires-Dist: pytest-timeout>=2.1.0; extra == 'dev'
81
+ Requires-Dist: pytest-xdist>=3.3.0; extra == 'dev'
82
+ Requires-Dist: pytest>=7.4.0; extra == 'dev'
83
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
84
+ Provides-Extra: docs
85
+ Requires-Dist: myst-parser>=2.0.0; extra == 'docs'
86
+ Requires-Dist: nbsphinx>=0.9.0; extra == 'docs'
87
+ Requires-Dist: sphinx-autodoc-typehints>=1.24.0; extra == 'docs'
88
+ Requires-Dist: sphinx-rtd-theme>=1.3.0; extra == 'docs'
89
+ Requires-Dist: sphinx>=7.0.0; extra == 'docs'
90
+ Provides-Extra: viz
91
+ Requires-Dist: dash>=2.11.0; extra == 'viz'
92
+ Requires-Dist: matplotlib>=3.7.0; extra == 'viz'
93
+ Requires-Dist: plotly>=5.15.0; extra == 'viz'
94
+ Description-Content-Type: text/markdown
95
+
96
+ # ml4t-backtest
97
+
98
+ Event-driven backtesting engine for ML4T quantitative trading strategies.
99
+
100
+ ## Features
101
+
102
+ - **Event-Driven Architecture**: Point-in-time correctness with no look-ahead bias
103
+ - **Exit-First Processing**: Matches real broker order execution behavior
104
+ - **VectorBT Validation**: Results validated against VectorBT Pro
105
+ - **Account Policies**: Cash and margin account support
106
+ - **Minimal Core**: ~2,800 lines of focused, maintainable code
107
+ - **100k+ events/sec**: High-performance event processing
108
+
109
+ ## Installation
110
+
111
+ ```bash
112
+ pip install ml4t-backtest
113
+ ```
114
+
115
+ ## Quick Start
116
+
117
+ ```python
118
+ from ml4t.backtest import Engine, Strategy, BacktestConfig
119
+
120
+ class SimpleMovingAverage(Strategy):
121
+ def __init__(self, fast=10, slow=30):
122
+ self.fast = fast
123
+ self.slow = slow
124
+
125
+ def on_bar(self, bar):
126
+ fast_ma = bar.close_ma(self.fast)
127
+ slow_ma = bar.close_ma(self.slow)
128
+
129
+ if fast_ma > slow_ma and self.position == 0:
130
+ self.buy(size=100)
131
+ elif fast_ma < slow_ma and self.position > 0:
132
+ self.close()
133
+
134
+ config = BacktestConfig(
135
+ initial_cash=100_000,
136
+ commission=0.001,
137
+ )
138
+
139
+ engine = Engine(data, SimpleMovingAverage(), config)
140
+ result = engine.run()
141
+
142
+ print(f"Total Return: {result.total_return:.2%}")
143
+ print(f"Sharpe Ratio: {result.metrics['sharpe']:.2f}")
144
+ ```
145
+
146
+ ## Documentation
147
+
148
+ - **[AGENT.md](AGENT.md)**: Comprehensive API reference for agents and developers
149
+ - **[api.yaml](api.yaml)**: Machine-readable API specification
150
+
151
+ ## Part of ML4T
152
+
153
+ This library is part of the ML4T quantitative trading toolkit:
154
+
155
+ - **ml4t-data**: Market data acquisition and storage
156
+ - **ml4t-engineer**: Feature engineering and indicators
157
+ - **ml4t-diagnostic**: Statistical validation and evaluation
158
+ - **ml4t-backtest**: Event-driven backtesting (this library)
159
+ - **ml4t-live**: Live trading platform
160
+
161
+ ## License
162
+
163
+ MIT License - see LICENSE for details.
@@ -0,0 +1,68 @@
1
+ # ml4t-backtest
2
+
3
+ Event-driven backtesting engine for ML4T quantitative trading strategies.
4
+
5
+ ## Features
6
+
7
+ - **Event-Driven Architecture**: Point-in-time correctness with no look-ahead bias
8
+ - **Exit-First Processing**: Matches real broker order execution behavior
9
+ - **VectorBT Validation**: Results validated against VectorBT Pro
10
+ - **Account Policies**: Cash and margin account support
11
+ - **Minimal Core**: ~2,800 lines of focused, maintainable code
12
+ - **100k+ events/sec**: High-performance event processing
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install ml4t-backtest
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ```python
23
+ from ml4t.backtest import Engine, Strategy, BacktestConfig
24
+
25
+ class SimpleMovingAverage(Strategy):
26
+ def __init__(self, fast=10, slow=30):
27
+ self.fast = fast
28
+ self.slow = slow
29
+
30
+ def on_bar(self, bar):
31
+ fast_ma = bar.close_ma(self.fast)
32
+ slow_ma = bar.close_ma(self.slow)
33
+
34
+ if fast_ma > slow_ma and self.position == 0:
35
+ self.buy(size=100)
36
+ elif fast_ma < slow_ma and self.position > 0:
37
+ self.close()
38
+
39
+ config = BacktestConfig(
40
+ initial_cash=100_000,
41
+ commission=0.001,
42
+ )
43
+
44
+ engine = Engine(data, SimpleMovingAverage(), config)
45
+ result = engine.run()
46
+
47
+ print(f"Total Return: {result.total_return:.2%}")
48
+ print(f"Sharpe Ratio: {result.metrics['sharpe']:.2f}")
49
+ ```
50
+
51
+ ## Documentation
52
+
53
+ - **[AGENT.md](AGENT.md)**: Comprehensive API reference for agents and developers
54
+ - **[api.yaml](api.yaml)**: Machine-readable API specification
55
+
56
+ ## Part of ML4T
57
+
58
+ This library is part of the ML4T quantitative trading toolkit:
59
+
60
+ - **ml4t-data**: Market data acquisition and storage
61
+ - **ml4t-engineer**: Feature engineering and indicators
62
+ - **ml4t-diagnostic**: Statistical validation and evaluation
63
+ - **ml4t-backtest**: Event-driven backtesting (this library)
64
+ - **ml4t-live**: Live trading platform
65
+
66
+ ## License
67
+
68
+ MIT License - see LICENSE for details.
@@ -0,0 +1,244 @@
1
+ # ml4t.backtest - Event-driven backtesting with institutional-grade correctness guarantees
2
+ # Independent package configuration for standalone distribution
3
+
4
+ [build-system]
5
+ requires = ["hatchling", "hatch-vcs"]
6
+ build-backend = "hatchling.build"
7
+
8
+ [tool.hatch.version]
9
+ source = "vcs"
10
+
11
+ [tool.hatch.build.hooks.vcs]
12
+ version-file = "src/ml4t/backtest/_version.py"
13
+
14
+ [tool.hatch.build.targets.wheel]
15
+ packages = ["src/ml4t"]
16
+ namespaces = true
17
+
18
+ [tool.hatch.build.targets.sdist]
19
+ include = [
20
+ "/src",
21
+ "/tests",
22
+ "/README.md",
23
+ "/LICENSE",
24
+ "/CHANGELOG.md",
25
+ ]
26
+
27
+ [project]
28
+ name = "ml4t-backtest"
29
+ dynamic = ["version"]
30
+ description = "State-of-the-art event-driven backtesting engine for quantitative trading"
31
+ readme = "README.md"
32
+ license = { text = "MIT" }
33
+ authors = [
34
+ { name = "QuantLab Team", email = "info@quantlab.io" },
35
+ ]
36
+ maintainers = [
37
+ { name = "QuantLab Contributors", email = "dev@quantlab.io" },
38
+ ]
39
+ keywords = [
40
+ "finance",
41
+ "backtesting",
42
+ "trading",
43
+ "simulation",
44
+ "event-driven",
45
+ "quantitative-finance",
46
+ "algorithmic-trading",
47
+ "portfolio",
48
+ "risk-management",
49
+ "execution",
50
+ "polars",
51
+ ]
52
+ classifiers = [
53
+ "Development Status :: 4 - Beta",
54
+ "Intended Audience :: Financial and Insurance Industry",
55
+ "Intended Audience :: Developers",
56
+ "Intended Audience :: Science/Research",
57
+ "License :: OSI Approved :: MIT License",
58
+ "Operating System :: OS Independent",
59
+ "Programming Language :: Python :: 3",
60
+ "Programming Language :: Python :: 3.11",
61
+ "Programming Language :: Python :: 3.12",
62
+ "Programming Language :: Python :: 3.13",
63
+ "Topic :: Office/Business :: Financial :: Investment",
64
+ "Topic :: Scientific/Engineering :: Information Analysis",
65
+ "Topic :: Software Development :: Libraries :: Application Frameworks",
66
+ "Typing :: Typed",
67
+ ]
68
+ requires-python = ">=3.11"
69
+
70
+ # Core dependencies
71
+ dependencies = [
72
+ # Data processing
73
+ "polars>=0.20.0",
74
+ "pandas>=2.0.0",
75
+ "numpy>=1.24.0",
76
+ "pyarrow>=14.0.0",
77
+ "tables>=3.8.0", # PyTables for HDF5 support
78
+ # Event system
79
+ "sortedcontainers>=2.4.0", # Efficient priority queue
80
+ # Performance optimization
81
+ "numba>=0.57.0",
82
+ # Configuration and validation
83
+ "pydantic>=1.10.0,<3.0.0", # Configuration schema and validation
84
+ "PyYAML>=6.0.0", # YAML configuration support
85
+ # Utilities
86
+ "structlog>=23.0.0",
87
+ "python-dateutil>=2.8.0",
88
+ # Market calendars (needed for clock module)
89
+ "pandas-market-calendars>=4.0.0",
90
+ ]
91
+
92
+ [project.optional-dependencies]
93
+ # Visualization and reporting
94
+ viz = [
95
+ "plotly>=5.15.0",
96
+ "matplotlib>=3.7.0",
97
+ "dash>=2.11.0", # Interactive dashboards
98
+ ]
99
+
100
+ # Advanced execution models
101
+ advanced = [
102
+ "networkx>=3.0", # Order routing graphs
103
+ "cvxpy>=1.3.0", # Portfolio optimization
104
+ ]
105
+
106
+ # Comparison libraries (for benchmarking)
107
+ comparison = [
108
+ "vectorbt>=0.24.0",
109
+ "backtrader>=1.9.0",
110
+ "zipline-reloaded>=2.4.0",
111
+ ]
112
+
113
+ # Development dependencies
114
+ dev = [
115
+ "pytest>=7.4.0",
116
+ "pytest-cov>=4.1.0",
117
+ "pytest-xdist>=3.3.0",
118
+ "pytest-timeout>=2.1.0",
119
+ "pytest-benchmark>=4.0.0",
120
+ "pytest-asyncio>=0.21.0",
121
+ "hypothesis>=6.80.0",
122
+ "ruff>=0.1.0",
123
+ "mypy>=1.5.0",
124
+ "ipython>=8.14.0",
125
+ "ipdb>=0.13.0",
126
+ "pre-commit>=3.3.0",
127
+ ]
128
+
129
+ # Documentation dependencies
130
+ docs = [
131
+ "sphinx>=7.0.0",
132
+ "sphinx-rtd-theme>=1.3.0",
133
+ "sphinx-autodoc-typehints>=1.24.0",
134
+ "myst-parser>=2.0.0",
135
+ "nbsphinx>=0.9.0",
136
+ ]
137
+
138
+ # All optional dependencies
139
+ all = [
140
+ "ml4t-backtest[viz,advanced,dev,docs]",
141
+ ]
142
+
143
+ [project.urls]
144
+ Homepage = "https://github.com/ml4t/ml4t-backtest"
145
+ Documentation = "https://ml4t-backtest.readthedocs.io"
146
+ Repository = "https://github.com/ml4t/ml4t-backtest"
147
+ Issues = "https://github.com/ml4t/ml4t-backtest/issues"
148
+ Changelog = "https://github.com/ml4t/ml4t-backtest/blob/main/CHANGELOG.md"
149
+
150
+ [tool.pytest.ini_options]
151
+ testpaths = ["tests"]
152
+ python_files = ["test_*.py"]
153
+ python_classes = ["Test*"]
154
+ python_functions = ["test_*"]
155
+ addopts = [
156
+ "-ra",
157
+ "--strict-markers",
158
+ "--ignore=tests/private", # Exclude private/commercial dependency tests
159
+ "--ignore=tests/validation", # Exclude optional cross-framework validation tests
160
+ "--cov=ml4t.backtest",
161
+ "--cov-report=term-missing",
162
+ "--cov-report=html",
163
+ ]
164
+ markers = [
165
+ "slow: marks tests as slow (deselect with '-m \"not slow\"')",
166
+ "integration: marks tests as integration tests",
167
+ "benchmark: marks benchmark tests",
168
+ "unit: marks unit tests",
169
+ "private: requires commercial dependencies (vectorbtpro) - excluded by default",
170
+ "requires_comparison: requires optional comparison frameworks (vectorbt, backtrader, zipline)",
171
+ ]
172
+ filterwarnings = [
173
+ "ignore::DeprecationWarning",
174
+ "ignore::PendingDeprecationWarning",
175
+ "ignore::UserWarning:vectorbt", # VectorBT accessor registration warnings
176
+ "ignore::tables.NaturalNameWarning", # PyTables naming warnings
177
+ "ignore::FutureWarning:zipline", # Zipline compatibility warnings
178
+ "ignore::pytest.PytestReturnNotNoneWarning", # Some tests return values for direct execution
179
+ ]
180
+
181
+ [tool.ruff]
182
+ line-length = 100
183
+ target-version = "py311"
184
+ fix = true
185
+ exclude = [
186
+ "validation/*", # Standalone scripts run in isolated venvs
187
+ "docs/*", # Documentation artifacts
188
+ ".claude/*", # Claude workspace files
189
+ ".serena/*", # Serena workspace files
190
+ ]
191
+
192
+ [tool.ruff.lint]
193
+ select = [
194
+ "E", # pycodestyle errors
195
+ "W", # pycodestyle warnings
196
+ "F", # pyflakes
197
+ "I", # isort
198
+ "B", # flake8-bugbear
199
+ "C4", # flake8-comprehensions
200
+ "UP", # pyupgrade
201
+ "ARG", # flake8-unused-arguments
202
+ "SIM", # flake8-simplify
203
+ ]
204
+ ignore = [
205
+ "E501", # line too long (handled by formatter)
206
+ "B008", # do not perform function calls in argument defaults
207
+ "B905", # zip without explicit strict parameter
208
+ "ARG002", # unused method arguments (intentional in strategy callbacks)
209
+ ]
210
+
211
+ [tool.ruff.lint.per-file-ignores]
212
+ "tests/*" = ["ARG001", "ARG002"] # Test functions often have unused fixtures
213
+
214
+ [tool.mypy]
215
+ python_version = "3.11"
216
+ strict = false
217
+ warn_return_any = false # numpy/pandas return Any, too many false positives
218
+ warn_unused_ignores = true
219
+ disallow_untyped_defs = false
220
+ disallow_any_unimported = false
221
+ no_implicit_optional = true
222
+ check_untyped_defs = true
223
+ show_error_codes = true
224
+ warn_redundant_casts = true
225
+ ignore_missing_imports = true
226
+
227
+ [tool.coverage.run]
228
+ source = ["src/ml4t/backtest"]
229
+ omit = [
230
+ "*/tests/*",
231
+ "*/__init__.py",
232
+ ]
233
+
234
+ [tool.coverage.report]
235
+ exclude_lines = [
236
+ "pragma: no cover",
237
+ "def __repr__",
238
+ "if self.debug:",
239
+ "if __name__ == .__main__.:",
240
+ "raise NotImplementedError",
241
+ "pass",
242
+ "except ImportError:",
243
+ "@abstractmethod",
244
+ ]
@@ -0,0 +1,67 @@
1
+ """ML4T Backtest - Event-driven backtesting engine.
2
+
3
+ A minimal, event-driven backtesting engine with:
4
+ - Point-in-time correctness
5
+ - Exit-first order processing
6
+ - Cash and margin account policies
7
+ - VectorBT-validated results
8
+
9
+ Example:
10
+ >>> from ml4t.backtest import Engine, Strategy, BacktestConfig
11
+ >>>
12
+ >>> class MyStrategy(Strategy):
13
+ ... def on_bar(self, bar):
14
+ ... if self.position == 0:
15
+ ... self.buy(size=100)
16
+ >>>
17
+ >>> result = Engine(data, MyStrategy()).run()
18
+ >>> print(result.metrics)
19
+ """
20
+
21
+ from ml4t.backtest.types import (
22
+ Order,
23
+ OrderType,
24
+ OrderSide,
25
+ Fill,
26
+ Position,
27
+ Trade,
28
+ )
29
+ from ml4t.backtest.config import BacktestConfig
30
+ from ml4t.backtest.strategy import Strategy
31
+ from ml4t.backtest.engine import Engine
32
+ from ml4t.backtest.broker import Broker
33
+ from ml4t.backtest.datafeed import DataFeed
34
+ from ml4t.backtest.result import BacktestResult
35
+
36
+ try:
37
+ from ml4t.backtest._version import __version__
38
+ except ImportError:
39
+ __version__ = "0.0.0.dev0"
40
+
41
+ __all__ = [
42
+ # Core types
43
+ "Order",
44
+ "OrderType",
45
+ "OrderSide",
46
+ "Fill",
47
+ "Position",
48
+ "Trade",
49
+ # Main classes
50
+ "BacktestConfig",
51
+ "Strategy",
52
+ "Engine",
53
+ "Broker",
54
+ "DataFeed",
55
+ "BacktestResult",
56
+ ]
57
+
58
+
59
+ def list_order_types() -> list[str]:
60
+ """List available order types."""
61
+ return [t.name for t in OrderType]
62
+
63
+
64
+ def list_presets() -> list[str]:
65
+ """List available configuration presets."""
66
+ from ml4t.backtest import presets
67
+ return [name for name in dir(presets) if not name.startswith('_')]
@@ -0,0 +1,34 @@
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
12
+
13
+ TYPE_CHECKING = False
14
+ if TYPE_CHECKING:
15
+ from typing import Tuple
16
+ from typing import Union
17
+
18
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
20
+ else:
21
+ VERSION_TUPLE = object
22
+ COMMIT_ID = object
23
+
24
+ version: str
25
+ __version__: str
26
+ __version_tuple__: VERSION_TUPLE
27
+ version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
30
+
31
+ __version__ = version = '0.1.0a2'
32
+ __version_tuple__ = version_tuple = (0, 1, 0, 'a2')
33
+
34
+ __commit_id__ = commit_id = None
@@ -0,0 +1,27 @@
1
+ """Accounting module for backtesting engine.
2
+
3
+ Provides proper accounting constraints for both cash accounts (no leverage, no shorts)
4
+ and margin accounts (leverage enabled, shorts allowed).
5
+
6
+ Key Components:
7
+ - Position: Unified position tracking (from types module)
8
+ - AccountPolicy: Interface for account type constraints
9
+ - CashAccountPolicy: Cash account constraints (cash >= 0, no shorts)
10
+ - MarginAccountPolicy: Margin account constraints (NLV/BP/MM calculations)
11
+ - AccountState: Account state management and position tracking
12
+ - Gatekeeper: Order validation before execution
13
+ """
14
+
15
+ from ..types import Position
16
+ from .account import AccountState
17
+ from .gatekeeper import Gatekeeper
18
+ from .policy import AccountPolicy, CashAccountPolicy, MarginAccountPolicy
19
+
20
+ __all__ = [
21
+ "Position",
22
+ "AccountPolicy",
23
+ "CashAccountPolicy",
24
+ "MarginAccountPolicy",
25
+ "AccountState",
26
+ "Gatekeeper",
27
+ ]