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)