o
    ̿SiD*                     @   s  d dl Z d dlmZ d dlmZmZmZmZmZmZm	Z	 d dl
mZ edZe ddZe dd	Ze d
dZee ddZdZdZdZd1dee defddZd2ddZdee dee fddZdddedee dedeeeeeef f  def
ddZdedee dede	eef fd d!Zdd"ded#eee  dee fd$d%Zdd&dedeee  deeee f fd'd(Zdedeeef fd)d*Zdedee deeef fd+d,Zdedee dedeeef fd-d.Z dededeeef fd/d0Z!dS )3    N)datetime)AnyDictIterableListOptionalSetTuple)ZoneInfozAsia/KolkataINTRADAY_WATCHLIST_COLLECTIONintraday_watchlist_itemsINTRADAY_ET_LAST_SYNC_META_KEY#intraday_watchlist_et_last_sync_utcINTRADAY_SEEDED_META_PREFIXintraday_watchlist_seededINTRADAY_ET_SYNC_MINUTES30EARLY_MOVERS	ET_MOVERSMANUALnow_utcreturnc                 C   s*   | pt  }|jtddt  S )NUTC)tzinfo)r   utcnowreplacer
   
astimezoneISTdate	isoformat)r   now r!   @/var/www/html/Trade-python/app/v1/services/intraday_watchlist.pyist_date_str   s   r#   c                 C   sf   z| t  jddgdddd W n	 ty   Y nw z| t  jddgddd W d S  ty2   Y d S w )	N)ist_date   symbolr%   T%ux_intraday_watchlist_ist_date_symbol)uniquename
background)sourcesr%   &ix_intraday_watchlist_ist_date_sources)r*   r+   )WATCHLIST_COLLECTIONcreate_index	Exception)dbr!   r!   r"   ensure_indexes   s&   
r2   symbolsc                 C   sF   g }| pg D ]}t |tsq|  }|r|| qtt|S N)
isinstancestrstripupperappendlistdictfromkeys)r3   outssymr!   r!   r"   _norm_symbols2   s   

r@   )meta_by_symbolr$   sourcerA   c             	   C   s   t |}|sdS t }d}|D ]Z}t|tr|pi |nd }	|||ddt|p*d  id|id}
t|	trN|	rN|	|
d dt|pFd   < z| t	 j
||d	|
d
d |d7 }W q tyj   Y qw |S )Nr   )r$   r'   
updated_atr,    
created_at)$setz	$addToSetz$setOnInsertrF   source_meta.r$   r'   Tupsertr%   )r@   r   r   r5   r;   getr6   r7   r8   r.   
update_oner0   )r1   r$   r3   rB   rA   symsr    updatedr?   metaupdater!   r!   r"   upsert_symbols>   s(   
"rQ   c          
      C   s   t |pd  }|sdS ||d}|rdtt|i|d< z | t |d|id| didt id	}t	|j
p<d
}W n tyJ   d
}Y nw z| t |dd
id}t	|jp]d
}	W ||	fS  tyq   d
}	Y ||	fS w )zbRemove a source tag from items not in `symbols`.

    Returns: (touched_count, deleted_count)
    rD   )r   r   r$   r,   z$ninr'   r,   rG   rC   z$pullz$unsetrF   r   $size)r6   r7   r8   sortedr:   r.   update_manyr   r   intmodified_countr0   delete_manydeleted_count)
r1   r$   r3   rB   srcqrestoucheddelresdeletedr!   r!   r"   _pull_source_   s.   
 ra   )sources_anyrb   c          	      C   s~   d|i}|rdd |D }|rd|i|d< | t  |dddd	g}g }|D ]}|d
p0d  }|r<|| q(|S )Nr$   c                 S   s0   g | ]}t |pd  rt |pd   qS )rD   )r6   r7   r8   .0r>   r!   r!   r"   
<listcomp>   s   0 z list_symbols.<locals>.<listcomp>$inr,   r   r%   )_idr'   r&   r'   rD   )r.   findsortrK   r7   r8   r9   )	r1   r$   rb   r\   srcscurr=   dr?   r!   r!   r"   list_symbols   s   
rm   )r3   c          	      C   s   d|i}|rdt |i|d< | t |dddd}i }|D ](}|dp&d  }|s.q|d}t|trBd	d
 |D ||< qg ||< q|S )Nr$   rf   r'   r   r%   )rg   r'   r,   rD   r,   c                 S   s.   g | ]}t |tr| rt|  qS r!   )r5   r6   r7   r8   rc   r!   r!   r"   re      s   . z*get_symbol_sources_map.<locals>.<listcomp>)r@   r.   rh   rK   r7   r8   r5   r:   )	r1   r$   r3   r\   rk   r=   rl   r?   rj   r!   r!   r"   get_symbol_sources_map   s   


