powerquant-cli 0.2.6__tar.gz → 0.2.7__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.
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/.gitignore +0 -2
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/PKG-INFO +34 -6
- powerquant_cli-0.2.7/README.md +69 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/pyproject.toml +1 -1
- powerquant_cli-0.2.7/src/quant_cli/app/config/__init__.py +1 -0
- powerquant_cli-0.2.7/src/quant_cli/app/config/config_cli.py +71 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/data_dependency.py +6 -6
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/quant_cli.py +2 -0
- powerquant_cli-0.2.7/src/quant_cli/config/__init__.py +1 -0
- powerquant_cli-0.2.7/src/quant_cli/config/connection_config.py +133 -0
- powerquant_cli-0.2.7/tests/unit/test_connection_config.py +169 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/uv.lock +1 -1
- powerquant_cli-0.2.6/README.md +0 -41
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/.env.example +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/LICENSE +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/client.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/download.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/exceptions.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/schema/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/schema/adjustment_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/schema/bar_content_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/schema/bar_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/schema/corporate_action_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/schema/history_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/schema/pit_daily_window.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/schema/query_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/schema/quote_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/schema/reference_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/schema/reliability_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/SPEC.md +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/backtest/SPEC.md +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/backtest/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/backtest/backtest_input_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/backtest/backtest_run.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/backtest/data_guard.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/backtest/historical_clock.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/backtest/legacy_result_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/backtest/metrics.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/backtest/performance_report.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/backtest/report_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/backtest/schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/backtest/service/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/backtest/service/backtest_execution_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/constants.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/domain/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/domain/trading_quantity_value.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/exceptions.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/interface/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/interface/adjustment_factor_query.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/interface/market_data_query.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/interface/market_data_verification.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/interface/market_event_source.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/interface/market_revision_query.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/interface/market_runtime_repository.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/interface/market_time_slice_source.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/repository/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/schema/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/schema/adjustment_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/schema/corporate_action_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/schema/event_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/schema/exchange_operating_state.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/schema/exchange_state_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/schema/history_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/schema/instrument_identity.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/schema/market_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/schema/pit_daily_window.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/schema/quote_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/schema/reliability_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/schema/snapshot_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/schema/trading_state_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/service/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/service/calendar_coverage_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/service/prepared_data_verification_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/service/prepared_market_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/data/service/price_adjustment_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/LICENSE.vnpy +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/builtin/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/builtin/alpha101_recipe.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/builtin/alpha158_recipe.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/builtin/factor_recipe_catalog.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/computation/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/computation/factor_batch_evaluator.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/computation/factor_expression.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/computation/factor_source_loader.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/computation/operators/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/computation/operators/arithmetic_operator.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/computation/operators/cross_section_operator.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/computation/operators/time_series_operator.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/computation/panel_evaluator.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/computation/panel_expression.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/computation/python_factor_executor.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/computation/universe_filter.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/constants.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/exceptions.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/factor_dependency.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/interface/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/interface/factor_compute.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/interface/factor_execution.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/interface/factor_local_data.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/interface/factor_panel_compute.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/interface/factor_panel_input.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/interface/factor_query_store.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/interface/public/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/interface/public/factor_diagnostics.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/interface/public/factor_exposure_query.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/interface/public/factor_local.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/interface/public/factor_query.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/interface/public/factor_selection.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/model/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/repository/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/diagnostic_types.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/factor_artifact_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/factor_computation_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/factor_compute_request.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/factor_contract.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/factor_input_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/factor_panel.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/factor_publication_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/factor_query_result_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/factor_result_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/local_factor_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/panel_policy.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/selection_report.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/schema/selection_types.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/service/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/service/factor_compute_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/service/factor_diagnostic_runner.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/service/factor_diagnostics_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/service/factor_exposure_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/service/factor_input_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/service/factor_local_execution_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/service/factor_panel_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/service/factor_runtime_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/service/factor_selection_runner.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/service/published_factor_execution_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/service/selection_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/factor/visibility.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/opportunity/SPEC.md +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/opportunity/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/SPEC.md +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/bar_matcher.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/constants.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/domain/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/domain/execution_batch.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/domain/order_entity.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/domain/order_event.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/domain/order_policy.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/domain/order_value.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/fee_model.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/interface/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/interface/order_account.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/interface/order_trading_rules.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/interface/public/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/interface/public/execution_account.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/interface/public/order_events.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/interface/public/order_execution.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/interface/public/order_runtime.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/interface/public/order_submission.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/order_event_bus.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/order_execution_dependency.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/order_submission_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/schema/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/schema/order_request_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/simulation_broker.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/slippage_model.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/tradability_policy.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/order_execution/validators.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/SPEC.md +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/domain/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/domain/entitlement_entity.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/domain/portfolio_entity.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/domain/portfolio_event.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/domain/portfolio_value.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/domain/position_entity.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/domain/reservation_entity.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/interface/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/interface/public/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/interface/public/portfolio.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/interface/public/simulation_account.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/ledger_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/order_account_listener.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/portfolio_dependency.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/portfolio_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/portfolio/simulated_portfolio.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/SPEC.md +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/adapter/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/adapter/market_label_query.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/interface/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/interface/research_dataset.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/interface/research_evaluation.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/schema/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/schema/comparison_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/schema/dataset_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/schema/research_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/service/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/service/research_dataset_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/service/research_evaluation_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/research/service/research_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/SPEC.md +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/constants.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/exceptions.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/interface/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/interface/public/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/interface/public/portfolio_construction.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/interface/public/strategy.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/interface/public/strategy_market_query.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/interface/public/strategy_portfolio_reader.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/interface/strategy_factor_reader.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/interface/strategy_order_reader.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/schema/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/schema/portfolio_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/schema/portfolio_target.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/schema/python_strategy_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/schema/screener_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/schema/signal_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/schema/strategy_publication_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/schema/strategy_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/service/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/service/factor_top_n_strategy.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/service/portfolio_construction_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/service/python_strategy_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/service/screener_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/service/store_factor_reader.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/service/strategy_market_view.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/service/strategy_runtime_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/service/strategy_scheduler.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/strategies/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/strategies/momentum_volume_breakout.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/strategy_context.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/strategy/strategy_dependency.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/trading_runtime/SPEC.md +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/trading_runtime/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/trading_runtime/domain/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/trading_runtime/replay/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/trading_runtime/replay/daily_state_expand.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/trading_runtime/replay/exchange_state_resolver.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/trading_runtime/replay/market_runtime_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/trading_runtime/replay/market_state_resolver.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/trading_runtime/runtime_ports.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/trading_runtime/runtime_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/trading_runtime/runtime_session.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/trading_runtime/strategy_portfolio_adapter.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/trading_runtime/trading_rule_book.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/app/trading_runtime/trading_rule_query.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/common/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/common/exceptions/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/common/exceptions/base.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/quant_core/common/local_run.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/cached_factor_screen.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/factors/ma_close_10.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/factors/max_drawdown_20d.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/factors/momentum_20d.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/factors/multi_intraday_screen.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/factors/risk_adjusted_momentum_20d.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/factors/volume_ratio_5d.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/factors/volume_weighted_close_pressure.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/full_market_screen.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/local_quant_validation.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/published_definition_validation.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/research/factor_pit_coverage.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/research/ipo_first_day.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/selection/README.md +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/selection/backtest.json +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/selection/buy_hold.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/selection/compute.json +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/selection/prepare.json +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/selection/select.json +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/strategies/bar_roundtrip.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/strategies/buy_and_hold.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/strategies/contrarian_timing.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/strategies/factor_gate_vwap.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/strategies/ipo_next_day_vwap.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/strategies/momentum_timing.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/strategies/monthly_equal_weight.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/strategies/session_roundtrip.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/strategies/trend_drawdown_guard.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/strategies/weekly_risk_adjusted_rotation.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/examples/unified_snapshot_validation.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/hatch_build.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/licenses/LICENSE.vnpy +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/api.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/backtest/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/backtest/cli/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/backtest/cli/local_backtest_cli.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/backtest/local_backtest_dependency.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/backtest/local_backtest_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/backtest/repository/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/backtest/repository/backtest_local_repository.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/backtest/service/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/backtest/service/local_backtest_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/cli/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/cli/data_cli.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/repository/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/repository/parquet_repository.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/schema/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/schema/dataset_audit_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/schema/dataset_request_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/schema/parquet_file_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/service/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/service/bar_cache_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/service/dataset_audit_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/service/dataset_load_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/data/service/dataset_prepare_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/cli/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/cli/factor_definition_cli.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/cli/local_factor_cli.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/cli/local_selection_cli.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/interface/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/interface/local_selection_store.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/local_factor_dependency.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/repository/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/repository/factor_local_repository.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/repository/selection_local_repository.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/schema/local_selection_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/service/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/service/factor_data_prepare_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/service/local_factor_query_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/service/local_factor_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/factor/service/local_selection_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/job/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/job/cli/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/job/cli/local_job_cli.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/job/schema/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/job/schema/local_job_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/job/service/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/job/service/local_job_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/research/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/research/cli/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/research/cli/local_research_cli.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/research/local_research_dependency.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/research/repository/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/research/repository/research_local_repository.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/research/schema/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/research/schema/local_research_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/research/service/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/research/service/local_research_execution_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/research/service/local_research_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/strategy/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/strategy/cli/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/app/strategy/cli/strategy_cli.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/common/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/common/constants.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/common/database/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/common/database/duckdb_connection.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/common/http/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/common/http/definition_client.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/common/utils/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/common/utils/cli_utils.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/common/utils/platform_utils.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/src/quant_cli/common/utils/runtime_environment.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/conftest.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/factor_fixtures.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/integration/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/integration/test_local_quant_storage.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/integration/test_local_selection.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/__init__.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_alpha_backtest_reports.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_alpha_identity.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_alpha_market_input.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_alpha_research.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_alpha_top_n.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_backtest_run_result.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_bar_cache.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_coarse_execution_capability.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_corporate_action_replay.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_d1_replay_execution_chain.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_daily_state_expand.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_daily_state_snapshot.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_daily_vwap_execution.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_data_guard.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_dataset_audit.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_domain_dependency_boundaries.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_domain_interface_boundary.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_exchange_state_execution.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_exchange_state_replay.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_exchange_state_resolver.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_exchange_state_schema.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_factor_contract.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_factor_diagnostic_runner.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_factor_diagnostics.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_factor_expression.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_factor_local_runner.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_factor_runtime_service.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_factor_selection.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_factor_selection_runner.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_ipo_vwap_study.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_local_quant_boundary.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_market_replay.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_market_trading_state.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_order_domain.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_order_submission.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_portfolio_construction.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_portfolio_contracts.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_python_strategy_runtime.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_replay_state_boundaries.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_risk_adjusted_strategy_example.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_simulated_order_execution.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_simulated_portfolio.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_store_factor_reader.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_strategy_adjusted_view.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_strategy_domain.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_strategy_lifecycle.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_tradability_policy.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_trading_runtime_contracts.py +0 -0
- {powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/tests/unit/test_trading_runtime_session.py +0 -0
|
@@ -15,8 +15,6 @@ __pycache__/
|
|
|
15
15
|
.venv/
|
|
16
16
|
dist/
|
|
17
17
|
build/
|
|
18
|
-
tasks/draft/TASK-20260906-1704-akshare-minute-ingestion/samples/
|
|
19
|
-
tasks/approved/TASK-20260906-2119-real-market-integration-review-fixes/samples/
|
|
20
18
|
|
|
21
19
|
node_modules/
|
|
22
20
|
apps/quant_frontend/public/data-dictionary.md
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: powerquant-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.7
|
|
4
4
|
Summary: Power Quant local research CLI
|
|
5
5
|
Project-URL: Repository, https://github.com/Kepler452Byte/power-quant
|
|
6
6
|
License-Expression: LicenseRef-PowerQuant-Proprietary AND MIT
|
|
@@ -37,18 +37,46 @@ uv tool upgrade powerquant-cli
|
|
|
37
37
|
|
|
38
38
|
## 接入行情
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
向管理员申请账户及具备 `market:read` 权限的平台 API Token。登录 JWT 不用于行情请求。
|
|
41
|
+
|
|
42
|
+
首次配置一次,之后新开终端、切换目录仍可使用:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
pq config set --market-url 'https://powerquant.cn/market/api/v1'
|
|
46
|
+
pq config token
|
|
47
|
+
pq config show
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`token` 命令隐藏输入密钥,不加 `Bearer`,避免写入命令历史。`show` 显示地址、配置来源和是否已配置 Token,不显示密钥原文或前缀。
|
|
51
|
+
|
|
52
|
+
家庭 LAN 可配置 `http://192.168.8.142:18026/market/api/v1`;公网 IP 临时入口为 `http://82.157.167.33/market/api/v1`。公网 HTTP 会明文传输 Token,只适合已明确接受风险的临时接入;长期公网访问使用可信 HTTPS 或 SSH/WireGuard 加密链路。直接使用 `https://82.157.167.33` 与现有域名证书不匹配。
|
|
53
|
+
|
|
54
|
+
配置保存在当前系统用户的 `~/.powerquant/config.json`,与工作目录无关,不自动加载 `.env`。这是本地明文配置:POSIX 新目录权限 700、文件权限 600;Windows 依赖用户目录 ACL,不声称加密存储。不要提交或分享该文件。
|
|
55
|
+
|
|
56
|
+
每项配置按环境变量 > 用户文件 > 默认值解析。默认地址为 `http://localhost:8002/api/v1`,默认 Token 为空。环境变量只影响当前终端及其启动的子进程,不改文件;显式空 Token 环境变量会覆盖已保存密钥。
|
|
57
|
+
|
|
58
|
+
PowerShell 临时覆盖示例:
|
|
59
|
+
|
|
60
|
+
```powershell
|
|
61
|
+
$env:MARKET_BASE_URL="http://192.168.8.142:18026/market/api/v1"
|
|
62
|
+
$env:MARKET_API_TOKEN="管理员签发的完整平台Token"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
删除已保存的配置:
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
pq config unset market-token
|
|
69
|
+
pq config unset market-url
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
随后准备本地行情快照:
|
|
41
73
|
|
|
42
74
|
```sh
|
|
43
|
-
export MARKET_BASE_URL='http://服务器地址/market/api/v1'
|
|
44
|
-
export MARKET_API_TOKEN='管理员提供的行情密钥'
|
|
45
75
|
pq examples --directory powerquant-examples
|
|
46
76
|
cd powerquant-examples/selection
|
|
47
77
|
pq data prepare --config prepare.json
|
|
48
78
|
```
|
|
49
79
|
|
|
50
|
-
PowerShell 使用 `$env:MARKET_BASE_URL="..."` 与 `$env:MARKET_API_TOKEN="..."`。
|
|
51
|
-
|
|
52
80
|
按实际覆盖调整 prepare.json 的股票和日期,将返回 manifest_path 写入 compute.json、select.json;按示例 README 执行 compute、select 和 backtest。不同使用目的的快照须分别通过完整性检查。
|
|
53
81
|
|
|
54
82
|
密钥到期或撤销后在线准备会失败,已下载快照仍可离线使用。行情密钥不用于定义发布;发布定义另使用 PQ_QUANT_URL/PQ_QUANT_TOKEN。默认本地目录为 ~/.powerquant。
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Power Quant CLI
|
|
2
|
+
|
|
3
|
+
本地行情准备、因子计算、选股、研究及策略回测;结果保存在本地 DuckDB 和文件。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
推荐通过 uv 安装独立工具环境:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
uv tool install --python 3.12 powerquant-cli
|
|
11
|
+
pq --help
|
|
12
|
+
uv tool upgrade powerquant-cli
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
也支持在 Python 3.12+ 环境通过 `pip install powerquant-cli` 安装。
|
|
16
|
+
|
|
17
|
+
## 接入行情
|
|
18
|
+
|
|
19
|
+
向管理员申请账户及具备 `market:read` 权限的平台 API Token。登录 JWT 不用于行情请求。
|
|
20
|
+
|
|
21
|
+
首次配置一次,之后新开终端、切换目录仍可使用:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
pq config set --market-url 'https://powerquant.cn/market/api/v1'
|
|
25
|
+
pq config token
|
|
26
|
+
pq config show
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`token` 命令隐藏输入密钥,不加 `Bearer`,避免写入命令历史。`show` 显示地址、配置来源和是否已配置 Token,不显示密钥原文或前缀。
|
|
30
|
+
|
|
31
|
+
家庭 LAN 可配置 `http://192.168.8.142:18026/market/api/v1`;公网 IP 临时入口为 `http://82.157.167.33/market/api/v1`。公网 HTTP 会明文传输 Token,只适合已明确接受风险的临时接入;长期公网访问使用可信 HTTPS 或 SSH/WireGuard 加密链路。直接使用 `https://82.157.167.33` 与现有域名证书不匹配。
|
|
32
|
+
|
|
33
|
+
配置保存在当前系统用户的 `~/.powerquant/config.json`,与工作目录无关,不自动加载 `.env`。这是本地明文配置:POSIX 新目录权限 700、文件权限 600;Windows 依赖用户目录 ACL,不声称加密存储。不要提交或分享该文件。
|
|
34
|
+
|
|
35
|
+
每项配置按环境变量 > 用户文件 > 默认值解析。默认地址为 `http://localhost:8002/api/v1`,默认 Token 为空。环境变量只影响当前终端及其启动的子进程,不改文件;显式空 Token 环境变量会覆盖已保存密钥。
|
|
36
|
+
|
|
37
|
+
PowerShell 临时覆盖示例:
|
|
38
|
+
|
|
39
|
+
```powershell
|
|
40
|
+
$env:MARKET_BASE_URL="http://192.168.8.142:18026/market/api/v1"
|
|
41
|
+
$env:MARKET_API_TOKEN="管理员签发的完整平台Token"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
删除已保存的配置:
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
pq config unset market-token
|
|
48
|
+
pq config unset market-url
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
随后准备本地行情快照:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
pq examples --directory powerquant-examples
|
|
55
|
+
cd powerquant-examples/selection
|
|
56
|
+
pq data prepare --config prepare.json
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
按实际覆盖调整 prepare.json 的股票和日期,将返回 manifest_path 写入 compute.json、select.json;按示例 README 执行 compute、select 和 backtest。不同使用目的的快照须分别通过完整性检查。
|
|
60
|
+
|
|
61
|
+
密钥到期或撤销后在线准备会失败,已下载快照仍可离线使用。行情密钥不用于定义发布;发布定义另使用 PQ_QUANT_URL/PQ_QUANT_TOKEN。默认本地目录为 ~/.powerquant。
|
|
62
|
+
|
|
63
|
+
## Python
|
|
64
|
+
|
|
65
|
+
公开请求模型与调用入口位于 quant_cli.api,与 CLI 使用同一应用服务。
|
|
66
|
+
|
|
67
|
+
## 使用许可
|
|
68
|
+
|
|
69
|
+
自有代码采用随包附带的专有许可证:允许安装、查看源码、为自用进行修改,以及商业使用;未经书面授权不得再分发或转售本软件及其修改版本。第三方组件保留各自许可证。行情访问仍需要有效 Token;本许可证不授予行情数据的使用或再分发权。
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""用户连接配置命令。"""
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""持久化行情连接配置;Token 通过隐藏交互录入,输出始终脱敏。"""
|
|
2
|
+
|
|
3
|
+
from enum import StrEnum
|
|
4
|
+
from typing import Annotated
|
|
5
|
+
|
|
6
|
+
import typer
|
|
7
|
+
|
|
8
|
+
from quant_cli.common.utils.cli_utils import cli_errors, output
|
|
9
|
+
from quant_cli.config.connection_config import (
|
|
10
|
+
get_config_path,
|
|
11
|
+
load_saved_config,
|
|
12
|
+
resolve_market_connection,
|
|
13
|
+
update_saved_config,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
app = typer.Typer(help="保存和查看当前用户的行情连接配置", no_args_is_help=True)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ConfigKey(StrEnum):
|
|
20
|
+
MARKET_URL = "market-url"
|
|
21
|
+
MARKET_TOKEN = "market-token"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@app.command("set")
|
|
25
|
+
@cli_errors
|
|
26
|
+
def set_config(
|
|
27
|
+
market_url: Annotated[str, typer.Option("--market-url", "--url", help="行情 API 基础地址")],
|
|
28
|
+
) -> None:
|
|
29
|
+
"""保存行情服务 URL;不会修改当前进程的环境变量。"""
|
|
30
|
+
update_saved_config("market_url", market_url)
|
|
31
|
+
output({"status": "saved", "path": str(get_config_path()), "key": "market_url"})
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@app.command("token")
|
|
35
|
+
@cli_errors
|
|
36
|
+
def set_token() -> None:
|
|
37
|
+
"""隐藏输入平台 Token,避免写入命令历史与进程参数。"""
|
|
38
|
+
value = typer.prompt("平台 Token(不加 Bearer)", hide_input=True, err=True)
|
|
39
|
+
update_saved_config("market_token", value)
|
|
40
|
+
output({"status": "saved", "path": str(get_config_path()), "key": "market_token"})
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@app.command("show")
|
|
44
|
+
@cli_errors
|
|
45
|
+
def show_config() -> None:
|
|
46
|
+
"""展示已保存和当前生效的配置、来源;不输出密钥原文或前缀。"""
|
|
47
|
+
saved = load_saved_config()
|
|
48
|
+
effective = resolve_market_connection()
|
|
49
|
+
output(
|
|
50
|
+
{
|
|
51
|
+
"path": str(get_config_path()),
|
|
52
|
+
"saved": {
|
|
53
|
+
"market_url": saved.get("market_url"),
|
|
54
|
+
"token_configured": bool(saved.get("market_token")),
|
|
55
|
+
},
|
|
56
|
+
"effective": {
|
|
57
|
+
"market_url": effective.url,
|
|
58
|
+
"token_configured": bool(effective.token),
|
|
59
|
+
"url_source": effective.url_source,
|
|
60
|
+
"token_source": effective.token_source,
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@app.command("unset")
|
|
67
|
+
@cli_errors
|
|
68
|
+
def unset_config(key: ConfigKey) -> None:
|
|
69
|
+
"""删除一项已保存配置,环境变量覆盖仍然有效。"""
|
|
70
|
+
update_saved_config(key.value.replace("-", "_"), None)
|
|
71
|
+
output({"status": "removed", "key": key.value})
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
from pqdata import MarketClient
|
|
2
|
-
|
|
3
1
|
"""量化数据组装;数据库会话不再参与行情读取。"""
|
|
4
2
|
|
|
5
3
|
from pathlib import Path
|
|
6
4
|
|
|
5
|
+
from pqdata import MarketClient
|
|
7
6
|
from quant_core.app.backtest.backtest_input_schema import BacktestMarketComponents
|
|
8
7
|
from quant_core.app.trading_runtime.replay.exchange_state_resolver import ExchangeStateResolver
|
|
9
8
|
from quant_core.app.trading_runtime.replay.market_runtime_service import ReplayMarketEventSource
|
|
10
9
|
from quant_core.app.trading_runtime.replay.market_state_resolver import MarketStateResolver
|
|
11
10
|
|
|
11
|
+
from quant_cli.config.connection_config import resolve_market_connection
|
|
12
|
+
|
|
12
13
|
|
|
13
14
|
def load_backtest_market(manifest_path: Path, max_rows: int) -> BacktestMarketComponents:
|
|
14
15
|
"""从已校验本地快照组装回放输入,不访问 SDK 或数据库。"""
|
|
@@ -27,9 +28,8 @@ def load_backtest_market(manifest_path: Path, max_rows: int) -> BacktestMarketCo
|
|
|
27
28
|
|
|
28
29
|
def build_market_query() -> MarketClient:
|
|
29
30
|
"""显式在线准备入口,配置仅为服务地址与令牌。"""
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
connection = resolve_market_connection()
|
|
32
32
|
return MarketClient(
|
|
33
|
-
|
|
34
|
-
token=
|
|
33
|
+
connection.url,
|
|
34
|
+
token=connection.token,
|
|
35
35
|
)
|
|
@@ -8,6 +8,7 @@ from typing import Annotated
|
|
|
8
8
|
import typer
|
|
9
9
|
|
|
10
10
|
from quant_cli.app.backtest.cli.local_backtest_cli import app as backtest
|
|
11
|
+
from quant_cli.app.config.config_cli import app as config
|
|
11
12
|
from quant_cli.app.data.cli.data_cli import app as data
|
|
12
13
|
from quant_cli.app.factor.cli.local_factor_cli import app as factor
|
|
13
14
|
from quant_cli.app.job.cli.local_job_cli import app as job
|
|
@@ -22,6 +23,7 @@ app.add_typer(factor, name="factor")
|
|
|
22
23
|
app.add_typer(research, name="research")
|
|
23
24
|
app.add_typer(backtest, name="backtest")
|
|
24
25
|
app.add_typer(strategy, name="strategy")
|
|
26
|
+
app.add_typer(config, name="config")
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
@app.command()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""CLI 用户连接配置,不读取服务端环境文件。"""
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"""行情连接配置:环境变量覆盖用户文件,密钥不参与展示与错误输出。"""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import tempfile
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from urllib.parse import urlsplit
|
|
9
|
+
|
|
10
|
+
from filelock import FileLock
|
|
11
|
+
|
|
12
|
+
DEFAULT_MARKET_URL = "http://localhost:8002/api/v1"
|
|
13
|
+
CONFIG_KEYS = {"market_url", "market_token"}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class MarketConnection:
|
|
18
|
+
url: str
|
|
19
|
+
token: str = field(repr=False)
|
|
20
|
+
url_source: str
|
|
21
|
+
token_source: str
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def get_config_path() -> Path:
|
|
25
|
+
"""当前系统用户的配置路径,独立于终端和工作目录。"""
|
|
26
|
+
return Path.home() / ".powerquant" / "config.json"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def validate_market_url(value: str) -> str:
|
|
30
|
+
"""拒绝凭据、查询参数、片段和非 HTTP(S) 地址,不回显输入。"""
|
|
31
|
+
try:
|
|
32
|
+
url = urlsplit(value)
|
|
33
|
+
port = url.port
|
|
34
|
+
valid = (
|
|
35
|
+
url.scheme in {"http", "https"}
|
|
36
|
+
and bool(url.hostname)
|
|
37
|
+
and not url.username
|
|
38
|
+
and not url.password
|
|
39
|
+
and not url.query
|
|
40
|
+
and not url.fragment
|
|
41
|
+
and not any(character.isspace() for character in value)
|
|
42
|
+
and (port is None or port > 0)
|
|
43
|
+
)
|
|
44
|
+
except ValueError:
|
|
45
|
+
valid = False
|
|
46
|
+
if not valid:
|
|
47
|
+
raise ValueError("行情地址必须是无凭据、查询参数和片段的 HTTP(S) 基础 URL")
|
|
48
|
+
return value.rstrip("/")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _validate_token(value: str) -> None:
|
|
52
|
+
if any(character.isspace() for character in value):
|
|
53
|
+
raise ValueError("Token 不能包含空白字符,请输入完整密钥,不加 Bearer 前缀")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def load_saved_config() -> dict[str, str]:
|
|
57
|
+
"""加载已保存配置;损坏时明确失败,不静默回退到其他服务器。"""
|
|
58
|
+
path = get_config_path()
|
|
59
|
+
if not path.exists():
|
|
60
|
+
return {}
|
|
61
|
+
try:
|
|
62
|
+
document = json.loads(path.read_text(encoding="utf-8"))
|
|
63
|
+
except (OSError, ValueError) as exc:
|
|
64
|
+
raise ValueError("无法读取用户连接配置,请检查 ~/.powerquant/config.json") from exc
|
|
65
|
+
if (
|
|
66
|
+
not isinstance(document, dict)
|
|
67
|
+
or set(document) - CONFIG_KEYS
|
|
68
|
+
or any(not isinstance(value, str) for value in document.values())
|
|
69
|
+
):
|
|
70
|
+
raise ValueError("用户连接配置格式不合法")
|
|
71
|
+
if "market_url" in document:
|
|
72
|
+
validate_market_url(document["market_url"])
|
|
73
|
+
if "market_token" in document:
|
|
74
|
+
_validate_token(document["market_token"])
|
|
75
|
+
return document
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def update_saved_config(key: str, value: str | None) -> None:
|
|
79
|
+
"""加锁修改并原子替换文件;POSIX 新目录 700、配置文件 600。"""
|
|
80
|
+
if key not in CONFIG_KEYS:
|
|
81
|
+
raise ValueError("不支持的配置项")
|
|
82
|
+
if value is not None:
|
|
83
|
+
if key == "market_url":
|
|
84
|
+
value = validate_market_url(value)
|
|
85
|
+
else:
|
|
86
|
+
if not value:
|
|
87
|
+
raise ValueError("Token 不能为空;删除配置请使用 pq config unset")
|
|
88
|
+
_validate_token(value)
|
|
89
|
+
path = get_config_path()
|
|
90
|
+
path.parent.mkdir(mode=0o700, parents=True, exist_ok=True)
|
|
91
|
+
with FileLock(str(path) + ".lock"):
|
|
92
|
+
document = load_saved_config()
|
|
93
|
+
if value is None:
|
|
94
|
+
document.pop(key, None)
|
|
95
|
+
else:
|
|
96
|
+
document[key] = value
|
|
97
|
+
temporary: Path | None = None
|
|
98
|
+
try:
|
|
99
|
+
descriptor, name = tempfile.mkstemp(prefix=".config-", dir=path.parent)
|
|
100
|
+
temporary = Path(name)
|
|
101
|
+
with os.fdopen(descriptor, "w", encoding="utf-8") as stream:
|
|
102
|
+
json.dump(document, stream, ensure_ascii=False, indent=2)
|
|
103
|
+
stream.write("\n")
|
|
104
|
+
stream.flush()
|
|
105
|
+
os.fsync(stream.fileno())
|
|
106
|
+
temporary.chmod(0o600)
|
|
107
|
+
os.replace(temporary, path)
|
|
108
|
+
except OSError as exc:
|
|
109
|
+
raise ValueError("无法保存用户连接配置,请检查用户目录权限") from exc
|
|
110
|
+
finally:
|
|
111
|
+
if temporary is not None:
|
|
112
|
+
temporary.unlink(missing_ok=True)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def resolve_market_connection() -> MarketConnection:
|
|
116
|
+
"""按环境变量、用户文件、默认值分别解析 URL 和 Token。"""
|
|
117
|
+
saved = (
|
|
118
|
+
{} if {"MARKET_BASE_URL", "MARKET_API_TOKEN"} <= os.environ.keys() else load_saved_config()
|
|
119
|
+
)
|
|
120
|
+
url = os.environ.get("MARKET_BASE_URL", saved.get("market_url", DEFAULT_MARKET_URL))
|
|
121
|
+
token = os.environ.get("MARKET_API_TOKEN", saved.get("market_token", ""))
|
|
122
|
+
url = validate_market_url(url)
|
|
123
|
+
_validate_token(token)
|
|
124
|
+
return MarketConnection(
|
|
125
|
+
url=url,
|
|
126
|
+
token=token,
|
|
127
|
+
url_source="environment"
|
|
128
|
+
if "MARKET_BASE_URL" in os.environ
|
|
129
|
+
else ("file" if "market_url" in saved else "default"),
|
|
130
|
+
token_source="environment"
|
|
131
|
+
if "MARKET_API_TOKEN" in os.environ
|
|
132
|
+
else ("file" if "market_token" in saved else "default"),
|
|
133
|
+
)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"""真实用户文件、配置命令与行情客户端的连接配置回归。"""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
from typer.testing import CliRunner
|
|
11
|
+
|
|
12
|
+
from quant_cli.app.quant_cli import app
|
|
13
|
+
from quant_cli.config.connection_config import (
|
|
14
|
+
DEFAULT_MARKET_URL,
|
|
15
|
+
get_config_path,
|
|
16
|
+
load_saved_config,
|
|
17
|
+
resolve_market_connection,
|
|
18
|
+
update_saved_config,
|
|
19
|
+
validate_market_url,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@pytest.fixture(autouse=True)
|
|
24
|
+
def isolated_config(monkeypatch, tmp_path):
|
|
25
|
+
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
|
26
|
+
monkeypatch.delenv("MARKET_BASE_URL", raising=False)
|
|
27
|
+
monkeypatch.delenv("MARKET_API_TOKEN", raising=False)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_default_connection():
|
|
31
|
+
connection = resolve_market_connection()
|
|
32
|
+
assert connection.url == DEFAULT_MARKET_URL
|
|
33
|
+
assert connection.token == ""
|
|
34
|
+
assert connection.url_source == connection.token_source == "default"
|
|
35
|
+
assert not get_config_path().exists()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_saved_connection_survives_a_new_process(tmp_path):
|
|
39
|
+
update_saved_config("market_url", "http://82.157.167.33/market/api/v1/")
|
|
40
|
+
update_saved_config("market_token", "test-platform-secret")
|
|
41
|
+
script = """
|
|
42
|
+
import json, sys
|
|
43
|
+
from pathlib import Path
|
|
44
|
+
Path.home = classmethod(lambda cls: Path(sys.argv[1]))
|
|
45
|
+
from quant_cli.config.connection_config import resolve_market_connection
|
|
46
|
+
c = resolve_market_connection()
|
|
47
|
+
print(json.dumps({'url': c.url, 'token_matches': c.token == 'test-platform-secret'}))
|
|
48
|
+
"""
|
|
49
|
+
result = subprocess.run(
|
|
50
|
+
[sys.executable, "-c", script, str(tmp_path)], capture_output=True, text=True, check=True
|
|
51
|
+
)
|
|
52
|
+
assert json.loads(result.stdout) == {
|
|
53
|
+
"url": "http://82.157.167.33/market/api/v1",
|
|
54
|
+
"token_matches": True,
|
|
55
|
+
}
|
|
56
|
+
if os.name == "posix":
|
|
57
|
+
assert get_config_path().stat().st_mode & 0o777 == 0o600
|
|
58
|
+
assert get_config_path().parent.stat().st_mode & 0o777 == 0o700
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_environment_overrides_each_field_without_changing_file(monkeypatch):
|
|
62
|
+
update_saved_config("market_url", "https://example.com/market/api/v1")
|
|
63
|
+
update_saved_config("market_token", "saved-secret")
|
|
64
|
+
original = get_config_path().read_bytes()
|
|
65
|
+
monkeypatch.setenv("MARKET_API_TOKEN", "environment-secret")
|
|
66
|
+
connection = resolve_market_connection()
|
|
67
|
+
assert connection.url == "https://example.com/market/api/v1"
|
|
68
|
+
assert connection.token == "environment-secret"
|
|
69
|
+
assert connection.url_source == "file"
|
|
70
|
+
assert connection.token_source == "environment"
|
|
71
|
+
monkeypatch.setenv("MARKET_BASE_URL", "http://localhost:9000/api/v1")
|
|
72
|
+
assert resolve_market_connection().url == "http://localhost:9000/api/v1"
|
|
73
|
+
assert get_config_path().read_bytes() == original
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def test_empty_environment_token_does_not_reuse_saved_secret(monkeypatch):
|
|
77
|
+
update_saved_config("market_token", "saved-secret")
|
|
78
|
+
monkeypatch.setenv("MARKET_API_TOKEN", "")
|
|
79
|
+
assert resolve_market_connection().token == ""
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def test_cli_hidden_token_and_show_never_output_secret():
|
|
83
|
+
runner = CliRunner()
|
|
84
|
+
assert (
|
|
85
|
+
runner.invoke(app, ["config", "set", "--url", "http://localhost:9000/api/v1"]).exit_code
|
|
86
|
+
== 0
|
|
87
|
+
)
|
|
88
|
+
token = runner.invoke(app, ["config", "token"], input="test-hidden-secret\n")
|
|
89
|
+
assert token.exit_code == 0, token.output
|
|
90
|
+
assert "test-hidden-secret" not in token.output
|
|
91
|
+
shown = runner.invoke(app, ["config", "show"])
|
|
92
|
+
assert shown.exit_code == 0
|
|
93
|
+
assert "test-hidden-secret" not in shown.output
|
|
94
|
+
assert json.loads(shown.stdout)["effective"]["token_configured"]
|
|
95
|
+
assert "test-hidden-secret" not in repr(resolve_market_connection())
|
|
96
|
+
assert runner.invoke(app, ["config", "unset", "market-token"]).exit_code == 0
|
|
97
|
+
assert load_saved_config() == {"market_url": "http://localhost:9000/api/v1"}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@pytest.mark.parametrize(
|
|
101
|
+
"url",
|
|
102
|
+
[
|
|
103
|
+
"[http://example.com](http://example.com)",
|
|
104
|
+
"ftp://example.com",
|
|
105
|
+
"https://u:secret@example.com",
|
|
106
|
+
"https://example.com?token=secret",
|
|
107
|
+
"https://example.com#token",
|
|
108
|
+
"https://example.com:99999",
|
|
109
|
+
"https://",
|
|
110
|
+
"",
|
|
111
|
+
"http://example.com/ white space",
|
|
112
|
+
],
|
|
113
|
+
)
|
|
114
|
+
def test_invalid_url_does_not_echo_credentials(url):
|
|
115
|
+
with pytest.raises(ValueError) as error:
|
|
116
|
+
validate_market_url(url)
|
|
117
|
+
assert "secret" not in str(error.value)
|
|
118
|
+
assert not get_config_path().exists()
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def test_corrupted_file_fails_without_exposing_content(monkeypatch):
|
|
122
|
+
path = get_config_path()
|
|
123
|
+
path.parent.mkdir()
|
|
124
|
+
path.write_text('{"market_token": "hidden-secret"', encoding="utf-8")
|
|
125
|
+
result = CliRunner().invoke(app, ["config", "show"])
|
|
126
|
+
assert result.exit_code == 1
|
|
127
|
+
assert "hidden-secret" not in result.output
|
|
128
|
+
monkeypatch.setenv("MARKET_BASE_URL", "https://example.com/api/v1")
|
|
129
|
+
monkeypatch.setenv("MARKET_API_TOKEN", "override-secret")
|
|
130
|
+
assert resolve_market_connection().token == "override-secret"
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_market_client_uses_saved_connection(monkeypatch):
|
|
134
|
+
from quant_cli.app.data import data_dependency
|
|
135
|
+
|
|
136
|
+
update_saved_config("market_url", "https://example.com/market/api/v1")
|
|
137
|
+
update_saved_config("market_token", "test-secret")
|
|
138
|
+
observed = {}
|
|
139
|
+
|
|
140
|
+
def fake_client(url, *, token):
|
|
141
|
+
observed.update(url=url, token=token)
|
|
142
|
+
return observed
|
|
143
|
+
|
|
144
|
+
monkeypatch.setattr(data_dependency, "MarketClient", fake_client)
|
|
145
|
+
assert data_dependency.build_market_query() == {
|
|
146
|
+
"url": "https://example.com/market/api/v1",
|
|
147
|
+
"token": "test-secret",
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def test_invalid_token_is_not_saved_or_echoed():
|
|
152
|
+
result = CliRunner().invoke(app, ["config", "token"], input="Bearer hidden-secret\n")
|
|
153
|
+
assert result.exit_code == 1
|
|
154
|
+
assert "hidden-secret" not in result.output
|
|
155
|
+
assert not get_config_path().exists()
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def test_failed_atomic_replace_preserves_previous_config(monkeypatch):
|
|
159
|
+
update_saved_config("market_token", "old-secret")
|
|
160
|
+
original = get_config_path().read_bytes()
|
|
161
|
+
|
|
162
|
+
def fail_replace(*args):
|
|
163
|
+
raise OSError("test write failure")
|
|
164
|
+
|
|
165
|
+
monkeypatch.setattr(os, "replace", fail_replace)
|
|
166
|
+
with pytest.raises(ValueError, match="无法保存"):
|
|
167
|
+
update_saved_config("market_token", "new-secret")
|
|
168
|
+
assert get_config_path().read_bytes() == original
|
|
169
|
+
assert not list(get_config_path().parent.glob(".config-*"))
|
powerquant_cli-0.2.6/README.md
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# Power Quant CLI
|
|
2
|
-
|
|
3
|
-
本地行情准备、因子计算、选股、研究及策略回测;结果保存在本地 DuckDB 和文件。
|
|
4
|
-
|
|
5
|
-
## 安装
|
|
6
|
-
|
|
7
|
-
推荐通过 uv 安装独立工具环境:
|
|
8
|
-
|
|
9
|
-
```sh
|
|
10
|
-
uv tool install --python 3.12 powerquant-cli
|
|
11
|
-
pq --help
|
|
12
|
-
uv tool upgrade powerquant-cli
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
也支持在 Python 3.12+ 环境通过 `pip install powerquant-cli` 安装。
|
|
16
|
-
|
|
17
|
-
## 接入行情
|
|
18
|
-
|
|
19
|
-
向管理员获取行情读取密钥,无需注册账户。服务当前仅在 LAN/WireGuard 内可达。
|
|
20
|
-
|
|
21
|
-
```sh
|
|
22
|
-
export MARKET_BASE_URL='http://服务器地址/market/api/v1'
|
|
23
|
-
export MARKET_API_TOKEN='管理员提供的行情密钥'
|
|
24
|
-
pq examples --directory powerquant-examples
|
|
25
|
-
cd powerquant-examples/selection
|
|
26
|
-
pq data prepare --config prepare.json
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
PowerShell 使用 `$env:MARKET_BASE_URL="..."` 与 `$env:MARKET_API_TOKEN="..."`。
|
|
30
|
-
|
|
31
|
-
按实际覆盖调整 prepare.json 的股票和日期,将返回 manifest_path 写入 compute.json、select.json;按示例 README 执行 compute、select 和 backtest。不同使用目的的快照须分别通过完整性检查。
|
|
32
|
-
|
|
33
|
-
密钥到期或撤销后在线准备会失败,已下载快照仍可离线使用。行情密钥不用于定义发布;发布定义另使用 PQ_QUANT_URL/PQ_QUANT_TOKEN。默认本地目录为 ~/.powerquant。
|
|
34
|
-
|
|
35
|
-
## Python
|
|
36
|
-
|
|
37
|
-
公开请求模型与调用入口位于 quant_cli.api,与 CLI 使用同一应用服务。
|
|
38
|
-
|
|
39
|
-
## 使用许可
|
|
40
|
-
|
|
41
|
-
自有代码采用随包附带的专有许可证:允许安装、查看源码、为自用进行修改,以及商业使用;未经书面授权不得再分发或转售本软件及其修改版本。第三方组件保留各自许可证。行情访问仍需要有效 Token;本许可证不授予行情数据的使用或再分发权。
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{powerquant_cli-0.2.6 → powerquant_cli-0.2.7}/bundled/pqdata/schema/corporate_action_schema.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|