股市大跌后,关于量化小市值策略的优化!

本文介绍了一种利用行业拥挤度和市场变化来筛选股票的方法,通过调整指数选择、清仓信号阈值,优化了策略效果,提高了收益率并减少了风险。策略主要关注小市值股票的流动性风险控制,结合技术指标如BOLL带进行买卖决策。
摘要由CSDN通过智能技术生成

几年前光伏锂电赛道股崩盘时,大家总结出带有一致性底色的反转因子——行业拥挤度。随着今年初微盘股暴跌暴露出小市值低流动性的特点,一致性信号的挖掘研究对小市值风控有很大意义。

调整处:
1、指数牛熊开关采用上证综指,考虑选股持仓为深市中小板,调整成全A指数。
2、清仓信号跌幅阈值调整。

效果:
年化从54.68%提高至66%,峰值回测从24.6%降低至21.4%。参考在23年11月后空仓时间较多,可能是影响收益的重要原因。

#一致性筛选
from jqdata import *
from jqfactor import get_factor_values
from jqlib.technical_analysis import *
import numpy as np
import pandas as pd
import statsmodels.api as sm
import datetime
import talib

# 过滤停牌股票
def filter_paused_stock(stock_list,last_date):
    return [stock for stock in stock_list if get_price(stock,end_date = last_date, count = 1,fields = 'paused')['paused'][0]==0]

# 2-2过滤ST及其他具有退市标签的股票
def filter_st_stock(stock_list,last_date):
    return [stock for stock in stock_list 
        if True not in get_extras('is_st',stock, start_date=last_date, end_date=last_date, df=False).values() 
        and 'ST' not in get_security_info(stock).display_name 
        and '*' not in get_security_info(stock).display_name 
        and '退' not in get_security_info(stock).display_name]

#2-6 过滤科创北交股票
def filter_kcbj_stock(stock_list,last_date):
    for stock in stock_list[:]:
        #if stock[0] == '4' or stock[0] == '8' or stock[:2] == '68' or stock[:3] == '300' or stock[:3] == '301':
        if stock[0] == '4' or stock[0] == '8' or stock[:2] == '68':
            stock_list.remove(stock)
    return stock_list

#2-7 过滤次新
def filter_new_stock(stock_list,days,last_date):
    return [stock for stock in stock_list if not last_date - get_security_info(stock).start_date < datetime.timedelta(days=days)]


def min_consistency_check(date,signal,mini_cosi_list):
    
    
    today_date = date
    lastd_date = get_trade_days(end_date=today_date, count=2)[-2]
    
    #0,增加基准指数的牛(关)熊(开)判断,1-年线上下
    #df_index = get_price('000001.XSHG', end_date=lastd_date, frequency='1d', fields='close',count=240, panel=False)
    #中证全指
    df_index = get_price('000985.XSHG', end_date=lastd_date, frequency='1d', fields='close',count=250, panel=False)
    #国证2000
    #df_index = get_price('399303.XSHE', end_date=last_date, frequency='1d', fields='close',count=240, panel=False)
    
    if df_index['close'].values[-1] >df_index['close'].values.mean():
        print('牛市,关闭一致性检查')
        return False, mini_cosi_list
    else:
        print('熊市,打开一致性检查')
    
    
    #1,取昨天的30天以上Min500(10%),去除ST
    stocklist = list(get_all_securities(['stock']).index)   #取all
    
    num1 = len(stocklist)   
    #print('所有股票数:', num1)
    #stocklist = [stockcode for stockcode in stocklist if not all_data[stockcode].paused]
    #stocklist = [stockcode for stockcode in stocklist if not all_data[stockcode].is_st]
    #stocklist = [stockcode for stockcode in stocklist if'退' not in all_data[stockcode].name]
    #stocklist = [stockcode for stockcode in stocklist if stockcode[0:3] != '688']
    #stocklist = [stockcode for stockcode in stocklist if (today_date-get_security_info(stockcode).start_date).days>20]
    stocklist = filter_paused_stock(stocklist,lastd_date)
    stocklist = filter_st_stock(stocklist,lastd_date)
    stocklist = filter_kcbj_stock(stocklist,lastd_date)
    stocklist = filter_new_stock(stocklist,250,lastd_date)
    
    
    #stocklist = [stockcode for stockcode in stocklist if (today_date-get_security_info(stockcode).start_date).days>250]
    num2 = len(stocklist)
    #print('实际交易股票数:', num2)
    
    df_all = get_price(stocklist, end_date=lastd_date, frequency='1d', fields='money',count=1, panel=False)
    
    q = query(valuation.code, valuation.market_cap).filter(valuation.code.in_(stocklist)).order_by(valuation.market_cap.asc())
    df = get_fundamentals(q)
    
    #num3 = round(0.05*num1) #原作数据
    num3 = round(0.2*num2) 
    stocklist = list(df['code'])[:num3]
    print('总样本数:', num3)
    
    #2,计算昨天的涨幅均值和方差,以及落在Mean+2方差内的
    df_chg = get_money_flow(stocklist, end_date=lastd_date, fields='change_pct', count=1)
    #log.info(df_chg)
    chg_med = np.median(df_chg.change_pct)
    chg_std = np.std(df_chg.change_pct)
    #log.info(chg_mean,chg_std)
    
    df_temp = df_chg[(df_chg.change_pct < (chg_med+chg_std)) & (df_chg.change_pct > (chg_med-chg_std))]
    num4 = len(df_temp)
    
    cosistency_last = num4/num3
    mini_cosi_list.append(cosistency_last)
    print('列表长度'+str(len(mini_cosi_list)))
    
    
    
        
    if len(mini_cosi_list) >=120:
        cosistency_mean = np.mean(mini_cosi_list[-120:])
        cosistency_std = np.std(mini_cosi_list[-120:])
        mini_cosi_list = mini_cosi_list[-120:]
    else:
        cosistency_mean = 0.8
        cosistency_std =0.05
    
    cosistency_upper = cosistency_mean+cosistency_std
    
    
    #使用BOLL带判断
    if (chg_med <-3 and cosistency_last>=cosistency_upper):
    #if (chg_med <-3 and cosistency_last>=cosistency_upper):# or (chg_med <-4 and num4/num3>0.84) or (chg_med <-6 and num4/num3>0.82) :
        print('清仓')
        return True, mini_cosi_list
    elif (chg_med >2 and cosistency_last>=cosistency_mean):
        print('满上')
        return False, mini_cosi_list
    else:
        print('照常,信号为False')
        
        return False, mini_cosi_list
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值