高收益的次新股买卖技巧

这篇内容探讨了投资者对新股的短期热衷及机构对有潜力的次新股的长期关注。次新股因其业绩成长性、高科技行业属性和较小的流通市值而具有投资和投机价值。文章提到了一种策略,即在新股超跌后选择市值小、估值低且业绩增长的次新股进行短线操作。此外,文中还提供了一种基于PB比率、收益率和市场资本化的量化选股策略,并通过聚宽量化平台的代码进行了展示。
摘要由CSDN通过智能技术生成

投资者往往只是热衷认购新股,一旦上市便获利了结,很少想一想这些新股中哪些是值得长线持有的。当新股的中签率越来越低,新股认购已经不能满足攫取暴利的大机构的需要时,他们便会主动停止认购新股的游戏,到二级市场抛售压力巨大的新股板块中寻找获利机会,所以一批真正有业绩有高成长性的次新股成为机构吸纳的主要对象。

次新股具有的最重要的特点,便是兼具投资投机价值。从投资角度来看,次新股大多业绩较好,又主要属于高科技成长性行业,而且许多流通规模也不大,使其具有业绩和股本的同步成长性,在市场中具有较好的活性。尤其是一些行业特殊的个股,市场炒作的朦胧题材较多。再加上次新股发行上市时所募集资金投资的系列项目,目前已进入回报期,新的利润增长点不断产生,对其业绩的大幅提高有较好的支撑作用。从投机价值看,次新股常呈现出阶段性的热点炒作,一旦大盘步入调整或市场缺乏热点时,次新股便会被主力挖出来炒作,以吸引市场人气。因此市场中的机会较多是其重要特点。

次新股的基本走势与投资策略

从过去新股的炒作来看,有一小部分新股上市后就大幅上升,这种股票对中小散户来说,只能是“望梅止渴”,并不敢杀入,但大多数新股上市后并不是马上大幅上升,而是经过一段时间后才会有较好的表现,这些股票对中小散户来说是可以参与的。中小散户如何参与这类股票的炒作,就必须对新股上市后的走势进行分析,才能做出投资决策。

次新股每一轮超跌之后,都会出现强势的反弹。为什么?因为他们流通盘小,流通市值都是在10来亿左右,有的只有5个亿、6个亿的流通市值。所以易上涨,易涨停。这是非常好的广告,自然在反弹时,吸引资金的围剿。A股是散户为主体的市场,追涨风格,重在涨得猛。次新股易上涨,波动大,涨起来易涨停,这非常吸引人。所以每一轮调整,超跌反弹都是有次新股的身影。这也是资金对炒新乐死不疲的原因。

同时,现在炒重组易被点名,炒故事股。有涨停的都是容易被点名。唯独次新股连板很少被点名,被点名时基本上都是涨了几个板的。这种点名空间大。资金炒作就大胆些。

我们股市重融资,不敢让次新太死,也有一定的心理因素。但这些还长远,规律不变条件下。超跌反弹先看次新的规律还是不会变。但注意,市场波动大,开板次新易反弹,但老次新反弹易被获利盘和套空盘、解禁盘冲击捕杀。操作上,次新股只合适短线快进快出为主。

次新股实战策略

1、选择中小板中市值最小的10只股票;
2、在这10只股票中选择估值最小、最近2个月涨幅最大的5只股票按平均仓位买入。

策略回测

策略代码(聚宽量化平台)

from jqdata import *
from kuanke.wizard import *
from abc import ABCMeta, abstractmethod


def initialize(context):
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    log.info('策略启动')


    # 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    g.strategy_manager = StrategyManager()

    ## 运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'000300.XSHG'或'510300.XSHG'是一样的)
    run_daily(timer_event, time='14:30', reference_security='000300.XSHG')

    
    
def timer_event(context):
    g.strategy_manager.timer_event(context)


#--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
class Configure(object):
    def __init__(self):
        self.select_symbol_peroid = 10
        self.use_remote_algorithm = False


class StrategyBase(object):
    def __init__(self, root, name, config):
        self.root = root
        self.name = name
        self.config = config
        self.trade_days = 0
        self.symbol_list = []
        #print('StrategyBase.__init__')
        pass
    
    # 风控管理
    @abstractmethod
    def risk_control(self, context):
        return True    
    
    
    # 选股 
    @abstractmethod
    def select_symbol(self, context):
        return []
    
    # 定时器    
    def timer_event(self, context):
        self.risk_control(context)
        self.select_symbol(context)
        
        
        
