You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于资金流入流出计算账户收益率的Python实现问询

计算排除资金流动影响的账户业绩收益率

问题描述

现有两个DataFrame:

  1. 账户余额DataFrame:包含Date(估值日)和Balance(账户总余额)两列
  2. 资金流动DataFrame:包含Date和Movement(当日资金存入/取出金额,存入为正,取出为负)两列

需要计算每日账户业绩收益率,要求排除当日资金流动对余额的影响,具体规则:

  • 当日业绩 = (当日余额 - 调整后的期初余额) / 调整后的期初余额
  • 调整后的期初余额规则:
    • 对于第n天(n>1),若第n-1天有资金流动,调整后的期初余额 = 第n-1天余额 + 第n-1天资金流动
    • 若第n-1天无资金流动,调整后的期初余额 = 第n-1天余额

示例数据

账户余额DataFrame

DateBalance
05/06/2023100
06/06/2023110
07/06/202390
08/06/2023120

资金流动DataFrame

DateMovement
07/06/202320

期望结果

DatePerformance
05/06/2023N/A
06/06/202310%
07/06/2023-18.2%
08/06/20239.1%

计算逻辑说明:

  • 06/06/2023:(110-100)/100 = 10%
  • 07/06/2023:无前期资金流动,(90-110)/110 ≈ -18.2%
  • 08/06/2023:前一天(07/06)有资金流入20,调整后期初余额=90+20=110,(120-110)/110≈9.1%

Pythonic解决方案

使用pandas可以高效实现需求,步骤如下:

1. 导入库并准备数据

import pandas as pd

# 账户余额数据
balance_df = pd.DataFrame({
    'Date': ['05/06/2023', '06/06/2023', '07/06/2023', '08/06/2023'],
    'Balance': [100, 110, 90, 120]
})

# 资金流动数据
movement_df = pd.DataFrame({
    'Date': ['07/06/2023'],
    'Movement': [20]
})

# 将Date列转为日期类型(确保排序正确)
balance_df['Date'] = pd.to_datetime(balance_df['Date'], format='%d/%m/%Y')
movement_df['Date'] = pd.to_datetime(movement_df['Date'], format='%d/%m/%Y')

2. 合并两个DataFrame

将资金流动数据合并到余额数据中,无流动的日期填充0:

# 按Date合并,无Movement的日期填充0
merged_df = pd.merge(balance_df, movement_df, on='Date', how='left').fillna(0)

3. 计算调整后的期初余额

通过shift()获取前一天的余额和资金流动,计算调整后的期初余额:

# 获取前一天的余额和资金流动
merged_df['prev_balance'] = merged_df['Balance'].shift(1)
merged_df['prev_movement'] = merged_df['Movement'].shift(1)

# 计算调整后的期初余额:前一天余额 + 前一天资金流动
merged_df['adjusted_start_balance'] = merged_df['prev_balance'] + merged_df['prev_movement']

4. 计算业绩收益率

基于调整后的期初余额计算收益率,并格式化百分比:

# 计算收益率,首日为N/A
merged_df['Performance'] = merged_df.apply(
    lambda row: (row['Balance'] - row['adjusted_start_balance']) / row['adjusted_start_balance'] 
    if pd.notna(row['adjusted_start_balance']) else 'N/A',
    axis=1
)

# 格式化百分比(保留1位小数)
merged_df['Performance'] = merged_df['Performance'].apply(
    lambda x: f"{x*100:.1f}%" if isinstance(x, float) else x
)

5. 整理最终结果

提取需要的列并按日期排序:

final_df = merged_df[['Date', 'Performance']].sort_values('Date')
# 转换日期格式为原格式
final_df['Date'] = final_df['Date'].dt.strftime('%d/%m/%Y')

print(final_df)

运行后输出结果:

Date Performance
0  05/06/2023          N/A
1  06/06/2023        10.0%
2  07/06/2023       -18.2%
3  08/06/2023         9.1%

关键说明

  • 使用shift()高效获取前一天的数据,避免循环,符合Pythonic风格
  • 通过合并填充确保所有日期都有资金流动数据(无流动为0)
  • 利用apply()和lambda函数简洁实现收益率计算和格式化

内容的提问来源于stack exchange,提问作者Hotone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 04:00:42