Compare commits

..
Author SHA1 Message Date
google-labs-jules[bot]andmaghdam 01b82a03bc Add test file for data/data_loader.py
This commit introduces a new test file, `tests/test_data_loader.py`, to verify the functionality of `get_data_mt5`. It uses `unittest.mock.MagicMock` to mock the `MetaTrader5` module, allowing tests to run on Linux where the module cannot be imported.

The tests cover:
- Live trading data retrieval (`start_pos=None`).
- Backtesting data retrieval with a specific `start_pos`.
- Error handling when `copy_rates_from_pos` returns `None`.
- The proper conversion of rates into a pandas DataFrame with a parsed datetime index.

Co-authored-by: maghdam <63883156+maghdam@users.noreply.github.com>
2026-03-11 18:37:47 +00:00
13 changed files with 84 additions and 8 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+10 -8
View File
@@ -129,9 +129,11 @@ def parkinson_estimator(window: pd.DataFrame) -> float:
def moving_parkinson_estimator(df: pd.DataFrame, window_size: int = 30) -> pd.DataFrame:
dfc = df.copy()
sq_log_hl = np.log(dfc["high"] / dfc["low"]) ** 2
rolling_sum = sq_log_hl.rolling(window=window_size).sum().shift(1)
dfc["rolling_volatility_parkinson"] = np.sqrt(rolling_sum / (4 * math.log(2) * window_size))
rolling_vol = pd.Series(dtype="float64", index=dfc.index)
for i in range(window_size, len(dfc)):
w = dfc.iloc[i - window_size : i]
rolling_vol.iloc[i] = parkinson_estimator(w)
dfc["rolling_volatility_parkinson"] = rolling_vol
return dfc
@@ -146,11 +148,11 @@ def yang_zhang_estimator(window: pd.DataFrame) -> float:
def moving_yang_zhang_estimator(df: pd.DataFrame, window_size: int = 30) -> pd.DataFrame:
dfc = df.copy()
term1 = np.log(dfc["high"] / dfc["low"]) ** 2
term2 = np.log(dfc["close"] / dfc["open"]) ** 2
term_sum = term1 + term2
rolling_mean = term_sum.rolling(window=window_size).mean().shift(1)
dfc["rolling_volatility_yang_zhang"] = np.sqrt(rolling_mean)
rolling_vol = pd.Series(dtype="float64", index=dfc.index)
for i in range(window_size, len(dfc)):
w = dfc.iloc[i - window_size : i]
rolling_vol.iloc[i] = yang_zhang_estimator(w)
dfc["rolling_volatility_yang_zhang"] = rolling_vol
return dfc
+74
View File
@@ -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)