* feat: add stable SDK helpers for volume, margin, and closed bars (#39, #40, #41)
Expose generic trading utilities in the stable downstream SDK so applications
like mteor can drop local MT5 adapter code:
- normalize_order_volume() for broker step/min/max sizing
- estimate_order_margin() and calculate_positions_margin() for margin totals
- fetch_latest_closed_rates_for_trading_client() for closed bars from Mt5TradingClient
Update STABLE_SDK_EXPORTS, package-root exports, docs, and unit tests.
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>
* chore: bump version to 0.8.3
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>
* fix: address PR review feedback on volume cap, rate time, and margin grouping
- Re-apply volume_max after step normalization in normalize_order_volume()
- Drop misleading non-time index reset branch in _ensure_rate_time_column()
- Group positions by (symbol, side) before margin estimation
- Add branch-coverage tests for tick price validation and volume cap edge case
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>
* fix: address remaining PR review threads on docs and DatetimeIndex
- Rename unnamed DatetimeIndex column to time after reset_index()
- Guard estimate_order_margin example on positive normalized volume
- Document calculate_positions_margin skip vs error propagation behavior
- Add test for unnamed DatetimeIndex branch coverage
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>
* fix: harden stable SDK margin, rate fetch, and volume normalization
- Wrap order_calc_margin conversion and reject None/non-numeric results
- Validate fetched rate objects are DataFrames before time normalization
- Return 0.0 for non-finite volume inputs and constraints in normalize_order_volume
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>
* fix: reject non-finite volumes in margin estimation helpers
Use _is_positive_finite_number() in estimate_order_margin() and
calculate_positions_margin() so NaN/inf volumes never reach broker calls.
Add focused tests and document non-finite volume skipping in trading.md.
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>
* fix: guard symbol filter in calculate_positions_margin for empty frames
Return 0.0 before filtering when positions are empty or lack a symbol column.
Add regression tests for filtered calls on malformed position frames.
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>
* Add trading session helpers and extend ThrottledHistoryUpdater
Introduce mt5cli.trading with mt5_trading_session() for Mt5TradingClient
lifecycle management and reusable operational helpers for position-side
detection, margin/volume sizing, and protective order price derivation.
Extend ThrottledHistoryUpdater to validate inputs before updates and to
optionally suppress ValueError, OSError, and missing-method errors without
advancing the throttle timestamp.
Export the new helpers from mt5cli.__init__, add unit tests with mocked
clients, and document migration guidance for downstream projects such as
mteor.
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>
* Narrow ThrottledHistoryUpdater suppress_errors handling (#27)
* Narrow ThrottledHistoryUpdater suppress_errors for MT5 capability only
Remove broad AttributeError/TypeError handling from recoverable errors.
Add _is_mt5_client_capability_error() to detect missing history API methods
or non-callable client attributes by message and attribute name.
Generic AttributeError/TypeError values always propagate even when
suppress_errors=True. Update docs and tests accordingly.
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>
* Detect non-callable history client methods in suppress_errors
Address review feedback: when a history API attribute exists but is not
callable, Python raises a generic TypeError. Inspect the traceback for
mt5cli.history client call sites so these capability mismatches are still
suppressed without matching all TypeError values.
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>
* Address PR review feedback on trading helpers
- Resolve history module path once at import time
- Only treat non-callable TypeErrors as capability errors at the raise site
- Validate SL/TP ratios in determine_order_limits
- Add tests for margin_free edge cases, body-raise shutdown, and internal TypeError propagation
- Clarify ThrottledHistoryUpdater suppress_errors docs
- Split README migration example into trading vs read-only history sessions
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>
* Tighten protective ratio validation and clamp negative margin_free
Add _require_protective_ratio enforcing 0 <= ratio < 1 for SL/TP limits so
a ratio of 1.0 cannot produce zero protective prices. Clamp negative
margin_free to 0.0 in calculate_margin_and_volume before sizing.
Add boundary and negative-margin tests; document constraints in trading API
docs.
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com>