
    ngA              	           d dl m Z mZ d dlmZ d dlmZ d dlZd dlZ	d dl
Z
 e
j                  d       	 ddZd ZddZd	 Zd
 Zd Zd Z	 	 	 ddee   dee   dee   defdZd Zd ZddZddZd Zy)    )datetime	timedelta)Optional)ObjectIdNignorec           	         |t        j                         }t        |t              rt	        j
                  |      }t        d      t        d      t        d      t        d      t        d      t        d      t        d	      d
}| |v r|||    z
  }||fS 	 | j                  d      \  }}t	        j
                  |      }t	        j
                  |      }||fS #  t        d|        xY w)a/  
    Calculate start date based on given duration

    Args:
    duration (str): Duration in format '1W', '1M', '3M', '6M', '1Y', '3Y', '5Y', or custom date range
    end_date (datetime, optional): End date for calculation. Defaults to current date.

    Returns:
    tuple: Start date and end date
       )weeks   daysZ      m  iG  i!  )1W1M3M6M1Y3Y5Y:zInvalid duration format: )	r   now
isinstancestrpdto_datetimer   split
ValueError)duration
start_dateend_dateduration_map	start_strend_strs         :/var/www/html/trade_iq/helper_functions/market_analysis.pyget_duration_range_mar'      s     <<> (C >>(+ a R R S!S!W%W%L <X 66
8##A%^^C0	7^^I.
>>'*8##A4XJ?@@s   AC C/c                     | j                   d   d   }| j                   d   d   }d}||z
  |z  dz  }||kD  ry|| k  ryy)	z
    Determine the current trend of the price data

    Args:
    df (pandas.DataFrame): DataFrame with price data

    Returns:
    str: Current trend (Uptrend, Downtrend, or Neutral)
    r   closeg?d   Uptrend	DowntrendNeutral)iloc)dffirst_close
last_closetrend_thresholdpercentage_changes        r&   determine_current_trend_mar5   7   s`     ''!*W%KW%J O#k1[@3F?*	o-	-    c                 $   |d|dz  z
  z  }|d|dz  z   z  }|r| | d   |k\  | d   |k  z     }n| | d   |k\  | d   |k  z     }g }|j                         D ]x  \  }}	|j                  d      |r|	d   n|	d   dd}
|r!t        j                  |	d   |d	      r&d
|
d<   n t        j                  |	d   |d	      rd
|
d<   |j	                  |
       z |t        |      |D cg c]
  }|d   s	| c}|D cg c]
  }|d   r	| c}|dS c c}w c c}w )a  
    Find the dates when a specific price occurred or was very close

    Args:
    df (pandas.DataFrame): DataFrame with price data
    price (float): Price to search for
    is_top (bool): Whether searching for top (high) or bottom (low) price
    tolerance_percent (float): Percentage tolerance for price matching

    Returns:
    dict: Detailed information about price occurrences
    r	   r+   highlow%Y-%m-%dF)datepriceexact_matchgMbP?)rtolTr=   )price_searchedtotal_occurrencesexact_matchesnear_matchesoccurrences)iterrowsstrftimenpiscloseappendlen)r0   r<   is_toptolerance_percentlower_boundupper_boundmatching_datesrC   indexrow
occurrenceoccs               r&   find_price_occurrence_marS   Q   sY    10445K10445KRZ;62f:;TUV RY+5"U){:RST K$--/ '
sNN:.$*S[E
 

 zz#f+u59,0
=)zz#e*e%8,0
=):&'$   -)4K#M8J#K(3N3};MN"  LNs   
D)D3
D
>D
c           	          	 t        |       }t        |      }|S # t        $ r4}t        d| j	                  dd       dt        |              Y d}~yd}~ww xY w)z
    Process price data and Return the Response.

    Args:
    data (dict): Dictionary containing price and instrument data
    zError processing data for symbolUnknownz: N)analyze_price_data_graphconvert_objectid_ma	Exceptionprintgetr   )dataoutputserialized_outputes       r&   process_price_data_mar`      s^    )$/ 07   *488Hi+H*ICPQF8TUs    	A*AAc                    K   	 t        | |      }t        |      }|S # t        $ r}dt        |      icY d}~S d}~ww xY ww)z
    Process price data for a single symbol asynchronously.

    Args:
    data (dict): Dictionary containing price and instrument data.
    duration (str): Duration to analyze.

    Returns:
    dict: Analyzed output.
    errorN)analyze_price_data_mamake_json_safe_marY   r   )r\   r    r]   r_   s       r&   process_single_symbol_mare      sF     	!&tX6 #6* !Q  !s(   A  A 	=8=A =A c                    t        | t              r| D cg c]  }t        |       c}S t        | t              r-| j	                         D ci c]  \  }}|t        |       c}}S t        | t
              rt        |       S | S c c}w c c}}w )N)r   listrX   dictitemsr   r   r\   itemkeyvalues       r&   rX   rX      st    $6:;d#D);;	D$	BF**,OJC(//OO	D(	#4y <Os   BB	c                    t        | t              r| D cg c]  }t        |       c}S t        | t              r-| j	                         D ci c]  \  }}|t        |       c}}S t        | t
        t        j                  t        j                  f      r6t        j                  |       st        j                  |       ryt        |       S t        | t        t        f      r| S t        |       S c c}w c c}}w )zN
    Recursively replace non-JSON-compliant values in the data structure.
    N)r   rg   rd   rh   ri   floatrF   float64float32isnanisinfintr   rj   s       r&   rd   rd      s     $489D!$'99	D$	@D

