You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
5.9 KiB

# -*- coding: utf-8 -*-
"""
===================================
Market data endpoints
===================================
Responsibilities:
1. Provide market indices data
2. Provide sector momentum data
3. Provide stock momentum recommendations
4. Provide new high/low stocks
5. Provide price distribution
"""
import logging
from datetime import datetime
from typing import Optional, List
from fastapi import APIRouter, Query, Depends
from api.v1.schemas.market import (
MarketIndex,
UpDownStats,
SectorMomentum,
StockMomentum,
NewHighLowStock,
PriceDistribution,
SentimentIndicator,
MarketOverview,
SectorListResponse,
StockMomentumResponse,
NewHighLowResponse,
PriceDistributionResponse,
KLineChartResponse,
)
from api.v1.schemas.common import ErrorResponse
from src.services.market_service import MarketService
logger = logging.getLogger(__name__)
router = APIRouter()
def get_market_service() -> MarketService:
"""Dependency injection for MarketService"""
return MarketService()
@router.get(
"/indices",
response_model=List[MarketIndex],
responses={
200: {"description": "Market indices data"},
500: {"description": "Server error", "model": ErrorResponse},
},
summary="Get market indices",
description="Get major market indices (Shanghai, Shenzhen, ChiNext, STAR50)"
)
def get_indices(
service: MarketService = Depends(get_market_service)
) -> List[MarketIndex]:
"""
Get market indices data
Returns major market indices including:
- Shanghai Composite Index (000001.SH)
- Shenzhen Component Index (399001.SZ)
- ChiNext Index (399006.SZ)
- STAR50 Index (000698.SH)
"""
try:
indices = service.get_indices()
return indices
except Exception as e:
logger.error(f"Failed to get market indices: {e}", exc_info=True)
return []
@router.get(
"/updown-stats",
response_model=UpDownStats,
responses={
200: {"description": "Up/down statistics"},
500: {"description": "Server error", "model": ErrorResponse},
},
summary="Get up/down statistics",
description="Get market up/down statistics including limit up/down counts"
)
def get_updown_stats(
service: MarketService = Depends(get_market_service)
) -> UpDownStats:
"""
Get up/down statistics
Returns statistics about:
- Number of rising stocks
- Number of falling stocks
- Number of flat stocks
- Limit up/down counts
"""
try:
stats = service.get_updown_stats()
return stats
except Exception as e:
logger.error(f"Failed to get updown stats: {e}", exc_info=True)
return UpDownStats(
up_count=0,
down_count=0,
flat_count=0,
limit_up_count=0,
limit_down_count=0,
total_count=0
)
@router.get(
"/price-distribution",
response_model=PriceDistributionResponse,
responses={
200: {"description": "Price distribution"},
500: {"description": "Server error", "model": ErrorResponse},
},
summary="Get price distribution",
description="Get stock price distribution across different price ranges"
)
def get_price_distribution(
service: MarketService = Depends(get_market_service)
) -> PriceDistributionResponse:
"""
Get price distribution
Returns distribution of stocks across price ranges:
- Under 10 yuan
- 10-20 yuan
- 20-50 yuan
- 50-100 yuan
- Over 100 yuan
"""
try:
distribution = service.get_price_distribution()
return distribution
except Exception as e:
logger.error(f"Failed to get price distribution: {e}", exc_info=True)
return PriceDistributionResponse(items=[], total_count=0)
@router.get(
"/overview",
response_model=MarketOverview,
responses={
200: {"description": "Market overview"},
500: {"description": "Server error", "model": ErrorResponse},
},
summary="Get market overview",
description="Get comprehensive market overview including indices, stats, and sentiment"
)
def get_market_overview(
service: MarketService = Depends(get_market_service)
) -> MarketOverview:
"""
Get market overview
Returns comprehensive market data including:
- Major indices
- Up/down statistics
- Sentiment indicators
"""
try:
indices = service.get_indices()
stats = service.get_updown_stats()
sentiment = service.get_sentiment_indicators()
return MarketOverview(
indices=indices,
updown_stats=stats,
sentiment=sentiment,
update_time=datetime.now().strftime("%Y-%m-%d %H:%M:%S")
)
except Exception as e:
logger.error(f"Failed to get market overview: {e}", exc_info=True)
return MarketOverview(
indices=[],
updown_stats=UpDownStats(
up_count=0, down_count=0, flat_count=0,
limit_up_count=0, limit_down_count=0, total_count=0
),
sentiment=[],
update_time=datetime.now().strftime("%Y-%m-%d %H:%M:%S")
)
@router.get(
"/sentiment",
response_model=List[SentimentIndicator],
responses={
200: {"description": "Sentiment indicators"},
500: {"description": "Server error", "model": ErrorResponse},
},
summary="Get sentiment indicators",
description="Get market sentiment indicators"
)
def get_sentiment(
service: MarketService = Depends(get_market_service)
) -> List[SentimentIndicator]:
"""
Get sentiment indicators
Returns various sentiment data including:
- Fear & Greed Index
- Market breadth
- Volatility index
"""
try:
sentiment = service.get_sentiment_indicators()
return sentiment
except Exception as e:
logger.error(f"Failed to get sentiment: {e}", exc_info=True)
return []