
    ]pj                     p    S r SSKrSSKrSSKrSSKJr  SSKJr  \R                  " \5      r	 " S S5      r
g)u  
Trade Signal Notifier — отправка сигналов через Telegram/Webhook.

Режимы:
  - Telegram: бот отправляет сообщение при BUY/SELL сигналах
  - Webhook: POST запрос на указанный URL

Использование:
  from utils.notifier import Notifier
  n = Notifier()
  n.send_signal(ticker='SBER', signal='BUY', confidence=0.75, price=294.13)
  n.send_summary(summary={'total_buy': 3, 'total_sell': 1, 'total_neutral': 10})
    N)datetime)Optionalc                   H   \ rS rSrSr    S S\\   S\\   S\\   S\4S jjr  S!S	\S
\S\S\S\S\SS4S jjr	S\
SS4S jrS\SS4S jr S!S	\S\S\S\SS4
S jjr\S	\S
\S\S\S\S\S\4S j5       r\S\
S\4S j5       rS\SS4S jrS\SS4S jrS\SS4S jrSrg)"Notifier   u   Уведомитель о торговых сигналах.

Поддерживает Telegram и Webhook.
Настройки читает из окружения (.env) либо переданных параметров.
Ntelegram_tokentelegram_chat_idwebhook_urlmin_confidencec                    U=(       d    [         R                  R                  S5      U l        U=(       d    [         R                  R                  S5      U l        U=(       d    [         R                  R                  S5      U l        X@l        [        U R                  =(       a    U R                  5      U l        [        U R
                  5      U l	        U R                  (       d(  U R                  (       d  [        R                  S5        g g g )NTELEGRAM_BOT_TOKENTELEGRAM_CHAT_IDNOTIFIER_WEBHOOK_URLzaNotifier: no channels configured. Set TELEGRAM_BOT_TOKEN+TELEGRAM_CHAT_ID or NOTIFIER_WEBHOOK_URL)osenvirongetr   r	   r
   r   bool_telegram_enabled_webhook_enabledloggerinfo)selfr   r	   r
   r   s        //home/ai/projects/AI_Strategy/utils/notifier.py__init__Notifier.__init__   s     -T

?S0T 0 VBJJNNCU4V&P"**..9O*P,!%d&9&9&Sd>S>S!T $T%5%5 6&&$*?*?KKR +@&    tickersignal
confidencepricep_longp_shortreturnc                 z    US:X  a  gX0R                   :  a  gU R                  XX4XV5      nU R                  U5        g)u{   Отправляет уведомление о сигнале (только BUY/SELL, если confidence >= порога).NEUTRALN)r   _format_signal_notify)r   r   r   r   r    r!   r"   messages           r   send_signalNotifier.send_signal8   s>     Y+++%%fjYWr   summaryc                 H    U R                  U5      nU R                  U5        g)u\   Отправляет сводку после мониторинга всех тикеров.N)_format_summaryr'   )r   r+   r(   s      r   send_summaryNotifier.send_summaryJ   s    &&w/Wr   textc                 ,    U R                  SU 35        g)ul   Отправляет произвольное предупреждение (ошибки, аномалии).u   ⚠️ *AI Strategy Alert*
Nr'   )r   r0   s     r   
send_alertNotifier.send_alertO   s    3D6:;r   reasonpnldepositc                     U(       a  US OSnU(       a  US OSnUS:  a  X4-  S-  S S3OSnSU S	U S
U SU SU S3nU R                  U5        g)ui  Уведомление о блокировке тикера через auto-disable (audit 2026-08-03).

Args:
    ticker: заблокированный тикер.
    reason: причина блокировки (например 'auto_disable (PnL -4367/92035...)').
    pnl: суммарный PnL за окно.
    deposit: текущий депозит.
z+.0fzN/Az.0fr   d   z+.1f%u2   🚫 *AI Strategy: Ticker Auto-Disabled*
Ticker: `z
`
Reason: u   
PnL за окно: u    ₽ (u    от депозита u    ₽)
Cooldown: 7 днейNr2   )	r   r   r5   r6   r7   pnl_strdep_strpnl_pctr(   s	            r   send_ticker_disabledNotifier.send_ticker_disabledS   s     $'SJE&-WSM507!S[_T*!,x  h "")&	9PQXPY Z#$ 	 	Wr   c                     US:X  a  SOSnU SU  SU SUS SUS	 S
US	 SUS	 S[         R                  " 5       R                  S5       3$ )NBUYu   🟢u   🔴z *z*: u   
├ Price: z.2fu   
├ Confidence: .1%u   
├ P(Long): u   
└ P(Short): u   
🕐 %H:%M %d.%m.%Y)r   nowstrftime)r   r   r   r    r!   r"   emojis          r   r&   Notifier._format_signalm   s{    
 !E/vgRxs6( + %)#. /"3< ($SM *LLN++,<=>@	
r   c                    U R                  SS5      U R                  SS5      -   U R                  SS5      -   nSSU S3/nU R                  S5      (       a  UR                  SU S    35        U R                  S5      (       a  UR                  S	U S    35        U R                  S5      (       a  UR                  S
U S    35        U R                  S5      (       aH  UR                  S5        U S    H.  nUR                  SUS    SUS    SUS    SUS   S S3	5        M0     UR                  S[        R                  " 5       R	                  S5       35        SR                  U5      $ )N	total_buyr   
total_selltotal_neutralu   📊 *Monitor Summary*u   ├ Total: z tickersu   ├ 🟢 BUY: u   ├ 🔴 SELL: u   ├ ⚪ NEUTRAL: signalsu   └ Signals:z   rF    r   z: r   z (r   rB   )u   🕐 rC   
)r   appendr   rD   rE   join)r+   totallinesss       r   r-   Notifier._format_summary|   sa   K+gkk,.JJW[[YhjkMll$%)
 ;;{##LL>'+*>)?@A;;|$$LL?7<+@*ABC;;''LL,W_-E,FGH;;y!!LL<)Y's1W:,a(}Bq{m2aP\o^aMbbcde (uX\\^445EFGHIyyr   r(   c                    / nU R                   (       a   U R                  U5        U R                  (       a   U R                  U5        U(       a&  [        R                  SSR                  U5      5        gg! [         a4  nUR                  SU 35        [        R                  SU5         SnANSnAff = f! [         a4  nUR                  SU 35        [        R                  SU5         SnANSnAff = f)u^   Отправляет сообщение через все настроенные каналы.z
Telegram: z Telegram notification failed: %sNz	Webhook: zWebhook notification failed: %szNotifier errors: %sz; )
r   _send_telegram	ExceptionrP   r   errorr   _send_webhookwarningrQ   )r   r(   errorses       r   r'   Notifier._notify   s    !!D##G,
   C""7+
 NN0$))F2CD   D
1#./?CCD  C	!o.>BBCs.   A7 B8 7
B5*B00B58
C6*C11C6c                 @   SSK nSU R                   S3nU R                  USSS.nUR                  X4SS	9nUR	                  5         UR                  5       nUR                  S
5      (       d  [        SUR                  SS5       35      e[        R                  S5        g)uD   Отправляет сообщение через Telegram Bot API.r   Nzhttps://api.telegram.org/botz/sendMessageMarkdownT)chat_idr0   
parse_modedisable_web_page_preview
   )jsontimeoutokzTelegram API error: descriptionunknownzTelegram notification sent)
requestsr   r	   postraise_for_statusre   r   RuntimeErrorr   debug)r   r0   rj   urlpayloadrespdatas          r   rW   Notifier._send_telegram   s    ,T-@-@,AN,,$(,	
 }}S};yy{xx~~!5dhh}i6X5YZ[[12r   c                     SSK nUS[        R                  " 5       R                  5       S.nUR	                  U R
                  USSS0S9nUR                  5         [        R                  S	5        g)
u8   Отправляет POST запрос на webhook URL.r   Nai_strategy)r0   source	timestamprd   zContent-Typezapplication/json)re   rf   headerszWebhook notification sent)	rj   r   utcnow	isoformatrk   r
   rl   r   rn   )r   r(   rj   rp   rq   s        r   rZ   Notifier._send_webhook   so     #!*446

 }}#%78	  
 	01r   )r   r   r   r	   r   r
   )NNNg?)        r|   )__name__
__module____qualname____firstlineno____doc__r   strfloatr   r)   dictr.   r3   r>   staticmethodr&   r-   r'   rW   rZ   __static_attributes__ r   r   r   r      s    )-*.%) $  #3- c]	
 >   	
    
$D T 
<s <t <
 BE3  #(9>IM4 

 
.3
<A

 %
 

 
    #    .Es Et E*33 34 3$2S 2T 2r   r   )r   r   re   loggingr   typingr   	getLoggerr}   r   r   r   r   r   <module>r      s7    
    			8	$s2 s2r   