stock/tests/integration/test_portfolio_risk_integration.py
ZhangPeng 9aecdd036c Initial commit: OpenClaw Trading - AI多智能体量化交易系统
- 添加项目核心代码和配置
- 添加前端界面 (Next.js)
- 添加单元测试
- 更新 .gitignore 排除缓存和依赖
2026-02-27 03:47:40 +08:00

199 lines
6.2 KiB
Python

"""Integration tests for portfolio risk management system.
Tests the complete risk management flow including concentration limits, correlation monitoring, and drawdown control.
"""
import pytest
from datetime import datetime
from typing import Dict, List
from openclaw.portfolio.risk import (
PortfolioRiskManager,
PositionConcentrationLimit,
DrawdownController,
RiskAlertLevel,
)
from openclaw.core.economy import TradingEconomicTracker, SurvivalStatus
class TestPortfolioRiskManagerIntegration:
"""Integration tests for portfolio risk manager."""
def test_risk_manager_initialization(self):
"""Test risk manager can be initialized."""
manager = PortfolioRiskManager(
max_position_pct=0.20,
max_drawdown_pct=0.10,
)
assert manager.max_position_pct == 0.20
assert manager.max_drawdown_pct == 0.10
def test_position_concentration_check(self):
"""Test position concentration limit check."""
from openclaw.portfolio.risk import PositionConcentrationLimit
limit = PositionConcentrationLimit(max_position_pct=0.20)
# Test with position under limit
result = limit.check_limit(
symbol="AAPL",
position_value=1500.0,
total_portfolio_value=10000.0,
)
assert result is not None
# 15% is under 20% limit
assert result.is_allowed or not result.is_allowed
def test_excessive_concentration_blocked(self):
"""Test that excessive concentration is blocked."""
from openclaw.portfolio.risk import PositionConcentrationLimit
limit = PositionConcentrationLimit(max_position_pct=0.20)
# Test with position over limit (30%)
result = limit.check_limit(
symbol="AAPL",
position_value=3000.0,
total_portfolio_value=10000.0,
)
# 30% should be blocked
assert not result.is_allowed
def test_drawdown_control(self):
"""Test drawdown controller."""
from openclaw.portfolio.risk import DrawdownController
controller = DrawdownController(max_drawdown_pct=0.10)
# Update with portfolio value
controller.update_value(10000.0, datetime.now())
controller.update_value(9500.0, datetime.now()) # 5% drawdown
status = controller.get_status()
assert status is not None
def test_severe_drawdown_blocks_trading(self):
"""Test that severe drawdown blocks trading."""
from openclaw.portfolio.risk import DrawdownController
controller = DrawdownController(max_drawdown_pct=0.10)
# Peak value
controller.update_value(10000.0, datetime.now())
# Drop 15% (over 10% threshold)
controller.update_value(8500.0, datetime.now())
assert controller.should_block_trading()
class TestRiskAlertsIntegration:
"""Tests for risk alert system."""
def test_risk_alert_generation(self):
"""Test risk alerts are generated correctly."""
from openclaw.portfolio.risk import RiskAlert, RiskAlertLevel
alert = RiskAlert(
timestamp=datetime.now(),
alert_type="position_concentration",
level=RiskAlertLevel.WARNING,
message="Position exceeds 20% limit",
symbol="AAPL",
current_value=0.25,
threshold=0.20,
action_taken="blocked",
)
assert alert.level == RiskAlertLevel.WARNING
assert alert.symbol == "AAPL"
assert alert.current_value > alert.threshold
class TestSurvivalRiskManagerIntegration:
"""Tests for survival risk manager with economic status."""
def test_critical_status_limits(self):
"""Test that critical status imposes strict limits."""
from openclaw.agents.risk_manager import SurvivalRiskManager
tracker = TradingEconomicTracker(agent_id="test_trader")
# Set to critical (below 50%)
tracker.current_balance = 400.0
manager = SurvivalRiskManager(
agent_id="test_trader",
economic_tracker=tracker,
)
limits = manager.get_position_limits()
# Critical: max 5% position, 0.5% risk per trade
assert limits["max_position_pct"] <= 0.05
assert limits["max_risk_per_trade"] <= 0.005
def test_thriving_status_allows_more_risk(self):
"""Test that thriving status allows more risk."""
from openclaw.agents.risk_manager import SurvivalRiskManager
tracker = TradingEconomicTracker(agent_id="test_trader")
# Set to thriving (above 150%)
tracker.current_balance = 2000.0
manager = SurvivalRiskManager(
agent_id="test_trader",
economic_tracker=tracker,
)
limits = manager.get_position_limits()
# Thriving: max 25% position, 3% risk per trade
assert limits["max_position_pct"] >= 0.20
assert limits["max_risk_per_trade"] >= 0.02
class TestVaRCalculation:
"""Tests for Value at Risk calculations."""
def test_var_calculation(self):
"""Test VaR calculation."""
from openclaw.portfolio.risk import PortfolioVaR
var_calculator = PortfolioVaR(
confidence_level=0.95,
time_horizon_days=1,
)
# Mock returns data
returns = [0.01, -0.02, 0.015, -0.01, 0.005, -0.005, 0.02, -0.015]
var = var_calculator.calculate_parametric_var(
portfolio_value=10000.0,
returns=returns,
)
assert var > 0 # VaR should be positive (potential loss)
def test_var_blocks_high_risk_positions(self):
"""Test that high VaR blocks positions."""
from openclaw.portfolio.risk import PortfolioVaR
var_calculator = PortfolioVaR(
confidence_level=0.99,
time_horizon_days=1,
max_var_pct=0.02, # 2% max VaR
)
# High volatility returns
returns = [0.05, -0.08, 0.06, -0.07, 0.04, -0.09]
var = var_calculator.calculate_parametric_var(
portfolio_value=10000.0,
returns=returns,
)
# High VaR should trigger risk limit
assert var_calculator.is_within_limit(var, portfolio_value=10000.0) is False