financial_news_bot / examples /valuation_example.py
Dmitry Beresnev
add valuation engine
2865657
"""
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:
# Run comprehensive valuation
result = await engine.value_stock(ticker)
# Print results
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"
# Create custom assumptions
assumptions = ValuationAssumptions(
dcf=DCFAssumptions(
growth_rate=0.08, # 8% growth
terminal_growth_rate=0.03, # 3% terminal growth
projection_years=7
),
risk_free_rate=0.045, # 4.5% risk-free rate
market_return=0.11 # 11% expected market return
)
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:
# Run valuations in parallel
tasks = [engine.value_stock(ticker) for ticker in tickers]
results = await asyncio.gather(*tasks)
# Print summary
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:
# Get just the weighted fair value (faster)
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" # Johnson & Johnson - dividend aristocrat
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}%")
# Check if DDM was used
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)
# Run examples
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())