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>
This commit is contained in:
@@ -52,7 +52,6 @@ def analyze_stock_dividend_and_price(ts_code, start_date=START_DATE, end_date=EN
|
||||
if start_date > today: start_date = today
|
||||
|
||||
GAP_DAYS = 360 # 定义TTM计算窗口期为360天
|
||||
n = 15 # 定义向前填充的最大非零值个数
|
||||
"""
|
||||
分析个股分红与行情数据。
|
||||
|
||||
@@ -110,23 +109,11 @@ def analyze_stock_dividend_and_price(ts_code, start_date=START_DATE, end_date=EN
|
||||
# 填充空值
|
||||
df_merged_temp['cash_div_tax'] = df_merged_temp['cash_div_tax'].fillna(0.0)
|
||||
|
||||
# 计算 cash_div_year (TTM)
|
||||
# 计算 cash_div_year (TTM) — 向量化 rolling 窗口
|
||||
df_merged_temp = df_merged_temp.sort_values('trade_date').reset_index(drop=True)
|
||||
# 使用滚动窗口计算过去 GAP_DAYS 天的总和
|
||||
# rolling的window参数是基于行数的,所以我们需要先确保日期是连续的交易日
|
||||
# 由于trade_date已经是交易日,我们可以直接使用rolling
|
||||
# 但需要处理时间窗口,确保是360天而不是360行(因为可能有节假日)
|
||||
# 更精确的方法是使用一个自定义函数来累加过去360天内的值
|
||||
|
||||
# 使用更精确的日期差计算
|
||||
def calculate_ttm_div(row_idx):
|
||||
current_date = df_merged_temp.loc[row_idx, 'trade_date']
|
||||
start_window_date = current_date - pd.Timedelta(days=GAP_DAYS)
|
||||
# 筛选出窗口期内的记录
|
||||
mask = (df_merged_temp['trade_date'] > start_window_date) & (df_merged_temp['trade_date'] <= current_date)
|
||||
return df_merged_temp.loc[mask, 'cash_div_tax'].sum()
|
||||
|
||||
df_merged_temp['cash_div_year'] = [calculate_ttm_div(i) for i in range(len(df_merged_temp))]
|
||||
df_temp = df_merged_temp.set_index('trade_date')
|
||||
df_temp['cash_div_year'] = df_temp['cash_div_tax'].rolling(f'{GAP_DAYS}D', min_periods=1).sum()
|
||||
df_merged_temp['cash_div_year'] = df_temp['cash_div_year'].values
|
||||
|
||||
|
||||
# 截取原始请求的起止时间内的数据
|
||||
@@ -155,37 +142,6 @@ def analyze_stock_dividend_and_price(ts_code, start_date=START_DATE, end_date=EN
|
||||
df_result['cash_div_year'] = df_result['cash_div_year'].fillna(0.0)
|
||||
|
||||
|
||||
'''
|
||||
向前填充cash_div_year(最多填充最近n个非零值)
|
||||
如果遇到0值,依次往下查询直到查询到非0数字为止,如果数字个数<=n个,就置last_valid_value, 否则保持不变
|
||||
'''
|
||||
# 确保按trade_date倒序遍历(日期从大到小)
|
||||
df_result = df_result.sort_values('trade_date', ascending=False).reset_index(drop=True)
|
||||
|
||||
last_valid_value = None # 初始化最后一个有效值变量
|
||||
for idx in range(len(df_result)): # 遍历DataFrame的每一行
|
||||
current_value = df_result.loc[idx, 'cash_div_year'] # 获取当前行的TTM分红值
|
||||
if current_value > 0: # 如果当前值大于0
|
||||
last_valid_value = current_value # 更新最后一个有效值
|
||||
else:
|
||||
# 向下查找最多n个位置内的非零值
|
||||
found_value = None # 初始化找到的值
|
||||
search_count = 0 # 初始化搜索计数
|
||||
# 从下一行开始搜索,最多搜索n行
|
||||
for search_idx in range(idx + 1, min(idx + n + 1, len(df_result))):
|
||||
search_value = df_result.loc[search_idx, 'cash_div_year'] # 获取搜索行的值
|
||||
search_count += 1 # 增加搜索计数
|
||||
if search_value > 0: # 如果找到非零值
|
||||
found_value = search_value # 记录找到的值
|
||||
break # 跳出搜索循环
|
||||
|
||||
# 如果找到非零值且在n个位置内
|
||||
if found_value is not None and search_count <= n:
|
||||
df_result.loc[idx, 'cash_div_year'] = found_value
|
||||
last_valid_value = found_value
|
||||
elif last_valid_value is not None:
|
||||
df_result.loc[idx, 'cash_div_year'] = last_valid_value
|
||||
|
||||
# 毛刺平滑处理 cash_div_year 列
|
||||
df_result=smooth_dataframe_brush(df_result, target_columns=['cash_div_year'], window_size=31, threshold_factor=0.5, max_brush_length=15 )
|
||||
# 恢复原始日期顺序
|
||||
|
||||
Reference in New Issue
Block a user