Files
crypto_trading/backend/tests/test_indicators.py
T
matitos c500fb7572
CI/CD / backend (pull_request) Successful in 5m21s
CI/CD / frontend (pull_request) Successful in 5m4s
CI/CD / build (pull_request) Skipped
CI/CD / deploy (pull_request) Skipped
CI/CD / cleanup (pull_request) Skipped
Bitcoin favicon, more strategies, default timeframe 5m
- Add an SVG Bitcoin favicon and link it in index.html.
- New indicators: macd() and roc().
- Five new strategies: macd_trend, bollinger_reversion, donchian_breakout,
  ema_cross, momentum (plus the existing sma_cross, rsi_reversion).
- Default TIMEFRAME is now 5m (config, .env.example, compose, workflow, UI).
2026-09-18 20:03:30 +00:00

63 lines
1.8 KiB
Python

from __future__ import annotations
import pytest
from app.engine.indicators import atr, ema, macd, roc, rolling_std, rsi, sma
from app.schemas import Candle
def candle(high: float, low: float, close: float, open_: float | None = None) -> Candle:
return Candle(
ts=0,
open=open_ if open_ is not None else close,
high=high,
low=low,
close=close,
volume=1,
)
def test_sma() -> None:
assert sma([1, 2, 3, 4, 5], 3) == [None, None, 2.0, 3.0, 4.0]
def test_ema() -> None:
assert ema([1, 2, 3, 4, 5], 3) == [None, None, 2.0, 3.0, 4.0]
def test_rsi_monotonic_is_100() -> None:
values = [float(i) for i in range(1, 20)]
assert rsi(values, 14)[-1] == pytest.approx(100.0)
def test_atr_flat_market_is_zero() -> None:
candles = [candle(100, 100, 100) for _ in range(20)]
assert atr(candles, 5)[-1] == pytest.approx(0.0)
def test_rolling_std() -> None:
result = rolling_std([1, 1, 1, 1], 2)
assert result[-1] == pytest.approx(0.0)
def test_roc() -> None:
values = [100.0, 110.0, 121.0, 100.0]
out = roc(values, 2)
assert out[0] is None and out[1] is None
assert out[2] == pytest.approx(0.21)
assert out[3] == pytest.approx(-0.09090909, rel=1e-4)
def test_macd_shapes_and_crossover_sign() -> None:
rising = [float(i) for i in range(1, 80)]
macd_line, signal_line, histogram = macd(rising, 12, 26, 9)
assert len(macd_line) == len(rising)
assert macd_line[-1] is not None and signal_line[-1] is not None
# In a steady uptrend MACD is positive (but can be below its signal after lag).
assert macd_line[-1] > 0
assert histogram[-1] == pytest.approx(macd_line[-1] - signal_line[-1])
falling = [float(i) for i in range(80, 0, -1)]
macd_falling, _, _ = macd(falling, 12, 26, 9)
assert macd_falling[-1] < 0