🔎 📈 🐍 💰 Backtest trading strategies in Python.
This report presents the forensic synthetic code analysis of kernc/backtesting.py, a Python project with 8,748 GitHub stars. SynthScan v2.0 examined 8,328 lines of code across 37 source files, recording 98 pattern matches distributed across 13 syntactic categories. The overall adjusted score of 19.0 places this repository in the Moderate AI signal band.
The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).
Longitudinal tracking requires multiple scan runs. Once this repository is re-scanned after new commits land, this chart will visualise how the synthetic code signal evolves over time — enabling you to detect whether AI authorship is growing, stabilising, or being actively corrected by human engineers.
Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.
This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.
The scanner identified 98 distinct pattern matches across 13 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH⚡ | backtesting/_plotting.py | 160 | assert not indicators or indicators[0].df.index.equals(df.index) | CODE |
| HIGH⚡ | backtesting/_plotting.py | 163 | assert equity_data.index.equals(df.index) | CODE |
| HIGH | backtesting/_plotting.py | 221 | assert df.index.equals(results['_equity_curve'].index) | CODE |
| HIGH | backtesting/_plotting.py | 289 | this.labels = this.labels || formatter.doFormat(ticks | CODE |
| HIGH | backtesting/_plotting.py | 291 | .filter(t => t !== undefined)); | CODE |
| HIGH | backtesting/_plotting.py | 361 | assert equity.index.equals(equity_data.index) | STRING |
| HIGH⚡ | backtesting/test/_test.py | 1124 | assert close.s.equals(pd.Series(close, index=index)) | CODE |
| HIGH⚡ | backtesting/test/_test.py | 1130 | assert close.s.equals(pd.Series(close, index=index)) | CODE |
| HIGH | backtesting/test/_test.py | 309 | self.assertTrue(df.equals(EURUSD)) | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | backtesting/lib.py | 261 | # Let's convert closing prices back to pandas Series. | COMMENT |
| LOW | doc/examples/Strategies Library.py | 1 | # --- | COMMENT |
| LOW | doc/examples/Strategies Library.py | 21 | # [basic package usage](https://kernc.github.io/backtesting.py/doc/examples/Quick%20Start%20User%20Guide.html). | COMMENT |
| LOW | doc/examples/Strategies Library.py | 101 | # For other strategies of the sort, and other reusable utilities in general, see | COMMENT |
| LOW | doc/examples/Quick Start User Guide.py | 1 | # --- | COMMENT |
| LOW | doc/examples/Quick Start User Guide.py | 21 | # _Backtesting.py_ is a small and lightweight, blazing fast backtesting framework that uses state-of-the-art Python stru | COMMENT |
| LOW | doc/examples/Quick Start User Guide.py | 41 | # DataFrame should ideally be indexed with a _datetime index_ (convert it with [`pd.to_datetime()`](https://pandas.pydat | COMMENT |
| LOW | doc/examples/Quick Start User Guide.py | 121 | # [`self.data`](https://kernc.github.io/backtesting.py/doc/backtesting/backtesting.html#backtesting.backtesting.Strategy | COMMENT |
| LOW | doc/examples/Quick Start User Guide.py | 141 | # self.position.close() | COMMENT |
| LOW | doc/examples/Quick Start User Guide.py | 161 | from backtesting import Backtest | COMMENT |
| LOW | doc/examples/Quick Start User Guide.py | 201 | # %% | COMMENT |
| LOW | doc/examples/Quick Start User Guide.py | 221 | # The columns should be self-explanatory. | COMMENT |
| LOW | doc/examples/Parameter Heatmap & Optimization.py | 1 | # -*- coding: utf-8 -*- | COMMENT |
| LOW | doc/examples/Parameter Heatmap & Optimization.py | 21 | # It is assumed you're already familiar with | COMMENT |
| LOW | doc/examples/Parameter Heatmap & Optimization.py | 121 | # It makes the function return a heatmap series along with the usual stats of the best run. | COMMENT |
| LOW | doc/examples/Parameter Heatmap & Optimization.py | 161 | ) | COMMENT |
| LOW | doc/examples/Parameter Heatmap & Optimization.py | 181 | # ## Model-based optimization | COMMENT |
| LOW | doc/examples/Trading with Machine Learning.py | 1 | # --- | COMMENT |
| LOW | doc/examples/Trading with Machine Learning.py | 21 | # [basic framework usage](https://kernc.github.io/backtesting.py/doc/examples/Quick%20Start%20User%20Guide.html) | COMMENT |
| LOW | doc/examples/Trading with Machine Learning.py | 261 | bt.plot() | COMMENT |
| LOW | doc/examples/Trading with Machine Learning.py | 281 | # by increasing the conviction needed and imposing extra domain expertise and discretionary limitations before enterin | COMMENT |
| LOW | doc/examples/Multiple Time Frames.py | 1 | # --- | COMMENT |
| LOW | doc/examples/Multiple Time Frames.py | 21 | # [pandas resampling](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#resampling). | COMMENT |
| LOW | doc/examples/Multiple Time Frames.py | 141 | # In conclusion, to test strategies on multiple time frames, you need to pass in OHLC data in the lowest time frame, the | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | backtesting/_stats.py | 14 | def compute_drawdown_duration_peaks(dd: pd.Series): | CODE |
| LOW⚡ | backtesting/test/_test.py | 1136 | def test_indicators_picklable(self): | CODE |
| LOW | backtesting/test/_test.py | 100 | def test_data_missing_columns(self): | CODE |
| LOW | backtesting/test/_test.py | 238 | def test_absolute_size_order_warns_on_insufficient_margin(self): | CODE |
| LOW | backtesting/test/_test.py | 393 | def test_compute_stats_bordercase(self): | CODE |
| LOW | backtesting/test/_test.py | 426 | def test_trade_enter_hit_sl_on_same_day(self): | CODE |
| LOW | backtesting/test/_test.py | 444 | def test_stop_price_between_sl_tp(self): | CODE |
| LOW | backtesting/test/_test.py | 453 | def test_position_close_portion(self): | CODE |
| LOW | backtesting/test/_test.py | 468 | def test_close_orders_from_last_strategy_iteration(self): | CODE |
| LOW | backtesting/test/_test.py | 480 | def test_check_adjusted_price_when_placing_order(self): | CODE |
| LOW | backtesting/test/_test.py | 533 | def test_broker_exclusive_orders(self): | CODE |
| LOW | backtesting/test/_test.py | 545 | def test_trade_multiple_close(self): | CODE |
| LOW | backtesting/test/_test.py | 566 | def test_stop_limit_order_price_is_stop_price(self): | CODE |
| LOW | backtesting/test/_test.py | 575 | def test_autoclose_trades_on_finish(self): | CODE |
| LOW | backtesting/test/_test.py | 659 | def test_optimize_invalid_param(self): | CODE |
| LOW | backtesting/test/_test.py | 807 | def test_resample_trades_vectorized(self): | CODE |
| LOW | backtesting/test/_test.py | 1160 | def test_backtest_run_docstring_contains_stats_keys(self): | CODE |
| LOW | backtesting/test/_test.py | 1165 | def test_readme_contains_stats_keys(self): | CODE |
| LOW | backtesting/test/_test.py | 1204 | def test_trade_on_close_closes_trades_on_close(self): | CODE |
| LOW | backtesting/test/_test.py | 1239 | def test_trades_dates_match_prices(self): | CODE |
| LOW | backtesting/test/_test.py | 1259 | def test_stop_entry_and_tp_in_same_bar(self): | CODE |
| LOW | backtesting/test/_test.py | 1270 | def test_optimize_datetime_index_with_timezone(self): | CODE |
| LOW | backtesting/test/_test.py | 1276 | def test_sl_tp_values_in_trades_df(self): | CODE |
| LOW | backtesting/test/_test.py | 1287 | def test_sl_value_in_trades_df_when_gapped_through(self): | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | doc/examples/Strategies Library.py | 17 | # ====================== | COMMENT |
| MEDIUM | doc/examples/Quick Start User Guide.py | 17 | # ======================= | COMMENT |
| MEDIUM | doc/examples/Parameter Heatmap & Optimization.py | 18 | # ========== | COMMENT |
| MEDIUM | doc/examples/Multiple Time Frames.py | 17 | # ============ | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | doc/examples/Strategies Library.py | 20 | # It is, henceforth, assumed you're already familiar with | COMMENT |
| MEDIUM | doc/examples/Quick Start User Guide.py | 21 | # _Backtesting.py_ is a small and lightweight, blazing fast backtesting framework that uses state-of-the-art Python stru | COMMENT |
| MEDIUM | doc/examples/Parameter Heatmap & Optimization.py | 91 | # It's not a robust strategy, but we can optimize it. | COMMENT |
| MEDIUM | doc/examples/Trading with Machine Learning.py | 151 | # Let's backtest a simple strategy that buys the asset for 20% of available equity with 20:1 leverage whenever the forec | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | backtesting/backtesting.py | 9 | CODE | |
| LOW | backtesting/lib.py | 14 | CODE | |
| LOW | backtesting/__init__.py | 68 | CODE | |
| LOW | backtesting/__init__.py | 69 | CODE | |
| LOW | backtesting/__init__.py | 71 | CODE | |
| LOW | backtesting/__init__.py | 71 | CODE | |
| LOW | backtesting/_plotting.py | 1 | CODE | |
| LOW | backtesting/_util.py | 1 | CODE | |
| LOW | backtesting/_stats.py | 1 | CODE | |
| LOW | backtesting/test/__init__.py | 3 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | backtesting/backtesting.py | 765 | CODE | |
| LOW | backtesting/backtesting.py | 875 | CODE | |
| LOW | backtesting/backtesting.py | 1271 | CODE | |
| LOW | backtesting/backtesting.py | 1386 | CODE | |
| LOW | backtesting/backtesting.py | 1513 | CODE | |
| LOW | backtesting/lib.py | 427 | CODE | |
| LOW | backtesting/_plotting.py | 198 | CODE | |
| LOW | backtesting/_plotting.py | 535 | CODE | |
| LOW | backtesting/_stats.py | 37 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | backtesting/backtesting.py | 1195 | CODE | |
| LOW | backtesting/backtesting.py | 1658 | CODE | |
| LOW | backtesting/lib.py | 330 | CODE | |
| LOW | backtesting/_plotting.py | 198 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | backtesting/backtesting.py | 145 | except Exception as e: | CODE |
| LOW⚡ | backtesting/_plotting.py | 152 | except Exception: | CODE |
| LOW | backtesting/_util.py | 304 | except Exception: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | backtesting/backtesting.py | 887 | # Check if stop condition was hit | COMMENT |
| LOW | backtesting/backtesting.py | 899 | # Check if limit order can be filled. | COMMENT |
| LOW | backtesting/_plotting.py | 495 | # Check if resampling was downsampling; error on upsampling | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | doc/examples/Quick Start User Guide.py | 95 | # Define the two MA lags as *class variables* | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | backtesting/backtesting.py | 1772 | __all__ = [getattr(v, '__name__', k) | CODE |
| LOW | backtesting/lib.py | 640 | __all__ = [getattr(v, '__name__', k) | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | doc/examples/Trading with Machine Learning.py | 283 | # Also make sure to familiarize yourself with the full | COMMENT |