diff --git a/.vscode/settings.json b/.vscode/settings.json index e27585c..def288c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,6 @@ { - "python.defaultInterpreterPath": "./.venv/bin/python", + "python.defaultInterpreterPath": ".venv/bin/python", "python.testing.pytestArgs": [ - "tests" ], "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true, diff --git a/clean b/clean new file mode 100644 index 0000000..31812c6 --- /dev/null +++ b/clean @@ -0,0 +1,1355 @@ +./lib/PyTrade/pytrade/interfaces/__pycache__ +./lib/PyTrade/pytrade/interfaces/__pycache__/broker.cpython-312.pyc +./lib/PyTrade/pytrade/interfaces/__pycache__/__init__.cpython-312.pyc +./lib/PyTrade/pytrade/interfaces/__pycache__/data.cpython-312.pyc +./lib/PyTrade/pytrade/interfaces/__pycache__/client.cpython-312.pyc +./lib/PyTrade/pytrade/__pycache__ +./lib/PyTrade/pytrade/__pycache__/broker.cpython-312.pyc +./lib/PyTrade/pytrade/__pycache__/__init__.cpython-312.pyc +./lib/PyTrade/pytrade/__pycache__/indicator.cpython-312.pyc +./lib/PyTrade/pytrade/__pycache__/data.cpython-312.pyc +./lib/PyTrade/pytrade/__pycache__/strategy.cpython-312.pyc +./lib/PyTrade/pytrade/__pycache__/models.cpython-312.pyc +./lib/PyTrade/pytrade/__pycache__/instruments.cpython-312.pyc +./lib/PyTrade/pytrade/events/__pycache__ +./lib/PyTrade/pytrade/events/__pycache__/__init__.cpython-312.pyc +./lib/PyTrade/pytrade/events/__pycache__/event.cpython-312.pyc +./lib/PyTrade/tests/unit/__pycache__ +./lib/PyTrade/tests/unit/__pycache__/test_broker.cpython-312.pyc +./lib/PyTrade/tests/unit/__pycache__/__init__.cpython-312.pyc +./lib/PyTrade/tests/unit/__pycache__/test_models.cpython-312-pytest-8.3.4.pyc +./lib/PyTrade/tests/unit/__pycache__/test_instrument_history.cpython-312-pytest-8.3.4.pyc +./lib/PyTrade/tests/unit/__pycache__/test_strategy.cpython-312-pytest-8.3.4.pyc +./lib/PyTrade/tests/unit/__pycache__/test_broker.cpython-312-pytest-8.3.4.pyc +./lib/PyTrade/tests/unit/__pycache__/test_indicator.cpython-312.pyc +./lib/PyTrade/tests/unit/__pycache__/test_instrument_history.cpython-312.pyc +./lib/PyTrade/tests/unit/__pycache__/test_models.cpython-312.pyc +./lib/PyTrade/tests/unit/__pycache__/test_strategy.cpython-312.pyc +./lib/PyTrade/tests/unit/__pycache__/test_indicator.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/flake8/plugins/__pycache__ +./.venv/lib/python3.12/site-packages/flake8/plugins/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/plugins/__pycache__/finder.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/plugins/__pycache__/pyflakes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/plugins/__pycache__/reporter.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/plugins/__pycache__/pycodestyle.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/options/__pycache__ +./.venv/lib/python3.12/site-packages/flake8/options/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/options/__pycache__/manager.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/options/__pycache__/config.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/options/__pycache__/aggregator.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/options/__pycache__/parse_args.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/main/__pycache__ +./.venv/lib/python3.12/site-packages/flake8/main/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/main/__pycache__/cli.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/main/__pycache__/debug.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/main/__pycache__/application.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/main/__pycache__/options.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/__pycache__ +./.venv/lib/python3.12/site-packages/flake8/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/__pycache__/_compat.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/__pycache__/violation.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/__pycache__/checker.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/__pycache__/defaults.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/__pycache__/discover_files.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/__pycache__/style_guide.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/__pycache__/utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/__pycache__/statistics.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/__pycache__/processor.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/__pycache__/exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/formatting/__pycache__ +./.venv/lib/python3.12/site-packages/flake8/formatting/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/formatting/__pycache__/_windows_color.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/formatting/__pycache__/default.cpython-312.pyc +./.venv/lib/python3.12/site-packages/flake8/formatting/__pycache__/base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__ +./.venv/lib/python3.12/site-packages/rich/__pycache__/region.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/_null_file.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/terminal_theme.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/_export_format.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/_emoji_codes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/color_triplet.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/_emoji_replace.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/cells.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/_ratio.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/_log_render.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/_palettes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/pager.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/padding.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/constrain.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/panel.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/theme.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/protocol.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/themes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/screen.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/control.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/spinner.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/live.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/_extension.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/console.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/text.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/measure.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/errors.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/_pick.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/palette.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/table.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/ansi.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/filesize.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/color.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/box.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/file_proxy.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/progress.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/_wrap.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/progress_bar.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/emoji.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/repr.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/live_render.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/segment.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/scope.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/_cell_widths.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/_spinners.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/containers.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/_loop.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/align.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/highlighter.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/default_styles.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/markup.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/jupyter.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/abc.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/pretty.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/_fileno.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/styled.cpython-312.pyc +./.venv/lib/python3.12/site-packages/rich/__pycache__/style.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pytz/__pycache__ +./.venv/lib/python3.12/site-packages/pytz/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pytz/__pycache__/tzinfo.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pytz/__pycache__/tzfile.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pytz/__pycache__/lazy.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pytz/__pycache__/exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__ +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/tester.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/constants.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/node_visitor.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/blacklisting.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/manager.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/config.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/context.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/issue.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/meta_ast.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/metrics.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/extension_loader.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/test_properties.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/test_set.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/core/__pycache__/docs_utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__ +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/injection_paramiko.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/django_xss.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/try_except_continue.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/general_hardcoded_tmp.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/ssh_no_host_key_verification.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/mako_templates.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/injection_wildcard.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/general_hardcoded_password.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/request_without_timeout.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/try_except_pass.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/general_bind_all_interfaces.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/snmp_security_check.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/crypto_request_no_cert_validation.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/pytorch_load_save.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/exec.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/weak_cryptographic_key.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/tarfile_unsafe_members.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/trojansource.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/django_sql_injection.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/injection_shell.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/general_bad_file_permissions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/injection_sql.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/logging_config_insecure_listen.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/yaml_load.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/jinja2_templates.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/asserts.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/insecure_ssl_tls.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/hashlib_insecure_functions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/plugins/__pycache__/app_debug.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/cli/__pycache__ +./.venv/lib/python3.12/site-packages/bandit/cli/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/cli/__pycache__/main.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/blacklists/__pycache__ +./.venv/lib/python3.12/site-packages/bandit/blacklists/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/blacklists/__pycache__/calls.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/blacklists/__pycache__/utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/blacklists/__pycache__/imports.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/formatters/__pycache__ +./.venv/lib/python3.12/site-packages/bandit/formatters/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/formatters/__pycache__/screen.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/formatters/__pycache__/custom.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/formatters/__pycache__/text.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/formatters/__pycache__/sarif.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/formatters/__pycache__/xml.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/formatters/__pycache__/json.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/formatters/__pycache__/utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/formatters/__pycache__/html.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/formatters/__pycache__/yaml.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/formatters/__pycache__/csv.cpython-312.pyc +./.venv/lib/python3.12/site-packages/bandit/__pycache__ +./.venv/lib/python3.12/site-packages/bandit/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__ +./.venv/lib/python3.12/site-packages/isort/__pycache__/format.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/output.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/literal.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/io.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/place.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/files.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/comments.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/settings.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/profiles.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/core.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/main.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/wrap_modes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/sorting.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/_version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/api.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/logo.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/wrap.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/identify.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/sections.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/__pycache__/parse.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/stdlibs/__pycache__ +./.venv/lib/python3.12/site-packages/isort/stdlibs/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/stdlibs/__pycache__/py3.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/stdlibs/__pycache__/py310.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/stdlibs/__pycache__/py312.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/stdlibs/__pycache__/py38.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/stdlibs/__pycache__/py311.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/stdlibs/__pycache__/py37.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/stdlibs/__pycache__/py39.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/stdlibs/__pycache__/py27.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/stdlibs/__pycache__/py2.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/stdlibs/__pycache__/all.cpython-312.pyc +./.venv/lib/python3.12/site-packages/isort/stdlibs/__pycache__/py36.cpython-312.pyc +./.venv/lib/python3.12/site-packages/black/__pycache__ +./.venv/lib/python3.12/site-packages/black/__pycache__/output.cpython-312.pyc +./.venv/lib/python3.12/site-packages/black/__pycache__/concurrency.cpython-312.pyc +./.venv/lib/python3.12/site-packages/black/__pycache__/files.cpython-312.pyc +./.venv/lib/python3.12/site-packages/black/__pycache__/report.cpython-312.pyc +./.venv/lib/python3.12/site-packages/stevedore/__pycache__ +./.venv/lib/python3.12/site-packages/stevedore/__pycache__/exception.cpython-312.pyc +./.venv/lib/python3.12/site-packages/stevedore/__pycache__/named.cpython-312.pyc +./.venv/lib/python3.12/site-packages/stevedore/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/stevedore/__pycache__/enabled.cpython-312.pyc +./.venv/lib/python3.12/site-packages/stevedore/__pycache__/driver.cpython-312.pyc +./.venv/lib/python3.12/site-packages/stevedore/__pycache__/extension.cpython-312.pyc +./.venv/lib/python3.12/site-packages/stevedore/__pycache__/hook.cpython-312.pyc +./.venv/lib/python3.12/site-packages/stevedore/__pycache__/_cache.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pytest/__pycache__ +./.venv/lib/python3.12/site-packages/pytest/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pytest/__pycache__/__main__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/platformdirs/__pycache__ +./.venv/lib/python3.12/site-packages/platformdirs/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/platformdirs/__pycache__/version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/platformdirs/__pycache__/unix.cpython-312.pyc +./.venv/lib/python3.12/site-packages/platformdirs/__pycache__/api.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/config/__pycache__ +./.venv/lib/python3.12/site-packages/_pytest/config/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/config/__pycache__/findpaths.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/config/__pycache__/compat.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/config/__pycache__/argparsing.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/config/__pycache__/exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/_io/__pycache__ +./.venv/lib/python3.12/site-packages/_pytest/_io/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/_io/__pycache__/wcwidth.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/_io/__pycache__/pprint.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/_io/__pycache__/terminalwriter.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/_io/__pycache__/saferepr.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/_code/__pycache__ +./.venv/lib/python3.12/site-packages/_pytest/_code/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/_code/__pycache__/source.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/_code/__pycache__/code.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/mark/__pycache__ +./.venv/lib/python3.12/site-packages/_pytest/mark/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/mark/__pycache__/structures.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/mark/__pycache__/expression.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/assertion/__pycache__ +./.venv/lib/python3.12/site-packages/_pytest/assertion/__pycache__/util.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/assertion/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/assertion/__pycache__/truncate.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/assertion/__pycache__/rewrite.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__ +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/stash.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/pastebin.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/recwarn.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/logging.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/pytester.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/cacheprovider.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/skipping.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/freeze_support.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/_argcomplete.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/tmpdir.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/fixtures.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/setupplan.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/capture.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/python.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/warning_types.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/hookspec.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/nodes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/stepwise.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/reports.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/terminal.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/python_api.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/python_path.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/helpconfig.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/legacypath.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/main.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/timing.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/_version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/doctest.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/compat.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/junitxml.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/monkeypatch.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/scope.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/unraisableexception.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/unittest.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/pathlib.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/setuponly.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/outcomes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/threadexception.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/warnings.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/runner.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/faulthandler.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/debugging.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/__pycache__/deprecated.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/_py/__pycache__ +./.venv/lib/python3.12/site-packages/_pytest/_py/__pycache__/error.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/_py/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/_pytest/_py/__pycache__/path.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pyflakes/__pycache__ +./.venv/lib/python3.12/site-packages/pyflakes/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pyflakes/__pycache__/checker.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pyflakes/__pycache__/messages.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pyflakes/__pycache__/reporter.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pyflakes/__pycache__/api.cpython-312.pyc +./.venv/lib/python3.12/site-packages/packaging/__pycache__ +./.venv/lib/python3.12/site-packages/packaging/__pycache__/specifiers.cpython-312.pyc +./.venv/lib/python3.12/site-packages/packaging/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/packaging/__pycache__/_elffile.cpython-312.pyc +./.venv/lib/python3.12/site-packages/packaging/__pycache__/_manylinux.cpython-312.pyc +./.venv/lib/python3.12/site-packages/packaging/__pycache__/version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/packaging/__pycache__/_structures.cpython-312.pyc +./.venv/lib/python3.12/site-packages/packaging/__pycache__/utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/packaging/__pycache__/tags.cpython-312.pyc +./.venv/lib/python3.12/site-packages/packaging/__pycache__/_musllinux.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__ +./.venv/lib/python3.12/site-packages/coverage/__pycache__/templite.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/inorout.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/env.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/pytracer.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/numbits.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/collector.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/plugin.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/files.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/execfile.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/python.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/control.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/multiproc.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/results.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/phystokens.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/annotate.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/lcovreport.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/report.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/misc.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/jsonreport.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/core.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/report_core.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/regions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/data.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/config.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/xmlreport.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/debug.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/sqldata.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/tomlconfig.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/cmdline.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/context.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/plugin_support.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/parser.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/sysmon.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/bytecode.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/html.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/types.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/sqlitedb.cpython-312.pyc +./.venv/lib/python3.12/site-packages/coverage/__pycache__/disposition.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__ +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/_dtype_ctypes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/_add_newdocs_scalars.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/_add_newdocs.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/shape_base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/defchararray.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/_methods.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/einsumfunc.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/_machar.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/_asarray.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/umath.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/_ufunc_config.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/overrides.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/multiarray.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/memmap.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/function_base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/_string_helpers.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/_internal.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/numeric.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/records.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/_type_aliases.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/_dtype.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/arrayprint.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/_exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/fromnumeric.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/getlimits.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/core/__pycache__/numerictypes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__ +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/format.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/arraypad.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/shape_base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/_datasource.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/_iotools.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/nanfunctions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/arrayterator.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/npyio.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/index_tricks.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/histograms.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/mixins.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/_version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/function_base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/scimath.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/ufunclike.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/twodim_base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/type_check.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/stride_tricks.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/arraysetops.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/lib/__pycache__/polynomial.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/matrixlib/__pycache__ +./.venv/lib/python3.12/site-packages/numpy/matrixlib/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/matrixlib/__pycache__/defmatrix.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/_core/__pycache__ +./.venv/lib/python3.12/site-packages/numpy/_core/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/_core/__pycache__/_multiarray_umath.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/compat/__pycache__ +./.venv/lib/python3.12/site-packages/numpy/compat/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/compat/__pycache__/py3k.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/fft/__pycache__ +./.venv/lib/python3.12/site-packages/numpy/fft/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/fft/__pycache__/_pocketfft.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/fft/__pycache__/helper.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/ma/__pycache__ +./.venv/lib/python3.12/site-packages/numpy/ma/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/ma/__pycache__/extras.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/ma/__pycache__/core.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/_utils/__pycache__ +./.venv/lib/python3.12/site-packages/numpy/_utils/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/_utils/__pycache__/_inspect.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/_utils/__pycache__/_convertions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/polynomial/__pycache__ +./.venv/lib/python3.12/site-packages/numpy/polynomial/__pycache__/hermite_e.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/polynomial/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/polynomial/__pycache__/hermite.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/polynomial/__pycache__/_polybase.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/polynomial/__pycache__/polyutils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/polynomial/__pycache__/laguerre.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/polynomial/__pycache__/legendre.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/polynomial/__pycache__/chebyshev.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/polynomial/__pycache__/polynomial.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/__pycache__ +./.venv/lib/python3.12/site-packages/numpy/__pycache__/dtypes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/__pycache__/_pytesttester.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/__pycache__/_globals.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/__pycache__/ctypeslib.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/__pycache__/__config__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/__pycache__/version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/__pycache__/_distributor_init.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/__pycache__/exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/_typing/__pycache__ +./.venv/lib/python3.12/site-packages/numpy/_typing/__pycache__/_array_like.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/_typing/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/_typing/__pycache__/_shape.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/_typing/__pycache__/_dtype_like.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/_typing/__pycache__/_char_codes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/_typing/__pycache__/_scalars.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/_typing/__pycache__/_nested_sequence.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/_typing/__pycache__/_nbit.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/random/__pycache__ +./.venv/lib/python3.12/site-packages/numpy/random/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/random/__pycache__/_pickle.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/linalg/__pycache__ +./.venv/lib/python3.12/site-packages/numpy/linalg/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/numpy/linalg/__pycache__/linalg.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/link.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/scheme.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/index.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/format_control.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/candidate.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/wheel.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/target_python.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/resolution/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/resolution/__pycache__/base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/locations/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/main.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/parser.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/operations/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/operations/install/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/git.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/index/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/index/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/index/__pycache__/collector.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/index/__pycache__/sources.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_file.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_set.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/constructors.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_install.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/__pycache__/pyproject.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/__pycache__/build_env.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/__pycache__/configuration.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/__pycache__/exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/__pycache__/cache.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/auth.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/session.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/cache.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/download.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/logging.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/_log.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/misc.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/_jaraco_text.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/compat.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/models.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/urls.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/core.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/macromanprober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachinedict.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/resultdict.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/johabprober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/johabfreq.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/utf1632prober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/region.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_null_file.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/control.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/live.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/console.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/text.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/table.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/color.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/box.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/align.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_fileno.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/style.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/filters/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/styles/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/distro/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/distro/__pycache__/distro.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pkg_resources/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/certifi/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/models.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/api.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__ +./.venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/__pycache__ +./.venv/lib/python3.12/site-packages/pip/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pip/__pycache__/__main__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/iniconfig/__pycache__ +./.venv/lib/python3.12/site-packages/iniconfig/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/iniconfig/__pycache__/_parse.cpython-312.pyc +./.venv/lib/python3.12/site-packages/iniconfig/__pycache__/exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pytest_cov/__pycache__ +./.venv/lib/python3.12/site-packages/pytest_cov/__pycache__/plugin.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_cov/__pycache__/__init__.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_cov/__pycache__/compat.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_cov/__pycache__/embed.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_cov/__pycache__/plugin.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_cov/__pycache__/compat.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_cov/__pycache__/engine.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_cov/__pycache__/engine.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_cov/__pycache__/embed.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_cov/__pycache__/__init__.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/__pycache__ +./.venv/lib/python3.12/site-packages/__pycache__/typing_extensions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/__pycache__/_virtualenv.cpython-312.pyc +./.venv/lib/python3.12/site-packages/__pycache__/autoflake.cpython-312.pyc +./.venv/lib/python3.12/site-packages/__pycache__/_black_version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/__pycache__/py.cpython-312.pyc +./.venv/lib/python3.12/site-packages/__pycache__/six.cpython-312.pyc +./.venv/lib/python3.12/site-packages/__pycache__/mccabe.cpython-312.pyc +./.venv/lib/python3.12/site-packages/__pycache__/pycodestyle.cpython-312.pyc +./.venv/lib/python3.12/site-packages/__pycache__/mypy_extensions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/click/__pycache__ +./.venv/lib/python3.12/site-packages/click/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/click/__pycache__/_compat.cpython-312.pyc +./.venv/lib/python3.12/site-packages/click/__pycache__/globals.cpython-312.pyc +./.venv/lib/python3.12/site-packages/click/__pycache__/termui.cpython-312.pyc +./.venv/lib/python3.12/site-packages/click/__pycache__/core.cpython-312.pyc +./.venv/lib/python3.12/site-packages/click/__pycache__/decorators.cpython-312.pyc +./.venv/lib/python3.12/site-packages/click/__pycache__/utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/click/__pycache__/parser.cpython-312.pyc +./.venv/lib/python3.12/site-packages/click/__pycache__/exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/click/__pycache__/types.cpython-312.pyc +./.venv/lib/python3.12/site-packages/click/__pycache__/formatting.cpython-312.pyc +./.venv/lib/python3.12/site-packages/dateutil/tz/__pycache__ +./.venv/lib/python3.12/site-packages/dateutil/tz/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/dateutil/tz/__pycache__/win.cpython-312.pyc +./.venv/lib/python3.12/site-packages/dateutil/tz/__pycache__/_common.cpython-312.pyc +./.venv/lib/python3.12/site-packages/dateutil/tz/__pycache__/tz.cpython-312.pyc +./.venv/lib/python3.12/site-packages/dateutil/tz/__pycache__/_factories.cpython-312.pyc +./.venv/lib/python3.12/site-packages/dateutil/parser/__pycache__ +./.venv/lib/python3.12/site-packages/dateutil/parser/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/dateutil/parser/__pycache__/isoparser.cpython-312.pyc +./.venv/lib/python3.12/site-packages/dateutil/parser/__pycache__/_parser.cpython-312.pyc +./.venv/lib/python3.12/site-packages/dateutil/__pycache__ +./.venv/lib/python3.12/site-packages/dateutil/__pycache__/relativedelta.cpython-312.pyc +./.venv/lib/python3.12/site-packages/dateutil/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/dateutil/__pycache__/_common.cpython-312.pyc +./.venv/lib/python3.12/site-packages/dateutil/__pycache__/_version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pytest_asyncio/__pycache__ +./.venv/lib/python3.12/site-packages/pytest_asyncio/__pycache__/_version.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_asyncio/__pycache__/plugin.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_asyncio/__pycache__/__init__.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_asyncio/__pycache__/plugin.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_asyncio/__pycache__/_version.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_asyncio/__pycache__/__init__.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/blib2to3/pgen2/__pycache__ +./.venv/lib/python3.12/site-packages/blib2to3/pgen2/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/blib2to3/__pycache__ +./.venv/lib/python3.12/site-packages/blib2to3/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pathspec/__pycache__ +./.venv/lib/python3.12/site-packages/pathspec/__pycache__/_meta.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pathspec/__pycache__/util.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pathspec/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pathspec/__pycache__/pathspec.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pathspec/__pycache__/gitignore.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pathspec/__pycache__/pattern.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pathspec/patterns/__pycache__ +./.venv/lib/python3.12/site-packages/pathspec/patterns/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pathspec/patterns/__pycache__/gitwildmatch.cpython-312.pyc +./.venv/lib/python3.12/site-packages/multimethod/__pycache__ +./.venv/lib/python3.12/site-packages/multimethod/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/internals/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/internals/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/internals/__pycache__/construction.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/internals/__pycache__/array_manager.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/internals/__pycache__/base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/internals/__pycache__/ops.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/internals/__pycache__/api.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/internals/__pycache__/blocks.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/internals/__pycache__/managers.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/internals/__pycache__/concat.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/ops/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/ops/__pycache__/common.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/ops/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/ops/__pycache__/docstrings.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/ops/__pycache__/mask_ops.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/ops/__pycache__/array_ops.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/ops/__pycache__/missing.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/ops/__pycache__/invalid.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/ops/__pycache__/dispatch.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__/timedeltas.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__/base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__/range.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__/datetimelike.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__/extension.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__/category.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__/accessors.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__/interval.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__/api.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__/period.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__/datetimes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__/multi.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexes/__pycache__/frozen.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/_numba/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/_numba/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/_numba/__pycache__/executor.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/arrow/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/arrays/arrow/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/arrow/__pycache__/accessors.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/arrow/__pycache__/array.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/sparse/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/arrays/sparse/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/sparse/__pycache__/array.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/sparse/__pycache__/accessor.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/masked.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/floating.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/timedeltas.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/numpy_.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/_arrow_string_mixins.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/_ranges.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/string_.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/datetimelike.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/integer.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/_mixins.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/interval.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/numeric.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/period.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/string_arrow.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/datetimes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/_utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/boolean.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/arrays/__pycache__/categorical.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/window/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/window/__pycache__/common.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/window/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/window/__pycache__/ewm.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/window/__pycache__/expanding.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/window/__pycache__/doc.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/window/__pycache__/rolling.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/window/__pycache__/numba_.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/window/__pycache__/online.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/dtypes/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/dtypes/__pycache__/common.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/dtypes/__pycache__/dtypes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/dtypes/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/dtypes/__pycache__/generic.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/dtypes/__pycache__/base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/dtypes/__pycache__/missing.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/dtypes/__pycache__/api.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/dtypes/__pycache__/inference.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/dtypes/__pycache__/cast.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/dtypes/__pycache__/astype.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/dtypes/__pycache__/concat.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/config_init.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/common.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/construction.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/frame.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/generic.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/algorithms.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/sample.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/missing.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/shared_docs.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/series.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/flags.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/sorting.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/arraylike.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/apply.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/api.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/roperator.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/accessor.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/nanops.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/resample.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/__pycache__/indexing.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/reshape/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/reshape/__pycache__/util.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/reshape/__pycache__/merge.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/reshape/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/reshape/__pycache__/tile.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/reshape/__pycache__/encoding.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/reshape/__pycache__/melt.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/reshape/__pycache__/pivot.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/reshape/__pycache__/api.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/reshape/__pycache__/concat.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/util/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/util/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/util/__pycache__/hashing.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/util/__pycache__/numba_.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexers/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/indexers/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexers/__pycache__/utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/indexers/__pycache__/objects.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/groupby/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/groupby/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/groupby/__pycache__/grouper.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/groupby/__pycache__/generic.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/groupby/__pycache__/base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/groupby/__pycache__/ops.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/groupby/__pycache__/groupby.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/groupby/__pycache__/numba_.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/groupby/__pycache__/categorical.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/groupby/__pycache__/indexing.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/array_algos/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/array_algos/__pycache__/transforms.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/array_algos/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/array_algos/__pycache__/take.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/array_algos/__pycache__/datetimelike_accumulations.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/array_algos/__pycache__/quantile.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/array_algos/__pycache__/masked_accumulations.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/array_algos/__pycache__/putmask.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/array_algos/__pycache__/masked_reductions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/array_algos/__pycache__/replace.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/interchange/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/interchange/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/interchange/__pycache__/dataframe_protocol.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/interchange/__pycache__/from_dataframe.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/interchange/__pycache__/utils.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/methods/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/methods/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/methods/__pycache__/selectn.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/methods/__pycache__/describe.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/strings/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/strings/__pycache__/object_array.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/strings/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/strings/__pycache__/base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/strings/__pycache__/accessor.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/tools/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/tools/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/tools/__pycache__/timedeltas.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/tools/__pycache__/times.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/tools/__pycache__/numeric.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/tools/__pycache__/datetimes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/computation/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/core/computation/__pycache__/common.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/computation/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/computation/__pycache__/pytables.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/computation/__pycache__/expressions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/computation/__pycache__/parsing.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/computation/__pycache__/eval.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/computation/__pycache__/check.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/computation/__pycache__/engines.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/computation/__pycache__/scope.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/computation/__pycache__/ops.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/computation/__pycache__/api.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/computation/__pycache__/align.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/core/computation/__pycache__/expr.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/plotting/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/plotting/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/plotting/__pycache__/_core.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/plotting/__pycache__/_misc.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/errors/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/errors/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/compat/numpy/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/compat/numpy/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/compat/numpy/__pycache__/function.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/compat/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/compat/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/compat/__pycache__/compressors.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/compat/__pycache__/pickle_compat.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/compat/__pycache__/_constants.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/compat/__pycache__/_optional.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/compat/__pycache__/pyarrow.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/_testing/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/_testing/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/_testing/__pycache__/asserters.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/_testing/__pycache__/_warnings.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/_testing/__pycache__/compat.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/_testing/__pycache__/_io.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/_testing/__pycache__/contexts.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/arrays/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/arrays/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/tseries/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/tseries/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/tseries/__pycache__/offsets.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/tseries/__pycache__/api.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/tseries/__pycache__/frequencies.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/__pycache__/_version_meson.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/__pycache__/testing.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/__pycache__/_typing.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/util/version/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/util/version/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/util/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/util/__pycache__/_validators.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/util/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/util/__pycache__/_tester.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/util/__pycache__/_print_versions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/util/__pycache__/_exceptions.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/util/__pycache__/_decorators.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/excel/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/io/excel/__pycache__/_odswriter.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/excel/__pycache__/_odfreader.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/excel/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/excel/__pycache__/_calamine.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/excel/__pycache__/_util.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/excel/__pycache__/_xlrd.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/excel/__pycache__/_pyxlsb.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/excel/__pycache__/_base.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/excel/__pycache__/_xlsxwriter.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/excel/__pycache__/_openpyxl.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/parsers/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/io/parsers/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/parsers/__pycache__/c_parser_wrapper.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/parsers/__pycache__/base_parser.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/parsers/__pycache__/python_parser.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/parsers/__pycache__/readers.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/parsers/__pycache__/arrow_parser_wrapper.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/common.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/stata.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/feather_format.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/pytables.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/_util.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/clipboards.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/sql.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/xml.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/api.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/html.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/pickle.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/orc.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/spss.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/gbq.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/__pycache__/parquet.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/json/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/io/json/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/json/__pycache__/_json.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/json/__pycache__/_table_schema.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/json/__pycache__/_normalize.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/formats/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/io/formats/__pycache__/format.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/formats/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/formats/__pycache__/info.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/formats/__pycache__/console.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/formats/__pycache__/printing.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/formats/__pycache__/string.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/sas/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/io/sas/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/io/sas/__pycache__/sasreader.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/api/types/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/api/types/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/api/extensions/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/api/extensions/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/api/typing/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/api/typing/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/api/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/api/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/api/indexers/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/api/indexers/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/api/interchange/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/api/interchange/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/_config/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/_config/__pycache__/localization.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/_config/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/_config/__pycache__/dates.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/_config/__pycache__/config.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/_config/__pycache__/display.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/_libs/tslibs/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/_libs/tslibs/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/_libs/window/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/_libs/window/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pandas/_libs/__pycache__ +./.venv/lib/python3.12/site-packages/pandas/_libs/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/mypy/__pycache__ +./.venv/lib/python3.12/site-packages/mypy/__pycache__/split_namespace.cpython-312.pyc +./.venv/lib/python3.12/site-packages/mypy/__pycache__/__main__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/mypy/__pycache__/bogus_type.cpython-312.pyc +./.venv/lib/python3.12/site-packages/mypy/__pycache__/version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/mypy/__pycache__/pyinfo.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__ +./.venv/lib/python3.12/site-packages/yaml/__pycache__/error.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/resolver.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/reader.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/nodes.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/scanner.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/serializer.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/tokens.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/constructor.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/cyaml.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/loader.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/representer.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/parser.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/emitter.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/events.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/dumper.cpython-312.pyc +./.venv/lib/python3.12/site-packages/yaml/__pycache__/composer.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pluggy/__pycache__ +./.venv/lib/python3.12/site-packages/pluggy/__pycache__/__init__.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pluggy/__pycache__/_result.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pluggy/__pycache__/_callers.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pluggy/__pycache__/_warnings.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pluggy/__pycache__/_version.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pluggy/__pycache__/_hooks.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pluggy/__pycache__/_tracing.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pluggy/__pycache__/_manager.cpython-312.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/storage/__pycache__ +./.venv/lib/python3.12/site-packages/pytest_benchmark/storage/__pycache__/__init__.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/storage/__pycache__/file.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/storage/__pycache__/file.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/storage/__pycache__/__init__.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__ +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/table.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/session.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/plugin.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/fixture.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/table.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/utils.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/__init__.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/timers.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/logger.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/compat.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/plugin.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/session.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/compat.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/fixture.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/hookspec.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/stats.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/logger.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/stats.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/hookspec.cpython-312-pytest-8.3.4.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/timers.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/utils.cpython-312-pytest-8.2.2.pyc +./.venv/lib/python3.12/site-packages/pytest_benchmark/__pycache__/__init__.cpython-312-pytest-8.2.2.pyc +./tests/unit/resources/__pycache__ +./tests/unit/resources/__pycache__/__init__.cpython-312.pyc +./tests/unit/resources/__pycache__/indicators.cpython-312.pyc +./tests/unit/__pycache__ +./tests/unit/__pycache__/test_utils.cpython-312-pytest-8.3.4.pyc +./tests/unit/__pycache__/test_backtest.cpython-312.pyc +./tests/unit/__pycache__/__init__.cpython-312.pyc +./tests/unit/__pycache__/test_backtest_broker.cpython-312.pyc +./tests/unit/__pycache__/test_data.cpython-312-pytest-8.3.4.pyc +./tests/unit/__pycache__/test_backtest_strategy.cpython-312-pytest-8.3.4.pyc +./tests/unit/__pycache__/test_utils.cpython-312.pyc +./tests/unit/__pycache__/test_backtest_indicator.cpython-312.pyc +./tests/unit/__pycache__/conftest.cpython-312.pyc +./tests/unit/__pycache__/test_backtest_indicator.cpython-312-pytest-8.3.4.pyc +./tests/unit/__pycache__/test_backtest.cpython-312-pytest-8.3.4.pyc +./tests/unit/__pycache__/conftest.cpython-312-pytest-8.3.4.pyc +./tests/unit/__pycache__/test_backtest_broker.cpython-312-pytest-8.3.4.pyc +./tests/unit/__pycache__/test_data.cpython-312.pyc +./tests/unit/__pycache__/test_backtest_strategy.cpython-312.pyc +./tests/integration/__pycache__ +./tests/integration/__pycache__/__init__.cpython-312.pyc +./tests/integration/__pycache__/test_default.cpython-312-pytest-8.3.4.pyc +./tests/integration/__pycache__/test_default.cpython-312.pyc +./pytradebacktest/__pycache__ +./pytradebacktest/__pycache__/broker.cpython-312.pyc +./pytradebacktest/__pycache__/backtest.cpython-312.pyc +./pytradebacktest/__pycache__/__init__.cpython-312.pyc +./pytradebacktest/__pycache__/data.cpython-312.pyc +./pytradebacktest/__pycache__/utils.cpython-312.pyc +./pytradebacktest/__pycache__/exceptions.cpython-312.pyc +./pytradebacktest/__pycache__/order.cpython-312.pyc diff --git a/lib/PyTrade b/lib/PyTrade index 8a40dbd..12786ae 160000 --- a/lib/PyTrade +++ b/lib/PyTrade @@ -1 +1 @@ -Subproject commit 8a40dbd03403447226a3015676e4966b8675059d +Subproject commit 12786aebc4a00df44737130af270d0e1d2013db8 diff --git a/makefiles/local.mk b/makefiles/local.mk index ba00ce9..6f16fde 100644 --- a/makefiles/local.mk +++ b/makefiles/local.mk @@ -33,15 +33,20 @@ mypy-local: lint-local: ##@lint Run lint tools lint-local: bandit-local black-local flake8-local isort-local mypy-local +.PHONY: clean-imports +clean-imports: ##@local Remove unused imports +clean-imports: + autoflake --in-place --remove-all-unused-imports --recursive pytradebacktest tests + .PHONY: reformat reformat: ##@local Reformat module reformat: files ?= ${SERVICE} tests -reformat: +reformat: clean-imports ${POETRY} run isort --overwrite-in-place ${files} ${POETRY} run black ${files} PHONY: test-local test-local: ##@local Run test suite test-local: venv - ${POETRY} run pytest -s --tb=native --durations=5 --cov=${SERVICE} --cov-report=html tests + ${POETRY} run pytest -s --tb=native --durations=5 --cov=${SERVICE} --cov-report=term-missing tests ${POETRY} run coverage report --fail-under=90 \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 06cc413..bf01e6f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,20 @@ # This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +[[package]] +name = "autoflake" +version = "2.3.1" +description = "Removes unused imports and unused variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "autoflake-2.3.1-py3-none-any.whl", hash = "sha256:3ae7495db9084b7b32818b4140e6dc4fc280b712fb414f5b8fe57b0a8e85a840"}, + {file = "autoflake-2.3.1.tar.gz", hash = "sha256:c98b75dc5b0a86459c4f01a1d32ac7eb4338ec4317a4469515ff1e687ecd909e"}, +] + +[package.dependencies] +pyflakes = ">=3.0.0" +tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} + [[package]] name = "backtesting" version = "0.3.3" @@ -22,13 +37,13 @@ test = ["matplotlib", "scikit-learn", "scikit-optimize", "seaborn"] [[package]] name = "bandit" -version = "1.8.0" +version = "1.8.2" description = "Security oriented static analyser for python code." optional = false python-versions = ">=3.9" files = [ - {file = "bandit-1.8.0-py3-none-any.whl", hash = "sha256:b1a61d829c0968aed625381e426aa378904b996529d048f8d908fa28f6b13e38"}, - {file = "bandit-1.8.0.tar.gz", hash = "sha256:b5bfe55a095abd9fe20099178a7c6c060f844bfd4fe4c76d28e35e4c52b9d31e"}, + {file = "bandit-1.8.2-py3-none-any.whl", hash = "sha256:df6146ad73dd30e8cbda4e29689ddda48364e36ff655dbfc86998401fcf1721f"}, + {file = "bandit-1.8.2.tar.gz", hash = "sha256:e00ad5a6bc676c0954669fe13818024d66b70e42cf5adb971480cf3b671e835f"}, ] [package.dependencies] @@ -878,13 +893,13 @@ files = [ [[package]] name = "pygments" -version = "2.19.0" +version = "2.19.1" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" files = [ - {file = "pygments-2.19.0-py3-none-any.whl", hash = "sha256:4755e6e64d22161d5b61432c0600c923c5927214e7c956e31c23923c89251a9b"}, - {file = "pygments-2.19.0.tar.gz", hash = "sha256:afc4146269910d4bdfabcd27c24923137a74d562a23a320a41a55ad303e19783"}, + {file = "pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"}, + {file = "pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f"}, ] [package.extras] @@ -914,13 +929,13 @@ dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments [[package]] name = "pytest-asyncio" -version = "0.25.1" +version = "0.25.2" description = "Pytest support for asyncio" optional = false python-versions = ">=3.9" files = [ - {file = "pytest_asyncio-0.25.1-py3-none-any.whl", hash = "sha256:c84878849ec63ff2ca509423616e071ef9cd8cc93c053aa33b5b8fb70a990671"}, - {file = "pytest_asyncio-0.25.1.tar.gz", hash = "sha256:79be8a72384b0c917677e00daa711e07db15259f4d23203c59012bcd989d4aee"}, + {file = "pytest_asyncio-0.25.2-py3-none-any.whl", hash = "sha256:0d0bb693f7b99da304a0634afc0a4b19e49d5e0de2d670f38dc4bfa5727c5075"}, + {file = "pytest_asyncio-0.25.2.tar.gz", hash = "sha256:3f8ef9a98f45948ea91a0ed3dc4268b5326c0e7bce73892acc654df4262ad45f"}, ] [package.dependencies] @@ -972,6 +987,7 @@ files = [] develop = true [package.dependencies] +autoflake = "^2.3.1" backtesting = "^0.3.3" multimethod = "^1.12" numpy = "^1.26.4" @@ -1185,27 +1201,27 @@ files = [ [[package]] name = "tzdata" -version = "2024.2" +version = "2025.1" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" files = [ - {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, - {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, + {file = "tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639"}, + {file = "tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694"}, ] [[package]] name = "xyzservices" -version = "2024.9.0" +version = "2025.1.0" description = "Source of XYZ tiles providers" optional = false python-versions = ">=3.8" files = [ - {file = "xyzservices-2024.9.0-py3-none-any.whl", hash = "sha256:776ae82b78d6e5ca63dd6a94abb054df8130887a4a308473b54a6bd364de8644"}, - {file = "xyzservices-2024.9.0.tar.gz", hash = "sha256:68fb8353c9dbba4f1ff6c0f2e5e4e596bb9e1db7f94f4f7dfbcb26e25aa66fde"}, + {file = "xyzservices-2025.1.0-py3-none-any.whl", hash = "sha256:fa599956c5ab32dad1689960b3bb08fdcdbe0252cc82d84fc60ae415dc648907"}, + {file = "xyzservices-2025.1.0.tar.gz", hash = "sha256:5cdbb0907c20be1be066c6e2dc69c645842d1113a4e83e642065604a21f254ba"}, ] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "c28e465d2f7d12b2b6d71c9f702d542d60285ce7067c5433f25b4a4e711b1448" +content-hash = "04e1fdcc5d2c4cd28ed0b8a4c2965cb10ed8de054d32d92915de51710b706bdb" diff --git a/pyproject.toml b/pyproject.toml index 16eb616..b004115 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,7 @@ python = "^3.10" pytrade = {path = "lib/PyTrade", develop = true} pandas = "^2.2.2" pytest-asyncio = "^0.25.1" +autoflake = "^2.3.1" [tool.poetry.group.dev.dependencies] @@ -47,4 +48,8 @@ exclude_also = [ "@(abc\\.)?abstractmethod", ] omit = [ -] \ No newline at end of file +] + +[tool.pytest.ini_options] +addopts = ["--import-mode=importlib"] +pythonpath = [ "." ] \ No newline at end of file diff --git a/pytradebacktest/backtest.py b/pytradebacktest/backtest.py index dd9de9b..1726f31 100644 --- a/pytradebacktest/backtest.py +++ b/pytradebacktest/backtest.py @@ -1,10 +1,10 @@ from typing import Type +from pytrade.indicator import Indicator from pytrade.strategy import FxStrategy from pytradebacktest.broker import BacktestBroker from pytradebacktest.data import MarketData -from pytradebacktest.strategy import BacktestStrategyWrapper class Backtest: @@ -25,21 +25,31 @@ def __init__( async def run(self): - broker = BacktestBroker(self.data) + # Monkey patch indicators so their update does not + # need to recalculate after each increment, instead + # store their initial values from the full data context + # and then increment based on the current context length + def increment_indicator(self): + if not hasattr(self, "_backtest_values"): + self._backtest_values = self._values.copy() + self._values = self._backtest_values[: len(self._data)] - strategy = BacktestStrategyWrapper(broker, self.data, self.kstrategy) + Indicator._update = increment_indicator + + broker = BacktestBroker(self.data, self.cash, self.comission, self.margin) + + strategy = self.kstrategy(broker, self.data) strategy.init() while self.data.next(): broker.next() - await strategy.next() + strategy.next() # Increment data points # Update indicators # Update trades # Claculate results/stats - pass def plot(self): pass diff --git a/pytradebacktest/broker.py b/pytradebacktest/broker.py index 24b8a0a..39cc24e 100644 --- a/pytradebacktest/broker.py +++ b/pytradebacktest/broker.py @@ -1,39 +1,269 @@ -from typing import Callable +from math import copysign +from typing import Optional +import numpy as np +from pandas import Timestamp +from pytrade.instruments import MINUTES_MAP, Granularity, Instrument from pytrade.interfaces.broker import IBroker -from pytrade.models.instruments import Candlestick, FxInstrument, Granularity -from pytrade.models.order import OrderRequest +from pytrade.interfaces.data import IInstrumentData +from pytrade.models import Order, Position, Trade from pytradebacktest.data import MarketData +from pytradebacktest.exceptions import OutOfMoneyError +from pytradebacktest.order import OrderContext class BacktestBroker(IBroker): - def __init__(self, data: MarketData): - self.data = data + def __init__( + self, + data: MarketData, + cash, + commission, + margin, + trade_on_close=False, + hedging=False, + exclusive_orders=False, + ): + self._data = data + self._cash = cash + self._commission = commission + self._leverage = 1 / margin + self._trade_on_close = trade_on_close + self._hedging = hedging + self._exclusive_orders = exclusive_orders + + self._equity = np.tile(np.nan, len(self._data)) + self.orders: list[Order] = [] + self.trades: list[Trade] = [] + self.positions: list[Position] = [] + self.closed_trades: list[Trade] = [] @property def equity(self) -> float: - return 0 return self._cash + sum(trade.pl for trade in self.trades) @property def margin_available(self) -> float: - return 0 - # From https://github.com/QuantConnect/Lean/pull/3768 margin_used = sum(trade.value / self._leverage for trade in self.trades) return max(0, self.equity - margin_used) - def order(self, order: OrderRequest): - pass + def order(self, order: Order): + + # If exclusive orders (each new order auto-closes previous orders/position), + # cancel all non-contingent orders and close all open trades beforehand + if self._exclusive_orders: + for o in list(self.orders): + if not o.is_contingent: + self.orders.remove(o) + for t in self.trades: + self.orders.insert(0, Order(t.instrument, -t.size)) + + self.orders.append(order) def subscribe( - self, - instrument: FxInstrument, - granularity: Granularity, - callback: Callable[[Candlestick], None], - ): - pass + self, instrument: Instrument, granularity: Granularity + ) -> IInstrumentData: + return self._data.get(instrument, granularity) + + def get_position(self, instrument: Instrument) -> Position: + return Position(instrument, self.trades) def next(self): - pass + self._process_orders() + self._update_equity() + + def _update_equity(self): + # Update equity + equity = self.equity + i = self._data.i + self._equity[i] = equity + # If equity is negative, set all to 0 and stop the simulation + if equity <= 0: + if self.margin_available > 0: + raise RuntimeError + for trade in self.trades: + _data = self._get_instrument_data(trade.instrument) + self._close_trade(trade, _data.Close.iloc[-1], _data.timestamp) + self._cash = 0 + self._equity[i:] = 0 + raise OutOfMoneyError + + def _process_orders(self): + + reprocess_orders = False + for order in list(self.orders): + _data = self._get_instrument_data(order.instrument) + + with OrderContext(order, _data, self._trade_on_close) as ctx: + # Related SL/TP order already removed + if order not in self.orders: + continue + + if order.stop: + stop_hit = self._evaluate_stop_order(ctx) + if not stop_hit: + continue + + if order.limit: + limit_hit, limit_hit_before_stop = self._evaluate_limit_order(ctx) + if not limit_hit or limit_hit_before_stop: + continue + + if order.is_contingent: + self._process_contingent_order(ctx) + else: + new_trade = self._process_market_order(ctx) + + if new_trade and ( + order.stop_loss_on_fill or order.take_profit_on_fill + ): + # Need to reprocess since we created a contingent order that could + # hit within the same bar + reprocess_orders = True + + if reprocess_orders: + self._process_orders() + + def _evaluate_stop_order(self, ctx: OrderContext): + order: Order = ctx.order + stop_hit = False + stop_hit = (ctx.high > order.stop) if order.is_long else (ctx.low < order.stop) + + return stop_hit + + def _evaluate_limit_order(self, ctx: OrderContext): + order = ctx.order + limit_hit = False + limit_hit = ctx.low < order.limit if order.is_long else ctx.high > order.limit + limit_hit_before_stop = limit_hit and ( + order.limit < (order.stop or -np.inf) + if order.is_long + else order.limit > (order.stop or np.inf) + ) + + return limit_hit, limit_hit_before_stop + + def _process_contingent_order(self, ctx: OrderContext): + order = ctx.order + trade = ctx.order.parent_trade + size = int(copysign(min(abs(trade.size), abs(order.size)), order.size)) + + if trade in self.trades: + closed = self._reduce_trade(trade, size, ctx.entry_price, ctx.entry_time) + if closed: + self.orders.remove(order) + + def _process_market_order(self, ctx: OrderContext): + order = ctx.order + _need_size = ctx.order.size + new_trade = False + if not self._hedging: + _need_size = self._update_position(ctx) + + # IF we have the margin to cover the order + _insufficent_funds = ( + abs(_need_size) * ctx.entry_price > self.margin_available * self._leverage + ) + if _need_size and not _insufficent_funds: + self._open_trade(ctx) + new_trade = True + + self.orders.remove(order) + + return new_trade + + def _update_position(self, ctx: OrderContext): + order = ctx.order + _need_size = ctx.order.size + # Fill position by FIFO closing/reducing existing opposite-facing trades. + # Existing trades are closed at unadjusted price, because the adjustment + # was already made when buying. + for trade in list(self.trades): + if trade.is_long and order.is_long: + continue + + # Order is equal or larger so close trade + if abs(_need_size) >= abs(trade.size): + self._close_trade(trade, ctx.entry_price, ctx.timestmap) + _need_size += trade.size + else: + self._reduce_trade(trade, _need_size, ctx.entry_price, ctx.timestmap) + _need_size = 0 + + if not _need_size: + break + + return _need_size + + def _open_trade(self, ctx: OrderContext, tag: Optional[str] = None): + order = ctx.order + trade = Trade( + order.instrument, order.size, ctx.entry_price, ctx.entry_time, tag + ) + self.trades.append(trade) + + if order.take_profit_on_fill: + tp_order = Order( + order.instrument, + -order.size, + limit=order.take_profit_on_fill, + parent_trade=trade, + ) + trade.tp = tp_order + self.orders.insert(0, tp_order) + + if order.stop_loss_on_fill: + sl_order = Order( + order.instrument, + -order.size, + stop=order.stop_loss_on_fill, + parent_trade=trade, + ) + trade.sl = sl_order + self.orders.insert(0, sl_order) + + def _reduce_trade( + self, trade: Trade, size: int, price: float, timestamp: Timestamp + ): + size_left = trade.size + size + closed = False + + if not size_left: + close_trade = trade + closed = True + else: + trade.reduce(size_left) + if trade.sl: + trade.sl.reduce(-size_left) + if trade.tp: + trade.tp.reduce(-size_left) + + close_trade = Trade( + trade.instrument, size, trade.entry_price, trade.entry_time + ) + self.trades.append(close_trade) + + self._close_trade(close_trade, price, timestamp) + return closed + + def _close_trade(self, trade: Trade, price: float, timestamp: Timestamp): + self.trades.remove(trade) + if trade.sl: + self.orders.remove(trade.sl) + if trade.tp: + self.orders.remove(trade.tp) + + trade.close(price, timestamp) + self.closed_trades.append(trade) + self._cash += trade.pl + + def _get_instrument_data(self, instrument: Instrument): + _instrument_data = [ + src + for src in self._data._sources + if src.instrument == instrument and self._data.index == src.index + ] + _instrument_data.sort(key=lambda src: MINUTES_MAP[src.granularity]) + _data = _instrument_data[0] + return _data diff --git a/pytradebacktest/data.py b/pytradebacktest/data.py index 42d416c..a59eb04 100644 --- a/pytradebacktest/data.py +++ b/pytradebacktest/data.py @@ -1,31 +1,87 @@ from abc import abstractmethod -from typing import Tuple +from typing import Optional import numpy as np import pandas as pd -from pandas import Timedelta, Timestamp -from pytrade.models.instruments import ( - CandleData, - FxInstrument, - Granularity, - InstrumentCandles, -) +from pandas import Index, Timestamp +from pytrade.events.event import Event +from pytrade.instruments import Granularity, Instrument +from pytrade.interfaces.data import IDataContext, IInstrumentData from pytradebacktest.utils import load_csv +class InstrumentData(IInstrumentData): + + def __init__( + self, instrument: Instrument, granularity: Granularity, df: pd.DataFrame + ): + self.__df = df + self.__i = len(df) - 1 + self.__pip: Optional[float] = None + self._instrument = instrument + self._granularity = granularity + self._update_event = Event() + + def __len__(self): + return self.__i + 1 + + @property + def instrument(self) -> Instrument: + return self._instrument + + @property + def granularity(self) -> Granularity: + return self._granularity + + @property + def df(self) -> pd.DataFrame: + return ( + self.__df.iloc[: self.__i + 1] if self.__i < len(self.__df) else self.__df + ) + + @property + def on_update(self) -> Event: + return self._update_event + + @on_update.setter + def on_update(self, value: Event): + self._update_event = value + + @property + def timestamp(self): + return self.index + + @property + def prev_timestamp(self): + return self.__df.index[self.__i - 1] + + @property + def i_index(self): + return self.__i + + @property + def index(self) -> Timestamp: + return self.__df.index[self.__i] + + @index.setter + def index(self, value: Timestamp): + if value in self.__df.index: + self.__i = self.__df.index.get_loc(value) # type: ignore + + self._update_event() + + class DataSource: - def __init__(self, instrument: FxInstrument | str, granularity: Granularity): + def __init__(self, instrument: Instrument, granularity: Granularity): self.instrument = instrument self.granularity = granularity class CsvDataSource(DataSource): - def __init__( - self, path: str, instrument: FxInstrument | str, granularity: Granularity - ): + def __init__(self, path: str, instrument: Instrument, granularity: Granularity): super().__init__(instrument, granularity) self.path = path @@ -33,7 +89,7 @@ def __init__( class MarketDataLoader: @abstractmethod - def load(self) -> dict[Tuple[FxInstrument | str, Granularity], pd.DataFrame]: + def load(self) -> list[InstrumentData]: raise NotImplementedError @@ -42,24 +98,31 @@ class CsvMarketDataLoader(MarketDataLoader): def __init__(self, sources: list[CsvDataSource]): self.sources = sources - def load(self) -> dict[Tuple[FxInstrument | str, Granularity], pd.DataFrame]: - _sources = dict() + def load(self) -> list[InstrumentData]: + _sources = [] for source in self.sources: df = load_csv(source.path, parse_dates=["Timestamp"]) df = df.set_index("Timestamp") df.replace("", np.nan, inplace=True) df.dropna(inplace=True) - _sources[(source.instrument, source.granularity)] = df + instrument_data = InstrumentData(source.instrument, source.granularity, df) + _sources.append(instrument_data) return _sources -class MarketData: +class MarketData(IDataContext): def __init__(self, loader: MarketDataLoader): self._sources = loader.load() - self._init_timeframe() + self._init_index() + + def __new__(cls, *args, **kwargs): + if not hasattr(cls, "instance"): + cls.instance = super().__new__(cls) + # Need to handle case where instantiatied and different max size is provided + return cls.instance @property def universe(self): @@ -69,118 +132,43 @@ def universe(self): def index(self): return self._index - def __len__(self): - span = self._end_index - self._start_index - return int(span / self._granularity) - - def _init_timeframe(self): - _start = None - _granularity = None - _end = None - for df in self._sources.values(): - start = df.index[0] - end = df.index[-1] - granularity = df.index[1] - df.index[0] - - if start: - if not _start: - _start = start - elif start < _start: - _start = start - - if end: - if not _end: - _end = end - elif end > _end: - _end = end - - if granularity: - if not _granularity: - _granularity = granularity - elif granularity < _granularity: - _granularity = granularity - - if not _start: - raise RuntimeError("Unable to determine start time for market data.") - - if not _granularity: - raise RuntimeError( - "Unable to determine smallest granularity for market data." - ) - - if not _end: - raise RuntimeError("Unable to determine end time for market data.") - - self._index: Timestamp = _start - _granularity - self._start_index = _start - self._granularity: Timedelta = _granularity - self._end_index: Timestamp = _end - - def next(self): - - self._index = self._index + self._granularity - return self._index <= self._end_index - - -class BacktestInstrumentCandles(InstrumentCandles): - - def __init__( - self, data: pd.DataFrame, instrument: FxInstrument, granularity: Granularity - ): - super().__init__(data, max_size=-1) - self._index = self._data.index[0] - self._i_index = 0 - @property - def index(self): - return self._index + def i(self) -> int: + return self._market_index.get_loc(self._index) - @index.setter - def index(self, value: pd.Timestamp): - if value in self._data.index: - self._index = value - - @property - def i_index(self): - return self._data.index.get_loc(self._index) + def __len__(self): + return len(self._market_index) - # def next(self): - # while self._i_index < len(self._data.index): - # yield self._data[self._i_index] - # self._i_index += 1 + def _init_index(self): + _market_index: Index[Timestamp] = pd.Index([]) + for source in self._sources: + _market_index = _market_index.union(source.df.index) + self._next = self.__next() + self._market_index = _market_index + self._index = _market_index[0] -class BacktestCandleData(CandleData): + def next(self): + try: + result = next(self._next) + except StopIteration: + result = False - def __init__(self): - self._max_size = -1 - self._data: dict[ - tuple[FxInstrument, Granularity], BacktestInstrumentCandles - ] = {} - self._index = None + return result - def __new__(cls, *args, **kwargs): - if not hasattr(cls, "instance"): - cls.instance = super().__new__(cls) - # Need to handle case where instantiatied and different max size is provided - return cls.instance + def __next(self): - @property - def index(self): - return self._index + for idx in self._market_index: + self._index = idx + for source in self._sources: + source.index = idx + yield True - @index.setter - def index(self, value: pd.Timestamp): - self._index = value - for candles in self._data.values(): - candles.index = self._index + yield False - def populate( - self, df: pd.DataFrame, instrument: FxInstrument, granularity: Granularity - ): - key = (instrument, granularity) - instrument_candles: BacktestInstrumentCandles = self._data.get( - key, - BacktestInstrumentCandles(df, instrument, granularity), + def get(self, instrument: Instrument, granularity: Granularity) -> IInstrumentData: + return next( + src + for src in self._sources + if src.instrument == instrument and src.granularity == granularity ) - self._data[key] = instrument_candles diff --git a/pytradebacktest/exceptions.py b/pytradebacktest/exceptions.py index e69de29..8c4ef6a 100644 --- a/pytradebacktest/exceptions.py +++ b/pytradebacktest/exceptions.py @@ -0,0 +1,2 @@ +class OutOfMoneyError(Exception): + pass diff --git a/pytradebacktest/order.py b/pytradebacktest/order.py new file mode 100644 index 0000000..84b89d5 --- /dev/null +++ b/pytradebacktest/order.py @@ -0,0 +1,74 @@ +import numpy as np +from pytrade.broker import Order + +from pytradebacktest.data import InstrumentData + + +class OrderContext: + + def __init__(self, order: Order, data: InstrumentData, trade_on_close: bool): + self._order = order + self._data = data + self._trade_on_close = trade_on_close + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + pass + + @property + def order(self): + return self._order + + @property + def data(self): + return self._data + + @property + def open(self): + return self._data.Open.iloc[-1] + + @property + def high(self): + return self._data.High.iloc[-1] + + @property + def low(self): + return self._data.Low.iloc[-1] + + @property + def close(self): + return self._data.Close.iloc[-1] + + @property + def prev_close(self): + return self._data.Close.iloc[-1] + + @property + def timestmap(self): + return self._data.timestamp + + @property + def entry_time(self): + return ( + self._data.prev_timestamp + if self.is_market_order and self._trade_on_close + else self._data.timestamp + ) + + @property + def is_market_order(self): + return not self.order.limit and not self.order.stop + + @property + def entry_price(self): + if self.order.limit: + func = min if self.order.is_long else max + price = func(self.order.stop or self.open, self.order.limit) + else: + price = self.prev_close if self._trade_on_close else self.open + func = max if self.order.is_long else min + stop_default = -np.inf if self.order.is_long else np.inf + price = func(price, self.order.stop or stop_default) + return price diff --git a/pytradebacktest/strategy.py b/pytradebacktest/strategy.py deleted file mode 100644 index e83929c..0000000 --- a/pytradebacktest/strategy.py +++ /dev/null @@ -1,67 +0,0 @@ -from typing import Type - -from pytrade.interfaces.broker import IBroker -from pytrade.models.indicator import Indicator -from pytrade.strategy import FxStrategy - -from pytradebacktest.data import ( - BacktestCandleData, - BacktestInstrumentCandles, - MarketData, -) - - -class BacktestStrategyWrapper: - - def __init__(self, broker: IBroker, data: MarketData, kstrategy: Type[FxStrategy]): - self._data = data - self._data_context = BacktestCandleData() - self._strategy = kstrategy(broker, self._data_context) - self._current_index = None - - def init(self): - for key, df in self._data.universe.items(): - self._data_context.populate(df, key[0], key[1]) - - self._strategy.init() - - self._indicators = { - attr: indicator - for attr, indicator in self._strategy.__dict__.items() - if isinstance(indicator, Indicator) - }.items() - - self._indicator_values = { - attr: indicator._values for attr, indicator in self._indicators - } - - self._indicator_i_index = {attr: None for attr, indicator in self._indicators} - - async def next(self) -> None: - - self._data_context.index = self._data.index - - updates = [] - # Incrememnt indicators - for attr, indicator in self._indicators: - indicator_updated = False - if isinstance(indicator._data, BacktestInstrumentCandles): - previous_i_index = self._indicator_i_index.get(attr) - if previous_i_index != indicator._data.i_index: - indicator._values = self._indicator_values[attr][ - : indicator._data.i_index + 1 - ] - self._indicator_i_index[attr] = indicator._data.i_index - indicator_updated = True - - updates.append(indicator_updated) - - all_updates_received = all(updates) - - # Currently making sure all indicators have been updated before calling next - # This aligns with the pending update logic when the strategy is event - # driven in live trading. If that behavior changes this will also need to - # change. - if all_updates_received: - # Call _next directly so we don't wait for pending updates - self._strategy._next() diff --git a/tests/unit/assets/EURGBP-2024-05_1Min.csv b/tests/unit/assets/EURGBP-2024-05_1Min.csv index 15948e3..6106104 100644 --- a/tests/unit/assets/EURGBP-2024-05_1Min.csv +++ b/tests/unit/assets/EURGBP-2024-05_1Min.csv @@ -1,4 +1,4 @@ -Timestamp,open,high,low,close +Timestamp,Open,High,Low,Close 2024-05-01 00:00:00,0.85401,0.85405,0.85397,0.85403 2024-05-01 00:01:00,0.85402,0.85404,0.85392,0.85403 2024-05-01 00:02:00,0.85397,0.85403,0.85396,0.854 diff --git a/tests/unit/assets/EURGBP-2024-05_5Min.csv b/tests/unit/assets/EURGBP-2024-05_5Min.csv index bb0f6e2..802923c 100644 --- a/tests/unit/assets/EURGBP-2024-05_5Min.csv +++ b/tests/unit/assets/EURGBP-2024-05_5Min.csv @@ -1,4 +1,4 @@ -Timestamp,open,high,low,close +Timestamp,Open,High,Low,Close 2024-05-01 00:00:00,0.85401,0.85405,0.85391,0.85396 2024-05-01 00:05:00,0.85396,0.85397,0.85389,0.85392 2024-05-01 00:10:00,0.85391,0.85397,0.85386,0.85396 diff --git a/tests/unit/assets/EURJPY-2024-05_1Min.csv b/tests/unit/assets/EURJPY-2024-05_1Min.csv index d7d407b..0b4286b 100644 --- a/tests/unit/assets/EURJPY-2024-05_1Min.csv +++ b/tests/unit/assets/EURJPY-2024-05_1Min.csv @@ -1,4 +1,4 @@ -Timestamp,open,high,low,close +Timestamp,Open,High,Low,Close 2024-05-01 00:00:00,168.263,168.274,168.201,168.229 2024-05-01 00:01:00,168.247,168.261,168.217,168.222 2024-05-01 00:02:00,168.222,168.242,168.191,168.213 diff --git a/tests/unit/assets/EURJPY-2024-05_5Min.csv b/tests/unit/assets/EURJPY-2024-05_5Min.csv index 55e674f..681c392 100644 --- a/tests/unit/assets/EURJPY-2024-05_5Min.csv +++ b/tests/unit/assets/EURJPY-2024-05_5Min.csv @@ -1,4 +1,4 @@ -Timestamp,open,high,low,close +Timestamp,Open,High,Low,Close 2024-05-01 00:00:00,168.263,168.274,168.177,168.226 2024-05-01 00:05:00,168.24,168.285,168.2,168.256 2024-05-01 00:10:00,168.274,168.275,168.201,168.242 diff --git a/tests/unit/assets/GBPUSD-2024-05_1Min.csv b/tests/unit/assets/GBPUSD-2024-05_1Min.csv index 0ce95bd..0acc55d 100644 --- a/tests/unit/assets/GBPUSD-2024-05_1Min.csv +++ b/tests/unit/assets/GBPUSD-2024-05_1Min.csv @@ -1,4 +1,4 @@ -Timestamp,open,high,low,close +Timestamp,Open,High,Low,Close 2024-05-01 00:00:00,1.24883,1.24896,1.24878,1.24893 2024-05-01 00:01:00,1.24894,1.24904,1.24883,1.24888 2024-05-01 00:02:00,1.24884,1.24894,1.24884,1.24889 @@ -1261,12 +1261,12 @@ Timestamp,open,high,low,close 2024-05-01 20:59:00,1.25268,1.25293,1.25223,1.25231 2024-05-01 21:00:00,1.25222,1.25222,1.25088,1.25088 2024-05-01 21:01:00,1.25095,1.25095,1.25085,1.25085 -2024-05-01 21:02:00,,,, -2024-05-01 21:03:00,,,, +2024-05-01 21:02:00,1.25095,1.25095,1.25085,1.25085 +2024-05-01 21:03:00,1.25095,1.25095,1.25085,1.25085 2024-05-01 21:04:00,1.25061,1.25061,1.25061,1.25061 2024-05-01 21:05:00,1.25085,1.25085,1.25085,1.25085 -2024-05-01 21:06:00,,,, -2024-05-01 21:07:00,,,, +2024-05-01 21:06:00,1.25085,1.25085,1.25085,1.25085 +2024-05-01 21:07:00,1.25085,1.25085,1.25085,1.25085 2024-05-01 21:08:00,1.25097,1.25109,1.25097,1.25108 2024-05-01 21:09:00,1.25096,1.25096,1.25096,1.25096 2024-05-01 21:10:00,1.25137,1.25143,1.25059,1.25059 @@ -2701,13 +2701,13 @@ Timestamp,open,high,low,close 2024-05-02 20:59:00,1.25343,1.25349,1.25294,1.25294 2024-05-02 21:00:00,1.25339,1.25339,1.24958,1.25022 2024-05-02 21:01:00,1.24958,1.2504,1.24958,1.2504 -2024-05-02 21:02:00,,,, -2024-05-02 21:03:00,,,, +2024-05-02 21:02:00,1.24958,1.2504,1.24958,1.2504 +2024-05-02 21:03:00,1.24958,1.2504,1.24958,1.2504 2024-05-02 21:04:00,1.25164,1.25164,1.25164,1.25164 2024-05-02 21:05:00,1.25123,1.25172,1.25122,1.25172 2024-05-02 21:06:00,1.25173,1.25173,1.25118,1.25156 2024-05-02 21:07:00,1.25163,1.25163,1.25155,1.25156 -2024-05-02 21:08:00,,,, +2024-05-02 21:08:00,1.25163,1.25163,1.25155,1.25156 2024-05-02 21:09:00,1.25159,1.25159,1.25156,1.25156 2024-05-02 21:10:00,1.2505,1.25235,1.2505,1.25203 2024-05-02 21:11:00,1.25235,1.25235,1.25203,1.25228 @@ -7020,15 +7020,15 @@ Timestamp,open,high,low,close 2024-05-05 20:58:00,,,, 2024-05-05 20:59:00,,,, 2024-05-05 21:00:00,1.25276,1.25276,1.25275,1.25275 -2024-05-05 21:01:00,,,, -2024-05-05 21:02:00,,,, -2024-05-05 21:03:00,,,, -2024-05-05 21:04:00,,,, +2024-05-05 21:01:00,1.25276,1.25276,1.25275,1.25275 +2024-05-05 21:02:00,1.25276,1.25276,1.25275,1.25275 +2024-05-05 21:03:00,1.25276,1.25276,1.25275,1.25275 +2024-05-05 21:04:00,1.25276,1.25276,1.25275,1.25275 2024-05-05 21:05:00,1.25257,1.25257,1.25221,1.25221 2024-05-05 21:06:00,1.25412,1.25442,1.25412,1.25416 -2024-05-05 21:07:00,,,, -2024-05-05 21:08:00,,,, -2024-05-05 21:09:00,,,, +2024-05-05 21:07:00,1.25412,1.25442,1.25412,1.25416 +2024-05-05 21:08:00,1.25412,1.25442,1.25412,1.25416 +2024-05-05 21:09:00,1.25412,1.25442,1.25412,1.25416 2024-05-05 21:10:00,1.2522,1.25221,1.2522,1.25221 2024-05-05 21:11:00,1.2522,1.25221,1.2522,1.25221 2024-05-05 21:12:00,1.2522,1.25221,1.2522,1.25221 @@ -8462,7 +8462,7 @@ Timestamp,open,high,low,close 2024-05-06 21:00:00,1.25603,1.25603,1.25502,1.25502 2024-05-06 21:01:00,1.25488,1.25502,1.25488,1.25502 2024-05-06 21:02:00,1.25504,1.25504,1.25504,1.25504 -2024-05-06 21:03:00,,,, +2024-05-06 21:03:00,1.25504,1.25504,1.25504,1.25504 2024-05-06 21:04:00,1.25504,1.25504,1.25504,1.25504 2024-05-06 21:05:00,1.25504,1.25548,1.25504,1.25504 2024-05-06 21:06:00,1.25476,1.25476,1.25448,1.25448 @@ -9901,10 +9901,10 @@ Timestamp,open,high,low,close 2024-05-07 20:59:00,1.25075,1.25082,1.25039,1.25073 2024-05-07 21:00:00,1.25042,1.25043,1.24966,1.24966 2024-05-07 21:01:00,1.24973,1.24973,1.24973,1.24973 -2024-05-07 21:02:00,,,, -2024-05-07 21:03:00,,,, -2024-05-07 21:04:00,,,, -2024-05-07 21:05:00,,,, +2024-05-07 21:02:00,1.24973,1.24973,1.24973,1.24973 +2024-05-07 21:03:00,1.24973,1.24973,1.24973,1.24973 +2024-05-07 21:04:00,1.24973,1.24973,1.24973,1.24973 +2024-05-07 21:05:00,1.24973,1.24973,1.24973,1.24973 2024-05-07 21:06:00,1.24959,1.24959,1.24959,1.24959 2024-05-07 21:07:00,1.24966,1.24966,1.24966,1.24966 2024-05-07 21:08:00,1.24959,1.24966,1.24959,1.24966 @@ -11343,12 +11343,12 @@ Timestamp,open,high,low,close 2024-05-08 21:01:00,1.24758,1.2481,1.24758,1.24758 2024-05-08 21:02:00,1.24764,1.24764,1.24764,1.24764 2024-05-08 21:03:00,1.24856,1.24856,1.24856,1.24856 -2024-05-08 21:04:00,,,, +2024-05-08 21:04:00,1.24856,1.24856,1.24856,1.24856 2024-05-08 21:05:00,1.24856,1.24856,1.24852,1.24852 2024-05-08 21:06:00,1.24854,1.24854,1.24854,1.24854 2024-05-08 21:07:00,1.24871,1.24871,1.24849,1.24849 2024-05-08 21:08:00,1.24851,1.24859,1.24851,1.24859 -2024-05-08 21:09:00,,,, +2024-05-08 21:09:00,1.24851,1.24859,1.24851,1.24859 2024-05-08 21:10:00,1.2489,1.2489,1.24848,1.24859 2024-05-08 21:11:00,1.2489,1.24897,1.24859,1.24896 2024-05-08 21:12:00,1.24883,1.24897,1.24878,1.24896 @@ -17100,15 +17100,15 @@ Timestamp,open,high,low,close 2024-05-12 20:58:00,,,, 2024-05-12 20:59:00,,,, 2024-05-12 21:00:00,1.25117,1.25117,1.25062,1.25062 -2024-05-12 21:01:00,,,, -2024-05-12 21:02:00,,,, -2024-05-12 21:03:00,,,, -2024-05-12 21:04:00,,,, -2024-05-12 21:05:00,,,, +2024-05-12 21:01:00,1.25117,1.25117,1.25062,1.25062 +2024-05-12 21:02:00,1.25117,1.25117,1.25062,1.25062 +2024-05-12 21:03:00,1.25117,1.25117,1.25062,1.25062 +2024-05-12 21:04:00,1.25117,1.25117,1.25062,1.25062 +2024-05-12 21:05:00,1.25117,1.25117,1.25062,1.25062 2024-05-12 21:06:00,1.25073,1.25073,1.25073,1.25073 -2024-05-12 21:07:00,,,, -2024-05-12 21:08:00,,,, -2024-05-12 21:09:00,,,, +2024-05-12 21:07:00,1.25073,1.25073,1.25073,1.25073 +2024-05-12 21:08:00,1.25073,1.25073,1.25073,1.25073 +2024-05-12 21:09:00,1.25073,1.25073,1.25073,1.25073 2024-05-12 21:10:00,1.25072,1.25073,1.25072,1.25073 2024-05-12 21:11:00,1.25072,1.25073,1.25072,1.25073 2024-05-12 21:12:00,1.25072,1.25073,1.25072,1.25073 @@ -18541,9 +18541,9 @@ Timestamp,open,high,low,close 2024-05-13 20:59:00,1.25591,1.25591,1.25547,1.25579 2024-05-13 21:00:00,1.2556,1.2556,1.25535,1.25535 2024-05-13 21:01:00,1.25536,1.25544,1.25522,1.25544 -2024-05-13 21:02:00,,,, +2024-05-13 21:02:00,1.25536,1.25544,1.25522,1.25544 2024-05-13 21:03:00,1.25549,1.25549,1.25549,1.25549 -2024-05-13 21:04:00,,,, +2024-05-13 21:04:00,1.25549,1.25549,1.25549,1.25549 2024-05-13 21:05:00,1.25534,1.25534,1.25534,1.25534 2024-05-13 21:06:00,1.25546,1.25551,1.25526,1.2553 2024-05-13 21:07:00,1.25531,1.25539,1.25531,1.25539 @@ -19980,14 +19980,14 @@ Timestamp,open,high,low,close 2024-05-14 20:58:00,1.25908,1.25915,1.25868,1.25883 2024-05-14 20:59:00,1.25887,1.25918,1.2586,1.25869 2024-05-14 21:00:00,1.25889,1.25889,1.25714,1.25714 -2024-05-14 21:01:00,,,, -2024-05-14 21:02:00,,,, +2024-05-14 21:01:00,1.25889,1.25889,1.25714,1.25714 +2024-05-14 21:02:00,1.25889,1.25889,1.25714,1.25714 2024-05-14 21:03:00,1.25748,1.25748,1.25748,1.25748 -2024-05-14 21:04:00,,,, +2024-05-14 21:04:00,1.25748,1.25748,1.25748,1.25748 2024-05-14 21:05:00,1.25716,1.25716,1.25716,1.25716 -2024-05-14 21:06:00,,,, -2024-05-14 21:07:00,,,, -2024-05-14 21:08:00,,,, +2024-05-14 21:06:00,1.25716,1.25716,1.25716,1.25716 +2024-05-14 21:07:00,1.25716,1.25716,1.25716,1.25716 +2024-05-14 21:08:00,1.25716,1.25716,1.25716,1.25716 2024-05-14 21:09:00,1.25753,1.25753,1.25716,1.25753 2024-05-14 21:10:00,1.25774,1.25774,1.25715,1.25722 2024-05-14 21:11:00,1.25721,1.25722,1.25721,1.25722 @@ -21420,14 +21420,14 @@ Timestamp,open,high,low,close 2024-05-15 20:58:00,1.26847,1.26853,1.26804,1.26851 2024-05-15 20:59:00,1.26821,1.26853,1.26808,1.26828 2024-05-15 21:00:00,1.26693,1.26693,1.26693,1.26693 -2024-05-15 21:01:00,,,, -2024-05-15 21:02:00,,,, +2024-05-15 21:01:00,1.26693,1.26693,1.26693,1.26693 +2024-05-15 21:02:00,1.26693,1.26693,1.26693,1.26693 2024-05-15 21:03:00,1.26729,1.26729,1.26729,1.26729 2024-05-15 21:04:00,1.26721,1.26721,1.26721,1.26721 -2024-05-15 21:05:00,,,, -2024-05-15 21:06:00,,,, -2024-05-15 21:07:00,,,, -2024-05-15 21:08:00,,,, +2024-05-15 21:05:00,1.26721,1.26721,1.26721,1.26721 +2024-05-15 21:06:00,1.26721,1.26721,1.26721,1.26721 +2024-05-15 21:07:00,1.26721,1.26721,1.26721,1.26721 +2024-05-15 21:08:00,1.26721,1.26721,1.26721,1.26721 2024-05-15 21:09:00,1.26747,1.26747,1.26746,1.26746 2024-05-15 21:10:00,1.26743,1.26747,1.26687,1.26721 2024-05-15 21:11:00,1.26687,1.26721,1.26687,1.26721 @@ -22863,12 +22863,12 @@ Timestamp,open,high,low,close 2024-05-16 21:01:00,1.26613,1.26613,1.26613,1.26613 2024-05-16 21:02:00,1.26626,1.26626,1.26626,1.26626 2024-05-16 21:03:00,1.26613,1.26626,1.26613,1.26613 -2024-05-16 21:04:00,,,, -2024-05-16 21:05:00,,,, -2024-05-16 21:06:00,,,, +2024-05-16 21:04:00,1.26613,1.26626,1.26613,1.26613 +2024-05-16 21:05:00,1.26613,1.26626,1.26613,1.26613 +2024-05-16 21:06:00,1.26613,1.26626,1.26613,1.26613 2024-05-16 21:07:00,1.26619,1.26619,1.26619,1.26619 -2024-05-16 21:08:00,,,, -2024-05-16 21:09:00,,,, +2024-05-16 21:08:00,1.26619,1.26619,1.26619,1.26619 +2024-05-16 21:09:00,1.26619,1.26619,1.26619,1.26619 2024-05-16 21:10:00,1.26618,1.26619,1.26618,1.26619 2024-05-16 21:11:00,1.26618,1.26619,1.26618,1.26619 2024-05-16 21:12:00,1.26618,1.26676,1.26618,1.26676 @@ -27183,12 +27183,12 @@ Timestamp,open,high,low,close 2024-05-19 21:01:00,1.26797,1.26797,1.26797,1.26797 2024-05-19 21:02:00,1.26798,1.2683,1.26798,1.2683 2024-05-19 21:03:00,1.26831,1.26831,1.26831,1.26831 -2024-05-19 21:04:00,,,, +2024-05-19 21:04:00,1.26831,1.26831,1.26831,1.26831 2024-05-19 21:05:00,1.2682,1.26831,1.2682,1.26831 2024-05-19 21:06:00,1.2682,1.2682,1.2682,1.2682 2024-05-19 21:07:00,1.2682,1.2682,1.2682,1.2682 -2024-05-19 21:08:00,,,, -2024-05-19 21:09:00,,,, +2024-05-19 21:08:00,1.2682,1.2682,1.2682,1.2682 +2024-05-19 21:09:00,1.2682,1.2682,1.2682,1.2682 2024-05-19 21:10:00,1.26819,1.2683,1.26819,1.2683 2024-05-19 21:11:00,1.26829,1.26831,1.26829,1.26831 2024-05-19 21:12:00,1.2683,1.26831,1.2683,1.26831 @@ -28621,9 +28621,9 @@ Timestamp,open,high,low,close 2024-05-20 20:59:00,1.27054,1.27061,1.27013,1.2703 2024-05-20 21:00:00,1.2694,1.2694,1.26901,1.26924 2024-05-20 21:01:00,1.26925,1.27007,1.26925,1.27007 -2024-05-20 21:02:00,,,, -2024-05-20 21:03:00,,,, -2024-05-20 21:04:00,,,, +2024-05-20 21:02:00,1.26925,1.27007,1.26925,1.27007 +2024-05-20 21:03:00,1.26925,1.27007,1.26925,1.27007 +2024-05-20 21:04:00,1.26925,1.27007,1.26925,1.27007 2024-05-20 21:05:00,1.27007,1.27007,1.27007,1.27007 2024-05-20 21:06:00,1.26981,1.27001,1.26979,1.27001 2024-05-20 21:07:00,1.27001,1.27007,1.26999,1.27 @@ -30061,13 +30061,13 @@ Timestamp,open,high,low,close 2024-05-21 20:59:00,1.27058,1.27089,1.27041,1.27055 2024-05-21 21:00:00,1.27056,1.27056,1.26945,1.26947 2024-05-21 21:01:00,1.26954,1.26956,1.26954,1.26956 -2024-05-21 21:02:00,,,, -2024-05-21 21:03:00,,,, -2024-05-21 21:04:00,,,, +2024-05-21 21:02:00,1.26954,1.26956,1.26954,1.26956 +2024-05-21 21:03:00,1.26954,1.26956,1.26954,1.26956 +2024-05-21 21:04:00,1.26954,1.26956,1.26954,1.26956 2024-05-21 21:05:00,1.26962,1.2698,1.26956,1.26971 2024-05-21 21:06:00,1.26968,1.26974,1.26956,1.26968 2024-05-21 21:07:00,1.26972,1.26985,1.26972,1.26982 -2024-05-21 21:08:00,,,, +2024-05-21 21:08:00,1.26972,1.26985,1.26972,1.26982 2024-05-21 21:09:00,1.26989,1.26991,1.26989,1.26991 2024-05-21 21:10:00,1.27005,1.27026,1.26962,1.26963 2024-05-21 21:11:00,1.26965,1.26969,1.26962,1.26969 @@ -31501,13 +31501,13 @@ Timestamp,open,high,low,close 2024-05-22 20:59:00,1.27137,1.2717,1.27137,1.27148 2024-05-22 21:00:00,1.27148,1.27148,1.27092,1.27096 2024-05-22 21:01:00,1.27102,1.27121,1.27102,1.27121 -2024-05-22 21:02:00,,,, -2024-05-22 21:03:00,,,, -2024-05-22 21:04:00,,,, -2024-05-22 21:05:00,,,, +2024-05-22 21:02:00,1.27102,1.27121,1.27102,1.27121 +2024-05-22 21:03:00,1.27102,1.27121,1.27102,1.27121 +2024-05-22 21:04:00,1.27102,1.27121,1.27102,1.27121 +2024-05-22 21:05:00,1.27102,1.27121,1.27102,1.27121 2024-05-22 21:06:00,1.27127,1.27127,1.27127,1.27127 2024-05-22 21:07:00,1.27117,1.27117,1.27117,1.27117 -2024-05-22 21:08:00,,,, +2024-05-22 21:08:00,1.27117,1.27117,1.27117,1.27117 2024-05-22 21:09:00,1.2712,1.27131,1.2712,1.27131 2024-05-22 21:10:00,1.27109,1.27131,1.27109,1.27128 2024-05-22 21:11:00,1.27113,1.27134,1.27113,1.27134 @@ -32943,11 +32943,11 @@ Timestamp,open,high,low,close 2024-05-23 21:01:00,1.26829,1.26829,1.26829,1.26829 2024-05-23 21:02:00,1.26818,1.26818,1.26818,1.26818 2024-05-23 21:03:00,1.26818,1.26818,1.26818,1.26818 -2024-05-23 21:04:00,,,, -2024-05-23 21:05:00,,,, +2024-05-23 21:04:00,1.26818,1.26818,1.26818,1.26818 +2024-05-23 21:05:00,1.26818,1.26818,1.26818,1.26818 2024-05-23 21:06:00,1.26831,1.26831,1.26831,1.26831 2024-05-23 21:07:00,1.26831,1.26831,1.26831,1.26831 -2024-05-23 21:08:00,,,, +2024-05-23 21:08:00,1.26831,1.26831,1.26831,1.26831 2024-05-23 21:09:00,1.26861,1.26861,1.26851,1.26852 2024-05-23 21:10:00,1.26876,1.26876,1.26835,1.26852 2024-05-23 21:11:00,1.26876,1.26876,1.26852,1.26852 @@ -37260,12 +37260,12 @@ Timestamp,open,high,low,close 2024-05-26 20:58:00,,,, 2024-05-26 20:59:00,,,, 2024-05-26 21:00:00,1.27273,1.27273,1.27273,1.27273 -2024-05-26 21:01:00,,,, -2024-05-26 21:02:00,,,, +2024-05-26 21:01:00,1.27273,1.27273,1.27273,1.27273 +2024-05-26 21:02:00,1.27273,1.27273,1.27273,1.27273 2024-05-26 21:03:00,1.27285,1.27285,1.27285,1.27285 -2024-05-26 21:04:00,,,, +2024-05-26 21:04:00,1.27285,1.27285,1.27285,1.27285 2024-05-26 21:05:00,1.27239,1.27285,1.27201,1.27201 -2024-05-26 21:06:00,,,, +2024-05-26 21:06:00,1.27239,1.27285,1.27201,1.27201 2024-05-26 21:07:00,1.27223,1.27224,1.27223,1.27224 2024-05-26 21:08:00,1.27225,1.27236,1.27225,1.27236 2024-05-26 21:09:00,1.27237,1.27238,1.27237,1.27238 @@ -40140,9 +40140,9 @@ Timestamp,open,high,low,close 2024-05-28 20:58:00,1.27568,1.27614,1.27563,1.2757 2024-05-28 20:59:00,1.27613,1.27614,1.27564,1.27583 2024-05-28 21:00:00,1.27509,1.27509,1.27509,1.27509 -2024-05-28 21:01:00,,,, +2024-05-28 21:01:00,1.27509,1.27509,1.27509,1.27509 2024-05-28 21:02:00,1.27518,1.27518,1.27518,1.27518 -2024-05-28 21:03:00,,,, +2024-05-28 21:03:00,1.27518,1.27518,1.27518,1.27518 2024-05-28 21:04:00,1.27527,1.27527,1.27527,1.27527 2024-05-28 21:05:00,1.27518,1.27527,1.27323,1.27384 2024-05-28 21:06:00,1.27373,1.27473,1.27323,1.27469 @@ -41585,7 +41585,7 @@ Timestamp,open,high,low,close 2024-05-29 21:03:00,1.26972,1.26979,1.26972,1.26979 2024-05-29 21:04:00,1.26979,1.2698,1.26979,1.2698 2024-05-29 21:05:00,1.26981,1.26981,1.26981,1.26981 -2024-05-29 21:06:00,,,, +2024-05-29 21:06:00,1.26981,1.26981,1.26981,1.26981 2024-05-29 21:07:00,1.26982,1.26982,1.26982,1.26982 2024-05-29 21:08:00,1.26987,1.26995,1.26987,1.26995 2024-05-29 21:09:00,1.26996,1.26996,1.26996,1.26996 @@ -43021,12 +43021,12 @@ Timestamp,open,high,low,close 2024-05-30 20:59:00,1.27281,1.27324,1.27262,1.27278 2024-05-30 21:00:00,1.27236,1.27236,1.27172,1.27172 2024-05-30 21:01:00,1.27175,1.27177,1.27175,1.27177 -2024-05-30 21:02:00,,,, +2024-05-30 21:02:00,1.27175,1.27177,1.27175,1.27177 2024-05-30 21:03:00,1.27214,1.27214,1.27214,1.27214 -2024-05-30 21:04:00,,,, +2024-05-30 21:04:00,1.27214,1.27214,1.27214,1.27214 2024-05-30 21:05:00,1.27213,1.27255,1.27213,1.27251 2024-05-30 21:06:00,1.2724,1.27244,1.27229,1.27229 -2024-05-30 21:07:00,,,, +2024-05-30 21:07:00,1.2724,1.27244,1.27229,1.27229 2024-05-30 21:08:00,1.27236,1.27236,1.27232,1.27233 2024-05-30 21:09:00,1.27254,1.27263,1.27244,1.27263 2024-05-30 21:10:00,1.2728,1.2728,1.27222,1.27258 diff --git a/tests/unit/assets/GBPUSD-2024-05_5Min.csv b/tests/unit/assets/GBPUSD-2024-05_5Min.csv index 486bc00..c2b25c4 100644 --- a/tests/unit/assets/GBPUSD-2024-05_5Min.csv +++ b/tests/unit/assets/GBPUSD-2024-05_5Min.csv @@ -1,4 +1,4 @@ -Timestamp,open,high,low,close +Timestamp,Open,High,Low,Close 2024-05-01 00:00:00,1.24883,1.24906,1.24878,1.24901 2024-05-01 00:05:00,1.24904,1.24911,1.24891,1.24902 2024-05-01 00:10:00,1.24903,1.24906,1.24868,1.24872 diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index a7d78d5..2a82b33 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -1,9 +1,10 @@ import numpy as np import pandas as pd import pytest +from pytrade.data import IInstrumentData from pytrade.events.event import Event -from pytrade.models.indicator import Indicator -from pytrade.models.instruments import FxInstrument, Granularity, IInstrumentData +from pytrade.indicator import Indicator +from pytrade.instruments import FxInstrument, Granularity from pytradebacktest.data import CsvDataSource, CsvMarketDataLoader, MarketData @@ -114,3 +115,13 @@ def test_fx_universe(test_csv_sources): @pytest.fixture(scope="function") def test_stock_universe(test_stock_sources): return MarketData(CsvMarketDataLoader(test_stock_sources)) + + +@pytest.fixture(scope="function") +def backtest_indicator(): + pass + + +@pytest.fixture(scope="function") +def backtest_strategy(): + pass diff --git a/tests/unit/resources/__init__.py b/tests/unit/resources/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/resources/indicators.py b/tests/unit/resources/indicators.py new file mode 100644 index 0000000..962f17e --- /dev/null +++ b/tests/unit/resources/indicators.py @@ -0,0 +1,108 @@ +from numbers import Number +from typing import Sequence + +import pandas as pd +from pytrade.indicator import Indicator +from pytrade.instruments import CandleSubscription, FxInstrument, Granularity +from pytrade.interfaces.data import IInstrumentData +from pytrade.strategy import FxStrategy + +BACKTEST_INSTRUMENT = FxInstrument.EURUSD +BACKTEST_GRANULARITY = Granularity.M5 + + +class BacktestIndicator(Indicator): + + def _run(self, *args, **kwargs): + return self._data.Open > self._data.Close + + +class BacktestStrategy(FxStrategy): + + @property + def subscriptions(self) -> list[CandleSubscription]: + """ + Declare the `InstrumentSubscription`s this strategy should use + for its signals + """ + return [CandleSubscription(BACKTEST_INSTRUMENT, BACKTEST_GRANULARITY)] + + def _init(self) -> None: + """ + Create indicators to be used for signals in the `_next` method. + """ + data = self.get_data(BACKTEST_INSTRUMENT, BACKTEST_GRANULARITY) + self.test_indicator = BacktestIndicator(data) + + def _next(self) -> None: + """ + Evaluate indicators and submit orders to the broker + """ + if self.test_indicator: + self.sell(1) + else: + self.buy(1) + + +def crossover(series1: Sequence, series2: Sequence) -> bool: + """ + Return `True` if `series1` just crossed over (above) + `series2`. + + >>> crossover(self.data.Close, self.sma) + True + """ + series1 = ( + series1.values + if isinstance(series1, pd.Series) + else (series1, series1) if isinstance(series1, Number) else series1 + ) + series2 = ( + series2.values + if isinstance(series2, pd.Series) + else (series2, series2) if isinstance(series2, Number) else series2 + ) + try: + return series1[-2] < series2[-2] and series1[-1] > series2[-1] + except IndexError: + return False + + +class Sma(Indicator): + + def __init__(self, data: IInstrumentData, period: int): + self._period = period + super().__init__(data) + + def _run(self): + return pd.Series(self._data.Close).rolling(self._period).mean() + + +class SmaCross(FxStrategy): + + fast = 10 + slow = 30 + + @property + def subscriptions(self) -> list[CandleSubscription]: + """ + Declare the `InstrumentSubscription`s this strategy should use + for its signals + """ + return [CandleSubscription("GOOG", Granularity.D1)] + + def _init(self) -> None: + """ + Create indicators to be used for signals in the `_next` method. + """ + data = self.get_data("GOOG", Granularity.D1) + self.sma1 = Sma(data, self.fast) + self.sma2 = Sma(data, self.slow) + + def _next(self): + if crossover(self.sma1._values, self.sma2._values): + # self.position.close() + self.buy("GOOG", 10) + elif crossover(self.sma2._values, self.sma1._values): + # self.position.close() + self.sell("GOOG", 10) diff --git a/tests/unit/test_backtest.py b/tests/unit/test_backtest.py index 8b3ecea..f1919f6 100644 --- a/tests/unit/test_backtest.py +++ b/tests/unit/test_backtest.py @@ -1,49 +1,16 @@ +from unittest.mock import patch + import pytest -from pytrade.models.indicator import Indicator -from pytrade.models.instruments import CandleSubscription, FxInstrument, Granularity -from pytrade.strategy import FxStrategy from pytradebacktest.backtest import Backtest - -BACKTEST_INSTRUMENT = FxInstrument.EURUSD -BACKTEST_GRANULARITY = Granularity.M5 - - -class BacktestIndicator(Indicator): - - def _run(self, *args, **kwargs): - return self._data.Open > self._data.Close - - -class BacktestStrategy(FxStrategy): - - @property - def subscriptions(self) -> list[CandleSubscription]: - """ - Declare the `InstrumentSubscription`s this strategy should use - for its signals - """ - return [CandleSubscription(BACKTEST_INSTRUMENT, BACKTEST_GRANULARITY)] - - def _init(self) -> None: - """ - Create indicators to be used for signals in the `_next` method. - """ - data = self.get_data(BACKTEST_INSTRUMENT, BACKTEST_GRANULARITY) - self.test_indicator = BacktestIndicator(data) - - def _next(self) -> None: - """ - Evaluate indicators and submit orders to the broker - """ - if self.test_indicator: - self.sell(1) - else: - self.buy(1) +from tests.unit.resources.indicators import SmaCross +@patch("pytradebacktest.backtest.BacktestBroker.order") @pytest.mark.asyncio -async def test_backtest_increments_indicator(test_fx_universe): +async def test_backtest_trade_count(mock_order, test_stock_universe): - test = Backtest(test_fx_universe, BacktestStrategy, 10000) + test = Backtest(test_stock_universe, SmaCross, 10000) await test.run() + + assert mock_order.call_count == 66 diff --git a/tests/unit/test_backtest_broker.py b/tests/unit/test_backtest_broker.py new file mode 100644 index 0000000..40d90b0 --- /dev/null +++ b/tests/unit/test_backtest_broker.py @@ -0,0 +1,335 @@ +import pytest +from pytrade.broker import Order +from pytrade.instruments import Granularity + +from pytradebacktest.broker import BacktestBroker +from pytradebacktest.data import MarketData +from pytradebacktest.exceptions import OutOfMoneyError + + +@pytest.mark.parametrize("iterations", [1, 10, 50, 75, 100]) +def test_fill_market_order(iterations, test_stock_universe: MarketData): + + goog_data = test_stock_universe.get("GOOG", Granularity.D1).df.copy() + broker = BacktestBroker(test_stock_universe, 100000, 0, 1, False, False, False) + + for _ in range(iterations): + test_stock_universe.next() + + broker.order(Order("GOOG", 100)) + + broker.next() + + assert len(broker.orders) == 0 + assert len(broker.trades) == 1 + trade = broker.trades[0] + assert trade.entry_price == goog_data.Open.iloc[iterations - 1] + + +def test_market_order_not_enough_equity(test_stock_universe: MarketData): + + broker = BacktestBroker(test_stock_universe, 100, 0, 1, False, False, False) + + test_stock_universe.next() + broker.order(Order("GOOG", 1000)) + broker.next() + + assert len(broker.orders) == 0 + assert len(broker.trades) == 0 + + +@pytest.mark.parametrize("price_index", [1, 10, 50, 75, 100]) +@pytest.mark.parametrize("buy", [True, False]) +def test_stop_order_conversion(price_index, buy, test_stock_universe: MarketData): + goog_data = test_stock_universe.get("GOOG", Granularity.D1).df.copy() + broker = BacktestBroker(test_stock_universe, 100000, 0, 1, False, False, False) + + price_timestamp = ( + goog_data[:price_index].High.idxmax() + if buy + else goog_data[:price_index].Low.idxmin() + ) + price_idx = goog_data.index.get_loc(price_timestamp) + price = goog_data.High.iloc[price_idx] if buy else goog_data.Low.iloc[price_idx] + stop = price - 0.01 if buy else price + 0.01 # Set to 1 cent past price + size = 100 if buy else -100 + broker.order(Order("GOOG", size, stop=stop)) + + for i in range(price_idx): + test_stock_universe.next() + assert len(broker.orders) == 1 + assert len(broker.trades) == 0 + assert broker.orders[0].stop == stop + broker.next() + + # Perform one more iteration + test_stock_universe.next() + broker.next() + + # Should have executed on the next iteration + assert len(broker.orders) == 0 + assert len(broker.trades) == 1 + trade = broker.trades[0] + assert trade.entry_price == stop + + +@pytest.mark.parametrize("price_index", [1, 10, 50, 75, 100]) +@pytest.mark.parametrize("buy", [True, False]) +def test_limit_order_conversion(price_index, buy, test_stock_universe: MarketData): + goog_data = test_stock_universe.get("GOOG", Granularity.D1).df.copy() + broker = BacktestBroker(test_stock_universe, 100000, 0, 1, False, False, False) + + price_timestamp = ( + goog_data[:price_index].Low.idxmin() + if buy + else goog_data[:price_index].High.idxmax() + ) + price_idx = goog_data.index.get_loc(price_timestamp) + price = goog_data.Low.iloc[price_idx] if buy else goog_data.High.iloc[price_idx] + limit = price + 0.01 if buy else price - 0.01 # Set to 1 cent past price + size = 100 if buy else -100 + broker.order(Order("GOOG", size, limit=limit)) + + for i in range(price_idx): + test_stock_universe.next() + assert len(broker.orders) == 1 + assert len(broker.trades) == 0 + assert broker.orders[0].limit == limit + broker.next() + + # Perform one more iteration + test_stock_universe.next() + broker.next() + + # Should have executed on the next iteration + assert len(broker.orders) == 0 + assert len(broker.trades) == 1 + trade = broker.trades[0] + assert trade.entry_price == limit + + +@pytest.mark.parametrize("index", [1, 10, 50, 75, 100]) +@pytest.mark.parametrize("buy", [True, False]) +def test_stop_loss_order(index, buy, test_stock_universe: MarketData): + goog_data = test_stock_universe.get("GOOG", Granularity.D1).df.copy() + broker = BacktestBroker(test_stock_universe, 100000, 0, 1, False, False, False) + + stop_timestmap = ( + goog_data[index:].Low.idxmin() if buy else goog_data[index:].High.idxmax() + ) + stop_idx = goog_data.index.get_loc(stop_timestmap) + stop_price = ( + goog_data.Low.iloc[stop_idx] + 0.01 if buy else goog_data.High.iloc[stop_idx] - 0.01 + ) + size = 100 if buy else -100 + entry_price = goog_data.Open.iloc[index] + + for i in range(index): + test_stock_universe.next() + + # Place market order + assert len(broker.orders) == 0 + assert len(broker.trades) == 0 + broker.order(Order("GOOG", size, stop_loss_on_fill=stop_price)) + test_stock_universe.next() + broker.next() + + assert len(broker.orders) == (1 if stop_idx > index else 0) + assert len(broker.trades) == (1 if stop_idx > index else 0) + + for i in range(index, stop_idx): + assert len(broker.orders) == 1 + assert broker.orders[0].stop == stop_price + assert len(broker.trades) == 1 + test_stock_universe.next() + broker.next() + + # Should have executed on the last iteration + assert len(broker.orders) == 0 + assert len(broker.trades) == 0 + assert len(broker.closed_trades) == 1 + trade = broker.closed_trades[0] + assert trade.entry_price == entry_price + assert trade.exit_price == stop_price + + +@pytest.mark.parametrize("index", [1, 10, 50, 75, 100]) +@pytest.mark.parametrize("buy", [True, False]) +def test_take_profit_order(index, buy, test_stock_universe: MarketData): + goog_data = test_stock_universe.get("GOOG", Granularity.D1).df.copy() + broker = BacktestBroker(test_stock_universe, 100000, 0, 1, False, False, False) + + limit_timestmap = ( + goog_data[index:].High.idxmax() if buy else goog_data[index:].Low.idxmin() + ) + limit_idx = goog_data.index.get_loc(limit_timestmap) + limit_price = ( + goog_data.High.iloc[limit_idx] - 0.01 + if buy + else goog_data.Low.iloc[limit_idx] + 0.01 + ) + size = 100 if buy else -100 + entry_price = goog_data.Open.iloc[index] + + for i in range(index): + test_stock_universe.next() + + # Place market order + assert len(broker.orders) == 0 + assert len(broker.trades) == 0 + broker.order(Order("GOOG", size, take_profit_on_fill=limit_price)) + test_stock_universe.next() + broker.next() + + assert len(broker.orders) == (1 if limit_idx > index else 0) + assert len(broker.trades) == (1 if limit_idx > index else 0) + + for i in range(index, limit_idx): + if len(broker.orders) == 0: + pass + assert len(broker.orders) == 1 + assert broker.orders[0].limit == limit_price + assert len(broker.trades) == 1 + test_stock_universe.next() + if i == 2137: + pass + broker.next() + + # Should have executed on the last iteration + assert len(broker.orders) == 0 + assert len(broker.trades) == 0 + assert len(broker.closed_trades) == 1 + trade = broker.closed_trades[0] + assert trade.entry_price == entry_price + assert trade.exit_price == limit_price + + +def test_negative_equity(test_stock_universe: MarketData): + broker = BacktestBroker(test_stock_universe, 200, 0, 1, False, False, False) + + broker.order(Order("GOOG", -1, stop_loss_on_fill=350)) + + test_stock_universe.next() + broker.next() + + assert len(broker.orders) == 1 + assert len(broker.trades) == 1 + + for _ in range(1, 300): + test_stock_universe.next() + broker.next() + + test_stock_universe.next() + with pytest.raises(OutOfMoneyError): + broker.next() + + assert len(broker.closed_trades) == 1 + assert broker.equity == 0 + assert broker._cash == 0 + + +def test_change_position(test_stock_universe: MarketData): + broker = BacktestBroker(test_stock_universe, 10000, 0, 1, False, False, False) + goog_position = broker.get_position("GOOG") + + broker.order(Order("GOOG", 100)) + test_stock_universe.next() + broker.next() + + assert len(broker.orders) == 0 + assert len(broker.trades) == 1 + + assert goog_position.is_long is True + assert goog_position.size == 100 + assert goog_position.pl == 0 + assert goog_position.pl_pct == 0 + assert len(goog_position.trades) == 1 + + broker.order(Order("GOOG", -200)) + test_stock_universe.next() + broker.next() + + assert goog_position.is_long is False + assert goog_position.size == -200 + assert goog_position.pl == 0 + assert goog_position.pl_pct == 0 + assert len(goog_position.trades) == 1 + + +def test_reduce_position(test_stock_universe: MarketData): + broker = BacktestBroker(test_stock_universe, 10000, 0, 1, False, False, False) + goog_position = broker.get_position("GOOG") + + broker.order(Order("GOOG", 100)) + test_stock_universe.next() + broker.next() + + assert len(broker.orders) == 0 + assert len(broker.trades) == 1 + + assert goog_position.is_long is True + assert goog_position.size == 100 + assert goog_position.pl == 0 + assert goog_position.pl_pct == 0 + assert len(goog_position.trades) == 1 + + broker.order(Order("GOOG", -50)) + test_stock_universe.next() + broker.next() + + assert goog_position.is_long is True + assert goog_position.size == 50 + assert goog_position.pl == 0 + assert goog_position.pl_pct == 0 + + +def test_close_position(test_stock_universe: MarketData): + broker = BacktestBroker(test_stock_universe, 10000, 0, 1, False, False, False) + goog_position = broker.get_position("GOOG") + + broker.order(Order("GOOG", 100)) + test_stock_universe.next() + broker.next() + + assert len(broker.orders) == 0 + assert len(broker.trades) == 1 + + assert goog_position.is_long is True + assert goog_position.size == 100 + assert goog_position.pl == 0 + assert goog_position.pl_pct == 0 + assert len(goog_position.trades) == 1 + + broker.order(Order("GOOG", -100)) + test_stock_universe.next() + broker.next() + + assert goog_position.is_long is False + assert goog_position.is_short is False + assert goog_position.size == 0 + assert goog_position.pl == 0 + assert goog_position.pl_pct == 0 + + +def test_exclusive_orders(test_stock_universe: MarketData): + broker = BacktestBroker(test_stock_universe, 10000, 0, 1, False, False, True) + broker.order(Order("GOOG", 10)) + test_stock_universe.next() + broker.next() + + assert len(broker.orders) == 0 + assert len(broker.trades) == 1 + + broker.order(Order("GOOG", 20)) + + # 1 to close existing position and then the new order + assert len(broker.orders) == 2 + assert len(broker.trades) == 1 + assert len(broker.closed_trades) == 0 + + test_stock_universe.next() + broker.next() + + assert len(broker.orders) == 0 + assert len(broker.trades) == 1 + assert len(broker.closed_trades) == 1 diff --git a/tests/unit/test_backtest_indicator.py b/tests/unit/test_backtest_indicator.py new file mode 100644 index 0000000..ee53609 --- /dev/null +++ b/tests/unit/test_backtest_indicator.py @@ -0,0 +1,40 @@ +import numpy as np +from pytrade.indicator import Indicator +from pytrade.instruments import FxInstrument, Granularity + +from pytradebacktest.data import MarketData + + +class OpenIndicator(Indicator): + + def _run(self, *args, **kwargs): + return self._data.df.Open + + +def test_indicator_values(data: np.ndarray, indicator: Indicator): + assert len(indicator._values) == len(data) + assert (indicator._values == data).all() + + +def test_indicator_updates(test_fx_universe: MarketData): + + def increment_indicator(self): + if not hasattr(self, "_backtest_values"): + self._backtest_values = self._values.copy() + self._values = self._backtest_values[: len(self._data)] + + Indicator._update = increment_indicator + + data = test_fx_universe.get(FxInstrument.GBPUSD, Granularity.M1) + indicator = OpenIndicator(data) + + data2 = test_fx_universe.get(FxInstrument.GBPUSD, Granularity.M5) + indicator2 = OpenIndicator(data2) + + assert len(data) != len(data2) + + while test_fx_universe.next(): + assert len(indicator._values) == len(data) + assert len(indicator2._values) == len(data2) + assert data.index == test_fx_universe.index + assert data2.index == test_fx_universe.index.floor(freq="5min") diff --git a/tests/unit/test_strategy.py b/tests/unit/test_backtest_strategy.py similarity index 62% rename from tests/unit/test_strategy.py rename to tests/unit/test_backtest_strategy.py index b9ff64f..8ed81b7 100644 --- a/tests/unit/test_strategy.py +++ b/tests/unit/test_backtest_strategy.py @@ -1,14 +1,13 @@ from unittest.mock import patch -import pandas as pd import pytest -from pytrade.models.indicator import Indicator -from pytrade.models.instruments import CandleSubscription, FxInstrument, Granularity +from pytrade.indicator import Indicator +from pytrade.instruments import CandleSubscription, FxInstrument, Granularity +from pytrade.interfaces.data import IInstrumentData from pytrade.strategy import FxStrategy from pytradebacktest.broker import BacktestBroker from pytradebacktest.data import MarketData -from pytradebacktest.strategy import BacktestStrategyWrapper BACKTEST_INSTRUMENT = FxInstrument.EURUSD BACKTEST_GRANULARITY = Granularity.M5 @@ -49,43 +48,56 @@ def _next(self) -> None: Evaluate indicators and submit orders to the broker """ if self.eurusd_m5: - self.sell(1) + self.sell(BACKTEST_INSTRUMENT, 1) else: - self.buy(1) + self.buy(BACKTEST_INSTRUMENT, 1) @pytest.mark.asyncio async def test_strategy_indicator_updates(test_fx_universe: MarketData): - broker = BacktestBroker(test_fx_universe) + broker = BacktestBroker(test_fx_universe, 10000, 0, 1) - strategy = BacktestStrategyWrapper(broker, test_fx_universe, BacktestStrategy) + def increment_indicator(self): + if not hasattr(self, "_backtest_values"): + self._backtest_values = self._values.copy() + self._values = self._backtest_values[: len(self._data)] + + Indicator._update = increment_indicator + + strategy = BacktestStrategy(broker, test_fx_universe) strategy.init() - m1_data: pd.DataFrame = test_fx_universe._sources.get( - (BACKTEST_INSTRUMENT, Granularity.M1) - ) - m5_data: pd.DataFrame = test_fx_universe._sources.get( - (BACKTEST_INSTRUMENT, Granularity.M5) - ) + m1_data: IInstrumentData = test_fx_universe.get( + BACKTEST_INSTRUMENT, Granularity.M1 + ).df.copy() + m5_data: IInstrumentData = test_fx_universe.get( + BACKTEST_INSTRUMENT, Granularity.M5 + ).df.copy() indicator_data = {"eurusd_m1": m1_data, "eurusd_m5": m5_data} expected_indicator_values = { "eurusd_m1": m1_data.Open > m1_data.Close, "eurusd_m5": m5_data.Open > m5_data.Close, } - for attr, indicator in strategy._indicators: + _indicators = { + attr: indicator + for attr, indicator in strategy.__dict__.items() + if isinstance(indicator, Indicator) + }.items() + + for attr, indicator in _indicators: assert len(indicator._values) == len(indicator_data[attr]) while test_fx_universe.next(): - await strategy.next() - for attr, indicator in strategy._indicators: + strategy.next() + for attr, indicator in _indicators: if test_fx_universe.index in indicator._data.df.index: data_i_index = indicator._data.df.index.get_loc(test_fx_universe.index) expected_length = data_i_index + 1 assert len(indicator._values) == expected_length - assert indicator == expected_indicator_values[attr][data_i_index] + assert indicator == expected_indicator_values[attr].iloc[data_i_index] @patch("pytrade.strategy.FxStrategy.sell") @@ -95,17 +107,24 @@ async def test_strategy_indicator_orders( mock_buy, mock_sell, test_fx_universe: MarketData ): - broker = BacktestBroker(test_fx_universe) + broker = BacktestBroker(test_fx_universe, 10000, 0, 1) + + def increment_indicator(self): + if not hasattr(self, "_backtest_values"): + self._backtest_values = self._values.copy() + self._values = self._backtest_values[: len(self._data)] + + Indicator._update = increment_indicator - strategy = BacktestStrategyWrapper(broker, test_fx_universe, BacktestStrategy) + strategy = BacktestStrategy(broker, test_fx_universe) strategy.init() - test_data: pd.DataFrame = test_fx_universe._sources.get( - (BACKTEST_INSTRUMENT, BACKTEST_GRANULARITY) - ) + test_data = test_fx_universe.get( + BACKTEST_INSTRUMENT, BACKTEST_GRANULARITY + ).df.copy() while test_fx_universe.next(): - await strategy.next() + strategy.next() expected_buy_calls = test_data[test_data.Open <= test_data.Close].count().Open expected_sell_calls = test_data[test_data.Open > test_data.Close].count().Open diff --git a/tests/unit/test_data.py b/tests/unit/test_data.py index fc5d1a5..317701a 100644 --- a/tests/unit/test_data.py +++ b/tests/unit/test_data.py @@ -1,4 +1,4 @@ -from datetime import datetime, timedelta +from datetime import datetime from pytradebacktest.data import MarketData @@ -8,16 +8,15 @@ def test_load_market_data(test_fx_universe): assert len(data._sources) == 8 -def test_init_timeframe(test_fx_universe): +def test_init_index(test_fx_universe): data: MarketData = test_fx_universe - assert data._index == datetime(2024, 4, 30, 23, 59) - assert data._granularity == timedelta(minutes=1) + assert data._index == datetime(2024, 5, 1) def test_fx_length(test_fx_universe): - assert len(test_fx_universe) == 44459 + assert len(test_fx_universe) == 32940 def test_stock_length(test_stock_universe): - assert len(test_stock_universe) == 3116 + assert len(test_stock_universe) == 2148 diff --git a/tests/unit/test_indicator.py b/tests/unit/test_indicator.py deleted file mode 100644 index 1d847e6..0000000 --- a/tests/unit/test_indicator.py +++ /dev/null @@ -1,15 +0,0 @@ -import numpy as np -from pytrade.models.indicator import Indicator - -from pytradebacktest.data import MarketData - - -def test_indicator_values(data: np.ndarray, indicator: Indicator): - assert len(indicator._values) == len(data) - assert (indicator._values == data).all() - - -def test_indicator_updates(test_fx_universe: MarketData, indicator: Indicator): - - while test_fx_universe.next(): - pass