生生不息

生生不息

AI在交易策略中添加交易成本

2025-06-30
AI在交易策略中添加交易成本

提示词

# Python代码
# 计算20日均线
price['short_mavg'] = price['收盘'].rolling(window=20, 
                                          min_periods=1).mean()

# 生成交易信号
price['signal'] = 0.0
price['signal'][price['收盘'] > price['short_mavg']] = 1.0

# 计算每日收益
price['daily_returns'] = price['收盘'].pct_change()

# 计算策略收益
price['strategy_returns'] =\
price['daily_returns'] * price['signal'].shift(1)

# 计算被动持有的收益(假设一直持有该股票)
price['benchmark_returns'] =\
price['daily_returns']

# 计算累积收益
price['cumulative_strategy_returns'] =\
(1 + price['strategy_returns']).cumprod()

price['cumulative_benchmark_returns'] =\
(1 + price['benchmark_returns']).cumprod()

# 绘制累积收益曲线
plt.figure(dpi=300)
plt.plot(price['cumulative_strategy_returns'], 
         label='策略收益', lw=1)
plt.plot(price['cumulative_benchmark_returns'], 
         label='被动持有收益', ls='--',lw=1)
plt.title('策略收益与被动持有收益对比')
plt.legend()
plt.savefig('图12-3.jpg', dpi=300)
plt.show()

现在需要在前面的代码中,添加0.5%的交易成本,然后将考虑交易成本的策略收益和被动持有收益进行对比,并进行可视化,请给出示例代码。

答案

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# 计算20日均线
price['short_mavg'] = price['收盘'].rolling(window=20, min_periods=1).mean()

# 生成交易信号 (收盘价上穿20日均线买入,否则卖出)
price['signal'] = 0.0
price['signal'] = np.where(price['收盘'] > price['short_mavg'], 1.0, 0.0)

# 计算每日收益
price['daily_returns'] = price['收盘'].pct_change()

# ===== 添加交易成本计算 =====
# 计算仓位变化 (信号变化时产生交易)
price['position_change'] = price['signal'].diff().abs()

# 计算交易成本 (0.5%的单向费率)
price['trading_cost'] = price['position_change'] * 0.005

# 计算策略收益 (扣除交易成本)
price['strategy_returns'] = price['daily_returns'] * price['signal'].shift(1) - price['trading_cost']

# 计算被动持有收益 (无交易成本)
price['benchmark_returns'] = price['daily_returns']

# ===== 计算累积收益 =====
# 策略累积收益 (考虑交易成本)
price['cumulative_strategy_returns'] = (1 + price['strategy_returns']).cumprod()

# 被动持有累积收益
price['cumulative_benchmark_returns'] = (1 + price['benchmark_returns']).cumprod()

# ===== 可视化对比 =====
plt.figure(figsize=(14, 8), dpi=100)
plt.grid(True, alpha=0.3)

# 绘制累积收益曲线
plt.plot(price.index, price['cumulative_strategy_returns'], 
         label='策略收益 (含0.5%交易成本)', lw=2, color='#FF6B6B')
plt.plot(price.index, price['cumulative_benchmark_returns'], 
         label='被动持有收益', ls='--', lw=2, color='#4D96FF')

# 标记交易点
trade_dates = price[price['position_change'] > 0].index
for date in trade_dates:
    plt.axvline(x=date, color='gray', alpha=0.3, lw=0.8)

# 添加最终收益标注
final_strategy = price['cumulative_strategy_returns'].iloc[-1]
final_benchmark = price['cumulative_benchmark_returns'].iloc[-1]

plt.annotate(f'策略最终收益: {final_strategy:.2f}x',
            xy=(price.index[-1], final_strategy),
            xytext=(price.index[-int(len(price)*0.3)], final_strategy*0.9),
            arrowprops=dict(arrowstyle='->', color='#FF6B6B'))

plt.annotate(f'被动持有收益: {final_benchmark:.2f}x',
            xy=(price.index[-1], final_benchmark),
            xytext=(price.index[-int(len(price)*0.3)], final_benchmark*1.1),
            arrowprops=dict(arrowstyle='->', color='#4D96FF'))

# 添加统计信息
trade_count = len(trade_dates)
total_cost = price['trading_cost'].sum() * 100
plt.figtext(0.15, 0.15, 
            f"交易次数: {trade_count}次\n总交易成本: {total_cost:.2f}%\n"
            f"策略年化收益: {final_strategy**(252/len(price))-1:.1%}\n"
            f"被动持有年化: {final_benchmark**(252/len(price))-1:.1%}",
            bbox=dict(facecolor='white', alpha=0.8))

# 设置图表元素
plt.title('考虑交易成本的策略收益 vs 被动持有收益', fontsize=15, pad=20)
plt.xlabel('日期', fontsize=12)
plt.ylabel('累积收益 (倍数)', fontsize=12)
plt.legend(loc='best', frameon=True)
plt.yscale('log')  # 对数刻度更好展示长期收益

plt.tight_layout()
plt.savefig('考虑交易成本的收益对比.jpg', dpi=300, bbox_inches='tight')
plt.show()

# ===== 额外分析:交易成本影响 =====
cost_impact = (final_benchmark - final_strategy) / final_benchmark * 100
print(f"交易成本导致收益减少: {cost_impact:.2f}%")
print(f"平均每次交易成本: {total_cost/trade_count:.4f}%")

结果: