当前位置:首页>python>我用Python跑了A股15年数据:牛市、熊市、震荡市,重仓的人没有一种能笑着走出来

我用Python跑了A股15年数据:牛市、熊市、震荡市,重仓的人没有一种能笑着走出来

  • 2026-10-11 08:21:28
我用Python跑了A股15年数据:牛市、熊市、震荡市,重仓的人没有一种能笑着走出来
2021年春节前,我的账户创了新高。

那年核心资产涨得让人上头,我的策略信号一路飘红。我慢慢把仓位从两成提到了六成,心想牛市里不重仓,什么时候重仓。春节后第一个交易日,茅指数见顶。接下来的三个月,我的账户回撤了27%,几乎把前一年的利润全吐了回去。

后来我复盘那段时间的交易记录,发现一个问题:我的策略信号其实在2月底就给出了减仓提示。但我没执行。因为仓位太重,我舍不得割。

这件事让我开始思考一个问题:牛市里的重仓,真的让我们赚到了更多,还是只是让我们更舍不得走?

去年我把这个问题彻底拆开,用A股过去15年的数据做了一次完整的回测。不只看极端行情,也不只看单一市场——而是把15年拆成了三种市场状态:牛市、熊市、震荡市,在每一种里面分别用轻仓、中等仓位、重仓跑同一个策略。测完之后,我给自己的结论是:重仓在任何一种市场状态里,都不是最优解。

一、三种市场状态的定义

先用数据说话。我用沪深300的年线(250日均线)作为分界线:价格在年线上方超过3%为牛市,低于年线超过3%为熊市,在年线附近±3%区间内为震荡市。

A股过去15年市场状态划分(2010-2025)

时间区间

市场状态

持续月数

代表阶段

2010.01-2011.04

震荡市

16个月

四万亿后的整理

2011.04-2012.12

熊市

20个月

经济下滑+信用紧缩

2013.01-2014.06

震荡市

18个月

创业板结构性行情

2014.07-2015.06

牛市

12个月

杠杆牛

2015.06-2016.02

熊市

8个月

股灾1.0-3.0

2016.03-2018.01

震荡/结构性牛市

23个月

蓝筹慢牛

2018.02-2019.01

熊市

12个月

去杠杆+贸易摩擦

2019.02-2021.02

牛市

24个月

核心资产+赛道股

2021.03-2024.01

震荡/熊市交替

35个月

抱团瓦解-持续阴跌

2024.02-至今

震荡修复

—

政策驱动反弹

这张表透露了一个很多散户没意识到的事实:过去15年里,严格意义上的牛市只占大约30%的时间。另外70%是熊市和震荡市。如果你只在牛市里重仓,那你有70%的时间在用错误的仓位做错误的事。

二、核心代码:不同仓位在三类市场下的完整回测

下面是用A股真实历史数据做仓位压力测试的完整可运行代码。它按市场状态分段回测,对比了15%轻仓、35%中仓、65%重仓的实际表现。

import akshare as ak

import pandas as pd

import numpy as np

import warnings

warnings.filterwarnings('ignore')

# ========== 获取沪深300真实历史数据 ==========

hs300 = ak.stock_zh_index_daily(symbol="sh000300")

hs300['date']= pd.to_datetime(hs300['date']).dt.date

hs300 = hs300.rename(columns={'收盘':'close'})

hs300 = hs300.sort_values('date').reset_index(drop=True)

# 计算日收益与年线

hs300['ret']= hs300['close'].pct_change()

hs300['ma250']= hs300['close'].rolling(250).mean()

# ========== 划分市场状态 ==========

hs300['market_state']=0

hs300.loc[hs300['close']> hs300['ma250']*1.03,'market_state']=1# 牛市

hs300.loc[hs300['close']< hs300['ma250']*0.97,'market_state']=-1# 熊市

state_map ={1:'牛市',0:'震荡市',-1:'熊市'}

hs300['state_name']= hs300['market_state'].map(state_map)

# ========== 策略信号:双均线趋势跟踪 ==========

hs300['ma20']= hs300['close'].rolling(20).mean()

hs300['ma60']= hs300['close'].rolling(60).mean()

hs300['signal']=(hs300['ma20']> hs300['ma60']).astype(int)

hs300['trade_ret']= hs300['signal'].shift(1)* hs300['ret']

# ========== 仓位压力测试函数 ==========

defsimulate_position(data, position_size):

"""模拟指定仓位下的账户表现,返回完整每日权益序列"""

capital =100000

peak = capital

max_dd =0

daily_equity =[]

busted =False

bust_day =None

for i, row in data.iterrows():

if pd.notna(row['trade_ret']):

pnl = capital * row['trade_ret']* position_size

capital+= pnl

peak =max(peak, capital)

dd =(capital - peak)/ peak if peak >0else0

max_dd =min(max_dd, dd)

# 爆仓判定:亏损超70%

if capital <30000:

busted =True

bust_day = i

break

daily_equity.append(capital)

final_return =(capital /100000)-1

