打印交易明细
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*3)
|
||||
start_date = end_date - pd.Timedelta(days=360)
|
||||
|
||||
print(f"\n限制回测时间范围: {start_date} 到 {end_date}")
|
||||
|
||||
|
||||
@ -175,6 +175,209 @@ def print_statistics(strategy_data, portfolio):
|
||||
print(f"做空信号次数: {short_count}")
|
||||
print(f"总信号次数: {total_signals}")
|
||||
|
||||
def print_trade_orders(strategy_data, stock_portfolio):
|
||||
"""打印所有交易订单信息"""
|
||||
if stock_portfolio is None:
|
||||
return
|
||||
|
||||
print("\n" + "="*60)
|
||||
print("=== 详细交易订单信息 ===")
|
||||
print("="*60)
|
||||
|
||||
try:
|
||||
# 获取订单记录
|
||||
orders_df = stock_portfolio.orders.records_readable
|
||||
|
||||
if len(orders_df) > 0:
|
||||
print(f"\n总订单数量: {len(orders_df)}")
|
||||
|
||||
# 按时间排序
|
||||
time_column = None
|
||||
possible_time_columns = ['Timestamp', 'Date', 'Time']
|
||||
for col in possible_time_columns:
|
||||
if col in orders_df.columns:
|
||||
time_column = col
|
||||
break
|
||||
|
||||
if time_column:
|
||||
orders_sorted = orders_df.sort_values(time_column)
|
||||
else:
|
||||
orders_sorted = orders_df
|
||||
|
||||
# 显示所有订单(按时间排序)
|
||||
pd.set_option('display.max_rows', None)
|
||||
pd.set_option('display.width', None)
|
||||
|
||||
print("\n【所有交易订单(按时间排序)】")
|
||||
print(orders_sorted.to_string(index=False))
|
||||
|
||||
# 按股票分组统计
|
||||
print(f"\n【按股票统计】")
|
||||
for column in ['SMIC', 'HHIC']:
|
||||
column_orders = orders_sorted[orders_sorted['Column'] == column]
|
||||
if len(column_orders) > 0:
|
||||
buy_orders = column_orders[column_orders['Side'] == 'Buy']
|
||||
sell_orders = column_orders[column_orders['Side'] == 'Sell']
|
||||
|
||||
print(f"\n{column} 订单统计:")
|
||||
print(f" 总订单数: {len(column_orders)}")
|
||||
print(f" 买入订单: {len(buy_orders)}")
|
||||
print(f" 卖出订单: {len(sell_orders)}")
|
||||
print(f" 总交易金额: {column_orders['Size'].abs().sum():.2f} 股")
|
||||
print(f" 总手续费: {column_orders['Fees'].sum():.2f}")
|
||||
|
||||
# 按日期分组统计
|
||||
if time_column:
|
||||
print(f"\n【按日期统计】")
|
||||
daily_orders = orders_sorted.groupby(time_column).agg({
|
||||
'Column': 'count',
|
||||
'Size': 'sum',
|
||||
'Fees': 'sum'
|
||||
}).rename(columns={'Column': '订单数'})
|
||||
|
||||
print(daily_orders.to_string())
|
||||
else:
|
||||
print(f"\n【按日期统计】- 未找到时间列")
|
||||
|
||||
# 重置pandas显示选项
|
||||
pd.reset_option('display.max_rows')
|
||||
pd.reset_option('display.width')
|
||||
|
||||
else:
|
||||
print("没有找到交易订单")
|
||||
|
||||
except Exception as e:
|
||||
print(f"打印订单信息时出错: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
def print_detailed_trade_analysis(strategy_data, stock_portfolio):
|
||||
"""打印详细的交易分析"""
|
||||
if stock_portfolio is None:
|
||||
return
|
||||
|
||||
print("\n" + "="*60)
|
||||
print("=== 详细交易分析 ===")
|
||||
print("="*60)
|
||||
|
||||
try:
|
||||
# 获取交易记录
|
||||
trades_df = stock_portfolio.trades.records_readable
|
||||
|
||||
if len(trades_df) > 0:
|
||||
print(f"\n总交易次数: {len(trades_df)}")
|
||||
|
||||
# 按开仓时间排序
|
||||
trades_sorted = trades_df.sort_values('Entry Timestamp')
|
||||
|
||||
# 显示所有交易(按时间排序)
|
||||
pd.set_option('display.max_rows', None)
|
||||
pd.set_option('display.width', None)
|
||||
|
||||
print("\n【所有交易记录(按开仓时间排序)】")
|
||||
print(trades_sorted.to_string(index=False))
|
||||
|
||||
# 按股票分组分析
|
||||
print(f"\n【按股票交易分析】")
|
||||
for column in ['SMIC', 'HHIC']:
|
||||
column_trades = trades_sorted[trades_sorted['Column'] == column]
|
||||
if len(column_trades) > 0:
|
||||
winning_trades = column_trades[column_trades['PnL'] > 0]
|
||||
losing_trades = column_trades[column_trades['PnL'] < 0]
|
||||
|
||||
print(f"\n{column} 交易分析:")
|
||||
print(f" 总交易次数: {len(column_trades)}")
|
||||
print(f" 盈利交易: {len(winning_trades)}")
|
||||
print(f" 亏损交易: {len(losing_trades)}")
|
||||
print(f" 胜率: {len(winning_trades)/len(column_trades)*100:.1f}%")
|
||||
print(f" 总盈亏: {column_trades['PnL'].sum():.2f}")
|
||||
print(f" 平均每笔盈亏: {column_trades['PnL'].mean():.2f}")
|
||||
print(f" 最大盈利: {column_trades['PnL'].max():.2f}")
|
||||
print(f" 最大亏损: {column_trades['PnL'].min():.2f}")
|
||||
if len(winning_trades) > 0:
|
||||
print(f" 平均盈利: {winning_trades['PnL'].mean():.2f}")
|
||||
if len(losing_trades) > 0:
|
||||
print(f" 平均亏损: {losing_trades['PnL'].mean():.2f}")
|
||||
|
||||
# 正确的配对交易分析
|
||||
print(f"\n【配对交易分析(修正)】")
|
||||
|
||||
# 按开仓时间分组,找出同一天开仓的SMIC和HHIC交易
|
||||
entry_groups = trades_sorted.groupby('Entry Timestamp').agg({
|
||||
'Column': list,
|
||||
'PnL': list,
|
||||
'Size': list,
|
||||
'Direction': list,
|
||||
'Exit Timestamp': list
|
||||
})
|
||||
|
||||
pair_trades = []
|
||||
for entry_date, group_data in entry_groups.iterrows():
|
||||
columns = group_data['Column']
|
||||
pnls = group_data['PnL']
|
||||
directions = group_data['Direction']
|
||||
exit_times = group_data['Exit Timestamp']
|
||||
|
||||
# 检查是否同时有SMIC和HHIC的交易
|
||||
if 'SMIC' in columns and 'HHIC' in columns:
|
||||
smic_idx = columns.index('SMIC')
|
||||
hhic_idx = columns.index('HHIC')
|
||||
|
||||
# 检查交易方向是否配对(一个做多,一个做空)
|
||||
if directions[smic_idx] != directions[hhic_idx]:
|
||||
pair_pnl = pnls[smic_idx] + pnls[hhic_idx]
|
||||
pair_trades.append({
|
||||
'entry_date': entry_date,
|
||||
'exit_date_smic': exit_times[smic_idx],
|
||||
'exit_date_hhic': exit_times[hhic_idx],
|
||||
'smic_pnl': pnls[smic_idx],
|
||||
'hhic_pnl': pnls[hhic_idx],
|
||||
'total_pnl': pair_pnl,
|
||||
'smic_direction': directions[smic_idx],
|
||||
'hhic_direction': directions[hhic_idx]
|
||||
})
|
||||
|
||||
if pair_trades:
|
||||
# 按开仓时间排序配对交易
|
||||
pair_trades_sorted = sorted(pair_trades, key=lambda x: x['entry_date'])
|
||||
|
||||
print(f"配对交易次数: {len(pair_trades_sorted)}")
|
||||
|
||||
total_pair_pnl = sum(trade['total_pnl'] for trade in pair_trades_sorted)
|
||||
avg_pair_pnl = total_pair_pnl / len(pair_trades_sorted)
|
||||
|
||||
winning_pairs = [t for t in pair_trades_sorted if t['total_pnl'] > 0]
|
||||
losing_pairs = [t for t in pair_trades_sorted if t['total_pnl'] < 0]
|
||||
|
||||
print(f"配对交易总盈亏: {total_pair_pnl:.2f}")
|
||||
print(f"平均每对盈亏: {avg_pair_pnl:.2f}")
|
||||
print(f"盈利配对: {len(winning_pairs)}")
|
||||
print(f"亏损配对: {len(losing_pairs)}")
|
||||
print(f"配对胜率: {len(winning_pairs)/len(pair_trades_sorted)*100:.1f}%")
|
||||
|
||||
# 显示每对交易的详细信息(按时间排序)
|
||||
print(f"\n【各配对交易详情(按开仓时间排序)】")
|
||||
for i, trade in enumerate(pair_trades_sorted, 1):
|
||||
status = "盈利" if trade['total_pnl'] > 0 else "亏损"
|
||||
print(f"第{i}对 - 开仓: {trade['entry_date']}")
|
||||
print(f" SMIC({trade['smic_direction']}): {trade['smic_pnl']:.2f} (平仓: {trade['exit_date_smic']})")
|
||||
print(f" HHIC({trade['hhic_direction']}): {trade['hhic_pnl']:.2f} (平仓: {trade['exit_date_hhic']})")
|
||||
print(f" 总盈亏: {trade['total_pnl']:.2f} [{status}]")
|
||||
print()
|
||||
else:
|
||||
print("没有找到配对交易")
|
||||
|
||||
# 重置pandas显示选项
|
||||
pd.reset_option('display.max_rows')
|
||||
pd.reset_option('display.width')
|
||||
|
||||
else:
|
||||
print("没有找到交易记录")
|
||||
|
||||
except Exception as e:
|
||||
print(f"打印交易分析时出错: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
@ -197,8 +400,13 @@ def main():
|
||||
# 绘制基于比率的结果
|
||||
plot_results(strategy_data, ratio_portfolio)
|
||||
|
||||
# 打印详细交易订单信息
|
||||
print_trade_orders(strategy_data, stock_portfolio)
|
||||
|
||||
# 打印详细交易分析
|
||||
print_detailed_trade_analysis(strategy_data, stock_portfolio)
|
||||
|
||||
print("程序执行完成!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user