o
    Ygx;                     @   s   d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dl	m
Z
mZ d dlZe
ddddZ	dZd	d
 Zdd Zdd Ze	jdd Zdd Zdd Zdd Zdd Ze	jdd Ze	jdd Ze	jdd ZdS )    Ndatetime)ThreadPoolExecutor)Celerygrouptaskszredis://localhost:6379/0)brokerbackendFc                  O   s   t rt| i | d S d S N)
DEBUG_MODEprint)argskwargs r   4/var/www/html/neutraledge.backtestingmarket/tasks.pydebug_print   s   r   c              
   C   sZ   | \}}z|t |fW S  ty, } ztd| d|  |d fW  Y d }~S d }~ww )Nu   ⚠ Error cargando : )pdread_csv	Exceptionr   )	file_info	file_date	file_pather   r   r   load_csv   s   r   c
                    st  ddl m   tj| d dd| d<  |d | d jj| d< | | d k  }
|
jr7td	|  d
S |
d 	 fdd|
d< |
d 
 }|
|
d |k  }|jd d }td t|dg   td t| t|d t| |d< t|d t| |d< |d  }|d  }|j|df }|j|df }|t| }|t| }t|||||}|jd d }|d
u rtd| d d
S ||	d  }t| ||||||||	\}}}td|  t|dt|t|t|t|t|tr|nt|dt|t|t|t|t|t|d}| D ]\}}t| d| dt| d q#|S )u  
    Encuentra las filas con el timestamp más cercano o posterior al tiempo objetivo, selecciona los strikes del Iron Condor y calcula el crédito inicial.
    Se asegura de retornar valores convertidos a tipos nativos (cadenas, float) para que sean serializables a JSON.
    r   r   	timestampz%Y-%m-%d %H:%M:%S)formatTime%H:%M:%S	only_timeu.   ⚠ No hay timestamps iguales o posteriores a Nc                    s$   t   j|   j  S r
   )abscombinemintotal_secondsxr   target_timer   r   <lambda><   s   $ z-find_next_closest_time_rows.<locals>.<lambda>	time_diffu"   Timestamp más cercano encontrado:u/   
Filas completas con el timestamp más cercano:
delta_calldelta_call_diff	delta_putdelta_put_diffstrikeunderlying_priceu   🚨 Día descartado: u#    - No se pudo calcular el crédito.d   u&   📌 Resultado final del Iron Condor: )r   z	SPX PriceOutcomezInitial CreditzCredit at Occurrencez
Occur Timez	Stop LosszTake ProfitzSell Call StrikezBuy Call StrikezSell Put StrikezBuy Put Striker   z ())r   r   to_datetimestrptimetimedtcopyemptyr   applyr"   ilocdrop_duplicatesr    floatidxminloccalculate_iron_condor_credit evaluate_iron_condor_performancestrftimestr
isinstanceitemsr   type)dftarget_time_str
call_delta	put_deltacall_spread
put_spread
takeProfitstopLossunitdesplazamientofuture_timesmin_diffclosest_rowsopening_timestampidx_min_call_deltaidx_min_put_delta	sell_callsell_putbuy_callbuy_putcredit	spx_price	resultadofinal_credit
occur_timeresult_dictkeyvaluer   r&   r   find_next_closest_time_rows$   sh   
"rb   c                 C   V   ddl m } | \}}}}}}}}	}
}}||d}t|}t|||||||	|
||
S Nr   r   %Y-%m-%dr   r4   r   r   process_dayr   r   file_date_strr   horariorH   rI   rJ   rK   rL   rM   rN   rO   r   rF   r   r   r   process_day_task   
   
rk   c
                 C   s&   t | |||||||||	
}
|
r|
S d S r
   )rb   )day_dfrj   rH   rI   rJ   rK   rL   rM   rN   rO   resultr   r   r   rg      s   rg   c                 C   s6   | \
\}}}}}}}}}	}
}t ||||||||	|
|
S r
   )rg   )r   r   rm   rj   rH   rI   rJ   rK   rL   rM   rN   rO   r   r   r   process_day_wrapper   s   ro   c              
      s  t t||||g\}}}} d t d<  fdd||||fD }|r=td|  td d    td d S z  d |k jd }  d |k jd }  d |k jd }  d |k jd }	|d |d	  d
 }
|d |d	  d
 }|d |d  d
 }|	d |	d  d
 }|
