1
0

新增backtesting框架用于回测

This commit is contained in:
2025-02-18 17:00:41 +08:00
parent 5489a0bb4b
commit b8f97f7203
4 changed files with 545 additions and 68 deletions

142
poetry.lock generated
View File

@@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 2.0.1 and should not be changed by hand. # This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand.
[[package]] [[package]]
name = "akracer" name = "akracer"
@@ -65,7 +65,7 @@ typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""}
[package.extras] [package.extras]
doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"]
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1) ; python_version >= \"3.10\"", "uvloop (>=0.21) ; platform_python_implementation == \"CPython\" and platform_system != \"Windows\" and python_version < \"3.14\""]
trio = ["trio (>=0.26.1)"] trio = ["trio (>=0.26.1)"]
[[package]] [[package]]
@@ -201,12 +201,12 @@ files = [
] ]
[package.extras] [package.extras]
benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] benchmark = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"]
cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"]
dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"]
docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"]
tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\""]
[[package]] [[package]]
name = "babel" name = "babel"
@@ -221,7 +221,30 @@ files = [
] ]
[package.extras] [package.extras]
dev = ["backports.zoneinfo", "freezegun (>=1.0,<2.0)", "jinja2 (>=3.0)", "pytest (>=6.0)", "pytest-cov", "pytz", "setuptools", "tzdata"] dev = ["backports.zoneinfo ; python_version < \"3.9\"", "freezegun (>=1.0,<2.0)", "jinja2 (>=3.0)", "pytest (>=6.0)", "pytest-cov", "pytz", "setuptools", "tzdata ; sys_platform == \"win32\""]
[[package]]
name = "backtesting"
version = "0.6.1"
description = "Backtest trading strategies in Python"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "backtesting-0.6.1-py3-none-any.whl", hash = "sha256:7d02df9610b1d0f7bfe53e2dab9453de71741ba323348dc7e2f77f0594bb8fa3"},
{file = "backtesting-0.6.1.tar.gz", hash = "sha256:570b3d395a6c7c58a4ad3534b6b3ba69e35845f25e1e7c6f73944abd5bb554a9"},
]
[package.dependencies]
bokeh = ">=1.4.0,<3.0.dev0 || >=3.1.dev0"
joblib = "*"
numpy = ">=1.17.0"
pandas = ">0.25.0"
[package.extras]
dev = ["coverage", "flake8", "mypy"]
doc = ["ipykernel", "jupyter-client", "jupytext (>=1.3)", "nbconvert", "pdoc3"]
test = ["matplotlib", "sambo", "scikit-learn"]
[[package]] [[package]]
name = "backtrader" name = "backtrader"
@@ -279,6 +302,29 @@ webencodings = "*"
[package.extras] [package.extras]
css = ["tinycss2 (>=1.1.0,<1.5)"] css = ["tinycss2 (>=1.1.0,<1.5)"]
[[package]]
name = "bokeh"
version = "3.6.3"
description = "Interactive plots and applications in the browser from Python"
optional = false
python-versions = ">=3.10"
groups = ["main"]
files = [
{file = "bokeh-3.6.3-py3-none-any.whl", hash = "sha256:1c219e2afe1405e6ada212071ac3bee91c95acfd1aa6d620eb6f61a751407747"},
{file = "bokeh-3.6.3.tar.gz", hash = "sha256:9b81d6a9ea62e75a04a1a9d9f931942016890beec9ab5d129a2a4432cf595c0a"},
]
[package.dependencies]
contourpy = ">=1.2"
Jinja2 = ">=2.9"
numpy = ">=1.16"
packaging = ">=16.8"
pandas = ">=1.2"
pillow = ">=7.1.0"
PyYAML = ">=3.10"
tornado = ">=6.2"
xyzservices = ">=2021.09.1"
[[package]] [[package]]
name = "bs4" name = "bs4"
version = "0.0.2" version = "0.0.2"
@@ -717,7 +763,7 @@ files = [
] ]
[package.extras] [package.extras]
tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich ; python_version >= \"3.11\""]
[[package]] [[package]]
name = "fastjsonschema" name = "fastjsonschema"
@@ -795,18 +841,18 @@ files = [
] ]
[package.extras] [package.extras]
all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\"", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0) ; python_version <= \"3.12\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"]
graphite = ["lz4 (>=1.7.4.2)"] graphite = ["lz4 (>=1.7.4.2)"]
interpolatable = ["munkres", "pycairo", "scipy"] interpolatable = ["munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\""]
lxml = ["lxml (>=4.0)"] lxml = ["lxml (>=4.0)"]
pathops = ["skia-pathops (>=0.5.0)"] pathops = ["skia-pathops (>=0.5.0)"]
plot = ["matplotlib"] plot = ["matplotlib"]
repacker = ["uharfbuzz (>=0.23.0)"] repacker = ["uharfbuzz (>=0.23.0)"]
symfont = ["sympy"] symfont = ["sympy"]
type1 = ["xattr"] type1 = ["xattr ; sys_platform == \"darwin\""]
ufo = ["fs (>=2.2.0,<3)"] ufo = ["fs (>=2.2.0,<3)"]
unicode = ["unicodedata2 (>=15.1.0)"] unicode = ["unicodedata2 (>=15.1.0) ; python_version <= \"3.12\""]
woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] woff = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "zopfli (>=0.1.4)"]
[[package]] [[package]]
name = "fqdn" name = "fqdn"
@@ -834,14 +880,14 @@ files = [
[[package]] [[package]]
name = "holidays" name = "holidays"
version = "0.66" version = "0.67"
description = "Open World Holidays Framework" description = "Open World Holidays Framework"
optional = false optional = false
python-versions = ">=3.9" python-versions = ">=3.9"
groups = ["main"] groups = ["main"]
files = [ files = [
{file = "holidays-0.66-py3-none-any.whl", hash = "sha256:76a84de3496e21fd67eff69a9c0be07fc689b75b62945c157498748f43be31ab"}, {file = "holidays-0.67-py3-none-any.whl", hash = "sha256:174b64b9c23ef97600b32f4c44d4cf685223d75188dd746bce185fcbcdfd0522"},
{file = "holidays-0.66.tar.gz", hash = "sha256:b7d5168c86c0dfeb7f9ffdfea62514e2ced91ce46bed4513bc147b40322d1aa5"}, {file = "holidays-0.67.tar.gz", hash = "sha256:d9a21be2c01e68f28bae1544a36736566830b065f467b59bca32caefb4c4487f"},
] ]
[package.dependencies] [package.dependencies]
@@ -864,10 +910,10 @@ six = ">=1.9"
webencodings = "*" webencodings = "*"
[package.extras] [package.extras]
all = ["chardet (>=2.2)", "genshi", "lxml"] all = ["chardet (>=2.2)", "genshi", "lxml ; platform_python_implementation == \"CPython\""]
chardet = ["chardet (>=2.2)"] chardet = ["chardet (>=2.2)"]
genshi = ["genshi"] genshi = ["genshi"]
lxml = ["lxml"] lxml = ["lxml ; platform_python_implementation == \"CPython\""]
[[package]] [[package]]
name = "httpcore" name = "httpcore"
@@ -910,7 +956,7 @@ httpcore = "==1.*"
idna = "*" idna = "*"
[package.extras] [package.extras]
brotli = ["brotli", "brotlicffi"] brotli = ["brotli ; platform_python_implementation == \"CPython\"", "brotlicffi ; platform_python_implementation != \"CPython\""]
cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"]
http2 = ["h2 (>=3,<5)"] http2 = ["h2 (>=3,<5)"]
socks = ["socksio (==1.*)"] socks = ["socksio (==1.*)"]
@@ -944,7 +990,7 @@ files = [
] ]
[package.extras] [package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
cover = ["pytest-cov"] cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
enabler = ["pytest-enabler (>=2.2)"] enabler = ["pytest-enabler (>=2.2)"]
@@ -1011,7 +1057,7 @@ traitlets = ">=5.13.0"
[package.extras] [package.extras]
all = ["ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]", "ipython[test,test-extra]"] all = ["ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]", "ipython[test,test-extra]"]
black = ["black"] black = ["black"]
doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinxcontrib-jquery", "tomli", "typing_extensions"] doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinxcontrib-jquery", "tomli ; python_version < \"3.11\"", "typing_extensions"]
kernel = ["ipykernel"] kernel = ["ipykernel"]
matplotlib = ["matplotlib"] matplotlib = ["matplotlib"]
nbconvert = ["nbconvert"] nbconvert = ["nbconvert"]
@@ -1097,6 +1143,18 @@ MarkupSafe = ">=2.0"
[package.extras] [package.extras]
i18n = ["Babel (>=2.7)"] i18n = ["Babel (>=2.7)"]
[[package]]
name = "joblib"
version = "1.4.2"
description = "Lightweight pipelining with Python functions"
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6"},
{file = "joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e"},
]
[[package]] [[package]]
name = "json5" name = "json5"
version = "0.10.0" version = "0.10.0"
@@ -1221,7 +1279,7 @@ traitlets = ">=5.3"
[package.extras] [package.extras]
docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"]
test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest (<8.2.0)", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko ; sys_platform == \"win32\"", "pre-commit", "pytest (<8.2.0)", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"]
[[package]] [[package]]
name = "jupyter-console" name = "jupyter-console"
@@ -2004,7 +2062,7 @@ tornado = ">=6.2.0"
[package.extras] [package.extras]
dev = ["hatch", "pre-commit"] dev = ["hatch", "pre-commit"]
docs = ["myst-parser", "nbsphinx", "pydata-sphinx-theme", "sphinx (>=1.3.6)", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] docs = ["myst-parser", "nbsphinx", "pydata-sphinx-theme", "sphinx (>=1.3.6)", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"]
test = ["importlib-resources (>=5.0)", "ipykernel", "jupyter-server[test] (>=2.4.0,<3)", "jupyterlab-server[test] (>=2.27.1,<3)", "nbval", "pytest (>=7.0)", "pytest-console-scripts", "pytest-timeout", "pytest-tornasync", "requests"] test = ["importlib-resources (>=5.0) ; python_version < \"3.10\"", "ipykernel", "jupyter-server[test] (>=2.4.0,<3)", "jupyterlab-server[test] (>=2.27.1,<3)", "nbval", "pytest (>=7.0)", "pytest-console-scripts", "pytest-timeout", "pytest-tornasync", "requests"]
[[package]] [[package]]
name = "notebook-shim" name = "notebook-shim"
@@ -2341,7 +2399,7 @@ docs = ["furo", "olefile", "sphinx (>=8.1)", "sphinx-copybutton", "sphinx-inline
fpx = ["olefile"] fpx = ["olefile"]
mic = ["olefile"] mic = ["olefile"]
tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "trove-classifiers (>=2024.10.12)"] tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "trove-classifiers (>=2024.10.12)"]
typing = ["typing-extensions"] typing = ["typing-extensions ; python_version < \"3.10\""]
xmp = ["defusedxml"] xmp = ["defusedxml"]
[[package]] [[package]]
@@ -2557,7 +2615,7 @@ files = [
] ]
[package.extras] [package.extras]
dev = ["backports.zoneinfo", "black", "build", "freezegun", "mdx_truly_sane_lists", "mike", "mkdocs", "mkdocs-awesome-pages-plugin", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-material (>=8.5)", "mkdocstrings[python]", "msgspec", "msgspec-python313-pre", "mypy", "orjson", "pylint", "pytest", "tzdata", "validate-pyproject[all]"] dev = ["backports.zoneinfo ; python_version < \"3.9\"", "black", "build", "freezegun", "mdx_truly_sane_lists", "mike", "mkdocs", "mkdocs-awesome-pages-plugin", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-material (>=8.5)", "mkdocstrings[python]", "msgspec ; implementation_name != \"pypy\" and python_version < \"3.13\"", "msgspec-python313-pre ; implementation_name != \"pypy\" and python_version == \"3.13\"", "mypy", "orjson ; implementation_name != \"pypy\"", "pylint", "pytest", "tzdata", "validate-pyproject[all]"]
[[package]] [[package]]
name = "pytz" name = "pytz"
@@ -3044,7 +3102,7 @@ numpy = ">=1.23.5,<2.5"
[package.extras] [package.extras]
dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"] dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"]
doc = ["intersphinx_registry", "jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.16.5)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0,<8.0.0)", "sphinx-copybutton", "sphinx-design (>=0.4.0)"] doc = ["intersphinx_registry", "jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.16.5)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0,<8.0.0)", "sphinx-copybutton", "sphinx-design (>=0.4.0)"]
test = ["Cython", "array-api-strict (>=2.0,<2.1.1)", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] test = ["Cython", "array-api-strict (>=2.0,<2.1.1)", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja ; sys_platform != \"emscripten\"", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"]
[[package]] [[package]]
name = "send2trash" name = "send2trash"
@@ -3059,9 +3117,9 @@ files = [
] ]
[package.extras] [package.extras]
nativelib = ["pyobjc-framework-Cocoa", "pywin32"] nativelib = ["pyobjc-framework-Cocoa ; sys_platform == \"darwin\"", "pywin32 ; sys_platform == \"win32\""]
objc = ["pyobjc-framework-Cocoa"] objc = ["pyobjc-framework-Cocoa ; sys_platform == \"darwin\""]
win32 = ["pywin32"] win32 = ["pywin32 ; sys_platform == \"win32\""]
[[package]] [[package]]
name = "setuptools" name = "setuptools"
@@ -3076,13 +3134,13 @@ files = [
] ]
[package.extras] [package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.0)"] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""]
core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"]
cover = ["pytest-cov"] cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
enabler = ["pytest-enabler (>=2.2)"] enabler = ["pytest-enabler (>=2.2)"]
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.14.*)", "pytest-mypy"] type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"]
[[package]] [[package]]
name = "simplejson" name = "simplejson"
@@ -3479,7 +3537,7 @@ files = [
] ]
[package.extras] [package.extras]
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""]
h2 = ["h2 (>=4,<5)"] h2 = ["h2 (>=4,<5)"]
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
zstd = ["zstandard (>=0.18.0)"] zstd = ["zstandard (>=0.18.0)"]
@@ -3566,7 +3624,19 @@ build = ["twine", "wheel"]
docs = ["sphinx"] docs = ["sphinx"]
test = ["pytest", "pytest-cov"] test = ["pytest", "pytest-cov"]
[[package]]
name = "xyzservices"
version = "2025.1.0"
description = "Source of XYZ tiles providers"
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "xyzservices-2025.1.0-py3-none-any.whl", hash = "sha256:fa599956c5ab32dad1689960b3bb08fdcdbe0252cc82d84fc60ae415dc648907"},
{file = "xyzservices-2025.1.0.tar.gz", hash = "sha256:5cdbb0907c20be1be066c6e2dc69c645842d1113a4e83e642065604a21f254ba"},
]
[metadata] [metadata]
lock-version = "2.1" lock-version = "2.1"
python-versions = "^3.12" python-versions = "^3.12"
content-hash = "29e798d42060fe4b0385b221e0c9c01976745e79ca6cc12b3e626d67d2607439" content-hash = "3268a51bcec35b4013551a12a8e976347c6fbec2cba3ae5f429c6bac7f8d2d04"

