diff --git a/data/__pycache__/__init__.cpython-311.pyc b/data/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 8f779c6..0000000 Binary files a/data/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/data/__pycache__/__init__.cpython-312.pyc b/data/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index e31893c..0000000 Binary files a/data/__pycache__/__init__.cpython-312.pyc and /dev/null differ diff --git a/data/__pycache__/data_loader.cpython-311.pyc b/data/__pycache__/data_loader.cpython-311.pyc deleted file mode 100644 index 447eec9..0000000 Binary files a/data/__pycache__/data_loader.cpython-311.pyc and /dev/null differ diff --git a/data/__pycache__/data_loader.cpython-312.pyc b/data/__pycache__/data_loader.cpython-312.pyc deleted file mode 100644 index 840903b..0000000 Binary files a/data/__pycache__/data_loader.cpython-312.pyc and /dev/null differ diff --git a/tests/test_data_loader.py b/tests/test_data_loader.py new file mode 100644 index 0000000..8f34001 --- /dev/null +++ b/tests/test_data_loader.py @@ -0,0 +1,74 @@ +import sys +from unittest.mock import MagicMock + +# Mock MetaTrader5 before importing data_loader +mt5_mock = MagicMock() +sys.modules['MetaTrader5'] = mt5_mock + +import pandas as pd +import pytest +from data.data_loader import get_data_mt5 + +def test_get_data_mt5_live_trading(): + """Test get_data_mt5 when start_pos is None (live trading).""" + # Arrange + symbol = "BTCUSD" + n_bars = 100 + timeframe = mt5_mock.TIMEFRAME_H1 + + # Mock return value of copy_rates_from_pos + mock_rates = [ + {"time": 1600000000, "open": 1.0, "high": 2.0, "low": 0.5, "close": 1.5}, + {"time": 1600003600, "open": 1.5, "high": 2.5, "low": 1.0, "close": 2.0}, + ] + mt5_mock.copy_rates_from_pos.return_value = mock_rates + + # Act + df = get_data_mt5(symbol, n_bars, timeframe) + + # Assert + mt5_mock.copy_rates_from_pos.assert_called_once_with(symbol, timeframe, 0, n_bars) + assert isinstance(df, pd.DataFrame) + assert df.index.name == 'time' + assert len(df) == 2 + assert "open" in df.columns + assert df.index[0] == pd.to_datetime(1600000000, unit='s') + +def test_get_data_mt5_backtesting(): + """Test get_data_mt5 when start_pos is provided (backtesting).""" + # Arrange + mt5_mock.copy_rates_from_pos.reset_mock() + symbol = "EURUSD" + n_bars = 50 + timeframe = mt5_mock.TIMEFRAME_M15 + start_pos = 10 + + mock_rates = [ + {"time": 1600000000, "open": 1.1, "high": 1.2, "low": 1.0, "close": 1.15}, + ] + mt5_mock.copy_rates_from_pos.return_value = mock_rates + + # Act + df = get_data_mt5(symbol, n_bars, timeframe, start_pos=start_pos) + + # Assert + mt5_mock.copy_rates_from_pos.assert_called_once_with(symbol, timeframe, start_pos, n_bars) + assert isinstance(df, pd.DataFrame) + assert df.index.name == 'time' + assert len(df) == 1 + +def test_get_data_mt5_no_data(): + """Test get_data_mt5 when copy_rates_from_pos returns None.""" + # Arrange + mt5_mock.copy_rates_from_pos.reset_mock() + symbol = "INVALID" + n_bars = 10 + timeframe = mt5_mock.TIMEFRAME_H1 + + mt5_mock.copy_rates_from_pos.return_value = None + + # Act & Assert + with pytest.raises(ValueError, match=f"Could not retrieve data for {symbol}"): + get_data_mt5(symbol, n_bars, timeframe) + + mt5_mock.copy_rates_from_pos.assert_called_once_with(symbol, timeframe, 0, n_bars)