Chuyển đến nội dung
Tất cả tài liệu trong thư viện

So sánh Backtrader và Zipline trên các chiến lược giao dịch được hỗ trợ

Mã Machine Learning for Trading

Tóm tắt

Sổ tay này báo cáo các so sánh mức độ tương đương giữa Backtrader, Zipline Reloaded và một khung giao dịch nội bộ trên các chiến lược nghiên cứu tình huống thực tế được chọn. Nội dung gồm các so sánh danh mục cổ phiếu ETF và US cho cả hai công cụ bên ngoài, cùng các so sánh hợp đồng tương lai CME và USD FX định giá bằng USD cho Backtrader. Cuộc kiểm tra đối chiếu giá và khối lượng khớp lệnh, dấu thời gian định giá và giá trị tài khoản với độ chính xác đến từng xu. Các mô hình tài sản không được hỗ trợ được liệt kê riêng, không tính là so sánh thành công; trong cuộc kiểm tra này, không công cụ nào được xem là hỗ trợ sẵn cơ chế funding của hợp đồng tương lai vĩnh cửu tiền mã hóa.

Sổ tay cũng báo cáo thời gian chạy riêng của bộ máy cho các so sánh đạt yêu cầu và trình bày các thử nghiệm căng thẳng tổng hợp với cấu hình khung tương ứng. Sổ tay lưu ý rằng thời gian đo không bao gồm chuẩn bị dữ liệu và bộ chuyển đổi, nên không nên khái quát sang chiến lược hoặc máy khác. Kết quả thử nghiệm căng thẳng tổng hợp là bằng chứng thứ cấp về quy mô khối lượng công việc và quy ước sự kiện; giá trị cuối kỳ khác nhau vì mỗi cấu hình tuân theo quy ước riêng của khung. Các bản ghi đạt yêu cầu được nêu chỉ mô tả những tổ hợp đã kiểm tra trong cuộc kiểm toán này, không xác lập tính tương đương cho các công cụ, tính năng bộ máy hoặc giả định khớp lệnh khác.

Ý chính

  • Cuộc kiểm toán so sánh khớp lệnh, định giá, dấu thời gian và giá trị tài khoản của các cặp chiến lược-bộ máy được hỗ trợ.
  • Backtrader được kiểm tra trên quỹ ETF, cổ phiếu US, hợp đồng tương lai CME và FX định giá bằng USD; Zipline được kiểm tra trên quỹ ETF và cổ phiếu US.
  • Mô hình tài sản không được hỗ trợ bị loại khỏi mẫu số tỷ lệ đạt yêu cầu, thay vì được xem là có hỗ trợ.
  • Thời gian chạy chỉ đo lệnh gọi bộ máy và có thể không áp dụng cho máy hoặc chiến lược khác.
  • Thử nghiệm căng thẳng tổng hợp đánh giá quy mô và quy ước sự kiện, còn các dòng dữ liệu thực cung cấp những so sánh cần thiết.

Thẻ

Toàn văn
# 17_backtrader_zipline_engine_parity.py