M*#u&u--MM	D5"**bjj9	:88D>RXXd^T{	D3*	%4y :Ms   C/C4
time_ranger!   r"   returnc                    t        j                         }|r.|r,t        j                  |d      t        j                  |d      fS | rk| j                         } dddd}t	        |       dk  rt        d      | d   }	 t        | d	d       }||vrt        d      |||   z  }|t        |      z
  |fS |t        d      z
  |fS # t
        $ r t        d
      w xY w)a  
    Parse time range or custom date range.

    Supported time ranges:
    - 1W: 1 Week
    - 1M: 1 Month
    - 3M: 3 Months
    - 6M: 6 Months
    - 1Y: 1 Year
    - 2Y: 2 Years
    - 3Y: 3 Years
    - 5Y: 5 Years

    If custom dates are provided, they take precedence.
    r:      r   r   )WMY   zInvalid time range formatr*   NzInvalid time range valuezInvalid time range unitr   )r   r   strptimeupperrI   r   rt   r   )ru   r!   r"   r   multipliersunitrm   r   s           r&   parse_time_range_mar      s   $ ,,.C h  Z8(:K:KHV`:aaa %%'

 z?Q899"~	9
3B(E {"677{4((YD))3.. $$c))  	9788	9s   <C Cc                     i }| j                         D ]/  \  }}t        j                  |d      }||cxk  r|k  s(n +|||<   1 |S )z7
    Filter prices dictionary based on date range.
    r:   )ri   r   r}   )pricesr!   r"   filtered_pricesdate_str
price_datar;   s          r&   filter_prices_by_date_range_mar      sT     O & 3*  :6))(2OH%3 r6   c           
         g g d}t        dt        |       dz
        D ]  }| j                  |dz
  | d   j                         }| j                  |dz   |dz    d   j                         }| j                  |   d   }||k  r~||k  ry|d   j	                  | j
                  |   j                  d      || j                  |   d   | j                  |   d	   | j                  |   d   | j                  |   d
   dd       | j                  |dz
  | d	   j                         }| j                  |dz   |dz    d	   j                         }| j                  |   d	   }||kD  sD||kD  sK|d   j	                  | j
                  |   j                  d      || j                  |   d   | j                  |   d	   | j                  |   d   | j                  |   d
   dd        |S )zSMark levels where the bottom candles before and after two candles are not touching.)bottom_levels
top_levelsr|   r9   r	      r   r:   openr8   r)   r   r8   r9   r)   )r;   r<   candle_datar   )rangerI   r/   minrH   rO   rE   max)	r0   special_levelsiprev_two_bottomnext_two_bottomcurrent_bottomprev_two_topnext_two_topcurrent_tops	            r&   mark_special_levels_mar     s   ')<N1c"gk"  ''!a%!,U3779''!a%!a%07;;=E*O+0P?+22HHQK00<+ "
6 2 "
6 2!wwqz%0!#G!4	$	 wwq1uq)&1557wwq1uq1u-f599;ggaj(%+*D<(//HHQK00<( "
6 2 "
6 2!wwqz%0!#G!4	$	+ B r6   c                    g }g }t        |t        |       |z
        D ]k  }| d   |   t        | d   ||z
  ||z   dz          k(  r|j                  |       | d   |   t	        | d   ||z
  ||z   dz          k(  s[|j                  |       m ||fS )z5Find support and resistance levels in the price data.r9   r	   r8   )r   rI   r   rH   r   )r   windowsupportsresistancesr   s        r&   find_support_resistance_mar   .  s    HK63v;/0 "%=s6%=Va&j1n#MNNOOA&>!F6N1v:F
