File size: 22,559 Bytes
3fe0726
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
"""
Individual metric calculation functions.
Each function is self-contained and follows formulas from stock_evaluation_formulas_and_process.md
"""

import pandas as pd
import numpy as np
from typing import Dict, Optional, Tuple


# ============================================================================
# 1. BUILDING BLOCKS & DATA EXTRACTION
# ============================================================================

def get_diluted_shares(info: Dict, financials: Dict) -> Optional[float]:
    """Get diluted shares outstanding"""
    return info.get('sharesOutstanding') or financials.get('shares_outstanding')


def get_eps_ttm(info: Dict) -> Optional[float]:
    """Earnings Per Share - Trailing Twelve Months"""
    return info.get('trailingEps')


def get_eps_forward(info: Dict) -> Optional[float]:
    """Earnings Per Share - Forward (Next 12 months)"""
    return info.get('forwardEps')


def get_book_value_per_share(info: Dict) -> Optional[float]:
    """Book Value Per Share"""
    return info.get('bookValue')


# ============================================================================
# 2. VALUATION METRICS
# ============================================================================

def calculate_market_cap(price: float, diluted_shares: float) -> Optional[float]:
    """
    Market Capitalization
    Formula: MktCap = Share Price × Diluted Shares
    """
    if type(price) in [int, float] and type(diluted_shares) in [int, float]:
        return price * diluted_shares
    return None


def calculate_enterprise_value(market_cap: float, total_debt: float, 
                               cash: float, minority_interest: float = 0,
                               preferred_stock: float = 0) -> Optional[float]:
    """
    Enterprise Value
    Formula: EV = MktCap + Total Debt + Minority Interest + Preferred Stock − Cash
    
    Explanation: Total value of firm's operating assets available to all capital providers
    """
    if type(market_cap) in [int, float] and type(total_debt) in [int, float] and \
       type(cash) in [int, float] and type(minority_interest) in [int, float] and \
       type(preferred_stock) in [int, float]:
        return market_cap + total_debt + minority_interest + preferred_stock - cash
    return None


def calculate_pe_ratio(price: float, eps: float) -> Optional[float]:
    """
    Price-to-Earnings Ratio
    Formula: P/E = Share Price / EPS
    
    Explanation: How many dollars investors pay per dollar of earnings
    """
    if type(price) in [int, float] and type(eps) in [int, float]:
        if eps and eps > 0:
            return price / eps
    return None


def calculate_peg_ratio(pe_ratio: float, eps_growth_rate: float) -> Optional[float]:
    """
    PEG Ratio (Price/Earnings-to-Growth)
    Formula: PEG = P/E / (Expected EPS annual growth rate in %)
    
    Explanation: Normalizes PE by growth. PEG ≈ 1 implies valuation equals growth
    Threshold: PEG < 1 suggests value, PEG > 1.5 suggests expensive
    """
    if type(pe_ratio) in [int, float] and type(eps_growth_rate) in [int, float]:
        if pe_ratio and eps_growth_rate and eps_growth_rate > 0:
            return pe_ratio / (eps_growth_rate * 100)
    return None


def calculate_ev_ebitda(enterprise_value: float, ebitda: float) -> Optional[float]:
    """
    EV/EBITDA Multiple
    Formula: EV/EBITDA = Enterprise Value / EBITDA
    
    Explanation: Capital-structure neutral valuation, useful for comparing 
    companies with different leverage
    """
    if type(enterprise_value) in [int, float] and type(ebitda) in [int, float]:
        if ebitda and ebitda > 0:
            return enterprise_value / ebitda
    return None


def calculate_price_to_fcf(market_cap: float, free_cash_flow: float) -> Optional[float]:
    """
    Price to Free Cash Flow
    Formula: P/FCF = Market Cap / Free Cash Flow
    
    Explanation: How many dollars investors pay per dollar of free cash flow
    """
    if type(market_cap) in [int, float] and type(free_cash_flow) in [int, float]:
        if free_cash_flow and free_cash_flow > 0:
            return market_cap / free_cash_flow
    return None


