- Introduced a new transformation module that includes safety limits for trade operations, enhancing data integrity and preventing errors. - Refactored existing transformation logic into dedicated classes and functions, improving modularity and maintainability. - Added detailed validation for trade sizes, prices, and symbol formats, ensuring compliance with trading rules. - Implemented logging for significant operations and validation checks, aiding in monitoring and debugging. - Created a changelog to document the new features and changes, providing clarity for future development. - Developed extensive unit tests to cover the new functionality, ensuring reliability and preventing regressions. These changes significantly enhance the architecture of the transformation module, making it more robust and easier to manage.
138 lines
3.9 KiB
Python
138 lines
3.9 KiB
Python
"""Tests for trade safety limits and validations."""
|
|
|
|
from decimal import Decimal
|
|
import pytest
|
|
|
|
from data.common.transformation.safety import (
|
|
TradeLimits,
|
|
DEFAULT_LIMITS,
|
|
STABLECOIN_LIMITS,
|
|
VOLATILE_LIMITS,
|
|
is_stablecoin_pair,
|
|
get_trade_limits,
|
|
validate_trade_size,
|
|
validate_trade_price,
|
|
validate_symbol_format
|
|
)
|
|
|
|
def test_stablecoin_detection():
|
|
"""Test stablecoin pair detection."""
|
|
# Test stablecoin pairs
|
|
assert is_stablecoin_pair('BTC-USDT')
|
|
assert is_stablecoin_pair('ETH/USDC')
|
|
assert is_stablecoin_pair('USDT-BTC')
|
|
assert is_stablecoin_pair('DAI/ETH')
|
|
|
|
# Test non-stablecoin pairs
|
|
assert not is_stablecoin_pair('BTC-ETH')
|
|
assert not is_stablecoin_pair('LTC/XRP')
|
|
assert not is_stablecoin_pair('DOT-SOL')
|
|
|
|
def test_get_trade_limits():
|
|
"""Test trade limits selection."""
|
|
# Stablecoin pairs should get higher limits
|
|
assert get_trade_limits('BTC-USDT') == STABLECOIN_LIMITS
|
|
assert get_trade_limits('ETH/USDC') == STABLECOIN_LIMITS
|
|
|
|
# Other pairs should get volatile limits
|
|
assert get_trade_limits('BTC-ETH') == VOLATILE_LIMITS
|
|
assert get_trade_limits('LTC/XRP') == VOLATILE_LIMITS
|
|
|
|
def test_validate_trade_size():
|
|
"""Test trade size validation."""
|
|
# Valid sizes should pass
|
|
validate_trade_size(
|
|
Decimal('1.0'),
|
|
Decimal('50000'),
|
|
'BTC-USDT'
|
|
)
|
|
|
|
# Test minimum size
|
|
with pytest.raises(ValueError, match='below minimum'):
|
|
validate_trade_size(
|
|
Decimal('0.000000001'),
|
|
Decimal('50000'),
|
|
'BTC-USDT'
|
|
)
|
|
|
|
# Test maximum size
|
|
with pytest.raises(ValueError, match='exceeds maximum'):
|
|
validate_trade_size(
|
|
Decimal('2000000'),
|
|
Decimal('50000'),
|
|
'BTC-USDT'
|
|
)
|
|
|
|
# Test minimum notional
|
|
with pytest.raises(ValueError, match='below minimum'):
|
|
validate_trade_size(
|
|
Decimal('0.00001'),
|
|
Decimal('10'),
|
|
'BTC-USDT'
|
|
)
|
|
|
|
# Test maximum notional
|
|
with pytest.raises(ValueError, match='exceeds maximum'):
|
|
validate_trade_size(
|
|
Decimal('1000'),
|
|
Decimal('1000000'),
|
|
'BTC-USDT'
|
|
)
|
|
|
|
def test_validate_trade_price():
|
|
"""Test trade price validation."""
|
|
# Valid prices should pass
|
|
validate_trade_price(
|
|
Decimal('50000'),
|
|
Decimal('49000'),
|
|
'BTC-USDT'
|
|
)
|
|
|
|
# Test maximum deviation for stablecoins
|
|
with pytest.raises(ValueError, match='deviation'):
|
|
validate_trade_price(
|
|
Decimal('1.10'),
|
|
Decimal('1.00'),
|
|
'USDT-USDC' # 10% deviation exceeds 5% limit
|
|
)
|
|
|
|
# Test maximum deviation for volatile pairs
|
|
with pytest.raises(ValueError, match='deviation'):
|
|
validate_trade_price(
|
|
Decimal('60000'),
|
|
Decimal('30000'),
|
|
'BTC-ETH' # 100% deviation exceeds 50% limit
|
|
)
|
|
|
|
# None market price should be handled
|
|
validate_trade_price(
|
|
Decimal('50000'),
|
|
None,
|
|
'BTC-USDT'
|
|
)
|
|
|
|
def test_validate_symbol_format():
|
|
"""Test symbol format validation."""
|
|
# Valid formats should pass
|
|
validate_symbol_format('BTC-USDT')
|
|
validate_symbol_format('ETH/USDC')
|
|
validate_symbol_format('LTC-BTC')
|
|
|
|
# Test invalid formats
|
|
with pytest.raises(ValueError):
|
|
validate_symbol_format('') # Empty
|
|
|
|
with pytest.raises(ValueError):
|
|
validate_symbol_format('BTCUSDT') # No separator
|
|
|
|
with pytest.raises(ValueError):
|
|
validate_symbol_format('BTC_USDT') # Wrong separator
|
|
|
|
with pytest.raises(ValueError):
|
|
validate_symbol_format('BTC-USD-T') # Too many parts
|
|
|
|
with pytest.raises(ValueError):
|
|
validate_symbol_format('a-b') # Too short
|
|
|
|
with pytest.raises(ValueError):
|
|
validate_symbol_format('VERYLONGTOKEN-BTC') # Too long |