#--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
class Strategy001(StrategyBase):
    def __init__(self, root, name, config):
        StrategyBase.__init__(self, root, name, config)
        pass
    
    # 风控管理
    def risk_control(self, context):
        #print('Strategy001.risk_control %r %s' % (context.current_dt.strftime('%Y-%m-%d %H:%M:%S'), self.root.name))
        
        # TODO ...
        return True    
    
    
    # 选股 
    def select_symbol(self, context):
        if self.trade_days % self.config.select_symbol_period != 0:
            self.trade_days += 1
            return self.symbol_list
            
        self.trade_days += 1
        
        # 原始股票池
        #symbol_list = get_security_universe(context, ['000300.XSHG'], []) # 沪深300   
        #symbol_list = get_security_universe(context, ['000905.XSHG'], []) # 中证500
        symbol_list = get_security_universe(context, ['399101.XSHE'], []) # 中小板
        
        q = query(valuation.code, valuation.pb_ratio, valuation.market_cap, indicator.roe, indicator.inc_total_revenue_year_on_year, indicator.inc_operation_profit_year_on_year, indicator.inc_net_profit_year_on_year
            ).filter(
                valuation.code.in_(symbol_list))
                
        df =  get_fundamentals(q)   
        
        
        if df is None or df.shape[0] == 0:
            log.error('--------------------------------------------')
            return self.symbol_list
            
        df.rename(columns={
            'inc_total_revenue_year_on_year': 'ystb',
            'inc_operation_profit_year_on_year': 'lrtb',
            'inc_net_profit_year_on_year': 'jlrtb',
            'anon_1': 'fuzhailv'}, inplace=True)      
            
        #删除空值
        df = df.dropna(axis=0, how='all')   
        
        if self.config.use_remote_algorithm:
            # TODO ...
            pass
        else:
            #df = df[(df.roe > 4) & (df.pb_ratio > 0) & (df.pb_ratio < 15) & (df.ystb > 10) & (df.ystb < 200)].sort_values('roe', ascending=False)
            #df = df[:max(50, min(100, self.root.max_stock_count * 10))]
            
            df = df[(df.pb_ratio > 0) & (df.pb_ratio < 50) & (df.ystb > 10) & (df.ystb < 2000)].sort_values('market_cap', ascending=True)
            df = df[:10]
            
            
            if df is None or df.shape[0] == 0:
                return self.symbol_list
            
            df.index = df['code'].values
            
            chg_list = []
            for index, row in df.iterrows():
                chg_list.append(get_n_day_chg(row.code, 30))
                
            df['chg'] = chg_list
            df['1/pb_ratio'] = 1 / df['pb_ratio']
            
            #df['score'] = df[['1/pb_ratio', 'chg', 'ystb']].rank().T.apply(lambda x : x[0] * 2 + x[1] * 2 + x[2] * 1)
            #df['score'] = df[['market_cap', 'chg', 'ystb']].rank().T.apply(lambda x : x[0] * 2 + x[1] * 2 + x[2] * 1)
            df['score'] = df[['1/pb_ratio', 'chg', 'ystb']].rank().T.apply(lambda x : x[0] * 2 + x[1] * 2 + x[2] * 2)

            
            #按得分进行排序,取指定数量的股票
            df = df.sort_values('score', ascending=False)
            self.symbol_list = df.index
        
        #self.symbol_list = [symbol for symbol in self.symbol_list if n_day_chg_dayu(symbol, 90, 0.1)]
        self.symbol_list = self.symbol_list[:int(self.root.max_stock_count / len(self.root.strategy_list))] 
        
        log.info('最新信号 ==> %s' % self.name)
        for symbol in self.symbol_list:
            log.info('%s  %s' % (symbol, get_security_info(symbol).display_name))  
            
        return self.symbol_list

  
