158 lines
5.1 KiB
Python
Executable File
158 lines
5.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
MQL Settings Validator with Telegram Notifications
|
|
Run via cron: python3 validate-and-notify.py
|
|
"""
|
|
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
from datetime import datetime
|
|
|
|
try:
|
|
import requests
|
|
except ImportError:
|
|
print("Installing requests...")
|
|
subprocess.run([sys.executable, "-m", "pip", "install", "requests", "-q"])
|
|
import requests
|
|
|
|
# Configuration
|
|
TELEGRAM_BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN", "")
|
|
TELEGRAM_CHAT_ID = os.environ.get("TELEGRAM_CHAT_ID", "")
|
|
REPO_DIR = "/home/garfield/mql-trading-bots"
|
|
|
|
def send_telegram(message):
|
|
"""Send message to Telegram"""
|
|
if not TELEGRAM_BOT_TOKEN or not TELEGRAM_CHAT_ID:
|
|
print("Telegram not configured. Message:")
|
|
print(message)
|
|
return False
|
|
|
|
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
|
|
payload = {
|
|
"chat_id": TELEGRAM_CHAT_ID,
|
|
"text": message,
|
|
"parse_mode": "HTML"
|
|
}
|
|
|
|
try:
|
|
response = requests.post(url, json=payload, timeout=10)
|
|
return response.status_code == 200
|
|
except Exception as e:
|
|
print(f"Failed to send Telegram: {e}")
|
|
return False
|
|
|
|
def check_set_files():
|
|
"""Validate all .set files"""
|
|
issues = []
|
|
warnings = []
|
|
|
|
os.chdir(REPO_DIR)
|
|
|
|
# Check confluence files
|
|
confluence_files = [f for f in os.listdir(".") if f.startswith("confluence-") and f.endswith(".set")]
|
|
grid_files = [f for f in os.listdir(".") if f.startswith("grid-") and f.endswith(".set")]
|
|
|
|
print(f"Found {len(confluence_files)} confluence files, {len(grid_files)} grid files")
|
|
|
|
# Check for invalid variable names
|
|
invalid_pattern = re.compile(r'InpMinConfluenceStrength|MinConfluenceStrength', re.IGNORECASE)
|
|
for f in confluence_files:
|
|
with open(f, 'r') as file:
|
|
content = file.read()
|
|
if invalid_pattern.search(content):
|
|
issues.append(f"❌ <b>Invalid variable</b> in {f}: InpMinConfluenceStrength (should be InpMinStrength)")
|
|
|
|
# Check for missing critical parameters
|
|
critical_params_conf = ['InpMinConfluence', 'InpMinStrength', 'InpMagicNumber', 'InpCloseBeforeWeekend']
|
|
critical_params_grid = ['InpCloseBeforeWeekend', 'InpMaxDailyDrawdown']
|
|
|
|
for f in confluence_files:
|
|
with open(f, 'r') as file:
|
|
content = file.read()
|
|
for param in critical_params_conf:
|
|
if param not in content:
|
|
issues.append(f"❌ <b>Missing {param}</b> in {f}")
|
|
|
|
for f in grid_files:
|
|
with open(f, 'r') as file:
|
|
content = file.read()
|
|
for param in critical_params_grid:
|
|
if param not in content:
|
|
issues.append(f"❌ <b>Missing {param}</b> in {f}")
|
|
|
|
# Check for high strength thresholds (warnings)
|
|
for f in confluence_files:
|
|
with open(f, 'r') as file:
|
|
content = file.read()
|
|
match = re.search(r'InpMinStrength=(\d+\.?\d*)', content)
|
|
if match:
|
|
strength = float(match.group(1))
|
|
if strength >= 0.80:
|
|
warnings.append(f"⚠️ <b>High threshold</b> in {f}: {strength} (may block trades)")
|
|
|
|
# Check debug mode
|
|
debug_off = 0
|
|
for f in confluence_files + grid_files:
|
|
with open(f, 'r') as file:
|
|
content = file.read()
|
|
if 'InpDebugMode=false' in content:
|
|
debug_off += 1
|
|
|
|
if debug_off > 5:
|
|
warnings.append(f"⚠️ <b>Debug disabled</b> in {debug_off} files - you won't see trade decisions")
|
|
|
|
return issues, warnings, len(confluence_files), len(grid_files)
|
|
|
|
def main():
|
|
"""Main function"""
|
|
print("=" * 50)
|
|
print("MQL Settings Validator")
|
|
print(f"Time: {datetime.now().isoformat()}")
|
|
print("=" * 50)
|
|
|
|
issues, warnings, conf_count, grid_count = check_set_files()
|
|
|
|
# Build report
|
|
report_lines = [
|
|
"<b>📊 MQL Settings Check</b>",
|
|
f"Confluence files: {conf_count}",
|
|
f"Grid files: {grid_count}",
|
|
""
|
|
]
|
|
|
|
if issues:
|
|
report_lines.append("<b>❌ Issues Found:</b>")
|
|
report_lines.extend(issues[:10]) # Limit to 10 issues
|
|
if len(issues) > 10:
|
|
report_lines.append(f"... and {len(issues) - 10} more issues")
|
|
report_lines.append("")
|
|
|
|
if warnings:
|
|
report_lines.append("<b>⚠️ Warnings:</b>")
|
|
report_lines.extend(warnings[:5])
|
|
report_lines.append("")
|
|
|
|
if not issues and not warnings:
|
|
report_lines.append("✅ <b>All checks passed!</b>")
|
|
report_lines.append("No issues found.")
|
|
|
|
report_lines.append(f"\n⏰ {datetime.now().strftime('%Y-%m-%d %H:%M')}")
|
|
|
|
report = "\n".join(report_lines)
|
|
print("\n" + report.replace('<b>', '').replace('</b>', ''))
|
|
|
|
# Send notification if issues found or if it's a scheduled check
|
|
if issues or warnings:
|
|
send_telegram(report)
|
|
return 1
|
|
else:
|
|
# Only send success message on first run of the day
|
|
if datetime.now().hour == 9:
|
|
send_telegram(report)
|
|
return 0
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|