ParallelLLC/algorithmic_trading
2732
1import pytest2import pandas as pd3import numpy as np4import tempfile5import os6from unittest.mock import patch, MagicMock7from agentic_ai_system.orchestrator import run, run_backtest, run_live_trading8from agentic_ai_system.main import load_config9 10class TestIntegration:11 """Integration tests for the entire trading system"""12 13 @pytest.fixture14 def config(self):15 """Sample configuration for integration testing"""16 return {17 'data_source': {18 'type': 'synthetic',19 'path': 'data/synthetic_market_data_test.csv'20 },21 'trading': {22 'symbol': 'AAPL',23 'timeframe': '1min',24 'capital': 10000025 },26 'risk': {27 'max_position': 100,28 'max_drawdown': 0.0529 },30 'execution': {31 'broker_api': 'paper',32 'order_size': 10,33 'delay_ms': 10, # Fast for testing34 'success_rate': 1.0 # Always succeed for testing35 },36 'synthetic_data': {37 'base_price': 150.0,38 'volatility': 0.02,39 'trend': 0.001,40 'noise_level': 0.005,41 'data_path': 'data/synthetic_market_data_test.csv'42 },43 'logging': {44 'log_level': 'INFO',45 'log_dir': 'logs',46 'enable_console': True,47 'enable_file': True48 }49 }50 51 def test_full_workflow(self, config):52 """Test the complete trading workflow"""53 result = run(config)54 55 # Check result structure56 assert isinstance(result, dict)57 assert 'success' in result58 assert 'data_loaded' in result59 assert 'signal_generated' in result60 assert 'order_executed' in result61 assert 'execution_time' in result62 assert 'errors' in result63 64 # Check that data was loaded65 assert result['data_loaded'] == True66 67 # Check that signal was generated68 assert result['signal_generated'] == True69 70 # Check execution time is reasonable71 assert result['execution_time'] > 072 assert result['execution_time'] < 60 # Should complete within 60 seconds73 74 def test_backtest_workflow(self, config):75 """Test the backtest workflow"""76 result = run_backtest(config, '2024-01-01', '2024-01-02')77 78 # Check result structure79 assert isinstance(result, dict)80 assert 'success' in result81 82 if result['success']:83 assert 'start_date' in result84 assert 'end_date' in result85 assert 'initial_capital' in result86 assert 'final_value' in result87 assert 'total_return' in result88 assert 'total_trades' in result89 assert 'trades' in result90 assert 'positions' in result91 92 # Check that backtest completed93 assert result['initial_capital'] == config['trading']['capital']94 assert result['final_value'] >= 095 assert isinstance(result['total_return'], float)96 assert result['total_trades'] >= 097 assert isinstance(result['trades'], list)98 assert isinstance(result['positions'], dict)99 100 def test_live_trading_workflow(self, config):101 """Test the live trading workflow (short duration)"""102 # Test with very short duration to avoid long test times103 result = run_live_trading(config, duration_minutes=1)104 105 # Check result structure106 assert isinstance(result, dict)107 assert 'success' in result108 109 if result['success']:110 assert 'duration_minutes' in result111 assert 'total_trades' in result112 assert 'trades' in result113 assert 'start_time' in result114 assert 'end_time' in result115 116 # Check that live trading completed117 assert result['duration_minutes'] == 1118 assert result['total_trades'] >= 0119 assert isinstance(result['trades'], list)120 121 def test_workflow_with_csv_data(self, config):122 """Test workflow with CSV data source"""123 # Create temporary CSV file124 with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as tmp_file:125 # Generate sample data with correct column names126 dates = pd.date_range(start='2024-01-01', periods=100, freq='1min')127 data = []128 for i, date in enumerate(dates):129 base_price = 150.0 + (i * 0.1)130 data.append({131 'date': date,132 'open': base_price + np.random.normal(0, 1),133 'high': base_price + abs(np.random.normal(0, 2)),134 'low': base_price - abs(np.random.normal(0, 2)),135 'close': base_price + np.random.normal(0, 1),136 'volume': np.random.randint(1000, 100000)137 })138 139 df = pd.DataFrame(data)140 df.to_csv(tmp_file.name, index=False)141 config['data_source']['type'] = 'csv'142 config['data_source']['path'] = tmp_file.name143 144 try:145 result = run(config)146 147 assert result['success'] == True148 assert result['data_loaded'] == True149 assert result['signal_generated'] == True150 151 finally:152 os.unlink(tmp_file.name)153 154 def test_workflow_error_handling(self, config):155 """Test workflow error handling"""156 # Test with invalid configuration157 invalid_config = config.copy()158 invalid_config['data_source']['type'] = 'invalid_type'159 160 result = run(invalid_config)161 162 assert result['success'] == False163 assert len(result['errors']) > 0164 165 def test_backtest_with_different_periods(self, config):166 """Test backtest with different time periods"""167 # Test short period168 short_result = run_backtest(config, '2024-01-01', '2024-01-01')169 assert isinstance(short_result, dict)170 171 # Test longer period172 long_result = run_backtest(config, '2024-01-01', '2024-01-07')173 assert isinstance(long_result, dict)174 175 # Both should be valid results (success or failure)176 assert 'success' in short_result177 assert 'success' in long_result178 179 def test_system_with_different_symbols(self, config):180 """Test system with different trading symbols"""181 symbols = ['AAPL', 'GOOGL', 'MSFT', 'TSLA']182 183 for symbol in symbols:184 test_config = config.copy()185 test_config['trading']['symbol'] = symbol186 187 result = run(test_config)188 189 assert result['success'] == True190 assert result['data_loaded'] == True191 assert result['signal_generated'] == True192 193 def test_system_with_different_capital_amounts(self, config):194 """Test system with different capital amounts"""195 capital_amounts = [10000, 50000, 100000, 500000]196 197 for capital in capital_amounts:198 test_config = config.copy()199 test_config['trading']['capital'] = capital200 201 result = run(test_config)202 203 assert result['success'] == True204 assert result['data_loaded'] == True205 assert result['signal_generated'] == True206 207 def test_execution_failure_simulation(self, config):208 """Test system behavior with execution failures"""209 # Set success rate to 0 to simulate all failures210 test_config = config.copy()211 test_config['execution']['success_rate'] = 0.0212 213 result = run(test_config)214 215 # System should still complete workflow216 assert result['success'] == True217 assert result['data_loaded'] == True218 assert result['signal_generated'] == True219 220 # If a non-hold order was executed, it should fail with success_rate = 0.0221 # But if only hold signals were generated, no orders would be executed222 if result['order_executed'] and result.get('execution_result', {}).get('action') != 'hold':223 assert result['execution_result']['success'] == False224 225 def test_data_validation_integration(self, config):226 """Test data validation integration"""227 # Create invalid data228 with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as tmp_file:229 invalid_data = pd.DataFrame({230 'date': pd.date_range('2024-01-01', periods=10, freq='1min'),231 'open': [150] * 10,232 'high': [145] * 10, # Invalid: high < open233 'low': [145] * 10,234 'close': [152] * 10,235 'volume': [1000] * 10236 })237 invalid_data.to_csv(tmp_file.name, index=False)238 config['data_source']['type'] = 'csv'239 config['data_source']['path'] = tmp_file.name240 241 try:242 result = run(config)243 244 # System should still work (fallback to synthetic data)245 assert result['success'] == True246 247 finally:248 os.unlink(tmp_file.name)249 250 def test_performance_metrics(self, config):251 """Test that performance metrics are calculated correctly"""252 result = run_backtest(config, '2024-01-01', '2024-01-03')253 254 if result['success']:255 # Check that return is calculated correctly256 initial_capital = result['initial_capital']257 final_value = result['final_value']258 calculated_return = (final_value - initial_capital) / initial_capital259 260 assert abs(result['total_return'] - calculated_return) < 0.001261 262 # Check that trade count is reasonable263 assert result['total_trades'] >= 0264 265 def test_config_loading(self):266 """Test configuration loading functionality"""267 # Test with valid config268 with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as tmp_file:269 config_content = """270data_source:271 type: 'synthetic'272 path: 'data/market_data.csv'273 274trading:275 symbol: 'AAPL'276 timeframe: '1min'277 capital: 100000278 279risk:280 max_position: 100281 max_drawdown: 0.05282 283execution:284 broker_api: 'paper'285 order_size: 10286"""287 tmp_file.write(config_content)288 tmp_file.flush()289 290 try:291 config = load_config(tmp_file.name)292 293 assert config['data_source']['type'] == 'synthetic'294 assert config['trading']['symbol'] == 'AAPL'295 assert config['trading']['capital'] == 100000296 297 finally:298 os.unlink(tmp_file.name)299 300 def test_system_scalability(self, config):301 """Test system scalability with larger datasets"""302 # Test with larger synthetic dataset303 test_config = config.copy()304 test_config['synthetic_data']['base_price'] = 200.0305 test_config['synthetic_data']['volatility'] = 0.03306 307 result = run(test_config)308 309 assert result['success'] == True310 assert result['data_loaded'] == True311 assert result['signal_generated'] == True312 313 # Check execution time is reasonable314 assert result['execution_time'] < 30 # Should complete within 30 seconds 