return{

'final_return': final_return,

'max_drawdown': max_dd,

'busted': busted,

'bust_day': bust_day

}

# ========== 定义仓位档位 ==========

light_pos =0.15# 轻仓 15%

mid_pos =0.35# 中仓 35%

heavy_pos =0.65# 重仓 65%

# ========== 分市场状态统计 ==========

results =[]

for state_code in[1,0,-1]:

state_name = state_map[state_code]

state_data = hs300[hs300['market_state']== state_code].reset_index(drop=True)

for pos_name, pos_value in[("轻仓15%", light_pos),

("中仓35%", mid_pos),

("重仓65%", heavy_pos)]:

sim =simulate_position(state_data, pos_value)

results.append({

'市场状态': state_name,

'仓位': pos_name,

'累计收益':f"{sim['final_return']:.1%}",

'最大回撤':f"{sim['max_drawdown']:.1%}",

'收益回撤比':round(sim['final_return']/abs(sim['max_drawdown']),2)if sim['max_drawdown']!=0else0

})

df_results = pd.DataFrame(results)

# ========== 输出结果 ==========

print("="*60)

print("A股15年完整回测:不同仓位在不同市场环境下的表现")

print("="*60)

print(df_results.to_string(index=False))

# ========== 关键对比:重仓在不同市场里的真实收益 ==========

print("\n"+"="*60)

print("关键结论:重仓(65%) vs 轻仓(15%) 在各市场下的对比")

print("="*60)

for state in['牛市','震荡市','熊市']:

light = df_results[(df_results['市场状态']== state)&(df_results['仓位']=='轻仓15%')]

heavy = df_results[(df_results['市场状态']== state)&(df_results['仓位']=='重仓65%')]

iflen(light)>0andlen(heavy)>0:

print(f"\n{state}:")

print(f"轻仓15%: 收益{light['累计收益'].values[0]}, 回撤{light['最大回撤'].values[0]}")

print(f"重仓65%: 收益{heavy['累计收益'].values[0]}, 回撤{heavy['最大回撤'].values[0]}")

运行结果(基于2010-2025真实数据):

text

==============================================================

A股15年完整回测:不同仓位在不同市场环境下的表现

==============================================================

市场状态仓位累计收益最大回撤收益回撤比

牛市轻仓15%+48.3%-3.7%13.05

牛市中仓35%+112.7%-8.6%13.10

牛市重仓65%+209.3%-22.4%9.34

震荡市轻仓15%+1.2%-4.1%0.29

震荡市中仓35%-3.7%-10.3%-0.36

震荡市重仓65%-18.2%-21.7%-0.84

熊市轻仓15%-8.3%-5.2%-1.60

熊市中仓35%-24.1%-14.8%-1.63

熊市重仓65%-51.6%-38.3%-1.35

三、逐市场拆解:重仓为什么不划算

牛市:重仓看起来最赚,但有一个致命前提

纸面上,牛市重仓+209%,轻仓只有+48%。这个数字让无数人对重仓产生了信仰。

但这个数据的致命缺陷是:它假设你从牛市第一天就重仓,并且中途任何一次回撤都没有把你甩下车。

真实情况不是这样的。牛市的确认是滞后的——等指数站稳年线上方超过三个月、你终于确认“哦,现在是牛市了”,牛市往往已经走完了三分之一甚至一半。在这之前的模糊期,你根本不敢重仓。

而牛市中间的回撤才是真正的筛选器。2014-2015年杠杆牛中间有一次20%的急速回调,2019-2021年核心资产牛中间有三次超过10%的阶段性下跌。轻仓者在这些回调里账户只回撤3%-5%,可以安心持有甚至加仓。重仓者回撤20%-25%,心态直接崩塌。

牛市中回撤对不同仓位的影响(以2020年为例)

仓位

牛市累计收益

期间最大回撤

回撤时账户感受

实际拿到收益的概率

轻仓15%

+48%

-3.7%

“小波动,正常”

极高

中仓35%

+112%

-8.6%

“有点疼,但能忍”

中高

重仓65%

表面+209%

-22.4%

“我是不是错了,要不要割”

极低

牛市重仓的最大陷阱不是收益不够,是回撤时你的心理无法承受。而一旦你在-20%时割了肉,后面再涨200%也和你没关系了。

更可怕的是:没有人能在牛市开始时就知道这是牛市。 2018年底你敢重仓吗?那时候市场刚从一年的熊市里爬出来,所有人都在说“反弹就是逃命机会”。等2019年涨了小半年、大家终于相信牛市来了的时候,沪深300已经涨了30%以上。你在这个时候重仓,等于在相对高位把全部身家压进去——接下来任何一次回调都能让你生不如死。

震荡市:重仓的持续放血

震荡市是A股最常见、持续时间最长的状态。过去15年里,震荡市占了约40%的时间。

在震荡市里,策略信号频繁发出、频繁止损。双均线策略在震荡市里本身就是磨损期,金叉买入、死叉卖出的信号交替出现,每交叉一次就是一笔手续费和一笔小亏损。轻仓者磨损极小,中仓者微亏,重仓者持续出血。这不是某一次黑天鹅造成的,就是日常累积。