| ||  }td td| d|
d td| d|d td| d|d td| d|d |W S  ty } ztd|  W Y d }~d S d }~ww )Nr.   c                    s   g | ]}| d  j vr|qS )r.   )values).0r.   rF   r   r   
<listcomp>   s    z0calculate_iron_condor_credit.<locals>.<listcomp>u'   ⚠ Strikes faltantes en el DataFrame: u#   📌 Strikes disponibles en el df: uE   ❌ Día descartado debido a datos insuficientes para el Iron Condor.r   bid_callask_call   bid_putask_putu   
🔹 Valores de precios:u   📌 Sell Call (z): .2fu   📌 Buy Call (u   📌 Sell Put (u   📌 Buy Put (u.   ⚠ Error al seleccionar filas del DataFrame: )mapr<   astyper   uniquer:   
IndexError)rF   rV   rX   rW   rY   missing_strikessell_call_rowbuy_call_rowsell_put_rowbuy_put_rowsell_call_pricebuy_call_pricesell_put_pricebuy_put_pricerZ   r   r   rr   r   r?      s:   r?   c	              	   C   s  t |}t |}t |d }td t| d | d< | | d |k d} ||||h}	| | d |	 } | jrDtd d||dfS | d | d	  d
 | d< | d | d  d
 | d< | jddddgd}
|
j	ddd
 }
|
d|f |
d|f  |
d|f |
d|f   d |
d< |
 D ]Z\}}|d }t|tjr|jd }td| d|dd|| d ||| krtd| d|d d||df  S ||| krtd| d|d d||df  S q|| }|dkrd}n	|dk rd}nd }td! |||dfS )"Nr0   u0   
📊 Evaluando el desempeño del Iron Condor...r   r.   u@   ⚠ No hay datos suficientes después del timestamp de apertura.Neutrossr   rt   ru   rv   mid_callrw   rx   mid_put)indexcolumnsrp         )windowmin_periodsrZ   r   u   ⏳ u    | Crédito: ry   z | P&L: u   ✅ Take Profit alcanzado en u    con crédito de Gananciau   ❌ Stop Loss alcanzado en u   PérdidazGanancia parcialu   Pérdida parcialNeutronu7   📌 Iron Condor llegó al cierre sin alcanzar TP ni SL)r<   r   r   r3   sort_valuesisinr8   rA   pivotrollingmeaniterrowsrC   Seriesr:   )rF   rV   rX   rW   rY   initial_credittake_profit	stop_lossrS   strikes_neededpivot_dfr   rowcurrent_creditpnlr\   r   r   r   r@      sP   
"r@   c                 C   rc   rd   rf   rh   r   r   r   rk      rl   c                 C   s   dd | D } | sddg dS dd l }d}||}tt|d |d	 }| D ]}|d
 dd }|||d< q'd| ddS )Nc                 S   s   g | ]}|d ur|qS r
   r   )rq   resr   r   r   rs      s    z%aggregate_results.<locals>.<listcomp>errorz$No se encontraron datos procesables.statusmessagedatar   z4/var/www/html/flask_project/spx_history_with_gap.csvdategapr    GapsuccesszDatos procesados correctamente)r   r   r   )pandasr   dictzipsplitget)resultsr   csv_path_gapdf_gapgap_dictr   date_strr   r   r   aggregate_results   s   
r   c              	      s8  t d | d}|dv rd| }| d}| d}| dd | d	 d
  | d	 d | d| d| d| d d
 | d d t| d ddlm} ||d}||d}dd l}dd l}d}	|	 d| d}
g }||
D ]Q}|j|}|	dd
d}t|dk rt d| d qz|d }z||d}W n ty   t d| d Y qzw ||  kr|krn qz|||f qz|jdd  d! |sd"d#g d$S  f	d%d&|D }|D ]}t d't|d  t d(t|d)  qdd*lm}m} |d+d& |D t }|jS ),Nz!Iniciando tarea de backtesting...symbol)SPXXSPRUT$
fechaDesde
fechaHastarj   z:00deltascallputrL   rM   rN   spreadsrO   r   r   re   z"/var/www/html/flask_project/chainsz/optionChain_z_*.csvz.csv _r   u&   ⚠ Advertencia: Nombre inesperado en z, archivo ignorado.u   ⚠ Error: Fecha inválida en c                 S   s   | d S )Nr   r   r$   r   r   r   r(   <  s    z*process_backtesting_task.<locals>.<lambda>)r`   r   z4No se encontraron archivos en el rango seleccionado.r   c                    s0   g | ]\}}| d | fqS )re   )rA   )rq   r   r   	rH   rJ   rO   rj   rI   rK   rM   rL   rN   r   r   rs   B  s    z,process_backtesting_task.<locals>.<listcomp>z!Tipo del primer elemento (fecha):z!Tipo del segundo elemento (ruta):r   )chordr   c                 S   s   g | ]}t |qS r   )rk   s)rq   r   r   r   r   rs   N  s    )r   r   r<   r   r4   globospathbasenamereplacer   len
ValueErrorappendsortrE   celeryr   r   r   r   id)r   r   fecha_desdefecha_hastar   fecha_desde_dtfecha_hasta_dtr   r   directory_pathpatternfiles_with_datesr   	base_namepartsri   file_date_dt	args_listr   r   r   jobr   r   r   process_backtesting_task  sd   





r   )r   r   r   r   numpynpr   concurrent.futuresr   r   r   r   jsonr   r   r   rb   taskrk   rg   ro   r?   r@   r   r   r   r   r   r   <module>   s2   ]
 3


