Repository navigation
Expand file tree
/
Copy pathconexion_broker.py
More file actions
190 lines (164 loc) · 6.79 KB
/
Copy pathconexion_broker.py
File metadata and controls
190 lines (164 loc) · 6.79 KB
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
import time
import threading
# Intentamos importar la librería de IQ Option
try:
from iqoptionapi.stable_api import IQ_Option
IQ_API_DISPONIBLE = True
except ImportError:
IQ_API_DISPONIBLE = False
IQ_Option = None
class ConexionBroker:
"""
Clase para gestionar la conexión con IQ Option.
Soporta cuentas Demo y Real, activos OTC y normales.
"""
def __init__(self, email="", password="", server="PRACTICE"):
self.email = email
self.password = password
self.server = server # "PRACTICE" (Demo) o "REAL"
self.conectado = False
self.api = None
self.saldo = 0.0
self._lock = threading.Lock()
if self.email and self.password:
self.conectar()
else:
print("[BROKER] Inicializado con credenciales vacías (modo seguro/simulación).")
def conectar(self):
"""Establece conexión con IQ Option"""
if not IQ_API_DISPONIBLE:
print("[BROKER] ⚠️ Advertencia: 'iqoptionapi' no está instalada.")
print("[BROKER] Instálala con: pip install iqoptionapi")
print("[BROKER] Modo simulación activado.")
self.conectado = False
return False, "Librería iqoptionapi no encontrada. Modo simulación."
try:
print(f"[BROKER] 🔌 Conectando a IQ Option como {self.email}...")
self.api = IQ_Option(self.email, self.password)
# Intentar conectar
check, reason = self.api.connect()
if not check:
print(f"[BROKER] ❌ Fallo en login: {reason}")
self.conectado = False
return False, f"Login fallido: {reason}"
# Cambiar a cuenta Demo o Real
self.api.change_balance(self.server)
self.conectado = True
# Obtener saldo inicial
self.saldo = self.api.get_balance()
print(f"[BROKER] ✅ ¡Conectado a IQ Option! | Cuenta: {self.server} | Saldo: ${self.saldo:.2f}")
return True, f"Conectado. Saldo: ${self.saldo:.2f}"
except Exception as e:
print(f"[BROKER] ❌ Error crítico: {e}")
self.conectado = False
return False, f"Error: {str(e)}"
def obtener_balance(self):
"""Retorna el saldo actual de la cuenta"""
if not self.conectado or self.api is None:
return self.saldo # Retorna saldo en caché o 0
try:
self.saldo = self.api.get_balance()
return self.saldo
except Exception as e:
print(f"[BROKER] Error obteniendo balance: {e}")
return self.saldo
def obtener_payout(self, activo="EURUSD"):
"""Obtiene el payout (rentabilidad) actual del activo"""
if not self.conectado or self.api is None:
return 80 # Valor por defecto en modo simulación
try:
# Para opciones binarias, obtenemos el payout
payout = self.api.get_all_profit()
if activo in payout:
return int(payout[activo]["turbo"] * 100)
return 80
except Exception as e:
print(f"[BROKER] Error obteniendo payout: {e}")
return 80
def obtener_velas_recientes(self, activo, timeframe, cantidad):
"""
Obtiene velas recientes del activo.
:param activo: Ejemplo "EURUSD", "EURUSD-OTC"
:param timeframe: Segundos (60, 300, etc.)
:param cantidad: Número de velas
:return: Lista de diccionarios con open, high, low, close
"""
if not self.conectado or self.api is None:
print("[BROKER] [Simulación] No hay datos de velas (sin conexión).")
return []
try:
velas = self.api.get_candles(activo, timeframe, cantidad, time.time())
datos = []
for vela in velas:
datos.append({
"open": vela["open"],
"high": vela["max"],
"low": vela["min"],
"close": vela["close"]
})
return datos
except Exception as e:
print(f"[BROKER] Error obteniendo velas: {e}")
return []
def enviar_orden_compra(self, simbolo="EURUSD", volumen=2.0, duracion=1):
"""
Envía una orden de COMPRA (CALL) a IQ Option.
:param simbolo: Activo a operar
:param volumen: Monto de inversión
:param duracion: Duración en minutos
"""
print(f"🟢 [BROKER] Ejecutando CALL en {simbolo} (Monto: ${volumen}, Duración: {duracion}m)")
if not self.conectado or self.api is None:
print("[BROKER] [Simulación] Orden CALL procesada localmente (sin conexión a IQ Option).")
return None
try:
check, id_orden = self.api.buy(volumen, simbolo, "call", duracion)
if check:
print(f"[BROKER] ✅ CALL ejecutada. ID: {id_orden}")
return id_orden
else:
print(f"[BROKER] ❌ Error ejecutando CALL: {id_orden}")
return None
except Exception as e:
print(f"[BROKER] ❌ Excepción en orden CALL: {e}")
return None
def enviar_orden_venta(self, simbolo="EURUSD", volumen=2.0, duracion=1):
"""
Envía una orden de VENTA (PUT) a IQ Option.
:param simbolo: Activo a operar
:param volumen: Monto de inversión
:param duracion: Duración en minutos
"""
print(f"🔴 [BROKER] Ejecutando PUT en {simbolo} (Monto: ${volumen}, Duración: {duracion}m)")
if not self.conectado or self.api is None:
print("[BROKER] [Simulación] Orden PUT procesada localmente (sin conexión a IQ Option).")
return None
try:
check, id_orden = self.api.buy(volumen, simbolo, "put", duracion)
if check:
print(f"[BROKER] ✅ PUT ejecutada. ID: {id_orden}")
return id_orden
else:
print(f"[BROKER] ❌ Error ejecutando PUT: {id_orden}")
return None
except Exception as e:
print(f"[BROKER] ❌ Excepción en orden PUT: {e}")
return None
def verificar_resultado(self, id_orden):
"""Verifica el resultado de una orden ejecutada"""
if not self.conectado or self.api is None:
return None
try:
return self.api.check_win_v4(id_orden)
except Exception as e:
print(f"[BROKER] Error verificando orden: {e}")
return None
def desconectar(self):
"""Cierra la conexión con IQ Option"""
if self.api:
try:
self.api.close_connect()
print("[BROKER] Conexión cerrada.")
except:
pass
self.conectado = False