Skip to content

wangzhe3224/valueinvest

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ValueInvest

A modular Python library for comprehensive stock valuation using multiple methodologies with real-time data fetching and news sentiment analysis.

Features

  • Real-time Data Fetching: A-shares (AKShare), US stocks (yfinance), optional Tushare
  • Graham Valuation: Graham Number, Graham Formula, NCAV (Net-Net)
  • Discounted Cash Flow: DCF (10-year projection), Reverse DCF
  • Earnings Power Value: Zero-growth intrinsic value
  • Dividend Models: Gordon Growth, Two-Stage DDM
  • Growth Valuation: PEG Ratio, GARP, Rule of 40
  • Bank Valuation: P/B Valuation, Residual Income Model
  • News & Sentiment Analysis: Keyword-based and LLM-based sentiment analysis
  • Analyst Data: Company guidance and analyst expectations
  • Insider Trading: Track executive buy/sell activity (A-share & US)
  • Buyback Analysis: Share repurchase tracking and shareholder yield
  • Free Cash Flow Analysis: FCF quality, SBC impact, and profitability metrics
  • Quality Scoring: Piotroski F-Score, Altman Z-Score for financial health
  • Earnings Manipulation Detection: Beneish M-Score for fraud risk assessment
  • Relative Valuation: PE/PB comparison vs historical and peer averages
  • QFQ/HFQ Price Adjustment: Proper price adjustment for valuation comparison and real returns

Installation

# Create virtual environment
uv venv --python 3.11
source .venv/bin/activate

# Install with data sources
pip install -e ".[fetch]"      # All data sources
pip install -e ".[us]"         # US stocks only (yfinance)
pip install -e ".[ashare]"     # A-shares only (AKShare, free)
pip install -e ".[tushare]"    # A-shares with Tushare (requires token)

Quick Start

Command Line

# Analyze A-share stock
python stock_analyzer.py 600887           # 伊利股份
python stock_analyzer.py 600900           # 长江电力
python stock_analyzer.py 601398 --bank    # 工商银行 (force bank analysis)

# Analyze US stock
python stock_analyzer.py AAPL

# Options
python stock_analyzer.py 600887 --period 3y     # 3-year history
python stock_analyzer.py 600900 --dividend      # Force dividend analysis
python stock_analyzer.py 601398 --growth        # Force growth analysis

# With news analysis
python stock_analyzer.py 600887 --news          # Include news sentiment
python stock_analyzer.py AAPL --news --llm      # Use LLM for analysis
python stock_analyzer.py 600887 --news --news-days 60  # 60-day news

# With insider trading analysis
python stock_analyzer.py 600887 --insider       # Include insider trading
python stock_analyzer.py AAPL --insider --insider-days 180  # 180-day insider trades

# With buyback analysis (recommended for US stocks)
python stock_analyzer.py AAPL --buyback         # Include buyback analysis
python stock_analyzer.py 600887 --buyback       # A-share buyback analysis

# With FCF (Free Cash Flow) analysis
python stock_analyzer.py AAPL --fcf             # Include FCF analysis
python stock_analyzer.py AAPL --fcf --fcf-years 7  # 7-year FCF history
python stock_analyzer.py AAPL --buyback --fcf   # Full shareholder return analysis

### Python API

