investing-algorithm-framework 4.1.0__tar.gz → 5.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/PKG-INFO +20 -11
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/README.md +17 -9
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/__init__.py +4 -2
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/algorithm.py +262 -21
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/app.py +271 -365
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/strategy.py +76 -15
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/dependency_container.py +27 -24
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/__init__.py +8 -3
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/constants.py +3 -3
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/__init__.py +2 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/backtesting/backtest_report.py +4 -1
- investing_algorithm_framework-5.0.0/investing_algorithm_framework/domain/models/market_data_type.py +46 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/order/order.py +4 -66
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/order/order_status.py +1 -1
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/time_frame.py +21 -0
- investing_algorithm_framework-5.0.0/investing_algorithm_framework/domain/models/trade/trade.py +296 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/trade/trade_status.py +1 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/services/market_data_sources.py +47 -16
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/services/market_service.py +1 -1
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/backtesting.py +61 -6
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/polars.py +4 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/indicators/trend.py +14 -2
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/__init__.py +5 -3
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/__init__.py +2 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py +54 -105
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/csv.py +69 -62
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/pandas.py +6 -44
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/order/order.py +19 -30
- investing_algorithm_framework-5.0.0/investing_algorithm_framework/infrastructure/models/order_trade_association.py +10 -0
- investing_algorithm_framework-5.0.0/investing_algorithm_framework/infrastructure/models/trade.py +106 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/repositories/__init__.py +2 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/repositories/position_repository.py +7 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/repositories/repository.py +3 -0
- investing_algorithm_framework-5.0.0/investing_algorithm_framework/infrastructure/repositories/trade_repository.py +71 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/performance_service/performance_service.py +35 -67
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/__init__.py +1 -5
- investing_algorithm_framework-5.0.0/investing_algorithm_framework/services/backtesting/__init__.py +5 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/backtesting/backtest_service.py +129 -12
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/configuration_service.py +8 -3
- investing_algorithm_framework-5.0.0/investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +207 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/market_data_source_service/market_data_source_service.py +149 -17
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/order_service/order_backtest_service.py +26 -56
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/order_service/order_service.py +42 -115
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/portfolios/portfolio_sync_service.py +8 -39
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/strategy_orchestrator_service.py +31 -18
- investing_algorithm_framework-5.0.0/investing_algorithm_framework/services/trade_service/trade_service.py +347 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/pyproject.toml +2 -2
- investing_algorithm_framework-4.1.0/investing_algorithm_framework/domain/models/trade/trade.py +0 -287
- investing_algorithm_framework-4.1.0/investing_algorithm_framework/services/backtesting/__init__.py +0 -12
- investing_algorithm_framework-4.1.0/investing_algorithm_framework/services/backtesting/backtest_report_writer_service.py +0 -91
- investing_algorithm_framework-4.1.0/investing_algorithm_framework/services/backtesting/graphs.py +0 -61
- investing_algorithm_framework-4.1.0/investing_algorithm_framework/services/market_data_source_service/backtest_market_data_source_service.py +0 -149
- investing_algorithm_framework-4.1.0/investing_algorithm_framework/services/trade_service/trade_service.py +0 -401
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/LICENSE +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/stateless/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/stateless/action_handlers/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/stateless/action_handlers/action_handler_strategy.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/stateless/action_handlers/check_online_handler.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/stateless/action_handlers/run_strategy_handler.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/stateless/exception_handler.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/task.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/controllers/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/controllers/orders.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/controllers/portfolio.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/controllers/positions.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/create_app.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/error_handler.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/responses.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/run_strategies.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/schemas/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/schemas/order.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/schemas/portfolio.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/schemas/position.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/app/web/setup_cors.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/create_azure_function_app_skeleton.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/deploy_to_azure_function.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/templates/azure_function_framework_app.py.template +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/templates/azure_function_function_app.py.template +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/templates/azure_function_host.json.template +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/templates/azure_function_local.settings.json.template +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/cli/templates/azure_function_requirements.txt.template +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/create_app.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/config.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/data_structures.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/decimal_parsing.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/exceptions.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/metrics/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/metrics/price_efficiency.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/app_mode.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/backtesting/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/backtesting/backtest_date_range.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/backtesting/backtest_position.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/backtesting/backtest_reports_evaluation.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/base_model.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/date_range.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/market/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/market/market_credential.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/order/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/order/order_side.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/order/order_type.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/portfolio/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/portfolio/portfolio.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/portfolio/portfolio_configuration.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/portfolio/portfolio_snapshot.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/position/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/position/position.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/position/position_snapshot.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/strategy_profile.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/time_interval.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/time_unit.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/tracing/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/tracing/trace.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/trade/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/trading_data_types.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/models/trading_time_frame.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/services/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/services/market_credential_service.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/services/portfolios/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/services/portfolios/portfolio_sync_service.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/services/rounding_service.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/singleton.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/stateless_actions.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/strategy.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/csv.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/random.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/signatures.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/stoppable_thread.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/domain/utils/synchronized.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/indicators/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/indicators/advanced.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/indicators/momentum.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/indicators/utils.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/database/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/database/sql_alchemy.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/decimal_parser.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/market_data_sources/us_treasury_yield.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/model_extension.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/order/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/portfolio/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/portfolio/portfolio_snapshot.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/portfolio/sql_portfolio.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/position/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/position/position.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/models/position/position_snapshot.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/repositories/order_repository.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/repositories/portfolio_repository.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/repositories/portfolio_snapshot_repository.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/repositories/position_snapshot_repository.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/azure/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/azure/state_handler.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/market_service/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/market_service/ccxt_market_service.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/performance_service/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/infrastructure/services/performance_service/backtest_performance_service.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/market_credential_service.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/market_data_source_service/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/order_service/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/portfolios/__init__.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/portfolios/backtest_portfolio_service.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/portfolios/portfolio_configuration_service.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/portfolios/portfolio_service.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/portfolios/portfolio_snapshot_service.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/position_service.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/position_snapshot_service.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/repository_service.py +0 -0
- {investing_algorithm_framework-4.1.0 → investing_algorithm_framework-5.0.0}/investing_algorithm_framework/services/trade_service/__init__.py +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: investing-algorithm-framework
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.0.0
|
|
4
4
|
Summary: A framework for creating trading bots
|
|
5
5
|
Author: MDUYN
|
|
6
|
-
Requires-Python: >=3.
|
|
6
|
+
Requires-Python: >=3.9
|
|
7
7
|
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
8
9
|
Classifier: Programming Language :: Python :: 3.10
|
|
9
10
|
Classifier: Programming Language :: Python :: 3.11
|
|
10
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -74,7 +75,8 @@ Features:
|
|
|
74
75
|
The following algorithm connects to binance and buys BTC every 5 seconds. It also exposes an REST API that allows you to interact with the algorithm.
|
|
75
76
|
|
|
76
77
|
```python
|
|
77
|
-
import logging
|
|
78
|
+
import logging.config
|
|
79
|
+
|
|
78
80
|
from investing_algorithm_framework import create_app, PortfolioConfiguration, \
|
|
79
81
|
TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
|
|
80
82
|
CCXTTickerMarketDataSource, MarketCredential, DEFAULT_LOGGING_CONFIG
|
|
@@ -96,7 +98,6 @@ bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
|
|
|
96
98
|
symbol="BTC/EUR",
|
|
97
99
|
)
|
|
98
100
|
app = create_app()
|
|
99
|
-
algorithm = Algorithm()
|
|
100
101
|
# Bitvavo market credentials are read from .env file
|
|
101
102
|
app.add_market_credential(MarketCredential(market="bitvavo"))
|
|
102
103
|
app.add_portfolio_configuration(
|
|
@@ -106,10 +107,9 @@ app.add_portfolio_configuration(
|
|
|
106
107
|
initial_balance=400
|
|
107
108
|
)
|
|
108
109
|
)
|
|
109
|
-
app.add_algorithm(algorithm)
|
|
110
110
|
|
|
111
111
|
# Run every two hours and register the data sources
|
|
112
|
-
@
|
|
112
|
+
@app.strategy(
|
|
113
113
|
time_unit=TimeUnit.HOUR,
|
|
114
114
|
interval=2,
|
|
115
115
|
market_data_sources=[bitvavo_btc_eur_ticker, bitvavo_btc_eur_ohlcv_2h]
|
|
@@ -117,7 +117,6 @@ app.add_algorithm(algorithm)
|
|
|
117
117
|
def perform_strategy(algorithm: Algorithm, market_data: dict):
|
|
118
118
|
# Access the data sources with the indentifier
|
|
119
119
|
polars_df = market_data["BTC-ohlcv"]
|
|
120
|
-
|
|
121
120
|
# Convert the polars dataframe to a pandas dataframe
|
|
122
121
|
pandas_df = polars_df.to_pandas()
|
|
123
122
|
ticker_data = market_data["BTC-ticker"]
|
|
@@ -128,18 +127,21 @@ def perform_strategy(algorithm: Algorithm, market_data: dict):
|
|
|
128
127
|
closed_trades = algorithm.get_closed_trades()
|
|
129
128
|
|
|
130
129
|
# Create a buy oder
|
|
131
|
-
algorithm.create_limit_order(
|
|
130
|
+
order = algorithm.create_limit_order(
|
|
132
131
|
target_symbol="BTC/EUR",
|
|
133
132
|
order_side="buy",
|
|
134
133
|
amount=0.01,
|
|
135
134
|
price=ticker_data["ask"],
|
|
136
135
|
)
|
|
136
|
+
trade = algorithm.get_trade(order_id=order.id)
|
|
137
|
+
algorithm.add_trailing_stop_loss(trade=trade, percentage=5)
|
|
137
138
|
|
|
138
139
|
# Close a trade
|
|
139
|
-
algorithm.close_trade(
|
|
140
|
+
algorithm.close_trade(trade=trade)
|
|
140
141
|
|
|
141
142
|
# Close a position
|
|
142
|
-
algorithm.
|
|
143
|
+
position = algorithm.get_position(symbol="BTC/EUR")
|
|
144
|
+
algorithm.close_position(position)
|
|
143
145
|
|
|
144
146
|
if __name__ == "__main__":
|
|
145
147
|
app.run()
|
|
@@ -151,7 +153,14 @@ if __name__ == "__main__":
|
|
|
151
153
|
|
|
152
154
|
The framework also supports backtesting and performing backtest experiments. After a backtest, you can print a report that shows the performance of your trading bot.
|
|
153
155
|
|
|
154
|
-
To run a single backtest you can use the example code that can be found [here](./examples/
|
|
156
|
+
To run a single backtest you can use the example code that can be found [here](./examples/backtest_example). Simply run:
|
|
157
|
+
|
|
158
|
+
> Its assumed here that you have cloned the repository, installed the framework and
|
|
159
|
+
> are in the root of the project.
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
python examples/backtest_example/run_backtest.py
|
|
163
|
+
```
|
|
155
164
|
|
|
156
165
|
### Backtesting report
|
|
157
166
|
|
|
@@ -37,7 +37,8 @@ Features:
|
|
|
37
37
|
The following algorithm connects to binance and buys BTC every 5 seconds. It also exposes an REST API that allows you to interact with the algorithm.
|
|
38
38
|
|
|
39
39
|
```python
|
|
40
|
-
import logging
|
|
40
|
+
import logging.config
|
|
41
|
+
|
|
41
42
|
from investing_algorithm_framework import create_app, PortfolioConfiguration, \
|
|
42
43
|
TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
|
|
43
44
|
CCXTTickerMarketDataSource, MarketCredential, DEFAULT_LOGGING_CONFIG
|
|
@@ -59,7 +60,6 @@ bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
|
|
|
59
60
|
symbol="BTC/EUR",
|
|
60
61
|
)
|
|
61
62
|
app = create_app()
|
|
62
|
-
algorithm = Algorithm()
|
|
63
63
|
# Bitvavo market credentials are read from .env file
|
|
64
64
|
app.add_market_credential(MarketCredential(market="bitvavo"))
|
|
65
65
|
app.add_portfolio_configuration(
|
|
@@ -69,10 +69,9 @@ app.add_portfolio_configuration(
|
|
|
69
69
|
initial_balance=400
|
|
70
70
|
)
|
|
71
71
|
)
|
|
72
|
-
app.add_algorithm(algorithm)
|
|
73
72
|
|
|
74
73
|
# Run every two hours and register the data sources
|
|
75
|
-
@
|
|
74
|
+
@app.strategy(
|
|
76
75
|
time_unit=TimeUnit.HOUR,
|
|
77
76
|
interval=2,
|
|
78
77
|
market_data_sources=[bitvavo_btc_eur_ticker, bitvavo_btc_eur_ohlcv_2h]
|
|
@@ -80,7 +79,6 @@ app.add_algorithm(algorithm)
|
|
|
80
79
|
def perform_strategy(algorithm: Algorithm, market_data: dict):
|
|
81
80
|
# Access the data sources with the indentifier
|
|
82
81
|
polars_df = market_data["BTC-ohlcv"]
|
|
83
|
-
|
|
84
82
|
# Convert the polars dataframe to a pandas dataframe
|
|
85
83
|
pandas_df = polars_df.to_pandas()
|
|
86
84
|
ticker_data = market_data["BTC-ticker"]
|
|
@@ -91,18 +89,21 @@ def perform_strategy(algorithm: Algorithm, market_data: dict):
|
|
|
91
89
|
closed_trades = algorithm.get_closed_trades()
|
|
92
90
|
|
|
93
91
|
# Create a buy oder
|
|
94
|
-
algorithm.create_limit_order(
|
|
92
|
+
order = algorithm.create_limit_order(
|
|
95
93
|
target_symbol="BTC/EUR",
|
|
96
94
|
order_side="buy",
|
|
97
95
|
amount=0.01,
|
|
98
96
|
price=ticker_data["ask"],
|
|
99
97
|
)
|
|
98
|
+
trade = algorithm.get_trade(order_id=order.id)
|
|
99
|
+
algorithm.add_trailing_stop_loss(trade=trade, percentage=5)
|
|
100
100
|
|
|
101
101
|
# Close a trade
|
|
102
|
-
algorithm.close_trade(
|
|
102
|
+
algorithm.close_trade(trade=trade)
|
|
103
103
|
|
|
104
104
|
# Close a position
|
|
105
|
-
algorithm.
|
|
105
|
+
position = algorithm.get_position(symbol="BTC/EUR")
|
|
106
|
+
algorithm.close_position(position)
|
|
106
107
|
|
|
107
108
|
if __name__ == "__main__":
|
|
108
109
|
app.run()
|
|
@@ -114,7 +115,14 @@ if __name__ == "__main__":
|
|
|
114
115
|
|
|
115
116
|
The framework also supports backtesting and performing backtest experiments. After a backtest, you can print a report that shows the performance of your trading bot.
|
|
116
117
|
|
|
117
|
-
To run a single backtest you can use the example code that can be found [here](./examples/
|
|
118
|
+
To run a single backtest you can use the example code that can be found [here](./examples/backtest_example). Simply run:
|
|
119
|
+
|
|
120
|
+
> Its assumed here that you have cloned the repository, installed the framework and
|
|
121
|
+
> are in the root of the project.
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
python examples/backtest_example/run_backtest.py
|
|
125
|
+
```
|
|
118
126
|
|
|
119
127
|
### Backtesting report
|
|
120
128
|
|
|
@@ -12,7 +12,7 @@ from investing_algorithm_framework.domain import ApiException, \
|
|
|
12
12
|
RESERVED_BALANCES, APP_MODE, AppMode, DATETIME_FORMAT, \
|
|
13
13
|
load_backtest_report, BacktestDateRange, convert_polars_to_pandas, \
|
|
14
14
|
DateRange, get_backtest_report, DEFAULT_LOGGING_CONFIG, \
|
|
15
|
-
BacktestReport
|
|
15
|
+
BacktestReport, TradeStatus, MarketDataType
|
|
16
16
|
from investing_algorithm_framework.infrastructure import \
|
|
17
17
|
CCXTOrderBookMarketDataSource, CCXTOHLCVMarketDataSource, \
|
|
18
18
|
CCXTTickerMarketDataSource, CSVOHLCVMarketDataSource, \
|
|
@@ -90,5 +90,7 @@ __all__ = [
|
|
|
90
90
|
"get_backtest_report",
|
|
91
91
|
"AzureBlobStorageStateHandler",
|
|
92
92
|
"DEFAULT_LOGGING_CONFIG",
|
|
93
|
-
"BacktestReport"
|
|
93
|
+
"BacktestReport",
|
|
94
|
+
"TradeStatus",
|
|
95
|
+
"MarketDataType"
|
|
94
96
|
]
|
|
@@ -4,7 +4,7 @@ from typing import List, Dict
|
|
|
4
4
|
import re
|
|
5
5
|
|
|
6
6
|
from investing_algorithm_framework.domain import OrderStatus, \
|
|
7
|
-
Position, Order, Portfolio, OrderType, OrderSide, \
|
|
7
|
+
Position, Order, Portfolio, OrderType, OrderSide, TradeStatus, \
|
|
8
8
|
BACKTESTING_FLAG, BACKTESTING_INDEX_DATETIME, MarketService, TimeUnit, \
|
|
9
9
|
OperationalException, random_string, RoundingService, Trade
|
|
10
10
|
from investing_algorithm_framework.services import MarketCredentialService, \
|
|
@@ -61,7 +61,7 @@ class Algorithm:
|
|
|
61
61
|
self.market_service: MarketService
|
|
62
62
|
self.configuration_service: ConfigurationService
|
|
63
63
|
self.portfolio_configuration_service: PortfolioConfigurationService
|
|
64
|
-
self.strategy_orchestrator_service: StrategyOrchestratorService
|
|
64
|
+
self.strategy_orchestrator_service: StrategyOrchestratorService = None
|
|
65
65
|
self._data_sources = {}
|
|
66
66
|
self._strategies = []
|
|
67
67
|
self._market_credential_service: MarketCredentialService
|
|
@@ -94,12 +94,21 @@ class Algorithm:
|
|
|
94
94
|
)
|
|
95
95
|
|
|
96
96
|
pattern = re.compile(r"^[a-zA-Z0-9]*$")
|
|
97
|
+
|
|
97
98
|
if not pattern.match(name):
|
|
98
99
|
raise OperationalException(
|
|
99
100
|
"The name of the algorithm can only contain" +
|
|
100
101
|
" letters and numbers"
|
|
101
102
|
)
|
|
102
103
|
|
|
104
|
+
illegal_chars = r"[\/:*?\"<>|]"
|
|
105
|
+
|
|
106
|
+
if re.search(illegal_chars, name):
|
|
107
|
+
raise OperationalException(
|
|
108
|
+
f"Illegal characters detected in algorithm: {name}. "
|
|
109
|
+
f"Illegal characters: / \\ : * ? \" < > |"
|
|
110
|
+
)
|
|
111
|
+
|
|
103
112
|
def initialize_services(
|
|
104
113
|
self,
|
|
105
114
|
configuration_service,
|
|
@@ -155,10 +164,28 @@ class Algorithm:
|
|
|
155
164
|
number_of_iterations=number_of_iterations
|
|
156
165
|
)
|
|
157
166
|
|
|
167
|
+
def stop(self) -> None:
|
|
168
|
+
"""
|
|
169
|
+
Function to stop the algorithm. This function will stop the
|
|
170
|
+
algorithm by stopping all jobs in the strategy orchestrator
|
|
171
|
+
service.
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
None
|
|
175
|
+
"""
|
|
176
|
+
|
|
177
|
+
if self.strategy_orchestrator_service is not None:
|
|
178
|
+
self.strategy_orchestrator_service.stop()
|
|
179
|
+
|
|
158
180
|
@property
|
|
159
181
|
def name(self):
|
|
160
182
|
return self._name
|
|
161
183
|
|
|
184
|
+
@name.setter
|
|
185
|
+
def name(self, name):
|
|
186
|
+
self._validate_name(name)
|
|
187
|
+
self._name = name
|
|
188
|
+
|
|
162
189
|
@property
|
|
163
190
|
def data_sources(self):
|
|
164
191
|
return self._data_sources
|
|
@@ -172,6 +199,14 @@ class Algorithm:
|
|
|
172
199
|
"""
|
|
173
200
|
return self.configuration_service.get_config()
|
|
174
201
|
|
|
202
|
+
def get_config(self):
|
|
203
|
+
"""
|
|
204
|
+
Function to get a config instance. This allows users when
|
|
205
|
+
having access to the algorithm instance also to read the
|
|
206
|
+
configs of the app.
|
|
207
|
+
"""
|
|
208
|
+
return self.configuration_service.get_config()
|
|
209
|
+
|
|
175
210
|
@property
|
|
176
211
|
def description(self):
|
|
177
212
|
"""
|
|
@@ -315,7 +350,7 @@ class Algorithm:
|
|
|
315
350
|
order and execute it if the execute parameter is set to True. If the
|
|
316
351
|
validate parameter is set to True, the order will be validated
|
|
317
352
|
|
|
318
|
-
|
|
353
|
+
Args:
|
|
319
354
|
target_symbol: The symbol of the asset to trade
|
|
320
355
|
price: The price of the asset
|
|
321
356
|
order_side: The side of the order
|
|
@@ -476,7 +511,7 @@ class Algorithm:
|
|
|
476
511
|
"""
|
|
477
512
|
|
|
478
513
|
if market is None:
|
|
479
|
-
return self.portfolio_service.
|
|
514
|
+
return self.portfolio_service.get_all()[0]
|
|
480
515
|
|
|
481
516
|
return self.portfolio_service.find({{"market": market}})
|
|
482
517
|
|
|
@@ -497,7 +532,7 @@ class Algorithm:
|
|
|
497
532
|
If the market parameter is specified, the unallocated balance
|
|
498
533
|
of the specified market will be returned.
|
|
499
534
|
|
|
500
|
-
|
|
535
|
+
Args:
|
|
501
536
|
market: The market of the portfolio
|
|
502
537
|
|
|
503
538
|
Returns:
|
|
@@ -507,7 +542,7 @@ class Algorithm:
|
|
|
507
542
|
if market:
|
|
508
543
|
portfolio = self.portfolio_service.find({{"market": market}})
|
|
509
544
|
else:
|
|
510
|
-
portfolio = self.portfolio_service.
|
|
545
|
+
portfolio = self.portfolio_service.get_all()[0]
|
|
511
546
|
|
|
512
547
|
trading_symbol = portfolio.trading_symbol
|
|
513
548
|
return self.position_service.find(
|
|
@@ -539,6 +574,19 @@ class Algorithm:
|
|
|
539
574
|
order_side=None,
|
|
540
575
|
order_type=None
|
|
541
576
|
) -> Order:
|
|
577
|
+
"""
|
|
578
|
+
Function to retrieve an order.
|
|
579
|
+
|
|
580
|
+
Exception is thrown when no param has been provided.
|
|
581
|
+
|
|
582
|
+
Args:
|
|
583
|
+
reference_id [optional] (int): id given by the external
|
|
584
|
+
market or exchange.
|
|
585
|
+
market [optional] (str): the market that the order was
|
|
586
|
+
executed on.
|
|
587
|
+
target_symbol [optional] (str): the symbol of the asset
|
|
588
|
+
that the order was executed
|
|
589
|
+
"""
|
|
542
590
|
query_params = {}
|
|
543
591
|
|
|
544
592
|
if reference_id:
|
|
@@ -563,6 +611,11 @@ class Algorithm:
|
|
|
563
611
|
)
|
|
564
612
|
query_params["position"] = [position.id for position in positions]
|
|
565
613
|
|
|
614
|
+
if not query_params:
|
|
615
|
+
raise OperationalException(
|
|
616
|
+
"No parameters provided to get order."
|
|
617
|
+
)
|
|
618
|
+
|
|
566
619
|
return self.order_service.find(query_params)
|
|
567
620
|
|
|
568
621
|
def get_orders(
|
|
@@ -1169,25 +1222,95 @@ class Algorithm:
|
|
|
1169
1222
|
query_params["status"] = OrderStatus.OPEN.value
|
|
1170
1223
|
return self.order_service.exists(query_params)
|
|
1171
1224
|
|
|
1172
|
-
def
|
|
1225
|
+
def get_trade(
|
|
1226
|
+
self,
|
|
1227
|
+
target_symbol=None,
|
|
1228
|
+
trading_symbol=None,
|
|
1229
|
+
market=None,
|
|
1230
|
+
portfolio=None,
|
|
1231
|
+
status=None,
|
|
1232
|
+
order_id=None
|
|
1233
|
+
) -> List[Trade]:
|
|
1173
1234
|
"""
|
|
1174
|
-
Function to
|
|
1235
|
+
Function to get all trades. This function will return all trades
|
|
1236
|
+
that match the specified query parameters. If the market parameter
|
|
1237
|
+
is specified, the trades with the specified market will be returned.
|
|
1238
|
+
|
|
1239
|
+
Args:
|
|
1240
|
+
market: The market of the asset
|
|
1241
|
+
portfolio: The portfolio of the asset
|
|
1242
|
+
status: The status of the trade
|
|
1243
|
+
order_id: The order id of the trade
|
|
1244
|
+
target_symbol: The symbol of the asset
|
|
1245
|
+
trading_symbol: The trading symbol of the asset
|
|
1246
|
+
|
|
1247
|
+
Returns:
|
|
1248
|
+
List[Trade]: A list of trades that match the query parameters
|
|
1175
1249
|
"""
|
|
1176
|
-
|
|
1250
|
+
query_params = {}
|
|
1251
|
+
|
|
1252
|
+
if market is not None:
|
|
1253
|
+
query_params["market"] = market
|
|
1254
|
+
|
|
1255
|
+
if portfolio is not None:
|
|
1256
|
+
query_params["portfolio"] = portfolio
|
|
1257
|
+
|
|
1258
|
+
if status is not None:
|
|
1259
|
+
query_params["status"] = status
|
|
1260
|
+
|
|
1261
|
+
if order_id is not None:
|
|
1262
|
+
query_params["order_id"] = order_id
|
|
1263
|
+
|
|
1264
|
+
if target_symbol is not None:
|
|
1265
|
+
query_params["target_symbol"] = target_symbol
|
|
1266
|
+
|
|
1267
|
+
if trading_symbol is not None:
|
|
1268
|
+
query_params["trading_symbol"] = trading_symbol
|
|
1269
|
+
|
|
1270
|
+
return self.trade_service.find(query_params)
|
|
1177
1271
|
|
|
1178
|
-
def get_trades(
|
|
1272
|
+
def get_trades(
|
|
1273
|
+
self,
|
|
1274
|
+
target_symbol=None,
|
|
1275
|
+
trading_symbol=None,
|
|
1276
|
+
market=None,
|
|
1277
|
+
portfolio=None,
|
|
1278
|
+
status=None,
|
|
1279
|
+
) -> List[Trade]:
|
|
1179
1280
|
"""
|
|
1180
1281
|
Function to get all trades. This function will return all trades
|
|
1181
1282
|
that match the specified query parameters. If the market parameter
|
|
1182
1283
|
is specified, the trades with the specified market will be returned.
|
|
1183
1284
|
|
|
1184
|
-
|
|
1285
|
+
Args:
|
|
1185
1286
|
market: The market of the asset
|
|
1287
|
+
portfolio: The portfolio of the asset
|
|
1288
|
+
status: The status of the trade
|
|
1289
|
+
target_symbol: The symbol of the asset
|
|
1290
|
+
trading_symbol: The trading symbol of the asset
|
|
1186
1291
|
|
|
1187
1292
|
Returns:
|
|
1188
1293
|
List[Trade]: A list of trades that match the query parameters
|
|
1189
1294
|
"""
|
|
1190
|
-
|
|
1295
|
+
|
|
1296
|
+
query_params = {}
|
|
1297
|
+
|
|
1298
|
+
if market is not None:
|
|
1299
|
+
query_params["market"] = market
|
|
1300
|
+
|
|
1301
|
+
if portfolio is not None:
|
|
1302
|
+
query_params["portfolio"] = portfolio
|
|
1303
|
+
|
|
1304
|
+
if status is not None:
|
|
1305
|
+
query_params["status"] = status
|
|
1306
|
+
|
|
1307
|
+
if target_symbol is not None:
|
|
1308
|
+
query_params["target_symbol"] = target_symbol
|
|
1309
|
+
|
|
1310
|
+
if trading_symbol is not None:
|
|
1311
|
+
query_params["trading_symbol"] = trading_symbol
|
|
1312
|
+
|
|
1313
|
+
return self.trade_service.get_all({"market": market})
|
|
1191
1314
|
|
|
1192
1315
|
def get_closed_trades(self) -> List[Trade]:
|
|
1193
1316
|
"""
|
|
@@ -1197,7 +1320,44 @@ class Algorithm:
|
|
|
1197
1320
|
Returns:
|
|
1198
1321
|
List[Trade]: A list of closed trades
|
|
1199
1322
|
"""
|
|
1200
|
-
return self.trade_service.
|
|
1323
|
+
return self.trade_service.get_all({"status": TradeStatus.CLOSED.value})
|
|
1324
|
+
|
|
1325
|
+
def count_trades(
|
|
1326
|
+
self,
|
|
1327
|
+
target_symbol=None,
|
|
1328
|
+
trading_symbol=None,
|
|
1329
|
+
market=None,
|
|
1330
|
+
portfolio=None
|
|
1331
|
+
) -> int:
|
|
1332
|
+
"""
|
|
1333
|
+
Function to count trades. This function will return the number of
|
|
1334
|
+
trades that match the specified query parameters.
|
|
1335
|
+
|
|
1336
|
+
Args:
|
|
1337
|
+
target_symbol: The symbol of the asset
|
|
1338
|
+
trading_symbol: The trading symbol of the asset
|
|
1339
|
+
market: The market of the asset
|
|
1340
|
+
portfolio: The portfolio of the asset
|
|
1341
|
+
|
|
1342
|
+
Returns:
|
|
1343
|
+
int: The number of trades that match the query parameters
|
|
1344
|
+
"""
|
|
1345
|
+
|
|
1346
|
+
query_params = {}
|
|
1347
|
+
|
|
1348
|
+
if market is not None:
|
|
1349
|
+
query_params["market"] = market
|
|
1350
|
+
|
|
1351
|
+
if portfolio is not None:
|
|
1352
|
+
query_params["portfolio"] = portfolio
|
|
1353
|
+
|
|
1354
|
+
if target_symbol is not None:
|
|
1355
|
+
query_params["target_symbol"] = target_symbol
|
|
1356
|
+
|
|
1357
|
+
if trading_symbol is not None:
|
|
1358
|
+
query_params["trading_symbol"] = trading_symbol
|
|
1359
|
+
|
|
1360
|
+
return self.trade_service.count(query_params)
|
|
1201
1361
|
|
|
1202
1362
|
def get_open_trades(self, target_symbol=None, market=None) -> List[Trade]:
|
|
1203
1363
|
"""
|
|
@@ -1208,32 +1368,107 @@ class Algorithm:
|
|
|
1208
1368
|
is specified, the open trades with the specified market will be
|
|
1209
1369
|
returned.
|
|
1210
1370
|
|
|
1211
|
-
|
|
1371
|
+
Args:
|
|
1212
1372
|
target_symbol: The symbol of the asset
|
|
1213
1373
|
market: The market of the asset
|
|
1214
1374
|
|
|
1215
1375
|
Returns:
|
|
1216
1376
|
List[Trade]: A list of open trades that match the query parameters
|
|
1217
1377
|
"""
|
|
1218
|
-
return self.trade_service.
|
|
1378
|
+
return self.trade_service.get_all(
|
|
1379
|
+
{
|
|
1380
|
+
"status": TradeStatus.OPEN.value,
|
|
1381
|
+
"target_symbol": target_symbol,
|
|
1382
|
+
"market": market
|
|
1383
|
+
}
|
|
1384
|
+
)
|
|
1219
1385
|
|
|
1220
|
-
def
|
|
1386
|
+
def add_stop_loss(self, trade, percentage: int) -> None:
|
|
1387
|
+
"""
|
|
1388
|
+
Function to add a stop loss to a trade. This function will add a
|
|
1389
|
+
stop loss to the specified trade. If the stop loss is triggered,
|
|
1390
|
+
the trade will be closed.
|
|
1391
|
+
|
|
1392
|
+
Args:
|
|
1393
|
+
trade: Trade - The trade to add the stop loss to
|
|
1394
|
+
percentage: int - The stop loss of the trade
|
|
1395
|
+
|
|
1396
|
+
Returns:
|
|
1397
|
+
None
|
|
1398
|
+
"""
|
|
1399
|
+
self.trade_service.add_stop_loss(trade, percentage=percentage)
|
|
1400
|
+
|
|
1401
|
+
def add_trailing_stop_loss(self, trade, percentage: int) -> None:
|
|
1402
|
+
"""
|
|
1403
|
+
Function to add a trailing stop loss to a trade. This function will
|
|
1404
|
+
add a trailing stop loss to the specified trade. If the trailing
|
|
1405
|
+
stop loss is triggered, the trade will be closed.
|
|
1406
|
+
|
|
1407
|
+
Args:
|
|
1408
|
+
trade: Trade - The trade to add the trailing stop loss to
|
|
1409
|
+
trailing_stop_loss: float - The trailing stop loss of the trade
|
|
1410
|
+
|
|
1411
|
+
Returns:
|
|
1412
|
+
None
|
|
1413
|
+
"""
|
|
1414
|
+
self.trade_service.add_trailing_stop_loss(trade, percentage=percentage)
|
|
1415
|
+
|
|
1416
|
+
def close_trade(self, trade, precision=None) -> None:
|
|
1221
1417
|
"""
|
|
1222
1418
|
Function to close a trade. This function will close a trade by
|
|
1223
1419
|
creating a market order to sell the position. If the precision
|
|
1224
1420
|
parameter is specified, the amount of the order will be rounded
|
|
1225
1421
|
down to the specified precision.
|
|
1226
1422
|
|
|
1227
|
-
|
|
1423
|
+
Args:
|
|
1228
1424
|
trade: Trade - The trade to close
|
|
1229
|
-
|
|
1230
|
-
precision: float - The precision of the amount
|
|
1425
|
+
precision: int - The precision of the amount
|
|
1231
1426
|
|
|
1232
1427
|
Returns:
|
|
1233
1428
|
None
|
|
1234
1429
|
"""
|
|
1235
|
-
|
|
1236
|
-
|
|
1430
|
+
|
|
1431
|
+
trade = self.trade_service.get(trade.id)
|
|
1432
|
+
|
|
1433
|
+
if TradeStatus.CLOSED.equals(trade.status):
|
|
1434
|
+
raise OperationalException("Trade already closed.")
|
|
1435
|
+
|
|
1436
|
+
if trade.remaining <= 0:
|
|
1437
|
+
raise OperationalException("Trade has no amount to close.")
|
|
1438
|
+
|
|
1439
|
+
position_id = trade.orders[0].position_id
|
|
1440
|
+
portfolio = self.portfolio_service.find({"position": position_id})
|
|
1441
|
+
position = self.position_service.find(
|
|
1442
|
+
{"portfolio": portfolio.id, "symbol": trade.target_symbol}
|
|
1443
|
+
)
|
|
1444
|
+
amount = trade.remaining
|
|
1445
|
+
|
|
1446
|
+
if precision is not None:
|
|
1447
|
+
amount = RoundingService.round_down(amount, precision)
|
|
1448
|
+
|
|
1449
|
+
if position.get_amount() < amount:
|
|
1450
|
+
logger.warning(
|
|
1451
|
+
f"Order amount {amount} is larger then amount "
|
|
1452
|
+
f"of available {position.symbol} "
|
|
1453
|
+
f"position: {position.get_amount()}, "
|
|
1454
|
+
f"changing order amount to size of position"
|
|
1455
|
+
)
|
|
1456
|
+
amount = position.get_amount()
|
|
1457
|
+
|
|
1458
|
+
ticker = self._market_data_source_service.get_ticker(
|
|
1459
|
+
symbol=trade.symbol, market=portfolio.market
|
|
1460
|
+
)
|
|
1461
|
+
|
|
1462
|
+
self.order_service.create(
|
|
1463
|
+
{
|
|
1464
|
+
"portfolio_id": portfolio.id,
|
|
1465
|
+
"trading_symbol": trade.trading_symbol,
|
|
1466
|
+
"target_symbol": trade.target_symbol,
|
|
1467
|
+
"amount": amount,
|
|
1468
|
+
"order_side": OrderSide.SELL.value,
|
|
1469
|
+
"order_type": OrderType.LIMIT.value,
|
|
1470
|
+
"price": ticker["bid"],
|
|
1471
|
+
}
|
|
1237
1472
|
)
|
|
1238
1473
|
|
|
1239
1474
|
def get_number_of_positions(self):
|
|
@@ -1386,3 +1621,9 @@ class Algorithm:
|
|
|
1386
1621
|
[order.get_amount() * order.get_price()
|
|
1387
1622
|
for order in pending_orders]
|
|
1388
1623
|
)
|
|
1624
|
+
|
|
1625
|
+
def get_trade_service(self):
|
|
1626
|
+
return self.trade_service
|
|
1627
|
+
|
|
1628
|
+
def get_market_data_source_service(self):
|
|
1629
|
+
return self._market_data_source_service
|