dfe80ce500
* feat: add close-positions CLI command and replace_symbol projection mode (#65 #66) Part 1 — close-positions CLI (#65): - Add `close-positions` subcommand delegating to `close_open_positions()`. - Accepts repeated `--symbol` and `--ticket` filters (AND semantics). - Supports `--dry-run` (no `--yes` required); live execution requires `--yes`. - Fails closed with `BadParameter` when neither `--symbol` nor `--ticket` is given. - Exports normalized `OrderExecutionResult` list as a DataFrame (request/response serialized as JSON strings for clean CSV/JSON/Parquet/SQLite output). - `order-send` remains the raw expert path; `close-positions` is the safer high-level helper that builds correct close requests automatically. Part 2 — ProjectionMode and replace_symbol (#66): - Add `ProjectionMode = Literal["add", "replace_symbol"]` type alias. - Add optional `projection_mode` parameter to `calculate_symbol_group_margin_ratio`. Default `"add"` preserves existing additive behavior. `"replace_symbol"` subtracts current margin for `new_symbol`, then adds candidate margin — the subtraction and addition are atomic (suppressed together). - Export `ProjectionMode` from `mt5cli` and add to `STABLE_SDK_EXPORTS`. - No mteor-specific strategy, risk-threshold, or policy logic added. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: remove unused ProjectionMode import in test_contracts.py The parametrized test_stable_exports_are_importable_from_package_root already covers ProjectionMode via hasattr(mt5cli, name). Ruff correctly flagged the explicit top-level import as unused (F401). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Bump version to v0.9.6 * fix: address PR #67 review feedback - Floor replace_symbol margin subtraction at zero to prevent negative ratio - Serialize response unconditionally via json.dumps (null for dry-run rows) - Return a schema-preserving empty DataFrame when results list is empty - Add test: --dry-run --yes precedence (dry-run wins, no order_send) - Add test: zero-match filter produces empty JSON array with exit 0 - Move projection_mode prose to stable trading section in docs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: add runtime validation for projection_mode in calculate_symbol_group_margin_ratio Unsupported values previously silently fell through as "add". The new _validate_projection_mode helper raises ValueError with a message that names the bad value and the two accepted modes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: agent <agent@localhost> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>