#!/usr/bin/env python3 """ AI Trading CLI Commands Advanced AI-powered trading algorithms and analytics """ import click import asyncio import json from typing import Optional, List, Dict, Any from datetime import datetime, timedelta # Ensure coordinator-api src is on path for app.services imports import os import sys _src_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'apps', 'coordinator-api', 'src')) if _src_path not in sys.path: sys.path.insert(0, _src_path) try: from app.services.ai_trading_engine import ( initialize_ai_engine, train_strategies, generate_trading_signals, get_engine_status, ai_trading_engine, TradingStrategy ) _import_error = None except ImportError as e: _import_error = e def _missing(*args, **kwargs): raise ImportError( f"Required service module 'app.services.ai_trading_engine' could not be imported: {_import_error}. " "Ensure coordinator-api dependencies are installed and the source directory is accessible." ) initialize_ai_engine = train_strategies = generate_trading_signals = get_engine_status = _missing ai_trading_engine = None class TradingStrategy: pass @click.group() def ai_trading(): """AI-powered trading and analytics commands""" pass @ai_trading.command() @click.pass_context def init(ctx): """Initialize AI trading engine""" try: click.echo(f"๐Ÿค– Initializing AI Trading Engine...") success = asyncio.run(initialize_ai_engine()) if success: click.echo(f"โœ… AI Trading Engine initialized successfully!") click.echo(f"๐Ÿ“Š Default strategies loaded:") click.echo(f" โ€ข Mean Reversion Strategy") click.echo(f" โ€ข Momentum Strategy") else: click.echo(f"โŒ Failed to initialize AI Trading Engine") except Exception as e: click.echo(f"โŒ Initialization failed: {e}", err=True) @ai_trading.command() @click.option("--symbol", default="BTC/USDT", help="Trading symbol") @click.option("--days", type=int, default=30, help="Days of historical data for training") @click.pass_context def train(ctx, symbol: str, days: int): """Train AI trading strategies""" try: click.echo(f"๐Ÿง  Training AI Trading Strategies...") click.echo(f"๐Ÿ“Š Symbol: {symbol}") click.echo(f"๐Ÿ“… Training Period: {days} days") success = asyncio.run(train_strategies(symbol, days)) if success: click.echo(f"โœ… Training completed successfully!") # Get training results status = get_engine_status() click.echo(f"๐Ÿ“ˆ Training Results:") click.echo(f" Strategies Trained: {status['trained_strategies']}/{status['strategies_count']}") click.echo(f" Success Rate: 100%") click.echo(f" Data Points: {days * 24} (hourly data)") else: click.echo(f"โŒ Training failed") except Exception as e: click.echo(f"โŒ Training failed: {e}", err=True) @ai_trading.command() @click.option("--symbol", default="BTC/USDT", help="Trading symbol") @click.option("--count", type=int, default=10, help="Number of signals to show") @click.pass_context def signals(ctx, symbol: str, count: int): """Generate AI trading signals""" try: click.echo(f"๐Ÿ“ˆ Generating AI Trading Signals...") click.echo(f"๐Ÿ“Š Symbol: {symbol}") signals = asyncio.run(generate_trading_signals(symbol)) if not signals: click.echo(f"โŒ No signals generated. Make sure strategies are trained.") return click.echo(f"\n๐ŸŽฏ Generated {len(signals)} Trading Signals:") # Display signals for i, signal in enumerate(signals[:count]): signal_icon = { "buy": "๐ŸŸข", "sell": "๐Ÿ”ด", "hold": "๐ŸŸก" }.get(signal['signal_type'], "โ“") confidence_color = "๐Ÿ”ฅ" if signal['confidence'] > 0.8 else "โšก" if signal['confidence'] > 0.6 else "๐Ÿ’ก" click.echo(f"\n{signal_icon} Signal #{i+1}") click.echo(f" Strategy: {signal['strategy'].replace('_', ' ').title()}") click.echo(f" Signal: {signal['signal_type'].upper()}") click.echo(f" Confidence: {signal['confidence']:.2%} {confidence_color}") click.echo(f" Predicted Return: {signal['predicted_return']:.2%}") click.echo(f" Risk Score: {signal['risk_score']:.2f}") click.echo(f" Reasoning: {signal['reasoning']}") click.echo(f" Time: {signal['timestamp'][:19]}") if len(signals) > count: click.echo(f"\n... and {len(signals) - count} more signals") # Show summary buy_signals = len([s for s in signals if s['signal_type'] == 'buy']) sell_signals = len([s for s in signals if s['signal_type'] == 'sell']) hold_signals = len([s for s in signals if s['signal_type'] == 'hold']) click.echo(f"\n๐Ÿ“Š Signal Summary:") click.echo(f" ๐ŸŸข Buy Signals: {buy_signals}") click.echo(f" ๐Ÿ”ด Sell Signals: {sell_signals}") click.echo(f" ๐ŸŸก Hold Signals: {hold_signals}") except Exception as e: click.echo(f"โŒ Signal generation failed: {e}", err=True) @ai_trading.command() @click.pass_context def status(ctx): """Show AI trading engine status""" try: click.echo(f"๐Ÿค– AI Trading Engine Status") status = get_engine_status() click.echo(f"\n๐Ÿ“Š Engine Overview:") click.echo(f" Total Strategies: {status['strategies_count']}") click.echo(f" Trained Strategies: {status['trained_strategies']}") click.echo(f" Active Signals: {status['active_signals']}") click.echo(f" Market Data Symbols: {len(status['market_data_symbols'])}") if status['market_data_symbols']: click.echo(f" Available Symbols: {', '.join(status['market_data_symbols'])}") # Performance metrics metrics = status.get('performance_metrics', {}) if metrics: click.echo(f"\n๐Ÿ“ˆ Performance Metrics:") click.echo(f" Total Signals Generated: {metrics.get('total_signals', 0)}") click.echo(f" Recent Signals: {metrics.get('recent_signals', 0)}") click.echo(f" Average Confidence: {metrics.get('avg_confidence', 0):.1%}") click.echo(f" Average Risk Score: {metrics.get('avg_risk_score', 0):.2f}") click.echo(f"\n๐Ÿ“Š Signal Distribution:") click.echo(f" ๐ŸŸข Buy Signals: {metrics.get('buy_signals', 0)}") click.echo(f" ๐Ÿ”ด Sell Signals: {metrics.get('sell_signals', 0)}") click.echo(f" ๐ŸŸก Hold Signals: {metrics.get('hold_signals', 0)}") # Strategy status if ai_trading_engine.strategies: click.echo(f"\n๐Ÿง  Strategy Status:") for strategy_name, strategy in ai_trading_engine.strategies.items(): status_icon = "โœ…" if strategy.is_trained else "โŒ" click.echo(f" {status_icon} {strategy_name.replace('_', ' ').title()}") except Exception as e: click.echo(f"โŒ Status check failed: {e}", err=True) @ai_trading.command() @click.option("--strategy", required=True, help="Strategy to backtest") @click.option("--symbol", default="BTC/USDT", help="Trading symbol") @click.option("--days", type=int, default=30, help="Backtesting period in days") @click.option("--capital", type=float, default=10000, help="Initial capital") @click.pass_context def backtest(ctx, strategy: str, symbol: str, days: int, capital: float): """Backtest AI trading strategy""" try: click.echo(f"๐Ÿ“Š Backtesting AI Trading Strategy...") click.echo(f"๐Ÿง  Strategy: {strategy}") click.echo(f"๐Ÿ“Š Symbol: {symbol}") click.echo(f"๐Ÿ“… Period: {days} days") click.echo(f"๐Ÿ’ฐ Initial Capital: ${capital:,.2f}") # Calculate date range end_date = datetime.now() start_date = end_date - timedelta(days=days) # Run backtest result = asyncio.run(ai_trading_engine.backtest_strategy( strategy, symbol, start_date, end_date, capital )) click.echo(f"\n๐Ÿ“ˆ Backtest Results:") click.echo(f" Strategy: {result.strategy.value.replace('_', ' ').title()}") click.echo(f" Period: {result.start_date.strftime('%Y-%m-%d')} to {result.end_date.strftime('%Y-%m-%d')}") click.echo(f" Initial Capital: ${result.initial_capital:,.2f}") click.echo(f" Final Capital: ${result.final_capital:,.2f}") # Performance metrics total_return_pct = result.total_return * 100 click.echo(f"\n๐Ÿ“Š Performance:") click.echo(f" Total Return: {total_return_pct:.2f}%") click.echo(f" Sharpe Ratio: {result.sharpe_ratio:.2f}") click.echo(f" Max Drawdown: {result.max_drawdown:.2%}") click.echo(f" Win Rate: {result.win_rate:.1%}") # Trading statistics click.echo(f"\n๐Ÿ“‹ Trading Statistics:") click.echo(f" Total Trades: {result.total_trades}") click.echo(f" Profitable Trades: {result.profitable_trades}") click.echo(f" Average Trade: ${(result.final_capital - result.initial_capital) / max(result.total_trades, 1):.2f}") # Performance assessment if total_return_pct > 10: assessment = "๐Ÿ”ฅ EXCELLENT" elif total_return_pct > 5: assessment = "โšก GOOD" elif total_return_pct > 0: assessment = "๐Ÿ’ก POSITIVE" else: assessment = "โŒ NEGATIVE" click.echo(f"\n{assessment} Performance Assessment") except Exception as e: click.echo(f"โŒ Backtesting failed: {e}", err=True) @ai_trading.command() @click.option("--symbol", default="BTC/USDT", help="Trading symbol") @click.option("--hours", type=int, default=24, help="Analysis period in hours") @click.pass_context def analyze(ctx, symbol: str, hours: int): """Analyze market with AI insights""" try: click.echo(f"๐Ÿ” AI Market Analysis...") click.echo(f"๐Ÿ“Š Symbol: {symbol}") click.echo(f"โฐ Period: {hours} hours") # Get market data market_data = ai_trading_engine.market_data.get(symbol) if not market_data: click.echo(f"โŒ No market data available for {symbol}") click.echo(f"๐Ÿ’ก Train strategies first with: aitbc ai-trading train --symbol {symbol}") return # Get recent data recent_data = market_data.tail(hours) if len(recent_data) == 0: click.echo(f"โŒ No recent data available") return # Calculate basic statistics current_price = recent_data.iloc[-1]['close'] price_change = (current_price - recent_data.iloc[0]['close']) / recent_data.iloc[0]['close'] volatility = recent_data['close'].pct_change().std() volume_avg = recent_data['volume'].mean() click.echo(f"\n๐Ÿ“Š Market Analysis:") click.echo(f" Current Price: ${current_price:,.2f}") click.echo(f" Price Change: {price_change:.2%}") click.echo(f" Volatility: {volatility:.2%}") click.echo(f" Average Volume: {volume_avg:,.0f}") # Generate AI signals signals = asyncio.run(generate_trading_signals(symbol)) if signals: click.echo(f"\n๐Ÿค– AI Insights:") for signal in signals: signal_icon = {"buy": "๐ŸŸข", "sell": "๐Ÿ”ด", "hold": "๐ŸŸก"}.get(signal['signal_type'], "โ“") click.echo(f" {signal_icon} {signal['strategy'].replace('_', ' ').title()}:") click.echo(f" Signal: {signal['signal_type'].upper()}") click.echo(f" Confidence: {signal['confidence']:.1%}") click.echo(f" Reasoning: {signal['reasoning']}") # Market recommendation if signals: buy_signals = len([s for s in signals if s['signal_type'] == 'buy']) sell_signals = len([s for s in signals if s['signal_type'] == 'sell']) if buy_signals > sell_signals: recommendation = "๐ŸŸข BULLISH - Multiple buy signals detected" elif sell_signals > buy_signals: recommendation = "๐Ÿ”ด BEARISH - Multiple sell signals detected" else: recommendation = "๐ŸŸก NEUTRAL - Mixed signals, hold position" click.echo(f"\n๐ŸŽฏ AI Recommendation: {recommendation}") except Exception as e: click.echo(f"โŒ Analysis failed: {e}", err=True) @ai_trading.command() @click.pass_context def strategies(ctx): """List available AI trading strategies""" try: click.echo(f"๐Ÿง  Available AI Trading Strategies") strategies = { "mean_reversion": { "name": "Mean Reversion", "description": "Identifies overbought/oversold conditions using statistical analysis", "indicators": ["Z-score", "Rolling mean", "Standard deviation"], "time_horizon": "Short-term (hours to days)", "risk_level": "Moderate", "best_conditions": "Sideways markets with clear mean" }, "momentum": { "name": "Momentum", "description": "Follows price trends and momentum indicators", "indicators": ["Price momentum", "Trend strength", "Volume analysis"], "time_horizon": "Medium-term (days to weeks)", "risk_level": "Moderate", "best_conditions": "Trending markets with clear direction" } } for strategy_key, strategy_info in strategies.items(): click.echo(f"\n๐Ÿ“Š {strategy_info['name']}") click.echo(f" Description: {strategy_info['description']}") click.echo(f" Indicators: {', '.join(strategy_info['indicators'])}") click.echo(f" Time Horizon: {strategy_info['time_horizon']}") click.echo(f" Risk Level: {strategy_info['risk_level'].title()}") click.echo(f" Best For: {strategy_info['best_conditions']}") # Show current status if ai_trading_engine.strategies: click.echo(f"\n๐Ÿ”ง Current Strategy Status:") for strategy_name, strategy in ai_trading_engine.strategies.items(): status_icon = "โœ…" if strategy.is_trained else "โŒ" click.echo(f" {status_icon} {strategy_name.replace('_', ' ').title()}") click.echo(f"\n๐Ÿ’ก Usage Examples:") click.echo(f" aitbc ai-trading train --symbol BTC/USDT") click.echo(f" aitbc ai-trading signals --symbol ETH/USDT") click.echo(f" aitbc ai-trading backtest --strategy mean_reversion --symbol BTC/USDT") except Exception as e: click.echo(f"โŒ Strategy listing failed: {e}", err=True) @ai_trading.command() @click.pass_context def test(ctx): """Test AI trading engine functionality""" try: click.echo(f"๐Ÿงช Testing AI Trading Engine...") # Test 1: Initialize click.echo(f"\n๐Ÿ“‹ Test 1: Engine Initialization") init_success = asyncio.run(initialize_ai_engine()) click.echo(f" โœ… Initialization: {'Success' if init_success else 'Failed'}") # Test 2: Train strategies click.echo(f"\n๐Ÿ“‹ Test 2: Strategy Training") train_success = asyncio.run(train_strategies("BTC/USDT", 7)) click.echo(f" โœ… Training: {'Success' if train_success else 'Failed'}") # Test 3: Generate signals click.echo(f"\n๐Ÿ“‹ Test 3: Signal Generation") signals = asyncio.run(generate_trading_signals("BTC/USDT")) click.echo(f" โœ… Signals Generated: {len(signals)}") # Test 4: Status check click.echo(f"\n๐Ÿ“‹ Test 4: Status Check") status = get_engine_status() click.echo(f" โœ… Status Retrieved: {len(status)} metrics") # Show summary click.echo(f"\n๐ŸŽ‰ Test Results Summary:") click.echo(f" Engine Status: {'โœ… Operational' if init_success and train_success else 'โŒ Issues'}") click.echo(f" Strategies: {status['strategies_count']} loaded, {status['trained_strategies']} trained") click.echo(f" Signals: {status['active_signals']} generated") if init_success and train_success: click.echo(f"\nโœ… AI Trading Engine is ready for production use!") else: click.echo(f"\nโš ๏ธ Some issues detected - check logs for details") except Exception as e: click.echo(f"โŒ Test failed: {e}", err=True) if __name__ == "__main__": ai_trading()