Warning: file_exists(): open_basedir restriction in effect. File(/www/wwwroot/com.xiximiao.oa/com.cmstop/public/www/wp-content/db.php) is not within the allowed path(s): (/www/wwwroot/com.xiximiao.oa/com.cmstop/public/www/:/tmp/:/proc/:/var/log/nginx/:/www/wwwroot/com.xiximiao.oa/com.cmstop/public/:/www/wwwroot/com.xiximiao.oa/com.cmstop/vendor/:/www/wwwroot/com.xiximiao.oa/com.cmstop/ppk/) in /www/wwwroot/com.xiximiao.oa/com.cmstop/public/www/wp-includes/load.php on line 707
2418 沪深 300 三态估值成长轮动策略 实例说明白马股攻防转换策略 50043 » 轻知量化 QMT、PTrade、聚宽策略分享交流平台

2418 沪深 300 三态估值成长轮动策略 实例说明白马股攻防转换策略 50043

市场温度自适应多因子轮动策略,核心逻辑如下:
  1. 三态市场判断体系
  • 温度标尺:基于沪深 300 指数 220 日区间位置,划分 "cold/warm/hot" 三种市场状态
  • cold 状态:指数位于历史前 20% 低位区间
  • hot 状态:指数创 60 日新高且突破前高 20%
  • warm 状态:介于两者之间的正常波动区间
  1. 动态因子筛选机制
  • cold 市场配置:
    • 深度价值:PB<1,现金流 / 净利润> 2 倍
    • 盈利质量:ROA/PB 比率排序,侧重低估值稳盈利
  • warm 市场配置:
    • 合理成长:PB<1,利润同比正增长,现金流覆盖盈利
    • 平衡选择:ROA/PB 综合排序,兼顾估值与成长性
  • hot 市场配置:
    • 成长追击:PB>3,净利润同比增速 > 20%
    • 动量强化:ROA 绝对排序,捕捉高增长赛道
  1. 组合管理规则
  • 严格风控:排除 ST / 次新 / 涨跌停个股,限定沪深 300 成分股
  • 分散持仓:等权重配置 5 只个股,月度调仓频率
  • 智能调仓:自动卖出非名单内个股,保留涨停持仓
  1. 风险控制体系
  • 状态熔断:极端市场自动切换配置模式
  • 流动性保护:限定主板交易品种,过滤微小市值
  • 安全边际:cold 市场要求现金流两倍覆盖利润,防范财务风险

策略代码

# 导入函数库
from jqdata import *

# 初始化函数,设定基准等等
def initialize(context):
	# 设定沪深300作为基准
	set_benchmark('000300.XSHG')
	# 开启动态复权模式(真实价格)
	set_option('use_real_price', True)
	#防止未来函数
	set_option("avoid_future_data", True)
	# 输出内容到日志 log.info()
	log.info('初始函数开始运行且全局只运行一次')
	# 过滤掉order系列API产生的比error级别低的log
	log.set_level('order', 'error')
	

	# 股票池
	g.buy_stock_count = 5
	g.check_out_lists = []
	g.market_temperature = "warm"
	
	### 股票相关设定 ###
	set_order_cost(OrderCost(close_tax=0.001, open_commission=0.00012, close_commission=0.00012, min_commission=5),
				   type='stock')
	
	# 开盘前运行
	run_monthly(before_market_open, 1, time='5:00', reference_security='000300.XSHG')
	run_monthly(my_trade, 1, time='9:45', reference_security='000300.XSHG')
	# 收盘后运行
	run_daily(after_market_close, time='after_close', reference_security='000300.XSHG')


## 开盘时运行函数
def my_trade(context):
	# 买卖
	adjust_position(context, g.check_out_lists)

## 收盘后运行函数
def after_market_close(context):
	log.info('#########################################################################################\n\n')


# 自定义下单
# 根据Joinquant文档,当前报单函数都是阻塞执行,报单函数(如order_target_value)返回即表示报单完成
# 报单成功返回报单(不代表一定会成交),否则返回None
def order_target_value_(security, value):
	if value == 0:
		log.debug("卖出 %s" % (get_name(security)))
	else:
		log.debug("买入 %s ,市值: %f" % (get_name(security), value))

	# 如果股票停牌,创建报单会失败,order_target_value 返回None
	# 如果股票涨跌停,创建报单会成功,order_target_value 返回Order,但是报单会取消
	# 部成部撤的报单,聚宽状态是已撤,此时成交量>0,可通过成交量判断是否有成交
	return order_target_value(security, value)


# 开仓,买入指定价值的证券
# 报单成功并成交(包括全部成交或部分成交,此时成交量大于0),返回True
# 报单失败或者报单成功但被取消(此时成交量等于0),返回False
def open_position(security, value):
	order = order_target_value_(security, value)
	if order != None and order.filled > 0:
		return True
	return False


# 平仓,卖出指定持仓
# 平仓成功并全部成交,返回True
# 报单失败或者报单成功但被取消(此时成交量等于0),或者报单非全部成交,返回False
def close_position(position):
	security = position.security
	order = order_target_value_(security, 0)  # 可能会因停牌失败
	if order != None:
		if order.status == OrderStatus.held and order.filled == order.amount:
			return True
	
	return False


# 交易
def adjust_position(context, buy_stocks):
	for stock in context.portfolio.positions:
		current_data = get_current_data()
		nosell_1 = context.portfolio.positions[stock].price >= current_data[stock].high_limit
		sell_2 = stock not in buy_stocks
		if sell_2 and not nosell_1:
			log.info("调出平仓:[%s]" % (stock))
			position = context.portfolio.positions[stock]
			close_position(position)
		else:
			log.info("已持仓,本次不买入:[%s]" % (stock))

	# 根据股票数量分仓
	# 此处只根据可用金额平均分配购买,不能保证每个仓位平均分配
	position_count = len(context.portfolio.positions)
	if g.buy_stock_count > position_count:
		value = context.portfolio.cash / (g.buy_stock_count - position_count)
		
		for stock in buy_stocks[:g.buy_stock_count]:
			if stock not in context.portfolio.positions:
				if open_position(stock, value):
					if len(context.portfolio.positions) >= g.buy_stock_count:
						break

# # 通过代码返回股票名称
def get_name(stk):
    return get_security_info(stk).display_name+':'+stk[:6]

关键函数解锁后查看:

2025-02-25
⚠️
本站资源大多来自网络,仅供网友学习交流,未经作者或上传书面授权,请勿作他用。
站长 vx: xiangyin615 或者 留言反馈 ,我们将尽快处理。
Notice: When you of the legal rights be violate, please stir to vx: xiangyin615
个人中心
购物车
优惠劵
搜索