def calculate_fcf_yield_equity(free_cash_flow: float, market_cap: float) -> Optional[float]:
    """
    Free Cash Flow Yield (Equity basis)
    Formula: FCF yield = Free Cash Flow / Market Cap
    
    Explanation: Cash return on equity investment
    Threshold: > 6% = attractive, < 3% = expensive
    Priority: HIGHEST - measures actual cash generation
    """
    if type(free_cash_flow) in [int, float] and type(market_cap) in [int, float]:
        if market_cap and market_cap > 0:
            return (free_cash_flow / market_cap) * 100  # Return as percentage
    return None


def calculate_fcf_yield_enterprise(free_cash_flow: float, enterprise_value: float) -> Optional[float]:
    """
    Free Cash Flow Yield (Enterprise basis)
    Formula: FCF yield = Free Cash Flow / EV
    
    Explanation: Cash return on enterprise value (preferred for comparing 
    leveraged vs unleveraged firms)
    Threshold: > 6% = Buy candidate, 4-6% = Hold, < 3% = Unattractive
    """
    if type(free_cash_flow) in [int, float] and type(enterprise_value) in [int, float]:
        if enterprise_value and enterprise_value > 0:
            return (free_cash_flow / enterprise_value) * 100  # Return as percentage
    return None


def calculate_price_to_book(price: float, book_value_per_share: float) -> Optional[float]:
    """
    Price-to-Book Ratio
    Formula: P/B = Price / Book Value per Share
    
    Explanation: Valuation relative to net asset value
    """
    if type(price) in [int, float] and type(book_value_per_share) in [int, float]:
        if book_value_per_share and book_value_per_share > 0:
            return price / book_value_per_share
    return None


# ============================================================================
# 3. PROFITABILITY & MARGIN METRICS
# ============================================================================

def calculate_gross_margin(revenue: float, cogs: float) -> Optional[float]:
    """
    Gross Margin
    Formula: Gross margin = (Revenue − COGS) / Revenue
    
    Explanation: Unit economics - whether price > cost. Rising gross margins 
    imply pricing power or scale
    """
    if type(revenue) in [int, float] and type(cogs) in [int, float]:
        if revenue and revenue > 0:
            return ((revenue - cogs) / revenue) * 100
    return None


def calculate_ebitda_margin(ebitda: float, revenue: float) -> Optional[float]:
    """
    EBITDA Margin
    Formula: EBITDA margin = EBITDA / Revenue
    
    Explanation: Operational cash profitability before capital structure and non-cash charges
    """
    if type(ebitda) in [int, float] and type(revenue) in [int, float]:
        if revenue and revenue > 0:
            return (ebitda / revenue) * 100
    return None


def calculate_ebit_margin(ebit: float, revenue: float) -> Optional[float]:
    """
    EBIT (Operating) Margin
    Formula: EBIT margin = EBIT / Revenue
    
    Explanation: Includes depreciation/amortization; useful for capital-intensive businesses
    """
    if type(ebit) in [int, float] and type(revenue) in [int, float]:
        if revenue and revenue > 0:
            return (ebit / revenue) * 100
    return None


def calculate_net_margin(net_income: float, revenue: float) -> Optional[float]:
    """
    Net Margin
    Formula: Net margin = Net Income / Revenue
    
    Explanation: True bottom-line profitability after interest and tax
    """
    if type(net_income) in [int, float] and type(revenue) in [int, float]:
        if revenue and revenue > 0:
            return (net_income / revenue) * 100
    return None


# ============================================================================
# 4. CASH FLOW METRICS
# ============================================================================

def calculate_free_cash_flow(cash_from_operations: float, capex: float) -> Optional[float]:
    """
    Free Cash Flow
    Formula: FCF = Cash from Operations − Capital Expenditures
    
    Explanation: Actual cash business generates after reinvestment. 
    This is the ULTIMATE value driver.
    """
    if type(cash_from_operations) in [int, float] and type(capex) in [int, float]:
        return cash_from_operations - abs(capex)  # CapEx is usually negative
    return None


def calculate_fcf_per_share(free_cash_flow: float, diluted_shares: float) -> Optional[float]:
    """
    Free Cash Flow per Share
    Formula: FCF per share = Free Cash Flow / Diluted Shares
    
    Explanation: Per-share cash generation, adjusted for dilution
    """
    if type(free_cash_flow) in [int, float] and type(diluted_shares) in [int, float]:
        if diluted_shares and diluted_shares > 0:
            return free_cash_flow / diluted_shares
    return None


