"""
Тесты микроструктурных функций: Yang-Zhang vol, Roll spread.
"""
import numpy as np
from models.experts import _compute_yang_zhang_vol, _compute_roll_spread


def test_yang_zhang_vol_shape_and_positive():
    """YZ vol возвращает корректную форму и положительные значения."""
    import pandas as pd
    rng = np.random.default_rng(0)
    n = 100
    px = 100 + np.cumsum(rng.normal(0, 1, n))
    df = pd.DataFrame({
        'High': px * (1 + rng.uniform(0, 0.01, n)),
        'Low': px * (1 - rng.uniform(0, 0.01, n)),
        'Open': np.concatenate([[px[0]], px[:-1]]),
        'Close': px,
    })
    yz = _compute_yang_zhang_vol(df, period=20)
    assert yz.shape == (n,), f"Expected shape ({n},), got {yz.shape}"
    assert np.all(yz[20:] >= 0), "YZ vol must be non-negative"
    assert np.all(np.isfinite(yz)), "YZ vol must be finite"
    assert np.nanmean(yz[20:]) > 0, "YZ vol mean must be positive"


def test_yang_zhang_vol_constant_price():
    """YZ vol на const price = 0."""
    import pandas as pd
    n = 50
    df = pd.DataFrame({
        'High': [100.0] * n,
        'Low': [100.0] * n,
        'Open': [100.0] * n,
        'Close': [100.0] * n,
    })
    yz = _compute_yang_zhang_vol(df, period=10)
    assert np.allclose(yz, 0.0, atol=1e-10), "YZ vol on constant price should be 0"


def test_roll_spread_shape():
    """Roll spread возвращает корректную форму."""
    import pandas as pd
    rng = np.random.default_rng(42)
    n = 100
    df = pd.DataFrame({'Close': 100 + np.cumsum(rng.normal(0, 0.5, n))})
    spread = _compute_roll_spread(df, window=5)
    assert spread.shape == (n,), f"Expected shape ({n},), got {spread.shape}"
    assert np.all(spread >= 0), "Roll spread must be non-negative"
    assert np.all(np.isfinite(spread)), "Roll spread must be finite"
