import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import time
import signal
import sys

PATH_UBUNTU = "/var/www/html/flask_project/"

def signal_handler(sig, frame):
    print("Interrupción recibida, deteniendo...")
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)

while True:
    # leyebdo el archivo del server
    df = pd.read_csv(PATH_UBUNTU + 'optionChain_2024-06-25.csv')

    df['timestamp'] = pd.to_datetime(df['timestamp'], format='%m/%d/%Y %H:%M:%S')

    # strikes para iron condors
    strikes_list_iron_butterfly = [
        # [5430.0, 5405.0, 5430.0, 5380.0, 'IRON BUTTERFLY'],
        # [5510.0, 5520.0, 5460.0, 5450.0, 'IRON CONDOR'],
        # [5485.0, 5490.0, 5440.0, 5435.0, 'SONAR'],
    ]

    # Strikes para  vertical(call o put)
    strikes_list_vertical = [
        [5445.0, 5440.0, 'PUT', 'VERTICAL'],
        # [5515.0, 5520.0, 'CALL', 'VERTICAL'],
    ]

    start_time = '06/25/2024 10:30:00'
    start_time = pd.to_datetime(start_time)

    # Filtrando datos!!!
    df = df[df['timestamp'] >= start_time]

    # Comprobar si después del filtrado hay datos
    if df.empty:
        print("No hay datos disponibles después del filtrado por start_time.")
    else:
        print(f"{len(df)} registros después del filtrado por start_time.")

    # Crear un DataFrame para almacenar los resultados de todas las configuraciones
    result_df = pd.DataFrame()
    verticals_df = pd.DataFrame()

    # Función para calcular valores de Iron Butterfly
    def calcular_iron_butterfly(strikes, label, df):
        filtered_df = df[df['strike'].isin(strikes)]

        sell_call_df = filtered_df[filtered_df['strike'] == strikes[0]].copy()
        buy_call_df = filtered_df[filtered_df['strike'] == strikes[1]].copy()
        sell_put_df = filtered_df[filtered_df['strike'] == strikes[2]].copy()
        buy_put_df = filtered_df[filtered_df['strike'] == strikes[3]].copy()

        sell_call_df.loc[:, 'mean_sell_call'] = 100 * (sell_call_df['bid_call'] + sell_call_df['ask_call']) / 2
        sell_put_df.loc[:, 'mean_sell_put'] = 100 * (sell_put_df['bid_put'] + sell_put_df['ask_put']) / 2
        buy_call_df.loc[:, 'mean_buy_call'] = 100 * (buy_call_df['bid_call'] + buy_call_df['ask_call']) / 2
        buy_put_df.loc[:, 'mean_buy_put'] = 100 * (buy_put_df['bid_put'] + buy_put_df['ask_put']) / 2

        iron_butterfly_values = pd.DataFrame()

        iron_butterfly_values['timestamp'] = sell_call_df['timestamp']
        iron_butterfly_values['mean_sell_call'] = sell_call_df['mean_sell_call'].values
        iron_butterfly_values['mean_sell_put'] = sell_put_df['mean_sell_put'].values
        iron_butterfly_values['mean_buy_call'] = buy_call_df['mean_buy_call'].values
        iron_butterfly_values['mean_buy_put'] = buy_put_df['mean_buy_put'].values

        iron_butterfly_values['iron_butterfly_value'] = (
            iron_butterfly_values['mean_sell_call'] +
            iron_butterfly_values['mean_sell_put'] -
            iron_butterfly_values['mean_buy_call'] -
            iron_butterfly_values['mean_buy_put']
        )

        credito_inicial = iron_butterfly_values['iron_butterfly_value'].iloc[0]
        iron_butterfly_values['diferencia'] = credito_inicial - iron_butterfly_values['iron_butterfly_value']
        iron_butterfly_values['label'] = f'{label} [{strikes[0]}, {strikes[1]}] [{strikes[2]}, {strikes[3]}]'

        return iron_butterfly_values

    # Función para calcular valores de Verticales
    def calcular_vertical(strikes, label, df):
        option_type = strikes[2]
        filtered_df = df[df['strike'].isin(strikes[:2])]

        if option_type == 'CALL':
            sell_df = filtered_df[filtered_df['strike'] == strikes[0]].copy()
            buy_df = filtered_df[filtered_df['strike'] == strikes[1]].copy()

            sell_df.loc[:, 'mean_sell'] = 100 * (sell_df['bid_call'] + sell_df['ask_call']) / 2
            buy_df.loc[:, 'mean_buy'] = 100 * (buy_df['bid_call'] + buy_df['ask_call']) / 2
        elif option_type == 'PUT':
            sell_df = filtered_df[filtered_df['strike'] == strikes[0]].copy()
            buy_df = filtered_df[filtered_df['strike'] == strikes[1]].copy()

            sell_df.loc[:, 'mean_sell'] = 100 * (sell_df['bid_put'] + sell_df['ask_put']) / 2
            buy_df.loc[:, 'mean_buy'] = 100 * (buy_df['bid_put'] + buy_df['ask_put']) / 2

        vertical_values = pd.DataFrame()

        vertical_values['timestamp'] = sell_df['timestamp']
        vertical_values['mean_sell'] = sell_df['mean_sell'].values
        vertical_values['mean_buy'] = buy_df['mean_buy'].values

        vertical_values['vertical_value'] = vertical_values['mean_sell'] - vertical_values['mean_buy']

        credito_inicial = vertical_values['vertical_value'].iloc[0]
        vertical_values['diferencia'] = credito_inicial - vertical_values['vertical_value']
        vertical_values['label'] = f'{label} [{strikes[0]}, {strikes[1]}] {strikes[2]}'

        # Agregar las columnas sell_strike y buy_strike
        vertical_values['sell_strike'] = strikes[0]
        vertical_values['buy_strike'] = strikes[1]

        return vertical_values

    # Calcular valores de Iron Butterfly
    for strikes in strikes_list_iron_butterfly:
        result_df = pd.concat([result_df, calcular_iron_butterfly(strikes[:4], strikes[4], df)], ignore_index=True)

    # Calcular valores de Verticales
    for strikes in strikes_list_vertical:
        vertical_result = calcular_vertical(strikes[:3], strikes[3], df)
        result_df = pd.concat([result_df, vertical_result], ignore_index=True)
        verticals_df = pd.concat([verticals_df, vertical_result[['timestamp', 'sell_strike', 'buy_strike', 'mean_sell', 'mean_buy', 'vertical_value', 'diferencia']]], ignore_index=True)

    # Guardar los datos de las verticales en un CSV
    verticals_df.to_csv('/home/seba/projects/VPS_Streaming_CS/verticals_result.csv', index=False)

    # Verificar que result_df no esté vacío y que contenga la columna 'timestamp'
    if not result_df.empty and 'timestamp' in result_df.columns:
        # Crear el gráfico de líneas con dos ejes Y
        fig = make_subplots(specs=[[{"secondary_y": True}]])

        # Agregar las líneas de diferencias del valor de Iron Butterfly y Verticales
        for label in result_df['label'].unique():
            df_label = result_df[result_df['label'] == label]
            fig.add_trace(
                go.Scatter(x=df_label['timestamp'], y=df_label['diferencia'], mode='lines', name=label, line=dict(width=1)),
                secondary_y=False
            )

        # Agregar la línea para 'underlying_price' en color negro continuo y ancho de 3
        fig.add_trace(
            go.Scatter(
                x=df['timestamp'],
                y=df['underlying_price'],
                mode='lines',
                name='Underlying Price',
                line=dict(color='black', width=1)
            ),
            secondary_y=True
        )

        # Actualizar los títulos de los ejes
        fig.update_xaxes(title_text='Timestamp')
        fig.update_yaxes(title_text='Profit & Loss ($)', secondary_y=False)
        fig.update_yaxes(title_text='Underlying Price', secondary_y=True)

        # Actualizar el título del gráfico
        start_time_str = start_time.strftime('%m/%d/%Y %H:%M:%S')

        fig.update_layout(title_text='Seguimiento Estrategias Bola 8 - ' + start_time_str)

        # Mostrar el gráfico
        fig.show()
    else:
        print("No hay datos disponibles para mostrar el gráfico.")

    # Esperar 10 segundos antes de la siguiente iteración
    time.sleep(10)
