|
|
""" |
|
|
Example usage of the Valuation Engine |
|
|
|
|
|
This demonstrates how to use the comprehensive valuation engine to value stocks |
|
|
using multiple models (DCF, DDM, P/E Multiple, etc.) |
|
|
""" |
|
|
|
|
|
import asyncio |
|
|
from src.core.valuation_engine import ValuationEngine, ValuationAssumptions, DCFAssumptions |
|
|
|
|
|
|
|
|
async def basic_valuation_example(): |
|
|
"""Basic valuation example with default assumptions""" |
|
|
print("=" * 60) |
|
|
print("BASIC VALUATION EXAMPLE") |
|
|
print("=" * 60) |
|
|
|
|
|
ticker = "AAPL" |
|
|
|
|
|
async with ValuationEngine() as engine: |
|
|
|
|
|
result = await engine.value_stock(ticker) |
|
|
|
|
|
|
|
|
print(f"\n{'='*60}") |
|
|
print(f"VALUATION RESULTS FOR {ticker}") |
|
|
print(f"{'='*60}") |
|
|
print(f"\nCurrent Price: ${result.current_price:.2f}") |
|
|
|
|
|
if result.weighted_fair_value: |
|
|
print(f"Weighted Fair Value: ${result.weighted_fair_value:.2f}") |
|
|
print(f"Upside/Downside: {result.upside_downside:+.1f}%") |
|
|
|
|
|
print(f"\nFair Value Range:") |
|
|
print(f" Pessimistic (P10): ${result.percentile_10:.2f}") |
|
|
print(f" Base Case (P50): ${result.percentile_50:.2f}") |
|
|
print(f" Optimistic (P90): ${result.percentile_90:.2f}") |
|
|
|
|
|
print(f"\nModels Used: {result.valid_models_count}") |
|
|
print(f"Total Confidence: {result.total_confidence:.2f}") |
|
|
|
|
|
print(f"\n{'='*60}") |
|
|
print("INDIVIDUAL MODEL RESULTS") |
|
|
print(f"{'='*60}") |
|
|
|
|
|
for model, valuation_result in result.model_results.items(): |
|
|
if valuation_result.is_valid: |
|
|
print(f"\n{model.value.upper()}:") |
|
|
print(f" Fair Value: ${valuation_result.fair_value_per_share:.2f}") |
|
|
print(f" Confidence: {valuation_result.confidence:.2f}") |
|
|
if valuation_result.assumptions: |
|
|
print(f" Assumptions: {valuation_result.assumptions}") |
|
|
else: |
|
|
print(f"\n{model.value.upper()}: FAILED") |
|
|
print(f" Error: {valuation_result.error}") |
|
|
|
|
|
|
|
|
async def custom_assumptions_example(): |
|
|
"""Valuation with custom assumptions""" |
|
|
print("\n\n" + "=" * 60) |
|
|
print("CUSTOM ASSUMPTIONS EXAMPLE") |
|
|
print("=" * 60) |
|
|
|
|
|
ticker = "MSFT" |
|
|
|
|
|
|
|
|
assumptions = ValuationAssumptions( |
|
|
dcf=DCFAssumptions( |
|
|
growth_rate=0.08, |
|
|
terminal_growth_rate=0.03, |
|
|
projection_years=7 |
|
|
), |
|
|
risk_free_rate=0.045, |
|
|
market_return=0.11 |
|
|
) |
|
|
|
|
|
async with ValuationEngine() as engine: |
|
|
result = await engine.value_stock(ticker, assumptions=assumptions) |
|
|
|
|
|
print(f"\nValuation for {ticker} with custom assumptions:") |
|
|
print(f" Current Price: ${result.current_price:.2f}") |
|
|
if result.weighted_fair_value: |
|
|
print(f" Fair Value: ${result.weighted_fair_value:.2f}") |
|
|
print(f" Upside/Downside: {result.upside_downside:+.1f}%") |
|
|
|
|
|
|
|
|
async def multiple_stocks_example(): |
|
|
"""Value multiple stocks in parallel""" |
|
|
print("\n\n" + "=" * 60) |
|
|
print("MULTIPLE STOCKS EXAMPLE") |
|
|
print("=" * 60) |
|
|
|
|
|
tickers = ["AAPL", "MSFT", "JNJ"] |
|
|
|
|
|
async with ValuationEngine() as engine: |
|
|
|
|
|
tasks = [engine.value_stock(ticker) for ticker in tickers] |
|
|
results = await asyncio.gather(*tasks) |
|
|
|
|
|
|
|
|
print(f"\n{'Ticker':<10} {'Current':<12} {'Fair Value':<12} {'Upside/Downside':<15} {'Models'}") |
|
|
print("-" * 65) |
|
|
|
|
|
for ticker, result in zip(tickers, results): |
|
|
upside_str = f"{result.upside_downside:+.1f}%" if result.upside_downside else "N/A" |
|
|
fair_value_str = f"${result.weighted_fair_value:.2f}" if result.weighted_fair_value else "N/A" |
|
|
|
|
|
print(f"{ticker:<10} ${result.current_price:<11.2f} {fair_value_str:<12} {upside_str:<15} {result.valid_models_count}") |
|
|
|
|
|
|
|
|
async def quick_valuation_example(): |
|
|
"""Quick valuation for fast lookup""" |
|
|
print("\n\n" + "=" * 60) |
|
|
print("QUICK VALUATION EXAMPLE") |
|
|
print("=" * 60) |
|
|
|
|
|
ticker = "GOOGL" |
|
|
|
|
|
async with ValuationEngine() as engine: |
|
|
|
|
|
fair_value = await engine.get_quick_valuation(ticker) |
|
|
|
|
|
print(f"\nQuick valuation for {ticker}:") |
|
|
if fair_value: |
|
|
print(f" Fair Value: ${fair_value:.2f}") |
|
|
else: |
|
|
print(f" Could not calculate fair value") |
|
|
|
|
|
|
|
|
async def dividend_stock_example(): |
|
|
"""Value a dividend-paying stock (DDM model will be used)""" |
|
|
print("\n\n" + "=" * 60) |
|
|
print("DIVIDEND STOCK EXAMPLE") |
|
|
print("=" * 60) |
|
|
|
|
|
ticker = "JNJ" |
|
|
|
|
|
async with ValuationEngine() as engine: |
|
|
result = await engine.value_stock(ticker) |
|
|
|
|
|
print(f"\nValuation for dividend stock {ticker}:") |
|
|
print(f" Current Price: ${result.current_price:.2f}") |
|
|
|
|
|
if result.weighted_fair_value: |
|
|
print(f" Fair Value: ${result.weighted_fair_value:.2f}") |
|
|
print(f" Upside/Downside: {result.upside_downside:+.1f}%") |
|
|
|
|
|
|
|
|
from src.core.valuation_engine.core.models import ValuationModel |
|
|
if ValuationModel.DDM in result.model_results: |
|
|
ddm_result = result.model_results[ValuationModel.DDM] |
|
|
if ddm_result.is_valid: |
|
|
print(f"\n DDM Model:") |
|
|
print(f" Fair Value: ${ddm_result.fair_value_per_share:.2f}") |
|
|
print(f" Confidence: {ddm_result.confidence:.2f}") |
|
|
print(f" Dividend Growth: {ddm_result.assumptions.get('dividend_growth_rate', 0)*100:.1f}%") |
|
|
|
|
|
|
|
|
async def main(): |
|
|
"""Run all examples""" |
|
|
print("\n" + "=" * 60) |
|
|
print("VALUATION ENGINE - EXAMPLE USAGE") |
|
|
print("=" * 60) |
|
|
|
|
|
|
|
|
await basic_valuation_example() |
|
|
await custom_assumptions_example() |
|
|
await multiple_stocks_example() |
|
|
await quick_valuation_example() |
|
|
await dividend_stock_example() |
|
|
|
|
|
print("\n" + "=" * 60) |
|
|
print("EXAMPLES COMPLETE") |
|
|
print("=" * 60) |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
asyncio.run(main()) |
|
|
|