def calculate_cash_conversion(cfo: float, net_income: float) -> Optional[float]:
    """
    Cash Conversion Ratio
    Formula: Cash Conversion = CFO / Net Income
    
    Explanation: Measures quality of earnings. Should be > 1.0
    RED FLAG if consistently < 1.0 (profits not converting to cash)
    """
    if type(cfo) in [int, float] and type(net_income) in [int, float]:
        if net_income and net_income != 0:
            return cfo / net_income
    return None


# ============================================================================
# 5. LIQUIDITY & SOLVENCY METRICS
# ============================================================================

def calculate_current_ratio(current_assets: float, current_liabilities: float) -> Optional[float]:
    """
    Current Ratio
    Formula: Current ratio = Current Assets / Current Liabilities
    
    Explanation: Basic short-term liquidity. > 1 is typical
    """
    if type(current_assets) in [int, float] and type(current_liabilities) in [int, float]:
        if current_liabilities and current_liabilities > 0:
            return current_assets / current_liabilities
    return None


def calculate_quick_ratio(cash: float, marketable_securities: float, 
                          receivables: float, current_liabilities: float) -> Optional[float]:
    """
    Quick Ratio (Acid Test)
    Formula: Quick ratio = (Cash + Marketable Securities + Receivables) / Current Liabilities
    
    Explanation: Stricter liquidity measure excluding inventory
    """
    if type(cash) in [int, float] and type(marketable_securities) in [int, float] and \
    type(receivables) in [int, float] and type(current_liabilities) in [int, float]:
        if current_liabilities and current_liabilities > 0:
            return (cash + marketable_securities + receivables) / current_liabilities
    return None


def calculate_net_debt_to_ebitda(total_debt: float, cash: float, ebitda: float) -> Optional[float]:
    """
    Net Debt to EBITDA
    Formula: Net debt / EBITDA = (Total Debt − Cash) / EBITDA
    
    Explanation: Years of EBITDA required to pay net debt
    Thresholds:
    - < 1.0: Low risk
    - 1-3: Moderate
    - > 3: High risk (alert if > 4-5)
    """
    if type(total_debt) in [int, float] and type(cash) in [int, float] and type(ebitda) in [int, float]:
        if ebitda and ebitda > 0:
            net_debt = total_debt - cash
            return net_debt / ebitda
    return None


def calculate_interest_coverage(ebit: float, interest_expense: float) -> Optional[float]:
    """
    Interest Coverage Ratio
    Formula: Interest coverage = EBIT / Interest Expense
    
    Explanation: Ability to pay interest from operating earnings
    Threshold: > 3x is safe, < 2x is risky
    """
    if type(ebit) in [int, float] and type(interest_expense) in [int, float]:
        if interest_expense and interest_expense > 0:
            return ebit / interest_expense
    return None


def calculate_debt_to_equity(total_debt: float, total_equity: float) -> Optional[float]:
    """
    Debt-to-Equity Ratio
    Formula: Debt-to-Equity = Total Debt / Total Equity
    
    Explanation: Capital structure leverage
    """
    if type(total_debt) in [int, float] and type(total_equity) in [int, float]:
        if total_equity and total_equity > 0:
            return total_debt / total_equity
    return None


# ============================================================================
# 6. RETURN & EFFICIENCY METRICS
# ============================================================================

def calculate_roe(net_income: float, avg_shareholders_equity: float) -> Optional[float]:
    """
    Return on Equity
    Formula: ROE = Net Income / Average Shareholders' Equity
    
    Explanation: Returns delivered to equity holders
    Threshold: > 15% is good, > 20% is excellent
    Priority: HIGH - quality indicator
    """
    if type(net_income) in [int, float] and type(avg_shareholders_equity) in [int, float]:
        if avg_shareholders_equity and avg_shareholders_equity > 0:
            return (net_income / avg_shareholders_equity) * 100
    return None


def calculate_roa(net_income: float, total_assets: float) -> Optional[float]:
    """
    Return on Assets
    Formula: ROA = Net Income / Total Assets
    
    Explanation: Asset utilization efficiency
    """
    if type(net_income) in [int, float] and type(total_assets) in [int, float]:
        if total_assets and total_assets > 0:
            return (net_income / total_assets) * 100
    return None