Q$O PPq!	"
 [  r6   c           
         | d   }t         j                  j                  |d      }t        j                  |j                        |_        |j                  d       	 t        ||j                  d         \  }}|j                  || }| d	   | d
   | d   | d   ||j                  d      |j                  d      dd}t        |      |d<   |d   j                         }	|d   j                         }
|	t        ||	dd      t        ||	dd      t        ||	dd      d|
t        ||
dd      t        ||
dd      t        ||
dd      dd|d<   |j                  d   d   }||j                  d   d   }|j                  d   d   }||z
  }||z  dz  }|||t!        |d      d |d!<   |S # t        $ r}dt        |      icY d}~S d}~ww xY w)"z
    Analyze price data for specified duration

    Args:
    data (dict): Dictionary containing price and instrument data
    duration (str): Duration to analyze

    Returns:
    dict: Comprehensive price analysis
    r   rO   orientTinplacer*   rb   NrU   
Instrumentinstrument_tokenexchange_tokenr:   )r!   r"   )rU   r   r   r   r    analysis_periodcurrent_trendr8   r9   g?)rJ   rK         ?r	   )r<   rA   znear_matches_0.5%znear_matches_1%F)	top_pricebottom_priceprice_detailsr   
prev_closer)   r+   r|   )r1   r2   absolute_changer4   price_performance)r   	DataFrame	from_dictr   rO   
sort_indexr'   r   r   locrE   r5   r   r   rS   r/   round)r\   r    r   r0   r!   r"   r_   df_durationr]   r   r   r1   r2   price_changer4   s                  r&   rc   rc   9  s,    (^F			w		7B~~bhh'BHMM$M!4Xrxx|L
H
 &&H-K x.<( !34/0$--j9 ))*5

F 9EF? F#'')Iu%))+L
 5k9UYmpq!9+yY]qt!u7YW[opq	
 "5k<X]qtu!9+|\aux!y7\Z_stu	
F?  ""1%l3K!&&q)'2!!"%g.J+L%3s: # '"#4a8	#F Ms  !Q  !s   F. .	G7G	G	Gc                    | d   }t         j                  j                  |d      }t        j                  |j                        |_        |j                  d       t        |      }t        |      \  }}g g g |d   |d   d}|D ]{  }|j                  |   j                  d	      }|d
   j                  ||j                  |   d   |j                  |   d   |j                  |   d   |j                  |   d   di       } |D ]{  }|j                  |   j                  d	      }|d   j                  ||j                  |   d   |j                  |   d   |j                  |   d   |j                  |   d   di       } t        ||z         }	g }
|	D ]R  }||v rdnd|j                  |   ||v r|j                  |   d   n|j                  |   d   d}|
j                  |       T t        dt        |
            D ]  }|
|dz
     }|
|   }|d   dk(  r
|d   dk(  rdn|d   dk(  r
|d   dk(  rdnd}|s9|d   }|d   }||z
  }||z  dz  }|d   |d   z
  j                  }|d   j                  d	      |d   j                  d	      |||||t        |d      d}|d   j                  |        | d   |d<   | d    |d <   |S )!z5Analyze price data and extract key levels and trends.r   rO   r   Tr   r   r   )bottomtoptrendsspecial_bottom_levelsspecial_top_levelsr:   r   r   r8   r9   r)   r   r   support
resistance)typer;   r<   r	   r   uptrend	downtrendNr<   r+   r;   r|   )r!   r"   trendr   start_price	end_pricer   r4   r   rU   r   )r   r   r   r   rO   r   r   r   rE   rH   r/   sortedr   rI   r   r   )r\   r   r0   special_marked_levelsr   r   r]   idxr;   levelstrend_pointspointr   start_point	end_point
trend_typer   r   r   r4   trend_durationtrend_detailss                         r&   rW   rW     sQ   (^F			w		7B~~bhh'BHMM$M2266r:Hk!6!G3LAF  
xx}%%j1xGGCL0GGCL0773<.WWS\'2			

  
xx}%%j1uGGCL0GGCL0773<.WWS\'2			

 H{*+FL #!$IlHHSM,/8ORWWS\%(fAU

 	E"# 1c,'( 3"1q5) O	 6"i/If4E4U  6"l2y7HI7U  	 %g.K!'*I${2L!-!;s B'/+f2EEKKN)&1:::F%f-66zB#&*& ,%*+<a%@	M 8##M2536 H~F8-F<Mr6   )NN)Tr   )NNN)r   )r   )r   r   typingr   bsonr   pandasr   numpyrF   warningsfilterwarningsr'   r5   rS   r`   re   rX   rd   r   tupler   r   r   r   rc   rW    r6   r&   <module>r      s    (         ! .*AX41f(!,$ 5915/31*HSM 1*!)#1*'}1*8=1*f	$L	!M`Mr6   