
    [jn                        S r SSKrSSKrSSKJr  SSKrSSKrSSK	J
r
  \" \5      R                  5       R                  R                  r\S-  S-  S-  r\S-  S-  S-  rSS	S
S.rS\R$                  S\R$                  4S jrS\R$                  S\R$                  S\S\R$                  4S jrS\R$                  S\R$                  S\S\R$                  4S jrS\R$                  S\R$                  S\4S jrS\4S jr SS\R$                  S\R$                  S\R$                  S\S\S\\\\4   4S jjrS\4S jr\S:X  a  \R<                  " \" 5       5        gg)u:  
Blend modello Dixon-Coles + mercato: il primo vero test di valore aggiunto.

Domanda: combinare le probabilità del modello con quelle del mercato produce
un log loss migliore del mercato da solo? Se sì, il modello contiene
informazione che il mercato non ha già incorporato.

Protocollo (senza look-ahead):
  - il peso del blend si impara sulla stagione di TRAIN (default 2024/25)
  - la valutazione avviene solo sulla stagione di TEST (default 2025/26)
  - bootstrap a coppie (1000 ricampionamenti) per la significatività

Due metodi di blend, il migliore viene scelto in base al TRAIN:
  - lineare:    p = w * modello + (1-w) * mercato
  - geometrico: p ∝ modello^w * mercato^(1-w)   (pooling in log-spazio)

Uso:
    python scripts/blend.py
    python scripts/blend.py --train-seasons 2024/25 --test-seasons 2025/26
    N)Path)minimize_scalardata	processedzbacktest_base.csvzbacktest_blend.csv      )HDApreturnc                 V    [         R                  " U SS5      n X R                  SSS9-  $ )N-q=r   T)axiskeepdims)npclipsum)r   s    (C:\wamp64\www\Tigertips\scripts\blend.py	normalizer   %   s*    
5!Auu!du+++    p_modelp_mktwc                 .    [        X -  SU-
  U-  -   5      $ )Nr   )r   r   r   r   s      r   linear_blendr   *   s    Q[AEU?233r   c                     [        [        R                  " U[        R                  " [        R                  " U SS5      5      -  SU-
  [        R                  " [        R                  " USS5      5      -  -   5      5      $ )Nr   r   )r   r   explogr   r   s      r   geometric_blendr!   .   sb    RVVArwwwq'A BB 1urwwueQ/G(HHI J K Kr   outcomec                     [        U 5      n [        [        R                  " [        R                  " U [        R
                  " [        U5      5      U4   5      5      * 5      $ N)r   floatr   meanr    arangelen)r   r"   s     r   loglossr)   3   sB    !A"''"&&299S\#:G#C!DEFFGGr   c                 X   ^ ^^^ [        U UUU4S jSSS9n[        UR                  5      $ )Nc                 ,   > [        T" TTU 5      T5      $ r$   )r)   )r   blend_fnr"   r   r   s    r   <lambda>fit_weight.<locals>.<lambda>9   s    GHWeQ,G$Qr   )g        g      ?bounded)boundsmethod)r   r%   x)r,   r   r   r"   ress   ```` r   
fit_weightr4   8   s#    
Q!+I?C<r   p_ap_bn_bootseedc                    [         R                  R                  U5      n[        U5      n[         R                  " [        U 5      [         R                  " U5      U4   5      * n[         R                  " [        U5      [         R                  " U5      U4   5      * nXx-
  n	[         R                  " [        U5       V
s/ s H%  oUR                  SXf5         R                  5       PM'     sn
5      n[        U	R                  5       5      [        [         R                  " US5      5      [        [         R                  " US5      5      4$ s  sn
f )zu
Differenza di log loss (A - B) con intervallo di confidenza al 95%
tramite bootstrap a coppie sulle stesse partite.
r   g?g333333?)r   randomdefault_rngr(   r    r   r'   arrayrangeintegersr&   r%   quantile)r5   r6   r"   r7   r8   rngnll_all_bdiff_bootss               r   bootstrap_diffrG   >   s     ))


%CGAFF9S>"))A,"7899DFF9S>"))A,"7899D;DHH%-P-Q3<<101668-PQEuR[[%>?r{{SXZ_G`Aaaa Qs   >,E	c                    ^ [         R                  " SS9n U R                  SSS/S9  U R                  SSS/S9  U R                  S	[        [        5      S
S9  U R                  5       n[        UR                  5      nUR                  5       (       d  [        SU S35        g[        R                  " U5      R                  / SQS9nX3S   R                  UR                  5         nX3S   R                  UR                  5         nUR                   (       d  UR                   (       a  [        S5        gS nU" U5      u  pxn	U" U5      u  pn[        S[#        U5       SUR                   S[#        U5       SUR                   35        0 mS[$        4S[&        44 HF  u  p[)        XX5      nX[+        U" XxU5      U	5      4TU'   [        SU SUS STU   S   S S35        MH     [-        TU4S  jS!9nTU   u  nnn[        S"U 35        U" XU5      n[        S#UR                   S$[#        U5       S%35        [        S&S' S(S) 35        [        S*S' [+        X5      S+ 35        [        S,S' [+        X5      S+ 35        [        S-U-   S' [+        UU5      S+ 35        [/        UX5      u  nnnUS.:  a  S/O	US.:  a  S0OS1n[        S2US3 S4US3 S5US3 S635        [        S7U 35        [        S85        UR1                  5       nUU/ S9Q'   UR3                  S:5       H  u  nnUS;   R5                  [6        5      R9                  5       n[+        U/ S9Q   R9                  5       U5      n[+        U/ SQ   R9                  5       U5      n[        S<US= S>US S?US S@UU-
  S3 35        M     UR;                  [<        SASB9  [        SC[<         35        g.)DNz&Blend modello+mercato con pesi appresi)descriptionz--train-seasons+z2024/25)nargsdefaultz--test-seasonsz2025/26z--inputz8CSV di backtest da valutare (default: backtest_base.csv))rL   helpzManca z": esegui prima scripts/backtest.pyr   mkt_hmkt_dmkt_a)subsetseasonz2Stagioni di train o test non trovate nel backtest.c                     U / SQ   R                  5       U / SQ   R                  5       U S   R                  [        5      R                  5       4$ )N)model_hmodel_dmodel_arN   result)to_numpymapRESULT_INDEX)dfs    r   unpackmain.<locals>.unpacka   sK    45>>@./88:8  .779; 	;r   zTrain: z	 partite z	 | Test: lineare
geometricoz  blend z: peso modello w = z.3fz (log loss train r   z.4f)c                    > TU    S   $ )Nr    )kmethodss    r   r-   main.<locals>.<lambda>r   s    71:a=r   )keyz  scelto (dal train): z

=== Test z (z partite) === z<22zlog lossz>10zMercato (closing)z>10.4fz
Modello DCzBlend r   zil blend BATTE il mercatozil mercato batte il blendz8differenza NON significativa (compatibile con il rumore)z!
Delta log loss blend - mercato: z+.4fz
 [IC 95%: z, ]z
Verdetto: z
Per lega (test):)blend_hblend_dblend_aleaguerX   z  z<5z blend z   mercato z   gap F)indexz
Predizioni blend salvate in: )argparseArgumentParseradd_argumentstrBT_PATH
parse_argsr   inputexistsprintpdread_csvdropnaisintrain_seasonstest_seasonsemptyr(   r   r!   r4   r)   minrG   copygroupbyrZ   r[   rY   to_csvOUT_PATH)parserargsin_pathbttraintestr]   pm_trpk_try_trpm_tepk_tey_tenamefnr   	best_namebest_fnbest_wrE   p_blend	mean_difflohiverdictlggrpyrC   ll_kre   s                                 @r   mainr   M   s   $$1YZF
)ykJ
(i[I
	3w<W  YD4::G>>wiABC	W		$	$,G	$	HB(|  !3!345El 1 123D{{djjBC;
  E$E$	GCJ<y););(< =t9+Yt'8'8&9; < G.0OPr%.5(;T BC1!C 9!!(q!1# 6a9 	: Q
 G!89I +GVQ	"9+
./ eF+G	K))*"SYK}
EF	RHZ$
%&	 %ge&:6%B
CD	\#wu3F;
<=	X	!#&ww'=f&E
FG&w<Ir2-/!V)')Av#B  
.y.> ?YbD	, -	Jwi
 !	
99;D.5D	*+<<)CMl+446s<=FFH!Ls67@@BAF2b'c
+d3Zwtd{SWFXYZ	 * 	KKK&	+H:
67r   __main__)i  *   )__doc__ro   syspathlibr   numpyr   pandasrx   scipy.optimizer   __file__resolveparentPROJECT_ROOTrs   r   r[   ndarrayr   r%   r   r!   r)   r4   inttuplerG   r   __name__exitrc   r   r   <module>r      s  *  
    *H~%%'..55

+
-0C
C& ;.1EEQQ', ,

 ,
4"** 4RZZ 4E 4bjj 4KRZZ K

 Ku K K
Hrzz HBJJ H5 H
U  46b

 b bbjj bb-0b:?ue@S:TbDc DN zHHTV r   