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

148 lines
4.9 KiB
Python

"""Integration tests for factor market system.
Tests the complete factor purchase and usage flow.
"""
import pytest
from datetime import datetime
from openclaw.factor import FactorStore
from openclaw.factor.base import BuyFactor, SellFactor
from openclaw.factor.basic import (
MovingAverageCrossoverFactor,
RSIOversoldFactor,
MACDCrossoverFactor,
)
from openclaw.factor.advanced import (
MachineLearningFactor,
SentimentMomentumFactor,
)
from openclaw.core.economy import TradingEconomicTracker
class TestFactorMarketIntegration:
"""Integration tests for factor market."""
def test_factor_store_initialization(self):
"""Test factor store can be initialized with tracker."""
tracker = TradingEconomicTracker(agent_id="test_trader")
store = FactorStore(agent_id="test_trader", tracker=tracker)
assert store.agent_id == "test_trader"
assert store.tracker == tracker
assert len(store.inventory) >= 0
def test_list_available_factors(self):
"""Test listing available factors."""
tracker = TradingEconomicTracker(agent_id="test_trader")
store = FactorStore(agent_id="test_trader", tracker=tracker)
factors = store.list_available()
assert isinstance(factors, list)
assert len(factors) > 0
def test_basic_factors_unlocked_by_default(self):
"""Test basic factors are unlocked by default."""
tracker = TradingEconomicTracker(agent_id="test_trader")
store = FactorStore(agent_id="test_trader", tracker=tracker)
# Basic factors should be available
basic_factor = store.get_factor("ma_crossover")
assert basic_factor is not None
assert basic_factor.metadata.price == 0.0
def test_advanced_factors_locked_by_default(self):
"""Test advanced factors are locked by default."""
tracker = TradingEconomicTracker(agent_id="test_trader")
store = FactorStore(agent_id="test_trader", tracker=tracker)
# Advanced factors should not be usable without purchase
ml_factor = store.get_factor("ml_prediction")
if ml_factor:
assert not ml_factor.is_unlocked()
class TestFactorPurchaseFlow:
"""Tests for factor purchase flow."""
def test_purchase_with_sufficient_balance(self):
"""Test purchasing factor with sufficient balance."""
tracker = TradingEconomicTracker(agent_id="test_trader")
# Add sufficient balance
tracker.record_income(500.0, "test_income")
store = FactorStore(agent_id="test_trader", tracker=tracker)
# Try to purchase an advanced factor
result = store.purchase("sentiment_momentum")
# Should succeed if balance is sufficient
assert result["success"] is True or result["success"] is False
def test_purchase_with_insufficient_balance(self):
"""Test purchasing factor with insufficient balance."""
tracker = TradingEconomicTracker(agent_id="test_trader")
# Start with minimal balance
store = FactorStore(agent_id="test_trader", tracker=tracker)
initial_balance = tracker.get_balance()
# Try to purchase expensive factor
result = store.purchase("ml_prediction", price=1000.0)
if not result["success"]:
assert "insufficient" in result.get("message", "").lower() or \
"cannot" in result.get("message", "").lower()
def test_purchase_deducts_balance(self):
"""Test that purchase deducts balance correctly."""
tracker = TradingEconomicTracker(agent_id="test_trader")
tracker.record_income(200.0, "test_income")
initial_balance = tracker.get_balance()
store = FactorStore(agent_id="test_trader", tracker=tracker)
# Purchase a factor
result = store.purchase("test_factor", price=50.0)
if result["success"]:
# Balance should be deducted
assert tracker.get_balance() <= initial_balance
class TestFactorEvaluation:
"""Tests for factor evaluation."""
def test_moving_average_factor_evaluation(self):
"""Test MA crossover factor evaluation."""
from openclaw.factor.types import FactorContext
factor = MovingAverageCrossoverFactor()
# Create mock context
context = FactorContext(
symbol="AAPL",
current_price=150.0,
data={}, # Simplified
timestamp=datetime.now(),
)
result = factor.evaluate(context)
assert result is not None
assert hasattr(result, "signal") or isinstance(result, dict)
def test_rsi_factor_evaluation(self):
"""Test RSI factor evaluation."""
from openclaw.factor.types import FactorContext
factor = RSIOversoldFactor()
context = FactorContext(
symbol="AAPL",
current_price=150.0,
data={},
timestamp=datetime.now(),
)
result = factor.evaluate(context)
assert result is not None