Files
AutoCoinTrader/src/tests/test_boundary_conditions.py

113 lines
4.5 KiB
Python

"""
경계값 테스트: profit_rate가 정확히 10%, 30%일 때 매도 조건 검증
"""
import pytest
from src.signals import evaluate_sell_conditions
class TestBoundaryConditions:
"""매도 조건의 경계값 테스트"""
def test_profit_rate_exactly_10_percent_triggers_partial_sell(self):
"""수익률이 정확히 10%일 때 부분 매도(조건3) 발생"""
# Given: 매수가 100, 현재가 110 (정확히 10% 수익)
buy_price = 100.0
current_price = 110.0
max_price = 110.0
holding_info = {"partial_sell_done": False}
# When
result = evaluate_sell_conditions(current_price, buy_price, max_price, holding_info)
# Then
assert result["status"] == "stop_loss" # 부분 익절은 stop_loss (1시간 주기)
assert result["sell_ratio"] == 0.5
assert result["set_partial_sell_done"] is True
assert "부분 익절" in result["reasons"][0]
def test_profit_rate_exactly_30_percent_in_high_zone(self):
"""최고 수익률 30% 초과 구간에서 수익률이 정확히 30%로 떨어질 때"""
# Given: 최고가 135 (35% 수익), 현재가 130 (30% 수익)
buy_price = 100.0
current_price = 130.0
max_price = 135.0
holding_info = {"partial_sell_done": True}
# When
result = evaluate_sell_conditions(current_price, buy_price, max_price, holding_info)
# Then: 수익률이 30% 이하(<= 30)로 하락하여 조건5-2 발동 (stop_loss)
assert result["status"] == "stop_loss"
assert result["sell_ratio"] == 1.0
assert "수익률 보호(조건5" in result["reasons"][0] # 조건5-2도 매칭
def test_profit_rate_below_30_percent_triggers_sell(self):
"""최고 수익률 30% 초과 구간에서 수익률이 30% 미만으로 떨어질 때"""
# Given: 최고가 135 (35% 수익), 현재가 129.99 (29.99% 수익)
buy_price = 100.0
current_price = 129.99
max_price = 135.0
holding_info = {"partial_sell_done": True}
# When
result = evaluate_sell_conditions(current_price, buy_price, max_price, holding_info)
# Then: 조건5-2 발동 (수익률 30% 미만으로 하락)
assert result["status"] == "stop_loss"
assert result["sell_ratio"] == 1.0
assert "수익률 보호(조건5" in result["reasons"][0] # 조건5-2도 매칭
def test_profit_rate_exactly_10_percent_in_mid_zone(self):
"""최고 수익률 10~30% 구간에서 수익률이 정확히 10%일 때"""
# Given: 최고가 120 (20% 수익), 현재가 110 (10% 수익)
buy_price = 100.0
current_price = 110.0
max_price = 120.0
holding_info = {"partial_sell_done": True}
# When
result = evaluate_sell_conditions(current_price, buy_price, max_price, holding_info)
# Then: 수익률이 10% 이하(<= 10)로 하락하여 조건4-2 발동 (stop_loss)
assert result["status"] == "stop_loss"
assert result["sell_ratio"] == 1.0
assert "수익률 보호(조건4" in result["reasons"][0] # 조건4-2도 매칭
def test_profit_rate_below_10_percent_triggers_sell(self):
"""최고 수익률 10~30% 구간에서 수익률이 10% 미만으로 떨어질 때"""
# Given: 최고가 120 (20% 수익), 현재가 109.99 (9.99% 수익)
buy_price = 100.0
current_price = 109.99
max_price = 120.0
holding_info = {"partial_sell_done": True}
# When
result = evaluate_sell_conditions(current_price, buy_price, max_price, holding_info)
# Then: 조건4-2 발동 (수익률 10% 미만으로 하락)
assert result["status"] == "stop_loss"
assert result["sell_ratio"] == 1.0
assert "수익률 보호(조건4" in result["reasons"][0] # 조건4-2도 매칭
def test_partial_sell_already_done_no_duplicate(self):
"""부분 매도 이미 완료된 경우 중복 발동 안됨"""
# Given: 매수가 100, 현재가 110 (10% 수익), 이미 부분 매도 완료
buy_price = 100.0
current_price = 110.0
max_price = 110.0
holding_info = {"partial_sell_done": True}
# When
result = evaluate_sell_conditions(current_price, buy_price, max_price, holding_info)
# Then: 부분 매도 재발동 안됨
assert result["status"] == "hold"
assert result["sell_ratio"] == 0.0
assert result["set_partial_sell_done"] is False
if __name__ == "__main__":
pytest.main([__file__, "-v"])