```python
from valueinvest import Stock, ValuationEngine

# Fetch real-time data
stock = Stock.from_api("600887")  # A-share
stock = Stock.from_api("AAPL")    # US stock

# Fetch price history separately
history = Stock.fetch_price_history("600887", period="5y")

# QFQ (前复权) - for valuation comparison
print(f"Price CAGR: {history.cagr:.2f}%")

# HFQ (后复权) - real returns including dividends
print(f"Real CAGR: {history.cagr_hfq:.2f}%")

# Run valuation
engine = ValuationEngine()
results = engine.run_all(stock)

# Category-specific methods
results = engine.run_dividend(stock)  # Dividend stocks
results = engine.run_bank(stock)      # Banks
results = engine.run_growth(stock)    # Growth stocks

News & Sentiment Analysis

Basic Usage

from valueinvest.news.registry import NewsRegistry
from valueinvest.news.analyzer.keyword_analyzer import KeywordSentimentAnalyzer

# Fetch news (auto-detect market: A-share or US)
fetcher = NewsRegistry.get_fetcher("600887")
result = fetcher.fetch_all("600887", days=30)

# Analyze sentiment with keyword matching
analyzer = KeywordSentimentAnalyzer()
analysis = analyzer.analyze_batch(result.news, "600887")

# Access results
print(f"Sentiment Score: {analysis.sentiment_score:+.2f}")  # -1 to 1
print(f"Sentiment Label: {analysis.sentiment_label}")        # positive/negative/neutral
print(f"Key Themes: {analysis.key_themes}")
print(f"Risks: {analysis.risks}")
print(f"Catalysts: {analysis.catalysts}")

# News counts
print(f"Positive: {analysis.positive_count}")
print(f"Negative: {analysis.negative_count}")
print(f"Neutral: {analysis.neutral_count}")

LLM-based Analysis (Optional)

For higher quality analysis, use the LLM analyzer with OpenAI:

from valueinvest.news.analyzer.llm_analyzer import LLMSentimentAnalyzer
import os

os.environ["OPENAI_API_KEY"] = "sk-xxx"

analyzer = LLMSentimentAnalyzer(model="gpt-4o-mini")
analysis = analyzer.analyze_batch(result.news, "AAPL")

# LLM provides additional insights
for item in analysis.news:
    print(f"Rationale: {item.rationale}")  # Explanation for each news item

Agent-based Analysis (No API Key Required)

Use coding agents for deep analysis without external API dependencies:

from valueinvest.news.analyzer.agent_analyzer import (
    AgentSentimentAnalyzer,
    create_agent_analysis_prompt,
    enhance_analysis_with_agent_result,
)

# Create agent analyzer with stock context
analyzer = AgentSentimentAnalyzer(
    stock_name="伊利股份",
    current_price=26.0,
    company_type="value",
)

# Get initial analysis (keyword-based as foundation)
analysis = analyzer.analyze_batch(news, "600887")

# Create prompt for coding agent (use with ultrabrain/deep)
prompt = create_agent_analysis_prompt(
    ticker="600887",
    stock_name="伊利股份",
    current_price=26.0,
    company_type="value",
    news=news,
    days=30,
)

# After getting response from coding agent, enhance the analysis:
agent_response = {
    "sentiment_score": 0.65,
    "key_themes": ["业绩增长", "分红提升"],
    "risks": ["竞争加剧"],
    "catalysts": ["新品发布"],
}
enhanced = enhance_analysis_with_agent_result(analysis, agent_response)

CLI usage for agent-based analysis:

# Use coding agent for deep news analysis
python stock_analyzer.py 600887 --news --agent

Guidance & Analyst Data

# Access analyst guidance
if analysis.has_guidance:
    guidance = analysis.latest_guidance
    
    print(f"Fiscal Year: {guidance.fiscal_year} Q{guidance.quarter}")
    
    # Company guidance
    if guidance.has_company_guidance:
        print(f"EPS Guidance: {guidance.company_eps_low}-{guidance.company_eps_high}")
    
    # Analyst expectations
    if guidance.has_analyst_data:
        print(f"Analyst EPS Mean: {guidance.analyst_eps_mean}")
        print(f"Analyst Count: {guidance.analyst_count}")
        print(f"Rating: {guidance.analyst_rating.value}")
    
    # Compare guidance vs consensus
    print(f"vs Consensus: {guidance.guidance_vs_consensus}")  # above/below/in_line

Insider Trading

Basic Usage

from valueinvest.insider import InsiderRegistry

# Auto-detect market
fetcher = InsiderRegistry.get_fetcher("600887")
result = fetcher.fetch_insider_trades("600887", days=365)

# Access summary
print(f"Sentiment: {result.summary.sentiment}")  # bullish/bearish/neutral
print(f"Buys: {result.summary.buy_count}, Sells: {result.summary.sell_count}")
print(f"Net shares: {result.summary.net_shares:+,.0f}")
print(f"Net value: ¥{result.summary.net_value:+,.0f}")

# Access individual trades
for trade in result.trades[:5]:
    print(f"{trade.trade_date}: {trade.insider_name} {trade.trade_type.value} {trade.shares:,.0f} @ ¥{trade.price}")

Insider Trading Data Sources

Source Markets Data Auth
AKShare (同花顺) A-shares ✅ 高管增减持 Free
yfinance US/Intl ✅ Insider purchases Free

Buyback Analysis

For US stocks, buyback yield is often more important than dividend yield (e.g., AAPL returns ~2.3% via buyback vs ~0.4% dividend).

Basic Usage

from valueinvest.buyback import BuybackRegistry

# Auto-detect market
fetcher = BuybackRegistry.get_fetcher("AAPL")
result = fetcher.fetch_buyback("AAPL", days=365)

# Access summary
summary = result.summary
print(f"Buyback Yield: {summary.buyback_yield:.2f}%")
print(f"Dividend Yield: {summary.dividend_yield:.2f}%")
print(f"Total Shareholder Yield: {summary.total_shareholder_yield:.2f}%")
print(f"Sentiment: {summary.sentiment.value}")  # aggressive/moderate/minimal/none

# Yearly buyback amounts
for year, amount in summary.yearly_amounts.items():
    print(f"{year}: ${amount/1e9:.2f}B")

# Access individual records
for record in result.records[:5]:
    print(f"{record.execution_date}: ${record.amount/1e9:.2f}B")

Buyback Data Sources

Source Markets Data Auth
AKShare (东方财富) A-shares ✅ 回购计划与执行 Free
yfinance US/Intl ✅ Cash flow buyback Free

CLI Usage

python stock_analyzer.py AAPL --buyback            # US stock buyback analysis
python stock_analyzer.py 600887 --buyback          # A-share buyback analysis
python stock_analyzer.py AAPL --buyback --buyback-days 730  # 2-year history

Free Cash Flow (FCF) Analysis

FCF analysis helps evaluate the quality of a company's cash generation, including SBC (Stock-Based Compensation) impact on true profitability.

Basic Usage

from valueinvest.cashflow import CashFlowRegistry

# Auto-detect market
fetcher = CashFlowRegistry.get_fetcher("AAPL")
result = fetcher.fetch_cashflow("AAPL", years=5)

# Access summary
summary = result.summary
print(f"FCF Quality: {summary.fcf_quality.value}")  # EXCELLENT/GOOD/ACCEPTABLE/POOR/NEGATIVE
print(f"FCF Trend: {summary.fcf_trend.value}")    # IMPROVING/STABLE/DECLINING/VOLATILE
print(f"FCF Yield: {summary.fcf_yield:.2f}%")
print(f"FCF Margin: {summary.fcf_margin:.2f}%")

# SBC-adjusted (True FCF)
print(f"True FCF (SBC-adjusted): ${summary.latest_true_fcf/1e9:.2f}B")
print(f"True FCF Yield: {summary.true_fcf_yield:.2f}%")
print(f"SBC as % of FCF: {summary.sbc_as_pct_of_fcf:.1f}%")

# Profitability quality
print(f"FCF / Net Income: {summary.fcf_to_net_income:.2f}x")
print(f"FCF CAGR: {summary.fcf_cagr:.1f}%")

Key Metrics

Metric Description
FCF Quality EXCELLENT (>15% yield), GOOD (10-15%), ACCEPTABLE (5-10%), POOR (0-5%), NEGATIVE (<0)
FCF Trend IMPROVING, STABLE, DECLINING, VOLATILE
FCF Yield FCF / Market Cap
FCF Margin FCF / Revenue
True FCF FCF - SBC (stock-based compensation)
FCF / Net Income Cash quality of earnings (>1.0 is excellent)

FCF Data Sources

Source Markets Data Auth
yfinance US/Intl ✅ Cash flow statement Free

CLI Usage

python stock_analyzer.py AAPL --fcf                  # FCF analysis (default 5 years)
python stock_analyzer.py AAPL --fcf --fcf-years 7   # 7-year FCF history
python stock_analyzer.py AAPL --buyback --fcf       # Combined shareholder return analysis

Piotroski F-Score

The Piotroski F-Score is a 9-point scale that evaluates the financial strength of a company, developed by accounting professor Joseph Piotroski. It's particularly useful for identifying high-quality value stocks.

Basic Usage

from valueinvest import Stock
from valueinvest.valuation import ValuationEngine
from valueinvest.valuation.quality import calculate_f_score

# Method 1: Via Engine (uses Stock's prior year fields)
stock = Stock(
    ticker="AAPL",
    name="Apple Inc.",
    current_price=180.0,
    shares_outstanding=15.5e9,
    net_income=100e9,
    total_assets=350e9,
    total_liabilities=120e9,
    current_assets=60e9,
    fcf=110e9,
    operating_margin=30.0,
    revenue=400e9,
    # Prior year data for trend analysis
    prior_roa=0.28,
    prior_debt_ratio=0.35,
    prior_current_ratio=0.9,
    prior_shares_outstanding=16.0e9,
    prior_gross_margin=28.0,
    prior_asset_turnover=1.1,
)

engine = ValuationEngine()
result = engine.run_single(stock, "piotroski_f")
print(f"F-Score: {result.details['f_score']}/9")
print(f"Risk Level: {result.details['risk_level']}")

# Method 2: Via convenience function
fscore = calculate_f_score(
    stock,
    prior_roa=0.28,
    prior_debt_ratio=0.35,
    prior_current_ratio=0.9,
    prior_shares_outstanding=16.0e9,
    prior_gross_margin=28.0,
    prior_asset_turnover=1.1,
)
print(f"F-Score: {fscore.total_score}/9")
print(f"Profitability: {fscore.profitability_score}/4")
print(f"Leverage: {fscore.leverage_score}/3")
print(f"Efficiency: {fscore.efficiency_score}/2")

The 9 Criteria

Category Criteria Points
Profitability ROA > 0 1
Operating Cash Flow > 0 1
ROA improved vs prior year 1
OCF > Net Income (earnings quality) 1
Leverage/Liquidity Debt ratio decreased 1
Current ratio increased 1
No significant share dilution 1
Operating Efficiency Gross margin improved 1
Asset turnover improved 1

Interpretation

Score Interpretation Risk Level
8-9 Strong - Excellent financial health Low
6-7 Good - Solid financial position Low
4-5 Average - Some financial concerns Medium
0-3 Weak - Poor financial health High

CLI Usage

python stock_analyzer.py 600887 --method piotroski_f

Beneish M-Score

The Beneish M-Score is an 8-variable model developed by Professor Messod D. Beneish to detect earnings manipulation. It identifies companies that may be manipulating their financial statements.

Basic Usage

from valueinvest import Stock
from valueinvest.valuation import ValuationEngine
from valueinvest.valuation.mscore import calculate_m_score

# Method 1: Via Engine (requires prior year data in Stock)
stock = Stock(
    ticker="AAPL",
    name="Apple Inc.",
    current_price=180.0,
    revenue=400e9,
    net_income=100e9,
    total_assets=350e9,
    accounts_receivable=30e9,
    # Prior year data for comparison
    prior_revenue=380e9,
    prior_gross_margin=28.0,
    prior_total_assets=330e9,
)

engine = ValuationEngine()
result = engine.run_single(stock, "beneish_m")
print(f"M-Score: {result.details['m_score']}")
print(f"Manipulation Risk: {result.details['manipulation_risk']}")

# Method 2: Via convenience function
m_result = calculate_m_score(
    stock,
    prior_revenue=380e9,
    prior_gross_margin=28.0,
    prior_total_assets=330e9,
)
print(f"M-Score: {m_result.m_score:.2f}")
print(f"Is Manipulator: {m_result.is_manipulator}")

The 8 Variables

Variable Name What It Measures
DSRI Days Sales Receivable Index Revenue inflation via loose credit
GMI Gross Margin Index Deteriorating margins
AQI Asset Quality Index Increased intangibles/other assets
SGI Sales Growth Index Pressure from high growth
DEPI Depreciation Index Aggressive depreciation policy
SGAI SG&A Index Declining efficiency
LVGI Leverage Index Increasing debt
TATA Total Accruals to Total Assets Low earnings quality

Interpretation

M-Score Interpretation Risk Level
< -2.22 Non-manipulator Low
-2.22 to -1.78 Potential manipulator Medium
> -1.78 High probability manipulator High

CLI Usage

python stock_analyzer.py AAPL --method beneish_m

Relative Valuation (PE/PB)

Relative valuation compares current multiples to historical averages and peer groups - the standard approach used in professional equity research.

PE Relative Valuation

Compares current P/E ratio to historical and peer averages. Best for profitable companies with stable earnings.

Basic Usage

from valueinvest import Stock
from valueinvest.valuation import ValuationEngine

stock = Stock(
    ticker="AAPL",
    name="Apple Inc.",
    current_price=180.0,
    eps=6.0,
    pe_ratio=30.0,
    historical_pe=[25, 28, 30, 32, 27],  # 5-year history
)

engine = ValuationEngine()
result = engine.run_single(stock, "pe_relative")

print(f"Current P/E: {result.details['current_pe']:.1f}x")
print(f"Historical Avg: {result.details['historical_avg_pe']:.1f}x")
print(f"Percentile: {result.details['percentile_in_history']:.0f}th")
print(f"vs Historical: {result.details['vs_historical_pct']:+.1f}%")

Interpretation

  • Bottom quartile (0-25th percentile): Potentially undervalued or deteriorating fundamentals
  • Middle range (40-60th percentile): Fair value
  • Top quartile (75-100th percentile): Potentially overvalued or improving fundamentals

PB Relative Valuation

Compares current P/B ratio to historical and peer averages. Best for banks, financials, and asset-heavy companies.

Basic Usage

from valueinvest import Stock
from valueinvest.valuation import ValuationEngine

stock = Stock(
    ticker="601398",
    name="工商银行",
    current_price=5.0,
    bvps=8.0,
    pb_ratio=0.625,
    historical_pb=[0.7, 0.8, 0.65, 0.75, 0.72],  # 5-year history
)

engine = ValuationEngine()
result = engine.run_single(stock, "pb_relative")

print(f"Current P/B: {result.details['current_pb']:.2f}x")
print(f"Historical Avg: {result.details['historical_avg_pb']:.2f}x")
print(f"Fair Value: ${result.fair_value:.2f}")

When to Use P/B Relative

  • Banks and financial institutions
  • Asset-heavy industries (manufacturing, utilities)
  • Value investing strategies
  • Companies trading below book value (P/B < 1.0)

CLI Usage

# PE Relative
python stock_analyzer.py AAPL --method pe_relative

# PB Relative
python stock_analyzer.py 601398 --method pb_relative

News Data Sources

Source Markets News Guidance Auth
AKShare A-shares ✅ East Money Free
yfinance US/Intl ✅ Yahoo Finance ✅ Analyst data Free

Data Sources

Source Markets Auth Install
AKShare A-shares Free pip install valueinvest[ashare]
yfinance US/Intl Free pip install valueinvest[us]
Tushare A-shares Token TUSHARE_TOKEN=xxx pip install valueinvest[tushare]

Auto-detection by ticker format:

  • 6 digits (600887) → AKShare
  • Letters (AAPL) → yfinance

QFQ vs HFQ Price Adjustment

Type Use Case Characteristics
QFQ (前复权) Valuation comparison Current price unchanged, historical adjusted
HFQ (后复权) Real investment returns Historical unchanged, dividends compounded
history = Stock.fetch_price_history("600900", period="5y")

# QFQ: Price-only growth (for comparing with valuation)
print(f"QFQ CAGR: {history.cagr:.2f}%")

# HFQ: Total return including dividends reinvested
print(f"HFQ CAGR: {history.cagr_hfq:.2f}%")

# Recent prices
stats_qfq = history.get_price_stats(days=30, adjust="qfq")
stats_hfq = history.get_price_stats(days=30, adjust="hfq")

Company Type Detection

Automatic classification based on ticker and financials:

  • Utilities (600900, etc.) → Dividend
  • Banks (601398, etc.) → Bank
  • Dividend yield > 3% → Dividend
  • HFQ CAGR > 10% → Growth
  • HFQ CAGR < 5% → Value

Available Valuation Methods

Method Best For Key Formula
Graham Number Defensive investors √(22.5 × EPS × BVPS)
Graham Formula Moderate growth V = (EPS × (8.5 + 2g) × 4.4) / Y
NCAV Deep value (Assets - Liabilities) / Shares
DCF Growth companies PV(Free Cash Flows) + Terminal Value
Reverse DCF Any What growth is priced in?
EPV Mature companies Distributable CF / Cost of Capital
DDM Dividend stocks D / (r - g)
Two-Stage DDM Dividend growth Stage 1 + Terminal perpetuity
PEG Profitable growth P/E ÷ Growth Rate
GARP Growth at reasonable price Future EPS × Target P/E, discounted
Rule of 40 SaaS/Subscription Growth % + Margin % ≥ 40
P/B Valuation Banks Fair P/B = (ROE - g) / (COE - g)
Residual Income Banks Book Value + PV(Excess Returns)
PE Relative Peer comparison Current PE vs Historical/Peer Avg
PB Relative Asset-heavy, Banks Current PB vs Historical/Peer Avg
Beneish M-Score Fraud detection 8-variable earnings manipulation score
Piotroski F-Score Quality screening 9-point financial strength score
Altman Z-Score Bankruptcy risk Z = 1.2X1 + 1.4X2 + 3.3X3 + 0.6X4 + 1.0X5

Project Structure

valueinvest/
├── stock.py                 # Stock dataclass, StockHistory
├── valuation/
│   ├── base.py              # Base classes
│   ├── engine.py            # Unified engine
│   ├── graham.py            # Graham methods
│   ├── dcf.py               # DCF methods
│   ├── epv.py               # Earnings Power Value
│   ├── ddm.py               # Dividend models
│   ├── growth.py            # Growth valuation
│   ├── bank.py              # Bank valuation
│   ├── quality.py           # Piotroski F-Score, Altman Z-Score, Owner Earnings
│   ├── value_trap.py        # Value trap detection
│   ├── magic_formula.py     # Magic Formula
│   ├── mscore.py            # Beneish M-Score (earnings manipulation)
│   └── relative.py          # PE/PB Relative valuation
├── news/                    # News & sentiment analysis
│   ├── base.py              # NewsItem, Guidance, NewsAnalysisResult
│   ├── registry.py          # Market detection & fetcher registry
│   ├── fetcher/
│   │   ├── base.py          # BaseNewsFetcher (ABC)
│   │   ├── akshare_news.py  # A-share news (East Money)
│   │   └── yfinance_news.py # US stock news & analyst data
│   └── analyzer/
│       ├── base.py          # BaseSentimentAnalyzer (ABC)
│       ├── keyword_analyzer.py  # Keyword-based sentiment
│       ├── llm_analyzer.py      # LLM-based sentiment (OpenAI)
│       └── agent_analyzer.py    # Coding agent-based sentiment
├── insider/                 # Insider trading data
│   ├── base.py              # InsiderTrade, InsiderSummary, InsiderFetchResult
│   ├── registry.py          # Market detection & fetcher registry
│   └── fetcher/
│       ├── base.py          # BaseInsiderFetcher (ABC)
│       ├── akshare_insider.py  # A-share (同花顺高管增减持)
│       └── yfinance_insider.py # US stock insider transactions
├── buyback/                 # Buyback/repurchase analysis
│   ├── base.py              # BuybackRecord, BuybackSummary, BuybackFetchResult
│   ├── registry.py          # Market detection & fetcher registry
│   └── fetcher/
│       ├── base.py          # BaseBuybackFetcher (ABC)
│       ├── akshare_buyback.py  # A-share (东方财富回购数据)
│       └── yfinance_buyback.py # US stock cash flow buyback
├── cashflow/                # Free Cash Flow analysis
│   ├── base.py              # CashFlowRecord, CashFlowSummary, CashFlowFetchResult
│   ├── registry.py          # Market detection & fetcher registry
│   └── fetcher/
│       ├── base.py          # BaseCashFlowFetcher (ABC)
│       └── yfinance_cashflow.py # US stock cash flow data
├── data/
│   ├── presets.py           # Pre-configured stocks
│   └── fetcher/             # Data fetching
│       ├── base.py          # Base classes
│       ├── akshare.py       # A-shares (free)
│       ├── yfinance.py      # US/Intl stocks
│       └── tushare.py       # A-shares (token)
└── reports/
    ├── reporter.py          # Report formatting
    └── enhanced_reporter.py # Enhanced report with news

stock_analyzer.py            # CLI entry point

## Example Output

### With News Analysis

====================================================================== 伊利股份 (600887) - 深度分析报告

【公司概况】 公司: 伊利股份 代码: 600887 类型: 价值股 当前股价: ¥26.48 总市值: ¥1675亿

【最新财务数据】 营业收入: ¥903亿 净利润: ¥104亿 每股收益 (EPS): ¥1.65 每股净资产 (BVPS): ¥8.90 市盈率 (PE): 16.0倍 市净率 (PB): 2.97倍

====================================================================== 【新闻情感分析】

情感得分: 📈 +0.25 (positive) 分析新闻数: 25 条 (7日内: 8) 正面/负面/中性: 12/5/8 置信度: 72% 趋势: ➡️ 稳定

【关键主题】 • 原材料成本下降 • 渠道扩张 • 产品创新

【风险提示】 ⚠️ 竞争加剧 ⚠️ 成本波动

【潜在催化剂】 ✅ 新品发布 ✅ 旺季销售

【近期重要新闻】 [+] 02-15 伊利股份发布业绩预告,净利润增长20%... [+] 02-14 公司宣布分红方案,股息率提升至3.5%... [ ] 02-12 行业分析:乳制品市场稳中有升...

====================================================================== 【估值汇总】

方法 公允价值 溢价/折价 评估
Graham Number ¥ 18.18 -31.3% Overvalued
DDM (Gordon Growth) ¥ 20.94 -20.9% Overvalued
GARP ¥ 19.54 -26.2% Overvalued
Reverse DCF ¥ 26.48 +0.0% Priced in
Graham Formula ¥ 46.17 +74.4% Undervalued

====================================================================== 【综合结论】

估值区间: ¥18-21 (保守) / ¥26 (现价) / ¥40+ (乐观)

【综合评级】: 🟡 合理 + 正面消息

投资建议:

  1. 目标买入价: ¥22 (15%安全边际)
  2. 止损位: ¥16
  3. 情绪面: 近期消息偏正面,可积极关注

## Extending the News Module

### Adding a New Market

```python
from valueinvest.news.base import Market
from valueinvest.news.fetcher.base import BaseNewsFetcher
from valueinvest.news.registry import NewsRegistry

