选股是股票交易中非常重要的一个环节,它决定了你是否能够买到有潜力的股票。在选股过程中,ROE和MA是两个非常重要的指标。
ROE
ROE是股东权益收益率的缩写,它是评估公司盈利能力的一项重要指标。ROE计算公式如下:
ROE = 净利润 / 股东权益
其中,净利润是指公司在一定时期内的净收益,股东权益是指公司所有者权益中的普通股股东权益。
通常情况下,ROE的计算周期为一年。我们可以通过查看公司的财务报表来获取净利润和股东权益的数据,然后将净利润除以股东权益即可得到ROE。
需要注意的是,ROE不是越高越好,还需要结合公司的行业和历史数据进行分析。一般来说,ROE超过15%可以被认为是一个优秀的指标,但如果行业平均ROE也很高,那么公司ROE高并不一定代表它的盈利能力很强。
MA
MA是移动平均线,它是根据股票价格的变化趋势来计算的。在股票交易中,MA可以用来判断股票的价格走势,以及预测未来的价格变化趋势。
代码概要
在使用下面提供的代码进行股票交易时,我们需要先进行股票筛选。这个函数会根据股票的ROE、流通市值等指标进行筛选,然后再进行MA的计算,以确定股票的买入点。在买入时,我们会根据当前可用资金和股票的价格来计算买入股票的数量。在卖出时,我们会根据当前股票的价格和成本价来判断是否需要卖出股票。如果股票价格跌破MA5,或者回撤5个点,或者成本损失达到5%,我们就会考虑卖出股票。
在进行股票交易时,我们需要注意一些细节。首先,我们需要过滤ST、停牌和科创股票,因为这些股票的交易风险较高。其次,我们需要过滤上市时间不满1080天的股票,因为这些股票的历史数据较少,难以准确预测价格变化趋势。最后,我们可以使用模拟交易进行实践,这样可以帮助我们更好地理解股票交易的过程,并提高我们的交易技能。
策略代码
# 股票策略模版
# 初始化函数,全局只运行一次
def init(context):
# 设置基准收益:沪深300指数
set_benchmark('000300.SH')
# 打印日志
log.info('策略开始运行,初始化函数全局只运行一次')
# 设置股票每笔交易的手续费为万分之二(手续费在买卖成交后扣除,不包括税费,税费在卖出成交后扣除)
set_commission(PerShare(type='stock',cost=0.0002))
# 设置股票交易滑点0.5%,表示买入价为实际价格乘1.005,卖出价为实际价格乘0.995
set_slippage(PriceSlippage(0.005))
# 设置日级最大成交比例25%,分钟级最大成交比例50%
# 日频运行时,下单数量超过当天真实成交量25%,则全部不成交
# 分钟频运行时,下单数量超过当前分钟真实成交量50%,则全部不成交
set_volume_limit(0.25,0.5)
# 设置要操作的股票:同花顺
context.security = '300033.SZ'
# 回测区间、初始资金、运行频率请在右上方设置
# 中小板股票池
#g.security_universe_index = '399101.SZ'
# 沪深300
#g.security_universe_index = '000300.SH'
# 股票类交易手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
# 盘间运行
# run_daily(market_open_buy, time_rule = 'after_open', hours = 0, minutes = 0, reference_security='000300.SH')
# run_daily(market_open_sell, time_rule = 'before_close', hours = 0, minutes = 5, reference_security='000300.SH')
# 收盘后运行
g.stock_list = []
g.buy_stock_num = 5
#每日开盘前9:00被调用一次,用于储存自定义参数、全局变量,执行盘前选股等
def before_trading(context):
# 获取日期
date = get_datetime().strftime('%Y-%m-%d %H:%M:%S')
# 打印日期
log.info('{} 盘前运行'.format(date))
g.stock_list = get_stocks(context)
def handle_bar(context,bar_dict):
time = get_datetime().strftime('%H:%M')
market_open_buy(context)
market_open_sell(context)
def get_stocks(context):
# stocks = get_index_stocks(g.security_universe_index)
stocklist = list(get_all_securities('stock',date = get_datetime().strftime('%Y%m%d')).index)
stocklist = stock_filter(context,stocklist)
stocklist = filter_stock_by_days(context, stocklist, 250)
stocklist = buy_point_filter(context, stocklist)
# 通过ROE倒序排列
q = query(valuation.symbol
).filter(valuation.symbol.in_(stocklist),
valuation.circulating_cap>50, # 流通市值>50
valuation.roe_ttm>0 # roe_ttm
).order_by(valuation.roe_ttm.desc()
).limit(10)
stocklist = list(get_fundamentals(q,date = get_datetime().strftime('%Y%m%d')).valuation_symbol)
print('选出%s只股票:%s' % (len(stocklist), stocklist))
return stocklist
# 买入函数
def market_open_buy(context):
if len(context.portfolio.positions) < g.buy_stock_num:
new_buy_stock_num = g.buy_stock_num - len(context.portfolio.positions)
buy_cash = context.portfolio.available_cash / new_buy_stock_num
for s in g.stock_list[:new_buy_stock_num]:
current_price = get_price(s,start_date=get_datetime().strftime('%Y%m%d')+' 14:55', end_date=get_datetime().strftime('%Y%m%d')+' 14:55', fre_step = '1m', fields = ['close'], fq = 'pre', is_panel = 1).close.item()
if s not in context.portfolio.positions and\
context.portfolio.available_cash >= buy_cash >= 100 * current_price:
order_target_value(s, buy_cash)
print('买入股票:%s' % (s))
# 卖出函数
def market_open_sell(context):
sells = list(context.portfolio.positions)
for s in sells:
loss = context.portfolio.positions[s].last_price / context.portfolio.positions[s].cost_basis
s_sell, sell_msg = check_sell_point(context, s)
if s_sell or loss < 0.95:
if context.portfolio.positions[s].available_amount>0:
order_target_value(s, 0)
print('卖出股票:%s, sell_msg=%s' % (s, sell_msg))
def buy_point_filter(context, stocks):
final_stocks = []
for stock in stocks:
s_buy = check_buy_point(context, stock)
if s_buy == True:
final_stocks.append(stock)
return final_stocks
def check_buy_point(context, stock):
import numpy as np
import datetime
s_buy = False
close_data = history(stock, bar_count = 120, fre_step = '1d', fields = ['close', 'high'], is_panel = 1)
closes = close_data['close'].values
# 取得过去五天的平均价格
ma55_list = list(np.zeros(120))
for i in range(54, 120):
ma55_list[i] = closes[i-54:i+1].mean()
# 近40天内,共有<5天大于ma55,且近3天有大于ma55的
over_55_in_40_days = np.array(closes[-40:]) > np.array(ma55_list[-40:])
num_over_55_40_days = sum(over_55_in_40_days)
ever_upcross_ma55 = sum(over_55_in_40_days[:20])
nowadays_upcross_ma55 = sum(over_55_in_40_days[-3:])
yesterday_over_ma55 = over_55_in_40_days[-1]
current_price = get_price(stock,start_date=get_datetime().strftime('%Y%m%d'), end_date=get_datetime().strftime('%Y%m%d'), fre_step = '1d', fields = ['close'], fq = 'pre', is_panel = 1).close.item()
current_ma55 = (np.sum(closes[-54:]) + current_price)/55
now_over_ma55 = current_price > current_ma55
ten_days_lowest = min(closes[-10:]) == min(closes[-60:])
if 1 <= ever_upcross_ma55 <= 3 and\
nowadays_upcross_ma55 >= 1 and\
now_over_ma55 and\
ten_days_lowest:
s_buy = True
return s_buy
def check_sell_point(context, stock):
s_sell = False
#持仓股票的当前价
current_price = get_price(stock,start_date=get_datetime().strftime('%Y%m%d')+' 14:55', end_date=get_datetime().strftime('%Y%m%d')+' 14:55', fre_step = '1m', fields = ['close'], fq = 'pre', is_panel = 1).close.item()
# 按天交易,【尾盘】跌破MA5或日内高点回撤5个点即撤
bars = get_price(stock, bar_count = 60, end_date = get_datetime().strftime('%Y%m%d'), fre_step = '1d', fields = ['high', 'close'], is_panel = 1)
closes = bars['close']
highs = bars['high']
closes[-1] = current_price
# ma3 & ma5
ma3 = closes[-3:].mean()
ma5 = closes[-5:].mean()
ma55 = closes[-55:].mean()
ma55_ = closes[-56:-1].mean()
loss = current_price / context.portfolio.positions[stock].cost_basis
high_allday = highs[-1]
# 跌破MA5 / 下跌3% / 高点回撤3% / 成本损失5%
signal1 = 0
signal2 = current_price / closes[-2] < 0.95
signal3 = current_price / high_allday < 0.95
signal4 = loss < 0.95
signal5 = current_price < ma55 * 0.98
if signal1 or signal2 or signal3 or signal4 or signal5:
s_sell = True
msg = []
if signal1:
msg.append('跌破MA5')
if signal2:
msg.append('下跌5%')
if signal3:
msg.append('高点回撤5%')
if signal4:
msg.append('总亏损5%')
if signal5:
msg.append('跌破MA55')
return s_sell, msg
##过滤上市时间不满1080天的股票
def filter_stock_by_days(context, stock_list, days):
import datetime
tmpList = []
for stock in stock_list :
days_public=(get_datetime() - get_security_info(stock).start_date).days
if days_public > days:
tmpList.append(stock)
return tmpList
##过滤ST,停牌,科创
def stock_filter(context,stock_list):
date = get_datetime().strftime("%Y%m%d")
curr_data = get_price(stock_list,end_date = date,fre_step = '1d',fields = ['open', 'high_limit','low_limit', 'is_paused','is_st'],skip_paused = False,fq = 'pre',bar_count = 1,is_panel = 1)
return [stock for stock in stock_list if not (
#(curr_data.open[stock].item() == curr_data.high_limit[stock].item()) or # 涨停开盘
#(curr_data.open[stock].item() == curr_data.low_limit[stock].item()) or # 跌停开盘
curr_data.is_paused[stock].item() or # 停牌
curr_data.is_st[stock].item() or # ST
#(stock.startswith('300')) or # 创业
(stock.startswith('688')) # 科创
)]
收益曲线

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/321258
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!