View File

@@ -16,6 +16,7 @@ prophet = "^1.1.6"
mplfinance = "^0.12.10b0" mplfinance = "^0.12.10b0"
scipy = "^1.15.1" scipy = "^1.15.1"
backtrader = "^1.9.78.123" backtrader = "^1.9.78.123"
backtesting = "^0.6.1"
[build-system] [build-system]

420
回测/backtesting.ipynb Normal file

File diff suppressed because one or more lines are too long

View File

@@ -3,8 +3,8 @@
{ {
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2025-02-17T14:33:50.205817Z", "end_time": "2025-02-18T02:25:15.671867Z",
"start_time": "2025-02-17T14:33:50.160964Z" "start_time": "2025-02-18T02:25:15.090164Z"
} }
}, },
"cell_type": "code", "cell_type": "code",
@@ -12,10 +12,10 @@
"import backtrader as bt\n", "import backtrader as bt\n",
"import pandas as pd\n", "import pandas as pd\n",
"\n", "\n",
"source_df = \\\n", "# source_df = \\\n",
"pd.read_csv(\"C:\\\\Users\\\\lanyuanxiaoyao\\\\SynologyDrive\\\\data\\\\Tushare\\\\日线行情 1990-2024\\\\分组行情\\\\000001.SZ.csv\") \\\n", "# pd.read_csv(\"C:\\\\Users\\\\lanyuanxiaoyao\\\\SynologyDrive\\\\data\\\\Tushare\\\\日线行情 1990-2024\\\\分组行情\\\\000001.SZ.csv\") \\\n",
"source_df = pd.read_csv(\"/Users/lanyuanxiaoyao/SynologyDrive/data/Tushare/日线行情 1990-2024/分组行情/000001.SZ.csv\") \\\n",
" [[\"trade_date\", \"vol\", \"open_qfq\", \"close_qfq\", \"high_qfq\", \"low_qfq\"]]\n", " [[\"trade_date\", \"vol\", \"open_qfq\", \"close_qfq\", \"high_qfq\", \"low_qfq\"]]\n",
"# source_df = pd.read_csv(\"/Users/lanyuanxiaoyao/SynologyDrive/data/Tushare/日线行情 1990-2024/分组行情/000001.SZ.csv\") \\\n",
"df = pd.DataFrame()\n", "df = pd.DataFrame()\n",
"df[[\"date\", \"volume\", \"open\", \"close\", \"high\", \"low\"]] = \\\n", "df[[\"date\", \"volume\", \"open\", \"close\", \"high\", \"low\"]] = \\\n",
" source_df[[\"trade_date\", \"vol\", \"open_qfq\", \"close_qfq\", \"high_qfq\", \"low_qfq\"]]\n", " source_df[[\"trade_date\", \"vol\", \"open_qfq\", \"close_qfq\", \"high_qfq\", \"low_qfq\"]]\n",
@@ -216,18 +216,18 @@
"</div>" "</div>"
] ]
}, },
"execution_count": 42, "execution_count": 2,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
], ],
"execution_count": 42 "execution_count": 2
}, },
{ {
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2025-02-17T14:33:50.231103Z", "end_time": "2025-02-18T02:29:43.443218Z",
"start_time": "2025-02-17T14:33:50.225919Z" "start_time": "2025-02-18T02:29:43.436601Z"
} }
}, },
"cell_type": "code", "cell_type": "code",
@@ -260,17 +260,17 @@
" print('夏普比率:', strat.analyzers.sharpe_ratio.get_analysis()['sharperatio'])\n", " print('夏普比率:', strat.analyzers.sharpe_ratio.get_analysis()['sharperatio'])\n",
" print('最大回撤:', strat.analyzers.draw_down.get_analysis()['max']['drawdown'])\n", " print('最大回撤:', strat.analyzers.draw_down.get_analysis()['max']['drawdown'])\n",
" # 绘制结果图表\n", " # 绘制结果图表\n",
" return cerebro.plot(style='candlestick', width=20, height=10)" " return cerebro.plot(style='candlestick')"
], ],
"id": "d25f6e4d51cdfb20", "id": "d25f6e4d51cdfb20",
"outputs": [], "outputs": [],
"execution_count": 43 "execution_count": 5
}, },
{ {
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2025-02-17T14:33:50.274745Z", "end_time": "2025-02-18T02:25:16.582436Z",
"start_time": "2025-02-17T14:33:50.269232Z" "start_time": "2025-02-18T02:25:15.803336Z"
} }
}, },
"cell_type": "code", "cell_type": "code",
@@ -291,21 +291,7 @@
"df['hist'] = hist\n", "df['hist'] = hist\n",
"df['hist'] = df['hist'].fillna(0)\n", "df['hist'] = df['hist'].fillna(0)\n",
"\n", "\n",
"# df" "\n",
],
"id": "5774f2437186c503",
"outputs": [],
"execution_count": 44
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-02-17T14:33:50.412752Z",
"start_time": "2025-02-17T14:33:50.327691Z"
}
},
"cell_type": "code",
"source": [
"class EnhancePandasData(bt.feeds.PandasData):\n", "class EnhancePandasData(bt.feeds.PandasData):\n",
" lines = (\"dif\", \"dea\", \"hist\")\n", " lines = (\"dif\", \"dea\", \"hist\")\n",
" params = (\n", " params = (\n",
@@ -343,7 +329,7 @@
"\n", "\n",
"run_backtrader(EnhancePandasData(dataname=df), MACDStrategy)" "run_backtrader(EnhancePandasData(dataname=df), MACDStrategy)"
], ],
"id": "45f8133af2348b95", "id": "5774f2437186c503",
"outputs": [ "outputs": [
{ {
"name": "stdout", "name": "stdout",
@@ -373,7 +359,7 @@
"<IPython.core.display.HTML object>" "<IPython.core.display.HTML object>"
], ],
"text/html": [ "text/html": [
"<div id='75a19a97-0e96-4034-a26a-d8ac2a51d841'></div>" "<div id='ba76dac9-3ef2-4dbb-a2b4-b75774d0b531'></div>"
] ]
}, },
"metadata": {}, "metadata": {},
@@ -385,12 +371,12 @@
"[[<Figure size 640x480 with 4 Axes>]]" "[[<Figure size 640x480 with 4 Axes>]]"
] ]
}, },
"execution_count": 45, "execution_count": 4,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
], ],
"execution_count": 45 "execution_count": 4
} }
], ],
"metadata": { "metadata": {