Files
simonandClaude Opus 4.7 2f1d8b4d03 feat: djapi 数据源归一化 + bug 修复 + 废弃 getDivData_AK
- 新增 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>
2026-06-16 15:01:04 +08:00

251 lines
8.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)