def calculate_roic(ebit: float, tax_rate: float, invested_capital: float) -> Optional[float]:
    """
    Return on Invested Capital
    Formula: 
        NOPAT = EBIT × (1 − Tax Rate)
        ROIC = NOPAT / Invested Capital
    Where: Invested Capital = Total Equity + Total Debt - Cash
    
    Explanation: Operating return on all capital (equity + debt)
    Thresholds:
    - > 10%: Good
    - > 15%: Excellent (high-quality business)
    - Trending up: High-return projects
    Priority: VERY HIGH - best measure of capital efficiency
    """
    if type(ebit) in [int, float] and type(tax_rate) in [int, float] and type(invested_capital) in [int, float]:
        if invested_capital and invested_capital > 0:
            nopat = ebit * (1 - tax_rate)
            return (nopat / invested_capital) * 100
    return None


def calculate_invested_capital(total_equity: float, total_debt: float, cash: float) -> Optional[float]:
    """
    Invested Capital
    Formula: Invested Capital = Total Equity + Total Debt - Cash
    
    Explanation: Total capital deployed in operations
    """
    if type(total_equity) in [int, float] and type(total_debt) in [int, float] and type(cash) in [int, float]:
        return total_equity + total_debt - cash
    return None


# ============================================================================
# 7. GROWTH METRICS
# ============================================================================

def calculate_revenue_growth(current_revenue: float, prior_revenue: float) -> Optional[float]:
    """
    Revenue Growth Rate (YoY)
    Formula: Revenue Growth = (Current Revenue - Prior Revenue) / Prior Revenue
    
    Explanation: Top-line growth momentum
    """
    if type(current_revenue) in [int, float] and type(prior_revenue) in [int, float]:
        if prior_revenue and prior_revenue > 0:
            return ((current_revenue - prior_revenue) / prior_revenue) * 100
    return None


def calculate_eps_growth(current_eps: float, prior_eps: float) -> Optional[float]:
    """
    EPS Growth Rate (YoY)
    Formula: EPS Growth = (Current EPS - Prior EPS) / Prior EPS
    
    Explanation: Bottom-line growth momentum
    """
    if type(current_eps) in [int, float] and type(prior_eps) in [int, float]:
        if prior_eps and prior_eps > 0:
            return ((current_eps - prior_eps) / prior_eps) * 100
    return None


def calculate_cagr(ending_value: float, beginning_value: float, years: int) -> Optional[float]:
    """
    Compound Annual Growth Rate
    Formula: CAGR = (Ending Value / Beginning Value)^(1/years) - 1
    
    Explanation: Smoothed annual growth rate over period
    """
    if type(ending_value) in [int, float] and type(beginning_value) in [int, float] and type(years) in [int, float]:
        if beginning_value and beginning_value > 0 and years > 0:
            return (((ending_value / beginning_value) ** (1 / years)) - 1) * 100
    return None


def calculate_sustainable_growth(roe: float, payout_ratio: float) -> Optional[float]:
    """
    Sustainable EPS Growth
    Formula: Sustainable Growth = ROE × (1 - Payout Ratio)
    Or: Sustainable Growth = ROE × Reinvestment Rate
    
    Explanation: Theoretical growth rate based on returns and reinvestment
    """
    if type(roe) in [int, float] and type(payout_ratio) in [int, float]:
        reinvestment_rate = 1 - payout_ratio
        return roe * reinvestment_rate
    return None


# ============================================================================
# 8. CAPITAL ALLOCATION METRICS
# ============================================================================

def calculate_payout_ratio(dividends: float, net_income: float) -> Optional[float]:
    """
    Payout Ratio
    Formula: Payout Ratio = Dividends / Net Income
    
    Explanation: Proportion of earnings paid as dividends
    """
    if type(dividends) in [int, float] and type(net_income) in [int, float]:
        if net_income and net_income > 0:
            return (dividends / net_income) * 100
    return None


def calculate_buyback_yield(buyback_cash: float, market_cap: float) -> Optional[float]:
    """
    Buyback Yield
    Formula: Buyback Yield = Cash spent on repurchases / Market Cap
    
    Explanation: Return to shareholders via buybacks
    """
    if type(buyback_cash) in [int, float] and type(market_cap) in [int, float]:
        if market_cap and market_cap > 0:
            return (buyback_cash / market_cap) * 100
    return None


