import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 模拟参数设定
# 使用固定的随机种子以保证结果可复现
np.random.seed(42)
# 假设年化毛回报(未扣除交易成本前)为10%
gross_return_annual = 0.10
# 假设每次完整换手(买入并卖出)的成本为1%
transaction_cost_per_trade = 0.01
# 生成两组模拟数据
# 较低交易频率群体 (模拟女性投资者), 均值为0.8
turnover_female = np.random.normal(0.8, 0.2, 100)
# 较高交易频率群体 (模拟男性投资者), 均值为1.45
turnover_male = np.random.normal(1.45, 0.4, 100)
# 将数据整合到Pandas DataFrame中
df_female = pd.DataFrame({'turnover': turnover_female, 'group': '较低频率交易者 (模拟)'})
df_male = pd.DataFrame({'turnover': turnover_male, 'group': '较高频率交易者 (模拟)'})
df_sim = pd.concat([df_female, df_male])
# 核心计算:净回报 = 毛回报 - 交易频率 * 单次交易成本
df_sim['net_return'] = gross_return_annual - (df_sim['turnover'] * transaction_cost_per_trade)
# 使用Matplotlib和Seaborn进行绘图
# plt.style.use('seaborn-v0_8-whitegrid')
plt.figure(figsize=(10, 5.5))
sns.scatterplot(
data=df_sim, x='turnover', y='net_return', hue='group',
palette={'较低频率交易者 (模拟)': '#3498db', '较高频率交易者 (模拟)': '#e74c3c'},
alpha=0.7, s=80
)
# 绘制理论上的回报侵蚀线
turnover_rates = np.linspace(0.2, 2.5, 200)
plt.plot(turnover_rates, gross_return_annual - (turnover_rates * transaction_cost_per_trade), 'k--',
label='回报侵蚀效应')
# 图表美化
plt.title('过度交易对投资回报的影响', fontsize=16, pad=20)
plt.xlabel('年化换手率 (交易频率)', fontsize=12)
plt.ylabel('年化净回报', fontsize=12)
plt.gca().yaxis.set_major_formatter(plt.FuncFormatter('{:.0%}'.format)) # Y轴显示为百分比
plt.legend(title='投资者群体', fontsize=10)
plt.grid(True, which='both', linestyle='--', linewidth=0.5)
plt.tight_layout()
plt.show()