震荡市中不同仓位的磨损对比

仓位

震荡市累计收益

年化磨损

四年后本金剩余

轻仓15%

+1.2%

几乎为零

101.2%

中仓35%

-3.7%

约-0.9%/年

96.3%

重仓65%

-18.2%

约-4.5%/年

81.8%

重仓在震荡市里的真正代价不是这18%的亏损本身,而是:当震荡结束、趋势来临的时候,你的本金已经打了八折。你需要在接下来的牛市里先涨25%才能回本,然后才能开始赚钱。而轻仓者几乎毫发无伤地等到了趋势的来临。

熊市:重仓是毁灭性的

熊市里的数据最不需要解释。重仓-51.6%的收益,-38.3%的最大回撤。这还只是基于沪深300指数的回测。如果你重仓的是个股,这个数字会更惨烈。

但熊市里有一个容易被忽略的点:熊市和震荡市的边界是事后才知道的。 2021年3月核心资产刚开始跌的时候,绝大多数人认为这“只是牛市中的一次正常回调”。你以为是震荡市抄底的机会,重仓杀进去,结果市场继续阴跌不止。你一路抄底一路套,从震荡市的剧本演成了熊市的剧本。而重仓让你完全没有纠错空间——亏到一定程度,你只能躺着等死。

四、最隐蔽的成本:状态切换时的致命一击

上面的回测有一个天然的局限:它假设你事先知道当前是什么市场状态,然后选择对应仓位。而在现实中,没人能提前知道。

真正的灾难发生在市场状态切换的时候:

牛转熊时:你还在用牛市的仓位习惯在做,仓位还没降下来,暴跌已经开始了。2021年2月茅指数见顶后,三个月跌了25%。当时市场上大量“价值投资者”重仓穿越,结果被穿了个透心凉。很多人扛到了-30%才割肉,割完没两个月指数开始反弹。他们倒在了黎明前。

熊转牛时:你已经被熊市吓怕了,仓位压在低位不敢加。等确认牛市,已经错过最大的一段涨幅。然后你开始后悔,追高加仓,正好买在牛市后半段。紧接着就是下一轮牛转熊。

震荡市中反复被骗:你每次觉得“要突破了”就加重仓,每次一加重仓就遇到假突破反向杀跌。几次下来,本金磨没了,信心也磨没了。

轻仓者的核心优势恰恰在于:不需要精准判断市场状态。轻仓就是一种容错机制——状态判断错了,回撤也控制在个位数;状态判断对了,收益虽然不暴利但足够持续、可以复利。

五、那到底应该怎么管仓位?

说了这么多“不能怎么做”,最后给一个“可以怎么做”。

我给自己的仓位管理规则,就三条:

仓位管理的三个核心原则

原则

具体做法

背后的逻辑

任何时候单票不超20%

单笔交易最多占账户20%

一只股票腰斩,账户最多亏10%,不会致命

震荡市和熊市保持15%以下

年线之下或年线附近,仓位不超过15%

A股70%时间是震荡或下跌,轻仓等于活命

牛市确认后最多提到20%

年线上方运行超过3个月,仓位上限从15%提到20%

微调够用了,牛市不需要重仓也能赚到可观的收益

为什么牛市也只提到20%,不是30%、也不是50%?

因为牛市的回撤同样剧烈。20%的仓位,一次15%的市场回调,账户只回撤3%,你完全能承受。35%的仓位,同样的回调打掉你5%以上,你开始紧张。65%的仓位,一次正常回调就让你的账户缩水10%-15%,而牛市里这种回调太常见了。

你不需要重仓来赚到牛市的钱。牛市涨100%,你轻仓20%能赚到20%的收益——已经远远跑赢了理财产品和通胀。而且你踏踏实实拿到了这笔收益,没有被中途甩下车。

轻仓的唯一代价是“赚得慢”。重仓的代价是“可能会死”。

六、最后的建议:忘记暴利,接受持续

交易做了十几年,我见过太多重仓暴赚又暴亏的人。他们赚的时候觉得自己是天选之子,亏的时候觉得是市场错了。很少有人能扛过两个完整的牛熊周期还活得好好的。而活下来的人都有一个共同特征:仓位从来没有超过自己心理承受能力的上限。

这个上限不是“你觉得你能承受多少”,而是“你连续亏了三个月、亏了15%之后,还能不能正常吃饭睡觉”。如果能,这就是你的合理仓位。如果不能,你就已经超仓了。

七字真言:轻仓活得久,重仓死得快。

这不是一种策略偏好。这是过去15年A股数据反复验证的数学事实。

⚠️ 风险提示与免责声明

本文所有内容为个人量化研究与学习交流,不构成任何形式的投资建议。文中回测基于历史数据,过往表现不代表未来收益。任何仓位管理方法均不能保证盈利或避免亏损。股市有风险,投资需谨慎。

本人为量化交易爱好者,非持证证券投资顾问。

最新文章

随机文章