
    E1WjN              	       
   S r SSKrSSKrSSKrSSKrSSKrSSKJr  SSKJrJ	r	J
r
  SSKrSSKr\R                  R!                  S\R                  R#                  \R                  R%                  \5      5      5        SSKJrJr  SSKJr  SSKJr  SSKJr  SS	KJr  SS
KJ r   SSK!J"r"  Sr#SrS(S\$S\$S\
\$   4S jjr%S)S\$S\$S\&S\RN                  4S jjr(S\)\$   4S jr*S\+S\$S\$S\+4S jr,S\+S\$S\$S\+4S jr-S*S\$S\+4S jjr.S(S\$S\$S\/4S jjr0S\	\   S\$S\$4S jr1S\$S\$4S jr2S\$S\	\   4S jr3S\$S\	\   SS4S  jr4S(S\$S\$S\
\   4S! jjr5S+S" jr6S+S# jr7S+S$ jr8S\Rr                  4S% jr:S& r;\<S':X  a  \;" 5         gg),u  
Ежечасный мониторинг торговых сигналов для всех MOEX тикеров.

Запуск вручную:  python3 monitor.py
Запуск через cron: 0 * * * * /usr/bin/python3 /path/to/AI_Strategy/monitor.py

Функции:
- Загрузка данных для каждого тикера
- Предсказание сигналов с использованием обученных моделей
- Запись результатов в отдельный файл для каждого тикера (Markdown таблица)
- Фильтрация: записи только при наличии новой свечи
    N)datetime)DictListOptional)MOEX_TICKERSSAVE_DIR)load_dataframe)engineer_features)add_directional_signals)add_curated_context)compute_dual_outcomes)ExpertEnsemble
