#!/usr/bin/env python3 """ Control Client for Signal Generator Send runtime commands to the signal generator """ import socket import sys import json def send_command(command: dict, socket_path="/tmp/signals_control.sock"): """Send a command to the signal generator""" try: sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.settimeout(5) sock.connect(socket_path) # Send command sock.sendall(json.dumps(command).encode('utf-8')) # Receive response response = b"" while True: chunk = sock.recv(4096) if not chunk: break response += chunk sock.close() # Parse and display result = json.loads(response.decode('utf-8')) if result.get("status") == "success": print(f"✓ {result['message']}") if "changes" in result: print("\nChanges:") for key, value in result["changes"].items(): print(f" {key}: {value['old']} -> {value['new']}") else: print(f"✗ Error: {result.get('message', 'Unknown error')}") return 0 except FileNotFoundError: print(f"Error: Socket not found at {socket_path}") print("Is the signal generator running?") return 1 except ConnectionRefusedError: print(f"Error: Connection refused at {socket_path}") return 1 except Exception as e: print(f"Error: {e}") return 1 def print_usage(): print(""" Signal Generator Control Client Usage: ./signal_control_client.py [arguments] Commands: reload - Reload config.json personality - Set personality (scalping/swing) confidence - Set min confidence (0.0-1.0) cooldown - Set cooldown period debug - Toggle debug logging clear-cooldowns - Clear all signal cooldowns reset-stats - Reset statistics Examples: ./signal_control_client.py reload ./signal_control_client.py personality swing ./signal_control_client.py confidence 0.45 ./signal_control_client.py cooldown 30 ./signal_control_client.py debug You can also use SIGUSR1 and SIGUSR2: kill -USR1 # Reload config kill -USR2 # Toggle debug """) def main(): if len(sys.argv) < 2: print_usage() return 1 command = sys.argv[1].lower() if command in ["help", "-h", "--help"]: print_usage() return 0 # Build command dictionary cmd = {} if command == "reload": cmd = {"action": "reload"} elif command == "personality": if len(sys.argv) < 3: print("Error: personality requires a value (scalping/swing)") return 1 cmd = {"action": "set_personality", "value": sys.argv[2]} elif command == "confidence": if len(sys.argv) < 3: print("Error: confidence requires a value (0.0-1.0)") return 1 try: value = float(sys.argv[2]) cmd = {"action": "set_confidence", "value": value} except ValueError: print("Error: confidence must be a number") return 1 elif command == "cooldown": if len(sys.argv) < 3: print("Error: cooldown requires a value in seconds") return 1 try: value = int(sys.argv[2]) cmd = {"action": "set_cooldown", "value": value} except ValueError: print("Error: cooldown must be an integer") return 1 elif command == "debug": cmd = {"action": "toggle_debug"} elif command == "clear-cooldowns": cmd = {"action": "clear_cooldowns"} elif command == "reset-stats": cmd = {"action": "reset_stats"} else: print(f"Unknown command: {command}") print_usage() return 1 # Send command socket_path = "/tmp/signals_control.sock" if len(sys.argv) > 2 and sys.argv[-1].startswith("/"): socket_path = sys.argv[-1] return send_command(cmd, socket_path) if __name__ == "__main__": sys.exit(main())