策略名称:股息率+均线选股策略
策略说明:
本策略结合股息率和均线技术指标,通过筛选高股息率股票并结合价格与均线的相对位置进行交易决策。策略的核心思想是选择分红稳定且股息率较高的股票,并在价格突破均线时买入,以实现稳健的收益。
策略核心逻辑:
1. **股票池筛选**:
- 从沪深300成分股中筛选出符合条件的股票。
- 通过财务数据(如净利润、市盈率等)初步筛选股票。
2. **股息率筛选**:
- 计算过去三年的现金分红总额,并筛选出分红稳定且股息率较高的股票。
- 要求过去一年的分红总额超过市值的2%,过去两年和三年分红总额分别超过市值的1.6%和1.28%。
3. **均线筛选**:
- 计算股票的30日均线,并筛选出当前价格高于30日均线的股票。
4. **交易决策**:
- 根据筛选结果,将资金平均分配到符合条件的股票中。
- 如果持仓股票不再符合筛选条件,则卖出。
策略特点:
- **高股息率**:通过筛选高股息率股票,获取稳定的分红收益。
- **均线突破**:结合均线技术指标,选择价格处于上升趋势的股票。
- **动态调仓**:定期调整持仓,确保持仓股票符合筛选条件。
适用场景:
- 适用于追求稳健收益的投资者,能够通过高股息率和均线突破获取稳定的收益。
- 适合中长期投资,通过定期调仓降低风险。
风险提示:
- 高股息率股票可能存在业绩下滑的风险,需定期监控财务数据。
- 均线突破策略在震荡市中可能产生较多的交易信号,增加交易成本。
策略代码结构:
1. **初始化函数(`initialize`)**:
- 设定基准指数(沪深300)。
- 配置交易手续费和滑点。
- 定义每月运行的函数。
2. **股票池筛选函数(`getBigStocks`)**:
- 从沪深300成分股中筛选出符合条件的股票。
3. **股息率筛选函数(`controlReport`)**:
- 计算过去三年的现金分红总额,并筛选出分红稳定且股息率较高的股票。
4. **均线筛选函数(`setSmallStocks`)**:
- 计算股票的30日均线,并筛选出当前价格高于30日均线的股票。
5. **交易决策函数(`orderStock`)**:
- 根据筛选结果,将资金平均分配到符合条件的股票中。
- 如果持仓股票不再符合筛选条件,则卖出。
6. **参数设置函数(`set_param`)**:
- 设置策略参数,如股票数量、手续费等。
---
策略优化建议:
1. **参数优化**:
- 可对股息率筛选条件(如分红比例、市值要求)进行优化,以适应不同的市场环境。
- 调整均线计算周期(如30日、60日),以更好地捕捉市场趋势。
2. **风险控制**:
- 增加止损机制,避免在极端行情中遭受过大损失。
- 设置最大回撤限制,当回撤超过一定比例时暂停交易。
3. **多因子结合**:
- 可结合其他财务指标(如ROE、资产负债率等)进行综合筛选,提高策略的稳定性。
---
总结:
本策略通过高股息率和均线突破的结合,实现了对稳健收益的追求,能够在中长期投资中有效管理仓位,降低风险。策略逻辑清晰,适合有一定编程基础的投资者进行进一步优化和实盘测试。
策略代码
# 标题:超稳的股息率+均线选股策略
# 作者:策略人生
# 标题:自带仓位控制的股息率策略,超稳
# 作者:只看年报来投资
# 导入函数库
from jqdata import *
import pandas as pd
import numpy as np
# 初始化函数,设定基准等等
def initialize(context):
set_param()
run_monthly(main,1,time='9:30')
def main(context):
#1、设置大股票池,返回df,包括code、statDate
df=getBigStocks()
#2、财报质量控制,返回code,lrzl,yszzl,zcfzl,ejdtb,ejdhb
df=controlReport(df)
#3、设置下单列表
setSmallStocks(df)
#4、下单
orderStock(context)
#1、设置大股票池,返回df,包括code、statDate
def getBigStocks():
stocks = get_index_stocks('000300.XSHG')
q=query(
income.statDate,
income.code
).filter(
#income.net_profit>100000000,
valuation.pe_ratio>0,
income.code.in_(stocks)#,
#income.code.in_(['601918.XSHG','601899.XSHG','601958.XSHG','600170.XSHG',
# '600631.XSHE','600585.XSHG','600023.XSHG','000333.XSHE','002157.XSHE',
# '600104.XSHG'])
)
rets=get_fundamentals(q)#.reset_index(drop=True)
return rets
def controlReport(df):
df_qc=pd.DataFrame()
for i in range(0,len(df)):
statDate=df.loc[i].statDate
q=int(int(statDate[5:7]) / 3)
year=int(statDate[:4])
statqs=[]
for kk in range(0,12):
statq=str(year) + 'q' + str(q)
statqs.append(statq)
q=q -1
if q==0 :
q=4
year= year - 1
code=df.loc[i].code
#只看现金分红
gx=finance.run_query(query(finance.STK_XR_XD.bonus_amount_rmb,finance.STK_XR_XD.report_date).filter(
finance.STK_XR_XD.code==code,
finance.STK_XR_XD.report_date<=statDate ).order_by(finance.STK_XR_XD.report_date.desc()).limit(12)) gx=gx.fillna(0) #统计分红 one_year=0.0 two_year=0.0 three_year=0.0 for j in range(0,len(gx)): report_date=gx.loc[j].report_date q=report_date.month//3 year=report_date.year statq=str(year) + 'q' + str(q) if statq in (statqs[0],statqs[1],statqs[2],statqs[3]): one_year=one_year+gx.loc[j].bonus_amount_rmb if statq in (statqs[4],statqs[5],statqs[6],statqs[7]): two_year=two_year+gx.loc[j].bonus_amount_rmb if statq in (statqs[8],statqs[9],statqs[10],statqs[11]): three_year=three_year+gx.loc[j].bonus_amount_rmb #市值 qcap=query(valuation.market_cap).filter(valuation.code==code) market_cap=get_fundamentals(qcap).loc[0,'market_cap']*10000 comp_value=market_cap*0.02 if one_year>comp_value and two_year>comp_value*0.8 and three_year>comp_value*0.64 and (one_year+two_year+three_year)>market_cap*0.1:
cc=pd.DataFrame([[code,one_year/market_cap,two_year/market_cap,three_year/market_cap]],columns=['code','gxl','gxl2','gxl3'])
df_qc=df_qc.append(cc,ignore_index=True)
return df_qc.reset_index(drop=True)
