蚂蚁量化 发布于2024-10-05
回复 98
浏览 14912
366
我2016年写的白马股策略”价值发现“,在2019到2021三年的年平均收益超过65%,但从2022年开始,收益长时间大幅回撤。这两年经过对市场的反思,我认识到策略要用单一的方法,应对市场的不同冷热状态是不行的,投资谚语:”涨时重势,跌时重质“,就是涨的时候看重趋势,是进取、进攻的姿态,跌的时候看重股票的价值,是一种防守的姿态。而根据市场的高度,把市场划分成冷、暖、热三种温度,不同的温度下,策略采取不同的方法选股,就得到了”白马股-攻防兼备“策略,年化收益61%,最大回撤20%,两个收益的对比图如下:

下面我用**Ahfu**朋友的”**大市值价值投资,从2005年至今超额稳定**“策略作为框架,以沪深300指数样本股为股票池,实现白马股攻防转换策略
## 策略框架克隆自聚宽文章:https://www.joinquant.com/post/41921
## 标题:大市值价值投资,从2005年至今超额稳定
## 作者:Ahfu
首先写一个市场温度策略函数:
```
# 测量市场所处的热度,分cold\warm\hot三种
def Market_temperature(context):
index300 = attribute_history('000300.XSHG', 220, '1d', ('close'), df=False)['close']
market_height = (mean(index300[-5:]) - min(index300)) / (max(index300) - min(index300))
if market_height < 0.20: # 高度在0.2以下定为低温
g.market_temperature = "cold"
elif market_height > 0.90: # 高度在0.9以上定为高温
g.market_temperature = "hot"
elif max(index300[-60:]) / min(index300) > 1.20:
# 高度在0.2~0.9之间时,如果60天内,指数从低位上涨大于20%,定为中温
g.market_temperature = "warm"
if g.market_temperature == "cold":
temp = 200
elif g.market_temperature == "warm":
temp = 300
else:
temp = 400
if context.run_params.type != 'sim_trade':
record(temp=temp)
```
然后在选股代码里,分三种情况筛选股票:
```
if g.market_temperature == "cold":
q = query(
valuation.code,
).filter(
valuation.pb_ratio > 0,
valuation.pb_ratio < 1,
cash_flow.subtotal_operate_cash_inflow > 0,
indicator.adjusted_profit > 0,
cash_flow.subtotal_operate_cash_inflow/indicator.adjusted_profit>2.0,
indicator.inc_return > 1.5,
indicator.inc_net_profit_year_on_year > -15,
valuation.code.in_(all_stocks)
).order_by(
(indicator.roa/valuation.pb_ratio).desc()
).limit(
g.buy_stock_count + 1
)
elif g.market_temperature == "warm":
q = query(
valuation.code,
).filter(
valuation.pb_ratio > 0,
valuation.pb_ratio < 1,
cash_flow.subtotal_operate_cash_inflow > 0,
indicator.adjusted_profit > 0,
cash_flow.subtotal_operate_cash_inflow/indicator.adjusted_profit>1.0,
indicator.inc_return > 2.0,
indicator.inc_net_profit_year_on_year > 0,
valuation.code.in_(all_stocks)
).order_by(
(indicator.roa/valuation.pb_ratio).desc()
).limit(
g.buy_stock_count + 1
)
elif g.market_temperature == "hot":
q = query(
valuation.code,
).filter(
valuation.pb_ratio > 3,
cash_flow.subtotal_operate_cash_inflow > 0,
indicator.adjusted_profit > 0,
cash_flow.subtotal_operate_cash_inflow/indicator.adjusted_profit>0.5,
indicator.inc_return > 3.0,
indicator.inc_net_profit_year_on_year > 20,
valuation.code.in_(all_stocks)
).order_by(
indicator.roa.desc()
).limit(
g.buy_stock_count + 1
)
```
然后月度调仓,买入前5名股票,策略收益年化35%,最大回撤23%,策略如下,抛砖引玉,欢迎大家批评改进:
评论
如果只做沪深300轮动,代码需要怎么修改?
2024-10-05
@老有所依 这个回测就是用的沪深300指数样本股为股票池,只做沪深300
2024-10-05
看过代码我有个问题,对于warm的定义为啥不直接用0.2到0.9就行了?
2024-10-05
感谢分享!这个是个好的解决办法。白马股应该有好的策略。这个思路很好!
2024-10-05
@小徐 厉害,问得好,被你发现了这个细节。这个是有区别的,比方说股市长期横盘,涨一点点高度就可能大于0.2,但大盘任然是很冷, 不宜切换成中温,函数这么写,即使到0.2也不立刻切换,只有从低点涨幅超过20%后才切换。这也是投资界常说的,从低点涨幅超过20%后,进入技术性牛市。
2024-10-05
原来如此,哈哈,好嘞@蚂蚁量化
2024-10-05
@璐璐202006 哈哈,永远在路上
2024-10-05
@韶华不负 对,看天气定策略,下雪了就要穿棉袄。
2024-10-05
@自强88 你还可以试试别的,如低温时转换成红利ETF等。
2024-10-05
24年涨了百分之60,太牛了
2024-10-05
有一个问题请教一下,temp这个变量赋值后主要用来做什么呢
2024-10-05
@alfred_123 用来在附图上显示温度变化曲线,record(temp=temp)
2024-10-05