#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ SmartBot AI Endpoint dengan ChatGPT Support =========================================== Endpoint AI yang mendukung multiple AI providers: - ChatGPT (OpenAI) - Local AI Model - Custom AI Model Installation: pip install flask pandas numpy openai requests python-dotenv Usage: python ai_endpoint_chatgpt.py """ from flask import Flask, request, jsonify import json import requests from datetime import datetime import logging import os from dotenv import load_dotenv # Load environment variables load_dotenv() # Setup logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) app = Flask(__name__) class ChatGPTProvider: """ChatGPT AI Provider""" def __init__(self): self.api_key = os.getenv('OPENAI_API_KEY') self.endpoint_url = "https://api.openai.com/v1/chat/completions" self.model = "gpt-3.5-turbo" def analyze_trade(self, data): """Analyze trade using ChatGPT""" try: if not self.api_key: return self._create_error_response("OpenAI API key not configured") # Create prompt prompt = self._create_analysis_prompt(data) # Call ChatGPT API response = self._call_chatgpt_api(prompt) # Parse response return self._parse_chatgpt_response(response, data) except Exception as e: logger.error(f"ChatGPT analysis error: {e}") return self._create_error_response(f"ChatGPT error: {str(e)}") def _create_analysis_prompt(self, data): """Create analysis prompt for ChatGPT""" pair = data.get('pair', 'Unknown') candidate = data.get('candidate', 'Unknown') mode = data.get('mode', 'intraday') indicators = data.get('indicators', {}) rsi = indicators.get('rsi', 0) adx = indicators.get('adx', 0) ema_fast = indicators.get('ema_fast', 0) ema_slow = indicators.get('ema_slow', 0) spread = data.get('spread', 0) atr = data.get('atr', 0) confirmations = data.get('confirmations', 0) signal_strength = data.get('signal_strength', 0) prompt = f""" Analyze this forex trading signal for {pair}: Signal: {candidate} Mode: {mode} Strength: {signal_strength}/100 Confirmations: {confirmations}/6 RSI: {rsi} ADX: {adx} EMA: {ema_fast}/{ema_slow} Spread: {spread} points ATR: {atr} Provide analysis in JSON format: {{ "verdict": "confirm_buy|confirm_sell|reject", "confidence": 0.85, "reason": "Explanation...", "suggested_sl": 1.2345, "suggested_tp": 1.2456 }} """ return prompt def _call_chatgpt_api(self, prompt): """Call ChatGPT API""" headers = { 'Authorization': f'Bearer {self.api_key}', 'Content-Type': 'application/json' } payload = { 'model': self.model, 'messages': [ {'role': 'system', 'content': 'You are a forex trading AI. Respond in JSON format only.'}, {'role': 'user', 'content': prompt} ], 'temperature': 0.3, 'max_tokens': 500 } response = requests.post(self.endpoint_url, headers=headers, json=payload) response.raise_for_status() return response.json() def _parse_chatgpt_response(self, response, original_data): """Parse ChatGPT response""" try: content = response['choices'][0]['message']['content'] # Extract JSON json_start = content.find('{') json_end = content.rfind('}') + 1 if json_start != -1 and json_end != 0: json_str = content[json_start:json_end] ai_response = json.loads(json_str) # Add metadata ai_response['timestamp'] = datetime.now().isoformat() ai_response['ai_provider'] = 'chatgpt' return ai_response else: return self._create_error_response("Invalid JSON response") except Exception as e: return self._create_error_response(f"Response parsing error: {str(e)}") def _create_error_response(self, error_msg): return { 'verdict': 'reject', 'confidence': 0.0, 'reason': error_msg, 'timestamp': datetime.now().isoformat(), 'ai_provider': 'chatgpt' } class LocalAIProvider: """Local AI Provider (Original SmartBot AI)""" def __init__(self): self.confidence_threshold = 0.7 self.min_signal_strength = 60 def analyze_trade(self, data): """Analyze trade using local AI logic""" try: candidate = data.get('candidate', '') if not candidate: return self._create_response('reject', 0.0, 'No trading candidate specified') # Calculate confidence confidence = self._calculate_confidence(data, candidate) # Decision logic if confidence < self.confidence_threshold: return self._create_response('reject', confidence, f'Confidence too low ({confidence:.2f} < {self.confidence_threshold})') # Check signal strength signal_strength = data.get('signal_strength', 0) if signal_strength < self.min_signal_strength: return self._create_response('reject', confidence, f'Signal strength too low ({signal_strength} < {self.min_signal_strength})') # Check confirmations confirmations = data.get('confirmations', 0) if confirmations < 3: return self._create_response('reject', confidence, f'Insufficient confirmations ({confirmations} < 3)') # Generate TP/SL suggestions tp_sl = self._calculate_optimal_tp_sl(data, candidate) # Decision if candidate == 'BUY': verdict = 'confirm_buy' reason = f'Strong buy signal with {confidence:.2f} confidence' elif candidate == 'SELL': verdict = 'confirm_sell' reason = f'Strong sell signal with {confidence:.2f} confidence' else: return self._create_response('reject', confidence, 'Invalid candidate') return self._create_response(verdict, confidence, reason, tp_sl) except Exception as e: logger.error(f"Local AI analysis error: {e}") return self._create_response('reject', 0.0, f'Error in analysis: {str(e)}') def _calculate_confidence(self, data, candidate): """Calculate confidence level""" try: signal_strength = data.get('signal_strength', 0) confirmations = data.get('confirmations', 0) # Base confidence base_confidence = min(signal_strength / 100.0, 1.0) confirmation_bonus = min(confirmations * 0.1, 0.3) # Market condition adjustments indicators = data.get('indicators', {}) rsi = indicators.get('rsi', 50) adx = indicators.get('adx', 25) # RSI adjustment if candidate == 'BUY' and rsi > 70: base_confidence -= 0.1 elif candidate == 'SELL' and rsi < 30: base_confidence -= 0.1 # ADX adjustment if adx < 20: base_confidence -= 0.05 # Spread penalty spread = data.get('spread', 0) if spread > 500: base_confidence -= 0.1 elif spread > 300: base_confidence -= 0.05 final_confidence = max(0.0, min(1.0, base_confidence + confirmation_bonus)) return final_confidence except Exception as e: logger.error(f"Error calculating confidence: {e}") return 0.5 def _calculate_optimal_tp_sl(self, data, candidate): """Calculate optimal TP/SL levels""" try: indicators = data.get('indicators', {}) ema_fast = indicators.get('ema_fast', 0) ema_slow = indicators.get('ema_slow', 0) atr = data.get('atr', 0.001) current_price = (ema_fast + ema_slow) / 2 if candidate == 'BUY': suggested_sl = current_price - (atr * 1.5) suggested_tp = current_price + (atr * 2.0) else: # SELL suggested_sl = current_price + (atr * 1.5) suggested_tp = current_price - (atr * 2.0) return { 'suggested_sl': round(suggested_sl, 5), 'suggested_tp': round(suggested_tp, 5) } except Exception as e: logger.error(f"Error calculating TP/SL: {e}") return None def _create_response(self, verdict, confidence, reason, tp_sl=None): """Create standardized response""" response = { 'verdict': verdict, 'confidence': round(confidence, 3), 'reason': reason, 'timestamp': datetime.now().isoformat(), 'ai_provider': 'local' } if tp_sl: response.update(tp_sl) return response class AIFactory: """Factory for creating AI providers""" @staticmethod def create_provider(provider_type): """Create AI provider based on type""" if provider_type == "chatgpt": return ChatGPTProvider() else: return LocalAIProvider() # Default to local AI # Initialize AI factory ai_factory = AIFactory() @app.route('/ai/trade', methods=['POST']) def trade_analysis(): """Main endpoint for trading analysis""" try: # Get request data data = request.get_json() if not data: return jsonify({ 'error': 'No data provided', 'verdict': 'reject' }), 400 # Get AI provider type from request ai_provider_type = data.get('ai_provider', 'local').lower() logger.info(f"Received trade analysis request: {data.get('pair', 'Unknown')} using {ai_provider_type}") # Create AI provider ai_provider = ai_factory.create_provider(ai_provider_type) # Generate AI decision decision = ai_provider.analyze_trade(data) logger.info(f"AI Decision ({ai_provider_type}): {decision['verdict']} (confidence: {decision['confidence']})") return jsonify(decision) except Exception as e: logger.error(f"Error in trade analysis: {e}") return jsonify({ 'error': str(e), 'verdict': 'reject', 'confidence': 0.0, 'reason': f'Server error: {str(e)}', 'ai_provider': 'unknown' }), 500 @app.route('/ai/providers', methods=['GET']) def list_providers(): """List available AI providers""" return jsonify({ 'providers': [ { 'name': 'local', 'description': 'Local SmartBot AI (Default)', 'features': ['Fast response', 'No API key needed', 'Basic analysis'] }, { 'name': 'chatgpt', 'description': 'ChatGPT AI (OpenAI)', 'features': ['Advanced analysis', 'Natural language reasoning', 'Requires API key'] } ], 'usage': { 'method': 'POST', 'url': '/ai/trade', 'body_format': { 'ai_provider': 'string (local|chatgpt)', 'pair': 'string', 'candidate': 'string (BUY|SELL)', 'mode': 'string (scalping|intraday|swing)', 'indicators': 'object', 'spread': 'integer', 'atr': 'float', 'confirmations': 'integer', 'signal_strength': 'float' } } }) @app.route('/health', methods=['GET']) def health_check(): """Health check endpoint""" return jsonify({ 'status': 'healthy', 'service': 'SmartBot AI with ChatGPT Support', 'version': '2.0.0', 'timestamp': datetime.now().isoformat(), 'providers': ['local', 'chatgpt'] }) if __name__ == '__main__': print("🤖 SmartBot AI Endpoint with ChatGPT Support Starting...") print("📍 Endpoint: http://localhost:5000/ai/trade") print("🔧 AI Providers: local, chatgpt") print("📊 Health Check: http://localhost:5000/health") print("=" * 50) # Check environment variables if os.getenv('OPENAI_API_KEY'): print("✅ OpenAI API key found - ChatGPT available") else: print("⚠️ OpenAI API key not found - ChatGPT disabled") print("=" * 50) # Run the Flask app app.run(host='0.0.0.0', port=5000, debug=True)