feat: stable MT5Client public API and infrastructure layer (#30)
* feat: add stable MT5Client public API and infrastructure layer Introduce a reusable public API for downstream trading applications: - MT5Client as the primary client abstraction with order_check/order_send - schemas module with DataKind contracts, validation, and normalization - converters, exceptions, retry, and storage facade modules - CLI order commands now route through MT5Client - connected_client made public; retry logic centralized - Contract tests for API surface, schemas, and storage round-trips - README and docs updated with Python API usage examples Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com> * fix: correct time coercion, broker-safe symbols, and execution docs - Normalize MT5 time columns with correct second/millisecond units - Coerce all present known MT5 time fields, including optional order times - Preserve broker symbol casing in normalize_symbol() - Document order_send() as a live execution primitive with clear scope boundaries - Add contract tests for timestamp and symbol normalization behavior 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>
This commit is contained in:
co-authored by
Daichi Narushima
Cursor Agent
parent
9356d5dcdf
commit
78c49238cf
+3
-3
@@ -175,7 +175,7 @@ class TestConnectionLifecycle:
|
||||
mock_client = MagicMock()
|
||||
mocker.patch("mt5cli.sdk.Mt5DataClient", return_value=mock_client)
|
||||
config = MagicMock()
|
||||
with sdk._connected_client(config): # type: ignore[reportPrivateUsage]
|
||||
with sdk.connected_client(config): # type: ignore[reportPrivateUsage]
|
||||
mock_client.initialize_and_login_mt5.assert_called_once()
|
||||
mock_client.shutdown.assert_called_once()
|
||||
|
||||
@@ -191,7 +191,7 @@ class TestConnectionLifecycle:
|
||||
mocker.patch("mt5cli.sdk.Mt5DataClient", return_value=mock_client)
|
||||
with (
|
||||
pytest.raises(RuntimeError, match="login failed"),
|
||||
sdk._connected_client(MagicMock()), # type: ignore[reportPrivateUsage]
|
||||
sdk.connected_client(MagicMock()), # type: ignore[reportPrivateUsage]
|
||||
):
|
||||
pass
|
||||
mock_client.shutdown.assert_called_once()
|
||||
@@ -1342,7 +1342,7 @@ class TestCollectLatestRatesForAccounts:
|
||||
"""Test account fields override base_config, empty login falls back."""
|
||||
configs: list[object] = []
|
||||
|
||||
def _record_config(*, config: object) -> MagicMock:
|
||||
def _record_config(*, config: object, **_: object) -> MagicMock:
|
||||
configs.append(config)
|
||||
return mock_client
|
||||
|
||||
|
||||
Reference in New Issue
Block a user