
    4tj/                        S r SSKJr  SSKrSSKrSSKJr  SSK	J
r
  SSKJrJr  SSKJr  SSKJrJr  SS	KJrJr  S
\R,                  S\4S jr  S"S
\R,                  S\S\S\R,                  4S jjrS
\R,                  S\S\R,                  4S jr S#SSSSSSSSSSSS.S\S\S\S\S\S\S\\   S\S\\   S\\   S\S\S \S\\R,                     4S! jjjrg)$u  
Унифицированный пайплайн подготовки DataFrame для обучения/инференса.

Заменяет 8 локальных копий _prepare_df / _prepare_ticker_df,
разбросанных по main.py, models/moe.py, monitor.py, cli/handlers.py,
run_walkforward.py, models/moe_regression.py.

Использование:
    from features.pipeline import prepare_df
    df = prepare_df('SBER', 'H1', with_mtf=True, limit=2000)
    )OptionalN)load_dataframe)engineer_features)add_directional_signalsadd_short_specific_features)add_curated_context)compute_dual_outcomescompute_swing_dual_outcomes)get_target_config
get_marketdfreturnc                 :   ^  SSK Jn  [        U 4S jU 5       5      $ )uN   Проверяет, есть ли в df колонки MTF контекста.r   )MTF_CONTEXT_COLSc              3   @   >#    U  H  oTR                   ;   v   M     g 7f)N)columns).0cr   s     features/pipeline.py	<genexpr>"has_mtf_context.<locals>.<genexpr>   s     9(81BJJ(8s   )features.mtf_contextr   any)r   r   s   ` r   has_mtf_contextr      s    59(8999    Flog_warningsinclude_str_dtypec                 <   SSK nUR                  S5      nU(       a  SS/OS/nU R                  US9R                   H  nUS;  d  M  U(       a{  X   R	                  5       R                  5       n[        R                  " X   SS	9X'   X   R	                  5       R                  5       nX:  a  UR                  U S
X-
   S35        M  M  [        R                  " X   SS	9X'   M     S H  nX`R                  ;  a  M  U(       a{  X   R	                  5       R                  5       nX   R                  [        5      X'   X   R	                  5       R                  5       nX:  a  UR                  U S
X-
   S35        M  M  X   R                  [        5      X'   M     U $ )u  
Конвертирует object-колонки (и опционально 'str' dtype) в числовой тип.

Централизованная версия — заменяет 8 копий конвертации по всему проекту.

Args:
    df: DataFrame с возможными object-колонками.
    log_warnings: Если True — логирует появление NaN после конвертации.
    include_str_dtype: Если True — включает колонки с dtype 'str'
                      (необходимо для Dask/Modin, используется в moe.py).

Returns:
    DataFrame с числовыми колонками.
r   NAI_Strategyobjectstr)include)DateTimecoerce)errors: z NaN values after conversion)OpenHighLowClose)logging	getLoggerselect_dtypesr   isnasumpd
to_numericwarningastypefloat)	r   r   r   r,   loggerdtype_includecoln_nan_beforen_nan_afters	            r   clean_numeric_columnsr;      sn     }-F):Xu%
M6>>&&!w||~113--A glln002-NNcU"[-G,HHd#ef . --A ? 0jj 7<<>--/LgnnU+BG',,.,,.K)#b)C(DD`ab * gnnU+BG 0 Ir   tickerc                 z   [        U5      nUS:w  a  U $  SSKJn  U" U 5      n SU R                  ;   ax  SU R                  ;   ah  SnU S   R                  USS9R                  5       R                  S	5      U S
'   U S   R                  USS9R                  5       R                  S	5      U S'   U $ ! [         a     Nf = f)u  Добавляет crypto-специфичные признаки, если тикер криптовалютный.

Вызывает _add_crypto_features (технические индикаторы) — может быть
вызван как до, так и после compute_dual_outcomes.
Rolling SR добавляется только если outcome_long/outcome_short уже вычислены.

Аналог блоков из monitor.py (crypto features + rolling base rate).
cryptor   )_add_crypto_featuresoutcome_longoutcome_shorti  d   )min_periodsg      ?rolling_long_srrolling_short_sr)r   models.crypto_moer?   ImportErrorr   rollingmeanfillna)r   r<   marketr?   ROLL_WINs        r   _add_crypto_features_if_neededrM   L   s     F	:!"%
 #2::(E "> 2 : :8QT : U Z Z \ c cdg h!#O!4!<!<XSV!<!W!\!\!^!e!efi!jI  s   B- -