def calculate_dilution_rate(current_shares: float, prior_shares: float) -> Optional[float]:
    """
    Dilution Rate
    Formula: Dilution = (Current Shares - Prior Shares) / Prior Shares
    
    Explanation: Share count increase (dilution) or decrease (buybacks)
    Negative value = buybacks, Positive value = dilution
    """
    if type(current_shares) in [int, float] and type(prior_shares) in [int, float]:
        if prior_shares and prior_shares > 0:
            return ((current_shares - prior_shares) / prior_shares) * 100
    return None


def calculate_total_payout_ratio(dividends: float, buybacks: float, net_income: float) -> Optional[float]:
    """
    Total Payout Ratio (including buybacks)
    Formula: Total Payout = (Dividends + Buybacks) / Net Income
    
    Explanation: Total cash returned to shareholders
    """
    if type(dividends) in [int, float] and type(buybacks) in [int, float] and type(net_income) in [int, float]:
        if net_income and net_income > 0:
            return ((dividends + buybacks) / net_income) * 100
    return None


# ============================================================================
# 9. EFFICIENCY METRICS
# ============================================================================

def calculate_asset_turnover(revenue: float, total_assets: float) -> Optional[float]:
    """
    Asset Turnover
    Formula: Asset Turnover = Revenue / Total Assets
    
    Explanation: How efficiently assets generate revenue
    """
    if type(revenue) in [int, float] and type(total_assets) in [int, float]:
        if total_assets and total_assets > 0:
            return revenue / total_assets
    return None


def calculate_inventory_turnover(cogs: float, avg_inventory: float) -> Optional[float]:
    """
    Inventory Turnover
    Formula: Inventory Turnover = COGS / Average Inventory
    
    Explanation: How quickly inventory is sold
    """
    if type(cogs) in [int, float] and type(avg_inventory) in [int, float]:
        if avg_inventory and avg_inventory > 0:
            return cogs / avg_inventory
    return None


def calculate_receivables_turnover(revenue: float, avg_receivables: float) -> Optional[float]:
    """
    Receivables Turnover
    Formula: Receivables Turnover = Revenue / Average Receivables
    
    Explanation: How quickly receivables are collected
    """
    if type(revenue) in [int, float] and type(avg_receivables) in [int, float]:
        if avg_receivables and avg_receivables > 0:
            return revenue / avg_receivables
    return None


# ============================================================================
# 10. WORKING CAPITAL METRICS
# ============================================================================

def calculate_working_capital(current_assets: float, current_liabilities: float) -> Optional[float]:
    """
    Working Capital
    Formula: Working Capital = Current Assets - Current Liabilities
    
    Explanation: Short-term operational liquidity
    """
    if type(current_assets) in [int, float] and type(current_liabilities) in [int, float]:
        return current_assets - current_liabilities
    return None


def calculate_working_capital_ratio(working_capital: float, revenue: float) -> Optional[float]:
    """
    Working Capital to Revenue
    Formula: WC Ratio = Working Capital / Revenue
    
    Explanation: Capital tied up in operations
    """
    if type(working_capital) in [int, float] and type(revenue) in [int, float]:
        if revenue and revenue > 0:
            return (working_capital / revenue) * 100
    return None


# ============================================================================
# HELPER FUNCTIONS
# ============================================================================

def safe_divide(numerator: float, denominator: float, 
                default: Optional[float] = None) -> Optional[float]:
    """Safely divide two numbers, returning default if denominator is 0"""
    if type(numerator) in [int, float] and type(denominator) in [int, float]:
        if denominator and denominator != 0:
            return numerator / denominator
    return default


def calculate_average(value1: float, value2: float) -> Optional[float]:
    """Calculate average of two values"""
    if type(value1) in [int, float] and type(value2) in [int, float]:
        return (value1 + value2) / 2
    return None


def annualize_quarterly(quarterly_value: float) -> Optional[float]:
    """Convert quarterly value to annual (TTM)"""
    if type(quarterly_value) in [int, float]:
        return quarterly_value * 4
    return None