39 lines
1.2 KiB
Python
39 lines
1.2 KiB
Python
"""Tests for alpha signal computation."""
|
|
import pandas as pd
|
|
|
|
from signals.reversal import ReversalSignal
|
|
|
|
|
|
def _make_df(closes):
|
|
return pd.DataFrame({"close": closes})
|
|
|
|
|
|
def test_reversal_name():
|
|
assert ReversalSignal(lookback=5).name == "reversal_5d"
|
|
assert ReversalSignal(lookback=10).name == "reversal_10d"
|
|
|
|
|
|
def test_reversal_is_negative_trailing_return():
|
|
# Monotonically rising prices -> negative (bearish) reversal signal.
|
|
df = _make_df([10.0, 11.0, 12.0, 13.0, 14.0, 15.0])
|
|
sig = ReversalSignal(lookback=5).compute(df)
|
|
# First 5 values are NaN (insufficient lookback).
|
|
assert sig.iloc[:5].isna().all()
|
|
# 15/10 - 1 = 0.5 return -> signal = -0.5
|
|
assert abs(sig.iloc[5] - (-0.5)) < 1e-9
|
|
|
|
|
|
def test_reversal_oversold_is_positive():
|
|
# Falling prices -> positive (bullish) reversal signal.
|
|
df = _make_df([20.0, 18.0, 16.0, 14.0, 12.0, 10.0])
|
|
sig = ReversalSignal(lookback=5).compute(df)
|
|
assert sig.iloc[5] > 0
|
|
# 10/20 - 1 = -0.5 -> signal = +0.5
|
|
assert abs(sig.iloc[5] - 0.5) < 1e-9
|
|
|
|
|
|
def test_reversal_output_length_matches_input():
|
|
df = _make_df([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0])
|
|
sig = ReversalSignal(lookback=3).compute(df)
|
|
assert len(sig) == len(df)
|