"""Independent arithmetic and proximity counterexamples for the research audit."""
import numpy as np
import pandas as pd
import pytest

from strategies.strategy_mlp_scores import _score_to_signals
from tools.run_mlp_entry_loss_experiment import evaluator
from tools.verify_mlp_revisit import measure, verify_trace


def test_smoothed_crossing_can_change_with_zero_raw_proximity():
    frame = pd.DataFrame(dict(activation_score=[200., .04, 199.92, 200.],
                              close=[100., 100., 101., 102.], high=[100., 100., 101., 102.]))
    params = dict(i_long_entry_activation_threshold=100.,
        i_long_exit_activation_threshold=900., i_long_exit_activation_confirmation_threshold=-900.,
        i_entry_score_window=2, i_trailing_stop_threshold=20.)
    assert evaluator().fragile_count(frame.activation_score, params, .05) == 0
    def replay(p):
        return _score_to_signals(frame.copy(), p, np.zeros(4), frame.close.to_numpy(), frame.high.to_numpy())
    original = replay(params)
    changed = replay(dict(params, i_long_entry_activation_threshold=100.05))
    assert original.execute_entry.tolist() == [False, False, True, False]
    assert changed.execute_entry.tolist() == [False, True, False, False]


def test_independent_measurement_keeps_first_loss_and_carry_in():
    times = pd.date_range('2026-02-28 12:00', periods=4, freq='6h').to_numpy()
    trace = dict(net_return=np.array([0., -.10, .02, -.03]),
                 execute_entry=np.array([True, False, False, False]),
                 execute_exit=np.array([False, False, False, True]))
    first = measure(times, trace, '2026-02-28', '2026-02-28')
    assert first['pnl_pct'] == pytest.approx(-10)
    assert first['dd_pct'] == pytest.approx(-10)
    carry = measure(times, trace, '2026-03-01', None)
    assert carry['entries'] == 0
    assert carry['pnl_pct'] == pytest.approx((1.02*.97-1)*100)


def test_verifier_rejects_corrupt_returns_and_invalid_position_transitions():
    times = pd.date_range('2026-01-01', periods=3, freq='6h').to_numpy()
    trace = dict(position=np.array([1, 1, 0]), execute_entry=np.array([True, False, False]),
                 execute_exit=np.array([False, False, True]), net_return=np.array([0., .095, -.005]))
    row = {'Period_Measurements': '[]'}
    verify_trace(times, np.array([100., 110., 110.]), trace, row)
    bad = dict(trace, net_return=np.array([0., .1, -.005]))
    with pytest.raises(AssertionError):
        verify_trace(times, np.array([100., 110., 110.]), bad, row)
    with pytest.raises(AssertionError):
        verify_trace(times, np.array([100., 110., 110.]), dict(trace, position=np.zeros(3)), row)
