我认为这是Python又一次炫技,但是我没有证据
以前说30岁前不碰股票,但随着对于一些投资理财类书籍的学习和了解,不再满足于定投基金这样的操作,于是拿出了一部分钱,做起了在股市里搏杀的实验,每每想起开户那一刻,都有一种电视剧《大时代》里方展博在交易所拥抱阿梅的遐想,当日恒生指数反弹上涨 4000多点。(当然,这只是剧情需要)
那该买什么样的股票呢?必有其策略,如果人可以通过策略实现选股,那便可以用 Python 遍历实现又快又好地选出目标标的,有策略的落地更有效率。
一、策略拆解
但凡策略,背后就有其理论。无论是价值投资,还是市盈率法,亦或者基本面分析,都需要拆解成可操作的指标。今天要分享的策略实现,我们姑且称之为“庄股理论”,意指找出庄家“挟持”的股票标的,跟着庄家吃点汤,获点小利。(友情提示:投资有危险,入市需谨慎。本例,仅作为 python 选股示例,目标标的不构成投资建议)
庄股理论(你可以不认可此理论,此处仅作为策略拆解示例)认为,一个被庄家挟持的股票,必然存在以下阶段:
阶段一:吸筹阶段
定义其在 8个交易日内,有且仅有 2-4个涨停板
阶段二:洗盘阶段
定义其40个交易日内,整体跌幅在-20%~-35%之间
阶段三:拉升阶段
定义其在 2 个交易日内,日均成交额是吸盘阶段日均成交额的 3 倍,且呈上升趋势
拆解完策略(当然我这里写的过于简单,实际拆解策略的环节其实是比较复杂的,需要反复研究理论并打磨,甚至还需要找相关专业人士沟通,有点开发沟通需求的意思)
二、用Python如何具体实现?
一些网站或接口已经整理好了此类我们需要的信息,我们不需要重复造轮子,只需要去调用相应的接口即可,此处使用tushare包,在社区(https://tushare.pro/)简单注册即可(部分接口数据可能需要一点积分,不算要求太高,比较容易获得)
1.参照数据接口的提示,调用 tushare中我们需要的数据
2.实现策略拆解中的详细定义,简单讲就是利用 pandas 按目标条件筛选
3.剔除掉一些新上市(一年内)、退市或者暂停
4.打印选出来的股票代码
说明:由于该策略过于保守,可能很多时候并不会有合适标的入选
5.对选出的股票进行跟踪,验证策略的有效性及后续进行跌代
比如说,一开始,我没有对次新股做剔除,也没有对入选前的一段时间做涨跌停限制,选出了一只次新股,新诺威(SZ:300765)。
虽然再代码选出当日涨了 4%,但随后一段时间的表现并没有如我所料想的那样,庄家带资拉起来。(次新股大概率不太可能)
当然,我也并没有对选出的股票做出买入操作,也就没有什么损失。这里提一下的目的,仅仅是想说,策略是需要持续拿结果数据验证和不断迭代的。比如说去修改我们做出的操作性指标定义,去把交易日范围缩小,把涨跌幅限制扩大一点等等。不过这些改动,最终要合乎理论。甚至说,我们去放开一点,用 python 限定结果,在结合人工干预的方式来选择合适的股票,这些都是可以操作的。
三、后记
Python 选股本身并没有不玄乎或者对技术本身有多高的要求,反而是很简单的 python 水平对现实的一点改造,提高选取股票的效率。或许你对我所举例的策略并不认可(哈哈,其实我也不是很认可,主要是帮朋友实现这一个策略而已),不妨思考以下,将自己认可的投资理财理论,结合数据,去做一些技术上的实现。
在股票界,曾经看到过一句话:“技术分析事后看永远是对的。”那股票技术分析到底可靠么?其实这个问题很多人争得你死我活,各有说辞,也不能简单地去判断对错。在我认为技术分析的本质是搏概率,提效率。通俗的讲,技术分析的方法就是根据策略,提高选股效率,拉升胜率。
其实,策略和技术,不是简单的结合,而是有机的、深度的结合。从效率角度,我对于“科技是第一生产力”是毫不怀疑的。但就算是99%的胜率,只要不是100%,就有可能失败。
在运用技术分析的时候,用什么策略不是关键,关键是你认定了一个指标之后,愿不愿去深度研究,降低风险。最终,能否赚钱取决于自己是否低风险介入。
再次提醒:投资有风险,入市需谨慎!
叶老师个人Vx:monkeyye9201,对商业分析感兴趣盆友,可加老师Vx交流。
完整代码参考如下:
# 导入相关包 import tushare as ts import pandas as pd import numpy as np import time import datetime # tushare_pro token设置 ts.set_token(your token) pro = ts.pro_api() # 股票列表,方便获取所有股票代码 df = pro.stock_basic(exchange='', list_status='L', fields='ts_code,symbol,name,area,industry,fullname,\ enname,market,exchange,curr_type,list_status,list_date,delist_date,is_hs') last_date=(datetime.datetime.now()+datetime.timedelta(days=-365)).strftime('%Y%m%d') # 仅筛选上市公司,退市或暂停上市的不管 df_filter=df[df['list_status']=='L'] # 对近一年内上市的股票进行剔除,即剔除次新股 df_filter=df_filter[df_filter['list_date']=10] pre_cnt=df_pre['交易日期'].count # 计算涨停板的个数 df_xc=df_xc[df_xc['涨跌幅 (未复权)']>=10] zt_cnt=df_xc['交易日期'].count() if pre_cnt<1: if zt_cnt>=2 | zt_cnt<=4: # 符合条件,加入候选名单 stock_xc.append(i) # 再行判断是否满足条件2 end_close=df_xp[0:1]['收盘价'].values[0] # 结束日收盘价 start_open=df_xp[-1:]['开盘价'].values[0] #初始日开盘价 rate=(end_close-start_open)/start_open if rate>=-0.35 and rate<=-0.20: stock_xp.append(i) amount_pull_mean=df_ls['成交额 (千元)'].mean() amount_xc_mean=df_xc['成交额 (千元)'].mean() df_xc['方向']=df_xc['涨跌额'].apply(lambda x: -1 if x<0 else 1 ) up_avg=df_xc['方向'].count if amount_pull_mean>=3*amount_xc_mean and up_avg==1: stock_ls.append(i) # print("真棒!百里挑一选出了一支股票:"+ i) else: pass else: pass else: pass time.sleep(0.1) #积分有限,调用次数有限,其实可以每次请求当日数据执行到数据,减少请求 else: pass except: pass if len(stock_ls)==0: print("很遗憾,今天没有合适的标的,不如明天再来试试看!") else: for code in stock_ls: print("恭喜你,百里挑一撸了一只:"+code) print("everything is ok")