Refactor MT5 constant parsing to delegate to pdmt5 >= 0.3.0 (#28)
* Refactor MT5 constant parsing to delegate to pdmt5 >= 0.3.0 Replace local TIMEFRAME_MAP, TICK_FLAG_MAP, and parser helpers with thin compatibility wrappers around pdmt5. COPY_TICKS flags now use real MT5 values (ALL=-1, INFO=1, TRADE=2). Click parameter types validate all inputs through the wrappers. Update tests and docs to describe the pdmt5/mt5cli/mt5api layering. Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com> * Fix timeframe defaults and COPY_TICKS flag defaults after pdmt5 migration Use short timeframe aliases for default history collection and granularity naming via pdmt5.get_timeframe_name. Set CLI/SDK default tick flags to ALL (-1) instead of the legacy mt5cli-only value. Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com> * Address CI lint failure and PR review feedback Fix ruff import ordering in history.py. Use ALL string defaults for CLI tick flags, isolate TICK_FLAG_MAP as a dict snapshot, derive flag names from pdmt5, reuse TIMEFRAME_NAMES for default history timeframes, and add tests for prefix stripping and TIMEFRAME_ key filtering. Co-authored-by: Daichi Narushima <dceoy@users.noreply.github.com> * Bump version to 0.7.0 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:
+51
-14
@@ -274,8 +274,14 @@ class TestParseTimeframe:
|
||||
assert parse_timeframe(value) == expected
|
||||
|
||||
def test_integer_timeframe(self) -> None:
|
||||
"""Test parsing integer timeframe."""
|
||||
assert parse_timeframe("42") == 42
|
||||
"""Test parsing supported integer timeframes."""
|
||||
assert parse_timeframe("1") == 1
|
||||
assert parse_timeframe(16385) == 16385
|
||||
|
||||
def test_unsupported_integer_timeframe_raises(self) -> None:
|
||||
"""Test that unsupported integer timeframes raise ValueError."""
|
||||
with pytest.raises(ValueError, match="Invalid timeframe"):
|
||||
parse_timeframe("42")
|
||||
|
||||
def test_invalid_timeframe_raises(self) -> None:
|
||||
"""Test that invalid timeframe raises ValueError."""
|
||||
@@ -288,15 +294,21 @@ class TestParseTickFlags:
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("value", "expected"),
|
||||
[("ALL", 1), ("info", 2), ("TRADE", 4)],
|
||||
[("ALL", -1), ("info", 1), ("TRADE", 2), ("COPY_TICKS_ALL", -1)],
|
||||
)
|
||||
def test_named_flag(self, value: str, expected: int) -> None:
|
||||
"""Test parsing named tick flags."""
|
||||
assert parse_tick_flags(value) == expected
|
||||
|
||||
def test_integer_flag(self) -> None:
|
||||
"""Test parsing integer tick flag."""
|
||||
assert parse_tick_flags("7") == 7
|
||||
"""Test parsing supported integer tick flags."""
|
||||
assert parse_tick_flags("-1") == -1
|
||||
assert parse_tick_flags(2) == 2
|
||||
|
||||
def test_unsupported_integer_flag_raises(self) -> None:
|
||||
"""Test that unsupported integer tick flags raise ValueError."""
|
||||
with pytest.raises(ValueError, match="Invalid tick flags"):
|
||||
parse_tick_flags("7")
|
||||
|
||||
def test_invalid_flag_raises(self) -> None:
|
||||
"""Test that invalid flag raises ValueError."""
|
||||
@@ -355,8 +367,11 @@ class TestConstants:
|
||||
assert key in TIMEFRAME_MAP
|
||||
|
||||
def test_tick_flag_map_has_expected_keys(self) -> None:
|
||||
"""Test that TICK_FLAG_MAP contains standard flags."""
|
||||
assert set(TICK_FLAG_MAP) == {"ALL", "INFO", "TRADE"}
|
||||
"""Test that TICK_FLAG_MAP contains standard flags with MT5 values."""
|
||||
assert {"ALL", "INFO", "TRADE"} <= set(TICK_FLAG_MAP)
|
||||
assert TICK_FLAG_MAP["ALL"] == -1
|
||||
assert TICK_FLAG_MAP["INFO"] == 1
|
||||
assert TICK_FLAG_MAP["TRADE"] == 2
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("dataset", "expected"),
|
||||
@@ -403,26 +418,48 @@ class TestTimeframeType:
|
||||
"""Test converting a string to timeframe integer."""
|
||||
assert TIMEFRAME_TYPE.convert("H1", None, None) == 16385
|
||||
|
||||
def test_convert_int_passthrough(self) -> None:
|
||||
"""Test that integer values pass through unchanged."""
|
||||
assert TIMEFRAME_TYPE.convert(42, None, None) == 42
|
||||
def test_convert_int(self) -> None:
|
||||
"""Test converting supported integer timeframe values."""
|
||||
assert TIMEFRAME_TYPE.convert(16385, None, None) == 16385
|
||||
|
||||
def test_convert_unsupported_int(self) -> None:
|
||||
"""Test that unsupported integer values raise BadParameter."""
|
||||
with pytest.raises(Exception, match="Invalid timeframe"):
|
||||
TIMEFRAME_TYPE.convert(42, None, None)
|
||||
|
||||
def test_convert_invalid(self) -> None:
|
||||
"""Test that invalid values raise BadParameter."""
|
||||
with pytest.raises(Exception, match="Invalid timeframe"):
|
||||
TIMEFRAME_TYPE.convert("bad", None, None)
|
||||
|
||||
@pytest.mark.parametrize("value", [True, False, None, 1.5])
|
||||
def test_convert_invalid_types(self, value: object) -> None:
|
||||
"""Test that bool, float, and None values raise BadParameter."""
|
||||
with pytest.raises(Exception, match="Invalid timeframe"):
|
||||
TIMEFRAME_TYPE.convert(value, None, None)
|
||||
|
||||
|
||||
class TestTickFlagsType:
|
||||
"""Tests for _TickFlagsType."""
|
||||
|
||||
def test_convert_string(self) -> None:
|
||||
"""Test converting a string to tick flags integer."""
|
||||
assert TICK_FLAGS_TYPE.convert("ALL", None, None) == 1
|
||||
assert TICK_FLAGS_TYPE.convert("ALL", None, None) == -1
|
||||
|
||||
def test_convert_int_passthrough(self) -> None:
|
||||
"""Test that integer values pass through unchanged."""
|
||||
assert TICK_FLAGS_TYPE.convert(7, None, None) == 7
|
||||
def test_convert_int(self) -> None:
|
||||
"""Test converting supported integer tick flag values."""
|
||||
assert TICK_FLAGS_TYPE.convert(2, None, None) == 2
|
||||
|
||||
def test_convert_unsupported_int(self) -> None:
|
||||
"""Test that unsupported integer values raise BadParameter."""
|
||||
with pytest.raises(Exception, match="Invalid tick flags"):
|
||||
TICK_FLAGS_TYPE.convert(7, None, None)
|
||||
|
||||
@pytest.mark.parametrize("value", [True, False, None, 1.5])
|
||||
def test_convert_invalid_types(self, value: object) -> None:
|
||||
"""Test that bool, float, and None values raise BadParameter."""
|
||||
with pytest.raises(Exception, match="Invalid tick flags"):
|
||||
TICK_FLAGS_TYPE.convert(value, None, None)
|
||||
|
||||
def test_convert_invalid(self) -> None:
|
||||
"""Test that invalid values raise BadParameter."""
|
||||
|
||||
Reference in New Issue
Block a user