check_2026.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import sys, io
  4. if sys.platform == 'win32':
  5. sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
  6. sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
  7. import pandas as pd
  8. import warnings
  9. warnings.filterwarnings('ignore')
  10. df = pd.read_csv(
  11. 'D:/work/project/cyb50-quant/cat-fly/t1/t1_trades_with_environment_20260327_141655.csv',
  12. encoding='utf-8-sig'
  13. )
  14. cols = [
  15. '交易方向','开仓时间','平仓时间','开仓价格','平仓价格','仓位',
  16. '盈亏金额','盈亏百分比','退出原因','持仓周期数','持仓小时数',
  17. 'T1调整','原平仓时间','原平仓价格','原盈亏','盈亏变化',
  18. '入场信号','开仓市值','平仓时资金','市场状态',
  19. '趋势短期','趋势中期','趋势强度','波动率分位','波动率水平',
  20. '成交量分位','布林带位置','布林带区域','RSI分位','RSI区域',
  21. '1日动量','入场价格'
  22. ]
  23. df.columns = cols
  24. df['开仓时间'] = pd.to_datetime(df['开仓时间'])
  25. df['年份'] = df['开仓时间'].dt.year
  26. df['盈利'] = df['盈亏金额'] > 0
  27. y26 = df[df['年份'] == 2026].copy()
  28. print(f'2026年交易: {len(y26)}笔, 胜率{y26["盈利"].mean():.1%}')
  29. print()
  30. # 各类别分布
  31. for col in ['市场状态', '波动率水平', 'RSI区域', '趋势中期', '布林带区域', 'T1调整']:
  32. print(f'[{col}]')
  33. vc = y26[col].value_counts()
  34. for v, cnt in vc.items():
  35. sub = y26[y26[col] == v]
  36. wr = sub['盈利'].mean()
  37. print(f' {v}: {cnt}笔, 胜率{wr:.1%}')
  38. print()
  39. # 连续指标
  40. for col in ['波动率分位', 'RSI分位', '趋势强度', '1日动量']:
  41. vals = y26[col].dropna()
  42. print(f'[{col}] min={vals.min():.3f}, max={vals.max():.3f}, mean={vals.mean():.3f}, median={vals.median():.3f}')
  43. print()
  44. # 逐笔明细
  45. print('2026年逐笔明细:')
  46. print('-' * 100)
  47. for _, r in y26.iterrows():
  48. win = 'WIN' if r['盈利'] else 'LOSS'
  49. date = str(r['开仓时间'])[:10]
  50. ms = str(r['市场状态'])
  51. vl = str(r['波动率水平'])
  52. rsi = str(r['RSI区域'])
  53. vq = r['波动率分位']
  54. rq = r['RSI分位']
  55. ts = r['趋势强度']
  56. mom = r['1日动量']
  57. t1 = str(r['T1调整'])
  58. pnl = r['盈亏金额']
  59. print(f'{date} {win:4s} | 市场:{ms:<12} 波动:{vl:<5} 波动分位:{vq:.2f} RSI区:{rsi:<8} RSI分位:{rq:.3f} 趋强:{ts:.2f} 动量:{mom:.4f} T1:{t1[:6]} | {pnl:>+9,.0f}元')
  60. print()
  61. # 检查 "禁止条件" 在2026年会误杀多少笔
  62. print('=' * 60)
  63. print('禁止条件在2026年的命中情况:')
  64. print()
  65. # 条件1: 市场状态 == 下跌趋势低波
  66. c1 = y26['市场状态'] == '下跌趋势低波'
  67. print(f'条件1 [市场状态=下跌趋势低波]: {c1.sum()}笔被过滤')
  68. if c1.sum() > 0:
  69. sub = y26[c1]
  70. print(f' 其中胜率: {sub["盈利"].mean():.1%}, 盈亏: {sub["盈亏金额"].sum():+,.0f}元')
  71. # 条件2: 波动率水平 == 极高
  72. c2 = y26['波动率水平'] == '极高'
  73. print(f'条件2 [波动率水平=极高]: {c2.sum()}笔被过滤')
  74. if c2.sum() > 0:
  75. sub = y26[c2]
  76. print(f' 其中胜率: {sub["盈利"].mean():.1%}, 盈亏: {sub["盈亏金额"].sum():+,.0f}元')
  77. # 条件3: 波动率分位 > 0.7
  78. c3 = y26['波动率分位'] > 0.7
  79. print(f'条件3 [波动率分位>0.7]: {c3.sum()}笔被过滤')
  80. if c3.sum() > 0:
  81. sub = y26[c3]
  82. print(f' 其中胜率: {sub["盈利"].mean():.1%}, 盈亏: {sub["盈亏金额"].sum():+,.0f}元')
  83. # 条件4: RSI区域 == 超卖
  84. c4 = y26['RSI区域'] == '超卖'
  85. print(f'条件4 [RSI区域=超卖]: {c4.sum()}笔被过滤')
  86. if c4.sum() > 0:
  87. sub = y26[c4]
  88. print(f' 其中胜率: {sub["盈利"].mean():.1%}, 盈亏: {sub["盈亏金额"].sum():+,.0f}元')
  89. # 条件5: T+1调整
  90. c5 = y26['T1调整'].str.contains('T0', na=False)
  91. print(f'条件5 [T1调整=T0→T1]: {c5.sum()}笔被过滤')
  92. if c5.sum() > 0:
  93. sub = y26[c5]
  94. print(f' 其中胜率: {sub["盈利"].mean():.1%}, 盈亏: {sub["盈亏金额"].sum():+,.0f}元')
  95. print()
  96. # 综合: 任意条件触发则过滤
  97. any_filter = c1 | c2 | c3 | c4 | c5
  98. print(f'任意禁止条件触发: {any_filter.sum()}笔被过滤 (共{len(y26)}笔)')
  99. kept = y26[~any_filter]
  100. filtered = y26[any_filter]
  101. print(f' 被过滤: {len(filtered)}笔, 胜率{filtered["盈利"].mean():.1%}, 盈亏{filtered["盈亏金额"].sum():+,.0f}元')
  102. print(f' 保留: {len(kept)}笔, 胜率{kept["盈利"].mean():.1%}, 盈亏{kept["盈亏金额"].sum():+,.0f}元')