-iHdZddlmZmZmZddlmZddlmZGddZy)z_ Warren Buffett Style Stock Analyzer Deterministic fundamental analysis without LLM dependency )DictOptionalAny)datetime)loggerc &eZdZdZgdZgdZgdZgdZeezZdZ dZ dZ dZ d Z d Zd Zd Zd ZdZdZdZdZd ZdZdZdZdZdZdedefdZdedeeeffdZ dede!e"de!e"dede#f dZ$dedede%fdZ&dedede%fd Z'dedede%fd!Z(dedede%fd"Z)dededede*fd#Z+dedeeeffd$Z,d8d%e*d&e#fd'Z-dede!e"fd(Z.dedede!e"fd)Z/dede!e#fd*Z0d+e!e"d,e!e"d-e!e#de"fd.Z1d/e"d0e"de"fd1Z2d2e#d3e"defd4Z3ded2e#d0e"d3e"d5edef d6Z4y7)9WarrenAnalyzerz Analyzes stocks using Warren Buffett-style value investing principles. Uses deterministic formulas instead of LLM for fast, reliable, and cost-free analysis. ) zISP.MIzUCG.MIzBAMI.MIzBPE.MIzBMPS.MIzFBK.MIzMB.MIPST.MIzUNI.MIzG.MIzAZM.MI)A2A.MIENEL.MIIG.MISRG.MITRN.MIzERG.MI)RACE.MIzSTLAM.MIzIVG.MIzPIRC.MI)zPRY.MIzTEN.MIzIP.MIzBZU.MIzLDO.MI皙ɿg$@g{Gz?g4@ zCRITICAL DANGERzDATA INSUFFICIENT(P.@<FWATCHcy)zInitialize the Warren AnalyzerN)selfs src/analysis/warren_analyzer.py__init__zWarrenAnalyzer.__init__>s stock_datareturnc  |jdd}|jdd}|jd}|jd}|jd}|jd}|jd}tj|d |j|} |j ||} |j |} tj|d | d | d | d } ||r||z } d } | |r |dk7r||z } |j ||}| }|j}|r|jd}||}d}|||ks|  | |jkDr|jddk(rt|jd|jd|j|jt|jdddt|jddddd| | | d S|jd|jd|j|jt|jdddt|jddddd| | | d Sd}|jd|jvr||||fD] }||dz } nO|jd|jd|jd|jdfD] }||dz } |dkDrt|jd|jd|j|jt|jdddt|jddddd| | | d S|j|||}|rtj |ddj#||jd|jd|j|jt|jdddt|jddddd dj#|| | | d S|j%|}|d!}|d"}|d#}|d$}|d%}|jdd}|j'||}|j)|}|d&}|d'}|d%} |j+| | | }!||!z}"t-d(t/|"d)z d(z}#|j1|#|}$|j3||#|||$}%id|jdd|jdd&|#d*|$d!t|dd+t|dd,t|dd-|%d.| d/| d0| d1|d2| d3|d4|d5|d6|S)7a Analyze a stock and return Warren Buffett-style recommendation Args: stock_data: Dictionary containing: - ticker: Stock symbol - name: Company name - sector: Industry sector - price: Current price - pe_ratio: P/E ratio - pb_ratio: P/B ratio - roe: Return on Equity (as decimal, e.g., 0.15 = 15%) - debt_to_equity: Debt to Equity ratio - dividend_yield: Dividend yield (as decimal) - revenue_growth: Revenue growth rate (as decimal) - earnings_growth: Earnings growth rate (as decimal) - market_cap: Market capitalization Returns: Dictionary with: - ticker: Stock symbol - name: Company name - score: Quality score (0-100) - valutazione: BUY/HOLD/AVOID/CRITICAL DANGER/DATA INSUFFICIENT - fair_value: Estimated fair value per share - current_price: Current market price - margin_of_safety: % discount/premium - ragionamento: Explanation text tickersector free_cashflow market_capenterprise_valueebitdanet_debtz3: Calculating Schema v4 advanced quality metrics...z: Advanced metrics - ROIC: z, Interest Coverage: z , F-Score: Nravg_fcf_yield_3ygr namepriceu{PST.MI: Criticità FCF/Debito non standard per settore finanziario/ibrido. Classificazione declassata a Dati Insufficienti.) r$r-score valutazione fair_value current_pricemargin_of_safety ragionamentoroicinterest_coveragepiotroski_fscorez7Dati critici: FCF yield o Net Debt/EBITDA fuori soglia.pe_ratiopb_ratioroez~Dati incompleti: per questo settore mancano metriche fondamentali necessarie (non richiesti FCF/EBITDA per financial/utility).z: CIO Quality Fail - z, zCIO Quality Fail: r3methodsmethod_weights adjustments parametersr1 breakdowndr2r4r5r6r7r8r9score_breakdownscore_parametersfair_value_methodsfair_value_method_weightsfair_value_adjustmentsfair_value_parameters)getrdebugcalculate_roiccalculate_interest_coveragecalculate_piotroski_fscore_is_auto_industrialHARD_FAIL_FCF_YIELD_THRESHOLD#HARD_FAIL_NET_DEBT_EBITDA_THRESHOLDSCORE_DATA_INSUFFICIENTRATING_DATA_INSUFFICIENTroundSCORE_CRITICAL_DANGERRATING_CRITICAL_DANGERSPECIAL_TREATMENT_TICKERS_check_cio_gatekeeperwarningjoincalculate_fair_value_calculate_margin_of_safetycalculate_score calculate_advanced_quality_scoreminint_get_recommendation_generate_reasoning)&rr!r$r&fcfr(evr*r+r7r8r9 fcf_yieldnet_debt_ebitdais_auto_industrialfcf_yield_to_checkhard_fail_fcf_threshold avg_fcf_yieldmissing_advancedv cio_failuresfair_value_resultr3rGrHrIrJr4r5 score_result base_scorerErFadvanced_quality raw_score final_scorer2r6s& ranalyzezWarrenAnalyzer.analyzeBsj>"-"-nn_-^^L1 ^^. /)>>*-  xRST""6* <M(%2"&+ #  */AD[/[  'Od>f>f,f~~h'83(nnX6&NN62!99#'#@#@"' w(BA"F%*:>>'1+Eq%I(+%b ):(8  %..2"v.33#::#JNN7A$>B!&z~~gq'A1!E$' Y%6$4    >>( #4+I+I I2vx0 *9$)$ * !nnZ0*..2Ljnn]bNceoesesuAfBC *9$)$ * a $..2"v.55#<<#JNN7A$>B!&z~~gq'A1!E$'!a%6$4   11*ffM  NNfX%:499\;R:ST U$..2"v.33#::#JNN7A$>B!&z~~gq'A1!E$'"4TYY|5L4M N%6$4  "!55jA&|4 .y9$56F$G!!2=!A 1, ?"w2 ;;M:V++J7 !'* &{3' 5 @@GXZjk!11 #sIOs#:;< ..{<|%| d><d=|d><| r| r| dkDr{| dkDrv| | z }&|r |jn |j}'||'|&z z}(t|(|d?z}(t |(|d@z}(|j|(|jdA|(|dB<|(| dB<dA|dB<|ri|dkDrd|dCkr|n|dz })dD}*dE|)cxkrdAkrKnnH||*|)z z}+t|+|d,z}+|j|+|jdF|+|dG<|+| dG<dF|dG<|r+t|},tdHt||D|,z }-n|}-|d=z}.t |.|-}-|-}/|/|dI<|rf|jdJ}0|jd}1dK}2|0 |0dLkr|2dFz }2|1r|1dCkr|1n|1dz })|)dFkDr|2dFz }2|2dkDrt|2dM}3|-dC|3zz}-|3|dN<|-dkDr||dznd} d8}48r8jnd 9|j!|8xst 9fdOdPD}| |s| dQkDr|4d:z }4n | dRkDr|4dMz }4| |dkr|4dMz }4| "|s |st 9fdSdTDr | d+kDr|4dAz }4t|4dU}4|4d8z }5|-|4z}-|5|dV<tj|dW|| ||||4dXYdK}6|j#dZrd=}6tj|d[n<|j#d\s|j#d]rdM}6tj|d^|-dC|6z z}-|6|d_<tj|d`|||t%|/da|6t%|-dadbYt dc|-}7|7| |||ddS)ea8 Calculate fair value using multiple valuation methods (Schema v2) Uses a weighted average of: 1. P/E based valuation (35%) 2. P/B based valuation (25%) 3. FCF Yield valuation (20%) [NEW - Schema v2] 4. EV/EBITDA valuation (15%) [NEW - Schema v2] 5. Dividend discount model (5%) Weights auto-normalize when data is missing. Special handling for luxury/growth stocks (Ferrari, Moncler, etc.) Returns Dict with fair_value, methods breakdown, adjustments, and parameters (v4.1) r.rr;r<r=earnings_growthdividend_yieldr&r%r$r(r'r)r*)pepbrf ev_ebitdadividend)base_fair_value utility_bonusquality_premiumcountry_penaltyF)growth_rate_originalgrowth_rate_usedis_growth_cappedgraham_multiplier is_luxury is_utility is_financialis_mature_sectorrrr+Nrz: Negative earnings growth (z.1%z#). Using conservative P/E approach.rCrrTr)financial services utilitiesenergybanksc3BK|]}|jvywN)lower.0keywordr&s r z6WarrenAnalyzer.calculate_fair_value..psXg6<<> 9Xsr@z: Mature sector (z) - growth capped at 4%@c3&K|]}|v ywrrrksector_ls rrz6WarrenAnalyzer.calculate_fair_value..swqH}w)rr insurancezasset managementrr@rz9: Financial sector - using defensive 15.0x P/E multiplierg6@r?r@gffffff?ry@r? ?rz333333?g?rf@g?333333?r{r:gQ?g{Gzt?g?r|c3,K|] \}}||zywrr)rrmws rrz6WarrenAnalyzer.calculate_fair_value..sHtq!QUHsr}betar0皙?g?r~c3&K|]}|v ywrr)rkwrs rrz6WarrenAnalyzer.calculate_fair_value..!sL#%hLr) financialbankrassetc3&K|]}|v ywrrrs rrz6WarrenAnalyzer.calculate_fair_value..2s$gqQ(]$gr)luxuryleisureconsumer cyclicalg?rz: Quality premium applied)r$roe_pctr+rr multiplier)extra.MIz4: Italian stock - applying -20% country risk penalty.PA.DEz:: French/German stock - applying -10% country risk penaltyrz: fair value components)r$ componentsweightsr}rfinal_fair_valueg{Gz?)r3r>r?r@rA)rK_is_luxury_brand_is_utility_sectorrrZmaxanyr`rLrappendTARGET_FCF_YIELDTARGET_EV_EBITDA_LUXURYTARGET_EV_EBITDAsumzip_is_financial_sectorendswithrU):rr!r.ryrzr=rwrxr$r(r'r)r*r>r?r@rA valuationsrrr net_debt_valroe_valr growth_ratermature_sectors is_maturegrowth_rate_cappedrfair_pe pe_fair_valuerfair_pb pb_fair_valuerftarget_fcf_yieldfcf_fair_valueev_ebitda_ratiotarget_ev_ebitda ev_fair_valuenormalized_div_yield target_yielddiv_fair_value total_weightr3min_fair_valuer}rdividend_yield_valbonus bonus_cappedrrrrr&rs: @@rr\z#WarrenAnalyzer.calculate_fair_values w* ^^J ' ^^J 'nnU#$..):;#(89"-"- ^^L1 "7 %>>*<=)     !   %& ! %!"! %   ))&&9 ,,VV< "+ ;#- < !~~j1 ..' "q&_8%h:?3:OP78 5Ds5J 1212 -.15 -.'6'<$!!%9: 5I 12"X\bCXXXhm 1: -.),[#)>&6AEW6WJ12"4KLLF8+&6AEW6WJ12"4K1< -. *0v||~RHw6vwwL)5J~ &b"s['8"89 x'`abdB{):$:;.5J* +!Wr\2M us{;M   m , NN4 ,Jt )GDM#'N4  "q&SS1WCiGc3sGaK#89c3sGbL#9:!Wr\2M us{;M   m , NN4 ,Jt )GDM#'N4  ZJN% 2I 1}#'#8#8 "')6F*F!G"%^US[!A!$^US[!A!!.1t$*8 ;''5 $.2{+ 6A::JQ:N.7O@It;;dNcNc "%5%GHM us{;M us{;M   m , NN4 &3J{ ##0GK *.N; ' nq05Ca5G>^^aMa  L+2d2!&,9M*M!N"%^US[!A!!.1t$)7 :&&4 #-1z* w>&)D!+0@!A ED3J !=ORS=S'9YknqYq$'$.TMEqy"5$/ q</0 /; O, >'.':gmGJ*0v||~RH44VVDL)TLIL "<R<$&Jr\$&J'L1,<d" "<$g.wslQ1=lr) automotiveautorrrrg @rrY@rr)rAUTOMOTIVE_TICKERSr) rr$rrgr&penalty is_auto_finde_ratiors @r_debt_penalty_sector_awarez)WarrenAnalyzer._debt_penalty_sector_awarels%+6<<> d-- - ml*kll  *"S(rMG%s*qLG&2=2B;. c>rMG*/D2 r cHddg}ddg}||vxstfd|DS)z Detect if stock is a luxury/brand-premium company These stocks trade at premium multiples due to: - Strong brand moat - Pricing power - Scarcity/exclusivity rzMONC.MILuxuryzConsumer Cyclicalc3&K|]}|v ywrrrs rrz2WarrenAnalyzer._is_luxury_brand..s.`Ww&/@.`rr)rr$r&luxury_tickersluxury_keywordss ` rrzWarrenAnalyzer._is_luxury_brands8$Y/$%89'`3.`P_.`+``r c|r|jndgd}||jvxs$||jvxstfd|DS)zCDetect automotive/industrial sectors where FCF can be volatile YoY.r%)r industrial construction machineryz capital goodsc3&K|]}|v ywrrrs rrz5WarrenAnalyzer._is_auto_industrial..s3Q1=3r)rrINDUSTRIAL_TICKERSr)rr$r&keywordsrs @rrPz"WarrenAnalyzer._is_auto_industrialsP%+6<<>] d-- - 4000 43(33 r cX|j}gd}||vxstfd|DS)ac Detect if stock is in BANKING/INSURANCE sector (NOT asset management) These stocks need special metrics: - D/E is meaningless (deposits/reserves counted as debt) - Use P/B ratio instead - Different valuation multiples NOTE: Excludes asset management firms (like Azimut) which operate differently )Banks InsurancezDiversified BankszRegional Banksc3&K|]}|v ywrrrs rrz6WarrenAnalyzer._is_financial_sector..s1f'V2C1fr)FINANCIALS_TICKERSr)rr$r&financial_tickersfinancial_keywordss ` rrz#WarrenAnalyzer._is_financial_sectors8!33 **fc1fSe1f.ffr cHgd}gd}||vxstfd|DS)ui Detect if stock is a utility company (Schema v2) Utilities have special characteristics: - High infrastructure costs → high debt is normal - Stable cashflows → dividends should be covered by FCF - Regulated pricing → lower growth but predictable Uses hybrid detection (hardcoded list + keywords) )r rrzHER.MIr r ) UtilitiesEnergyz Oil & GasElectricGasc3&K|]}|v ywrrrs rrz4WarrenAnalyzer._is_utility_sector..s/bg60A/brr)rr$r&utility_tickersutility_keywordss ` rrz!WarrenAnalyzer._is_utility_sectors0  (bC/bQa/b,bbr cg}|jd}|jd}||dkDr|||kr|jd|jd}||dkr|jd|jd}|c|dkDr|d z n|} ||jvr |S||jvr| d kDr|jd | d d |S| dkDr|jd | d d|S)a CIO Quality Trio: Gatekeeper to avoid value traps. Returns list of failure reasons (empty = pass all checks). Three quality checks using snapshot data (Schema v2): 1. Cash King: OCF should support earnings (OCF >= Net Income) 2. Margin Check: Operating margin must be positive 3. Solvency Check: D/E within sector-appropriate thresholds net_incomeoperating_cashflowrz$Cash Flow Quality (OCF < Net Income)operating_marginzNegative Operating Margindebt_to_equityrrrzHigh Debt/Equity (.2fz > 2.5)rz > 1.5))rKrrUTILITY_TICKERS) rr!r$r&failuresr  operating_cfrrrs rrYz$WarrenAnalyzer._check_cio_gatekeepers ^^L1 !~~&:;  !j1n9Qj( FG&>>*<=  ',OO&8#g$NO c>OO&8#g$NOr c dddddddddddddddddddddddddddddd}ddd dd d d d d }d}|jd }|jd }|jd d}|rK|dkr|dz }d|dd<n8|dkr|dz }d|dd<n%|dkr|dz }d|dd<n|dkr |dz }d|dd<|rK|dkr|dz }d|dd<n8|dkr|dz }d|dd<n%|dkr|dz }d|dd<n|dkr |dz }d|dd<|rI|dkr|n|dz }|dz} | dkDr|d z }d |dd!<n%| dkDr|dz }d|dd!<n| dkDr |dz }d|dd!<|jd"} |jd#} |jd }|jd$d%} |jd&d%} | | dz}|d(kDr|dz }d|d)d"<n||dkDr|d(z }d(|d)d"<ni|dkDr|dz }d|d)d"<nV|d kDr|dz }d|d)d"<nC|dkDr|d*z }d*|d)d"<n0|d+kDr|d z}d+|d)d"<d |d,d-<n|dz}d.|d)d"<d|d,d-<|j| | xs| |jv}||d/<|rN||d0kr|dz }d|d)d1<n|d2kr|dz }d|d)d1<n|dkr|dz }d|d)d1<n|d3kr|dz }d|d)d1<nt| r| dkDr| d4z n| }|d5kr|dz }d|d)d1<nS|d6kr|dz }d|d)d1<n@|d7kr|dz }d|d)d1<n-|d3kr|dz }d|d)d1<n|d8kDr|d z}d+|d)d1<d |d,d9<|jd:}|jd;}|c|dz}|dkDr|dz }d|d<d=<nK|dkDr|dz }d|d<d=<n8|d kDr|d>z }d>|d<d=<n%|dkDr|d z }d |d<d=<n|d+kDr |dz }d|d<d=<|c|dz}|dkDr|dz }d|d<d?<nK|dkDr|dz }d|d<d?<n8|d kDr|d>z }d>|d<d?<n%|dkDr|d z }d |d<d?<n|d+kDr |dz }d|d<d?<|j| | }||d@<|jdA}|jdB}|A|?|dz}|dz}d}|dCkDr|dkDrd}n|dDkDr|dkDrd}n |d(kDr|d kDrd}||z }||dEdF<|jdG}|jdH}d'}|||dkDr||z }|rI|d3kr|d z }d |dEdI<n~|dJkr|d*z }d*|dEdI<nk|dKkDrf|dz}dL|dEdI<|d,d9xxdz cc<nH|d7kr|d z }d |dEdI<n5|d3kr|d*z }d*|dEdI<n"|dJkDr|dz}dL|dEdI<|d,d9xxdz cc<|j | | || }||z}|dkDr|d,d9xx|z cc<|r|jdM}|jdN} |jdO}!|r]| r[|!rY| |!z}"|dkDr|"|z nd}#|#dPkr|d z }d |dEdQ<n5|#dRkr|dz }d|dEdQ<n"|#d2kDr|dz}dL|dEdQ<|d,d9xxdz cc<d}$|jdS}%|%*|%dkDr%|%d7kr|$d z }$d |dEdT<n|%dkr |$d*z }$d*|dEdT<|jdU}&|&*|&dkDr%|&dVkr|$d z }$d |dEdW<n|&dXkr |$d*z }$d*|dEdW<||$z }t |dd|dd|dd!g|ddY<t |d)d"|d)d1g|d)dY<t |d<d=|d<d?g|d<dY<t |dEdF|dEdI|dEdQ|dEdT|dEdWg|dEdY<t |d,d-|d,d9g|d,dY<t dtd|}'|'||dZS)[ad Calculate Warren Buffett quality score (0-100) Breakdown: - Valuation (30 points): P/E, P/B, Dividend yield - Quality (40 points): ROE, Debt/Equity - Growth (30 points): Revenue growth, Earnings growth Returns: Dict with final_score, raw_score, breakdown, and parameters (Schema v4.1) r)totalryrzr|)rr=debt)rrevenueearnings)rmargins debt_coverage fcf_payoutpegr{)r roe_negative debt_excess)rr7r8 piotroski) valuationqualitygrowthbonuses penaltiesrrF)rrrrrrrrhr;r<rxrrr ryr#rrrrzrr/r:rCrr|r=rr&r%r$Nrr!r$rirrrg333333?rrrg333333?rrrrevenue_growthrwr"r rr gross_marginrrrr#rr+r*rrrir' dividend_rateshares_outstandinggffffff?r? peg_ratior ev_to_ebitdag @r{g(@r)r1rBrA)rKrrrrrrr`)(rr!rBrAr1ryrz div_yieldnormalized_divdiv_pctr=rr&r$rrrr,rwrev_pctearn_pctrr.r gross_pct operating_pct margin_bonusr+r*net_debt_ebitda_ratio debt_penaltyr'r/r0total_dividendspayout_ratio_fcf bonus_forwardr2r3rts( rr^zWarrenAnalyzer.calculate_score s $%AQAF!"1a8 !aQ?!"q1TU^_nop#$aJ*+QQ]^ _  %& ! %!"!"'  ^^J ' ^^J 'NN#3Q7  Bw /1 +&t,b /1 +&t,b /0 +&t,b /0 +&t, Cx /1 +&t,c /0 +&t,a /0 +&t,a /0 +&t, *3a-YY_N$s*G{ 56 +&z23 56 +&z21 56 +&z2nnU##(89 ^^J '"-"- ?CiG| .0 )$U+2 .0 )$U+2 .0 )$U+1 ./ )$U+1 ./ )$U+2 .0 )$U+9: +&~6 .1 )$U+9; +&~6 00@bFdNbNbDb %1 >" ~8RKE35Ii(0#XRKE35Ii(0#XQJE34Ii(0#XQJE34Ii(0)6Db5H>E1nc>RKE35Ii(0^RKE35Ii(0^QJE34Ii(0^QJE34Ii(0^QJE35Ii(0<=Ik*=9$(89$..):;  %$s*G| 13 (#I.2 13 (#I.1 12 (#I.1 12 (#I.2 12 (#I.  &&,H"} 24 (#J/B 24 (#J/A 23 (#J/A 23 (#J/B 23 (#J/ ,,VV< #- < "~~n5 %>>*<=  #(8(D$s*I,s2ML2~-""4! RMB$6 RMA$5 \ !E.:Ii  +>>*-) $  F$66A:$,v$5 !(3.QJE<=Ii(9*S0QJE<=Ii(9*S0RKE 2 k "= 1/ + +w' !Se_- !"$  r field_names period_indexc,|$|jst|j|kry|D]}|jj ddj ddj dd}|j D]}t |jj ddj ddj dd}||vs||vsU |j||j|f}|t|tr||k7s|ccSy#YxYw)aT Safely extract field from yfinance DataFrame with fuzzy name matching Args: df: DataFrame (balance_sheet, financials, cashflow) field_names: List of possible field names period_index: Column index (0 = most recent) Returns: Field value or None if not found N r%_-) emptylencolumnsrreplaceindexstrloc isinstancefloat) rdfrArBr-name_normalizedidxidx_normalizedvalues r_safe_get_fieldzWarrenAnalyzer._safe_get_fieldxs :S_ %D !D"jjl223;CCCLTTUXZ\]Oxx !!$S!1!9!9#r!B!J!J3PR!S![![\_ac!d"n4/8Y! "sBJJ|,D'D E ,j6NTY]bTb#(L  ! !! s 6DDc ddl}|j|}|j}|j}|js |jrt j |dy|j|gd}|t j |d|j|gd}|j|gd}|j|gd} |=|}||t|z }| |t| z }t j |d |nt j |d y|j|gd} |j|gd}| rI|rG|t| zdk7r6t| |t| zz } t j |d | d n2d |vrd} nd|vrd} n d|vrd} nd} t j |d| d |d| z z} t j |d| |j|ddg} |j|gd} |j|gd}d}| (| &| | z }|r||z}t j |d|||dkrt j |d|j|gd}|j|gd}|+|)t||z}t j |d|n||}t j |d |||dkrt j |d!y| |z d"z}t|d#kDrt j|d$|d%yt j |d&|d'd(t|d)S#t$r$}t j |d*|Yd}~yd}~wwxYw)+u6 Calculate ROIC = NOPAT / Invested Capital NOPAT = EBIT × (1 - Tax Rate) Invested Capital = Total Assets - Current Liabilities - Cash OR Debt + Equity (fallback) Returns: ROIC as percentage (e.g., 15.5) or None if not calculable rNz0: ROIC - Empty balance sheet or income statementEBITzOperating IncomeOperatingIncomez"Total Operating Income As ReportedzNormalized EBITDAz<: ROIC - Primary EBIT not found, trying fallback calculation) Net Income NetIncomezNet Income Common Stockholders)Interest ExpenseInterestExpenseNet Interest Income)z Tax Provision TaxProvisionzIncome Tax Expensez': ROIC - Calculated EBIT via fallback: z.: ROIC - Cannot calculate EBIT (no Net Income)z.: ROIC - Calculated tax rate from financials: z.2%rgQ?rrrrgzG?z0: ROIC - Using country-aware fallback tax rate: r:z: ROIC - NOPAT: Total Assets TotalAssets)Current LiabilitiesCurrentLiabilitieszTotal Current Liabilities)zCash And Cash EquivalentsCashz0Cash Cash Equivalents And Short Term InvestmentsCashAndCashEquivalentsz,: ROIC - Invested Capital (primary method): zI: ROIC - Primary Invested Capital failed, trying fallback (Debt + Equity))z Total Debt TotalDebtLong Term DebtzNet DebtzShort Long Term Debt Total)zStockholders EquityStockholdersEquityz$Total Equity Gross Minority InterestzCommon Stock Equityz2: ROIC - Invested Capital (fallback Debt+Equity): z9: ROIC - Invested Capital (ultra-fallback, Equity only): z?: ROIC - Cannot calculate Invested Capital (all methods failed)rCiz0: ROIC calculation resulted in anomalous value: z% - returning Nonez: ROIC - Final ROIC: r%r/z: Error calculating ROIC: ) yfinanceTicker balance_sheet financialsrGrrLrUabsrZrU Exception)rr$yf ticker_objrl income_stmtebitr  interest_exptax_provtax_ratenopat total_assets current_liabcashinvested_capital total_debtstockholders_equityr7es rrMzWarrenAnalyzer.calculate_roics u  !6*J&44M$//K""k&7&7 x'WXY'' 6D | x'cde!11+?|} #33KA A // =tu)%D#/L 11+H -LLF8+RSWRX!YZLLF8+Y!Z[++K9pqH--k;xyJJJX,F1+Lx=JX,FG x'UV^_bUcdeF?#Hf_#Hf_#H#H x'WX`adWefgAL)E LLF8#3E7; < // P]?^_L// @L'' 8D $ 'L,D#/,#> $,$ x'STdSefg '+;q+@ x'pqr!11-B '+&:&:=K'# ).A.M'*:9L'L$LLF8+]^n]o!pq(4':$LLF8+deudv!wx'+;q+@ x'fgh,,3D4y4&)YZ^Y__qrs LLF8#8c !D Eq> !  LLF8#=aSA B s2AM CM"G M1M5'M N &NN c|j||s||jvrtj|dy ddl}|j |}|j }|jrtj|dy|j|gd}|j|gd}|tj|dy|tj|dyt|}|dk(rtj|d y||z } tj|d | d d t| d S#t$r$} tj|d| Yd} ~ yd} ~ wwxYw)z Calculate Interest Coverage = EBIT / Interest Expense Returns: Coverage ratio (e.g., 5.2) or None z8: Interest Coverage - Skipped (Financial/Utility sector)Nrz,: Interest Coverage - Empty income statementrW)r\r]zInterest Expense Non Operatingr^z$: Interest Coverage - EBIT not foundz0: Interest Coverage - Interest Expense not foundz.: Interest Coverage - Interest Expense is zeroz": Interest Coverage - Calculated: rxr/z': Error calculating Interest Coverage: ) rrrrLrjrkrmrGrUrnrUro) rr$r&rprqrrrsinterest interest_abscoverager~s rrNz*WarrenAnalyzer.calculate_interest_coveragesk  $ $VV 4$BVBV8V LLF8#[\ ]&  !6*J$//K   x'STU'' 6D++K:H | x'KLM x'WXYx=Lq  x'UVWl*H LLF8#Ehs^STU V1% %  LLF8#J1#N O s1AD5AD5D5(D5,D55 E">EE"c  ddl}|j|}|j}|j}|j}|j s|j s |j rt j|dyt|jdkst|jdkrt j|dyd}g}|j|ddgd} |j|dd gd} | rz| rx| dkDrs| | z } | dkDr|d z }|jd |j|ddgd } |j|dd gd } | r'| r%| dkDr | | z }| |kDr|d z }|jd |j|gd d}|r8|dkDr3|d z }|jd| r|| kDr|d z }|jd|j|ddgd}|j|ddgd }| | ||kr|d z }|j|ddgd}|j|ddgd}|j|ddgd }|j|ddgd }t||||gr|dkDr|dkDr||z }||z }||kDr|d z }|j|gdd}|j|gdd }|r |r ||kr|d z }|j|ddgd}|j|ddgd}|j|ddgd }|j|ddgd }t||||gr|dkDr|dkDr||z }||z }||kDr|d z }|r9| r7|r5|j|dd gd } | dkDr| r| dkDr|| z } || z }!| |!kDr|d z }t j|d|dt|d|S#t$r$}"t j|d|"Yd}"~"yd}"~"wwxYw)u) Calculate Piotroski F-Score (0-9 points) Requires 2+ years of historical data for YoY comparisons 9 Criteria: Profitability (4): ROA>0, OCF>0, ΔROA>0, Accruals<0 Leverage (3): ΔLTD≤0, ΔCR>0, NoNewEquity Efficiency (2): ΔGM>0, ΔAT>0 rNz(: F-Score - Missing financial statementsr/z8: F-Score - Insufficient historical data (need 2+ years)rZr[r`rar:zROA>0uΔROA>0)zOperating Cash FlowOperatingCashFlowz$Total Cash From Operating ActivitieszOCF>0z Accruals<0rg LongTermDebtzCurrent Assets CurrentAssetsrbrc)z Share IssuedzOrdinary Shares NumberzCommon Stock Shares Outstanding ShareIssuedz Gross Profit GrossProfitz Total Revenue TotalRevenuez: F-Score - Calculated: z/9 (criteria met: )z': Error calculating Piotroski F-Score: )rjrkrlrmcashflowrGrrLrHrIrUrallro)#rr$rprqbsinccfr1 criteria_metr rxroa_t0 net_income_t1total_assets_t1roa_t1ocfltd_t0ltd_t1curr_assets_t0 curr_liab_t0curr_assets_t1 curr_liab_t1cr_t0cr_t1 shares_t0 shares_t1gross_profit_t0 revenue_t0gross_profit_t1 revenue_t1gm_t0gm_t1at_t0at_t1r~s# rrOz)WarrenAnalyzer.calculate_piotroski_fscoreJsr  !6*J))B''C$$Bxx399 x'OPQ2::"c#++&6&: x'_`aEL --cL+3NPQRJ//^]4SUVWLl|a/?#l2A:QJE ''0!% 4 4S<:UWX Y "&"6"6rNM;Z\]"^ _19L*_j1n+j8E+j8Eu} lz"&"6"6rNM;Z\]"^!#Oaz }|S|dk(r|d?z }|S|d@k(r"||dA|dB| ddC|dd z }|dD|dEzddFz }|S||jk(rt|dG|dH}| r| d'z}|dIkDr |dJ|ddKz }|jdL}|r|dMkDr |dN|d'zddOz }|dP| ddQt|ddR|ddz }|dS|dTzddU|dVzddWz }|S|dXz }|S)Yz8Generate human-readable reasoning for the recommendationr$r%r-r&zN/Ar.rr;r=rdebt_to_equity_reportedr+ru1 è un'eccezionale opportunità di valore: score z,/100 con margin of safety straordinario del z.1fz%! ru& è un'opportunità eccellente: score z/100 con margin of safety del z%. ru# è un business di qualità (score u/100). Il prezzo attuale di €rz incorpora uno sconto del u% rispetto al fair value di €z6, ma il punteggio non raggiunge ancora la soglia BUY (z). u/100). Il prezzo di €z offre uno sconto limitato del z. z (score u/100) quota a €z, con uno sconto del u'% rispetto al fair value stimato di €u>, ma la qualità del business non soddisfa i nostri standard. z presenta un premio del rCrzEccellente ROE del u,% indica un business di qualità superiore. rzROE del u!% mostra una buona redditività. u,% è al di sotto degli standard desiderati. zP/E di ux è attraente. rux è nella norma. ux è elevato. rz"Posizione net cash: D/E riportato z distorto dalla cassa/depositi. g?z#Bilancio solido con debt/equity di rzDebt/equity di u è accettabile. z richiede cautela. uUQuesta è un'occasione rara - Acquistare immediatamente! Il margine di sicurezza del z% offre protezione eccezionale.z'Raccomando l'acquisto a prezzi attuali.rz/ presenta fondamentali discreti (Warren Score: u/100) e sta trattando a €u;, sostanzialmente in linea con il fair value stimato di €u 📊 **Nota**: Prezzo congruo ma **manca un ampio margine di sicurezza**. Opportunità di acquisto limitata. Considerare ingresso solo se scende sotto €r1z (-10% da fair value).u) è un'azienda eccellente (Warren Score: z/100) con fondamentali solidi rz(ROE z%), profit_marginrzmargini operativi z%, uma il prezzo attuale di €z incorpora un premio eccessivo (u% sopra il fair value di €u 📊 **Strategia Consigliata**: Inserire in **Watchlist** e attendere storni del mercato. Livelli di ingresso interessanti: €g?u (fair value) o €g333333?z (con 15% margin of safety).uGEvitare al prezzo attuale, non soddisfa i criteri di qualità e prezzo.)rKrrrnr)rr!r1r3r5r2r$r-r&r.ryr=debt_eqdebt_eq_reportedr reasoningr display_ders rrcz"WarrenAnalyzer._generate_reasonings"-~~fb)%0w* ^^J 'nnUA&..!12%>>*CD!~~j1  , && QRWQXYEFVWZE[[^_I E !& FugMkl|~AlBBEFI  !{#t6& CE7K338+=WXhilWmnMNXY\M]]OOS~~N^^ac & CE7K++0+5TUefiTjkJKUVYJZZ\] fHUG+?? bwr#h.@AA wr#hn==   # (9>N>Z_oru_u =>Ns=SSst tI  -=-I)wJ}B:cBRRTUU 3z#.>>OPP z#.>>QRR  , & prBCFqGGfg gIPOE ! B CILKF " &GwO((-c{333=c2B"F I @@JT@QRU?VVln I>3D-- -& I%PnoI)R<5 T!::I&NN?;M!51-#2Ec1J#NN -eC[9!"23C88TU_`cTddgi I 88BT8I#7NO"T)#..JL I b cIr N)r)5__name__ __module__ __qualname____doc__rrrrrXrQrRrrrrVrSrWrTVALUATION_WEIGHTQUALITY_WEIGHT GROWTH_WEIGHTrrrrrrrrrurLrr\rrOrarboolrrPrrlistrYr^rUrMrNrOr_r]rbrcrr rr r s SOFJ!3_ D%*!*.'" .2NMIJJKL M $M 4M ^Y tY S#XY v 8E?emnsetBGJ>asaCaDa" # s t g3ggg0ccccdc@--c-3-SW-^g $g 4S>g V t38@S@Xe_@D2#2s2xPU2h||#||+Xe_+=Ee_+2:3-+DI+Z--E-V[-#4yyy y  y  y yr r N) rtypingrrrrlogururr rr rrs$ '&GGr