@@ -0,0 +1,403 @@
|
||||
#!/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)
|
||||
Reference in New Issue
Block a user