File size: 8,809 Bytes
8e56885 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
import json
import time
import logging
from datetime import datetime
import requests
from flask import Flask, jsonify
from apscheduler.schedulers.background import BackgroundScheduler
from db import paires, deeper
import ai
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# Initialize Flask app
app = Flask(__name__)
def fetch_pairs_configuration():
"""Fetch the current pairs configuration from GitHub"""
result = paires.fetch_json_from_github()
if result["success"]:
config = result["data"]
if not config: # If the JSON is empty
config = {"status": False, "GROUPS": {}}
return config
else:
logger.error(f"Error fetching pairs configuration: {result['message']}")
return {"status": False, "GROUPS": {}}
def fetch_deeper_configuration():
"""Fetch the current deeper analysis configuration from GitHub"""
result = deeper.fetch_json_from_github()
if result["success"]:
config = result["data"]
if not config: # If the JSON is empty
config = {"status": True, "forwards": {}}
return config
else:
logger.error(f"Error fetching deeper configuration: {result['message']}")
return {"status": True, "forwards": {}}
def save_deeper_configuration(config):
"""Save the deeper configuration to GitHub"""
# Format the JSON as a single line with no indentation or whitespace
formatted_json = json.dumps(config, separators=(',', ':'))
# Get authentication token and commit ID
auth_token, commit_oid = deeper.fetch_authenticity_token_and_commit_oid()
if auth_token and commit_oid:
# Update the GitHub file
result = deeper.update_user_json_file(auth_token, commit_oid, formatted_json)
if result["success"]:
logger.info("Deeper analysis saved successfully!")
return True
else:
logger.error(f"Error saving deeper analysis: {result['message']}")
return False
else:
logger.error("Failed to get authentication token or commit ID. Deeper analysis not saved.")
return False
def extract_forward_content(analysis_text):
"""Extract content between <Forward> and </Forward> tags"""
start_tag = "<Forward>"
end_tag = "</Forward>"
start_index = analysis_text.find(start_tag)
if start_index == -1:
return None
start_index += len(start_tag)
end_index = analysis_text.find(end_tag, start_index)
if end_index == -1:
return None
return analysis_text[start_index:end_index].strip()
def analyze_forex_groups():
"""Main function to analyze forex groups and update deeper analysis"""
logger.info("Starting forex group analysis...")
try:
# Fetch current configurations
pairs_config = fetch_pairs_configuration()
# Check if trading is enabled
if not pairs_config.get("status", False):
logger.info("Trading is currently disabled. No analysis will be performed.")
return
# Process each group
groups = pairs_config.get("GROUPS", {})
if not groups:
logger.info("No groups configured for analysis.")
return
# Create a new forwards dictionary to replace the existing one
new_forwards = {}
for group_id, group_data in groups.items():
logger.info(f"Analyzing group {group_id}...")
try:
# Extract group information
pairs = group_data.get("pairs", [])
description = group_data.get("description", "")
relationships = group_data.get("relationships", "")
if not pairs:
logger.warning(f"No pairs defined for group {group_id}, skipping.")
continue
# Get AI analysis for the group
analysis = ai.analyze_forex_group(pairs, description, relationships)
logger.info(f"Analysis received for group {group_id}")
# Extract forward-looking content if present
forward_content = extract_forward_content(analysis)
if forward_content:
logger.info(f"Forward-looking analysis found for group {group_id}")
# Add to the new forwards dictionary with group ID as key
new_forwards[group_id] = {
"pairs": pairs,
"message": forward_content
}
else:
logger.info(f"No forward-looking analysis for group {group_id}")
except Exception as e:
logger.error(f"Error analyzing group {group_id}: {str(e)}", exc_info=True)
# Continue with next group instead of stopping the entire process
continue
# After collecting all analyses, update the deeper configuration in a single operation
if new_forwards:
logger.info(f"Saving forward analysis for {len(new_forwards)} groups...")
# Fetch the latest deeper configuration
deeper_config = fetch_deeper_configuration()
# Ensure deeper config has the correct structure
if "status" not in deeper_config:
deeper_config["status"] = True
# Replace the entire forwards section with our new data
deeper_config["forwards"] = new_forwards
# Save the configuration
save_deeper_configuration(deeper_config)
logger.info("All forward analyses saved successfully")
else:
logger.info("No forward-looking analyses found for any groups")
logger.info("Analysis cycle completed successfully")
except Exception as e:
logger.error(f"Unexpected error in analyze_forex_groups: {str(e)}", exc_info=True)
# Flask routes
@app.route('/')
def health_check():
"""Health check endpoint to verify the service is running"""
return jsonify({
"status": "running",
"message": "Forex Analysis System is active",
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
})
@app.route('/analyze/now')
def trigger_analysis():
"""Endpoint to manually trigger analysis"""
try:
analyze_forex_groups()
return jsonify({
"status": "success",
"message": "Analysis triggered successfully",
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
})
except Exception as e:
logger.error(f"Error triggering analysis: {e}", exc_info=True)
return jsonify({
"status": "error",
"message": f"Error triggering analysis: {str(e)}"
}), 500
@app.route('/status')
def get_status():
"""Endpoint to get system status"""
try:
pairs_config = fetch_pairs_configuration()
deeper_config = fetch_deeper_configuration()
# Count all pairs across all groups
total_pairs = 0
for group_data in pairs_config.get("GROUPS", {}).values():
total_pairs += len(group_data.get("pairs", []))
return jsonify({
"service_status": "running",
"trading_enabled": pairs_config.get("status", False),
"groups_count": len(pairs_config.get("GROUPS", {})),
"total_pairs_count": total_pairs,
"deeper_analysis_enabled": deeper_config.get("status", True),
"forwards_count": len(deeper_config.get("forwards", {})),
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
})
except Exception as e:
logger.error(f"Error getting status: {e}", exc_info=True)
return jsonify({
"service_status": "running",
"error": str(e)
})
# Initialize scheduler
scheduler = BackgroundScheduler(daemon=True)
def start_scheduler():
"""Start the scheduler with the analysis job"""
logger.info("Starting scheduler for forex analysis")
# Schedule the analysis function to run every hour
scheduler.add_job(
analyze_forex_groups, # Changed from analyze_forex_pairs to analyze_forex_groups
'interval',
hours=1,
id='forex_analysis',
replace_existing=True,
next_run_time=datetime.now() # Run immediately on startup
)
# Start the scheduler if it's not already running
if not scheduler.running:
scheduler.start()
logger.info("Scheduler started successfully")
if __name__ == "__main__":
logger.info("Starting Forex Analysis System...")
# Start the scheduler
start_scheduler()
# Start the Flask application
app.run(host='0.0.0.0', port=7860, debug=False) |