B:9B:TrB   )with_mtfwith_short_specificwith_targetswith_crypto_featureslimitmin_rows	shift_mtfwinsor_boundslog_nan_conversionr   reset_index	timeframerN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   c          	          [        XU5      nUb  [        U5      U:  a  g[	        U5      n[        XUS9n[        U5      nU(       a  [        U5      n[        U5      nU(       a  [        U 5      nSSK
JnJn  U" U 5      nSnUR                  5        VVs0 s H  u  nnUU;   d  M  UU_M     nnnU(       a  [        U40 UDS	U0D6nO@S
nUR                  5        VVs0 s H  u  nnUU;   d  M  UU_M     nnn[        U40 UDS	U0D6nU(       a  [!        X5      nU(       a   SSKJn  0 nUb  UUS'   U" X40 UD6nU	b   SSKJn  U" XS9u  nnS Ha  nUUR,                  ;   d  M  UU   R/                  5       R1                  5       (       d  M=  UU   R3                  5       R5                  5       UU'   Mc     UR,                   Vs/ s H  nUS;  d  M  UPM     nnUR7                  US9n[        U5      U:  a  gU(       a  UR9                  SS9nU$ ! [         a  n[        SU  SU SU 35         SnAgSnAff = fs  snnf s  snnf ! [         a  n[        SU 35         SnAGN*SnAff = f! [*         a     GN,f = fs  snf )u  
Загружает и подготавливает DataFrame для одного тикера × timeframe.

Универсальный пайплайн, заменяющий 8 копий по проекту.
Все параметры опциональны и настраиваются под сценарий.

Pipeline:
    1. load_dataframe → сырые свечи
    2. engineer_features → технические индикаторы
    3. clean_numeric_columns → object → numeric
    4. add_directional_signals → directional сигналы
    5. (если with_short_specific) add_short_specific_features
    6. add_curated_context → свечные паттерны, streaks
    7. (если with_targets) compute_dual_outcomes → SL/TP исходы
    8. (если with_crypto_features) crypto-specific фичи (после targets)
    9. (если with_mtf) add_mtf_context → мультитаймфрейм контекст
    10. (если winsor_bounds) winsorize_features
    11. dropna → финальная очистка

Args:
    ticker: Тикер инструмента.
    timeframe: Таймфрейм ('H1', 'D1', 'W1').
    with_mtf: Добавлять MTF контекст (D1+W1). По умолчанию True.
              Параметр shift_mtf передаётся в add_mtf_context если задан.
    with_short_specific: Добавлять short-специфичные признаки.
                         True для MoE/Monitor, False для main.py legacy.
    with_targets: Вычислять outcome_long/outcome_short.
    with_crypto_features: Добавлять crypto-специфичные признаки + rolling SR.
                          True для monitor.py, False для основного MoE.
    limit: Ограничение количества строк.
    min_rows: Минимальное число строк (иначе None). По умолчанию 100.
    shift_mtf: Сдвиг D1/W1 на 1 период назад (защита от lookahead).
               True — тренировка, False — инференс, None — значение по умолчанию.
    winsor_bounds: Границы winsorization из train-фазы.
                   Если переданы — применяет winsorize_features (как monitor.py).
                   Если None — не применяет (winsorization после split'а).
    log_nan_conversion: Логировать появление NaN при конвертации типов
                       (как в monitor.py).
    include_str_dtype: Включать колонки с dtype 'str' в конвертацию.
                       Нужно для moe.py/moe_regression.py (Dask/Modin).
    reset_index: Сбросить индекс DataFrame. Нужен для run_walkforward.py.

Returns:
    DataFrame с признаками или None при ошибке/нехватке данных.
u2       [WARN] Не удалось загрузить _r'   N)r   r   r   )USE_SWING_TARGETSshould_disable_short_training)atr_mult_slatr_mult_tpmax_barsswing_lookbackdisable_short)r]   r^   r_   )add_mtf_contextrT   u6       [WARN] MTF контекст недоступен: )winsorize_features)bounds)sma_200ema_200)subsetT)drop)r   	Exceptionprintlenr   r;   r   r   r   r   configr[   r\   itemsr
   r	   rM   r   rb   data.cleanerrc   rG   r   r/   r   bfillffilldropnarW   ) r<   rX   rN   rO   rP   rQ   rR   rS   rT   rU   rV   r   rW   r   e
target_cfgr[   r\   ra   target_only_keyskvtarget_kwargsatr_only_keysatr_only_cfgrb   kwargsrc   rZ   _colr   	core_colss                                    r   
prepare_dfr}   h   s   zFu5
 
zSWx' 
2	B 
r1B
DB 
!	$B(,	R	 B
 &v.
K5f= X*4*:*:*<V*<$!QEU@UA*<V,R^=^P]^B GM-:-@-@-BY-BTQa=FXDAqD-BLY&rW\WWB +B7 	P<F$&/{# 6v6B
  	7&r@EB '2::"T(--/"5"5"7"7$x~~'--/BtH ' JJJJq!3I*IJIJ	)	$B
2w^^^&I]  B6(!I;VXYZX[\]< W Z  	PJ1#NOO	P  		 Kse   H H;&H;I.I"I ?I- 
I>I>
H8H33H8
I*I%%I*-
I;:I;)FF)H1)__doc__typingr   pandasr1   numpynpdata.loaderr   features.technicalr   features.directionalr   r   features.contextr   features.targetsr	   r
   rl   r   r   	DataFrameboolr   r;   r!   rM   intdictr}    r   r   <module>r      su  
    & 0 U 0 O 0: : : BG49*bll *$ *-1*>@ll*Zr|| S R\\ < M  $!& $$($#MMM 	M
 M M M C=M M ~M D>M M M M bllMr   