regular commit
This commit is contained in:
@ -54,7 +54,7 @@ def get_processed_data():
|
||||
|
||||
# 限制为最近一年数据
|
||||
end_date = smic_data.index.max()
|
||||
start_date = end_date - pd.Timedelta(days=360)
|
||||
start_date = end_date - pd.Timedelta(days=360*3)
|
||||
|
||||
print(f"\n限制回测时间范围: {start_date} 到 {end_date}")
|
||||
|
||||
|
||||
@ -2,14 +2,12 @@
|
||||
import vectorbt as vbt
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
from strategy_executor import execute_strategy
|
||||
from strategy_executor import *
|
||||
from strategy_executor import generate_strategy, create_portfolio, create_real_stock_portfolio
|
||||
|
||||
# 设置中文显示
|
||||
plt.rcParams['font.sans-serif'] = ['SimHei']
|
||||
plt.rcParams['axes.unicode_minus'] = False
|
||||
|
||||
|
||||
def plot_results(strategy_data, portfolio):
|
||||
"""绘制结果图表"""
|
||||
price_ratio = strategy_data['price_ratio']
|
||||
@ -177,10 +175,11 @@ def print_statistics(strategy_data, portfolio):
|
||||
print(f"做空信号次数: {short_count}")
|
||||
print(f"总信号次数: {total_signals}")
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
# 执行策略
|
||||
strategy_data = execute_strategy()
|
||||
# 生成策略
|
||||
strategy_data = generate_strategy()
|
||||
|
||||
# 创建基于比率的投资组合(用于分析)
|
||||
ratio_portfolio = create_portfolio(strategy_data)
|
||||
@ -188,45 +187,18 @@ def main():
|
||||
# 创建基于真实股票的投资组合(用于真实收益计算)
|
||||
stock_portfolio = create_real_stock_portfolio(strategy_data)
|
||||
|
||||
# 绘制基于比率的结果
|
||||
plot_results(strategy_data, ratio_portfolio)
|
||||
|
||||
# 打印基于比率的统计
|
||||
print_statistics(strategy_data, ratio_portfolio)
|
||||
|
||||
# 打印真实股票组合的统计
|
||||
if stock_portfolio is not None:
|
||||
print("\n" + "="*60)
|
||||
print("=== 真实股票投资组合表现 ===")
|
||||
print("="*60)
|
||||
|
||||
try:
|
||||
stats = stock_portfolio.stats()
|
||||
print(f"总收益率: {stats.get('Total Return [%]', 'N/A')}%")
|
||||
print(f"年化收益率: {stats.get('Annual Return [%]', 'N/A')}%")
|
||||
print(f"夏普比率: {stats.get('Sharpe Ratio', 'N/A')}")
|
||||
print(f"最大回撤: {stats.get('Max Drawdown [%]', 'N/A')}%")
|
||||
print(f"最终组合价值: {stock_portfolio.value().iloc[-1]:.2f}")
|
||||
print(f"总盈亏: {stock_portfolio.value().iloc[-1] - strategy_data['initial_cash']:.2f}")
|
||||
|
||||
# 绘制真实股票组合的净值曲线
|
||||
plt.figure(figsize=(12, 6))
|
||||
plt.plot(stock_portfolio.value().index, stock_portfolio.value(),
|
||||
label='真实股票组合净值', linewidth=2, color='darkgreen')
|
||||
plt.axhline(y=strategy_data['initial_cash'], color='red', linestyle='--',
|
||||
alpha=0.7, label=f'初始资金({strategy_data["initial_cash"]})')
|
||||
plt.title('真实股票配对交易组合净值')
|
||||
plt.ylabel('组合价值')
|
||||
plt.xlabel('日期')
|
||||
plt.legend()
|
||||
plt.grid(True, alpha=0.3)
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
|
||||
except Exception as e:
|
||||
print(f"分析真实股票组合时出错: {e}")
|
||||
print(stock_portfolio['SMIC'].stats())
|
||||
print(stock_portfolio['HHIC'].stats())
|
||||
|
||||
# 绘制基于比率的结果
|
||||
plot_results(strategy_data, ratio_portfolio)
|
||||
|
||||
print("程序执行完成!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
||||
@ -132,8 +132,8 @@ def generate_stock_sizes(signals, close_smic, close_hhic, initial_cash=100000, p
|
||||
|
||||
return size_df
|
||||
|
||||
def execute_strategy():
|
||||
"""执行配对交易策略"""
|
||||
def generate_strategy():
|
||||
"""生成配对交易策略"""
|
||||
# 获取数据
|
||||
smic_data, hhic_data = get_processed_data()
|
||||
|
||||
@ -257,13 +257,80 @@ def create_real_stock_portfolio(strategy_data):
|
||||
traceback.print_exc()
|
||||
return None
|
||||
|
||||
def generate_stock_sizes(signals, close_smic, close_hhic, initial_cash=100000, position_ratio=0.5):
|
||||
"""
|
||||
生成真实股票交易的size数据
|
||||
返回两个DataFrame:smic_size和hhic_size
|
||||
"""
|
||||
# 创建空的size Series
|
||||
smic_size = pd.Series(0.0, index=signals.index, name='SMIC')
|
||||
hhic_size = pd.Series(0.0, index=signals.index, name='HHIC')
|
||||
|
||||
current_position = 0 # 0: 无仓位, 1: 做多价差, -1: 做空价差
|
||||
|
||||
for i in range(len(signals)):
|
||||
if i < 20: # 跳过布林带计算期
|
||||
continue
|
||||
|
||||
signal = signals.iloc[i]
|
||||
smic_price = close_smic.iloc[i]
|
||||
hhic_price = close_hhic.iloc[i]
|
||||
|
||||
if signal == 1 and current_position != 1: # 做多价差:买入中芯,卖空华虹
|
||||
# 计算每只股票的仓位价值(等市值对冲)
|
||||
position_value = initial_cash * position_ratio
|
||||
|
||||
# 做多中芯国际
|
||||
smic_shares = position_value / smic_price
|
||||
smic_size.iloc[i] = smic_shares
|
||||
|
||||
# 做空华虹半导体
|
||||
hhic_shares = -position_value / hhic_price
|
||||
hhic_size.iloc[i] = hhic_shares
|
||||
|
||||
current_position = 1
|
||||
|
||||
elif signal == -1 and current_position != -1: # 做空价差:卖空中芯,买入华虹
|
||||
# 计算每只股票的仓位价值(等市值对冲)
|
||||
position_value = initial_cash * position_ratio
|
||||
|
||||
# 做空中芯国际
|
||||
smic_shares = -position_value / smic_price
|
||||
smic_size.iloc[i] = smic_shares
|
||||
|
||||
# 做多华虹半导体
|
||||
hhic_shares = position_value / hhic_price
|
||||
hhic_size.iloc[i] = hhic_shares
|
||||
|
||||
current_position = -1
|
||||
|
||||
elif signal == 0 and current_position != 0: # 平仓
|
||||
# 平掉所有仓位
|
||||
if current_position == 1: # 平掉做多价差仓位
|
||||
smic_size.iloc[i] = -smic_size.shift(1).iloc[i] if i > 0 else 0
|
||||
hhic_size.iloc[i] = -hhic_size.shift(1).iloc[i] if i > 0 else 0
|
||||
elif current_position == -1: # 平掉做空价差仓位
|
||||
smic_size.iloc[i] = -smic_size.shift(1).iloc[i] if i > 0 else 0
|
||||
hhic_size.iloc[i] = -hhic_size.shift(1).iloc[i] if i > 0 else 0
|
||||
|
||||
current_position = 0
|
||||
|
||||
# 创建size DataFrame
|
||||
size_df = pd.DataFrame({
|
||||
'SMIC': smic_size,
|
||||
'HHIC': hhic_size
|
||||
})
|
||||
|
||||
return size_df
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
strategy_data = execute_strategy()
|
||||
strategy_data = generate_strategy()
|
||||
|
||||
# 测试基于比率的投资组合
|
||||
ratio_portfolio = create_portfolio(strategy_data)
|
||||
|
||||
# 测试基于真实股票的投资组合
|
||||
stock_portfolio = create_real_stock_portfolio(strategy_data)
|
||||
|
||||
print("策略执行完成!")
|
||||
|
||||
print("策略生成完成!")
|
||||
Reference in New Issue
Block a user