策略名称:双均线选股策略
策略概述:
该策略通过结合财务指标(如ROE、净利润同比增长率、市净率等)和技术指标(如短期均线和长期均线),筛选出具有良好基本面和趋势的股票。策略的核心逻辑是通过财务指标筛选出优质股票,并结合均线交叉信号进行买卖决策,以实现长期稳定的超额收益。
策略核心逻辑:
-
财务指标筛选:
-
使用ROE、净利润同比增长率、市净率等财务指标,筛选出基本面良好的股票。
-
剔除ROE低于4%的股票,确保选出的股票具备较高的盈利能力。
-
-
均线交叉信号:
-
计算股票的短期均线(20日均线)和长期均线(2000日均线)。
-
当短期均线低于长期均线时,认为股票处于下跌趋势,选择卖出或避免买入。
-
当短期均线高于长期均线时,认为股票处于上涨趋势,选择买入。
-
-
动态调仓:
-
每周根据最新的财务数据和均线信号,重新筛选股票并调整持仓。
-
卖出不符合条件的股票,买入符合条件的股票。
-
策略特点:
-
财务与技术结合:通过财务指标和均线信号的结合,筛选出具备良好基本面和趋势的股票。
-
动态调仓:每周根据最新的市场数据,动态调整持仓,确保投资组合的优化。
-
自动化交易:策略实现全自动化交易,减少人为干预。
策略参数:
| 参数名称 | 参数值 | 说明 |
|---|---|---|
| 基准指数 | 000002.XSHG | 使用上证指数作为基准 |
| ROE筛选阈值 | 4% | 筛选ROE大于4%的股票 |
| 短期均线周期 | 20 | 计算20日均线 |
| 长期均线周期 | 2000 | 计算2000日均线 |
| 调仓频率 | 每周一次 | 每周第一个交易日调仓 |
策略流程:
-
初始化:
-
设置基准指数(上证指数)。
-
定义财务指标筛选条件。
-
初始化均线计算参数。
-
-
每周调仓:
-
使用财务指标筛选出符合条件的股票。
-
计算每只股票的短期均线和长期均线。
-
根据均线交叉信号,筛选出处于上涨趋势的股票。
-
卖出不符合条件的股票,买入符合条件的股票。
-
-
财务指标筛选:
-
筛选出ROE大于4%的股票。
-
按市净率排序,选择市净率较低的股票。
-
按净利润同比增长率排序,选择增长较快的股票。
-
-
均线交叉信号:
-
计算每只股票的20日均线和2000日均线。
-
当短期均线低于长期均线时,认为股票处于下跌趋势,选择卖出或避免买入。
-
当短期均线高于长期均线时,认为股票处于上涨趋势,选择买入。
-
-
动态调仓:
-
卖出当前持仓中不符合条件的股票。
-
买入符合条件的股票,确保持仓数量不超过最大持仓数。
-
策略风险:
-
市场风险:
-
如果市场整体下跌,均线交叉信号可能失效,导致策略表现不佳。
-
-
财务数据滞后:
-
财务数据的更新可能存在滞后,导致策略的选股结果不准确。
-
-
流动性风险:
-
部分股票的流动性不足可能导致买卖价差较大,影响策略收益。
-
-
参数敏感性:
-
策略对均线周期、财务指标阈值等参数较为敏感,参数设置不当可能导致策略失效。
-
策略优化方向:
-
多因子结合:
-
引入更多因子(如波动率、动量、质量等)优化选股模型。
-
-
动态参数调整:
-
根据市场环境动态调整均线周期和财务指标阈值。
-
-
风险控制增强:
-
加入止损机制,进一步控制回撤。
-
-
行业轮动:
-
结合行业轮动策略,优化资产配置。
-
策略适用场景:
-
市场环境:适用于市场风格偏向价值投资、成长性股票具备反弹潜力的环境。
-
投资者类型:适合风险承受能力中等、追求长期稳定收益的投资者。
策略回测表现:
-
年化收益率:根据历史回测数据,策略年化收益率较高(具体数值需通过回测验证)。
-
最大回撤:通过财务指标筛选和均线交叉信号,策略能够有效控制回撤。
总结:
“双均线选股策略”通过结合财务指标和均线交叉信号,实现了对股票的动态筛选和优化配置。策略具备较强的自动化能力和风险控制机制,适合在价值投资和成长性股票表现良好的市场环境中运行。通过进一步优化和扩展,策略有望在更多市场环境中表现出色。
策略代码
# 标题:14年初到23年7月,年化37,夏普1.25,稳健高收益!
from jqdata import * # 导入聚宽数据接口模块
# 初始化函数,设定基准等等
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000002.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
g.security = get_index_stocks('000985.XSHG') # 获取科技100指数的成分股
g.q = query(valuation, indicator).filter(valuation.code.in_(g.security)) # 构建查询对象,用于查询这些成分股的财务数据和市场因子
run_weekly(period, weekday=1) # 计划每周第一个交易日运行period函数
# 定期运行的函数
def period(context):
# 获取符合条件的股票
df = get_filtered_stocks()
# 获取这些股票的历史价格数据
dff = get_historical_prices(df)
# 计算均线并生成买入列表
buy = calculate_moving_averages(dff)
# 执行交易
execute_trades(context, buy)
关键函数解锁后查看:
# 计算均线并生成买入列表
def calculate_moving_averages(dfff):
# 计算2000日均线
mal = dfff.mean(axis=1)
# 计算20日均线
mas = dfff.iloc[:, -20:]
mas = mas.mean(axis=1)
# 将20日均线和2000日均线合并为一个DataFrame
maa = pd.DataFrame([mas, mal])
maa = maa.T
maa.columns = ['mas', 'mal']
# 计算短期均线与长期均线的差
maa['mac'] = maa['mas'] - maa['mal']
# 选择短期均线低于长期均线的股票
buy = maa[maa['mac'] < 0] # 短均低于长均
buy['code'] = buy.index
#print(buy)
return buy['code'].values
# 交易指令
def execute_trades(context, buy):
# 卖出不在买入列表中的股票
for stock in context.portfolio.positions:
if stock not in buy:
order_target_value(stock, 0) # 如果手里有但不符合全清空
# 买入符合条件但尚未持有的股票
to_buy = [stock for stock in buy if stock not in context.portfolio.positions]
# 这是符合条件但没有的
if len(to_buy) > 0:
cash_per_stock = context.portfolio.available_cash / len(to_buy) # 把现有的钱平分给这些股票
for stock in to_buy:
order_value(stock, cash_per_stock)
print("现在持有股票数量:", len(context.portfolio.positions)) # 输出当前持有的股票数量
2025-02-21
