#!/usr/bin/env python3
"""
Indicador Inside Bar
====================
Detecta patrones Inside Bar y genera senales de trading con
lineas de Entry, Stop Loss y Take Profit en el chart.
"""
import requests
from typing import List, Dict, Any
# =============================================================================
# CONFIGURACION
# =============================================================================
API_BASE_URL = "https://api.innova-trading.com"
API_KEY = "tu_api_key_aqui" # Obtener desde Dashboard Settings
SYMBOL = "EURUSD"
TIMEFRAME = 60 # H1 (1 hora en minutos)
BARS_TO_FETCH = 500
# Parametros de senal
SIGNAL_DELAY_BARS = 3 # Colocar senal 3 barras despues del inside bar
SL_MULTIPLIER = 2 # SL = 2x rango del Inside Bar
TP_RR_RATIOS = [1, 2, 3] # Riesgo:Recompensa para TP1, TP2, TP3
LINE_EXTEND_BARS = 10 # Lineas se extienden 10 barras
# Colores
COLOR_BUY = "#3b82f6" # Azul
COLOR_SELL = "#ef4444" # Rojo
COLOR_SL = "#ef4444" # Rojo
COLOR_TP1 = "#22c55e" # Verde
COLOR_TP2 = "#10b981" # Esmeralda
COLOR_TP3 = "#059669" # Verde oscuro
# =============================================================================
# FUNCIONES API
# =============================================================================
def get_bars(symbol: str, timeframe: int, limit: int = 500) -> List[Dict]:
"""Obtener barras OHLC de la API"""
response = requests.get(
f"{API_BASE_URL}/api/external/bars",
params={"symbol": symbol, "timeframe": timeframe, "limit": limit},
headers={"Authorization": f"Bearer {API_KEY}"}
)
if response.status_code != 200:
raise Exception(f"Error al obtener barras: {response.status_code}")
return response.json()["bars"]
def submit_indicator(
indicator_id: str,
symbol: str,
timeframe: int,
indicator_name: str,
points: List[Dict],
lines: List[Dict]
) -> Dict:
"""Enviar datos del indicador a la API"""
response = requests.post(
f"{API_BASE_URL}/api/external/indicators/{indicator_id}",
json={
"symbol": symbol,
"timeframe": timeframe,
"indicator_name": indicator_name,
"version": "1.0",
"points": points,
"lines": lines
},
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
)
if response.status_code not in [200, 201]:
raise Exception(f"Error al enviar: {response.status_code}")
return response.json()
# =============================================================================
# DETECCION INSIDE BAR
# =============================================================================
def detect_inside_bars(bars: List[Dict]) -> List[Dict]:
"""
Detectar patrones Inside Bar.
Inside Bar = High < High Anterior AND Low > Low Anterior
"""
inside_bars = []
for i in range(1, len(bars)):
current = bars[i]
previous = bars[i - 1]
is_inside = (
current["high"] < previous["high"] and
current["low"] > previous["low"]
)
if is_inside:
# Alcista si cierre > apertura
is_bullish = current["close"] > current["open"]
inside_bars.append({
"bar_index": i,
"time": current["time"],
"high": current["high"],
"low": current["low"],
"close": current["close"],
"is_bullish": is_bullish,
"range": current["high"] - current["low"]
})
return inside_bars
def generate_signals(bars: List[Dict], inside_bars: List[Dict]) -> tuple:
"""Generar senales de trading desde patrones Inside Bar"""
points = []
lines = []
signal_count = 0
tf_seconds = TIMEFRAME * 60
for ib in inside_bars:
# Barra de senal = 3 barras despues del inside bar
signal_bar_index = ib["bar_index"] + SIGNAL_DELAY_BARS
if signal_bar_index >= len(bars):
continue
signal_bar = bars[signal_bar_index]
signal_time = signal_bar["time"]
# Calcular riesgo
ib_range = ib["range"]
risk = ib_range * SL_MULTIPLIER
signal_count += 1
signal_id = f"ib_{signal_count:03d}"
if ib["is_bullish"]:
# Senal de COMPRA
entry = signal_bar["close"]
sl = entry - risk
tps = [entry + (risk * rr) for rr in TP_RR_RATIOS]
points.append({
"time": signal_time,
"type": "low",
"price": entry,
"label": "COMPRA",
"color": COLOR_BUY,
"shape": "arrowUp",
"size": 2
})
else:
# Senal de VENTA
entry = signal_bar["close"]
sl = entry + risk
tps = [entry - (risk * rr) for rr in TP_RR_RATIOS]
points.append({
"time": signal_time,
"type": "high",
"price": entry,
"label": "VENTA",
"color": COLOR_SELL,
"shape": "arrowDown",
"size": 2
})
# Agregar linea de Stop Loss
lines.append({
"id": f"{signal_id}_sl",
"price": sl,
"start_time": signal_time,
"bars": LINE_EXTEND_BARS,
"label": "SL",
"color": COLOR_SL,
"style": "dashed",
"width": 1
})
# Agregar lineas de Take Profit
tp_colors = [COLOR_TP1, COLOR_TP2, COLOR_TP3]
for idx, (tp, color) in enumerate(zip(tps, tp_colors), 1):
lines.append({
"id": f"{signal_id}_tp{idx}",
"price": tp,
"start_time": signal_time,
"bars": LINE_EXTEND_BARS,
"label": f"TP{idx}",
"color": color,
"style": "dotted",
"width": 1
})
return points, lines
# =============================================================================
# MAIN
# =============================================================================
def main():
print(f"Obteniendo {BARS_TO_FETCH} barras de {SYMBOL} {TIMEFRAME}m...")
bars = get_bars(SYMBOL, TIMEFRAME, BARS_TO_FETCH)
print(f"Recibidas {len(bars)} barras")
print("Detectando Inside Bars...")
inside_bars = detect_inside_bars(bars)
print(f"Encontrados {len(inside_bars)} Inside Bars")
print("Generando senales...")
points, lines = generate_signals(bars, inside_bars)
print(f"Generadas {len(points)} senales con {len(lines)} lineas")
print("Enviando a la API...")
result = submit_indicator(
indicator_id="inside_bar_signals",
symbol=SYMBOL,
timeframe=TIMEFRAME,
indicator_name="Senales Inside Bar",
points=points,
lines=lines
)
print(f"Exito! Puntos: {result['points_received']}, Lineas: {result['lines_received']}")
print(f"Ver en: https://innova-trading.com/trading?symbol={SYMBOL}")
if __name__ == "__main__":
main()