```py
# ---
# jupyter:
#   jupytext:
#     cell_metadata_filter: tags,-all
#     text_representation:
#       extension: .py
#       format_name: percent
#       format_version: '1.3'
#       jupytext_version: 1.19.3
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# %% [markdown]
# # Backtrader and Zipline on Current Case-Study Strategies
#
# This notebook reports the Backtrader and Zipline Reloaded rows from the current real-strategy
# audit. It does not infer asset support from ML4T's configurability: a pair is included only when
# the external engine and frozen bundle can express the same native contract.
#
# **Learning objectives**
#
# - Compare Backtrader and Zipline against ML4T on supported real strategies
# - Apply a monetary comparison unit to account values without weakening fill comparison
# - Interpret the measured engine-only runtime boundary
# - Use synthetic stress evidence as a secondary conformance result
#
# **Book reference**: Chapter 16, Section 16.3

# %% [markdown]
# ## Setup

# %%
"""Current Backtrader and Zipline parity evidence."""

import json

import polars as pl
from IPython.display import display

from utils.paths import get_chapter_dir

# %% tags=["parameters"]
# Production defaults - Papermill injects overrides after this cell
ROUND_SECONDS = 3

# %%
AUDIT_PATH = get_chapter_dir(16) / "resources" / "framework_parity_audit.json"
audit = json.loads(AUDIT_PATH.read_text(encoding="utf-8"))
FRAMEWORKS = ["backtrader", "zipline"]
FRAMEWORK_NAMES = {
    key: f"{audit['frameworks'][key]['display_name']} {audit['frameworks'][key]['version']}"
    for key in FRAMEWORKS
}
CASE_NAMES = {
    "etfs": "ETF allocation",
    "cme_futures": "CME futures",
    "crypto_perps_funding": "Crypto perpetual funding",
    "fx_pairs": "FX allocation (USD-quoted pairs)",
    "us_equities_panel": "US equity panel",
}

# %% [markdown]
# ## 1. Required comparisons

# %% tags=["results"]
results = (
    pl.DataFrame(audit["real_strategy_records"])
    .filter(pl.col("framework").is_in(FRAMEWORKS))
    .with_columns(
        pl.col("case_study").replace_strict(CASE_NAMES).alias("strategy"),
        pl.col("framework").replace_strict(FRAMEWORK_NAMES).alias("engine"),
    )
    .select(
        "strategy",
        "engine",
        "status",
        "fills",
        "valuations",
        "valuation_timestamps_match",
        "equity_gap",
        "equity_raw_gap",
        "terminal_gap",
        "terminal_raw_gap",
    )
    .sort("strategy", "engine")
)

assert results.height == 6
assert results.filter(pl.col("status") == "pass").height == 6
assert results["valuation_timestamps_match"].all()

display(results)

# %% [markdown]
# Backtrader and Zipline both participate in the ETF and US equity-panel comparisons. Backtrader
# also participates in the CME and USD-quoted foreign-exchange comparisons. The fill stream is
# compared at eight-decimal price precision and five-decimal quantity precision, while account
# values must round to the same cent. Zipline has no required CME or spot-FX row because the frozen
# inputs do not map to its native asset models.

# %% [markdown]
# ## 2. Unsupported asset models

# %% tags=["results"]
unsupported = (
    pl.DataFrame(audit["unsupported_records"])
    .filter(pl.col("framework").is_in(FRAMEWORKS))
    .with_columns(
        pl.col("case_study").replace_strict(CASE_NAMES).alias("strategy"),
        pl.col("framework").replace_strict(FRAMEWORK_NAMES).alias("engine"),
    )
    .select("strategy", "engine", "reason")
    .sort("strategy", "engine")
)
display(unsupported)

# %% [markdown]
# Neither engine is credited with crypto-perpetual funding support it does not natively provide.
# Unsupported rows are excluded from the pass denominator.

# %% [markdown]
# ## 3. Engine-only timing
#
# Timing is retained only for correctness-passing rows and covers the engine call only.

# %% tags=["results"]
timing = (
    pl.DataFrame(audit["performance_records"])
    .filter(pl.col("framework").is_in(FRAMEWORKS))
    .with_columns(
        pl.col("case_study").replace_strict(CASE_NAMES).alias("strategy"),
        pl.col("framework").replace_strict(FRAMEWORK_NAMES).alias("engine"),
        pl.col("framework_median_seconds").round(ROUND_SECONDS).alias("external_seconds"),
        pl.col("ml4t_median_seconds").round(ROUND_SECONDS).alias("ml4t_seconds"),
        pl.col("framework_to_ml4t_ratio").round(2).alias("external_div_ml4t"),
    )
    .select("strategy", "engine", "external_seconds", "ml4t_seconds", "external_div_ml4t")
)

assert timing.height == 6
display(timing)

# %% [markdown]
# The timer excludes data and adapter preparation. The ratios should not be applied to other
# strategies or machines.

# %% [markdown]
# ## 4. Synthetic stress evidence

# %% tags=["results"]
stress = (
    pl.DataFrame(audit["synthetic_stress"]["records"])
    .filter(pl.col("framework").is_in(FRAMEWORKS))
    .with_columns(pl.col("framework").replace_strict(FRAMEWORK_NAMES).alias("engine"))
    .select("engine", "intents", "fills", "trades", "terminal_value", "status")
)
display(stress)

# %% [markdown]
# Both synthetic stress rows pass against their matching ML4T profiles. Their terminal values differ
# because the profiles reproduce different framework conventions. The test is pairwise: ML4T versus
# Backtrader and ML4T versus Zipline. The workload tests scale and event conventions, while the
# required rows above determine the real-data comparison.

```

Hiển thị toàn văn kèm ghi nguồn theo giấy phép của tài liệu gốc. Giấy phép: MIT

Bản tóm tắt này do tác nhân nghiên cứu của Stratmill biên soạn từ tài liệu gốc; đây không phải bản sao của tài liệu.