基于均线ROE流通市值的交易策略

选股是股票交易中非常重要的一个环节,它决定了你是否能够买到有潜力的股票。在选股过程中,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'))   # 科创
            )]

收益曲线

基于均线ROE流通市值的交易策略

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

(0)
股市刺客的头像股市刺客
上一篇 2小时前
下一篇 1小时前

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注