from fxhnt.application.xsfunding_strategy import XsFundingForward


class _FakeLive:
    def __init__(self, seq): self._seq = seq; self._i = -1
    def snapshot(self, prev):
        self._i += 1
        return self._seq[self._i]


def _snap(funding):   # perp=spot=100 (no basis move), trailing=today=funding
    return {s: (f, f, 100.0, 100.0, 5e6) for s, f in funding.items()}


def test_inception_books_nothing():
    live = _FakeLive([_snap({"A": 0.002, "B": 0.001, "C": 0.0, "D": -0.001, "E": -0.002})])
    strat = XsFundingForward(live, quantile=0.4, clock=lambda: "2026-06-19")
    rows, extra = strat.advance(None, {})
    assert rows == []                       # no prior book to book at inception
    assert extra["positions"]               # executable weights set (long top-carry)
    assert any(w > 0 for w in extra["positions"].values())


def test_second_day_books_delta_neutral_return():
    day1 = _snap({"A": 0.002, "B": 0.001, "C": 0.0, "D": -0.001, "E": -0.002})
    day2 = {"A": (0.002, 0.002, 99.0, 100.0, 5e6),   # A perp 100->99 (short-perp gains) + funding
            "B": (0.001, 0.001, 100.0, 100.0, 5e6), "C": (0.0, 0.0, 100.0, 100.0, 5e6),
            "D": (-0.001, -0.001, 100.0, 100.0, 5e6), "E": (-0.002, -0.002, 100.0, 100.0, 5e6)}
    live = _FakeLive([day1, day2])
    strat = XsFundingForward(live, quantile=0.4, cost_bps=0.0, clock=lambda: "2026-06-20")
    _, extra = strat.advance(None, {})       # inception on day1
    rows, extra = strat.advance("2026-06-19", extra)
    assert len(rows) == 1 and rows[0][0] == "2026-06-20"
    assert rows[0][1] > 0.0                   # A long: short-perp gain (1%) + funding


def test_short_leg_profits_when_negative_funding_coin_craters():
    # market_neutral-ish: E (most negative funding) is shorted (long perp + short spot); if E's perp rises, short loses,
    # but here test the funding sign: E short-carry earns -w*funding>0 when funding negative. Keep prices flat.
    day1 = _snap({"A": 0.003, "B": 0.002, "C": 0.0, "D": -0.002, "E": -0.003})
    day2 = _snap({"A": 0.003, "B": 0.002, "C": 0.0, "D": -0.002, "E": -0.003})
    live = _FakeLive([day1, day2])
    strat = XsFundingForward(live, quantile=0.4, cost_bps=0.0, clock=lambda: "2026-06-20")
    _, extra = strat.advance(None, {})
    rows, _ = strat.advance("2026-06-19", extra)
    assert rows[0][1] > 0.0                   # long A (+0.003 funding) and short E (-w*-0.003>0) both positive carry
