8. Backtesting-Engine und Leistung (Designperspektive)

In diesem Kapitel wird aus der Perspektive der Architektur und Implementierung erklärt, wie die Backtesting-Engine von qteasy Vektorisierung und Numba verwendet und wie sie sich von Frameworks wie VectorBT unterscheidet, für Leser, die ein tieferes Verständnis benötigen oder technische Entscheidungen treffen. Erläuterungen zur Nutzungsebene finden Sie unter 6. Backtesting Engine und Leistung in „Backtest und Evaluierung von Handelsstrategien“.

8.1. 1. 回测引擎在整体中的位置

Der Arbeitsablauf des Backtest-Modus (Modus=1) ist in Backtesting, Live-Handel und Optimierung zusammengefasst: Historische Daten vorbereiten → Backtester erstellen → Operator Schritt für Schritt gemäß group_timing_table ausführen, um Signale zu generieren → Signale analysieren und Füllungen simulieren → auswerten und ausgeben. Unter anderem wird „Signale analysieren und Füllungen simulieren“ von den Numba-Funktionen im Backtest-Modul verarbeitet, wodurch „sequentiell entlang der Zeitdimension, vektorisiert entlang der Instrumentendimension“ erreicht wird.

8.2. 2. Numba 使用点与向量化结构

2.1 Kernfunktionen

qteasy/backtest.py 中:

  • backtest_step: @njit(nogil=True, Cache=True). In einem einzigen Schritt berechnet es auf der Grundlage der Signale und der aktuellen Positionen, des Bargelds und der Abwicklungswarteschlange Kauf-/Verkaufsmengen, Gebühren, Positionsaktualisierungen und Aktualisierungen der Abwicklungswarteschlange. Es führt Array-Operationen für den gesamten Instrumentenstapel durch.

  • calculate_trade_results: „@njit“, wird zur Berechnung von Handelsergebnissen und Bargeldänderungen verwendet.

  • backtest_batch_steps: @njit(nogil=True, Cache=True). Es durchläuft innerhalb von Numba eine Schleife nach „signal_count“ (Anzahl der Zeitschritte); Bei jedem Schritt wird „backtest_step“ aufgerufen, um das gesamte Backtest-Segment abzuschließen und so „sequenziell entlang der Zeitdimension, vektorisiert entlang der Instrumentendimension“ zu erreichen.

  • backtest_flash_steps: @njit(nogil=True, Cache=True). Ähnlich wie „backtest_batch_steps“, aber es behält keine Zwischen-Bargeld- und Positionsreihen bei – nur der Endzustand wird beibehalten – um während der Optimierungsphase beim Backtesten mehrerer Parametersätze Speicherplatz zu sparen.

In „qteasy/blender.py“ verwenden einige Operatoren, die für die Signalmischung verwendet werden (wie „op_sum“, „op_floor“ usw.), auch „@njit“ für die Beschleunigung.

2.2 Zeitdimensionale Ordnung und Vektorisierung entlang der Instrumentendimension

  • Die Zeitdimension muss sequentiell sein: Da es Zustände wie die Abwicklungswarteschlange, T+1, MOQ usw. gibt, hängt der nächste Handel von den aktuellen Positionen und dem Abwicklungsstatus ab und kann daher nicht vollständig entlang der Zeitachse parallelisiert oder auf einmal in eine Matrix umgewandelt werden.

  • Vektorisierung der Instrumentendimension: Verwenden Sie innerhalb jedes Zeitschritts NumPy-Arrays und Inline-Operationen in Numba für die Signale, Positionen, Kauf-/Verkaufsmengen, Gebühren usw. aller Instrumente und vermeiden Sie Schleifen auf Python-Ebene.

Daher kann ein einzelner Backtest wie folgt verstanden werden: eine Zeitschrittschleife innerhalb einer Numba-Ebene + vektorisierte Berechnung innerhalb jedes Schritts.

2.3 Optimierungsphase

In „qteasy/optimization.py“ führen mehrere Parametersätze Backtests parallel über Multiprocessing durch (z. B. „ProcessPoolExecutor“); Innerhalb jedes Satzes werden Pfade wie „backtest_flash_steps“ verwendet, wobei nur die endgültigen Gelder/Positionen beibehalten werden, um die Speichernutzung zu reduzieren und den Durchsatz zu erhöhen.

8.3. 3. 与 VectorBT 的架构差异

Dimension

qteasy

VectorBT

Zeitdimension

Sequentielle Schritte (For-Loop-Schritte), vektorisiert innerhalb jedes Schritts

Einmalige Matrixoperationen über die gesamte Zeitachse, ohne explizite Zeitschleife

Asset-Dimension

Führen Sie bei jedem Schritt Array-Operationen für alle Assets durch (1D-Arrays).

Das Instrument und die Zeit nehmen gemeinsam an der Ausstrahlung teil; Mehrere Strategien/mehrere Parametersätze können auf einmal übertragen werden.

Kernbeschleunigung

„backtest_step“, „backtest_batch_steps“, „backtest_flash_steps“ usw. sind „@njit“; Signalanalyse, Abwicklungs-/Lieferwarteschlange usw. verwenden ebenfalls Numba.

NumPy + Numba, mit Strategien, die als reine Array-Operationen ausgedrückt werden

Zustände und Einschränkungen

Verwaltet explizit Bargeld, Positionen und eine Abwicklungs-/Lieferwarteschlange (T+1 usw.); Der Status hängt vom nächsten Trade ab, daher muss die Zeitdimension sequentiell sein.

Größtenteils eine vereinfachte Eigenkapitalkurve ohne Betonung von T+1/Abwicklung/MOQ, was die Erstellung einer vollständigen Matrix erleichtert.

Schlussfolgerung: qteasy weist keine „mangelnde Vektorisierung/Numba“ auf; Vielmehr wurde unter der Prämisse, die Zustandskorrektheit sicherzustellen (T+1, Abrechnung, MOQ, Multi-Strategie-Zusammenführung usw.), ein Kompromiss aus „zeitlich geordneter + instrumentendimensionierter Vektorisierung + Numba pro Schritt“ gewählt; it und VectorBTs „Full-Matrix-Broadcasting“ haben jeweils ihre eigenen anwendbaren Szenarien (qteasy tendiert zu strengen Regeln und Konsistenz beim Live-Handel, während VectorBT zu schnellem Screening über umfangreiche Parameterraster tendiert).

8.4. 4. 相关文档

  • Einheitlicher Einstiegspunkt und einheitliche Modi: [Backtesting, Live-Handel und Optimierung] (06-backtest-live-optimization.md).

  • Benutzerseitige Erklärung: [Backtest und Bewertung von Handelsstrategien – Backtest-Engine und Leistung] (…/back_testing/6.%20backtest_engine_and_performance.md).

  • Designabsicht und Datenisolierung: [Designbegründung und einzigartige Vorteile] (08-design-rationale-and-advantages.md).