- 新增 djapi/api/stock/data_source.py 统一数源入口 (Tushare 单例) - 迁移 10 个模块至统一数据源入口 - 废弃 getDivData_AK.py - 修复 getStockDiv2.py / smoothBrush.py 等模块 - indexDatas API 参数 tscode 类型修正 (股票→指数代码) - views.py + urls.py 接口清理 - continuation.md 状态更新 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
251 lines
8.9 KiB
Python
251 lines
8.9 KiB
Python
import sys
|
||
from django.shortcuts import render
|
||
from django.http import HttpResponse
|
||
from rest_framework.decorators import api_view
|
||
from rest_framework.response import Response
|
||
from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiTypes
|
||
|
||
from .stock.stock_utils import viewFunc_tsCodeAndDate, viewFunc_singleParam
|
||
from .stock.stock_basic import getStockBasic, getStockListByIndustry, getStockInfo
|
||
from .stock.getStockParam import getStockParam
|
||
from .stock.getStockEp import getStockEp_ttm, get_quarterly_eps
|
||
from .stock.getIndexs import get_index_daily_data, get_index_by_name
|
||
from .stock.stockMargin import getStockMargin, getDailyMargin
|
||
from .stock.getStockFina import get_finance_data_range
|
||
from .stock.getStockDiv2 import analyze_stock_dividend_and_price
|
||
from .stock.xwlbDaily import get_xwlb, get_xwlb_fine
|
||
from .serializers import (
|
||
StockDailySerializer, StockInfoSerializer, IndustryStockSerializer,
|
||
StockParamSerializer, StockEpSerializer, QuarterlyEpsSerializer,
|
||
IndexInfoSerializer, IndexDailySerializer, MarginDailySerializer,
|
||
StockMarginSerializer, FinanceDataSerializer, DividendSerializer,
|
||
XwlbNewsSerializer,
|
||
)
|
||
|
||
# === 通用参数定义(复用) ===
|
||
_PARAM_TSCODE = OpenApiParameter(name='tscode', type=str, default='000001.SZ',
|
||
description='股票代码,如 000001.SZ')
|
||
_PARAM_INDEX_CODE = OpenApiParameter(name='tscode', type=str, default='000001.SH',
|
||
description='指数代码,如 000001.SH=上证指数, 399001.SZ=深证成指, 399006.SZ=创业板指')
|
||
_PARAM_START = OpenApiParameter(name='start_date', type=str, default='20200101',
|
||
description='起始日期 yyyyMMdd')
|
||
_PARAM_END = OpenApiParameter(name='end_date', type=str, default='20251231',
|
||
description='结束日期 yyyyMMdd')
|
||
_PARAM_INDEX_NAME = OpenApiParameter(name='index_name', type=str, default='沪深300',
|
||
description='指数名称,如 沪深300、上证50')
|
||
_PARAM_INDUSTRY = OpenApiParameter(name='industry', type=str, required=True,
|
||
description='行业名称,如 银行、半导体')
|
||
_PARAM_TRADE_DATE = OpenApiParameter(name='trade_date', type=str,
|
||
description='交易日期 yyyyMMdd')
|
||
_PARAM_EXCHANGE_ID = OpenApiParameter(name='exchange_id', type=str,
|
||
description='交易所代码 SSE/SZSE')
|
||
|
||
|
||
@extend_schema(
|
||
responses={200: OpenApiTypes.STR},
|
||
description='返回服务器 Python 版本',
|
||
tags=['系统'],
|
||
)
|
||
@api_view(['GET'])
|
||
def python_version(request):
|
||
return HttpResponse(f"Python Version: {sys.version}")
|
||
|
||
|
||
@extend_schema(exclude=True)
|
||
@api_view(['GET'])
|
||
def home(request):
|
||
return render(request, 'home.html')
|
||
|
||
|
||
@extend_schema(
|
||
parameters=[_PARAM_TSCODE, _PARAM_START, _PARAM_END],
|
||
responses={200: StockDailySerializer(many=True)},
|
||
description='获取个股日线行情数据(开高低收、成交量、成交额)',
|
||
tags=['行情'],
|
||
)
|
||
@api_view(['GET'])
|
||
def stockbasic(request):
|
||
return viewFunc_tsCodeAndDate(request, getStockBasic)
|
||
|
||
|
||
@extend_schema(
|
||
parameters=[_PARAM_INDUSTRY],
|
||
responses={200: IndustryStockSerializer(many=True)},
|
||
description='按申万行业分类查询成分股列表',
|
||
tags=['基础数据'],
|
||
)
|
||
@api_view(['GET'])
|
||
def industrys(request):
|
||
return viewFunc_singleParam(request, getStockListByIndustry, param_name='industry')
|
||
|
||
|
||
@extend_schema(
|
||
parameters=[_PARAM_TSCODE],
|
||
responses={200: StockInfoSerializer()},
|
||
description='获取个股基本信息(名称、行业、上市日期、交易所等)',
|
||
tags=['基础数据'],
|
||
)
|
||
@api_view(['GET'])
|
||
def stockInfo(request):
|
||
return viewFunc_singleParam(request, getStockInfo, param_name='tscode')
|
||
|
||
|
||
@extend_schema(
|
||
parameters=[_PARAM_TSCODE, _PARAM_START, _PARAM_END],
|
||
responses={200: StockParamSerializer(many=True)},
|
||
description='获取个股每日参数(市值、PE/PB/PS、换手率等)',
|
||
tags=['行情'],
|
||
)
|
||
@api_view(['GET'])
|
||
def stockparam(request):
|
||
return viewFunc_tsCodeAndDate(request, getStockParam)
|
||
|
||
|
||
@extend_schema(
|
||
parameters=[_PARAM_TSCODE, _PARAM_START, _PARAM_END],
|
||
responses={200: StockEpSerializer(many=True)},
|
||
description='获取个股 TTM 每股收益(EPS)',
|
||
tags=['财务'],
|
||
)
|
||
@api_view(['GET'])
|
||
def stockep(request):
|
||
return viewFunc_tsCodeAndDate(request, getStockEp_ttm)
|
||
|
||
|
||
@extend_schema(
|
||
parameters=[_PARAM_TSCODE, _PARAM_START, _PARAM_END],
|
||
responses={200: QuarterlyEpsSerializer(many=True)},
|
||
description='获取个股季度每股收益(EPS),按财报日期对齐',
|
||
tags=['财务'],
|
||
)
|
||
@api_view(['GET'])
|
||
def quarterlyEps(request):
|
||
return viewFunc_tsCodeAndDate(request, get_quarterly_eps)
|
||
|
||
|
||
@extend_schema(
|
||
parameters=[_PARAM_INDEX_NAME],
|
||
responses={200: IndexInfoSerializer()},
|
||
description='按名称模糊查询指数基本信息',
|
||
tags=['指数'],
|
||
)
|
||
@api_view(['GET'])
|
||
def indexByName(request):
|
||
index_name = request.GET.get('index_name', '沪深300')
|
||
if not index_name:
|
||
return Response({'error': '缺少 index_name 参数'}, status=400)
|
||
try:
|
||
data = get_index_by_name(index_name)
|
||
dict_data = data.to_dict(orient='records')
|
||
return Response(dict_data)
|
||
except ImportError:
|
||
return Response({'error': '模块不存在'}, status=500)
|
||
except Exception as e:
|
||
return Response({'error': str(e)}, status=500)
|
||
|
||
|
||
@extend_schema(
|
||
parameters=[_PARAM_INDEX_CODE, _PARAM_START, _PARAM_END],
|
||
responses={200: IndexDailySerializer(many=True)},
|
||
description='获取指数日线行情数据(含 PE/PB/市值/换手率等扩展指标)',
|
||
tags=['指数'],
|
||
)
|
||
@api_view(['GET'])
|
||
def indexDatas(request):
|
||
return viewFunc_tsCodeAndDate(request, get_index_daily_data)
|
||
|
||
|
||
@extend_schema(
|
||
parameters=[_PARAM_TSCODE, _PARAM_START, _PARAM_END],
|
||
responses={200: StockMarginSerializer(many=True)},
|
||
description='获取个股融资融券明细数据',
|
||
tags=['融资融券'],
|
||
)
|
||
@api_view(['GET'])
|
||
def stockMargin(request):
|
||
return viewFunc_tsCodeAndDate(request, getStockMargin)
|
||
|
||
|
||
@extend_schema(
|
||
parameters=[_PARAM_TRADE_DATE, _PARAM_START, _PARAM_END, _PARAM_EXCHANGE_ID],
|
||
responses={200: MarginDailySerializer(many=True)},
|
||
description='获取每日融资融券汇总数据(按交易所)',
|
||
tags=['融资融券'],
|
||
)
|
||
@api_view(['GET'])
|
||
def dailyMargin(request):
|
||
trade_date = request.GET.get('trade_date', None)
|
||
start_date = request.GET.get('start_date', None)
|
||
end_date = request.GET.get('end_date', None)
|
||
exchange_id = request.GET.get('exchange_id', None)
|
||
|
||
try:
|
||
data = getDailyMargin(trade_date=trade_date, start_date=start_date,
|
||
end_date=end_date, exchange_id=exchange_id)
|
||
dict_data = data.to_dict(orient='records')
|
||
return Response(dict_data)
|
||
except ImportError:
|
||
return Response({'error': '模块不存在'}, status=500)
|
||
except Exception as e:
|
||
return Response({'error': str(e)}, status=500)
|
||
|
||
|
||
@extend_schema(
|
||
parameters=[_PARAM_TSCODE, _PARAM_START, _PARAM_END],
|
||
responses={200: FinanceDataSerializer(many=True)},
|
||
description='获取个股财务报表分析数据(资产负债表+利润表+现金流,含运营/资产/负债/回报率指标)',
|
||
tags=['财务'],
|
||
)
|
||
@api_view(['GET'])
|
||
def getFinaData(request):
|
||
return viewFunc_tsCodeAndDate(request, get_finance_data_range)
|
||
|
||
|
||
@extend_schema(
|
||
parameters=[_PARAM_TSCODE, _PARAM_START, _PARAM_END],
|
||
responses={200: DividendSerializer(many=True)},
|
||
description='获取个股股息率数据(含 TTM 分红、收盘价、股息率)',
|
||
tags=['分红'],
|
||
)
|
||
@api_view(['GET'])
|
||
def getDivData(request):
|
||
return viewFunc_tsCodeAndDate(request, analyze_stock_dividend_and_price)
|
||
|
||
|
||
|
||
|
||
def _xwlb_view(request, data_func):
|
||
start_date = request.GET.get('start_date', None)
|
||
end_date = request.GET.get('end_date', None)
|
||
try:
|
||
data = data_func(start_date=start_date, end_date=end_date)
|
||
dict_data = data.to_dict(orient='records')
|
||
status = "success" if dict_data else "Error"
|
||
return Response({"status": status, "data": {"news": dict_data}})
|
||
except ImportError:
|
||
return Response({'error': '模块不存在'}, status=500)
|
||
except Exception as e:
|
||
return Response({'error': str(e)}, status=500)
|
||
|
||
|
||
@extend_schema(
|
||
parameters=[_PARAM_START, _PARAM_END],
|
||
responses={200: XwlbNewsSerializer(many=True)},
|
||
description='获取新闻联播原始识别文本(ASR 转写结果)',
|
||
tags=['新闻联播'],
|
||
)
|
||
@api_view(['GET'])
|
||
def xwlbNews(request):
|
||
return _xwlb_view(request, get_xwlb)
|
||
|
||
|
||
@extend_schema(
|
||
parameters=[_PARAM_START, _PARAM_END],
|
||
responses={200: XwlbNewsSerializer(many=True)},
|
||
description='获取新闻联播精编内容(AI 分割+标题提取后的独立新闻)',
|
||
tags=['新闻联播'],
|
||
)
|
||
@api_view(['GET'])
|
||
def xwlbFine(request):
|
||
return _xwlb_view(request, get_xwlb_fine)
|