monitoringzmodels/savedticker	timeframereturnc                 z   [         R                  R                  [        5      nU R	                  5        SUR	                  5        S3U R	                  5        SUR	                  5        S3/nU HJ  n[         R                  R                  X$5      n[         R                  R                  U5      (       d  MH  Us  $    g)u   Находит путь к модели для тикера.

Приоритет (от лучшего к базовому):
  1. {ticker}_{timeframe}_experts.joblib  — ExpertEnsemble + RF
  2. {ticker}_{timeframe}_directional.joblib — Directional RF
_z_experts.joblibz_directional.joblibN)ospathjoinr   lowerexists)r   r   
models_dirpatternsfnamer   s         (/home/ai/projects/AI_Strategy/monitor.py_find_model_pathr   /   s     h'J <<>
!IOO-.o><<>
!IOO-..ABH
 ww||J.77>>$K 
     limitc                     [        XU5      n[        U5      n[        U5      n[        U5      n[	        USSSS9nUR                  5       $ )uG   Подготавливает DataFrame для предсказания.g      ?g      @d   )atr_mult_slatr_mult_tpmax_bars)r	   r
   r   r   r   dropna)r   r   r    dfs       r   _prepare_dfr(   J   sH    	5	1B	2	B	 	$B	R	 B	rsc	RB99;r   c                      SSK Jn   SSKJnJnJn  SSKJn  [        [        R                  X-   U-   U-   U-   5      5      nU$ )u1   Базовые колонки признаков.r   )DIRECTIONAL_COLS)FEATURE_COLSINTERACTION_COLSTEMPORAL_COLS)CONTEXT_COLS)features.directionalr*   features.technicalr+   r,   r-   features.contextr.   listdictfromkeys)r*   r+   r,   r-   r.   colss         r   _get_feature_colsr6   T   s@    5PP-',69IIMY D Kr   savedc           	         [        XSS9n[        U5      S:  a  [        S5      $ U R                  S/ 5      nU(       d  U R                  S/ 5      nU(       d+  [	        5        Vs/ s H  oUUR
                  ;   d  M  UPM     nnU Vs/ s H  oUUR
                  ;   d  M  UPM     nnU(       d  [        S5      $ U R                  S/ 5      nU R                  S	[        U5      5      n[        XS
9n	U	R                  U S   5        U	R                  5         U	R                  X65      n
U	R                  X65      nSSKJn  U" X:XUS9nSU ;   =(       a    SU ;   nU(       Ga
  U S   nU S   nU R                  S5      nUR                  U5      S   nUR                  U5      S   nU(       aR  UR                  S5      nUR                  S5      nUb  UR                  U/5      S   nUb  UR                  U/5      S   n[        U5      [        U5      nnU R                  SSSS.5      nUR                  SS5      nUR                  SS5      nUU:  a  UU:  a  SOUU:  a  UU:  a  SOSnOU S   nUR                  U5      nUS   R                   S   S:  a  US   S   OUS   S   nUS   R                   S   S:  a  US   S   OUS   S   nUU:  a  US:  a  SOUU:  a  US:  a  SOSn[#        UU5      nUR$                  S   nU['        [        U5      S5      ['        [        U5      S5      ['        [        U5      S5      [)        US    5      [        US!   5      S".$ s  snf s  snf )#u}  Делает предсказание через ExpertEnsemble (16 экспертов + ExpertFusion + RF).

Поддерживает:
  - v1: MultiOutputClassifier, ключ 'model'
  - v2: раздельные rf_long/rf_short + калибрация + per-ticker thresholds

Возвращает dict с ключами:
    signal, confidence, p_long, p_short, timestamp, close
  r    2   %   Недостаточно данныхfeature_colsfeatures,   Нет доступных признаковexpert_namesn_base_features)
n_featuresexpertsexpert_stater   )_build_dataset)fusion_embedding
model_longmodel_shortcalibrators)   longshort
thresholds皙?)rL   rM   BUYSELLNEUTRALmodelrK   )rJ   r   rJ      	timestampClosesignal
confidencep_longp_shortrU   close)r(   len_null_resultgetr6   columnsr   load_state_dict	to_devicepredict_allcompute_fusion_embedding
models.moerE   predict_probapredictfloatshapemaxilocroundint) r7   r   r   r'   	feat_colsc	availabler@   n_baseensembleexpert_signals
fusion_embbuild_datasetXis_v2rf_longrf_shortrI   
p_long_rawp_short_rawiso_long	iso_shortlpsprN   long_thshort_thrX   rfprobsrY   lasts                                    r   _predict_expertsr   c   s[    
Vd	3B
2w|CDD 		."-IIIj"-	 1 3G 31BJJQ 3	G%9IqbjjII9JKK 99^R0LYY(#i.9FFHU>23 ))"8N222AJ ;b('1	3A E!<mu&<E%'ii.**1-e4
,,Q/6 "v.H#0I#%--zl;A>
$'//>qAz"E+$6B YY|dT-JK
...>>'40r'bGmGh&I 	 7^  # %aq 1A 5U1Xe_58E? %aq 1A 5U1Xe_58E?r'bDjbRSWZv]fRJ772;D E*-q1b	1%rA&k*+tG}%  H9s   #M:MMMc           	         [        XSS9n[        U5      S:  a  [        S5      $ U R                  S/ 5      nU Vs/ s H  oUUR                  ;   d  M  UPM     nnU(       d  [        S5      $ X6   R
                  nU S   nUR                  U5      n	S n
U
" U	S	   5      S
   nU
" U	S   5      S
   nUR                  S
   nX:  a  US:  a  SOX:  a  US:  a  SOSn[        X5      nU[        [        U5      S5      [        [        U5      S5      [        [        U5      S5      [        US   5      [        US   5      S.$ s  snf )u   Делает предсказание через Directional RF.

Возвращает dict с ключами:
    signal, confidence, p_long, p_short, timestamp, close
r9   r:   r;   r<   r>   r?   rS   c                 ~    U R                   S   S:  a	  U S S 2S4   $ [        R                  " U S S 2S4   S:  SS5      $ )NrK   r   g      ?g      ?        )ri   npwhere)prob_arrs    r   
_safe_prob(_predict_directional.<locals>._safe_prob   sA    >>!q AqD>!xxA,c377r   r   rJ   rK   rO   rP   rQ   rR   rT   rU   rV   rW   )r(   r]   r^   r_   r`   valuesrf   rk   rj   rl   rh   rm   )r7   r   r   r'   rn   ro   rp   rv   rS   r   r   r~   r   r   rX   rY   s                   r   _predict_directionalr      sE    
Vd	3B
2w|CDD 		*b)I%9IqbjjII9JKK 	A'NE"E8
 
E!H	b	!B	E!H	b	!B772;Dg"*URWt6YbFRJ E*-q1b	1%rA&k*+tG}% / :s   D?D?reasonc                     SSSSSSU S.$ )u-   Возвращает null-результат.rR   r   r   )rX   rY   rZ   r[   rU   r\   error )r   s    r   r^   r^      s#      r   c                      [        XSS9n[        U5      S:  a  g[        UR                  S   S   5      n[        UR                  S   S   5      nX4:  $ ! [         a     gf = f)uL   Проверяет, есть ли новая свеча для тикера.   r:   FrJ   rU   )r	   r]   rm   rk   	Exception)r   r   r'   last_tsprev_tss        r   _is_new_candler     sl    FQ7r7Q;bggbk+./bggbk+./    s   A 9A 
A#"A#resultsc                 t   U (       d-  [         R                  " 5       R                  S5      nSU SU S3$ [         R                  " U S   S   5      R                  S5      nSU SU S[	        U 5       S	3nU  Hx  n[         R                  " US   5      R                  S5      nUS
   S nUS   S nUS   S n	US   S n
US   nUS:X  a  SnOUS:X  a  SnOSnUSU SU SU SU SU	 SU
 S3-  nMz     [        S U  5       5      n[        S U  5       5      n[        S U  5       5      nUSU SU SU S3-  nU$ ) uK   Генерирует Markdown таблицу для результатов.%Y-%m-%d %H:%Mz# u:    - Мониторинг сигналов

**Время:** u   

_Нет данных_
rJ   rU   uC    - Мониторинг сигналов

**Дата/Время:** u   

*Всего записей:* z

| Timestamp | Close | Signal | Confidence | P(Long) | P(Short) |
|-----------|-------|--------|-----------|--------|----------|
r\   .2frY   .1%rZ   r[   rX   rP   u   🟢 **BUY**rQ   u   🔴 **SELL**u   ⚪ NEUTRALz| z | z |
c              3   :   #    U  H  oS    S:X  d  M  Sv   M     g7f)rX   rP   rK   Nr   .0rs     r   	<genexpr>*generate_markdown_table.<locals>.<genexpr><  s     ;7akU&:7   	c              3   :   #    U  H  oS    S:X  d  M  Sv   M     g7f)rX   rQ   rK   Nr   r   s     r   r   r   =  s     =Gq{f'<Gr   c              3   :   #    U  H  oS    S:X  d  M  Sv   M     g7f)rX   rR   rK   Nr   r   s     r   r   r   >  s     Cw!H+*BAAwr   u'   
---

**Статистика:**
- BUY: z	 | SELL: z | NEUTRAL: 
)r   nowstrftimefromtimestampr]   sum)r   r   r   date_strmdr   tsr\   confrZ   r[   rX   n_buyn_sell	n_neutrals                  r   generate_markdown_tabler     s   lln%%&67 "e $&'	
 %%gbk+&>?HHIYZH VH $$,: .((+G~ 6K	K  ##AkN3<<=MNW:c"L/#&hK$y\#&8U?#Fv$F"F
2$c%F83tfCxs7)4PP " ;7;;E=G==FCwCCI		&i[	DB Ir   c                 l    [         R                  R                  [        U R	                  5        S35      $ )Nz_monitor.md)r   r   r   SAVE_DIR_MONITORr   )r   s    r   _monitor_filenamer   M  s&    77<<(V\\^,<K*HIIr   c           
         [        U 5      n[        R                  R                  U5      (       d  / $  [	        USSS9 nUR                  5       nSSS5        / nWR                  S5       GH  nUR                  5       nUR                  S5      (       a  SU;   d  SU;   a  M8  UR                  S5       Vs/ s H  ofR                  5       PM     nn[        U5      S	:  a  Mw   [        R                  " US
   S5      R                  5       n[        US   5      n	US   n
SU
;   a  SO	SU
;   a  SOSn[        US   R                  SS5      R                  SS5      R                  5       5      n[        US   R                  SS5      R                  SS5      R                  5       5      n[        US	   R                  SS5      R                  SS5      R                  5       5      nUR                  [!        U5      U	UUUUS.5        GM     U$ ! , (       d  f       GN= fs  snf ! ["        [$        4 a     GM  f = f! [&         a    / s $ f = f)uN   Загружает историю предсказаний из md-файла.r   utf-8encodingNr   |z---	Timestamp   rK   r   r      rP   rQ   rR   rT   % z**   )rU   r\   rX   rY   rZ   r[   )r   r   r   r   openreadsplitstrip
startswithr]   r   strptimerU   rh   replaceappendrm   
ValueError
IndexErrorr   )r   r   fcontentr   lineppartsr   r\   
raw_signalrX   rY   rZ   r[   s                  r   _load_historyr   Q  s
   V$D77>>$	#$g.!ffhG / MM$'D::<D??3''5D=K4<O(,

381WWYE85zA~&&uQx1ABLLNeAh"1X
"':"5fPZFZF`i"58#3#3C#<#D#DT2#N#T#T#VW
uQx//R8@@rJPPRSa 0 0b 9 A A$ K Q Q ST!$R"$",$&  # (8 A /. 9* 
+   	sZ   H: HA&H: 5HH: "D"H"H: 
HH: "H72H: 6H77H: :I	I	historyc                     [         R                  " [        SS9  [        X5      n[	        [        U 5      SSS9 nUR                  U5        SSS5        [        S[        U 5       35        g! , (       d  f       N&= f)u2   Сохраняет результат в файл.T)exist_okwr   r   Nu     ✓ Сохранено: )r   makedirsr   r   r   r   writeprint)r   r   r   r   s       r   _save_resultr   }  sa    KK 40	 	1B	'w	?1	 
@	&'8'@&A
BC 
@	?s   A++
A9c                 X   [        X5      nUc  [        SU  SU S35        gSSKnUR                  U5      nSU;   n U(       a  [	        X@U5      nO[        X@U5      nUR                  S5      (       a  [        SUS    35        gU$ ! [         a  n[        S	U 35         SnAgSnAff = f)
u|   Делает предсказание для одного тикера. Возвращает результат или None.Nu&   ✗ Модель не найдена (r   z_experts/directional)r   rD   r      ✗ u%   ✗ Ошибка инференса: )r   r   joblibloadr   r   r_   r   )r   r   
model_pathr   r7   
is_expertsresultes           r   _predict_tickerr     s    !&4J6vha	{J_`aKK
#E  5(J%eY?F)%CF::gD)*+ 5aS9:s   AB B 
B)B$$B)c                    [        S5        [        S5        [        S5        [        S[        R                  " 5       R                  S5       35        [        5         Sn[         H  n[        SU S3SS	S
9  [        X R                  5      (       d  [        S5        M9  S	n[        X R                  5      nUc  MU  [        U5      nUR                  U5        [        U5      S:  a  USS n[        X$5        [        SUS    SUS   S SUS   S SUS   S 35        M     U(       d  [        S5        g[        S5        [        S5        [        S5        S=n=pg[         H4  n[        U5      nU(       d  M  US   S   nXXS:H  -  nXhS:H  -  nXxS:H  -  nM6     [        S U 35        [        S!U 35        [        S"U 35        [        S5        g)#u-   Мониторинг всех тикеров.zF======================================================================uC     MOEX Trading Strategy — Ежечасный мониторингu   Время запуска: z%Y-%m-%d %H:%M:%SFu   Обработка z... T)endflushu-   ✗ Новая свеча не найденаNr9   iu   ✓ rX   z  conf=rY   r   z
  P(long)=rZ   z  P(short)=r[   uU   ✓ Новые свечи не найдены. Мониторинг завершен.zG
======================================================================u+     СВОДКА ПО ВСЕМ ТИКЕРАМr   rJ   rP   rQ   rR   u   
  🟢 BUY: u     🔴 SELL: u     ⚪ NEUTRAL: )r   r   r   r   r   r   r   r   r   r   r]   r   )	argsnew_candles_foundr   r   r   	total_buy
total_selltotal_neutralsigs	            r   monitor_allr     s   	(O	
OP	(O	'(?(?@S(T'U
VW	G#F83/SEfnn55AB  8>  'v w<$efoGV%VH%& '\*3/ 0)#.k&:KC9PR 	S/ 6 ef 
/	
78	(O-..I.
'bk(#E\!	Vm#
	))  
N9+
&'	M*
&'	OM?
+,	/r   c                    U R                   R                  5       n[        XR                  5      (       d  [	        SU S35        g[        XR                  5      nUc  g[	        SUS    35        [	        SUS   S 35        [	        S	US
   S 35        [	        SUS   S 35        [	        SUS   S 35        [        U5      nUR                  U5        [        X5        g)u/   Мониторинг одного тикера.r   u+   : Новая свеча не найденаNu   
  🟡 Signal: rX   u     📊 Confidence: rY   r   u     📈 P(Long): rZ   u     📉 P(Short): r[   u     💰 Close: r\   r   )	r   upperr   r   r   r   r   r   r   )r   r   r   r   s       r   monitor_singler     s    [[ F&..11VHGHIV^^4F~	fX./
01	| 4S9
:;	VH-c2
34	fY/4
56	N6'?3/
01F#GNN6!r   c           	          [        S5        [         H>  n[        XR                  5      n[        SU(       a  SOS SU SU(       a  SOS 35        M@     [        5         g	)
u8   Проверка наличия новых свечей.u;   Проверка наличия новых свечей...
z  u   ✓u   ✗r   z: u   НОВАЯ свечаu   Свечи нетN)r   r   r   r   )r   r   oks      r   check_new_candlesr     sR    	
HIFNN3B5E*!F82QS6MYl5mno  
Gr   c                      [         R                  " S[         R                  SS9n U R                  S[        S SS9  U R                  S[        S/ S	QS
S9  U R                  SSSS9  U $ )NuN   Ежечасный мониторинг торговых сигналов MOEXug  
Примеры:
  python monitor.py                    # Мониторинг всех тикеров
  python monitor.py --ticker SBER       # Мониторинг одного тикера
  python monitor.py --check            # Проверка новых свечей
  python monitor.py --timeframe D1     # Дневной мониторинг
        )descriptionformatter_classepilogz--tickeru(   Тикер для мониторинга)typedefaulthelpz--timeframeH1)r   D1W1u   Таймфрейм)r   r   choicesr   z--check
store_trueu7   Проверка наличия новых свечей)actionr   )argparseArgumentParserRawDescriptionHelpFormatteradd_argumentstr)parsers    r   _build_parserr
    s    $$d <<
F 
dG  I
C 21  3 	,V  XMr   c                      [        5       n U R                  5       nUR                  (       a  [        U5        g UR                  (       a  [        U5        g [        U5        g )N)r
  
parse_argscheckr   r   r   r   )r	  r   s     r   mainr  "  s=    _FDzz$	tDr   __main__)r   )r9   )r   )r   N)=__doc__r  r   systimeglobr   typingr   r   r   pandaspdnumpyr   r   insertdirnameabspath__file__configr   r   data.loaderr	   r0   r
   r/   r   r1   r   features.targetsr   models.expertsr   r   r  r   rm   	DataFramer(   r2   r6   r3   r   r   r^   boolr   r   r   r   r   r   r   r   r   r  r
  r  __name__r   r   r   <module>r#     s    	 
    ' '   277??277??8#<= > ) & 0 8 0 2 )   S S HSM 6  C 2<< 49 YD Y# Y# Y$ Y@* *c *c *d *Z
 
d 
"3 3 $ ,/T$Z / / /lJc Jc J)# )$t* )XD DtDz Dd DC C 8D> <;|".x.. ,	 zF r   