rn   c             
   C   s$  t  d| }| d d|i}|r$t|dpd dkr$ddd	S | td
d ji dgd}|s9ddd	S t|trC|dnd}t|trL|ni }t|dt	r[|dng }t|dt	rj|dng }g }i }	|D ]9}
t|
tszqr|
dpd 
 }|sqr|| d|
d|
d|
d|
d|
d|
dd|	|< qr|D ]9}
t|
tsq|
dpd 
 }|sq|| d|
d|
d|
d|
d|
d|
dd|	|< qt| ||t|	d}| d jd|id|dt |dd id!d" d!||dd#S )$zSeed today's watchlist from the latest early movers snapshot.

    - One-time per `ist_date` (tracked in system_meta)
    - No removals: early movers list is fixed for the trading day.
    :system_metakeyvaluerD   1Falready_seeded)seededreason EARLY_MOVERS_SNAPSHOT_COLLECTIONearly_movers_snapshots)r   )ri   no_snapshottopNbullishbearishr'   BULLISHfinal_score
algo_scorescore	key_leveldistance_to_level_pct
risk_flags)biasr   r   r   r   r   r   BEARISH)r$   r3   rB   rA   rF   r   )rq   rr   rC   snapshot_dateTrI   )ru   countr   )_SEEDED_KEY_PREFIXfind_oner6   rK   r7   osgetenvr5   r;   r:   r8   r9   rQ   SOURCE_EARLYrL   r   r   )r1   r$   meta_keyalreadysnapr{   r|   r}   r3   rO   itr?   insertedr!   r!   r"   %maybe_seed_from_early_movers_snapshot   sh   







r   c                C   s  t  }| d dtipi }|d}d}t|tr2| r2zt |}W n t	y1   d}Y nw t|t rQ|| 
 d }|tdttk rQddt|d	d
S t|}t|}	t| ||td}
t| ||	td\}}| d jdtidt| |t|didd d|
||t|dS )zReconcile today's watchlist ET symbols to exactly `symbols`.

    - Adds missing symbols with source=ET_MOVERS
    - Removes ET source tag from symbols no longer present
    rp   rq   rr   Ng      N@r%   Fcooldown   )syncedrv   age_minutes)r$   r3   rB   rF   )rq   rr   rC   r   TrI   )r   addedremoved_sourcer`   r   )r   r   r   _ET_LAST_SYNC_KEYrK   r5   r6   r7   fromisoformatr0   total_secondsmaxrW   ET_SYNC_MINUTESroundr@   setrQ   	SOURCE_ETra   rL   r   len)r1   r$   r3   r    lastlast_vlast_dtage_minrM   keepr   r^   r`   r!   r!   r"   maybe_sync_from_et_movers   s0   

r   c          
      C   s   t |pd  }t|}|r|sddddS z%| t |d|idd|id| did	t id
}t|j	p:d}W n t
yH   d}Y nw z| t |ddid}t|jp[d}	W n t
yi   d}	Y nw d||	dS )z@Remove `source` tag for the given symbols on the given IST date.rD   Tr   okr   r`   rf   rH   r,   rG   rC   rS   rT   rR   )r6   r7   r8   r@   r.   rV   r   r   rW   rX   r0   rY   rZ   )
r1   r$   r3   rB   r[   rM   r]   removedr_   r`   r!   r!   r"   remove_source_for_symbols  s(    r   c                C   s   t |pd  }|sddddS z#| t ||dd|id| didt id	}t|jp2d}W n t	y@   d}Y nw z| t 
|d
did}t|jpSd}W n t	ya   d}Y nw d||dS )z1Remove `source` from ALL items for that IST date.rD   Tr   r   rR   r,   rG   rC   rS   rT   )r6   r7   r8   r.   rV   r   r   rW   rX   r0   rY   rZ   )r1   r$   rB   r[   r]   r   r_   r`   r!   r!   r"   clear_source_for_date*  s&    r   r4   )r   N)"r   r   typingr   r   r   r   r   r   r	   zoneinfor
   r   r   r.   r   r   rW   r   r   r   SOURCE_MANUALr6   r#   r2   r@   rQ   ra   rm   rn   r   r   r   r   r!   r!   r!   r"   <module>   sD    $

&!(!0"I&$"