QQ技术群
191103786
微信公众号
客户反馈
(86) 021-36359360-707

对外合作
(86) 021-36359360-511

商务邮箱
business@chinascope.com

技术支持
api@chinascope.com
证券基本面行情服务 深度分析服务 文本分析服务

API股票实战(python篇)

对于股票投资,大部分的非IT行业的市场管理人员和金融工作者都是没有任何编程基础的。同时,更多的普通投资者,在购买股票、基金等等的时候,也迫切需要一些专业的数据分析知识和数据,而不是单纯靠经验或者仅仅猜测。随着大数据时代的到来,专业的股票数据API接口应运而生,不需要高深的编码,简单的接口调用即可以获得想要的数据。



本次关于股票的所有历史数据均来自--数库开发者中心的API接口(http://developer.chinascope.com/),该接口覆盖了17000多家公司基本面数据、上市公司财报、千万份公告研究报告、数百个财经新闻、行业宏观资讯、社交媒体、所有的公募基金、股票行情数据等等,数库还将源数据从财务、业务、股东以及事件等纬度进行标准化的处理,使得用户可以实现跨市场、跨区间的比较分析。



本次python分析仅获取数库API里面的股票数据。# Python version: 3.5.x



一开始让我们来安装下本次股票分析所需的模块,这里强烈推荐大家使用jupyter notebook,即时调试,交互式进行,非常方便。



pip install jupyter
pip install numpy
pip install pandas
pip install seaborn

Pip安装好之后,首先当然是导入我们需要的模块了
from urllib import request as http
from urllib.parse import urlencode
import base64
from hashlib import sha1
from hmac import new as hmac
import json
from datetime import datetime
import time
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
from pandas.io.json import json_normalize
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('whitegrid')
%matplotlib inline
from multiprocessing import Pool



这里我们把接入API所需的参数准备好(主要是access_key和secret_key^^):(点击查看 “如何调用数库API” )



def create_token(access_key,secret_key):
    t = str(time.time())
    if sys.version > "3":
        token = base64.encodebytes(hmac(
            bytearray('%s,%s,%s'%(access_key,t,secret_key),'utf-8')s, digestmod=shdiget())[:-1]
    else:
        token = base64.encodestring(hmac("%s,%s,%s" % (access_key, t, secret_key), digestmod=sha1).digest())[:-1]
return t,token
access_key = '** 您的access key **'
secret_key = '** 您的secret key **'
t,token = create_token(access_key,secret_key)
headers = {'access_key':access_key,'t':t,'token':token}
        

设定下分析的时间:
###开始及结束时间,这里我们取最近一年的数据
end = datetime.now()
start = datetime(end.year - 1,end.month,end.day)



以万科a(股票代码:000002)为例,如果要获取它的历史行情,只需要访问股票行情数据中的股票日度行情历史数据(http://developer.chinascope.com/doc/api/1?id=18),输入股票代码及始末时间获得相应接口链接,把获取到的json数据转化为pandas格式



def get_day_hq(code):
    url = 'http://api.ichinascope.com/api/hq/stock/price/daily'
    params = {'code': code, 'adjusted': 'f', 'from': start, 'to': end}
    req = http.Request(url+'?%s'%urlencode(params),headers=headers)
    data = http.urlopen(req).read()
    if isinstance(data,bytes):
        result = json.loads(data.decode('utf-8'))
    else:
        result = json.loads(data)
    return result
result = get_day_hq('000002')
stock_datas = json_normalize(result['message']).set_index('dt')
        


让我们来看看一年的数据信息:
stock_datas.describe()




画一下每日收盘价的走势图
stock_datas['close'].plot(legend=True,figsize=(10,4))



每日成交量的走势图:
stock_datas['vol'].plot(legend=True,figsize=(10,4))



看看股票分析技术派们最喜欢的移动平均线图,是不是跟平时在各大股票APP上看到的一样漂亮!!! (PS:股票APP可以试试数库自主研发的“智投”APP哦 ~ 每日扫盘功能非常强大!!!)
stock_datas[['close','ma.MA5','ma.MA10','ma.MA20']].plot(figsize=(10,4))



每日涨跌幅图,可以以此判断下股票的活跃程度,下图就能看出万科的活跃度不错
stock_datas['inc'].plot(figsize=(10,4),legend=True)



这里我们改变一下线条的类型(linestyle)以及加一些标记(marker)
stock_datas["inc"].plot(figsize=(10,4),legend=True,linestyle="--",marker="o")



再来瞧瞧核密度评估图吧,这里plot一下
sns.distplot(stock_datas["inc"].dropna(),bins=100)



下面我们来看下同行业股票之间的相关性,通过jointplot这个函数,可以画出两两公司之间的“相关性系数”,或者说皮尔森相关系数,某些时候时候我们可以通过大数据之间的相关性来预测相关股票接下来的走势,# 先随机取房地产行业四支股票:海德股份(000567)\绿景控股(000502)\中关村(000931)\广宇集团(002133),再来单独获取下每个公司的涨跌幅记录
stock_lis = ['000567','000502','000931','002133']
stock_67 = json_normalize(get_day_hq('000567')['message'])['inc']
stock_02 = json_normalize(get_day_hq('000502')['message'])['inc']
stock_31 = json_normalize(get_day_hq('000931')['message'])['inc']
stock_33 = json_normalize(get_day_hq('002133')['message'])['inc']
sns.jointplot(stock_31,stock_31,kind='scatter')



皮尔森相关系数的值在-1到1之间,1代表正相关,-1代表负相关,0代表没有任何相关性。如上散点图所示,我们画出的是中关村与中关村自己的皮尔森相关系数,当然是1啦!下面我们挨个画出4家公司之间的系数图,比较出来发现绿景控股(000502)和中关村(000931)的prarsonr值最高为0.69,根据这点可以反复比较找出行业内相关性最高的两只股票进行观察。sns.jointplot(stock_02,stock_31,kind='scatter')



下面来说说风险控制这一块,比如推测哪支股票风险高~~
先来算下每支股票的涨幅平均值:
###平均值
mean_lis = [stock_02.mean(),stock_31.mean(),stock_33.mean(),stock_67.mean()]
print(mean_lis)
结果如下:
[-0.17094262295081963, -0.087704918032786877, -0.011762295081967116, 0.1770901639344262]



其次算下每支股票的标准差,其中标准差越大,变动的程度就越大,代表回报远离过去平均值,回报较不稳定故风险就越高:
###标准差
std_lis = [stock_02.std(),stock_31.std(),stock_33.std(),stock_67.std()]
print(std_lis)
结果如下:
[3.3064271388732984, 2.477871875604118, 3.4355201846516081, 3.8263880367096683]



最后就是采用画图比较:
###点的大小
area = np.pi *20

###分别以平均值,标准差为xy轴
plt.scatter(stock_mean,stock_std)

###分别设定xy轴的标注
plt.xlabel("Expected Return")
plt.ylabel("Risk")

for label,x,y in zip(stock_lis,mean_lis,std_lis):
    plt.annotate(
        label,
        xy = (x,y),xytext = (50,50),
        textcoords = "offset points",ha = "right",va = "bottom",
        arrowprops = dict(arrowstyle = "-",connectionstyle ="arc3,rad=-0.3")
    )
            



结果如下所示,可以看出002133(广宇集团)的预计收益要远高于其他三家公司,但是风险值也要高于其他三家公司



前面简单的分析了下股票数据的几种调用与比较,下面来看看如何应用API数据进行简单的选股。
让我们来假设,你是刚进入股市的新手,KDJ、MACD指标等等技术还不明确,又打算进行中长线投资,那么可以采用这么个策略:根据接口数据筛选出前一日收盘价与近一
年历史最低股价相差不多的股票,既然是在底部,即使还会再跌,长期来看肯定有上涨的时候~
首先导出所有的股票代码
(证券列表参考接口:http://developer.chinascope.com/doc/api/1?id=250

def get_code_list():
    url = 'http://api.ichinascope.com/api/stock/list'
    req = http.Request(url,headers=headers)
    data = http.urlopen(req).read()
    content = json.loads(data.decode('utf-8'))
    sh_code = []
    for i in content['message']:
        if i['market_code']=='1001' and 'T'not in i['tick']:
            sh_code.append(i['tick'])
    return sh_code
            


其次筛选出前一日的停牌股
(个股停牌参考接口:http://developer.chinascope.com/doc/api/1?id=235
def halt_stock(code):
    url = 'http://api.ichinascope.com/api/stock/delist'
    params = {'code': code, 'dt': '2016-12-06'}
    req = http.Request(url+'?%s'%urlencode(params),headers=headers)
    data = http.urlopen(req).read()
    if json.loads(data.decode('utf-8'))['message'] == []:
        return True
            


然后根据日行情数据计算出每日收盘价的最低值及前一天的股价,两两相差,找出差价在0.3以内的(最大差价可自行定义)股票代码:
def get_min_code(code):
    try:
        datas = get_day_hq(code)['message']
        if datas != [] and datas != None:
            if halt_stock(code):
                hq_c = json_normalize(get_day_hq(code)['message'])['close']
                c_min = float(hq_c.min())
                c_last = float(hq_c.tail(1).values)
                balance = c_last - c_min
                if balance < 0.3:
                    print(c_last, c_min,  '%.2f'%balance,code)
    except Exception as e:
        print(e,code)

    这里我们采用多进程快速地筛选出符合条件的股票代码:
if __name__ == '__main__':
    pool=Pool()
    pool.map(get_min_code,get_code_list())
            




当当,结果就出来啦:



最后,排除掉前一日刚发行的新股603033,排除掉股价太低差价相对来说比较高的股票,再根据财务基本面最终找到你要投资的股票代码。
当然啦,在股市摸索很多年的普通股民或者专业投资者都有自己的策略,完全可以通过API导出各种数据来验证您的策略是否正确。



PS:以上jupyter部分图表分析引用原英文官方文档:
http://nbviewer.jupyter.org/github/jmportilla/Udemy-notes/blob/master/Data%20Project%20-%20Stock%20Market%20Analysis.ipynb