class Strategy002(StrategyBase):
    def __init__(self, root, name, config):
        StrategyBase.__init__(self, root, name, config)
        pass
    
    # 风控管理
    def risk_control(self, context):
        #print('Strategy002.risk_control %r %s' % (context.current_dt.strftime('%Y-%m-%d %H:%M:%S'), self.root.name))
        
        # TODO ...
        return True    
    
    
    # 选股 
    def select_symbol(self, context):
        if self.trade_days % self.config.select_symbol_period != 0:
            self.trade_days += 1
            return self.symbol_list
            
        self.trade_days += 1
        
        # 原始股票池
        #symbol_list = get_security_universe(context, ['000300.XSHG'], []) # 沪深300   
        symbol_list = get_security_universe(context, ['000905.XSHG'], []) # 中证500
        
        q = query(valuation.code, valuation.pb_ratio, valuation.market_cap, indicator.roe, indicator.inc_total_revenue_year_on_year, 
            indicator.inc_operation_profit_year_on_year, indicator.inc_net_profit_year_on_year
            ).filter(
                valuation.code.in_(symbol_list))
                
        df =  get_fundamentals(q)   
        
        
        if df is None or df.shape[0] == 0:
            log.error('--------------------------------------------')
            return self.symbol_list
            
        df.rename(columns={
            'inc_total_revenue_year_on_year': 'ystb',
            'inc_operation_profit_year_on_year': 'lrtb',
            'inc_net_profit_year_on_year': 'jlrtb',
            'anon_1': 'fuzhailv'}, inplace=True)      
            
        #删除空值
        df = df.dropna(axis=0, how='all')   
        
        if self.config.use_remote_algorithm:
            # TODO ...
            pass
        else:
            df = df[(df.roe > 4) & (df.pb_ratio > 0) & (df.pb_ratio < 15) & (df.ystb > 10) & (df.ystb < 200)].sort_values('roe', ascending=False)
            df = df[:max(50, min(100, self.root.max_stock_count * 10))]
            
            
            if df is None or df.shape[0] == 0:
                return self.symbol_list
                
            df.index = df['code'].values                
            
            chg_list = []
            for index, row in df.iterrows():
                chg_list.append(get_n_day_chg(row.code, 30))
                
            df['chg'] = chg_list
            df['1/pb_ratio'] = 1 / df['pb_ratio']
            
            df['score'] = df[['1/pb_ratio', 'chg', 'ystb']].rank().T.apply(lambda x : x[0] * 2 + x[1] * 2 + x[2] * 1)

            
            #按得分进行排序,取指定数量的股票
            df = df.sort_values('score', ascending=False)
            self.symbol_list = df.index
        
        self.symbol_list = [symbol for symbol in self.symbol_list if n_day_chg_dayu(symbol, 90, -0.1)]
        
        self.symbol_list = self.symbol_list[:int(self.root.max_stock_count / len(self.root.strategy_list))] 
        
        log.info('最新信号 ==> %s' % self.name)
        for symbol in self.symbol_list:
            log.info('%s  %s' % (symbol, get_security_info(symbol).display_name))  
            
        return self.symbol_list

#--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
class StrategyManager():
    def __init__(self):
        self.name = 'root'
        self.strategy_list = []
        self.max_stock_count = 10
        
        config = Configure()
        config.select_symbol_period = 10
        
        self.strategy_list.append(Strategy001(self, '次新股策略', config))
        #self.strategy_list.append(Strategy002(self, '中证500指数增强', config))
        
        
    # 定时器    
    def timer_event(self, context):
        print('\n==========================================================\n')
        
        symbol_list = []
        for strategy in self.strategy_list:
            strategy.timer_event(context)
            symbol_list.extend(strategy.symbol_list)
            
        # TODO tet    
        #log.info('大盘预测[%s]' % '上涨' if rsi_judge('000300.XSHG', '1d', 15, (50, 100)) else '下跌')
        #log.info('held symbol:%s' % symbol_list)
        self.adjust_position(context, symbol_list, self.max_stock_count)
        
    
    @staticmethod
    def adjust_position(context, pool, max_stock_count):
        cash = context.portfolio.total_value / max_stock_count #* StrategyManager.get_dynamic_turnover()
        hold_stock = context.portfolio.positions.keys()
        
        #卖出不在持仓中的股票
        for stock in hold_stock:
            if stock not in pool:
                order_target_value(stock, 0)
                
        #买入股票
        held_stock = context.portfolio.positions.keys() 
        for stock in pool:
            if len(held_stock) < max_stock_count + 1:
                order_target_value(stock, cash)

            
    @staticmethod        
    def get_dynamic_turnover():
        count = 0
        periods = [15, 30, 45, 60, 90]
        for period in periods:
            if RSI_judge_qujian('000300.XSHG', (53, 99), period):
                count += 1
                
            if RSI_judge_qujian('000001.XSHG', (53, 99), period):    
                count += 1
        
        return count / len(periods) / 2            

            
#--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+
# 获取股票股票池
def get_security_universe(context, security_universe_index, security_universe_user_securities):
    temp_index = []
    for s in security_universe_index:
        if s == 'all_a_securities':
            temp_index += list(get_all_securities(['stock'], context.current_dt.date()).index)
        else:
            temp_index += get_index_stocks(s)
    for x in security_universe_user_securities:
        temp_index += x
        
    return  sorted(list(set(temp_index)))

# 行业过滤
def industry_filter(context, security_list, industry_list):
    if len(industry_list) == 0:
        # 返回股票列表
        return security_list
    else:
        securities = []
        for s in industry_list:
            temp_securities = get_industry_stocks(s)
            securities += temp_securities
        
        security_list = [stock for stock in security_list if stock in securities]
        # 返回股票列表
        return security_list

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值