class HKNewsFetcher(BaseNewsFetcher):
    market = Market.HK
    
    @property
    def source_name(self) -> str:
        return "hk_source"
    
    def fetch_news(self, ticker, days=30, start_date=None, end_date=None):
        # Implement news fetching for Hong Kong stocks
        ...
    
    def fetch_guidance(self, ticker):
        # Implement guidance fetching
        ...

# Register the new fetcher
NewsRegistry.register_fetcher(Market.HK, HKNewsFetcher)

# Register market detector
NewsRegistry.register_detector(
    lambda t: Market.HK if t.isdigit() and len(t) == 5 else None
)

Extending the Insider Module

Adding a New Market

from valueinvest.news.base import Market
from valueinvest.insider.base import InsiderTrade, InsiderFetchResult
from valueinvest.insider.fetcher.base import BaseInsiderFetcher
from valueinvest.insider.registry import InsiderRegistry

class HKInsiderFetcher(BaseInsiderFetcher):
    market = Market.HK
    
    @property
    def source_name(self) -> str:
        return "hk_source"
    
    def fetch_insider_trades(self, ticker, days=90, start_date=None, end_date=None):
        # Implement insider trading fetching for Hong Kong stocks
        ...

# Register the new fetcher
InsiderRegistry.register_fetcher(Market.HK, HKInsiderFetcher)

License

MIT License

About

value invest build for agent

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages