exchange-data-manager/tests/test_candles.py

215 lines
6.4 KiB
Python

"""Tests for candle models."""
import pytest
from exchange_data_manager.candles.models import Candle, CandleRequest
class TestCandle:
"""Tests for Candle dataclass."""
def test_create_candle(self):
"""Test creating a candle."""
candle = Candle(
time=1709337600,
open=50000.0,
high=51000.0,
low=49500.0,
close=50500.0,
volume=100.5,
)
assert candle.time == 1709337600
assert candle.open == 50000.0
assert candle.high == 51000.0
assert candle.low == 49500.0
assert candle.close == 50500.0
assert candle.volume == 100.5
assert candle.closed is True
def test_candle_closed_default(self):
"""Test that closed defaults to True."""
candle = Candle(
time=1709337600,
open=50000.0,
high=50000.0,
low=50000.0,
close=50000.0,
volume=0.0,
)
assert candle.closed is True
def test_candle_not_closed(self):
"""Test creating an unclosed candle."""
candle = Candle(
time=1709337600,
open=50000.0,
high=50000.0,
low=50000.0,
close=50000.0,
volume=0.0,
closed=False,
)
assert candle.closed is False
def test_to_dict(self):
"""Test converting candle to dictionary."""
candle = Candle(
time=1709337600,
open=50000.0,
high=51000.0,
low=49500.0,
close=50500.0,
volume=100.5,
)
result = candle.to_dict()
assert result == {
"time": 1709337600,
"open": 50000.0,
"high": 51000.0,
"low": 49500.0,
"close": 50500.0,
"volume": 100.5,
"closed": True,
}
def test_from_dict(self):
"""Test creating candle from dictionary."""
data = {
"time": 1709337600,
"open": 50000.0,
"high": 51000.0,
"low": 49500.0,
"close": 50500.0,
"volume": 100.5,
}
candle = Candle.from_dict(data)
assert candle.time == 1709337600
assert candle.open == 50000.0
assert candle.high == 51000.0
assert candle.low == 49500.0
assert candle.close == 50500.0
assert candle.volume == 100.5
def test_from_ccxt(self):
"""Test creating candle from ccxt OHLCV format."""
# ccxt format: [timestamp_ms, open, high, low, close, volume]
ohlcv = [1709337600000, 50000.0, 51000.0, 49500.0, 50500.0, 100.5]
candle = Candle.from_ccxt(ohlcv)
# Time should be converted from ms to seconds
assert candle.time == 1709337600
assert candle.open == 50000.0
assert candle.high == 51000.0
assert candle.low == 49500.0
assert candle.close == 50500.0
assert candle.volume == 100.5
assert candle.closed is True
def test_timestamp_ms_property(self):
"""Test timestamp_ms property."""
candle = Candle(
time=1709337600,
open=50000.0,
high=50000.0,
low=50000.0,
close=50000.0,
volume=0.0,
)
assert candle.timestamp_ms == 1709337600000
def test_datetime_property(self):
"""Test datetime property."""
candle = Candle(
time=1709337600,
open=50000.0,
high=50000.0,
low=50000.0,
close=50000.0,
volume=0.0,
)
dt = candle.datetime
assert dt.year == 2024
assert dt.month == 3
assert dt.day == 2 # 1709337600 = 2024-03-02 00:00:00 UTC
class TestCandleRequest:
"""Tests for CandleRequest dataclass."""
def test_create_request(self):
"""Test creating a candle request."""
request = CandleRequest(
exchange="binance",
symbol="BTC/USDT",
timeframe="5m",
)
assert request.exchange == "binance"
assert request.symbol == "BTC/USDT"
assert request.timeframe == "5m"
assert request.start is None
assert request.end is None
assert request.limit is None
def test_create_request_with_range(self):
"""Test creating a candle request with time range."""
request = CandleRequest(
exchange="binance",
symbol="BTC/USDT",
timeframe="1h",
start=1709251200,
end=1709337600,
limit=100,
)
assert request.start == 1709251200
assert request.end == 1709337600
assert request.limit == 100
def test_cache_key_property(self):
"""Test cache key generation."""
request = CandleRequest(
exchange="Binance", # Mixed case
symbol="btc/usdt", # Lowercase
timeframe="5M", # Uppercase
)
# Should be normalized
assert request.cache_key == "binance:BTC/USDT:5m"
def test_cache_key_different_symbols(self):
"""Test that different symbols produce different keys."""
request1 = CandleRequest(exchange="binance", symbol="BTC/USDT", timeframe="5m")
request2 = CandleRequest(exchange="binance", symbol="ETH/USDT", timeframe="5m")
assert request1.cache_key != request2.cache_key
def test_cache_key_different_timeframes(self):
"""Test that different timeframes produce different keys."""
request1 = CandleRequest(exchange="binance", symbol="BTC/USDT", timeframe="5m")
request2 = CandleRequest(exchange="binance", symbol="BTC/USDT", timeframe="1h")
assert request1.cache_key != request2.cache_key
def test_symbol_normalization(self):
"""Test that symbols are normalized."""
# Lowercase should be uppercased
request = CandleRequest(exchange="binance", symbol="btc/usdt", timeframe="5m")
assert request.symbol == "BTC/USDT"
def test_symbol_separator_added(self):
"""Test that separator is added to symbols without one."""
request = CandleRequest(exchange="binance", symbol="BTCUSDT", timeframe="5m")
assert request.symbol == "BTC/USDT"
def test_exchange_normalization(self):
"""Test that exchange is normalized to lowercase."""
request = CandleRequest(exchange="BINANCE", symbol="BTC/USDT", timeframe="5m")
assert request.exchange == "binance"