量化学习平台
文章
市场宽度
背离图
登录
注册
(股票交易模板)小市值-EPS-成长因子选股
策略
作者: 水滴
```python # 风险及免责提示:该策略由聚宽用户在聚宽社区分享,仅供学习交流使用。 # 原文一般包含策略说明,如有疑问请到原文和作者交流讨论。 # 原文网址:https://www.joinquant.com/post/36426 # 标题:(股票交易模板)小市值-EPS-成长因子选股 # 作者:大蠢驴小疯子 # 导入函数库 from jqdata import * from jqfactor import get_factor_values ''' 自建股票交易模板 模板结构: 1.initialize 初始化函数 2.before_market_open 开盘前运行函数 3.market_open 开盘时运行函数 4.after_market_close 收盘后运行函数 5.filter_stock 剔除无效股票函数 6.get_stock_list 选股策略实现函数 策略逻辑: 1.小市值策略为基础 2.每周运行一次 3.尝试不同因子选股策略(本次选择成长因子) 4.增加择时策略(暂时没有) ''' '''初始化函数,设定基准等等''' def initialize(context): '''交易系统设置''' # 设定沪深300作为基准 # set_benchmark('000300.XSHG') set_benchmark('000300.XSHG') # 开启动态复权模式(真实价格) set_option('use_real_price', True) # 打开防未来函数 set_option("avoid_future_data", True) # 输出内容到日志 log.info() log.info('初始函数开始运行且全局只运行一次') # 过滤掉order系列API产生的比error级别低的log log.set_level('order', 'error') '''股票相关设定''' # 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱 set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5),type='fund') '''自有超参设置''' # 持仓数量 g.stock_num = 5 ''' 运行相关函数''' # 开盘前运行 run_weekly(before_market_open, weekday=1, time='9:00', reference_security='000300.XSHG') # 开盘时运行 run_weekly(market_open, weekday=1, time='9:30', reference_security='000300.XSHG') # 收盘后运行 run_weekly(after_market_close, weekday=1, time='15:00', reference_security='000300.XSHG') '''开盘前运行函数''' def before_market_open(context): # 输出运行时间 log.info('函数运行时间(before_market_open):'+str(context.current_dt.time())) # 给微信发送消息(添加模拟交易,并绑定微信生效) # send_message('美好的一天~') # 构建自选股 stock_list = get_stock_list(context) stock_list = stock_list[:g.stock_num] g.security = stock_list print('今日自选股:{}'.format(stock_list)) '''开盘时运行函数''' def market_open(context): log.info('函数运行时间(market_open):'+str(context.current_dt.time())) buy_stocks = [stock for stock in g.security] '''判断当前持仓是否包含自选股中的股票''' for stock in context.portfolio.positions: if stock not in g.security: log.info("[%s]不在应买入列表中,清仓处理!" % (stock)) position = context.portfolio.positions[stock] security = position.security order = order_target_value(security, 0) # 可能会因停牌失败 else: log.info("[%s]已经持有无需重复买入" % (stock)) buy_stocks.remove(stock) print('-----------------------------------------------------------') print('剩余待买入自选股:',buy_stocks) print('-----------------------------------------------------------') # 根据股票数量分仓 # 此处只根据可用金额平均分配购买,不能保证每个仓位平均分配 buy_stocks_num = len(buy_stocks) if buy_stocks_num > 0: value = context.portfolio.cash / buy_stocks_num for stock in buy_stocks: order_target_value(stock, value) '''收盘后运行函数''' def after_market_close(context): log.info(str('函数运行时间(after_market_close):'+str(context.current_dt.time()))) #得到当天所有成交记录 trades = get_trades() for _trade in trades.values(): log.info('成交记录:'+str(_trade)) #打印账户信息 for position in list(context.portfolio.positions.values()): securities=position.security cost=position.avg_cost price=position.price ret=100*(price/cost-1) value=position.value amount=position.total_amount print('代码:{}'.format(securities)) print('成本价:{}'.format(format(cost,'.2f'))) print('现价:{}'.format(price)) print('收益率:{}%'.format(format(ret,'.2f'))) print('持仓(股):{}'.format(amount)) print('市值:{}'.format(format(value,'.2f'))) print('—————————————————一天结——————————————————') print('######################################分割线######################################') '''剔除无效股票函数''' def filter_stock(context,stock_list): ''' 参数说明: 1.stock_list 待处理股票列表 2.del_paused 剔除停牌股 3.del_st 剔除ST股 4.del_delist 剔除退市股 5.del_hl 剔除涨停股 6.del_dl 剔除跌停股 7.del_kcb 剔除科创板股 ''' current_data = get_current_data() yesterday = context.previous_date # 剔除上市不满250天的股票 stock_list = [stock for stock in stock_list if not yesterday - get_security_info(stock).start_date < datetime.timedelta(days=250)] # 剔除科创板 stock_list = [stock for stock in stock_list if stock[0:3] != '688'] # 剔除ST stock_list = [stock for stock in stock_list if not current_data[stock].is_st] stock_list = [stock for stock in stock_list if not 'ST' in current_data[stock].name] stock_list = [stock for stock in stock_list if not '*' in current_data[stock].name] stock_list = [stock for stock in stock_list if not '退' in current_data[stock].name] # 剔除停牌 stock_list = [stock for stock in stock_list if not current_data[stock].paused] # 剔除退市 # 剔除涨停 stock_list = [stock for stock in stock_list if not current_data[stock].day_open >= current_data[stock].high_limit] # 剔除跌停 stock_list = [stock for stock in stock_list if not current_data[stock].day_open <= current_data[stock].low_limit] return stock_list '''选股策略实现函数''' def get_stock_list(context): ''' 选股策略: 1.按流通市值挑选小市值股票 2.每股收益EPS>0 3.growth成长因子选股 ''' '''1.聚宽sales_growth成长因子选股''' yesterday = context.previous_date initial_list = get_all_securities().index.tolist() initial_list = filter_stock(context, initial_list) jqfactor = 'growth' score_list = get_factor_values(initial_list, jqfactor, end_date=yesterday, count=1)[jqfactor].iloc[0].tolist() df = pd.DataFrame(columns=['code','score']) df['code'] = initial_list df['score'] = score_list df = df.dropna() df.sort_values(by='score', ascending=False, inplace=True) x_list = list(df.code)[0:int(0.1*len(initial_list))] '''2.每股收益EPS和流通市值选股''' q = query(valuation.code,valuation.circulating_market_cap,indicator.eps ).filter(valuation.code.in_(x_list),indicator.eps>0 ).order_by(valuation.circulating_market_cap.asc() ) df = get_fundamentals(q) final_list = list(df.code) return final_list ```
文章分类
关于作者
水滴
注册时间: