Repository: waditu/tushare Branch: master Commit: 093856995af0 Files: 77 Total size: 446.5 KB Directory structure: gitextract_rwiezwpg/ ├── .gitignore ├── .travis.yml ├── LICENSE ├── MANIFEST ├── README.md ├── issues/ │ ├── from_email.txt │ └── from_sns.txt ├── requirements.txt ├── setup.py ├── test/ │ ├── __init__.py │ ├── bar_test.py │ ├── billboard_test.py │ ├── classifying_test.py │ ├── dateu_test.py │ ├── fund_test.py │ ├── indictor_test.py │ ├── macro_test.py │ ├── nav_test.py │ ├── news_test.py │ ├── ref_test.py │ ├── shibor_test.py │ ├── storing_test.py │ └── trading_test.py ├── test_unittest.py ├── tushare/ │ ├── VERSION.txt │ ├── __init__.py │ ├── bond/ │ │ ├── __init__.py │ │ └── bonds.py │ ├── coins/ │ │ ├── __init__.py │ │ └── market.py │ ├── data/ │ │ └── __init__.py │ ├── fund/ │ │ ├── __init__.py │ │ ├── cons.py │ │ └── nav.py │ ├── futures/ │ │ ├── __init__.py │ │ ├── cons.py │ │ ├── domestic.py │ │ ├── domestic_cons.py │ │ └── intlfutures.py │ ├── internet/ │ │ ├── __init__.py │ │ ├── boxoffice.py │ │ ├── caixinnews.py │ │ └── indexes.py │ ├── pro/ │ │ ├── __init__.py │ │ ├── client.py │ │ └── data_pro.py │ ├── stock/ │ │ ├── __init__.py │ │ ├── billboard.py │ │ ├── classifying.py │ │ ├── cons.py │ │ ├── fundamental.py │ │ ├── globals.py │ │ ├── indictor.py │ │ ├── macro.py │ │ ├── macro_vars.py │ │ ├── news_vars.py │ │ ├── newsevent.py │ │ ├── ref_vars.py │ │ ├── reference.py │ │ ├── shibor.py │ │ ├── trading.py │ │ └── trendline.py │ ├── trader/ │ │ ├── __init__.py │ │ ├── trader.py │ │ ├── utils.py │ │ └── vars.py │ └── util/ │ ├── __init__.py │ ├── common.py │ ├── conns.py │ ├── dateu.py │ ├── formula.py │ ├── mailmerge.py │ ├── netbase.py │ ├── store.py │ ├── upass.py │ └── vars.py └── whats_new.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Byte-compiled / optimized / DLL files *.log *.swp *.pdb .project .pydevproject .settings __pycache__/ *.py[cod] # C extensions *.so # Distribution / packaging .Python env/ build/ develop-eggs/ dist/ downloads/ eggs/ source/ baks/ lib/ lib64/ parts/ sdist/ var/ docs/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .cache nosetests.xml coverage.xml # Translations *.mo *.pot # Django stuff: *.log # Sphinx documentation docs/_build/ docs/*.md docs/bin .idea/ # PyBuilder target/ #Visual Studio Environment *.pyproj *.sln .vs/ #Vim Environment tags *~ ================================================ FILE: .travis.yml ================================================ language: python python: # We don't actually use the Travis Python, but this keeps it organized. - "2.7" # "3.3" - "3.4" install: - sudo apt-get update # We do this conditionally because it saves us some downloading if the # version is the same. - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then wget https://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh; else wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; fi - bash miniconda.sh -b -p $HOME/miniconda - export PATH="$HOME/miniconda/bin:$PATH" - hash -r - conda config --set always_yes yes --set changeps1 no - conda update -q conda # Useful for debugging any issues with conda - conda info -a before_script: - conda install --yes python=$TRAVIS_PYTHON_VERSION numpy scipy pandas matplotlib lxml pytesseract - python setup.py install script: - python test_unittest.py ================================================ FILE: LICENSE ================================================ Copyright (c) 2015, 挖地兔 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of tushare nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: MANIFEST ================================================ # file GENERATED by distutils, do NOT edit setup.py test\test.py tushare\__init__.py tushare\data\__init__.py tushare\data\all.csv tushare\stock\__init__.py tushare\stock\cons.py tushare\stock\fundamental.py tushare\stock\trading.py ================================================ FILE: README.md ================================================ TuShare Tushare Pro版已发布,请访问新的官网了解和查询数据接口! [https://tushare.pro](https://tushare.pro) TuShare是实现对股票/期货等金融数据从**数据采集**、**清洗加工** 到 **数据存储**过程的工具,满足金融量化分析师和学习数据分析的人在数据获取方面的需求,它的特点是数据覆盖范围广,接口调用简单,响应快速。 ![](http://tushare.org/_images/main_pic_min.png) 欢迎关注扫描TuShare的微信公众号“挖地兔”,更多资源和信息与您分享。另外,由于tushare官网在重新设计和开发,最新接口的使用文档都会在挖地兔公众号发布,所以,请扫码关注,谢谢! ![](http://tushare.org/_images/ts.jpg) QQ交流群: - 一群(已满):14934432 - 二群(付费高级用户群,可获得更多支持及参与圈子活动):658562506 - 三群(免费):665480579 - 四群 (免费) :527416821 Dependencies ========= python 2.x/3.x [pandas](http://pandas.pydata.org/ "pandas") Installation ==== - 方式1:pip install tushare - 方式2:python setup.py install - 方式3:访问[https://pypi.python.org/pypi/tushare/](https://pypi.python.org/pypi/tushare/)下载安装 Upgrade ======= pip install tushare --upgrade Quick Start ====== **Example 1.** 获取个股历史交易数据(包括均线数据): import tushare as ts ts.get_hist_data('600848') #一次性获取全部数据 另外,参考get_k_data函数 结果显示: > 日期 ,开盘价, 最高价, 收盘价, 最低价, 成交量, 价格变动 ,涨跌幅,5日均价,10日均价,20日均价,5日均量,10日均量,20日均量,换手率 open high close low volume p_change ma5 \ date 2012-01-11 6.880 7.380 7.060 6.880 14129.96 2.62 7.060 2012-01-12 7.050 7.100 6.980 6.900 7895.19 -1.13 7.020 2012-01-13 6.950 7.000 6.700 6.690 6611.87 -4.01 6.913 2012-01-16 6.680 6.750 6.510 6.480 2941.63 -2.84 6.813 2012-01-17 6.660 6.880 6.860 6.460 8642.57 5.38 6.822 2012-01-18 7.000 7.300 6.890 6.880 13075.40 0.44 6.788 2012-01-19 6.690 6.950 6.890 6.680 6117.32 0.00 6.770 2012-01-20 6.870 7.080 7.010 6.870 6813.09 1.74 6.832 ma10 ma20 v_ma5 v_ma10 v_ma20 turnover date 2012-01-11 7.060 7.060 14129.96 14129.96 14129.96 0.48 2012-01-12 7.020 7.020 11012.58 11012.58 11012.58 0.27 2012-01-13 6.913 6.913 9545.67 9545.67 9545.67 0.23 2012-01-16 6.813 6.813 7894.66 7894.66 7894.66 0.10 2012-01-17 6.822 6.822 8044.24 8044.24 8044.24 0.30 2012-01-18 6.833 6.833 7833.33 8882.77 8882.77 0.45 2012-01-19 6.841 6.841 7477.76 8487.71 8487.71 0.21 2012-01-20 6.863 6.863 7518.00 8278.38 8278.38 0.23 设定历史数据的时间: ts.get_hist_data('600848',start='2015-01-05',end='2015-01-09') open high close low volume p_change ma5 ma10 \ date 2015-01-05 11.160 11.390 11.260 10.890 46383.57 1.26 11.156 11.212 2015-01-06 11.130 11.660 11.610 11.030 59199.93 3.11 11.182 11.155 2015-01-07 11.580 11.990 11.920 11.480 86681.38 2.67 11.366 11.251 2015-01-08 11.700 11.920 11.670 11.640 56845.71 -2.10 11.516 11.349 2015-01-09 11.680 11.710 11.230 11.190 44851.56 -3.77 11.538 11.363 ma20 v_ma5 v_ma10 v_ma20 turnover date 2015-01-05 11.198 58648.75 68429.87 97141.81 1.59 2015-01-06 11.382 54854.38 63401.05 98686.98 2.03 2015-01-07 11.543 55049.74 61628.07 103010.58 2.97 2015-01-08 11.647 57268.99 61376.00 105823.50 1.95 2015-01-09 11.682 58792.43 60665.93 107924.27 1.54 **复权历史数据** 获取历史复权数据,分为前复权和后复权数据,接口提供股票上市以来所有历史数据,默认为前复权。如果不设定开始和结束日期,则返回近一年的复权数据,从性能上考虑,推荐设定开始日期和结束日期,而且最好不要超过一年以上,获取到数据后,请及时在本地存储。 ts.get_h_data('002337') #前复权 ts.get_h_data('002337',autype='hfq') #后复权 ts.get_h_data('002337',autype=None) #不复权 ts.get_h_data('002337',start='2015-01-01',end='2015-03-16') #两个日期之间的前复权数据 **Example 2.** 一次性获取最近一个日交易日所有股票的交易数据(结果显示速度取决于网速) ts.get_today_all() 结果显示: > 代码,名称,涨跌幅,现价,开盘价,最高价,最低价,最日收盘价,成交量,换手率 code name changepercent trade open high low settlement \ 0 002738 中矿资源 10.023 19.32 19.32 19.32 19.32 17.56 1 300410 正业科技 10.022 25.03 25.03 25.03 25.03 22.75 2 002736 国信证券 10.013 16.37 16.37 16.37 16.37 14.88 3 300412 迦南科技 10.010 31.54 31.54 31.54 31.54 28.67 4 300411 金盾股份 10.007 29.68 29.68 29.68 29.68 26.98 5 603636 南威软件 10.006 38.15 38.15 38.15 38.15 34.68 6 002664 信质电机 10.004 30.68 29.00 30.68 28.30 27.89 7 300367 东方网力 10.004 86.76 78.00 86.76 77.87 78.87 8 601299 中国北车 10.000 11.44 11.44 11.44 11.29 10.40 9 601880 大连港 10.000 5.72 5.34 5.72 5.22 5.20 10 000856 冀东装备 10.000 8.91 8.18 8.91 8.18 8.10 volume turnoverratio 0 375100 1.25033 1 85800 0.57200 2 1058925 0.08824 3 69400 0.51791 4 252220 1.26110 5 1374630 5.49852 6 6448748 9.32700 7 2025030 6.88669 8 433453523 4.28056 9 323469835 9.61735 10 25768152 19.51090 **Example 3.** 获取历史分笔数据 import tushare as ts df = ts.get_tick_data('600848',date='2014-01-09') df.head(10) 结果显示: >成交时间、成交价格、价格变动,成交手、成交金额(元),买卖类型 Out[3]: time price change volume amount type 0 15:00:00 6.05 -- 8 4840 卖盘 1 14:59:55 6.05 -- 50 30250 卖盘 2 14:59:35 6.05 -- 20 12100 卖盘 3 14:59:30 6.05 -0.01 165 99825 卖盘 4 14:59:20 6.06 0.01 4 2424 买盘 5 14:59:05 6.05 -0.01 2 1210 卖盘 6 14:58:55 6.06 -- 4 2424 买盘 7 14:58:45 6.06 -- 2 1212 买盘 8 14:58:35 6.06 0.01 2 1212 买盘 9 14:58:25 6.05 -0.01 20 12100 卖盘 10 14:58:05 6.06 -- 5 3030 买盘 **Example 4.** 获取实时交易数据(Realtime Quotes Data) df = ts.get_realtime_quotes('000581') #Single stock symbol df[['code','name','price','bid','ask','volume','amount','time']] 结果显示: >名称、开盘价、昨价、现价、最高、最低、买入价、卖出价、成交量、成交金额...more in docs code name price bid ask volume amount time 0 000581 威孚高科 31.15 31.14 31.15 8183020 253494991.16 11:30:36 请求多个股票方法(一次最好不要超过30个): ts.get_realtime_quotes(['600848','000980','000981']) #symbols from a list ts.get_realtime_quotes(df['code'].tail(10)) #from a Series 更多文档 ======== [https://tushare.pro](https://tushare.pro) [http://tushare.org/](http://tushare.org/ "TuShare Docs") Change Logs ----------- 1.2.17 2018/11/24 ====== - Pro版增加期货数据 - Pro版增加A股周/月数据 - Pro版增加通用行情pro_bar接口股票/基金/期货/数据货币行情的支持,同时支持股票的复权行情 1.2.15 2018/10/15 ==== - 增加通用行情pro_bar接口 - 优化set_token功能 1.2.12 2018/08/10 ==== - 发布Pro版第一稿 - 发布Pro网站,[https://tushare.pro](https://tushare.pro) 1.0.5 2017/11/12 ====== - 新增可转债数据 - 增加长连接关闭函数 - 修复部分bug 1.0.2 2017/10/29 ========== - 新增bar接口,支持更稳定的股票、ETF、期货期权、港股、中概股等品种 - 新增tick接口,支持以上品种的成交数据 - 新增沪深港通每日资金流向数据 - 修复了部分bug 0.9.2 2017/09/13 =========== - 新增数据货币行情数据接口,同时支持火币、okcoin、中国比特币 - 部分bug修复 0.8.8 2017/08/29 =========== - 新增分红送股数据(包含历史) - 新增get_day_all接口 - 新增BDI接口 0.8.0 2017/06/05 =========== - 新增期货行情数据6个接口,感谢debugo贡献代码 - 修复部分bug 0.7.6 2017/05/16 ============= - get\_today\_all接口数据补齐 - forecast\_data mac下编码问题修复 0.7.0 2017/03/12 ============= - get\_today\_all接口提速 - 版本累积更新 0.6.2 2016/12/03 ========== - 新增十大股东和十大流通股接口 top10_holders - 新增全球实时指数列表接口 global_realtime - 修复部分bug 0.6.1 2016/11/22 =========== - 修正get_k_databug - 修正实盘交易登录问题 0.5.6 2016/11/06 ============= - 新增全新行情数据接口get_k_data(请关注tushare公众号“挖地兔”后查看历史文章《全新的免费行情数据接口》) - 修复程序和文档bug 0.5.1 2016/10/16 ============= - 新增实盘交易接口 - 修复bug 0.4.9 2016/03/26 ============= - 新增申万行业分类get_industry_classified(standard='sw') - 新增交易日历trade_cal() - 修复bug 0.4.3 2015/12/24 ============ - 新增电影票房数据 - 修复部分bug 0.4.1 2015/11/27 ============== - 新增sina大单数据 - 修改当日分笔bug - 深市融资融券数据修复 0.3.9 2015/10/13 ============ - 新增期权隐含波动率数据 - 修复指数成份及权重接口问题 0.3.8 2015/09/19 ============ - 沪深300成份股和权重接口问题修复 - 其它bug的修复 0.3.5 2015/07/27 ========== - 部分代码修正 0.3.4 2015/06/15 =========== - 新增‘龙虎榜’模块 1. 每日龙虎榜列表 1. 个股上榜统计 1. 营业部上榜统计 1. 龙虎榜机构席位追踪 1. 龙虎榜机构席位成交明细 - 修改get\_h\_data数据类型为float - 修改get_index接口遗漏的open列 - 合并GitHub上提交的bug修复 0.2.8 2015/04/28 ============ - 新增大盘指数实时行情列表 - 新增大盘指数历史行情数据(全部) - 新增终止上市公司列表(退市) - 新增暂停上市公司列表 - 修正融资融券明细无日期的缺陷 - 修正get\_h\_data部分bug 0.2.6 ======== - 新增沪市融资融券列表 - 新增沪市融资融券明细列表 - 新增深市融资融券列表 - 新增深市融资融券明细列表 - 修正复权数据数据源出现null造成异常问题(对大约300个股票有影响) 0.2.5 2015/04/16 =========== - 完成python2.x和python3.x兼容性支持 - 部分算法优化和代码重构 - 新增中证500成份股 - 新增当日分笔交易明细 - 修正分配预案(高送转)bug 0.2.3 2015/04/11 =========== - 新增“新浪股吧”消息和热度 - 新增新股上市数据 - 修正“基本面”模块中数据重复的问题 - 修正历史数据缺少一列column(数据来源问题)的bug 0.2.0 2015/03/17 ======= - 新增历史复权数据接口 - 新增即时滚动新闻、信息地雷数据 - 新增沪深300指数成股份及动态权重、 - 新增上证50指数成份股 - 修改历史行情数据类型为float 0.1.9 2015/02/06 ======== - 增加分类数据 - 增加数据存储示例 0.1.6 2015/01/27 ======== - 增加了重点指数的历史和实时行情 - 更新docs 0.1.5 2015/01/26 ===== - 增加基本面数据接口 - 发布一版使用手册,开通[TuShare docs](http://tushare.waditu.com)网站 0.1.3 2015/01/13 === - 增加实时交易数据的获取 - Done for crawling Realtime Quotes data 0.1.1 2015/01/11 === - 增加tick数据的获取 0.1.0 2014/12/01 === - 创建第一个版本 - 实现个股历史数据的获取 ================================================ FILE: issues/from_email.txt ================================================ 2015-2-10 ------------ ASK:Stupidinsect:ϣӻ REP: 2015-2-26 ------------ ASK:Allisnoneproblem with python keywords REP:н 2015-3-1 ------------ ASK:: get_hist_dataMySQLdate(index)޷ REP:ʱͨdf['date'] = df.indexto_sqlòindex=Falseһ汾ȡindex 2015-3-23 -------------- chendonghui1987:ȡǰȨݱTypeError: cannot convert the series to from v0.2.1 2015-04-05 ------------------- ̹: JimmyTuã ȸлṩôõһ⣬Һܾõ⣬ ύһbugع˾걨ݣreport = ts.get_report_data(2014, 1) ⣺ 1ȱ˾ƽУ000001 2˾ظ總ˢ ϣлָ 2015-04-18 --------------- huhaook:ijЩɵĸȨ쳣ʵԴΪnullҪ޸ij(418) 2015-04-28 ---------------- Ԭͨget_hist_dataȡ600102ʱ600102йƱݷأֱӷNone 2015-06-13 Tales Yuantushareprofit_dataȡ2015Ԥʧܡ61423ʱ25 ================================================ FILE: issues/from_sns.txt ================================================ 2015-02-12 ----------- QQȺ297882961kݸȨ۵⡢ݲ 2015-03-01 ----------- QQȺ275882700@ kߴ⣬ȷʵǷ˲ƾԴ⣨ɸget_h_data()ӿڣ 2015-03-02 ----------- QQȺ275882700@װ˹̹ ϣṩָijɷݹɺȨ 2015-03-20 QQȺ297882961:@x ֤100֤800ָk 2015-04-09 ------------- QQȺ297882961:@㽭-QT002738Ʊʷݱget_hist_data飬ԭǷ˲ƾĽӿһлʵݡʽжһcolumnsöԵȵcolumsб 2015-04-10 ------------- ־ȨݵΪobject 2015-04-16 ------------- ΢@ariestigerget_h_data()ijɽƴд 2015-05-01 ------------------ QQȺ297882961:@Koffʹget_today_tickӿڵʱUnboundLocalError: local variable 'data' referenced before assignment쳣̺ϵõģ 2015-05-05 QQ Mr.OKӹ˾ɶĽӿ PHENXI-ڻ -------------------- http://vip.stock.finance.sina.com.cn/mkt/#hqIndex ҳбȽȫгϢ http://blog.sina.com.cn/s/blog_7ed3ed3d0101gphj.html ƪгһЩݽṹ http://quote.hexun.com/futures/newfutures.aspx?market=9&type=all&n=%C8%AB%B2%BF http://webcffex.hermes.hexun.com/cffex/kline?code=CFFEXIH1606&start=20160206091500&number=-1000&type=5 PHENXI 2016/2/15 8:57:44 http://webftcn.hermes.hexun.com/ http://webcffex.hermes.hexun.com/cffex/quotelist?code=CFFEXIH1606,CFFEXIF1609,CFFEXIC1603,dceA1611,CFFEXIC1512,&column=code,name,price,priceweight,updownrate,high,low,updown,lastclose,open&callback=getdata1&callback=jQuery111107492109271895186_1455497884413&_=1455497884414 ================================================ FILE: requirements.txt ================================================ pandas>=0.18.0 requests>=2.0.0 lxml>=3.8.0 simplejson>=3.16.0 bs4>=0.0.1 beautfulsoup4>=4.5.1 ================================================ FILE: setup.py ================================================ from setuptools import setup, find_packages import codecs import os def read(fname): return codecs.open(os.path.join(os.path.dirname(__file__), fname)).read() long_desc = """ TuShare =============== .. image:: https://api.travis-ci.org/waditu/tushare.png?branch=master :target: https://travis-ci.org/waditu/tushare .. image:: https://badge.fury.io/py/tushare.png :target: http://badge.fury.io/py/tushare * easy to use as most of the data returned are pandas DataFrame objects * can be easily saved as csv, excel or json files * can be inserted into MySQL or Mongodb Target Users -------------- * financial market analyst of China * learners of financial data analysis with pandas/NumPy * people who are interested in China financial data Installation -------------- pip install tushare Upgrade --------------- pip install tushare --upgrade Quick Start -------------- :: import tushare as ts ts.get_hist_data('600848') return:: open high close low volume p_change ma5 \ date 2012-01-11 6.880 7.380 7.060 6.880 14129.96 2.62 7.060 2012-01-12 7.050 7.100 6.980 6.900 7895.19 -1.13 7.020 2012-01-13 6.950 7.000 6.700 6.690 6611.87 -4.01 6.913 2012-01-16 6.680 6.750 6.510 6.480 2941.63 -2.84 6.813 2012-01-17 6.660 6.880 6.860 6.460 8642.57 5.38 6.822 2012-01-18 7.000 7.300 6.890 6.880 13075.40 0.44 6.788 2012-01-19 6.690 6.950 6.890 6.680 6117.32 0.00 6.770 2012-01-20 6.870 7.080 7.010 6.870 6813.09 1.74 6.832 """ def read_install_requires(): reqs = [ 'pandas>=0.18.0', 'requests>=2.0.0', 'lxml>=3.8.0', 'simplejson>=3.16.0', 'msgpack>=0.5.6', 'pyzmq>=16.0.0' ] return reqs setup( name='tushare', version=read('tushare/VERSION.txt'), description='A utility for crawling historical and Real-time Quotes data of China stocks', # long_description=read("READM.rst"), long_description = long_desc, author='Jimmy Liu', author_email='jimmysoa@sina.cn', license='BSD', url='http://tushare.org', install_requires=read_install_requires(), keywords='Global Financial Data', classifiers=['Development Status :: 4 - Beta', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'License :: OSI Approved :: BSD License'], packages=find_packages(), include_package_data=True, package_data={'': ['*.csv', '*.txt']}, ) ================================================ FILE: test/__init__.py ================================================ ================================================ FILE: test/bar_test.py ================================================ # -*- coding:utf-8 -*- ''' Created on 2017/9/24 @author: Jimmy Liu ''' import unittest import tushare.stock.trading as fd class Test(unittest.TestCase): def set_data(self): self.code = '600848' self.start = '' self.end = '' def test_bar_data(self): self.set_data() print(fd.bar(self.code, self.start, self.end)) if __name__ == "__main__": #import sys;sys.argv = ['', 'Test.testName'] unittest.main() ================================================ FILE: test/billboard_test.py ================================================ # -*- coding:utf-8 -*- ''' Created on 2015/3/14 @author: Jimmy Liu ''' import unittest import tushare.stock.billboard as fd class Test(unittest.TestCase): def set_data(self): self.date = '2015-06-12' self.days = 5 def test_top_list(self): self.set_data() print(fd.top_list(self.date)) def test_cap_tops(self): self.set_data() print(fd.cap_tops(self.days)) def test_broker_tops(self): self.set_data() print(fd.broker_tops(self.days)) def test_inst_tops(self): self.set_data() print(fd.inst_tops(self.days)) def test_inst_detail(self): print(fd.inst_detail()) if __name__ == "__main__": unittest.main() ================================================ FILE: test/classifying_test.py ================================================ # -*- coding:utf-8 -*- ''' Created on 2015/3/14 @author: Jimmy Liu ''' import unittest import tushare.stock.classifying as fd class Test(unittest.TestCase): def set_data(self): self.code = '600848' self.start = '2015-01-03' self.end = '2015-04-07' self.year = 2014 self.quarter = 4 def test_get_industry_classified(self): print(fd.get_industry_classified()) def test_get_concept_classified(self): print(fd.get_concept_classified()) def test_get_area_classified(self): print(fd.get_area_classified()) def test_get_gem_classified(self): print(fd.get_gem_classified()) def test_get_sme_classified(self): print(fd.get_sme_classified()) def test_get_st_classified(self): print(fd.get_st_classified()) def test_get_hs300s(self): print(fd.get_hs300s()) def test_get_sz50s(self): print(fd.get_sz50s()) def test_get_zz500s(self): print(fd.get_zz500s()) if __name__ == "__main__": unittest.main() # suite = unittest.TestSuite() # suite.addTest(Test('test_get_gem_classified')) # unittest.TextTestRunner(verbosity=2).run(suite) ================================================ FILE: test/dateu_test.py ================================================ # -*- coding:utf-8 -*- """ @author: ZackZK """ from unittest import TestCase from tushare.util import dateu from tushare.util.dateu import is_holiday class Test_Is_holiday(TestCase): def test_is_holiday(self): dateu.holiday = ['2016-01-04'] # holiday stub for later test self.assertTrue(is_holiday('2016-01-04')) # holiday self.assertFalse(is_holiday('2016-01-01')) # not holiday self.assertTrue(is_holiday('2016-01-09')) # Saturday self.assertTrue(is_holiday('2016-01-10')) # Sunday ================================================ FILE: test/fund_test.py ================================================ # -*- coding:utf-8 -*- import unittest import tushare.stock.fundamental as fd class Test(unittest.TestCase): def set_data(self): self.code = '600848' self.start = '2015-01-03' self.end = '2015-04-07' self.year = 2014 self.quarter = 4 def test_get_stock_basics(self): print(fd.get_stock_basics()) # def test_get_report_data(self): # self.set_data() # print(fd.get_report_data(self.year, self.quarter)) # # def test_get_profit_data(self): # self.set_data() # print(fd.get_profit_data(self.year, self.quarter)) # # def test_get_operation_data(self): # self.set_data() # print(fd.get_operation_data(self.year, self.quarter)) # # def test_get_growth_data(self): # self.set_data() # print(fd.get_growth_data(self.year, self.quarter)) # # def test_get_debtpaying_data(self): # self.set_data() # print(fd.get_debtpaying_data(self.year, self.quarter)) # # def test_get_cashflow_data(self): # self.set_data() # print(fd.get_cashflow_data(self.year, self.quarter)) if __name__ == '__main__': unittest.main() ================================================ FILE: test/indictor_test.py ================================================ # -*- coding:utf-8 -*- ''' Created on 2018/05/26 @author: Jackie Liao ''' import unittest import tushare.stock.indictor as idx import tushare as ts class Test(unittest.TestCase): def test_plot_all(self): data = ts.get_k_data("601398", start="2018-01-01", end="2018-05-27") data = data.sort_values(by=["date"], ascending=True) idx.plot_all(data, is_show=True, output=None) if __name__ == "__main__": # import sys;sys.argv = ['', 'Test.testName'] unittest.main() ================================================ FILE: test/macro_test.py ================================================ # -*- coding:utf-8 -*- ''' Created on 2015/3/14 @author: Jimmy Liu ''' import unittest import tushare.stock.macro as fd class Test(unittest.TestCase): def test_get_gdp_year(self): print(fd.get_gdp_year()) def test_get_gdp_quarter(self): print(fd.get_gdp_quarter()) def test_get_gdp_for(self): print(fd.get_gdp_for()) def test_get_gdp_pull(self): print(fd.get_gdp_pull()) def test_get_gdp_contrib(self): print(fd.get_gdp_contrib()) def test_get_cpi(self): print(fd.get_cpi()) def test_get_ppi(self): print(fd.get_ppi()) def test_get_deposit_rate(self): print(fd.get_deposit_rate()) def test_get_loan_rate(self): print(fd.get_loan_rate()) def test_get_rrr(self): print(fd.get_rrr()) def test_get_money_supply(self): print(fd.get_money_supply()) def test_get_money_supply_bal(self): print(fd.get_money_supply_bal()) if __name__ == "__main__": #import sys;sys.argv = ['', 'Test.testName'] unittest.main() ================================================ FILE: test/nav_test.py ================================================ # -*- coding:utf-8 -*- ''' Created on 2016/5/26 @author: leo ''' import unittest import tushare.fund.nav as nav class Test(unittest.TestCase): def set_data(self): self.symbol = '600848' self.start = '2014-11-24' self.end = '2016-02-29' self.disp = 5 def test_get_nav_open(self): self.set_data() lst = ['all', 'equity', 'mix', 'bond', 'monetary', 'qdii'] print('get nav open................\n') for item in lst: print('=============\nget %s nav\n=============' % item) fund_df = nav.get_nav_open(item) print('\nnums=%d' % len(fund_df)) print(fund_df[:self.disp]) def test_get_nav_close(self): self.set_data() type2 = ['all', 'fbqy', 'fbzq'] qy_t3 = ['all', 'ct', 'cx'] zq_t3 = ['all', 'wj', 'jj', 'cz'] print('\nget nav closed................\n') fund_df = None for item in type2: if item == 'fbqy': for t3i in qy_t3: print('\n=============\nget %s-%s nav\n=============' % (item, t3i)) fund_df = nav.get_nav_close(item, t3i) print('\nnums=%d' % len(fund_df)) print(fund_df[:self.disp]) elif item == 'fbzq': for t3i in zq_t3: print('\n=============\nget %s-%s nav\n=============' % (item, t3i)) fund_df = nav.get_nav_close(item, t3i) print('\nnums=%d' % len(fund_df)) print(fund_df[:self.disp]) else: print('\n=============\nget %s nav\n=============' % item) fund_df = nav.get_nav_close(item) print('\nnums=%d' % len(fund_df)) print(fund_df[:self.disp]) def test_get_nav_grading(self): self.set_data() t2 = ['all', 'fjgs', 'fjgg'] t3 = {'all': '0', 'wjzq': '13', 'gp': '14', 'zs': '15', 'czzq': '16', 'jjzq': '17'} print('\nget nav grading................\n') fund_df = None for item in t2: if item == 'all': print('\n=============\nget %s nav\n=============' % item) fund_df = nav.get_nav_grading(item) print('\nnums=%d' % len(fund_df)) print(fund_df[:self.disp]) else: for t3i in t3.keys(): print('\n=============\nget %s-%s nav\n=============' % (item, t3i)) fund_df = nav.get_nav_grading(item, t3i) print('\nnums=%d' % len(fund_df)) print(fund_df[:self.disp]) def test_nav_history(self): self.set_data() lst = ['164905', '161005', '380007', '000733', '159920', '164902', '184721', '165519', '164302', '519749', '150275', '150305', '150248'] for _, item in enumerate(lst): print('\n=============\nget %s nav\n=============' % item) fund_df = nav.get_nav_history(item, self.start, self.end) if fund_df is not None: print('\nnums=%d' % len(fund_df)) print(fund_df[:self.disp]) def test_get_fund_info(self): self.set_data() lst = ['164905', '161005', '380007', '000733', '159920', '164902', '184721', '165519', '164302', '519749', '150275', '150305', '150248'] for item in lst: print('\n=============\nget %s nav\n=============' % item) fund_df = nav.get_fund_info(item) if fund_df is not None: print('%s fund info' % item) print(fund_df) if __name__ == '__main__': unittest.main() ================================================ FILE: test/news_test.py ================================================ # -*- coding:utf-8 -*- ''' Created on 2015/3/14 @author: Jimmy Liu ''' import unittest import tushare.stock.newsevent as fd class Test(unittest.TestCase): def set_data(self): self.code = '600848' self.start = '2015-01-03' self.end = '2015-04-07' self.year = 2014 self.quarter = 4 self.top = 60 self.show_content = True def test_get_latest_news(self): self.set_data() print(fd.get_latest_news(self.top, self.show_content)) def test_get_notices(self): self.set_data() df = fd.get_notices(self.code) print(fd.notice_content(df.ix[0]['url'])) def test_guba_sina(self): self.set_data() print(fd.guba_sina(self.show_content)) if __name__ == "__main__": unittest.main() ================================================ FILE: test/ref_test.py ================================================ # -*- coding:utf-8 -*- ''' Created on 2015/3/14 @author: Jimmy Liu ''' import unittest from tushare.stock import reference as fd class Test(unittest.TestCase): def set_data(self): self.code = '600848' self.start = '2015-01-03' self.end = '2015-04-07' self.year = 2014 self.quarter = 4 self.top = 60 self.show_content = True def test_profit_data(self): self.set_data() print(fd.profit_data(top=self.top)) def test_forecast_data(self): self.set_data() print(fd.forecast_data(self.year, self.quarter)) def test_xsg_data(self): print(fd.xsg_data()) def test_fund_holdings(self): self.set_data() print(fd.fund_holdings(self.year, self.quarter)) def test_new_stocksa(self): print(fd.new_stocks()) def test_sh_margin_details(self): self.set_data() print(fd.sh_margin_details(self.start, self.end, self.code)) def test_sh_margins(self): self.set_data() print(fd.sh_margins(self.start, self.end)) def test_sz_margins(self): self.set_data() print(fd.sz_margins(self.start, self.end)) def test_sz_margin_details(self): self.set_data() print(fd.sz_margin_details(self.end)) if __name__ == "__main__": unittest.main() ================================================ FILE: test/shibor_test.py ================================================ # -*- coding:utf-8 -*- import unittest import tushare.stock.shibor as fd class Test(unittest.TestCase): def set_data(self): self.year = 2014 # self.year = None def test_shibor_data(self): self.set_data() fd.shibor_data(self.year) def test_shibor_quote_data(self): self.set_data() fd.shibor_quote_data(self.year) def test_shibor_ma_data(self): self.set_data() fd.shibor_ma_data(self.year) def test_lpr_data(self): self.set_data() fd.lpr_data(self.year) def test_lpr_ma_data(self): self.set_data() fd.lpr_ma_data(self.year) if __name__ == '__main__': unittest.main() ================================================ FILE: test/storing_test.py ================================================ # -*- coding:utf-8 -*- import os from sqlalchemy import create_engine from pandas.io.pytables import HDFStore import tushare as ts def csv(): df = ts.get_hist_data('000875') df.to_csv('c:/day/000875.csv',columns=['open','high','low','close']) def xls(): df = ts.get_hist_data('000875') #直接保存 df.to_excel('c:/day/000875.xlsx', startrow=2,startcol=5) def hdf(): df = ts.get_hist_data('000875') # df.to_hdf('c:/day/store.h5','table') store = HDFStore('c:/day/store.h5') store['000875'] = df store.close() def json(): df = ts.get_hist_data('000875') df.to_json('c:/day/000875.json',orient='records') #或者直接使用 print(df.to_json(orient='records')) def appends(): filename = 'c:/day/bigfile.csv' for code in ['000875', '600848', '000981']: df = ts.get_hist_data(code) if os.path.exists(filename): df.to_csv(filename, mode='a', header=None) else: df.to_csv(filename) def db(): df = ts.get_tick_data('600848',date='2014-12-22') engine = create_engine('mysql://root:jimmy1@127.0.0.1/mystock?charset=utf8') # db = MySQLdb.connect(host='127.0.0.1',user='root',passwd='jimmy1',db="mystock",charset="utf8") # df.to_sql('TICK_DATA',con=db,flavor='mysql') # db.close() df.to_sql('tick_data',engine,if_exists='append') def nosql(): import pymongo import json conn = pymongo.Connection('127.0.0.1', port=27017) df = ts.get_tick_data('600848',date='2014-12-22') print(df.to_json(orient='records')) conn.db.tickdata.insert(json.loads(df.to_json(orient='records'))) # print conn.db.tickdata.find() if __name__ == '__main__': nosql() ================================================ FILE: test/trading_test.py ================================================ # -*- coding:utf-8 -*- ''' Created on 2015/3/14 @author: Jimmy Liu ''' import unittest import tushare.stock.trading as fd class Test(unittest.TestCase): def set_data(self): self.code = '600848' self.start = '2015-01-03' self.end = '2015-04-07' self.year = 2014 self.quarter = 4 def test_get_hist_data(self): self.set_data() print(fd.get_hist_data(self.code, self.start)) def test_get_tick_data(self): self.set_data() print(fd.get_tick_data(self.code, self.end)) def test_get_today_all(self): print(fd.get_today_all()) def test_get_realtime_quotesa(self): self.set_data() print(fd.get_realtime_quotes(self.code)) def test_get_h_data(self): self.set_data() print(fd.get_h_data(self.code, self.start, self.end)) def test_get_today_ticks(self): self.set_data() print(fd.get_today_ticks(self.code)) if __name__ == "__main__": #import sys;sys.argv = ['', 'Test.testName'] unittest.main() ================================================ FILE: test_unittest.py ================================================ ''' UnitTest for API @author: Jimmy ''' import unittest import tushare.stock.trading as td class TestTrading(unittest.TestCase): def set_data(self): self.code = '600848' self.start = '2014-11-03' self.end = '2014-11-07' def test_tickData(self): self.set_data() td.get_tick_data(self.code, date=self.start) # def test_histData(self): # self.set_data() # td.get_hist_data(self.code, start=self.start, end=self.end) if __name__ == "__main__": #import sys;sys.argv = ['', 'Test.testName'] unittest.main() ================================================ FILE: tushare/VERSION.txt ================================================ 1.2.18 ================================================ FILE: tushare/__init__.py ================================================ # -*- coding:utf-8 -*- import codecs import os __version__ = codecs.open(os.path.join(os.path.dirname(__file__), 'VERSION.txt')).read() __author__ = 'Jimmy Liu' """ for trading data """ from tushare.stock.trading import (get_hist_data, get_tick_data, get_today_all, get_realtime_quotes, get_h_data, get_today_ticks, get_index, get_hists, get_k_data, get_day_all, get_sina_dd, bar, tick, get_markets, quotes, get_instrument, reset_instrument) """ for trading data """ from tushare.stock.fundamental import (get_stock_basics, get_report_data, get_profit_data, get_operation_data, get_growth_data, get_debtpaying_data, get_cashflow_data, get_balance_sheet, get_profit_statement, get_cash_flow) """ for macro data """ from tushare.stock.macro import (get_gdp_year, get_gdp_quarter, get_gdp_for, get_gdp_pull, get_gdp_contrib, get_cpi, get_ppi, get_deposit_rate, get_loan_rate, get_rrr, get_money_supply, get_money_supply_bal, get_gold_and_foreign_reserves) """ for classifying data """ from tushare.stock.classifying import (get_industry_classified, get_concept_classified, get_area_classified, get_gem_classified, get_sme_classified, get_st_classified, get_hs300s, get_sz50s, get_zz500s, get_terminated, get_suspended) """ for macro data """ from tushare.stock.newsevent import (get_latest_news, latest_content, get_notices, notice_content, guba_sina) """ for reference moneyflow_hsgt:沪深港通资金流向 """ from tushare.stock.reference import (profit_data, forecast_data, xsg_data, fund_holdings, new_stocks, new_cbonds, sh_margins, sh_margin_details, sz_margins, sz_margin_details, top10_holders, profit_divis, moneyflow_hsgt, margin_detail, margin_target, margin_offset, margin_zsl, stock_issuance, stock_pledged, pledged_detail) """ for shibor """ from tushare.stock.shibor import (shibor_data, shibor_quote_data, shibor_ma_data, lpr_data, lpr_ma_data) """ for tushare pro api """ from tushare.pro.data_pro import (pro_api, pro_bar) """ for LHB """ from tushare.stock.billboard import (top_list, cap_tops, broker_tops, inst_tops, inst_detail) """ for utils """ from tushare.util.dateu import (trade_cal, is_holiday) from tushare.internet.boxoffice import (realtime_boxoffice, day_boxoffice, day_cinema, month_boxoffice) from tushare.internet.indexes import (bdi) """ for fund data """ from tushare.fund.nav import (get_nav_open, get_nav_close, get_nav_grading, get_nav_history, get_fund_info) """ for trader API """ from tushare.trader.trader import TraderAPI """ for futures API """ from tushare.futures.intlfutures import (get_intlfuture) from tushare.stock.globals import (global_realtime) from tushare.util.mailmerge import (MailMerge) """ for futures API """ from tushare.futures.domestic import (get_cffex_daily, get_czce_daily, get_dce_daily, get_future_daily, get_shfe_daily, get_shfe_vwap) from tushare.coins.market import (coins_tick, coins_bar, coins_snapshot, coins_trade) from tushare.util.conns import (get_apis, close_apis) from tushare.util.upass import (get_token, set_token) ================================================ FILE: tushare/bond/__init__.py ================================================ ================================================ FILE: tushare/bond/bonds.py ================================================ # -*- coding:utf-8 -*- """ 投资参考数据接口 Created on 2017/10/01 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ def get_bond_info(code): pass if __name__ == '__main__': pass ================================================ FILE: tushare/coins/__init__.py ================================================ ================================================ FILE: tushare/coins/market.py ================================================ #!/usr/bin/env python # -*- coding:utf-8 -*- """ 数字货币行情数据 Created on 2017年9月9日 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ import pandas as pd import traceback import time import json try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request URL = { "hb": { "rt" : 'http://api.huobi.com/staticmarket/ticker_%s_json.js', "kline" : 'http://api.huobi.com/staticmarket/%s_kline_%s_json.js?length=%s', "snapshot" : 'http://api.huobi.com/staticmarket/depth_%s_%s.js', "tick" : 'http://api.huobi.com/staticmarket/detail_%s_json.js', }, "ok": { "rt" : 'https://www.okcoin.cn/api/v1/ticker.do?symbol=%s_cny', "kline" : 'https://www.okcoin.cn/api/v1/kline.do?symbol=%s_cny&type=%s&size=%s', "snapshot" : 'https://www.okcoin.cn/api/v1/depth.do?symbol=%s_cny&merge=&size=%s', "tick" : 'https://www.okcoin.cn/api/v1/trades.do?symbol=%s_cny', }, 'chbtc': { "rt" : 'http://api.chbtc.com/data/v1/ticker?currency=%s_cny', "kline" : 'http://api.chbtc.com/data/v1/kline?currency=%s_cny&type=%s&size=%s', "snapshot" : 'http://api.chbtc.com/data/v1/depth?currency=%s_cny&size=%s&merge=', "tick" : 'http://api.chbtc.com/data/v1/trades?currency=%s_cny', } } KTYPES = { "D": { "hb" : '100', 'ok' : '1day', 'chbtc' : '1day', }, "W": { "hb" : '200', 'ok' : '1week', 'chbtc' : '1week', }, "M": { "hb" : '300', "ok" : '', "chbtc" : '', }, "1MIN": { "hb" : '001', 'ok' : '1min', 'chbtc' : '1min', }, "5MIN": { "hb" : '005', 'ok' : '5min', 'chbtc' : '5min', }, "15MIN": { "hb" : '015', 'ok' : '15min', 'chbtc' : '15min', }, "30MIN": { "hb" : '030', 'ok' : '30min', 'chbtc' : '30min', }, "60MIN": { "hb" : '060', 'ok' : '1hour', 'chbtc' : '1hour', }, } def coins_tick(broker='hb', code='btc'): """ 实时tick行情 params: --------------- broker: hb:火币 ok:okCoin chbtc:中国比特币 code: hb:btc,ltc ----okcoin--- btc_cny:比特币 ltc_cny:莱特币 eth_cny :以太坊 etc_cny :以太经典 bcc_cny :比特现金 ----chbtc---- btc_cny:BTC/CNY ltc_cny :LTC/CNY eth_cny :以太币/CNY etc_cny :ETC币/CNY bts_cny :BTS币/CNY eos_cny :EOS币/CNY bcc_cny :BCC币/CNY qtum_cny :量子链/CNY hsr_cny :HSR币/CNY return:json --------------- hb: { "time":"1504713534", "ticker":{ "symbol":"btccny", "open":26010.90, "last":28789.00, "low":26000.00, "high":28810.00, "vol":17426.2198, "buy":28750.000000, "sell":28789.000000 } } ok: { "date":"1504713864", "ticker":{ "buy":"28743.0", "high":"28886.99", "last":"28743.0", "low":"26040.0", "sell":"28745.0", "vol":"20767.734" } } chbtc: { u'date': u'1504794151878', u'ticker': { u'sell': u'28859.56', u'buy': u'28822.89', u'last': u'28859.56', u'vol': u'2702.71', u'high': u'29132', u'low': u'27929' } } """ return _get_data(URL[broker]['rt'] % (code)) def coins_bar(broker='hb', code='btc', ktype='D', size='2000'): """ 获取各类k线数据 params: broker:hb,ok,chbtc code:btc,ltc,eth,etc,bcc ktype:D,W,M,1min,5min,15min,30min,60min size:<2000 return DataFrame: 日期时间,开盘价,最高价,最低价,收盘价,成交量 """ try: js = _get_data(URL[broker]['kline'] % (code, KTYPES[ktype.strip().upper()][broker], size)) if js is None: return js if broker == 'chbtc': js = js['data'] df = pd.DataFrame(js, columns=['DATE', 'OPEN', 'HIGH', 'LOW', 'CLOSE', 'VOL']) if broker == 'hb': if ktype.strip().upper() in ['D', 'W', 'M']: df['DATE'] = df['DATE'].apply(lambda x: x[0:8]) else: df['DATE'] = df['DATE'].apply(lambda x: x[0:12]) else: df['DATE'] = df['DATE'].apply(lambda x: int2time(x / 1000)) if ktype.strip().upper() in ['D', 'W', 'M']: df['DATE'] = df['DATE'].apply(lambda x: str(x)[0:10]) df['DATE'] = pd.to_datetime(df['DATE']) return df except Exception: print(traceback.print_exc()) def coins_snapshot(broker='hb', code='btc', size='5'): """ 获取实时快照数据 params: broker:hb,ok,chbtc code:btc,ltc,eth,etc,bcc size:<150 return Panel: asks,bids """ try: js = _get_data(URL[broker]['snapshot'] % (code, size)) if js is None: return js if broker == 'hb': timestr = js['ts'] timestr = int2time(timestr / 1000) if broker == 'ok': timestr = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) if broker == 'chbtc': timestr = js['timestamp'] timestr = int2time(timestr) asks = pd.DataFrame(js['asks'], columns = ['price', 'vol']) bids = pd.DataFrame(js['bids'], columns = ['price', 'vol']) asks['time'] = timestr bids['time'] = timestr djs = {"asks": asks, "bids": bids} pf = pd.Panel(djs) return pf except Exception: print(traceback.print_exc()) def coins_trade(broker='hb', code='btc'): """ 获取实时交易数据 params: ------------- broker: hb,ok,chbtc code:btc,ltc,eth,etc,bcc return: --------------- DataFrame 'tid':order id 'datetime', date time 'price' : trade price 'amount' : trade amount 'type' : buy or sell """ js = _get_data(URL[broker]['tick'] % code) if js is None: return js if broker == 'hb': df = pd.DataFrame(js['trades']) df = df[['id', 'ts', 'price', 'amount', 'direction']] df['ts'] = df['ts'].apply(lambda x: int2time(x / 1000)) if broker == 'ok': df = pd.DataFrame(js) df = df[['tid', 'date_ms', 'price', 'amount', 'type']] df['date_ms'] = df['date_ms'].apply(lambda x: int2time(x / 1000)) if broker == 'chbtc': df = pd.DataFrame(js) df = df[['tid', 'date', 'price', 'amount', 'type']] df['date'] = df['date'].apply(lambda x: int2time(x)) df.columns = ['tid', 'datetime', 'price', 'amount', 'type'] return df def _get_data(url): try: request = Request(url) lines = urlopen(request, timeout = 10).read() if len(lines) < 50: #no data return None js = json.loads(lines.decode('GBK')) return js except Exception: print(traceback.print_exc()) def int2time(timestamp): value = time.localtime(timestamp) dt = time.strftime('%Y-%m-%d %H:%M:%S', value) return dt ================================================ FILE: tushare/data/__init__.py ================================================ __version__ = "0.0.1" ================================================ FILE: tushare/fund/__init__.py ================================================ ================================================ FILE: tushare/fund/cons.py ================================================ # -*- coding:utf-8 -*- """ Created on 2016/04/03 @author: Leo @group : lazytech @contact: lazytech@sina.cn """ VERSION = '0.0.1' P_TYPE = {'http': 'http://', 'ftp': 'ftp://'} FORMAT = lambda x: '%.2f' % x FORMAT4 = lambda x: '%.4f' % x DOMAINS = {'sina': 'sina.com.cn', 'sinahq': 'sinajs.cn', 'ifeng': 'ifeng.com', 'sf': 'finance.sina.com.cn', 'ssf': 'stock.finance.sina.com.cn', 'vsf': 'vip.stock.finance.sina.com.cn', 'idx': 'www.csindex.com.cn', '163': 'money.163.com', 'em': 'eastmoney.com', 'sseq': 'query.sse.com.cn', 'sse': 'www.sse.com.cn', 'szse': 'www.szse.cn', 'oss': '218.244.146.57', 'shibor': 'www.shibor.org'} NAV_OPEN_API = {'all': 'getNetValueOpen', 'equity': 'getNetValueOpen', 'mix': 'getNetValueOpen', 'bond': 'getNetValueOpen', 'monetary': 'getNetValueMoney', 'qdii': 'getNetValueOpen'} NAV_OPEN_KEY = {'all': '6XxbX6h4CED0ATvW', 'equity': 'Gb3sH5uawH5WCUZ9', 'mix': '6XxbX6h4CED0ATvW', 'bond': 'Gb3sH5uawH5WCUZ9', 'monetary': 'uGo5qniFnmT5eQjp', 'qdii': 'pTYExKwRmqrSaP0P'} NAV_OPEN_T2 = {'all': '0', 'equity': '2', 'mix': '1', 'bond': '3', 'monetary': '0', 'qdii': '6'} NAV_OPEN_T3 = '' NAV_CLOSE_API = 'getNetValueClose' NAV_CLOSE_KEY = '' NAV_CLOSE_T2 = {'all': '0', 'fbqy': '4', 'fbzq': '9'} NAV_CLOSE_T3 = {'all': '0', 'ct': '10', 'cx': '11', 'wj': '3', 'jj': '5', 'cz': '12'} NAV_GRADING_API = 'getNetValueCX' NAV_GRADING_KEY = '' NAV_GRADING_T2 = {'all': '0', 'fjgs': '7', 'fjgg': '8'} NAV_GRADING_T3 = {'all': '0', 'wjzq': '13', 'gp': '14', 'zs': '15', 'czzq': '16', 'jjzq': '17'} NAV_DEFAULT_PAGE = 1 ########################################################################## # 基金数据列名 NAV_OPEN_COLUMNS = ['symbol', 'sname', 'per_nav', 'total_nav', 'yesterday_nav', 'nav_rate', 'nav_a', 'nav_date', 'fund_manager', 'jjlx', 'jjzfe'] NAV_HIS_JJJZ = ['fbrq', 'jjjz', 'ljjz'] NAV_HIS_NHSY = ['fbrq', 'nhsyl', 'dwsy'] FUND_INFO_COLS = ['symbol', 'jjqc', 'jjjc', 'clrq', 'ssrq', 'xcr', 'ssdd', 'Type1Name', 'Type2Name', 'Type3Name', 'jjgm', 'jjfe', 'jjltfe', 'jjferq', 'quarter', 'glr', 'tgr'] NAV_CLOSE_COLUMNS = ['symbol', 'sname', 'per_nav', 'total_nav', 'nav_rate', 'discount_rate', 'nav_date', 'start_date', 'end_date', 'fund_manager', 'jjlx', 'jjzfe'] NAV_GRADING_COLUMNS = ['symbol', 'sname', 'per_nav', 'total_nav', 'nav_rate', 'discount_rate', 'nav_date', 'start_date', 'end_date', 'fund_manager', 'jjlx', 'jjzfe'] NAV_COLUMNS = {'open': NAV_OPEN_COLUMNS, 'close': NAV_CLOSE_COLUMNS, 'grading': NAV_GRADING_COLUMNS} ########################################################################## # 数据源URL SINA_NAV_COUNT_URL = '%s%s/fund_center/data/jsonp.php/IO.XSRV2.CallbackList[\'%s\']/NetValue_Service.%s?ccode=&type2=%s&type3=%s' SINA_NAV_DATA_URL = '%s%s/fund_center/data/jsonp.php/IO.XSRV2.CallbackList[\'%s\']/NetValue_Service.%s?page=%s&num=%s&ccode=&type2=%s&type3=%s' SINA_NAV_HISTROY_COUNT_URL = '%s%s/fundInfo/api/openapi.php/CaihuiFundInfoService.getNav?symbol=%s&datefrom=%s&dateto=%s' SINA_NAV_HISTROY_DATA_URL = '%s%s/fundInfo/api/openapi.php/CaihuiFundInfoService.getNav?symbol=%s&datefrom=%s&dateto=%s&num=%s' SINA_NAV_HISTROY_COUNT_CUR_URL = '%s%s/fundInfo/api/openapi.php/CaihuiFundInfoService.getNavcur?symbol=%s&datefrom=%s&dateto=%s' SINA_NAV_HISTROY_DATA_CUR_URL = '%s%s/fundInfo/api/openapi.php/CaihuiFundInfoService.getNavcur?symbol=%s&datefrom=%s&dateto=%s&num=%s' SINA_DATA_DETAIL_URL = '%s%s/quotes_service/api/%s/Market_Center.getHQNodeData?page=1&num=400&sort=symbol&asc=1&node=%s&symbol=&_s_r_a=page' SINA_FUND_INFO_URL = '%s%s/fundInfo/api/openapi.php/FundPageInfoService.tabjjgk?symbol=%s&format=json' ########################################################################## DATA_GETTING_TIPS = '[Getting data:]' DATA_GETTING_FLAG = '#' DATA_ROWS_TIPS = '%s rows data found.Please wait for a moment.' DATA_INPUT_ERROR_MSG = 'date input error.' NETWORK_URL_ERROR_MSG = '获取失败,请检查网络和URL' DATE_CHK_MSG = '年度输入错误:请输入1989年以后的年份数字,格式:YYYY' DATE_CHK_Q_MSG = '季度输入错误:请输入1、2、3或4数字' TOP_PARAS_MSG = 'top有误,请输入整数或all.' LHB_MSG = '周期输入有误,请输入数字5、10、30或60' OFT_MSG = u'开放型基金类型输入有误,请输入all、equity、mix、bond、monetary、qdii' DICT_NAV_EQUITY = { 'fbrq': 'date', 'jjjz': 'value', 'ljjz': 'total', 'change': 'change' } DICT_NAV_MONETARY = { 'fbrq': 'date', 'nhsyl': 'value', 'dwsy': 'total', 'change': 'change' } import sys PY3 = (sys.version_info[0] >= 3) def _write_head(): sys.stdout.write(DATA_GETTING_TIPS) sys.stdout.flush() def _write_console(): sys.stdout.write(DATA_GETTING_FLAG) sys.stdout.flush() def _write_tips(tip): sys.stdout.write(DATA_ROWS_TIPS % tip) sys.stdout.flush() def _write_msg(msg): sys.stdout.write(msg) sys.stdout.flush() def _check_nav_oft_input(found_type): if found_type not in NAV_OPEN_KEY.keys(): raise TypeError(OFT_MSG) else: return True def _check_input(year, quarter): if isinstance(year, str) or year < 1989: raise TypeError(DATE_CHK_MSG) elif quarter is None or isinstance(quarter, str) or quarter not in [1, 2, 3, 4]: raise TypeError(DATE_CHK_Q_MSG) else: return True ================================================ FILE: tushare/fund/nav.py ================================================ # -*- coding:utf-8 -*- """ 获取基金净值数据接口 Created on 2016/04/03 @author: leo @group : lazytech @contact: lazytech@sina.cn """ from __future__ import division import time import json import re import pandas as pd import numpy as np from tushare.fund import cons as ct from tushare.util import dateu as du try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request def get_nav_open(fund_type='all'): """ 获取开放型基金净值数据 Parameters ------ type:string 开放基金类型: 1. all 所有开放基金 2. equity 股票型开放基金 3. mix 混合型开放基金 4. bond 债券型开放基金 5. monetary 货币型开放基金 6. qdii QDII型开放基金 return ------- DataFrame 开放型基金净值数据(DataFrame): symbol 基金代码 sname 基金名称 per_nav 单位净值 total_nav 累计净值 yesterday_nav 前一日净值 nav_a 涨跌额 nav_rate 增长率(%) nav_date 净值日期 fund_manager 基金经理 jjlx 基金类型 jjzfe 基金总份额 """ if ct._check_nav_oft_input(fund_type) is True: ct._write_head() nums = _get_fund_num(ct.SINA_NAV_COUNT_URL % (ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.NAV_OPEN_KEY[fund_type], ct.NAV_OPEN_API[fund_type], ct.NAV_OPEN_T2[fund_type], ct.NAV_OPEN_T3)) pages = 2 # 分两次请求数据 limit_cnt = int(nums/pages)+1 # 每次取的数量 fund_dfs = [] for page in range(1, pages+1): fund_dfs = _parse_fund_data(ct.SINA_NAV_DATA_URL % (ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.NAV_OPEN_KEY[fund_type], ct.NAV_OPEN_API[fund_type], page, limit_cnt, ct.NAV_OPEN_T2[fund_type], ct.NAV_OPEN_T3)) return pd.concat(fund_dfs, ignore_index=True) def get_nav_close(fund_type='all', sub_type='all'): """ 获取封闭型基金净值数据 Parameters ------ type:string 封闭基金类型: 1. all 所有封闭型基金 2. fbqy 封闭-权益 3. fbzq 封闭债券 sub_type:string 基金子类型: 1. type=all sub_type无效 2. type=fbqy 封闭-权益 *all 全部封闭权益 *ct 传统封基 *cx 创新封基 3. type=fbzq 封闭债券 *all 全部封闭债券 *wj 稳健债券型 *jj 激进债券型 *cz 纯债债券型 return ------- DataFrame 开放型基金净值数据(DataFrame): symbol 基金代码 sname 基金名称 per_nav 单位净值 total_nav 累计净值 nav_rate 增长率(%) discount_rate 折溢价率(%) nav_date 净值日期 start_date 成立日期 end_date 到期日期 fund_manager 基金经理 jjlx 基金类型 jjzfe 基金总份额 """ ct._write_head() nums = _get_fund_num(ct.SINA_NAV_COUNT_URL % (ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.NAV_CLOSE_KEY, ct.NAV_CLOSE_API, ct.NAV_CLOSE_T2[fund_type], ct.NAV_CLOSE_T3[sub_type])) fund_df = _parse_fund_data(ct.SINA_NAV_DATA_URL % (ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.NAV_OPEN_KEY, ct.NAV_CLOSE_API, ct.NAV_DEFAULT_PAGE, nums, ct.NAV_CLOSE_T2[fund_type], ct.NAV_CLOSE_T3[sub_type]), 'close') return fund_df def get_nav_grading(fund_type='all', sub_type='all'): """ 获取分级子基金净值数据 Parameters ------ type:string 封闭基金类型: 1. all 所有分级基金 2. fjgs 分级-固收 3. fjgg 分级-杠杆 sub_type:string 基金子类型(type=all sub_type无效): *all 全部分级债券 *wjzq 稳健债券型 *czzq 纯债债券型 *jjzq 激进债券型 *gp 股票型 *zs 指数型 return ------- DataFrame 开放型基金净值数据(DataFrame): symbol 基金代码 sname 基金名称 per_nav 单位净值 total_nav 累计净值 nav_rate 增长率(%) discount_rate 折溢价率(%) nav_date 净值日期 start_date 成立日期 end_date 到期日期 fund_manager 基金经理 jjlx 基金类型 jjzfe 基金总份额 """ ct._write_head() nums = _get_fund_num(ct.SINA_NAV_COUNT_URL % (ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.NAV_GRADING_KEY, ct.NAV_GRADING_API, ct.NAV_GRADING_T2[fund_type], ct.NAV_GRADING_T3[sub_type])) fund_df = _parse_fund_data(ct.SINA_NAV_DATA_URL % (ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.NAV_GRADING_KEY, ct.NAV_GRADING_API, ct.NAV_DEFAULT_PAGE, nums, ct.NAV_GRADING_T2[fund_type], ct.NAV_GRADING_T3[sub_type]), 'grading') return fund_df def get_nav_history(code, start=None, end=None, retry_count=3, pause=0.001, timeout=10): ''' 获取历史净值数据 Parameters ------ code:string 基金代码 e.g. 000001 start:string 开始日期 format:YYYY-MM-DD 为空时取当前日期 end:string 结束日期 format:YYYY-MM-DD 为空时取去年今日 retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 timeout: int 默认 10s 请求大量数据时的网络超时 return ------- DataFrame date 发布日期 (index) value 基金净值(股票/混合/QDII型基金) / 年华收益(货币/债券基金) total 累计净值(股票/混合/QDII型基金) / 万分收益(货币/债券基金) change 净值增长率(股票/混合/QDII型基金) ''' start = du.today_last_year() if start is None else start end = du.today() if end is None else end # 判断基金类型 ismonetary = False # 是否是债券型和货币型基金 df_fund = get_fund_info(code) fund_type = df_fund.ix[0]['Type2Name'] if (fund_type.find(u'债券型') != -1) or (fund_type.find(u'货币型') != -1): ismonetary = True ct._write_head() nums = _get_nav_histroy_num(code, start, end, ismonetary) data = _parse_nav_history_data( code, start, end, nums, ismonetary, retry_count, pause, timeout) return data def get_fund_info(code): ''' 获取基金基本信息 Parameters ------ code:string 基金代码 e.g. 000001 return ------- DataFrame jjqc 基金全称 jjjc 基金简称 symbol 基金代码 clrq 成立日期 ssrq 上市日期 xcr 存续期限 ssdd 上市地点 Type1Name 运作方式 Type2Name 基金类型 Type3Name 二级分类 jjgm 基金规模(亿元) jjfe 基金总份额(亿份) jjltfe 上市流通份额(亿份) jjferq 基金份额日期 quarter 上市季度 glr 基金管理人 tgr 基金托管人 ''' request = ct.SINA_FUND_INFO_URL % ( ct.P_TYPE['http'], ct.DOMAINS['ssf'], code) text = urlopen(request, timeout=10).read() text = text.decode('gbk') org_js = json.loads(text) status_code = int(org_js['result']['status']['code']) if status_code != 0: status = str(org_js['result']['status']['msg']) raise ValueError(status) data = org_js['result']['data'] fund_df = pd.DataFrame(data, columns=ct.FUND_INFO_COLS, index=[0]) fund_df = fund_df.set_index('symbol') return fund_df def _parse_fund_data(url, fund_type='open'): ct._write_console() try: request = Request(url) text = urlopen(request, timeout=10).read() if text == 'null': return None text = text.decode('gbk') if ct.PY3 else text text = text.split('data:')[1].split(',exec_time')[0] reg = re.compile(r'\,(.*?)\:') text = reg.sub(r',"\1":', text) text = text.replace('"{symbol', '{"symbol') text = text.replace('{symbol', '{"symbol"') if ct.PY3: jstr = json.dumps(text) else: jstr = json.dumps(text, encoding='gbk') org_js = json.loads(jstr) fund_df = pd.DataFrame(pd.read_json(org_js, dtype={'symbol': object}), columns=ct.NAV_COLUMNS[fund_type]) fund_df.fillna(0, inplace=True) return fund_df except Exception as er: print(str(er)) def _get_fund_num(url): """ 获取基金数量 """ ct._write_console() try: request = Request(url) text = urlopen(request, timeout=10).read() text = text.decode('gbk') if text == 'null': raise ValueError('get fund num error') text = text.split('((')[1].split('))')[0] reg = re.compile(r'\,(.*?)\:') text = reg.sub(r',"\1":', text) text = text.replace('{total_num', '{"total_num"') text = text.replace('null', '0') org_js = json.loads(text) nums = org_js["total_num"] return int(nums) except Exception as er: print(str(er)) def _get_nav_histroy_num(code, start, end, ismonetary=False): """ 获取基金历史净值数量 -------- 货币和证券型基金采用的url不同,需要增加基金类型判断 """ ct._write_console() if ismonetary: request = Request(ct.SINA_NAV_HISTROY_COUNT_CUR_URL % (ct.P_TYPE['http'], ct.DOMAINS['ssf'], code, start, end)) else: request = Request(ct.SINA_NAV_HISTROY_COUNT_URL % (ct.P_TYPE['http'], ct.DOMAINS['ssf'], code, start, end)) text = urlopen(request, timeout=10).read() text = text.decode('gbk') org_js = json.loads(text) status_code = int(org_js['result']['status']['code']) if status_code != 0: status = str(org_js['result']['status']['msg']) raise ValueError(status) nums = org_js['result']['data']['total_num'] return int(nums) def _parse_nav_history_data(code, start, end, nums, ismonetary=False, retry_count=3, pause=0.01, timeout=10): if nums == 0: return None for _ in range(retry_count): time.sleep(pause) # try: ct._write_console() if ismonetary: request = Request(ct.SINA_NAV_HISTROY_DATA_CUR_URL % (ct.P_TYPE['http'], ct.DOMAINS['ssf'], code, start, end, nums)) else: request = Request(ct.SINA_NAV_HISTROY_DATA_URL % (ct.P_TYPE['http'], ct.DOMAINS['ssf'], code, start, end, nums)) text = urlopen(request, timeout=timeout).read() text = text.decode('gbk') org_js = json.loads(text) status_code = int(org_js['result']['status']['code']) if status_code != 0: status = str(org_js['result']['status']['msg']) raise ValueError(status) data = org_js['result']['data']['data'] if 'jjjz' in data[0].keys(): fund_df = pd.DataFrame(data, columns=ct.NAV_HIS_JJJZ) fund_df['jjjz'] = fund_df['jjjz'].astype(float) fund_df['ljjz'] = fund_df['ljjz'].astype(float) fund_df.rename(columns=ct.DICT_NAV_EQUITY, inplace=True) else: fund_df = pd.DataFrame(data, columns=ct.NAV_HIS_NHSY) fund_df['nhsyl'] = fund_df['nhsyl'].astype(float) fund_df['dwsy'] = fund_df['dwsy'].astype(float) fund_df.rename(columns=ct.DICT_NAV_MONETARY, inplace=True) #fund_df.fillna(0, inplace=True) if fund_df['date'].dtypes == np.object: fund_df['date'] = pd.to_datetime(fund_df['date']) fund_df = fund_df.set_index('date') fund_df = fund_df.sort_index(ascending=False) fund_df['pre_value'] = fund_df['value'].shift(-1) fund_df['change'] = (fund_df['value'] / fund_df['pre_value'] - 1) * 100 fund_df = fund_df.drop('pre_value', axis=1) return fund_df raise IOError(ct.NETWORK_URL_ERROR_MSG) ================================================ FILE: tushare/futures/__init__.py ================================================ ================================================ FILE: tushare/futures/cons.py ================================================ #!/usr/bin/env python # -*- coding:utf-8 -*- ''' Created on 2016年10月17日 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn ''' P_TYPE = {'http': 'http://', 'ftp': 'ftp://'} DOMAINS = { 'EM': 'eastmoney.com' } PAGES = {'INTL_FUT': 'index.aspx'} INTL_FUTURE_CODE = 'CONX0,GLNZ0,LCPS0,SBCX0,CRCZ0,WHCZ0,SMCZ0,SOCZ0,CTNZ0,HONV0,LALS0,LZNS0,LTNS0,LNKS0,LLDS0,RBTZ0,SBCC0,SMCC0,SOCC0,WHCC0,SGNC0,SFNC0,CTNC0,CRCC0,CCNC0,CFNC0,GLNC0,CONC0,HONC0,RBTC0,OILC0' INTL_FUTURE_URL = '%shq2gjqh.%s/EM_Futures2010NumericApplication/%s?type=z&jsName=quote_future&sortType=A&sortRule=1&jsSort=1&ids=%s&_g=0.%s' INTL_FUTURES_COL = ['code', 'name', 'price', 'open', 'high', 'low', 'preclose', 'vol', 'pct_count', 'pct_change', 'posi', 'b_amount', 's_amount'] ================================================ FILE: tushare/futures/domestic.py ================================================ #!/usr/bin/env python # -*- coding:utf-8 -*- ''' Created on 2017年06月04日 @author: debugo @contact: me@debugo.com ''' import json import datetime from bs4 import BeautifulSoup import pandas as pd from tushare.futures import domestic_cons as ct try: from urllib.request import urlopen, Request from urllib.parse import urlencode from urllib.error import HTTPError from http.client import IncompleteRead except ImportError: from urllib import urlencode from urllib2 import urlopen, Request from urllib2 import HTTPError from httplib import IncompleteRead def get_cffex_daily(date = None): """ 获取中金所日交易数据 Parameters ------ date: 日期 format:YYYY-MM-DD 或 YYYYMMDD 或 datetime.date对象 为空时为当天 Return ------- DataFrame 中金所日交易数据(DataFrame): symbol 合约代码 date 日期 open 开盘价 high 最高价 low 最低价 close 收盘价 volume 成交量 open_interest 持仓量 turnover 成交额 settle 结算价 pre_settle 前结算价 variety 合约类别 或 None(给定日期没有交易数据) """ day = ct.convert_date(date) if date is not None else datetime.date.today() try: html = urlopen(Request(ct.CFFEX_DAILY_URL % (day.strftime('%Y%m'), day.strftime('%d'), day.strftime('%Y%m%d')), headers=ct.SIM_HAEDERS)).read().decode('gbk', 'ignore') except HTTPError as reason: if reason.code != 404: print(ct.CFFEX_DAILY_URL % (day.strftime('%Y%m'), day.strftime('%d'), day.strftime('%Y%m%d')), reason) return if html.find(u'网页错误') >= 0: return html = [i.replace(' ','').split(',') for i in html.split('\n')[:-2] if i[0][0] != u'小' ] if html[0][0]!=u'合约代码': return dict_data = list() day_const = day.strftime('%Y%m%d') for row in html[1:]: m = ct.FUTURE_SYMBOL_PATTERN.match(row[0]) if not m: continue row_dict = {'date': day_const, 'symbol': row[0], 'variety': m.group(1)} for i,field in enumerate(ct.CFFEX_COLUMNS): if row[i+1] == u"": row_dict[field] = 0.0 elif field in ['volume', 'open_interest', 'oi_chg']: row_dict[field] = int(row[i+1]) else: row_dict[field] = float(row[i+1]) row_dict['pre_settle'] = row_dict['close'] - row_dict['change1'] dict_data.append(row_dict) return pd.DataFrame(dict_data)[ct.OUTPUT_COLUMNS] def get_czce_daily(date=None, type="future"): """ 获取郑商所日交易数据 Parameters ------ date: 日期 format:YYYY-MM-DD 或 YYYYMMDD 或 datetime.date对象 为空时为当天 type: 数据类型, 为'future'期货 或 'option'期权二者之一 Return ------- DataFrame 郑商所每日期货交易数据: symbol 合约代码 date 日期 open 开盘价 high 最高价 low 最低价 close 收盘价 volume 成交量 open_interest 持仓量 turnover 成交额 settle 结算价 pre_settle 前结算价 variety 合约类别 或 DataFrame 郑商所每日期权交易数据 symbol 合约代码 date 日期 open 开盘价 high 最高价 low 最低价 close 收盘价 pre_settle 前结算价 settle 结算价 delta 对冲值 volume 成交量 open_interest 持仓量 oi_change 持仓变化 turnover 成交额 implied_volatility 隐含波动率 exercise_volume 行权量 variety 合约类别 None(类型错误或给定日期没有交易数据) """ if type == 'future': url = ct.CZCE_DAILY_URL listed_columns = ct.CZCE_COLUMNS output_columns = ct.OUTPUT_COLUMNS elif type == 'option': url = ct.CZCE_OPTION_URL listed_columns = ct.CZCE_OPTION_COLUMNS output_columns = ct.OPTION_OUTPUT_COLUMNS else: print('invalid type :' + type + ',type should be one of "future" or "option"') return day = ct.convert_date(date) if date is not None else datetime.date.today() try: html = urlopen(Request(url % (day.strftime('%Y'), day.strftime('%Y%m%d')), headers=ct.SIM_HAEDERS)).read().decode('gbk', 'ignore') except HTTPError as reason: if reason.code != 404: print(ct.CZCE_DAILY_URL % (day.strftime('%Y'), day.strftime('%Y%m%d')), reason) return if html.find(u'您的访问出错了') >= 0 or html.find(u'无期权每日行情交易记录') >= 0: return html = [i.replace(' ','').split('|') for i in html.split('\n')[:-4] if i[0][0] != u'小'] if html[1][0] not in [u'品种月份', u'品种代码']: return dict_data = list() day_const = int(day.strftime('%Y%m%d')) for row in html[2:]: m = ct.FUTURE_SYMBOL_PATTERN.match(row[0]) if not m: continue row_dict = {'date': day_const, 'symbol': row[0], 'variety': m.group(1)} for i,field in enumerate(listed_columns): if row[i+1] == "\r": row_dict[field] = 0.0 elif field in ['volume', 'open_interest', 'oi_chg', 'exercise_volume']: row[i+1] = row[i+1].replace(',','') row_dict[field] = int(row[i+1]) else: row[i+1] = row[i+1].replace(',','') row_dict[field] = float(row[i+1]) dict_data.append(row_dict) return pd.DataFrame(dict_data)[output_columns] def get_shfe_vwap(date = None): """ 获取上期所日成交均价数据 Parameters ------ date: 日期 format:YYYY-MM-DD 或 YYYYMMDD 或 datetime.date对象 为空时为当天 Return ------- DataFrame 郑商所日交易数据(DataFrame): symbol 合约代码 date 日期 time_range vwap时段,分09:00-10:15和09:00-15:00两类 vwap 加权平均成交均价 或 None(给定日期没有数据) """ day = ct.convert_date(date) if date is not None else datetime.date.today() try: json_data = json.loads(urlopen(Request(ct.SHFE_VWAP_URL % (day.strftime('%Y%m%d')), headers=ct.SIM_HAEDERS)).read().decode('utf8')) except HTTPError as reason: if reason.code != 404: print(ct.SHFE_DAILY_URL % (day.strftime('%Y%m%d')), reason) return if len(json_data['o_currefprice']) == 0: return df = pd.DataFrame(json_data['o_currefprice']) df['INSTRUMENTID'] = df['INSTRUMENTID'].str.strip() df[':B1'].astype('int16') return df.rename(columns=ct.SHFE_VWAP_COLUMNS)[list(ct.SHFE_VWAP_COLUMNS.values())] def get_shfe_daily(date = None): """ 获取上期所日交易数据 Parameters ------ date: 日期 format:YYYY-MM-DD 或 YYYYMMDD 或 datetime.date对象 为空时为当天 Return ------- DataFrame 上期所日交易数据(DataFrame): symbol 合约代码 date 日期 open 开盘价 high 最高价 low 最低价 close 收盘价 volume 成交量 open_interest 持仓量 turnover 成交额 settle 结算价 pre_settle 前结算价 variety 合约类别 或 None(给定日期没有交易数据) """ day = ct.convert_date(date) if date is not None else datetime.date.today() try: json_data = json.loads(urlopen(Request(ct.SHFE_DAILY_URL % (day.strftime('%Y%m%d')), headers=ct.SIM_HAEDERS)).read().decode('utf8')) except HTTPError as reason: if reason.code != 404: print(ct.SHFE_DAILY_URL % (day.strftime('%Y%m%d')), reason) return if len(json_data['o_curinstrument']) == 0: return df = pd.DataFrame([row for row in json_data['o_curinstrument'] if row['DELIVERYMONTH'] != u'小计' and row['DELIVERYMONTH'] != '']) df['variety'] = df.PRODUCTID.str.slice(0, -6).str.upper() df['symbol'] = df['variety'] + df['DELIVERYMONTH'] df['date'] = day.strftime('%Y%m%d') vwap_df = get_shfe_vwap(day) if vwap_df is not None: df = pd.merge(df, vwap_df[vwap_df.time_range == '9:00-15:00'], on=['date', 'symbol'], how='left') df['turnover'] = df.vwap * df.VOLUME else: print('Failed to fetch SHFE vwap.', day.strftime('%Y%m%d')) df['turnover'] = .0 df.rename(columns=ct.SHFE_COLUMNS, inplace=True) return df[ct.OUTPUT_COLUMNS] def get_dce_daily(date = None, type="future", retries=0): """ 获取大连商品交易所日交易数据 Parameters ------ date: 日期 format:YYYY-MM-DD 或 YYYYMMDD 或 datetime.date对象 为空时为当天 type: 数据类型, 为'future'期货 或 'option'期权二者之一 retries: int, 当前重试次数,达到3次则获取数据失败 Return ------- DataFrame 大商所日交易数据(DataFrame): symbol 合约代码 date 日期 open 开盘价 high 最高价 low 最低价 close 收盘价 volume 成交量 open_interest 持仓量 turnover 成交额 settle 结算价 pre_settle 前结算价 variety 合约类别 或 DataFrame 郑商所每日期权交易数据 symbol 合约代码 date 日期 open 开盘价 high 最高价 low 最低价 close 收盘价 pre_settle 前结算价 settle 结算价 delta 对冲值 volume 成交量 open_interest 持仓量 oi_change 持仓变化 turnover 成交额 implied_volatility 隐含波动率 exercise_volume 行权量 variety 合约类别 或 None(给定日期没有交易数据) """ day = ct.convert_date(date) if date is not None else datetime.date.today() if retries > 3: print("maximum retires for DCE market data: ", day.strftime("%Y%m%d")) return if type == 'future': url = ct.DCE_DAILY_URL + '?' + urlencode({"currDate":day.strftime('%Y%m%d'), "year":day.strftime('%Y'), "month": str(int(day.strftime('%m'))-1), "day":day.strftime('%d')}) listed_columns = ct.DCE_COLUMNS output_columns = ct.OUTPUT_COLUMNS elif type == 'option': url = ct.DCE_DAILY_URL + '?' + urlencode({"currDate":day.strftime('%Y%m%d'), "year":day.strftime('%Y'), "month": str(int(day.strftime('%m'))-1), "day":day.strftime('%d'), "dayQuotes.trade_type": "1"}) listed_columns = ct.DCE_OPTION_COLUMNS output_columns = ct.OPTION_OUTPUT_COLUMNS else: print('invalid type :' + type + ', should be one of "future" or "option"') return try: response = urlopen(Request(url, method='POST', headers=ct.DCE_HEADERS)).read().decode('utf8') except IncompleteRead as reason: return get_dce_daily(day, retries=retries+1) except HTTPError as reason: if reason.code == 504: return get_dce_daily(day, retries=retries+1) elif reason.code != 404: print(ct.DCE_DAILY_URL, reason) return if u'错误:您所请求的网址(URL)无法获取' in response: return get_dce_daily(day, retries=retries+1) elif u'暂无数据' in response: return data = BeautifulSoup(response, 'html.parser').find_all('tr') if len(data) == 0: return dict_data = list() implied_data = list() for idata in data[1:]: if u'小计' in idata.text or u'总计' in idata.text: continue x = idata.find_all('td') if type == 'future': row_dict = {'variety': ct.DCE_MAP[x[0].text.strip()]} row_dict['symbol'] = row_dict['variety'] + x[1].text.strip() for i,field in enumerate(listed_columns): field_content = x[i+2].text.strip() if '-' in field_content: row_dict[field] = 0 elif field in ['volume', 'open_interest']: row_dict[field] = int(field_content.replace(',','')) else: row_dict[field] = float(field_content.replace(',','')) dict_data.append(row_dict) elif len(x) == 16: m = ct.FUTURE_SYMBOL_PATTERN.match(x[1].text.strip()) if not m: continue row_dict = {'symbol': x[1].text.strip(), 'variety': m.group(1).upper(), 'contract_id': m.group(0)} for i,field in enumerate(listed_columns): field_content = x[i+2].text.strip() if '-' in field_content: row_dict[field] = 0 elif field in ['volume', 'open_interest']: row_dict[field] = int(field_content.replace(',','')) else: row_dict[field] = float(field_content.replace(',','')) dict_data.append(row_dict) elif len(x) == 2: implied_data.append({'contract_id': x[0].text.strip(), 'implied_volatility': float(x[1].text.strip())}) df = pd.DataFrame(dict_data) df['date'] = day.strftime('%Y%m%d') if type == 'future': return df[output_columns] else: return pd.merge(df, pd.DataFrame(implied_data), on='contract_id', how='left', indicator=False)[output_columns] def get_future_daily(start = None, end = None, market = 'CFFEX'): """ 获取中金所日交易数据 Parameters ------ start: 开始日期 format:YYYY-MM-DD 或 YYYYMMDD 或 datetime.date对象 为空时为当天 end: 结束数据 format:YYYY-MM-DD 或 YYYYMMDD 或 datetime.date对象 为空时为当天 market: 'CFFEX' 中金所, 'CZCE' 郑商所, 'SHFE' 上期所, 'DCE' 大商所 之一。默认为中金所 Return ------- DataFrame 中金所日交易数据(DataFrame): symbol 合约代码 date 日期 open 开盘价 high 最高价 low 最低价 close 收盘价 volume 成交量 open_interest 持仓量 turnover 成交额 settle 结算价 pre_settle 前结算价 variety 合约类别 或 None(给定日期没有交易数据) """ if market.upper() == 'CFFEX': f = get_cffex_daily elif market.upper() == 'CZCE': f = get_czce_daily elif market.upper() == 'SHFE': f = get_shfe_daily elif market.upper() == 'DCE': f = get_dce_daily else: print('Invalid market.') return start = ct.convert_date(start) if start is not None else datetime.date.today() end = ct.convert_date(end) if end is not None else datetime.date.today() df_list = list() while start <= end: df = f(start) if df is not None: df_list.append(df) start += datetime.timedelta(days = 1) if len(df_list) > 0: return pd.concat(df_list) ================================================ FILE: tushare/futures/domestic_cons.py ================================================ #!/usr/bin/env python # -*- coding:utf-8 -*- ''' Created on 2017年06月04日 @author: debugo @contact: me@debugo.com ''' import re import datetime CFFEX_DAILY_URL = 'http://www.cffex.com.cn/fzjy/mrhq/%s/%s/%s_1.csv' SHFE_DAILY_URL = 'http://www.shfe.com.cn/data/dailydata/kx/kx%s.dat' SHFE_VWAP_URL = 'http://www.shfe.com.cn/data/dailydata/ck/%sdailyTimePrice.dat' DCE_DAILY_URL = 'http://www.dce.com.cn//publicweb/quotesdata/dayQuotesCh.html' CZCE_DAILY_URL = 'http://www.czce.com.cn/portal/DFSStaticFiles/Future/%s/%s/FutureDataDaily.txt' CZCE_OPTION_URL = 'http://www.czce.com.cn/portal/DFSStaticFiles/Option/%s/%s/OptionDataDaily.txt' CFFEX_COLUMNS = ['open','high','low','volume','turnover','open_interest','close','settle','change1','change2'] CZCE_COLUMNS = ['pre_settle','open','high','low','close','settle','change1','change2','volume','open_interest','oi_chg','turnover','final_settle'] CZCE_OPTION_COLUMNS = ['pre_settle', 'open', 'high', 'low', 'close', 'settle', 'change1', 'change2', 'volume', 'open_interest', 'oi_chg', 'turnover', 'delta', 'implied_volatility', 'exercise_volume'] SHFE_COLUMNS = {'CLOSEPRICE': 'close', 'HIGHESTPRICE': 'high', 'LOWESTPRICE': 'low', 'OPENINTEREST': 'open_interest', 'OPENPRICE': 'open', 'PRESETTLEMENTPRICE': 'pre_settle', 'SETTLEMENTPRICE': 'settle', 'VOLUME': 'volume'} SHFE_VWAP_COLUMNS = {':B1': 'date', 'INSTRUMENTID': 'symbol', 'TIME': 'time_range', 'REFSETTLEMENTPRICE': 'vwap'} DCE_COLUMNS = ['open', 'high', 'low', 'close', 'pre_settle', 'settle', 'change1','change2','volume','open_interest','oi_chg','turnover'] DCE_OPTION_COLUMNS = ['open', 'high', 'low', 'close', 'pre_settle', 'settle', 'change1', 'change2', 'delta', 'volume', 'open_interest', 'oi_chg', 'turnover', 'exercise_volume'] OUTPUT_COLUMNS = ['symbol', 'date', 'open', 'high', 'low', 'close', 'volume', 'open_interest', 'turnover', 'settle', 'pre_settle', 'variety'] OPTION_OUTPUT_COLUMNS = ['symbol', 'date', 'open', 'high', 'low', 'close', 'pre_settle', 'settle', 'delta', 'volume', 'open_interest', 'oi_chg', 'turnover', 'implied_volatility', 'exercise_volume', 'variety'] CLOSE_LOC = 5 PRE_SETTLE_LOC = 11 FUTURE_SYMBOL_PATTERN = re.compile(r'(^[A-Za-z]{1,2})[0-9]+') DATE_PATTERN = re.compile(r'^([0-9]{4})[-/]?([0-9]{2})[-/]?([0-9]{2})') SIM_HAEDERS = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'} DCE_HEADERS = { 'cache-control': "no-cache", 'postman-token': "153f42ca-148a-8f03-3302-8172cc4a5185" } def convert_date(date): """ transform a date string to datetime.date object. :param day, string, e.g. 2016-01-01, 20160101 or 2016/01/01 :return: object of datetime.date(such as 2016-01-01) or None """ if isinstance(date, datetime.date): return date elif isinstance(date, str): match = DATE_PATTERN.match(date) if match: groups = match.groups() if len(groups) == 3: return datetime.date(year=int(groups[0]), month=int(groups[1]), day=int(groups[2])) return None DCE_MAP = { '豆一': 'A', '豆二': 'B', '豆粕': 'M', '豆油': 'Y', '棕榈油': 'P', '玉米': 'C', '玉米淀粉': 'CS', '鸡蛋': 'JD', '纤维板': 'FB', '胶合板': 'BB', '聚乙烯': 'L', '聚氯乙烯': 'V', '聚丙烯': 'PP', '焦炭': 'J', '焦煤': 'JM', '铁矿石': 'I' } FUTURE_CODE={ 'IH': ('CFFEX', '上证50指数', 300), 'IF': ('CFFEX', '沪深300指数', 300), 'IC': ('CFFEX', '中证500指数', 200), 'T': ('CFFEX', '10年期国债期货', 10000), 'TF': ('CFFEX', '5年期国债期货', 10000), 'CU': ('SHFE', '沪铜' ,5), 'AL': ('SHFE', '沪铝', 5), 'ZN': ('SHFE', '沪锌', 5), 'PB': ('SHFE', '沪铅', 5), 'NI': ('SHFE', '沪镍', 1), 'SN': ('SHFE', '沪锡', 1), 'AU': ('SHFE', '沪金', 1000), 'AG': ('SHFE', '沪银', 15), 'RB': ('SHFE', '螺纹钢', 10), 'WR': ('SHFE', '线材', 10), 'HC': ('SHFE', '热轧卷板', 10), 'FU': ('SHFE', '燃油', 50), 'BU': ('SHFE', '沥青', 10), 'RU': ('SHFE', '橡胶', 10), 'A': ('DCE', '豆一', 10), 'B': ('DCE', '豆二', 10), 'M': ('DCE', '豆粕', 10), 'Y': ('DCE', '豆油', 10), 'P': ('DCE', '棕榈油', 10), 'C': ('DCE', '玉米', 10), 'CS': ('DCE', '玉米淀粉', 10), 'JD': ('DCE', '鸡蛋', 5), 'FB': ('DCE', '纤维板', 500), 'BB': ('DCE', '胶合板', 500), 'L': ('DCE', '聚乙烯', 5), 'V': ('DCE', '聚氯乙烯', 5), 'PP': ('DCE', '聚丙烯', 5), 'J': ('DCE', '焦炭', 100), 'JM': ('DCE', '焦煤', 60), 'I': ('DCE', '铁矿石', 100), 'SR': ('CZCE', '白糖', 10), 'CF': ('CZCE', '棉花',5), 'PM': ('CZCE', '普麦',50), 'WH': ('CZCE', '强麦',20), 'OI': ('CZCE', '菜籽油',10), 'PTA': ('CZCE', 'PTA', 0), 'RI': ('CZCE', '早籼稻',20), 'LR': ('CZCE', '晚籼稻',20), 'MA': ('CZCE', '甲醇', 10), 'FG': ('CZCE', '玻璃', 20), 'RS': ('CZCE', '油菜籽', 10), 'RM': ('CZCE', '籽粕', 10), 'TC': ('CZCE', '动力煤', 200), 'ZC': ('CZCE', '动力煤', 100), 'JR': ('CZCE', '粳稻', 20), 'SF': ('CZCE', '硅铁', 5), 'SM': ('CZCE', '锰硅', 5) } ================================================ FILE: tushare/futures/intlfutures.py ================================================ # -*- coding:utf-8 -*- """ 国际期货 Created on 2016/10/01 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ import json import six import pandas as pd from tushare.futures import cons as ct try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request def get_intlfuture(symbols=None): symbols = ct.INTL_FUTURE_CODE if symbols is None else symbols df = _get_data(ct.INTL_FUTURE_URL%(ct.P_TYPE['http'], ct.DOMAINS['EM'], ct.PAGES['INTL_FUT'], symbols, _random(17))) return df def _get_data(url): try: request = Request(url) data_str = urlopen(request, timeout=10).read() data_str = data_str.split('=')[1] data_str = data_str.replace('futures', '"futures"') if six.PY3: data_str = data_str.decode('utf-8') data_str = json.loads(data_str) df = pd.DataFrame([[col for col in row.split(',')] for row in data_str.values()[0]] ) df = df[[1, 2, 5, 4, 6, 7, 13, 9, 17, 18, 16, 21, 22]] df.columns = ct.INTL_FUTURES_COL return df except Exception as er: print(str(er)) def _random(n=13): from random import randint start = 10**(n-1) end = (10**n)-1 return str(randint(start, end)) ================================================ FILE: tushare/internet/__init__.py ================================================ ================================================ FILE: tushare/internet/boxoffice.py ================================================ # -*- coding:utf-8 -*- """ 电影票房 Created on 2015/12/24 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ import pandas as pd from tushare.stock import cons as ct from tushare.util import dateu as du try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request import time import json def realtime_boxoffice(retry_count=3,pause=0.001): """ 获取实时电影票房数据 数据来源:EBOT艺恩票房智库 Parameters ------ retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 return ------- DataFrame BoxOffice 实时票房(万) Irank 排名 MovieName 影片名 boxPer 票房占比 (%) movieDay 上映天数 sumBoxOffice 累计票房(万) time 数据获取时间 """ for _ in range(retry_count): time.sleep(pause) try: request = Request(ct.MOVIE_BOX%(ct.P_TYPE['http'], ct.DOMAINS['mbox'], ct.BOX, _random())) lines = urlopen(request, timeout = 10).read() if len(lines) < 15: #no data return None except Exception as e: print(e) else: js = json.loads(lines.decode('utf-8') if ct.PY3 else lines) df = pd.DataFrame(js['data2']) df = df.drop(['MovieImg','mId'], axis=1) df['time'] = du.get_now() return df def day_boxoffice(date=None, retry_count=3, pause=0.001): """ 获取单日电影票房数据 数据来源:EBOT艺恩票房智库 Parameters ------ date:日期,默认为上一日 retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 return ------- DataFrame AvgPrice 平均票价 AvpPeoPle 场均人次 BoxOffice 单日票房(万) BoxOffice_Up 环比变化 (%) IRank 排名 MovieDay 上映天数 MovieName 影片名 SumBoxOffice 累计票房(万) WomIndex 口碑指数 """ for _ in range(retry_count): time.sleep(pause) try: if date is None: date = 0 else: date = int(du.diff_day(du.today(), date)) + 1 request = Request(ct.BOXOFFICE_DAY%(ct.P_TYPE['http'], ct.DOMAINS['mbox'], ct.BOX, date, _random())) lines = urlopen(request, timeout = 10).read() if len(lines) < 15: #no data return None except Exception as e: print(e) else: js = json.loads(lines.decode('utf-8') if ct.PY3 else lines) df = pd.DataFrame(js['data1']) df = df.drop(['MovieImg', 'BoxOffice1', 'MovieID', 'Director', 'IRank_pro'], axis=1) return df def month_boxoffice(date=None, retry_count=3, pause=0.001): """ 获取单月电影票房数据 数据来源:EBOT艺恩票房智库 Parameters ------ date:日期,默认为上一月,格式YYYY-MM retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 return ------- DataFrame Irank 排名 MovieName 电影名称 WomIndex 口碑指数 avgboxoffice 平均票价 avgshowcount 场均人次 box_pro 月度占比 boxoffice 单月票房(万) days 月内天数 releaseTime 上映日期 """ if date is None: date = du.day_last_week(-30)[0:7] elif len(date)>8: print(ct.BOX_INPUT_ERR_MSG) return date += '-01' for _ in range(retry_count): time.sleep(pause) try: request = Request(ct.BOXOFFICE_MONTH%(ct.P_TYPE['http'], ct.DOMAINS['mbox'], ct.BOX, date)) lines = urlopen(request, timeout = 10).read() if len(lines) < 15: #no data return None except Exception as e: print(e) else: js = json.loads(lines.decode('utf-8') if ct.PY3 else lines) df = pd.DataFrame(js['data1']) df = df.drop(['defaultImage', 'EnMovieID'], axis=1) return df def day_cinema(date=None, retry_count=3, pause=0.001): """ 获取影院单日票房排行数据 数据来源:EBOT艺恩票房智库 Parameters ------ date:日期,默认为上一日 retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 return ------- DataFrame Attendance 上座率 AvgPeople 场均人次 CinemaName 影院名称 RowNum 排名 TodayAudienceCount 当日观众人数 TodayBox 当日票房 TodayShowCount 当日场次 price 场均票价(元) """ if date is None: date = du.day_last_week(-1) data = pd.DataFrame() ct._write_head() for x in range(1, 11): df = _day_cinema(date, x, retry_count, pause) if df is not None: data = pd.concat([data, df]) data = data.drop_duplicates() return data.reset_index(drop=True) def _day_cinema(date=None, pNo=1, retry_count=3, pause=0.001): ct._write_console() for _ in range(retry_count): time.sleep(pause) try: request = Request(ct.BOXOFFICE_CBD%(ct.P_TYPE['http'], ct.DOMAINS['mbox'], ct.BOX, pNo, date)) lines = urlopen(request, timeout = 10).read() if len(lines) < 15: #no data return None except Exception as e: print(e) else: js = json.loads(lines.decode('utf-8') if ct.PY3 else lines) df = pd.DataFrame(js['data1']) df = df.drop(['CinemaID'], axis=1) return df def _random(n=13): from random import randint start = 10**(n-1) end = (10**n)-1 return str(randint(start, end)) ================================================ FILE: tushare/internet/caixinnews.py ================================================ # -*- coding:utf-8 -*- """ 财新网新闻数据检索下载 Created on 2017/06/09 @author: Yuan Yifan @group : ~ @contact: tsingjyujing@163.com """ """ # 测试脚本 from caixinnews import * urls = query_news(start_date='2017-05-09',end_date='2017-05-09') title,text = read_page(urls[0]) print(title) print(text) """ import re import datetime from bs4 import BeautifulSoup try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request caixin_search_url = "http://search.caixin.com/search/search.jsp?startDate=%s&endDate=%s&keyword=%s&x=0&y=0" default_parser = "html.parser" #default_parser = "lxml" UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "+\ "AppleWebKit/537.36 (KHTML, like Gecko) "+\ "Chrome/42.0.2311.135 "+\ "Safari/537.36 "+\ "Edge/12.10240" req_header = {\ 'User-Agent': UA,\ 'Accept': '"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"',\ 'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3'} req_timeout = 10 def read_url(url): """ 读取URL对应的内容(模拟浏览器) Parameters ------ url string 需要读取的链接 Return ------ string 读取的内容 """ req_header_this = req_header req_header_this['Host'] = re.findall('://.*?/',url,re.DOTALL)[0][3:-1] return urlopen(Request(url,None,req_header),None,req_timeout).read() def get_soup(url): """ 读取URL对应的内容,并解析为Soup Parameters url string 需要读取的链接 Return string 读取的内容 """ return BeautifulSoup(read_url(url), default_parser) def query_news(keywords='*',start_date=None,end_date=None): """ 读取某一时间段对应的新闻链接列表 Parameters ------ keywords string 关键词 start_date string 开始日期,格式yyyy-mm-dd end_date string 结束日期,格式yyyy-mm-dd Return ------ List 读取的内容 """ if start_date is None or end_date is None: now_time = datetime.datetime.now() last_day = datetime.datetime(now_time.year,now_time.month,now_time.day,12,0) - datetime.timedelta(seconds = 3600*24) start_date = last_day.strftime("%Y-%m-%d") end_date = start_date url = caixin_search_url % (start_date,end_date,keywords) soup = get_soup(url) info_urls = [] while(True): next_info = soup.find_all(name='a',attrs={'class','pageNavBtn2'})[0] all_res = soup.find_all(name='div',attrs={'class','searchxt'}) for res in all_res: info_urls.append(res.a.attrs['href']) next_info = next_info.attrs['href'] if next_info=="javascript:void();": break; else: soup = get_soup(caixin_search_url+next_info) return info_urls def is_blog(url): """ 判断某一链接是否博客 Parameters ------ url string 需要判断的链接 Return ------ bool 该url是否是博客URL """ return len(re.findall('blog\.caixin\.com',url))>0 def read_page(url): """ 读取链接的内容 Parameters ------ url string 需要判断的链接 Return ------ title string 文章标题 text string 文章内容 """ if is_blog(url): return read_blog(url) else: return read_normal_artical(url) def read_normal_artical(url): soup = get_soup(url) title = soup.title.get_text() ps = soup.find_all('p') text = '' for p in ps: text += p.get_text() + "\n" return title,text def read_blog(url): soup = get_soup(url) title = soup.title.get_text() bcontent = soup.find_all(name='div',attrs={'class','blog_content'}) ps = bcontent[0].find_all('p') text = '' for p in ps: text += p.get_text() + "\n" return title,text ================================================ FILE: tushare/internet/indexes.py ================================================ #!/usr/bin/env python # -*- coding:utf-8 -*- """ 龙虎榜数据 Created on 2017年8月13日 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ import pandas as pd from pandas.compat import StringIO from tushare.stock import cons as ct import time import re import lxml.html from lxml import etree try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request def bdi(itype='D', retry_count=3, pause=0.001): for _ in range(retry_count): time.sleep(pause) try: request = Request(ct.BDI_URL%(ct.P_TYPE['http'], ct.DOMAINS['v500'])) lines = urlopen(request, timeout = 10).read() if len(lines) < 100: #no data return None except Exception as e: print(e) else: linestr = lines.decode('utf-8') if ct.PY3 else lines if itype == 'D': # Daily reg = re.compile(r'\"chart_data\",\"(.*?)\"\);') lines = reg.findall(linestr) lines = lines[0] lines = lines.replace('chart', 'table').\ replace('', '').\ replace('', '').\ replace('series', 'tr').\ replace('value', 'td').\ replace('graph', 'tr').\ replace('graphs', 'td') df = pd.read_html(lines, encoding='utf8')[0] df = df.T df.columns = ['date', 'index'] df['date'] = df['date'].map(lambda x: x.replace(u'年', '-')).\ map(lambda x: x.replace(u'月', '-')).\ map(lambda x: x.replace(u'日', '')) df['date'] = pd.to_datetime(df['date']) df['index'] = df['index'].astype(float) df = df.sort_values('date', ascending=False).reset_index(drop = True) df['change'] = df['index'].pct_change(-1) df['change'] = df['change'] * 100 df['change'] = df['change'].map(lambda x: '%.2f' % x) df['change'] = df['change'].astype(float) return df else: #Weekly html = lxml.html.parse(StringIO(linestr)) res = html.xpath("//table[@class=\"style33\"]/tr/td/table[last()]") if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = '%s
'%sarr df = pd.read_html(sarr)[0][1:] df.columns = ['month', 'index'] df['month'] = df['month'].map(lambda x: x.replace(u'年', '-')).\ map(lambda x: x.replace(u'月', '')) df['month'] = pd.to_datetime(df['month']) df['month'] = df['month'].map(lambda x: str(x).replace('-', '')).\ map(lambda x: x[:6]) df['index'] = df['index'].astype(float) df['change'] = df['index'].pct_change(-1) df['change'] = df['change'].map(lambda x: '%.2f' % x) df['change'] = df['change'].astype(float) return df ================================================ FILE: tushare/pro/__init__.py ================================================ ================================================ FILE: tushare/pro/client.py ================================================ # !/usr/bin/env python # -*- coding: utf-8 -*- """ Pro数据接口 Created on 2017/07/01 @author: polo,Jimmy @group : tushare.pro """ import pandas as pd import simplejson as json from functools import partial import requests class DataApi: __token = '' __http_url = 'http://api.tushare.pro' def __init__(self, token, timeout=10): """ Parameters ---------- token: str API接口TOKEN,用于用户认证 """ self.__token = token self.__timeout = timeout def query(self, api_name, fields='', **kwargs): req_params = { 'api_name': api_name, 'token': self.__token, 'params': kwargs, 'fields': fields } res = requests.post(self.__http_url, json=req_params, timeout=self.__timeout) result = json.loads(res.text) if result['code'] != 0: raise Exception(result['msg']) data = result['data'] columns = data['fields'] items = data['items'] return pd.DataFrame(items, columns=columns) def __getattr__(self, name): return partial(self.query, name) ================================================ FILE: tushare/pro/data_pro.py ================================================ # -*- coding:utf-8 -*- """ pro init Created on 2018/07/01 @author: Jimmy Liu @group : tushare.pro @contact: jimmysoa@sina.cn """ from tushare.pro import client from tushare.util import upass from tushare.util.formula import MA PRICE_COLS = ['open', 'close', 'high', 'low', 'pre_close'] FORMAT = lambda x: '%.2f' % x FREQS = {'D': '1DAY', 'W': '1WEEK', 'Y': '1YEAR', } def pro_api(token=''): """ 初始化pro API,第一次可以通过ts.set_token('your token')来记录自己的token凭证,临时token可以通过本参数传入 """ if token == '' or token is None: token = upass.get_token() if token is not None and token != '': pro = client.DataApi(token) return pro else: raise Exception('api init error.') def pro_bar(ts_code='', pro_api=None, start_date=None, end_date=None, freq='D', asset='E', exchange='', adj = None, ma = [], factors = None, contract_type = '', retry_count = 3): """ BAR数据 Parameters: ------------ ts_code:证券代码,支持股票,ETF/LOF,期货/期权,港股,数字货币 start_date:开始日期 YYYYMMDD end_date:结束日期 YYYYMMDD freq:支持1/5/15/30/60分钟,周/月/季/年 asset:证券类型 E:股票和交易所基金,I:沪深指数,C:数字货币,FT:期货 FD:基金/O期权/H港股/中概美国/中证指数/国际指数 exchange:市场代码,用户数字货币行情 adj:复权类型,None不复权,qfq:前复权,hfq:后复权 ma:均线,支持自定义均线频度,如:ma5/ma10/ma20/ma60/maN factors因子数据,目前支持以下两种: vr:量比,默认不返回,返回需指定:factor=['vr'] tor:换手率,默认不返回,返回需指定:factor=['tor'] 以上两种都需要:factor=['vr', 'tor'] retry_count:网络重试次数 Return ---------- DataFrame code:代码 open:开盘close/high/low/vol成交量/amount成交额/maN均价/vr量比/tor换手率 期货(asset='X') code/open/close/high/low/avg_price:均价 position:持仓量 vol:成交总量 """ ts_code = ts_code.strip().upper() if asset != 'C' else ts_code.strip().lower() api = pro_api if pro_api is not None else pro_api() for _ in range(retry_count): try: freq = freq.strip().upper() if asset != 'C' else freq.strip().lower() asset = asset.strip().upper() if asset == 'E': if freq == 'D': df = api.daily(ts_code=ts_code, start_date=start_date, end_date=end_date) if factors is not None and len(factors) >0 : ds = api.daily_basic(ts_code=ts_code, start_date=start_date, end_date=end_date)[['trade_date', 'turnover_rate', 'volume_ratio']] ds = ds.set_index('trade_date') df = df.set_index('trade_date') df = df.merge(ds, left_index=True, right_index=True) df = df.reset_index() if ('tor' in factors) and ('vr' not in factors): df = df.drop('volume_ratio', axis=1) if ('vr' in factors) and ('tor' not in factors): df = df.drop('turnover_rate', axis=1) if freq == 'W': df = api.weekly(ts_code=ts_code, start_date=start_date, end_date=end_date) if freq == 'M': df = api.monthly(ts_code=ts_code, start_date=start_date, end_date=end_date) if adj is not None: fcts = api.adj_factor(ts_code=ts_code, start_date=start_date, end_date=end_date)[['trade_date', 'adj_factor']] data = df.set_index('trade_date', drop=False).merge(fcts.set_index('trade_date'), left_index=True, right_index=True, how='left') data['adj_factor'] = data['adj_factor'].fillna(method='bfill') for col in PRICE_COLS: if adj == 'hfq': data[col] = data[col] * data['adj_factor'] else: data[col] = data[col] * data['adj_factor'] / float(fcts['adj_factor'][0]) data[col] = data[col].map(FORMAT) for col in PRICE_COLS: data[col] = data[col].astype(float) data = data.drop('adj_factor', axis=1) df['change'] = df['close'] - df['pre_close'] df['pct_change'] = df['close'].pct_change() * 100 else: data = df elif asset == 'I': if freq == 'D': data = api.index_daily(ts_code=ts_code, start_date=start_date, end_date=end_date) elif asset == 'FT': if freq == 'D': data = api.fut_daily(ts_code=ts_code, start_dae=start_date, end_date=end_date, exchange=exchange) elif asset == 'O': if freq == 'D': data = api.opt_daily(ts_code=ts_code, start_dae=start_date, end_date=end_date, exchange=exchange) elif asset == 'FD': if freq == 'D': data = api.fund_daily(ts_code=ts_code, start_dae=start_date, end_date=end_date) if asset == 'C': if freq == 'd': freq = 'daily' elif freq == 'w': freq = 'week' data = api.coinbar(exchange=exchange, symbol=ts_code, freq=freq, start_dae=start_date, end_date=end_date, contract_type=contract_type) if ma is not None and len(ma) > 0: for a in ma: if isinstance(a, int): data['ma%s'%a] = MA(data['close'], a).map(FORMAT).shift(-(a-1)) data['ma%s'%a] = data['ma%s'%a].astype(float) data['ma_v_%s'%a] = MA(data['vol'], a).map(FORMAT).shift(-(a-1)) data['ma_v_%s'%a] = data['ma_v_%s'%a].astype(float) return data except Exception as e: print(e) return None else: return raise IOError('ERROR.') if __name__ == '__main__': # upass.set_token('your token here') pro = pro_api() # print(pro_bar(ts_code='000001.SZ', pro_api=pro, start_date='19990101', end_date='', adj='qfq', ma=[5, 10, 15])) # print(pro_bar(ts_code='000905.SH', pro_api=pro, start_date='20181001', end_date='', asset='I')) # print(pro.trade_cal(exchange_id='', start_date='20131031', end_date='', fields='pretrade_date', is_open='0')) # print(pro_bar(ts_code='CU1811.SHF', pro_api=pro, start_date='20180101', end_date='', asset='FT', ma=[5, 10, 15])) # print(pro_bar(ts_code='150023.SZ', pro_api=pro, start_date='20180101', end_date='', asset='FD', ma=[5, 10, 15])) # print(pro_bar(pro_api=pro, ts_code='000528.SZ',start_date='20180101', end_date='20181121', ma=[20])) # print(pro_bar(ts_code='000528.SZ', pro_api=pro, freq='W', start_date='20180101', end_date='20180820', adj='hfq', ma=[5, 10, 15])) # print(pro_bar(ts_code='000528.SZ', pro_api=pro, freq='M', start_date='20180101', end_date='20180820', adj='qfq', ma=[5, 10, 15])) # print(pro_bar(ts_code='btcusdt', pro_api=pro, exchange='huobi', freq='D', start_date='20180101', end_date='20181123', asset='C', ma=[5, 10])) # df = pro_bar(ts_code='000001.SZ', pro_api=pro, adj='qfq', start_date='19900101', end_date='20050509') df = pro_bar(ts_code='600862.SH', pro_api=pro, start_date='20150118', end_date='20150615', factors=['tor', 'vr']) print(df) ================================================ FILE: tushare/stock/__init__.py ================================================ ================================================ FILE: tushare/stock/billboard.py ================================================ #!/usr/bin/env python # -*- coding:utf-8 -*- """ 龙虎榜数据 Created on 2015年6月10日 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ import pandas as pd from pandas.compat import StringIO from tushare.stock import cons as ct import numpy as np import time import json import re import lxml.html from lxml import etree from tushare.util import dateu as du from tushare.stock import ref_vars as rv try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request def top_list(date = None, retry_count=3, pause=0.001): """ 获取每日龙虎榜列表 Parameters -------- date:string 明细数据日期 format:YYYY-MM-DD 如果为空,返回最近一个交易日的数据 retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 Return ------ DataFrame code:代码 name :名称 pchange:涨跌幅 amount:龙虎榜成交额(万) buy:买入额(万) bratio:占总成交比例 sell:卖出额(万) sratio :占总成交比例 reason:上榜原因 date :日期 """ if date is None: if du.get_hour() < 18: date = du.last_tddate() else: date = du.today() else: if(du.is_holiday(date)): return None for _ in range(retry_count): time.sleep(pause) try: request = Request(rv.LHB_URL%(ct.P_TYPE['http'], ct.DOMAINS['em'], date, date)) text = urlopen(request, timeout=10).read() text = text.decode('GBK') text = text.split('_1=')[1] text = eval(text, type('Dummy', (dict,), dict(__getitem__ = lambda s, n:n))()) text = json.dumps(text) text = json.loads(text) df = pd.DataFrame(text['data'], columns=rv.LHB_TMP_COLS) df.columns = rv.LHB_COLS df = df.fillna(0) df = df.replace('', 0) df['buy'] = df['buy'].astype(float) df['sell'] = df['sell'].astype(float) df['amount'] = df['amount'].astype(float) df['Turnover'] = df['Turnover'].astype(float) df['bratio'] = df['buy'] / df['Turnover'] df['sratio'] = df['sell'] /df['Turnover'] df['bratio'] = df['bratio'].map(ct.FORMAT) df['sratio'] = df['sratio'].map(ct.FORMAT) df['date'] = date for col in ['amount', 'buy', 'sell']: df[col] = df[col].astype(float) df[col] = df[col] / 10000 df[col] = df[col].map(ct.FORMAT) df = df.drop('Turnover', axis=1) except Exception as e: print(e) else: return df raise IOError(ct.NETWORK_URL_ERROR_MSG) def cap_tops(days= 5, retry_count= 3, pause= 0.001): """ 获取个股上榜统计数据 Parameters -------- days:int 天数,统计n天以来上榜次数,默认为5天,其余是10、30、60 retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 Return ------ DataFrame code:代码 name:名称 count:上榜次数 bamount:累积购买额(万) samount:累积卖出额(万) net:净额(万) bcount:买入席位数 scount:卖出席位数 """ if ct._check_lhb_input(days) is True: ct._write_head() df = _cap_tops(days, pageNo=1, retry_count=retry_count, pause=pause) if df is not None: df['code'] = df['code'].map(lambda x: str(x).zfill(6)) df = df.drop_duplicates('code') return df def _cap_tops(last=5, pageNo=1, retry_count=3, pause=0.001, dataArr=pd.DataFrame()): ct._write_console() for _ in range(retry_count): time.sleep(pause) try: request = Request(rv.LHB_SINA_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], rv.LHB_KINDS[0], ct.PAGES['fd'], last, pageNo)) text = urlopen(request, timeout=10).read() text = text.decode('GBK') html = lxml.html.parse(StringIO(text)) res = html.xpath("//table[@id=\"dataTable\"]/tr") if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = '%s
'%sarr df = pd.read_html(sarr)[0] df.columns = rv.LHB_GGTJ_COLS dataArr = dataArr.append(df, ignore_index=True) nextPage = html.xpath('//div[@class=\"pages\"]/a[last()]/@onclick') if len(nextPage)>0: pageNo = re.findall(r'\d+', nextPage[0])[0] return _cap_tops(last, pageNo, retry_count, pause, dataArr) else: return dataArr except Exception as e: print(e) def broker_tops(days= 5, retry_count= 3, pause= 0.001): """ 获取营业部上榜统计数据 Parameters -------- days:int 天数,统计n天以来上榜次数,默认为5天,其余是10、30、60 retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 Return --------- broker:营业部名称 count:上榜次数 bamount:累积购买额(万) bcount:买入席位数 samount:累积卖出额(万) scount:卖出席位数 top3:买入前三股票 """ if ct._check_lhb_input(days) is True: ct._write_head() df = _broker_tops(days, pageNo=1, retry_count=retry_count, pause=pause) return df def _broker_tops(last=5, pageNo=1, retry_count=3, pause=0.001, dataArr=pd.DataFrame()): ct._write_console() for _ in range(retry_count): time.sleep(pause) try: request = Request(rv.LHB_SINA_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], rv.LHB_KINDS[1], ct.PAGES['fd'], last, pageNo)) text = urlopen(request, timeout=10).read() text = text.decode('GBK') html = lxml.html.parse(StringIO(text)) res = html.xpath("//table[@id=\"dataTable\"]/tr") if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = '%s
'%sarr df = pd.read_html(sarr)[0] df.columns = rv.LHB_YYTJ_COLS dataArr = dataArr.append(df, ignore_index=True) nextPage = html.xpath('//div[@class=\"pages\"]/a[last()]/@onclick') if len(nextPage)>0: pageNo = re.findall(r'\d+', nextPage[0])[0] return _broker_tops(last, pageNo, retry_count, pause, dataArr) else: return dataArr except Exception as e: print(e) def inst_tops(days= 5, retry_count= 3, pause= 0.001): """ 获取机构席位追踪统计数据 Parameters -------- days:int 天数,统计n天以来上榜次数,默认为5天,其余是10、30、60 retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 Return -------- code:代码 name:名称 bamount:累积买入额(万) bcount:买入次数 samount:累积卖出额(万) scount:卖出次数 net:净额(万) """ if ct._check_lhb_input(days) is True: ct._write_head() df = _inst_tops(days, pageNo=1, retry_count=retry_count, pause=pause) df['code'] = df['code'].map(lambda x: str(x).zfill(6)) return df def _inst_tops(last=5, pageNo=1, retry_count=3, pause=0.001, dataArr=pd.DataFrame()): ct._write_console() for _ in range(retry_count): time.sleep(pause) try: request = Request(rv.LHB_SINA_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], rv.LHB_KINDS[2], ct.PAGES['fd'], last, pageNo)) text = urlopen(request, timeout=10).read() text = text.decode('GBK') html = lxml.html.parse(StringIO(text)) res = html.xpath("//table[@id=\"dataTable\"]/tr") if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = '%s
'%sarr df = pd.read_html(sarr)[0] df = df.drop([2,3], axis=1) df.columns = rv.LHB_JGZZ_COLS dataArr = dataArr.append(df, ignore_index=True) nextPage = html.xpath('//div[@class=\"pages\"]/a[last()]/@onclick') if len(nextPage)>0: pageNo = re.findall(r'\d+', nextPage[0])[0] return _inst_tops(last, pageNo, retry_count, pause, dataArr) else: return dataArr except Exception as e: print(e) def inst_detail(retry_count= 3, pause= 0.001): """ 获取最近一个交易日机构席位成交明细统计数据 Parameters -------- retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 Return ---------- code:股票代码 name:股票名称 date:交易日期 bamount:机构席位买入额(万) samount:机构席位卖出额(万) type:类型 """ ct._write_head() df = _inst_detail(pageNo=1, retry_count=retry_count, pause=pause) if len(df)>0: df['code'] = df['code'].map(lambda x: str(x).zfill(6)) return df def _inst_detail(pageNo=1, retry_count=3, pause=0.001, dataArr=pd.DataFrame()): ct._write_console() for _ in range(retry_count): time.sleep(pause) try: request = Request(rv.LHB_SINA_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], rv.LHB_KINDS[3], ct.PAGES['fd'], '', pageNo)) text = urlopen(request, timeout=10).read() text = text.decode('GBK') html = lxml.html.parse(StringIO(text)) res = html.xpath("//table[@id=\"dataTable\"]/tr") if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = '%s
'%sarr df = pd.read_html(sarr)[0] df.columns = rv.LHB_JGMX_COLS dataArr = dataArr.append(df, ignore_index=True) nextPage = html.xpath('//div[@class=\"pages\"]/a[last()]/@onclick') if len(nextPage)>0: pageNo = re.findall(r'\d+', nextPage[0])[0] return _inst_detail(pageNo, retry_count, pause, dataArr) else: return dataArr except Exception as e: print(e) def _f_rows(x): if '%' in x[3]: x[11] = x[6] for i in range(6, 11): x[i] = x[i-5] for i in range(1, 6): x[i] = np.NaN return x ================================================ FILE: tushare/stock/classifying.py ================================================ # -*- coding:utf-8 -*- """ 获取股票分类数据接口 Created on 2015/02/01 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ import pandas as pd from tushare.stock import cons as ct from tushare.stock import ref_vars as rv import json import re from pandas.util.testing import _network_error_classes import time import tushare.stock.fundamental as fd from tushare.util.netbase import Client try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request def get_industry_classified(standard='sina'): """ 获取行业分类数据 Parameters ---------- standard sina:新浪行业 sw:申万 行业 Returns ------- DataFrame code :股票代码 name :股票名称 c_name :行业名称 """ if standard == 'sw': # df = _get_type_data(ct.SINA_INDUSTRY_INDEX_URL%(ct.P_TYPE['http'], # ct.DOMAINS['vsf'], ct.PAGES['ids_sw'])) df = pd.read_csv(ct.TSDATA_CLASS%(ct.P_TYPE['http'], ct.DOMAINS['oss'], 'industry_sw'), dtype={'code':object}) else: # df = _get_type_data(ct.SINA_INDUSTRY_INDEX_URL%(ct.P_TYPE['http'], # ct.DOMAINS['vsf'], ct.PAGES['ids'])) df = pd.read_csv(ct.TSDATA_CLASS%(ct.P_TYPE['http'], ct.DOMAINS['oss'], 'industry'), dtype={'code':object}) # data = [] # ct._write_head() # for row in df.values: # rowDf = _get_detail(row[0], retry_count=10, pause=0.01) # rowDf['c_name'] = row[1] # data.append(rowDf) # data = pd.concat(data, ignore_index=True) return df def get_concept_classified(): """ 获取概念分类数据 Return -------- DataFrame code :股票代码 name :股票名称 c_name :概念名称 """ df = pd.read_csv(ct.TSDATA_CLASS%(ct.P_TYPE['http'], ct.DOMAINS['oss'], 'concept'), dtype={'code':object}) return df def concetps(): ct._write_head() df = _get_type_data(ct.SINA_CONCEPTS_INDEX_URL%(ct.P_TYPE['http'], ct.DOMAINS['sf'], ct.PAGES['cpt'])) data = [] for row in df.values: rowDf = _get_detail(row[0]) if rowDf is not None: rowDf['c_name'] = row[1] data.append(rowDf) if len(data) > 0: data = pd.concat(data, ignore_index=True) data.to_csv('d:\\cpt.csv', index=False) def get_concepts(src='dfcf'): """ 获取概念板块行情数据 Return -------- DataFrame code :股票代码 name :股票名称 c_name :概念名称 """ clt = Client(ct.ET_CONCEPTS_INDEX_URL%(ct.P_TYPE['http'], ct.DOMAINS['dfcf'], _random(15)), ref='') content = clt.gvalue() content = content.decode('utf-8') if ct.PY3 else content js = json.loads(content) data = [] for row in js: cols = row.split(',') cs = cols[6].split('|') arr = [cols[2], cols[3], cs[0], cs[2], cols[7], cols[9]] data.append(arr) df = pd.DataFrame(data, columns=['concept', 'change', 'up', 'down', 'top_code', 'top_name']) return df def get_area_classified(): """ 获取地域分类数据 Return -------- DataFrame code :股票代码 name :股票名称 area :地域名称 """ df = fd.get_stock_basics() df = df[['name', 'area']] df.reset_index(inplace=True) df = df.sort_values('area').reset_index(drop=True) return df def get_gem_classified(): """ 获取创业板股票 Return -------- DataFrame code :股票代码 name :股票名称 """ df = fd.get_stock_basics() df.reset_index(inplace=True) df = df[ct.FOR_CLASSIFY_COLS] df = df.ix[df.code.str[0] == '3'] df = df.sort_values('code').reset_index(drop=True) return df def get_sme_classified(): """ 获取中小板股票 Return -------- DataFrame code :股票代码 name :股票名称 """ df = fd.get_stock_basics() df.reset_index(inplace=True) df = df[ct.FOR_CLASSIFY_COLS] df = df.ix[df.code.str[0:3] == '002'] df = df.sort_values('code').reset_index(drop=True) return df def get_st_classified(): """ 获取风险警示板股票 Return -------- DataFrame code :股票代码 name :股票名称 """ df = fd.get_stock_basics() df.reset_index(inplace=True) df = df[ct.FOR_CLASSIFY_COLS] df = df.ix[df.name.str.contains('ST')] df = df.sort_values('code').reset_index(drop=True) return df def _get_detail(tag, retry_count=3, pause=0.001): dfc = pd.DataFrame() p = 0 num_limit = 100 while(True): p = p+1 for _ in range(retry_count): time.sleep(pause) try: ct._write_console() request = Request(ct.SINA_DATA_DETAIL_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['jv'], p,tag)) text = urlopen(request, timeout=10).read() text = text.decode('gbk') except _network_error_classes: pass else: break reg = re.compile(r'\,(.*?)\:') text = reg.sub(r',"\1":', text) text = text.replace('"{symbol', '{"symbol') text = text.replace('{symbol', '{"symbol"') jstr = json.dumps(text) js = json.loads(jstr) df = pd.DataFrame(pd.read_json(js, dtype={'code':object}), columns=ct.THE_FIELDS) # df = df[ct.FOR_CLASSIFY_B_COLS] df = df[['code', 'name']] dfc = pd.concat([dfc, df]) if df.shape[0] < num_limit: return dfc #raise IOError(ct.NETWORK_URL_ERROR_MSG) def _get_type_data(url): try: request = Request(url) data_str = urlopen(request, timeout=10).read() data_str = data_str.decode('GBK') data_str = data_str.split('=')[1] data_json = json.loads(data_str) df = pd.DataFrame([[row.split(',')[0], row.split(',')[1]] for row in data_json.values()], columns=['tag', 'name']) return df except Exception as er: print(str(er)) def get_hs300s(): """ 获取沪深300当前成份股及所占权重 Return -------- DataFrame code :股票代码 name :股票名称 date :日期 weight:权重 """ try: wt = pd.read_excel(ct.HS300_CLASSIFY_URL_FTP%(ct.P_TYPE['http'], ct.DOMAINS['idx'], ct.PAGES['hs300w']), usecols=[0, 4, 5, 8]) wt.columns = ct.FOR_CLASSIFY_W_COLS wt['code'] = wt['code'].map(lambda x :str(x).zfill(6)) return wt except Exception as er: print(str(er)) def get_sz50s(): """ 获取上证50成份股 Return -------- DataFrame date :日期 code :股票代码 name :股票名称 """ try: df = pd.read_excel(ct.SZ_CLASSIFY_URL_FTP%(ct.P_TYPE['http'], ct.DOMAINS['idx'], ct.PAGES['sz50b']), parse_cols=[0, 4, 5]) df.columns = ct.FOR_CLASSIFY_B_COLS df['code'] = df['code'].map(lambda x :str(x).zfill(6)) return df except Exception as er: print(str(er)) def get_zz500s(): """ 获取中证500成份股 Return -------- DataFrame date :日期 code :股票代码 name :股票名称 weight : 权重 """ try: wt = pd.read_excel(ct.HS300_CLASSIFY_URL_FTP%(ct.P_TYPE['http'], ct.DOMAINS['idx'], ct.PAGES['zz500wt']), usecols=[0, 4, 5, 8]) wt.columns = ct.FOR_CLASSIFY_W_COLS wt['code'] = wt['code'].map(lambda x :str(x).zfill(6)) return wt except Exception as er: print(str(er)) def get_terminated(): """ 获取终止上市股票列表 Return -------- DataFrame code :股票代码 name :股票名称 oDate:上市日期 tDate:终止上市日期 """ try: ref = ct.SSEQ_CQ_REF_URL%(ct.P_TYPE['http'], ct.DOMAINS['sse']) clt = Client(rv.TERMINATED_URL%(ct.P_TYPE['http'], ct.DOMAINS['sseq'], ct.PAGES['ssecq'], _random(5), _random()), ref=ref, cookie=rv.MAR_SH_COOKIESTR) lines = clt.gvalue() lines = lines.decode('utf-8') if ct.PY3 else lines lines = lines[19:-1] lines = json.loads(lines) df = pd.DataFrame(lines['result'], columns=rv.TERMINATED_T_COLS) df.columns = rv.TERMINATED_COLS return df except Exception as er: print(str(er)) def get_suspended(): """ 获取暂停上市股票列表 Return -------- DataFrame code :股票代码 name :股票名称 oDate:上市日期 tDate:终止上市日期 """ try: ref = ct.SSEQ_CQ_REF_URL%(ct.P_TYPE['http'], ct.DOMAINS['sse']) clt = Client(rv.SUSPENDED_URL%(ct.P_TYPE['http'], ct.DOMAINS['sseq'], ct.PAGES['ssecq'], _random(5), _random()), ref=ref, cookie=rv.MAR_SH_COOKIESTR) lines = clt.gvalue() lines = lines.decode('utf-8') if ct.PY3 else lines lines = lines[19:-1] lines = json.loads(lines) df = pd.DataFrame(lines['result'], columns=rv.TERMINATED_T_COLS) df.columns = rv.TERMINATED_COLS return df except Exception as er: print(str(er)) def _random(n=13): from random import randint start = 10**(n-1) end = (10**n)-1 return str(randint(start, end)) ================================================ FILE: tushare/stock/cons.py ================================================ # -*- coding:utf-8 -*- ''' Created on 2014/07/31 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn ''' VERSION = '1.0.3' K_LABELS = ['D', 'W', 'M'] K_MIN_LABELS = ['5', '15', '30', '60'] K_TYPE = {'D': 'akdaily', 'W': 'akweekly', 'M': 'akmonthly'} TT_K_TYPE = {'D': 'day', 'W': 'week', 'M': 'month'} FQ_KEY = ['qfqday', 'hfqday', 'day'] INDEX_LABELS = ['sh', 'sz', 'hs300', 'sz50', 'cyb', 'zxb', 'zx300', 'zh500'] INDEX_LIST = {'sh': 'sh000001', 'sz': 'sz399001', 'hs300': 'sh000300', 'sz50': 'sh000016', 'zxb': 'sz399005', 'cyb': 'sz399006', 'zx300': 'sz399008', 'zh500':'sh000905'} P_TYPE = {'http': 'http://', 'ftp': 'ftp://'} PAGE_NUM = [40, 60, 80, 100] FORMAT = lambda x: '%.2f' % x FORMAT4 = lambda x: '%.4f' % x DOMAINS = {'sina': 'sina.com.cn', 'sinahq': 'sinajs.cn', 'ifeng': 'ifeng.com', 'sf': 'finance.sina.com.cn', 'vsf': 'vip.stock.finance.sina.com.cn', 'idx': 'www.csindex.com.cn', '163': 'money.163.com', 'em': 'eastmoney.com', 'sseq': 'query.sse.com.cn', 'sse': 'www.sse.com.cn', 'szse': 'www.szse.cn', 'oss': 'file.tushare.org', 'idxip':'115.29.204.48', 'shibor': 'www.shibor.org', 'mbox':'www.cbooo.cn', 'tt': 'gtimg.cn', 'gw': 'gw.com.cn', 'v500': 'value500.com', 'sstar': 'stock.stockstar.com', 'dfcf': 'nufm.dfcfw.com'} PAGES = {'fd': 'index.phtml', 'dl': 'downxls.php', 'jv': 'json_v2.php', 'cpt': 'newFLJK.php', 'ids': 'newSinaHy.php', 'lnews':'rollnews_ch_out_interface.php', 'ntinfo':'vCB_BulletinGather.php', 'hs300b':'000300cons.xls', 'hs300w':'000300closeweight.xls','sz50b':'000016cons.xls', 'dp':'all_fpya.php', '163dp':'fpyg.html', 'emxsg':'JS.aspx', '163fh':'jjcgph.php', 'newstock':'vRPD_NewStockIssue.php', 'zz500b':'000905cons.xls', 'zz500wt':'000905closeweight.xls', 't_ticks':'vMS_tradedetail.php', 'dw': 'downLoad.html', 'qmd':'queryMargin.do', 'szsefc':'ShowReport.szse', 'ssecq':'commonQuery.do', 'sinadd':'cn_bill_download.php', 'ids_sw':'SwHy.php', 'idx': 'index.php', 'index': 'index.html'} TICK_COLUMNS = ['time', 'price', 'change', 'volume', 'amount', 'type'] TODAY_TICK_COLUMNS = ['time', 'price', 'pchange', 'change', 'volume', 'amount', 'type'] DAY_TRADING_COLUMNS = ['code', 'symbol', 'name', 'changepercent', 'trade', 'open', 'high', 'low', 'settlement', 'volume', 'turnoverratio', 'amount', 'per', 'pb', 'mktcap', 'nmc'] REPORT_COLS = ['code', 'name', 'eps', 'eps_yoy', 'bvps', 'roe', 'epcf', 'net_profits', 'profits_yoy', 'distrib', 'report_date'] FORECAST_COLS = ['code', 'name', 'type', 'report_date', 'pre_eps', 'range'] PROFIT_COLS = ['code', 'name', 'roe', 'net_profit_ratio', 'gross_profit_rate', 'net_profits', 'eps', 'business_income', 'bips'] OPERATION_COLS = ['code', 'name', 'arturnover', 'arturndays', 'inventory_turnover', 'inventory_days', 'currentasset_turnover', 'currentasset_days'] GROWTH_COLS = ['code', 'name', 'mbrg', 'nprg', 'nav', 'targ', 'epsg', 'seg'] DEBTPAYING_COLS = ['code', 'name', 'currentratio', 'quickratio', 'cashratio', 'icratio', 'sheqratio', 'adratio'] CASHFLOW_COLS = ['code', 'name', 'cf_sales', 'rateofreturn', 'cf_nm', 'cf_liabilities', 'cashflowratio'] DAY_PRICE_COLUMNS = ['date', 'open', 'high', 'close', 'low', 'volume', 'price_change', 'p_change', 'ma5', 'ma10', 'ma20', 'v_ma5', 'v_ma10', 'v_ma20', 'turnover'] INX_DAY_PRICE_COLUMNS = ['date', 'open', 'high', 'close', 'low', 'volume', 'price_change', 'p_change', 'ma5', 'ma10', 'ma20', 'v_ma5', 'v_ma10', 'v_ma20'] LIVE_DATA_COLS = ['name', 'open', 'pre_close', 'price', 'high', 'low', 'bid', 'ask', 'volume', 'amount', 'b1_v', 'b1_p', 'b2_v', 'b2_p', 'b3_v', 'b3_p', 'b4_v', 'b4_p', 'b5_v', 'b5_p', 'a1_v', 'a1_p', 'a2_v', 'a2_p', 'a3_v', 'a3_p', 'a4_v', 'a4_p', 'a5_v', 'a5_p', 'date', 'time', 's'] US_LIVE_DATA_COLS = ['name', 'price', 'change_percent', 'time', 'change', 'open', 'high', 'low', 'high_52week', 'low_52week', 'volume', 'volume_average', 'mktcap', 'eps', 'pe', 'fpe', 'beta', 'dividend', 'earnings_yield', 'totals', 'instown', 'extended_price', 'extended_change_percent', 'extended_change', 'extended_time', 'time_est', 'pre_close', 'extended_volume'] FOR_CLASSIFY_COLS = ['code','name'] FOR_CLASSIFY_B_COLS = ['date', 'code','name'] FOR_CLASSIFY_W_COLS = ['date','code', 'name', 'weight'] FOR_CLASSIFY_W5_COLS = ['date','code', 'name', 'weight'] TSDATA_CLASS = '%s%s/tsdata/industry/%s.csv' THE_FIELDS = ['code','symbol','name','changepercent','trade','open','high','low','settlement','volume','turnoverratio'] KLINE_TT_COLS_MINS = ['date', 'open', 'close', 'high', 'low', 'volume'] KLINE_TT_COLS = ['date', 'open', 'close', 'high', 'low', 'volume', 'amount', 'turnoverratio'] TICK_PRICE_URL = '%smarket.%s/%s?date=%s&symbol=%s' TICK_PRICE_URL_TT = '%sstock.%s/data/%s?appn=detail&action=download&c=%s&d=%s' TICK_PRICE_URL_NT = '%squotes.%s/cjmx/%s/%s/%s.xls' TODAY_TICKS_PAGE_URL = '%s%s/quotes_service/api/%s/CN_Transactions.getAllPageTime?date=%s&symbol=%s' TODAY_TICKS_URL = '%s%s/quotes_service/view/%s?symbol=%s&date=%s&page=%s' KLINE_TT_URL = '%sweb.ifzq.%s/appstock/app/%skline/get?_var=kline_day%s¶m=%s,%s,%s,%s,640,%s&r=0.%s' KLINE_TT_MIN_URL = '%sifzq.%s/appstock/app/kline/mkline?param=%s,m%s,,640&_var=m%s_today&r=0.%s' DAY_PRICE_URL = '%sapi.finance.%s/%s/?code=%s&type=last' LIVE_DATA_URL = '%shq.%s/rn=%s&list=%s' DAY_PRICE_MIN_URL = '%sapi.finance.%s/akmin?scode=%s&type=%s' SINA_DAY_PRICE_URL = '%s%s/quotes_service/api/%s/Market_Center.getHQNodeData?num=80&sort=code&asc=0&node=%s&symbol=&_s_r_a=page&page=%s' # SINA_DAY_PRICE_URL = '%s%s/quotes_service/api/%s/Market_Center.getHQNodeData?num=10000&node=%s' REPORT_URL = '%s%s/q/go.php/vFinanceAnalyze/kind/mainindex/%s?s_i=&s_a=&s_c=&reportdate=%s&quarter=%s&p=%s&num=%s' FORECAST_URL = '%s%s/q/go.php/vFinanceAnalyze/kind/performance/%s?s_i=&s_a=&s_c=&s_type=&reportdate=%s&quarter=%s&p=%s&num=%s' PROFIT_URL = '%s%s/q/go.php/vFinanceAnalyze/kind/profit/%s?s_i=&s_a=&s_c=&reportdate=%s&quarter=%s&p=%s&num=%s' OPERATION_URL = '%s%s/q/go.php/vFinanceAnalyze/kind/operation/%s?s_i=&s_a=&s_c=&reportdate=%s&quarter=%s&p=%s&num=%s' GROWTH_URL = '%s%s/q/go.php/vFinanceAnalyze/kind/grow/%s?s_i=&s_a=&s_c=&reportdate=%s&quarter=%s&p=%s&num=%s' DEBTPAYING_URL = '%s%s/q/go.php/vFinanceAnalyze/kind/debtpaying/%s?s_i=&s_a=&s_c=&reportdate=%s&quarter=%s&p=%s&num=%s' CASHFLOW_URL = '%s%s/q/go.php/vFinanceAnalyze/kind/cashflow/%s?s_i=&s_a=&s_c=&reportdate=%s&quarter=%s&p=%s&num=%s' SHIBOR_TYPE ={'Shibor': 'Shibor数据', 'Quote': '报价数据', 'Tendency': 'Shibor均值数据', 'LPR': 'LPR数据', 'LPR_Tendency': 'LPR均值数据'} SHIBOR_DATA_URL = '%s%s/shibor/web/html/%s?nameNew=Historical_%s_Data_%s.xls&downLoadPath=data&nameOld=%s%s.xls&shiborSrc=http://www.shibor.org/shibor/' ALL_STOCK_BASICS_FILE = P_TYPE['http'] + DOMAINS['oss'] + '/tsdata/%sall%s.csv' ALL_DAY_FILE = P_TYPE['http'] + DOMAINS['oss'] + '/tsdata/h/%s%s.csv' ALL_CAL_FILE = '%s%s/tsdata/calAll.csv'%(P_TYPE['http'], DOMAINS['oss']) SINA_CONCEPTS_INDEX_URL = '%smoney.%s/q/view/%s?param=class' ET_CONCEPTS_INDEX_URL = '%s%s/EM_Finance2014NumericApplication/JS.aspx?type=CT&cmd=C._BKGN&js=[(x)]&sty=FPGBKI&st=c&sr=-1&p=1&ps=5000&cb=&token=7bc05d0d4c3c22ef9fca8c2a912d779c&v=0.0%s' SINA_INDUSTRY_INDEX_URL = '%s%s/q/view/%s' SINA_DATA_DETAIL_URL = '%s%s/quotes_service/api/%s/Market_Center.getHQNodeData?page=%s&num=1000&sort=symbol&asc=1&node=%s&symbol=&_s_r_a=page' SINA_BALANCESHEET_URL = 'http://money.finance.sina.com.cn/corp/go.php/vDOWN_BalanceSheet/displaytype/4/stockid/%s/ctrl/all.phtml' SINA_PROFITSTATEMENT_URL = 'http://money.finance.sina.com.cn/corp/go.php/vDOWN_ProfitStatement/displaytype/4/stockid/%s/ctrl/all.phtml' SINA_CASHFLOW_URL = 'http://money.finance.sina.com.cn/corp/go.php/vDOWN_CashFlow/displaytype/4/stockid/%s/ctrl/all.phtml' INDEX_C_COMM = 'sseportal/ps/zhs/hqjt/csi' HS300_CLASSIFY_URL_FTP = '%s%s/uploads/file/autofile/closeweight/%s' SZ_CLASSIFY_URL_FTP = '%s%s/uploads/file/autofile/cons/%s' HS300_CLASSIFY_URL_HTTP = '%s%s/%s/%s' BDI_URL = '%s%s/BDI.asp' HIST_FQ_URL = '%s%s/corp/go.php/vMS_FuQuanMarketHistory/stockid/%s.phtml?year=%s&jidu=%s' HIST_INDEX_URL = '%s%s/corp/go.php/vMS_MarketHistory/stockid/%s/type/S.phtml?year=%s&jidu=%s' HIST_FQ_FACTOR_URL = '%s%s/api/json.php/BasicStockSrv.getStockFuQuanData?symbol=%s&type=hfq' ADJ_FAC_URL = '%s%s/tsdata/f/factor/%s.csv' MG_URL = '%s%s/tsdata/rzrq/%s/%s%s.csv' MG_ZSL_URL = '%s%s/tsdata/rzrq/%s/zsl/%s_%s.csv' GPZY_URL = '%s%s/tsdata/gpzy/%s.csv' GPZY_D_URL = '%s%s/tsdata/gpzy/%s.csv' SHS_FAC_URL = '%s%s/tsdata/shares/%s.csv' ZF = '%s%s/tsdata/%s.csv' INDEX_HQ_URL = '''%shq.%s/rn=xppzh&list=sh000001,sh000002,sh000003,sh000008,sh000009,sh000010,sh000011,sh000012,sh000016,sh000017,sh000300,sh000905,sz399001,sz399002,sz399003,sz399004,sz399005,sz399006,sz399008,sz399100,sz399101,sz399106,sz399107,sz399108,sz399333,sz399606''' SSEQ_CQ_REF_URL = '%s%s/assortment/stock/list/name' ALL_STK_URL = '%s%s/all.csv' SINA_DD = '%s%s/quotes_service/view/%s?symbol=%s&num=60&page=1&sort=ticktime&asc=0&volume=%s&amount=0&type=0&day=%s' BOX = 'boxOffice' MOVIE_BOX = '%s%s/%s/GetHourBoxOffice?d=%s' BOXOFFICE_DAY = '%s%s/%s/GetDayBoxOffice?num=%s&d=%s' BOXOFFICE_MONTH = '%s%s/%s/getMonthBox?sdate=%s' BOXOFFICE_CBD = '%s%s/%s/getCBD?pIndex=%s&dt=%s' SHIBOR_COLS = ['date', 'ON', '1W', '2W', '1M', '3M', '6M', '9M', '1Y'] SHIBOR_Q_COLS = ['date', 'bank', 'ON', '1W', '2W', '1M', '3M', '6M', '9M', '1Y'] QUOTE_COLS = ['date', 'bank', 'ON_B', 'ON_A', '1W_B', '1W_A', '2W_B', '2W_A', '1M_B', '1M_A', '3M_B', '3M_A', '6M_B', '6M_A', '9M_B', '9M_A', '1Y_B', '1Y_A'] SHIBOR_MA_COLS = ['date', 'ON_5', 'ON_10', 'ON_20', '1W_5', '1W_10', '1W_20','2W_5', '2W_10', '2W_20', '1M_5', '1M_10', '1M_20', '3M_5', '3M_10', '3M_20', '6M_5', '6M_10', '6M_20', '9M_5', '9M_10', '9M_20','1Y_5', '1Y_10', '1Y_20'] LPR_COLS = ['date', '1Y'] KTYPE = { 'D' : 9, 'XD' : 4, 'W' : 5, 'M' : 6, 'Q' : 10, 'Y' : 11, '1MIN' : 8, '5MIN' : 0, '15MIN' : 1, '30MIN' : 2, '60MIN' : 3, } ASSET = { 'E' : 'get_security_bars', 'INDEX' : 'get_index_bars', 'X' : 'get_instrument_bars', } KTYPE_LOW_COLS = ['D', 'XD', 'W', 'M', 'Q', 'Y'] KTYPE_ARR = ['1MIN', '5MIN', '15MIN', '30MIN', '60MIN'] BAR_E_COLS = ['code', 'open', 'close', 'high', 'low', 'vol', 'amount'] BAR_X_COLS = ['code', 'open', 'close', 'high', 'low', 'price', 'position','trade'] BAR_X_FUTURE_COLS = ['code', 'open', 'close', 'high', 'low', 'avg_price', 'position', 'vol'] BAR_X_FUTURE_RL_COLS = ['code', 'open', 'close', 'high', 'low', 'vol', 'avg_price', 'position'] BAR_X_OTHER_COLS = ['code', 'open', 'close', 'high', 'low', 'vol'] T_DROP_COLS = ['year', 'month', 'day', 'hour','minute'] LPR_MA_COLS = ['date', '1Y_5', '1Y_10', '1Y_20'] INDEX_HEADER = 'code,name,open,preclose,close,high,low,0,0,volume,amount,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,d,c,3\n' INDEX_COLS = ['code', 'name', 'change', 'open', 'preclose', 'close', 'high', 'low', 'volume', 'amount'] HIST_FQ_COLS = ['date', 'open', 'high', 'close', 'low', 'volume', 'amount', 'factor'] SINA_DD_COLS = ['code', 'name', 'time', 'price', 'volume', 'preprice', 'type'] GLOBAL_HQ_SYMBOL = 'sh000001,hkHSI,znb_UKX,znb_DAX,znb_INDEXCF,znb_CAC,znb_SMI,znb_FTSEMIB,znb_MADX,znb_OMX,znb_SPX,znb_HEX,znb_OSEAX,znb_ISEQ,znb_AEX,znb_ICEXI,znb_NKY,znb_TWSE,znb_FSSTI,znb_KOSPI,znb_FBMKLCI,znb_SET,znb_JCI,znb_PCOMP,znb_KSE100,znb_SENSEX,znb_VNINDEX,znb_CSEALL,znb_SASEIDX,znb_SPTSX,znb_MEXBOL,znb_IBOV,znb_MERVAL,znb_AS51,znb_NZSE50FG,znb_CASE,znb_JALSH,sz399001,znb_INDU,znb_CCMP' GLOBAL_HQ_COLS = ['symbol', 'name', 'price', 'chga', 'chgp', 'datetime'] INST_PLK_F = 'ts_instrument.plk' PROFIT_DIVIS = ['code', 'name', 'year', 'bshares', 'incshares', 'totals', 'cash', 'plandate', 'regdate', 'exdate', 'eventproc', 'anndate'] HIST_FQ_FACTOR_COLS = ['code','value'] DATA_GETTING_TIPS = '[Getting data:]' DATA_GETTING_FLAG = '#' DATA_ROWS_TIPS = '%s rows data found.Please wait for a moment.' DATA_INPUT_ERROR_MSG = 'date input error.' MSG_NOT_CONNECTED = '服务器连接为空,请通过ts.get_apis()获取' NETWORK_URL_ERROR_MSG = '获取失败,请检查网络.' DATE_CHK_MSG = '年度输入错误:请输入1989年以后的年份数字,格式:YYYY' DATE_CHK_Q_MSG = '季度输入错误:请输入1、2、3或4数字' TOP_PARAS_MSG = 'top有误,请输入整数或all.' LHB_MSG = '周期输入有误,请输入数字5、10、30或60' TOKEN_F_P = 'tk.csv' TOKEN_ERR_MSG = '请设置tushare pro的token凭证码,如果没有请访问https://tushare.pro注册申请' BOX_INPUT_ERR_MSG = '请输入YYYY-MM格式的年月数据' TICK_SRCS = ['sn', 'tt', 'nt'] TICK_SRC_ERROR = '数据源代码只能输入sn,tt,nt其中之一' INDEX_SYMBOL = {'399990': 'sz399990', '000006': 'sh000006', '399998': 'sz399998', '399436': 'sz399436', '399678': 'sz399678', '399804': 'sz399804', '000104': 'sh000104', '000070': 'sh000070', '399613': 'sz399613', '399690': 'sz399690', '399928': 'sz399928', '000928': 'sh000928', '000986': 'sh000986', '399806': 'sz399806', '000032': 'sh000032', '000005': 'sh000005', '399381': 'sz399381', '399908': 'sz399908', '000908': 'sh000908', '399691': 'sz399691', '000139': 'sh000139', '399427': 'sz399427', '399248': 'sz399248', '000832': 'sh000832', '399901': 'sz399901', '399413': 'sz399413', '000901': 'sh000901', '000078': 'sh000078', '000944': 'sh000944', '000025': 'sh000025', '399944': 'sz399944', '399307': 'sz399307', '000052': 'sh000052', '399680': 'sz399680', '399232': 'sz399232', '399993': 'sz399993', '000102': 'sh000102', '000950': 'sh000950', '399950': 'sz399950', '399244': 'sz399244', '399925': 'sz399925', '000925': 'sh000925', '000003': 'sh000003', '000805': 'sh000805', '000133': 'sh000133', '399677': 'sz399677', '399319': 'sz399319', '399397': 'sz399397', '399983': 'sz399983', '399654': 'sz399654', '399440': 'sz399440', '000043': 'sh000043', '000012': 'sh000012', '000833': 'sh000833', '000145': 'sh000145', '000053': 'sh000053', '000013': 'sh000013', '000022': 'sh000022', '000094': 'sh000094', '399299': 'sz399299', '000101': 'sh000101', '399817': 'sz399817', '399481': 'sz399481', '399434': 'sz399434', '399301': 'sz399301', '000029': 'sh000029', '399812': 'sz399812', '399441': 'sz399441', '000098': 'sh000098', '399557': 'sz399557', '000068': 'sh000068', '399298': 'sz399298', '399302': 'sz399302', '000961': 'sh000961', '000959': 'sh000959', '399961': 'sz399961', '000126': 'sh000126', '000036': 'sh000036', '399305': 'sz399305', '000116': 'sh000116', '399359': 'sz399359', '399810': 'sz399810', '000062': 'sh000062', '399618': 'sz399618', '399435': 'sz399435', '000149': 'sh000149', '000819': 'sh000819', '000020': 'sh000020', '000061': 'sh000061', '000016': 'sh000016', '000028': 'sh000028', '399809': 'sz399809', '000999': 'sh000999', '399238': 'sz399238', '000100': 'sh000100', '399979': 'sz399979', '000979': 'sh000979', '399685': 'sz399685', '000152': 'sh000152', '000153': 'sh000153', '399318': 'sz399318', '000853': 'sh000853', '000040': 'sh000040', '399693': 'sz399693', '000076': 'sh000076', '000017': 'sh000017', '000134': 'sh000134', '399989': 'sz399989', '000042': 'sh000042', '000066': 'sh000066', '000008': 'sh000008', '000002': 'sh000002', '000001': 'sh000001', '000011': 'sh000011', '000031': 'sh000031', '399403': 'sz399403', '000951': 'sh000951', '399951': 'sz399951', '000092': 'sh000092', '399234': 'sz399234', '000823': 'sh000823', '399986': 'sz399986', '399647': 'sz399647', '000050': 'sh000050', '000073': 'sh000073', '399357': 'sz399357', '000940': 'sh000940', '000107': 'sh000107', '000048': 'sh000048', '399411': 'sz399411', '399366': 'sz399366', '399373': 'sz399373', '000015': 'sh000015', '000021': 'sh000021', '000151': 'sh000151', '000851': 'sh000851', '000058': 'sh000058', '399404': 'sz399404', '399102': 'sz399102', '399431': 'sz399431', '399971': 'sz399971', '000125': 'sh000125', '000069': 'sh000069', '000063': 'sh000063', '399395': 'sz399395', '000038': 'sh000038', '399240': 'sz399240', '399903': 'sz399903', '000989': 'sh000989', '399321': 'sz399321', '399675': 'sz399675', '399235': 'sz399235', '000057': 'sh000057', '000056': 'sh000056', '000903': 'sh000903', '399310': 'sz399310', '000004': 'sh000004', '000019': 'sh000019', '399919': 'sz399919', '000974': 'sh000974', '000919': 'sh000919', '399635': 'sz399635', '399663': 'sz399663', '399106': 'sz399106', '399107': 'sz399107', '399555': 'sz399555', '000090': 'sh000090', '000155': 'sh000155', '000060': 'sh000060', '399636': 'sz399636', '000816': 'sh000816', '000010': 'sh000010', '399671': 'sz399671', '000035': 'sh000035', '399352': 'sz399352', '399683': 'sz399683', '399554': 'sz399554', '399409': 'sz399409', '000018': 'sh000018', '399101': 'sz399101', '000992': 'sh000992', '399416': 'sz399416', '399918': 'sz399918', '399379': 'sz399379', '399674': 'sz399674', '399239': 'sz399239', '399384': 'sz399384', '399367': 'sz399367', '000918': 'sh000918', '000914': 'sh000914', '399914': 'sz399914', '000054': 'sh000054', '000806': 'sh000806', '399619': 'sz399619', '399015': 'sz399015', '399393': 'sz399393', '399313': 'sz399313', '399231': 'sz399231', '000846': 'sh000846', '000854': 'sh000854', '399010': 'sz399010', '399666': 'sz399666', '399387': 'sz399387', '399399': 'sz399399', '000026': 'sh000026', '399934': 'sz399934', '000150': 'sh000150', '000934': 'sh000934', '399317': 'sz399317', '000138': 'sh000138', '399371': 'sz399371', '399394': 'sz399394', '399659': 'sz399659', '399665': 'sz399665', '399931': 'sz399931', '000161': 'sh000161', '399380': 'sz399380', '000931': 'sh000931', '399704': 'sz399704', '399616': 'sz399616', '000817': 'sh000817', '399303': 'sz399303', '399629': 'sz399629', '399624': 'sz399624', '399009': 'sz399009', '399233': 'sz399233', '399103': 'sz399103', '399242': 'sz399242', '399627': 'sz399627', '000971': 'sh000971', '399679': 'sz399679', '399912': 'sz399912', '000982': 'sh000982', '399668': 'sz399668', '000096': 'sh000096', '399982': 'sz399982', '000849': 'sh000849', '000148': 'sh000148', '399364': 'sz399364', '000912': 'sh000912', '000129': 'sh000129', '000055': 'sh000055', '000047': 'sh000047', '399355': 'sz399355', '399622': 'sz399622', '000033': 'sh000033', '399640': 'sz399640', '000852': 'sh000852', '399966': 'sz399966', '399615': 'sz399615', '399802': 'sz399802', '399602': 'sz399602', '000105': 'sh000105', '399660': 'sz399660', '399672': 'sz399672', '399913': 'sz399913', '399420': 'sz399420', '000159': 'sh000159', '399314': 'sz399314', '399652': 'sz399652', '399369': 'sz399369', '000913': 'sh000913', '000065': 'sh000065', '000808': 'sh000808', '399386': 'sz399386', '399100': 'sz399100', '000997': 'sh000997', '000990': 'sh000990', '000093': 'sh000093', '399637': 'sz399637', '399439': 'sz399439', '399306': 'sz399306', '000855': 'sh000855', '000123': 'sh000123', '399623': 'sz399623', '399312': 'sz399312', '399249': 'sz399249', '399311': 'sz399311', '399975': 'sz399975', '399356': 'sz399356', '399400': 'sz399400', '399676': 'sz399676', '000136': 'sh000136', '399361': 'sz399361', '399974': 'sz399974', '399995': 'sz399995', '399316': 'sz399316', '399701': 'sz399701', '000300': 'sh000300', '000030': 'sh000030', '000976': 'sh000976', '399686': 'sz399686', '399108': 'sz399108', '399374': 'sz399374', '000906': 'sh000906', '399707': 'sz399707', '000064': 'sh000064', '399633': 'sz399633', '399300': 'sz399300', '399628': 'sz399628', '399398': 'sz399398', '000034': 'sh000034', '399644': 'sz399644', '399905': 'sz399905', '399626': 'sz399626', '399625': 'sz399625', '000978': 'sh000978', '399664': 'sz399664', '399682': 'sz399682', '399322': 'sz399322', '000158': 'sh000158', '000842': 'sh000842', '399550': 'sz399550', '399423': 'sz399423', '399978': 'sz399978', '399996': 'sz399996', '000905': 'sh000905', '000007': 'sh000007', '000827': 'sh000827', '399655': 'sz399655', '399401': 'sz399401', '399650': 'sz399650', '000963': 'sh000963', '399661': 'sz399661', '399922': 'sz399922', '000091': 'sh000091', '399375': 'sz399375', '000922': 'sh000922', '399702': 'sz399702', '399963': 'sz399963', '399011': 'sz399011', '399012': 'sz399012', '399383': 'sz399383', '399657': 'sz399657', '399910': 'sz399910', '399351': 'sz399351', '000910': 'sh000910', '000051': 'sh000051', '399376': 'sz399376', '399639': 'sz399639', '000821': 'sh000821', '399360': 'sz399360', '399604': 'sz399604', '399315': 'sz399315', '399658': 'sz399658', '000135': 'sh000135', '000059': 'sh000059', '399006': 'sz399006', '399320': 'sz399320', '000991': 'sh000991', '399606': 'sz399606', '399428': 'sz399428', '399406': 'sz399406', '399630': 'sz399630', '000802': 'sh000802', '399803': 'sz399803', '000071': 'sh000071', '399358': 'sz399358', '399013': 'sz399013', '399385': 'sz399385', '399008': 'sz399008', '399649': 'sz399649', '399673': 'sz399673', '399418': 'sz399418', '399370': 'sz399370', '000814': 'sh000814', '399002': 'sz399002', '399814': 'sz399814', '399641': 'sz399641', '399001': 'sz399001', '399662': 'sz399662', '399706': 'sz399706', '399932': 'sz399932', '000095': 'sh000095', '000932': 'sh000932', '399965': 'sz399965', '399363': 'sz399363', '399354': 'sz399354', '399638': 'sz399638', '399648': 'sz399648', '399608': 'sz399608', '000939': 'sh000939', '399939': 'sz399939', '399365': 'sz399365', '399382': 'sz399382', '399631': 'sz399631', '399612': 'sz399612', '399611': 'sz399611', '399645': 'sz399645', '399324': 'sz399324', '399552': 'sz399552', '000858': 'sh000858', '000045': 'sh000045', '000121': 'sh000121', '399703': 'sz399703', '399003': 'sz399003', '399348': 'sz399348', '399389': 'sz399389', '399007': 'sz399007', '399391': 'sz399391', '000973': 'sh000973', '000984': 'sh000984', '000969': 'sh000969', '000952': 'sh000952', '399332': 'sz399332', '399952': 'sz399952', '399553': 'sz399553', '000856': 'sh000856', '399969': 'sz399969', '399643': 'sz399643', '399402': 'sz399402', '399372': 'sz399372', '399632': 'sz399632', '399344': 'sz399344', '399808': 'sz399808', '399620': 'sz399620', '000103': 'sh000103', '399911': 'sz399911', '000993': 'sh000993', '000983': 'sh000983', '399687': 'sz399687', '399933': 'sz399933', '000933': 'sh000933', '399437': 'sz399437', '399433': 'sz399433', '000046': 'sh000046', '000911': 'sh000911', '000114': 'sh000114', '000049': 'sh000049', '399392': 'sz399392', '399653': 'sz399653', '000975': 'sh000975', '000044': 'sh000044', '399378': 'sz399378', '000828': 'sh000828', '399634': 'sz399634', '399005': 'sz399005', '000162': 'sh000162', '399333': 'sz399333', '000122': 'sh000122', '399646': 'sz399646', '000077': 'sh000077', '000074': 'sh000074', '399656': 'sz399656', '399396': 'sz399396', '399415': 'sz399415', '399408': 'sz399408', '000115': 'sh000115', '000987': 'sh000987', '399362': 'sz399362', '000841': 'sh000841', '000141': 'sh000141', '000120': 'sh000120', '399992': 'sz399992', '000807': 'sh000807', '399350': 'sz399350', '000009': 'sh000009', '000998': 'sh000998', '399390': 'sz399390', '399405': 'sz399405', '000099': 'sh000099', '399337': 'sz399337', '000142': 'sh000142', '399419': 'sz399419', '399407': 'sz399407', '000909': 'sh000909', '000119': 'sh000119', '399909': 'sz399909', '399805': 'sz399805', '000996': 'sh000996', '000847': 'sh000847', '000130': 'sh000130', '399377': 'sz399377', '399388': 'sz399388', '399610': 'sz399610', '000958': 'sh000958', '399958': 'sz399958', '000075': 'sh000075', '399346': 'sz399346', '000147': 'sh000147', '000132': 'sh000132', '000108': 'sh000108', '399642': 'sz399642', '000977': 'sh000977', '399689': 'sz399689', '399335': 'sz399335', '399977': 'sz399977', '399972': 'sz399972', '399970': 'sz399970', '399004': 'sz399004', '399341': 'sz399341', '399330': 'sz399330', '399917': 'sz399917', '000160': 'sh000160', '399432': 'sz399432', '399429': 'sz399429', '000917': 'sh000917', '000128': 'sh000128', '000067': 'sh000067', '000079': 'sh000079', '399236': 'sz399236', '399994': 'sz399994', '399237': 'sz399237', '000966': 'sh000966', '000957': 'sh000957', '399328': 'sz399328', '399353': 'sz399353', '399957': 'sz399957', '399412': 'sz399412', '000904': 'sh000904', '399904': 'sz399904', '399410': 'sz399410', '000027': 'sh000027', '399667': 'sz399667', '000857': 'sh000857', '000131': 'sh000131', '000964': 'sh000964', '399339': 'sz399339', '399964': 'sz399964', '399991': 'sz399991', '399417': 'sz399417', '000146': 'sh000146', '399551': 'sz399551', '000137': 'sh000137', '000118': 'sh000118', '399976': 'sz399976', '000109': 'sh000109', '399681': 'sz399681', '399438': 'sz399438', '000117': 'sh000117', '399614': 'sz399614', '399669': 'sz399669', '000111': 'sh000111', '399670': 'sz399670', '000097': 'sh000097', '000106': 'sh000106', '000039': 'sh000039', '399935': 'sz399935', '000935': 'sh000935', '399813': 'sz399813', '000037': 'sh000037', '399811': 'sz399811', '399705': 'sz399705', '399556': 'sz399556', '000113': 'sh000113', '000072': 'sh000072', '399651': 'sz399651', '399617': 'sz399617', '399684': 'sz399684', '000041': 'sh000041', '399807': 'sz399807', '399959': 'sz399959', '399967': 'sz399967', '399326': 'sz399326', '399688': 'sz399688', '399368': 'sz399368', '399241': 'sz399241', '399696': 'sz399696', '000850': 'sh000850', '000110': 'sh000110', '399621': 'sz399621', '399243': 'sz399243', '399973': 'sz399973', '399987': 'sz399987', '000112': 'sh000112', '399997': 'sz399997', '000915': 'sh000915', '000916': 'sh000916', 'hkHSI':'hkHSI'} MKTS = { 'TP': [1, 1,'临时股'], 'OZ': [4, 12, '郑州商品期权'], 'OD': [5, 12, '大连商品期权'], 'OS': [6, 12, '上海商品期权'], 'QQ': [8, 12, '上海个股期权'], 'FH': [27, 5, '香港指数'], 'QZ': [28, 3, '郑州商品'], 'QD': [29, 3, '大连商品'], 'QS': [30, 3, '上海期货'], 'KH': [31, 2, '香港主板'], 'KR': [32, 2, '香港权证'], 'FU': [33, 8, '开放式基金'], 'FB': [34, 9, '货币型基金'], 'LC': [35, 8,'招商理财产品'], 'LB': [36, 9,'招商货币产品'], 'FW': [37, 11, '国际指数'], 'HG': [38, 10,'国内宏观指标'], 'CH': [40, 11, '中国概念股'], 'MG': [41, 11,'美股知名公司'], 'HB': [43, 1, 'B股转H股'], 'SB': [44, 1, '股份转让'], 'CZ': [47, 3, '股指期货'], 'KG': [48, 2, '香港创业板'], 'KT': [49, 2,'香港信托基金'], 'GY': [54, 6, '国债预发行'], 'MA': [60, 3,'主力期货合约'], 'ZZ': [62, 5, '中证指数'], 'GH': [71, 2, '港股通'], 'SZ': [0, 0, 'SHENZHEN'], 'SH': [1, 1, 'SHANGHAI'] } SLIST = ['180.153.18.170', '180.153.18.171', '202.108.253.130', '202.108.253.131', '60.191.117.167', '115.238.56.198', '218.75.126.9', '115.238.90.165', '124.160.88.183', '60.12.136.250', '218.108.98.244', '218.108.47.69', '14.17.75.71', '180.153.39.51'] XXLIST = ['61.152.107.141'] XLIST = ['121.14.110.210', '119.147.212.76', '113.105.73.86', '119.147.171.211', '119.147.164.57', '119.147.164.58', '61.49.50.180', '61.49.50.181', '61.135.142.85', '61.135.149.181', '114.80.80.210', '222.73.49.15', '221.194.181.176'] T_PORT = 7709 X_PORT = 7727 import sys PY3 = (sys.version_info[0] >= 3) def _write_head(): sys.stdout.write(DATA_GETTING_TIPS) sys.stdout.flush() def _write_console(): sys.stdout.write(DATA_GETTING_FLAG) sys.stdout.flush() def _write_tips(tip): sys.stdout.write(DATA_ROWS_TIPS%tip) sys.stdout.flush() def _write_msg(msg): sys.stdout.write(msg) sys.stdout.flush() def _check_input(year, quarter): if isinstance(year, str) or year < 1989 : raise TypeError(DATE_CHK_MSG) elif quarter is None or isinstance(quarter, str) or quarter not in [1, 2, 3, 4]: raise TypeError(DATE_CHK_Q_MSG) else: return True def _check_lhb_input(last): if last not in [5, 10, 30, 60]: raise TypeError(LHB_MSG) else: return True def _market_code(code): code = str(code) if code[0] in ['5', '6', '9'] or code[:3] in ['009', '100', '110', '112', \ '113', '120', '129', '181', \ '126', '201', '202', '203', \ '204', '190', '191']: return 1 return 0 def _idx_market_code(code): code = str(code) if code[0] in ['0']: return 1 if code[:3] in ['399']: return 0 return code def _code_to_symbol(code): ''' 生成symbol代码标志 ''' if code in INDEX_LABELS: return INDEX_LIST[code] elif code[:3] == 'gb_': return code else: if len(code) != 6 : return code else: return 'sh%s'%code if code[:1] in ['5', '6', '9'] or code[:2] in ['11', '13'] else 'sz%s'%code def _code_to_symbol_dgt(code): ''' 生成symbol代码标志 ''' if code in INDEX_LABELS: return INDEX_LIST[code] else: if len(code) != 6 : return code else: return '0%s'%code if code[:1] in ['5', '6', '9'] else '1%s'%code def _get_server(): import random ips = SLIST random.shuffle(ips) return ips[0] def _get_xserver(): import random ips = XLIST random.shuffle(ips) return ips[0] def _get_xxserver(): import random ips = XXLIST random.shuffle(ips) return ips[0] ================================================ FILE: tushare/stock/fundamental.py ================================================ # -*- coding:utf-8 -*- """ 基本面数据接口 Created on 2015/01/18 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ import pandas as pd from tushare.stock import cons as ct import lxml.html from lxml import etree import re import time from pandas.compat import StringIO from tushare.util import dateu as du try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request def get_stock_basics(date=None): """ 获取沪深上市公司基本情况 Parameters date:日期YYYY-MM-DD,默认为上一个交易日,目前只能提供2016-08-09之后的历史数据 Return -------- DataFrame code,代码 name,名称 industry,细分行业 area,地区 pe,市盈率 outstanding,流通股本 totals,总股本(万) totalAssets,总资产(万) liquidAssets,流动资产 fixedAssets,固定资产 reserved,公积金 reservedPerShare,每股公积金 eps,每股收益 bvps,每股净资 pb,市净率 timeToMarket,上市日期 """ wdate = du.last_tddate() if date is None else date wdate = wdate.replace('-', '') if wdate < '20160809': return None datepre = '' if date is None else wdate[0:4] + wdate[4:6] + '/' request = Request(ct.ALL_STOCK_BASICS_FILE%(datepre, '' if date is None else wdate)) text = urlopen(request, timeout=10).read() text = text.decode('GBK') text = text.replace('--', '') df = pd.read_csv(StringIO(text), dtype={'code':'object'}) df = df.set_index('code') return df def get_report_data(year, quarter): """ 获取业绩报表数据 Parameters -------- year:int 年度 e.g:2014 quarter:int 季度 :1、2、3、4,只能输入这4个季度 说明:由于是从网站获取的数据,需要一页页抓取,速度取决于您当前网络速度 Return -------- DataFrame code,代码 name,名称 eps,每股收益 eps_yoy,每股收益同比(%) bvps,每股净资产 roe,净资产收益率(%) epcf,每股现金流量(元) net_profits,净利润(万元) profits_yoy,净利润同比(%) distrib,分配方案 report_date,发布日期 """ if ct._check_input(year,quarter) is True: ct._write_head() df = _get_report_data(year, quarter, 1, pd.DataFrame()) if df is not None: # df = df.drop_duplicates('code') df['code'] = df['code'].map(lambda x:str(x).zfill(6)) return df def _get_report_data(year, quarter, pageNo, dataArr, retry_count=3, pause=0.001): ct._write_console() for _ in range(retry_count): time.sleep(pause) try: request = Request(ct.REPORT_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['fd'], year, quarter, pageNo, ct.PAGE_NUM[1])) text = urlopen(request, timeout=10).read() text = text.decode('GBK') text = text.replace('--', '') html = lxml.html.parse(StringIO(text)) res = html.xpath("//table[@class=\"list_table\"]/tr") if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = '%s
'%sarr df = pd.read_html(sarr)[0] df = df.drop(11, axis=1) df.columns = ct.REPORT_COLS dataArr = dataArr.append(df, ignore_index=True) nextPage = html.xpath('//div[@class=\"pages\"]/a[last()]/@onclick') if len(nextPage)>0: pageNo = re.findall(r'\d+', nextPage[0])[0] return _get_report_data(year, quarter, pageNo, dataArr) else: return dataArr except Exception as e: pass raise IOError(ct.NETWORK_URL_ERROR_MSG) def get_profit_data(year, quarter): """ 获取盈利能力数据 Parameters -------- year:int 年度 e.g:2014 quarter:int 季度 :1、2、3、4,只能输入这4个季度 说明:由于是从网站获取的数据,需要一页页抓取,速度取决于您当前网络速度 Return -------- DataFrame code,代码 name,名称 roe,净资产收益率(%) net_profit_ratio,净利率(%) gross_profit_rate,毛利率(%) net_profits,净利润(万元) eps,每股收益 business_income,营业收入(百万元) bips,每股主营业务收入(元) """ if ct._check_input(year, quarter) is True: ct._write_head() data = _get_profit_data(year, quarter, 1, pd.DataFrame()) if data is not None: # data = data.drop_duplicates('code') data['code'] = data['code'].map(lambda x:str(x).zfill(6)) return data def _get_profit_data(year, quarter, pageNo, dataArr, retry_count=3, pause=0.001): ct._write_console() for _ in range(retry_count): time.sleep(pause) try: request = Request(ct.PROFIT_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['fd'], year, quarter, pageNo, ct.PAGE_NUM[1])) text = urlopen(request, timeout=10).read() text = text.decode('GBK') text = text.replace('--', '') html = lxml.html.parse(StringIO(text)) res = html.xpath("//table[@class=\"list_table\"]/tr") if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = '%s
'%sarr df = pd.read_html(sarr)[0] df.columns=ct.PROFIT_COLS dataArr = dataArr.append(df, ignore_index=True) nextPage = html.xpath('//div[@class=\"pages\"]/a[last()]/@onclick') if len(nextPage)>0: pageNo = re.findall(r'\d+', nextPage[0])[0] return _get_profit_data(year, quarter, pageNo, dataArr) else: return dataArr except: pass raise IOError(ct.NETWORK_URL_ERROR_MSG) def get_operation_data(year, quarter): """ 获取营运能力数据 Parameters -------- year:int 年度 e.g:2014 quarter:int 季度 :1、2、3、4,只能输入这4个季度 说明:由于是从网站获取的数据,需要一页页抓取,速度取决于您当前网络速度 Return -------- DataFrame code,代码 name,名称 arturnover,应收账款周转率(次) arturndays,应收账款周转天数(天) inventory_turnover,存货周转率(次) inventory_days,存货周转天数(天) currentasset_turnover,流动资产周转率(次) currentasset_days,流动资产周转天数(天) """ if ct._check_input(year, quarter) is True: ct._write_head() data = _get_operation_data(year, quarter, 1, pd.DataFrame()) if data is not None: # data = data.drop_duplicates('code') data['code'] = data['code'].map(lambda x:str(x).zfill(6)) return data def _get_operation_data(year, quarter, pageNo, dataArr, retry_count=3, pause=0.001): ct._write_console() for _ in range(retry_count): time.sleep(pause) try: request = Request(ct.OPERATION_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['fd'], year, quarter, pageNo, ct.PAGE_NUM[1])) text = urlopen(request, timeout=10).read() text = text.decode('GBK') text = text.replace('--', '') html = lxml.html.parse(StringIO(text)) res = html.xpath("//table[@class=\"list_table\"]/tr") if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = '%s
'%sarr df = pd.read_html(sarr)[0] df.columns=ct.OPERATION_COLS dataArr = dataArr.append(df, ignore_index=True) nextPage = html.xpath('//div[@class=\"pages\"]/a[last()]/@onclick') if len(nextPage)>0: pageNo = re.findall(r'\d+', nextPage[0])[0] return _get_operation_data(year, quarter, pageNo, dataArr) else: return dataArr except Exception as e: pass raise IOError(ct.NETWORK_URL_ERROR_MSG) def get_growth_data(year, quarter): """ 获取成长能力数据 Parameters -------- year:int 年度 e.g:2014 quarter:int 季度 :1、2、3、4,只能输入这4个季度 说明:由于是从网站获取的数据,需要一页页抓取,速度取决于您当前网络速度 Return -------- DataFrame code,代码 name,名称 mbrg,主营业务收入增长率(%) nprg,净利润增长率(%) nav,净资产增长率 targ,总资产增长率 epsg,每股收益增长率 seg,股东权益增长率 """ if ct._check_input(year, quarter) is True: ct._write_head() data = _get_growth_data(year, quarter, 1, pd.DataFrame()) if data is not None: # data = data.drop_duplicates('code') data['code'] = data['code'].map(lambda x:str(x).zfill(6)) return data def _get_growth_data(year, quarter, pageNo, dataArr, retry_count=3, pause=0.001): ct._write_console() for _ in range(retry_count): time.sleep(pause) try: request = Request(ct.GROWTH_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['fd'], year, quarter, pageNo, ct.PAGE_NUM[1])) text = urlopen(request, timeout=50).read() text = text.decode('GBK') text = text.replace('--', '') html = lxml.html.parse(StringIO(text)) res = html.xpath("//table[@class=\"list_table\"]/tr") if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = '%s
'%sarr df = pd.read_html(sarr)[0] df.columns=ct.GROWTH_COLS dataArr = dataArr.append(df, ignore_index=True) nextPage = html.xpath('//div[@class=\"pages\"]/a[last()]/@onclick') if len(nextPage)>0: pageNo = re.findall(r'\d+', nextPage[0])[0] return _get_growth_data(year, quarter, pageNo, dataArr) else: return dataArr except Exception as e: pass raise IOError(ct.NETWORK_URL_ERROR_MSG) def get_debtpaying_data(year, quarter): """ 获取偿债能力数据 Parameters -------- year:int 年度 e.g:2014 quarter:int 季度 :1、2、3、4,只能输入这4个季度 说明:由于是从网站获取的数据,需要一页页抓取,速度取决于您当前网络速度 Return -------- DataFrame code,代码 name,名称 currentratio,流动比率 quickratio,速动比率 cashratio,现金比率 icratio,利息支付倍数 sheqratio,股东权益比率 adratio,股东权益增长率 """ if ct._check_input(year, quarter) is True: ct._write_head() df = _get_debtpaying_data(year, quarter, 1, pd.DataFrame()) if df is not None: # df = df.drop_duplicates('code') df['code'] = df['code'].map(lambda x:str(x).zfill(6)) return df def _get_debtpaying_data(year, quarter, pageNo, dataArr, retry_count=3, pause=0.001): ct._write_console() for _ in range(retry_count): time.sleep(pause) try: request = Request(ct.DEBTPAYING_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['fd'], year, quarter, pageNo, ct.PAGE_NUM[1])) text = urlopen(request, timeout=10).read() text = text.decode('GBK') html = lxml.html.parse(StringIO(text)) res = html.xpath("//table[@class=\"list_table\"]/tr") if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = '%s
'%sarr df = pd.read_html(sarr)[0] df.columns = ct.DEBTPAYING_COLS dataArr = dataArr.append(df, ignore_index=True) nextPage = html.xpath('//div[@class=\"pages\"]/a[last()]/@onclick') if len(nextPage)>0: pageNo = re.findall(r'\d+', nextPage[0])[0] return _get_debtpaying_data(year, quarter, pageNo, dataArr) else: return dataArr except Exception as e: pass raise IOError(ct.NETWORK_URL_ERROR_MSG) def get_cashflow_data(year, quarter): """ 获取现金流量数据 Parameters -------- year:int 年度 e.g:2014 quarter:int 季度 :1、2、3、4,只能输入这4个季度 说明:由于是从网站获取的数据,需要一页页抓取,速度取决于您当前网络速度 Return -------- DataFrame code,代码 name,名称 cf_sales,经营现金净流量对销售收入比率 rateofreturn,资产的经营现金流量回报率 cf_nm,经营现金净流量与净利润的比率 cf_liabilities,经营现金净流量对负债比率 cashflowratio,现金流量比率 """ if ct._check_input(year, quarter) is True: ct._write_head() df = _get_cashflow_data(year, quarter, 1, pd.DataFrame()) if df is not None: # df = df.drop_duplicates('code') df['code'] = df['code'].map(lambda x:str(x).zfill(6)) return df def _get_cashflow_data(year, quarter, pageNo, dataArr, retry_count=3, pause=0.001): ct._write_console() for _ in range(retry_count): time.sleep(pause) try: request = Request(ct.CASHFLOW_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['fd'], year, quarter, pageNo, ct.PAGE_NUM[1])) text = urlopen(request, timeout=10).read() text = text.decode('GBK') text = text.replace('--', '') html = lxml.html.parse(StringIO(text)) res = html.xpath("//table[@class=\"list_table\"]/tr") if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = '%s
'%sarr df = pd.read_html(sarr)[0] df.columns = ct.CASHFLOW_COLS dataArr = dataArr.append(df, ignore_index=True) nextPage = html.xpath('//div[@class=\"pages\"]/a[last()]/@onclick') if len(nextPage)>0: pageNo = re.findall(r'\d+', nextPage[0])[0] return _get_cashflow_data(year, quarter, pageNo, dataArr) else: return dataArr except Exception as e: pass raise IOError(ct.NETWORK_URL_ERROR_MSG) def _data_path(): import os import inspect caller_file = inspect.stack()[1][1] pardir = os.path.abspath(os.path.join(os.path.dirname(caller_file), os.path.pardir)) return os.path.abspath(os.path.join(pardir, os.path.pardir)) def get_balance_sheet(code): """ 获取某股票的历史所有时期资产负债表 Parameters -------- code:str 股票代码 e.g:600518 Return -------- DataFrame 行列名称为中文且数目较多,建议获取数据后保存到本地查看 """ if code.isdigit(): request = Request(ct.SINA_BALANCESHEET_URL%(code)) text = urlopen(request, timeout=10).read() text = text.decode('GBK') text = text.replace('\t\n', '\r\n') text = text.replace('\t', ',') df = pd.read_csv(StringIO(text), dtype={'code':'object'}) return df def get_profit_statement(code): """ 获取某股票的历史所有时期利润表 Parameters -------- code:str 股票代码 e.g:600518 Return -------- DataFrame 行列名称为中文且数目较多,建议获取数据后保存到本地查看 """ if code.isdigit(): request = Request(ct.SINA_PROFITSTATEMENT_URL%(code)) text = urlopen(request, timeout=10).read() text = text.decode('GBK') text = text.replace('\t\n', '\r\n') text = text.replace('\t', ',') df = pd.read_csv(StringIO(text), dtype={'code':'object'}) return df def get_cash_flow(code): """ 获取某股票的历史所有时期现金流表 Parameters -------- code:str 股票代码 e.g:600518 Return -------- DataFrame 行列名称为中文且数目较多,建议获取数据后保存到本地查看 """ if code.isdigit(): request = Request(ct.SINA_CASHFLOW_URL%(code)) text = urlopen(request, timeout=10).read() text = text.decode('GBK') text = text.replace('\t\n', '\r\n') text = text.replace('\t', ',') df = pd.read_csv(StringIO(text), dtype={'code':'object'}) return df ================================================ FILE: tushare/stock/globals.py ================================================ #!/usr/bin/env python # -*- coding:utf-8 -*- ''' 全球市场 Created on 2016/11/27 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn ''' import pandas as pd from tushare.stock import cons as ct from tushare.util import dateu as du try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request def global_realtime(symbols=None): """ 全球实时指数 """ symbols_list = '' if symbols is None or symbols == '': symbols_list = ct.GLOBAL_HQ_SYMBOL else: if isinstance(symbols, list) or isinstance(symbols, set) or isinstance(symbols, tuple) or isinstance(symbols, pd.Series): for code in symbols: symbols_list += 'znb_' + code + ',' else: symbols_list = 'znb_' + symbols symbols_list = symbols_list[:-1] if len(symbols_list) > 8 else symbols_list request = Request(ct.LIVE_DATA_URL%(ct.P_TYPE['http'], ct.DOMAINS['sinahq'], du._random(), symbols_list)) content = urlopen(request,timeout=10).readlines() datalist = [] for cont in content: arrs = [] cont = cont.decode('GBK') cont = cont.split('=') symbolstr = cont[0].split('_') symbol = symbolstr[2] vals = cont[1][1:-3] valarr = vals.split(',') if (symbol == 'sh000001') or (symbol == 'sz399001'): price = float(valarr[3]) preclose = float(valarr[2]) chg = (price - preclose) / preclose * 100 arrs = [symbol, valarr[0], valarr[3], price-preclose , chg, valarr[30] + ' ' + valarr[31]] elif symbol == 'hkHSI': arrs = [symbol, valarr[1], valarr[6], valarr[7], valarr[8], valarr[17].replace('/', '-') + ' ' + valarr[18] + ':00'] else: arrs = [symbolstr[3], valarr[0], valarr[1], valarr[2], valarr[3], du.int2time(int(valarr[5]))] datalist.append(arrs) df = pd.DataFrame(datalist, columns=ct.GLOBAL_HQ_COLS) return df ================================================ FILE: tushare/stock/indictor.py ================================================ # -*- coding:utf-8 -*- """ 股票技术指标接口 Created on 2018/05/26 @author: Jackie Liao @group : ** @contact: info@liaocy.net """ def ma(data, n=10, val_name="close"): import numpy as np ''' 移动平均线 Moving Average Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 n:int 移动平均线时长,时间单位根据data决定 val_name:string 计算哪一列的列名,默认为 close 收盘值 return ------- list 移动平均线 ''' values = [] MA = [] for index, row in data.iterrows(): values.append(row[val_name]) if len(values) == n: del values[0] MA.append(np.average(values)) return np.asarray(MA) def md(data, n=10, val_name="close"): import numpy as np ''' 移动标准差 Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 n:int 移动平均线时长,时间单位根据data决定 val_name:string 计算哪一列的列名,默认为 close 收盘值 return ------- list 移动平均线 ''' values = [] MD = [] for index, row in data.iterrows(): values.append(row[val_name]) if len(values) == n: del values[0] MD.append(np.std(values)) return np.asarray(MD) def _get_day_ema(prices, n): a = 1 - 2 / (n + 1) day_ema = 0 for index, price in enumerate(reversed(prices)): day_ema += a ** index * price return day_ema def ema(data, n=12, val_name="close"): import numpy as np ''' 指数平均数指标 Exponential Moving Average Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 n:int 移动平均线时长,时间单位根据data决定 val_name:string 计算哪一列的列名,默认为 close 收盘值 return ------- EMA:numpy.ndarray 指数平均数指标 ''' prices = [] EMA = [] for index, row in data.iterrows(): if index == 0: past_ema = row[val_name] EMA.append(row[val_name]) else: # Y=[2*X+(N-1)*Y’]/(N+1) today_ema = (2 * row[val_name] + (n - 1) * past_ema) / (n + 1) past_ema = today_ema EMA.append(today_ema) return np.asarray(EMA) def macd(data, quick_n=12, slow_n=26, dem_n=9, val_name="close"): import numpy as np ''' 指数平滑异同平均线(MACD: Moving Average Convergence Divergence) Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 quick_n:int DIFF差离值中快速移动天数 slow_n:int DIFF差离值中慢速移动天数 dem_n:int DEM讯号线的移动天数 val_name:string 计算哪一列的列名,默认为 close 收盘值 return ------- OSC:numpy.ndarray MACD bar / OSC 差值柱形图 DIFF - DEM DIFF:numpy.ndarray 差离值 DEM:numpy.ndarray 讯号线 ''' ema_quick = np.asarray(ema(data, quick_n, val_name)) ema_slow = np.asarray(ema(data, slow_n, val_name)) DIFF = ema_quick - ema_slow data["diff"] = DIFF DEM = ema(data, dem_n, "diff") OSC = DIFF - DEM return OSC, DIFF, DEM def kdj(data): import numpy as np ''' 随机指标KDJ Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 return ------- K:numpy.ndarray K线 D:numpy.ndarray D线 J:numpy.ndarray J线 ''' K, D, J = [], [], [] last_k, last_d = None, None for index, row in data.iterrows(): if last_k is None or last_d is None: last_k = 50 last_d = 50 c, l, h = row["close"], row["low"], row["high"] rsv = (c - l) / (h - l) * 100 k = (2 / 3) * last_k + (1 / 3) * rsv d = (2 / 3) * last_d + (1 / 3) * k j = 3 * k - 2 * d K.append(k) D.append(d) J.append(j) last_k, last_d = k, d return np.asarray(K), np.asarray(D), np.asarray(J) def rsi(data, n=6, val_name="close"): import numpy as np ''' 相对强弱指标RSI Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 n:int 统计时长,时间单位根据data决定 return ------- RSI:numpy.ndarray RSI线 ''' RSI = [] UP = [] DOWN = [] for index, row in data.iterrows(): if index == 0: past_value = row[val_name] RSI.append(0) else: diff = row[val_name] - past_value if diff > 0: UP.append(diff) DOWN.append(0) else: UP.append(0) DOWN.append(diff) if len(UP) == n: del UP[0] if len(DOWN) == n: del DOWN[0] past_value = row[val_name] rsi = np.sum(UP) / (-np.sum(DOWN) + np.sum(UP)) * 100 RSI.append(rsi) return np.asarray(RSI) def boll(data, n=10, val_name="close", k=2): ''' 布林线指标BOLL Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 n:int 统计时长,时间单位根据data决定 return ------- BOLL:numpy.ndarray 中轨线 UPPER:numpy.ndarray D线 J:numpy.ndarray J线 ''' BOLL = ma(data, n, val_name) MD = md(data, n, val_name) UPPER = BOLL + k * MD LOWER = BOLL - k * MD return BOLL, UPPER, LOWER def wnr(data, n=14): ''' 威廉指标 w&r Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 n:int 统计时长,时间单位根据data决定 return ------- WNR:numpy.ndarray 威廉指标 ''' high_prices = [] low_prices = [] WNR = [] for index, row in data.iterrows(): high_prices.append(row["high"]) if len(high_prices) == n: del high_prices[0] low_prices.append(row["low"]) if len(low_prices) == n: del low_prices[0] highest = max(high_prices) lowest = min(low_prices) wnr = (highest - row["close"]) / (highest - lowest) * 100 WNR.append(wnr) return WNR def _get_any_ma(arr, n): import numpy as np MA = [] values = [] for val in arr: values.append(val) if len(values) == n: del values[0] MA.append(np.average(values)) return np.asarray(MA) def dmi(data, n=14, m=14, k=6): import numpy as np ''' 动向指标或趋向指标 DMI Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 n:int +-DI(n): DI统计时长,默认14 m:int ADX(m): ADX统计时常参数,默认14 k:int ADXR(k): ADXR统计k个周期前数据,默认6 return ------- P_DI:numpy.ndarray +DI指标 M_DI:numpy.ndarray -DI指标 ADX:numpy.ndarray ADX指标 ADXR:numpy.ndarray ADXR指标 ref. ------- https://www.mk-mode.com/octopress/2012/03/03/03002038/ ''' # 上升动向(+DM) P_DM = [0.] # 下降动向(-DM) M_DM = [0.] # 真实波幅TR TR = [0.] # 动向 DX = [0.] P_DI = [0.] M_DI = [0.] for index, row in data.iterrows(): if index == 0: past_row = row else: p_dm = row["high"] - past_row["high"] m_dm = past_row["low"] - row["low"] if (p_dm < 0 and m_dm < 0) or (np.isclose(p_dm, m_dm)): p_dm = 0 m_dm = 0 if p_dm > m_dm: m_dm = 0 if m_dm > p_dm: p_dm = 0 P_DM.append(p_dm) M_DM.append(m_dm) tr = max(row["high"] - past_row["low"], row["high"] - past_row["close"], past_row["close"] - row["low"]) TR.append(tr) if len(P_DM) == n: del P_DM[0] if len(M_DM) == n: del M_DM[0] if len(TR) == n: del TR[0] # 上升方向线(+DI) p_di = (np.average(P_DM) / np.average(TR)) * 100 P_DI.append(p_di) # 下降方向线(-DI) m_di = (np.average(M_DM) / np.average(TR)) * 100 M_DI.append(m_di) # 当日+DI与-DI # p_day_di = (p_dm / tr) * 100 # m_day_di = (m_dm / tr) * 100 # 动向DX # dx=(di dif÷di sum) ×100 #   di dif为上升指标和下降指标的价差的绝对值 #   di sum为上升指标和下降指标的总和 #   adx就是dx的一定周期n的移动平均值。 if (p_di + m_di) == 0: dx = 0 else: dx = (abs(p_di - m_di) / (p_di + m_di)) * 100 DX.append(dx) past_row = row ADX = _get_any_ma(DX, m) # # # 估计数值ADXR ADXR = [] for index, adx in enumerate(ADX): if index >= k: adxr = (adx + ADX[index - k]) / 2 ADXR.append(adxr) else: ADXR.append(0) return P_DI, M_DI, ADX, ADXR def bias(data, n=5): import numpy as np ''' 乖离率 bias Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 n:int 统计时长,默认5 return ------- BIAS:numpy.ndarray 乖离率指标 ''' MA = ma(data, n) CLOSES = data["close"] BIAS = (np.true_divide((CLOSES - MA), MA)) * (100 / 100) return BIAS def asi(data, n=5): import numpy as np ''' 振动升降指标 ASI Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 n:int 统计时长,默认5 return ------- ASI:numpy.ndarray 振动升降指标 ''' SI = [] for index, row in data.iterrows(): if index == 0: last_row = row SI.append(0.) else: a = abs(row["close"] - last_row["close"]) b = abs(row["low"] - last_row["close"]) c = abs(row["high"] - last_row["close"]) d = abs(last_row["close"] - last_row["open"]) if b > a and b > c: r = b + (1 / 2) * a + (1 / 4) * d elif c > a and c > b: r = c + (1 / 4) * d else: r = 0 e = row["close"] - last_row["close"] f = row["close"] - last_row["open"] g = last_row["close"] - last_row["open"] x = e + (1 / 2) * f + g k = max(a, b) l = 3 if np.isclose(r, 0) or np.isclose(l, 0): si = 0 else: si = 50 * (x / r) * (k / l) SI.append(si) ASI = _get_any_ma(SI, n) return ASI def vr(data, n=26): import numpy as np ''' Volatility Volume Ratio 成交量变异率 Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 n:int 统计时长,默认26 return ------- VR:numpy.ndarray 成交量变异率 ''' VR = [] AV_volumes, BV_volumes, CV_volumes = [], [], [] for index, row in data.iterrows(): if row["close"] > row["open"]: AV_volumes.append(row["volume"]) elif row["close"] < row["open"]: BV_volumes.append(row["volume"]) else: CV_volumes.append(row["volume"]) if len(AV_volumes) == n: del AV_volumes[0] if len(BV_volumes) == n: del BV_volumes[0] if len(CV_volumes) == n: del CV_volumes[0] avs = sum(AV_volumes) bvs = sum(BV_volumes) cvs = sum(CV_volumes) if (bvs + (1 / 2) * cvs) != 0: vr = (avs + (1 / 2) * cvs) / (bvs + (1 / 2) * cvs) else: vr = 0 VR.append(vr) return np.asarray(VR) def arbr(data, n=26): import numpy as np ''' AR 指标 BR指标 Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 n:int 统计时长,默认26 return ------- AR:numpy.ndarray AR指标 BR:numpy.ndarray BR指标 ''' H, L, O, PC = np.array([0]), np.array([0]), np.array([0]), np.array([0]) AR, BR = np.array([0]), np.array([0]) for index, row in data.iterrows(): if index == 0: last_row = row else: h = row["high"] H = np.append(H, [h]) if len(H) == n: H = np.delete(H, 0) l = row["low"] L = np.append(L, [l]) if len(L) == n: L = np.delete(L, 0) o = row["open"] O = np.append(O, [o]) if len(O) == n: O = np.delete(O, 0) pc = last_row["close"] PC = np.append(PC, [pc]) if len(PC) == n: PC = np.delete(PC, 0) ar = (np.sum(np.asarray(H) - np.asarray(O)) / sum(np.asarray(O) - np.asarray(L))) * 100 AR = np.append(AR, [ar]) br = (np.sum(np.asarray(H) - np.asarray(PC)) / sum(np.asarray(PC) - np.asarray(L))) * 100 BR = np.append(BR, [br]) last_row = row return np.asarray(AR), np.asarray(BR) def dpo(data, n=20, m=6): ''' 区间震荡线指标 DPO Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 n:int 统计时长,默认20 m:int MADPO的参数M,默认6 return ------- DPO:numpy.ndarray DPO指标 MADPO:numpy.ndarray MADPO指标 ''' CLOSES = data["close"] DPO = CLOSES - ma(data, int(n / 2 + 1)) MADPO = _get_any_ma(DPO, m) return DPO, MADPO def trix(data, n=12, m=20): import numpy as np ''' 三重指数平滑平均线 TRIX Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 n:int 统计时长,默认12 m:int TRMA的参数M,默认20 return ------- TRIX:numpy.ndarray AR指标 TRMA:numpy.ndarray BR指标 ''' CLOSES = [] TRIX = [] for index, row in data.iterrows(): CLOSES.append(row["close"]) if len(CLOSES) == n: del CLOSES[0] tr = np.average(CLOSES) if index == 0: past_tr = tr TRIX.append(0) else: trix = (tr - past_tr) / past_tr * 100 TRIX.append(trix) TRMA = _get_any_ma(TRIX, m) return TRIX, TRMA def bbi(data): import numpy as np ''' Bull And Bearlndex 多空指标 Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 return ------- BBI:numpy.ndarray BBI指标 ''' CS = [] BBI = [] for index, row in data.iterrows(): CS.append(row["close"]) if len(CS) < 24: BBI.append(row["close"]) else: bbi = np.average([np.average(CS[-3:]), np.average(CS[-6:]), np.average(CS[-12:]), np.average(CS[-24:])]) BBI.append(bbi) return np.asarray(BBI) def mtm(data, n=6): import numpy as np ''' Momentum Index 动量指标 Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 n:int 统计时长,默认6 return ------- MTM:numpy.ndarray MTM动量指标 ''' MTM = [] CN = [] for index, row in data.iterrows(): if index < n - 1: MTM.append(0.) else: mtm = row["close"] - CN[index - n] MTM.append(mtm) CN.append(row["close"]) return np.asarray(MTM) def obv(data): import numpy as np ''' On Balance Volume 能量潮指标 Parameters ------ data:pandas.DataFrame 通过 get_h_data 取得的股票数据 return ------- OBV:numpy.ndarray OBV能量潮指标 ''' tmp = np.true_divide(((data["close"] - data["low"]) - (data["high"] - data["close"])), (data["high"] - data["low"])) OBV = tmp * data["volume"] return OBV def sar(data, n=4): raise Exception("Not implemented yet") def plot_all(data, is_show=True, output=None): import matplotlib.pyplot as plt from pylab import rcParams import numpy as np rcParams['figure.figsize'] = 18, 50 plt.figure() # 收盘价 plt.subplot(20, 1, 1) plt.plot(data["date"], data["close"], label="close") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 移动平均线 plt.subplot(20, 1, 2) MA = ma(data, n=10) plt.plot(data["date"], MA, label="MA(n=10)") plt.plot(data["date"], data["close"], label="CLOSE PRICE") plt.title("MA") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 移动标准差 n = 10 plt.subplot(20, 1, 3) MD = md(data, n) plt.plot(data["date"], MD, label="MD(n=10)") plt.title("MD") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 指数平均数指标 plt.subplot(20, 1, 4) EMA = ema(data, n) plt.plot(data["date"], EMA, label="EMA(n=12)") plt.title("EMA") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 指数平滑异同平均线(MACD: Moving Average Convergence Divergence) plt.subplot(20, 1, 5) OSC, DIFF, DEM = macd(data, n) plt.plot(data["date"], OSC, label="OSC") plt.plot(data["date"], DIFF, label="DIFF") plt.plot(data["date"], DEM, label="DEM") plt.title("MACD") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 随机指标 plt.subplot(20, 1, 6) K, D, J = kdj(data) plt.plot(data["date"], K, label="K") plt.plot(data["date"], D, label="D") plt.plot(data["date"], J, label="J") plt.title("KDJ") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 相对强弱指标 plt.subplot(20, 1, 7) RSI6 = rsi(data, 6) RSI12 = rsi(data, 12) RSI24 = rsi(data, 24) plt.plot(data["date"], RSI6, label="RSI(n=6)") plt.plot(data["date"], RSI12, label="RSI(n=12)") plt.plot(data["date"], RSI24, label="RSI(n=24)") plt.title("RSI") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # BOLL 林线指标 plt.subplot(20, 1, 8) BOLL, UPPER, LOWER = boll(data) plt.plot(data["date"], BOLL, label="BOLL(n=10)") plt.plot(data["date"], UPPER, label="UPPER(n=10)") plt.plot(data["date"], LOWER, label="LOWER(n=10)") plt.plot(data["date"], data["close"], label="CLOSE PRICE") plt.title("BOLL") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # W&R 威廉指标 plt.subplot(20, 1, 9) WNR = wnr(data, n=14) plt.plot(data["date"], WNR, label="WNR(n=14)") plt.title("WNR") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 动向或趋向指标 plt.subplot(20, 1, 10) P_DI, M_DI, ADX, ADXR = dmi(data) plt.plot(data["date"], P_DI, label="+DI(n=14)") plt.plot(data["date"], M_DI, label="-DI(n=14)") plt.plot(data["date"], ADX, label="ADX(m=14)") plt.plot(data["date"], ADXR, label="ADXR(k=6)") plt.title("DMI") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 乖离值 plt.subplot(20, 1, 11) BIAS = bias(data, n=5) plt.plot(data["date"], BIAS, label="BIAS(n=5)") plt.title("BIAS") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 振动升降指标 plt.subplot(20, 1, 12) ASI = asi(data, n=5) plt.plot(data["date"], ASI, label="ASI(n=5)") plt.title("ASI") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 振动升降指标 plt.subplot(20, 1, 13) VR = vr(data, n=26) plt.plot(data["date"], VR, label="VR(n=26)") plt.title("VR") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 振动升降指标 plt.subplot(20, 1, 14) AR, BR = arbr(data, n=26) plt.plot(data["date"], AR, label="AR(n=26)") plt.plot(data["date"], BR, label="BR(n=26)") plt.title("ARBR") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 区间震荡线 plt.subplot(20, 1, 15) DPO, MADPO = dpo(data, n=20, m=6) plt.plot(data["date"], DPO, label="DPO(n=20)") plt.plot(data["date"], MADPO, label="MADPO(m=6)") plt.title("DPO") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 三重指数平滑平均线 plt.subplot(20, 1, 16) TRIX, TRMA = trix(data, n=12, m=20) plt.plot(data["date"], TRIX, label="DPO(n=12)") plt.plot(data["date"], TRMA, label="MADPO(m=20)") plt.title("TRIX") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 多空指标 plt.subplot(20, 1, 17) BBI = bbi(data) plt.plot(data["date"], BBI, label="BBI(3,6,12,24)") plt.title("BBI") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 动量指标 plt.subplot(20, 1, 18) MTM = mtm(data, n=6) plt.plot(data["date"], MTM, label="MTM(n=6)") plt.title("MTM") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) # 动量指标 plt.subplot(20, 1, 19) OBV = obv(data) plt.plot(data["date"], OBV, label="OBV") plt.title("OBV") plt.xlabel('date') plt.ylabel('value') plt.legend() plt.xticks(rotation=90) plt.tight_layout() if is_show: plt.show() if output is not None: plt.savefig(output) ================================================ FILE: tushare/stock/macro.py ================================================ # -*- coding:utf-8 -*- """ 宏观经济数据接口 Created on 2015/01/24 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ import pandas as pd import numpy as np import re import json from tushare.stock import macro_vars as vs from tushare.stock import cons as ct try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request def get_gdp_year(): """ 获取年度国内生产总值数据 Return -------- DataFrame year :统计年度 gdp :国内生产总值(亿元) pc_gdp :人均国内生产总值(元) gnp :国民生产总值(亿元) pi :第一产业(亿元) si :第二产业(亿元) industry :工业(亿元) cons_industry :建筑业(亿元) ti :第三产业(亿元) trans_industry :交通运输仓储邮电通信业(亿元) lbdy :批发零售贸易及餐饮业(亿元) """ rdint = vs.random() request = Request(vs.MACRO_URL%(vs.P_TYPE['http'], vs.DOMAINS['sina'], rdint, vs.MACRO_TYPE[0], 0, 70, rdint)) text = urlopen(request, timeout=10).read() text = text.decode('gbk') if ct.PY3 else text regSym = re.compile(r'\,count:(.*?)\}') datastr = regSym.findall(text) datastr = datastr[0] datastr = datastr.split('data:')[1] datastr = datastr.replace('"', '').replace('null', '0') js = json.loads(datastr) df = pd.DataFrame(js, columns=vs.GDP_YEAR_COLS) df[df==0] = np.NaN return df def get_gdp_quarter(): """ 获取季度国内生产总值数据 Return -------- DataFrame quarter :季度 gdp :国内生产总值(亿元) gdp_yoy :国内生产总值同比增长(%) pi :第一产业增加值(亿元) pi_yoy:第一产业增加值同比增长(%) si :第二产业增加值(亿元) si_yoy :第二产业增加值同比增长(%) ti :第三产业增加值(亿元) ti_yoy :第三产业增加值同比增长(%) """ rdint = vs.random() request = Request(vs.MACRO_URL%(vs.P_TYPE['http'], vs.DOMAINS['sina'], rdint, vs.MACRO_TYPE[0], 1, 250, rdint)) text = urlopen(request,timeout=10).read() text = text.decode('gbk') if ct.PY3 else text regSym = re.compile(r'\,count:(.*?)\}') datastr = regSym.findall(text) datastr = datastr[0] datastr = datastr.split('data:')[1] datastr = datastr.replace('"', '').replace('null', '0') js = json.loads(datastr) df = pd.DataFrame(js, columns=vs.GDP_QUARTER_COLS) df['quarter'] = df['quarter'].astype(object) df[df==0] = np.NaN return df def get_gdp_for(): """ 获取三大需求对GDP贡献数据 Return -------- DataFrame year :统计年度 end_for :最终消费支出贡献率(%) for_rate :最终消费支出拉动(百分点) asset_for :资本形成总额贡献率(%) asset_rate:资本形成总额拉动(百分点) goods_for :货物和服务净出口贡献率(%) goods_rate :货物和服务净出口拉动(百分点) """ rdint = vs.random() request = Request(vs.MACRO_URL%(vs.P_TYPE['http'], vs.DOMAINS['sina'], rdint, vs.MACRO_TYPE[0], 4, 80, rdint)) text = urlopen(request,timeout=10).read() text = text.decode('gbk') if ct.PY3 else text regSym = re.compile(r'\,count:(.*?)\}') datastr = regSym.findall(text) datastr = datastr[0] datastr = datastr.split('data:')[1] datastr = datastr.replace('"','').replace('null','0') js = json.loads(datastr) df = pd.DataFrame(js,columns=vs.GDP_FOR_COLS) df[df==0] = np.NaN return df def get_gdp_pull(): """ 获取三大产业对GDP拉动数据 Return -------- DataFrame year :统计年度 gdp_yoy :国内生产总值同比增长(%) pi :第一产业拉动率(%) si :第二产业拉动率(%) industry:其中工业拉动(%) ti :第三产业拉动率(%) """ rdint = vs.random() request = Request(vs.MACRO_URL%(vs.P_TYPE['http'], vs.DOMAINS['sina'], rdint, vs.MACRO_TYPE[0], 5, 60, rdint)) text = urlopen(request,timeout=10).read() text = text.decode('gbk') if ct.PY3 else text regSym = re.compile(r'\,count:(.*?)\}') datastr = regSym.findall(text) datastr = datastr[0] datastr = datastr.split('data:')[1] datastr = datastr.replace('"', '').replace('null', '0') js = json.loads(datastr) df = pd.DataFrame(js, columns=vs.GDP_PULL_COLS) df[df==0] = np.NaN return df def get_gdp_contrib(): """ 获取三大产业贡献率数据 Return -------- DataFrame year :统计年度 gdp_yoy :国内生产总值 pi :第一产业献率(%) si :第二产业献率(%) industry:其中工业献率(%) ti :第三产业献率(%) """ rdint = vs.random() request = Request(vs.MACRO_URL%(vs.P_TYPE['http'], vs.DOMAINS['sina'], rdint, vs.MACRO_TYPE[0], 6, 60, rdint)) text = urlopen(request, timeout=10).read() text = text.decode('gbk') if ct.PY3 else text regSym = re.compile(r'\,count:(.*?)\}') datastr = regSym.findall(text) datastr = datastr[0] datastr = datastr.split('data:')[1] datastr = datastr.replace('"', '').replace('null', '0') js = json.loads(datastr) df = pd.DataFrame(js, columns=vs.GDP_CONTRIB_COLS) df[df==0] = np.NaN return df def get_cpi(): """ 获取居民消费价格指数数据 Return -------- DataFrame month :统计月份 cpi :价格指数 """ rdint = vs.random() request = Request(vs.MACRO_URL%(vs.P_TYPE['http'], vs.DOMAINS['sina'], rdint, vs.MACRO_TYPE[1], 0, 600, rdint)) text = urlopen(request,timeout=10).read() text = text.decode('gbk') if ct.PY3 else text regSym = re.compile(r'\,count:(.*?)\}') datastr = regSym.findall(text) datastr = datastr[0] datastr = datastr.split('data:')[1] js = json.loads(datastr) df = pd.DataFrame(js, columns=vs.CPI_COLS) df['cpi'] = df['cpi'].astype(float) return df def get_ppi(): """ 获取工业品出厂价格指数数据 Return -------- DataFrame month :统计月份 ppiip :工业品出厂价格指数 ppi :生产资料价格指数 qm:采掘工业价格指数 rmi:原材料工业价格指数 pi:加工工业价格指数 cg:生活资料价格指数 food:食品类价格指数 clothing:衣着类价格指数 roeu:一般日用品价格指数 dcg:耐用消费品价格指数 """ rdint = vs.random() request = Request(vs.MACRO_URL%(vs.P_TYPE['http'], vs.DOMAINS['sina'], rdint, vs.MACRO_TYPE[1], 3, 600, rdint)) text = urlopen(request, timeout=10).read() text = text.decode('gbk') if ct.PY3 else text regSym = re.compile(r'\,count:(.*?)\}') datastr = regSym.findall(text) datastr = datastr[0] datastr = datastr.split('data:')[1] js = json.loads(datastr) df = pd.DataFrame(js, columns=vs.PPI_COLS) for i in df.columns: df[i] = df[i].apply(lambda x:np.where(x is None, np.NaN, x)) if i != 'month': df[i] = df[i].astype(float) return df def get_deposit_rate(): """ 获取存款利率数据 Return -------- DataFrame date :变动日期 deposit_type :存款种类 rate:利率(%) """ rdint = vs.random() request = Request(vs.MACRO_URL%(vs.P_TYPE['http'], vs.DOMAINS['sina'], rdint, vs.MACRO_TYPE[2], 2, 600, rdint)) text = urlopen(request, timeout=10).read() text = text.decode('gbk') regSym = re.compile(r'\,count:(.*?)\}') datastr = regSym.findall(text) datastr = datastr[0] datastr = datastr.split('data:')[1] js = json.loads(datastr) df = pd.DataFrame(js, columns=vs.DEPOSIT_COLS) for i in df.columns: df[i] = df[i].apply(lambda x:np.where(x is None, '--', x)) return df def get_loan_rate(): """ 获取贷款利率数据 Return -------- DataFrame date :执行日期 loan_type :存款种类 rate:利率(%) """ rdint = vs.random() request = Request(vs.MACRO_URL%(vs.P_TYPE['http'], vs.DOMAINS['sina'], rdint, vs.MACRO_TYPE[2], 3, 800, rdint)) text = urlopen(request, timeout=10).read() text = text.decode('gbk') regSym = re.compile(r'\,count:(.*?)\}') datastr = regSym.findall(text) datastr = datastr[0] datastr = datastr.split('data:')[1] js = json.loads(datastr) df = pd.DataFrame(js, columns=vs.LOAN_COLS) for i in df.columns: df[i] = df[i].apply(lambda x:np.where(x is None, '--', x)) return df def get_rrr(): """ 获取存款准备金率数据 Return -------- DataFrame date :变动日期 before :调整前存款准备金率(%) now:调整后存款准备金率(%) changed:调整幅度(%) """ rdint = vs.random() request = Request(vs.MACRO_URL%(vs.P_TYPE['http'], vs.DOMAINS['sina'], rdint, vs.MACRO_TYPE[2], 4, 100, rdint)) text = urlopen(request, timeout=10).read() text = text.decode('gbk') regSym = re.compile(r'\,count:(.*?)\}') datastr = regSym.findall(text) datastr = datastr[0] datastr = datastr.split('data:')[1] js = json.loads(datastr) df = pd.DataFrame(js, columns=vs.RRR_COLS) for i in df.columns: df[i] = df[i].apply(lambda x:np.where(x is None, '--', x)) return df def get_money_supply(): """ 获取货币供应量数据 Return -------- DataFrame month :统计时间 m2 :货币和准货币(广义货币M2)(亿元) m2_yoy:货币和准货币(广义货币M2)同比增长(%) m1:货币(狭义货币M1)(亿元) m1_yoy:货币(狭义货币M1)同比增长(%) m0:流通中现金(M0)(亿元) m0_yoy:流通中现金(M0)同比增长(%) cd:活期存款(亿元) cd_yoy:活期存款同比增长(%) qm:准货币(亿元) qm_yoy:准货币同比增长(%) ftd:定期存款(亿元) ftd_yoy:定期存款同比增长(%) sd:储蓄存款(亿元) sd_yoy:储蓄存款同比增长(%) rests:其他存款(亿元) rests_yoy:其他存款同比增长(%) """ rdint = vs.random() request = Request(vs.MACRO_URL%(vs.P_TYPE['http'], vs.DOMAINS['sina'], rdint, vs.MACRO_TYPE[2], 1, 600, rdint)) text = urlopen(request, timeout=10).read() text = text.decode('gbk') regSym = re.compile(r'\,count:(.*?)\}') datastr = regSym.findall(text) datastr = datastr[0] datastr = datastr.split('data:')[1] js = json.loads(datastr) df = pd.DataFrame(js, columns=vs.MONEY_SUPPLY_COLS) for i in df.columns: df[i] = df[i].apply(lambda x:np.where(x is None, '--', x)) return df def get_money_supply_bal(): """ 获取货币供应量(年底余额)数据 Return -------- DataFrame year :统计年度 m2 :货币和准货币(亿元) m1:货币(亿元) m0:流通中现金(亿元) cd:活期存款(亿元) qm:准货币(亿元) ftd:定期存款(亿元) sd:储蓄存款(亿元) rests:其他存款(亿元) """ rdint = vs.random() request = Request(vs.MACRO_URL%(vs.P_TYPE['http'], vs.DOMAINS['sina'], rdint, vs.MACRO_TYPE[2], 0, 200, rdint)) text = urlopen(request,timeout=10).read() text = text.decode('gbk') regSym = re.compile(r'\,count:(.*?)\}') datastr = regSym.findall(text) datastr = datastr[0] datastr = datastr.split('data:')[1] js = json.loads(datastr) df = pd.DataFrame(js, columns=vs.MONEY_SUPPLY_BLA_COLS) for i in df.columns: df[i] = df[i].apply(lambda x:np.where(x is None, '--', x)) return df def get_gold_and_foreign_reserves(): """ 获取外汇储备 Returns ------- DataFrame month :统计时间 gold:黄金储备(万盎司) foreign_reserves:外汇储备(亿美元) """ rdint = vs.random() request = Request(vs.MACRO_URL % (vs.P_TYPE['http'], vs.DOMAINS['sina'], rdint, vs.MACRO_TYPE[2], 5, 200, rdint)) text = urlopen(request,timeout=10).read() text = text.decode('gbk') regSym = re.compile(r'\,count:(.*?)\}') datastr = regSym.findall(text) datastr = datastr[0] datastr = datastr.split('data:')[1] js = json.loads(datastr) df = pd.DataFrame(js, columns=vs.GOLD_AND_FOREIGN_CURRENCY_RESERVES) for i in df.columns: df[i] = df[i].apply(lambda x: np.where(x is None, '--', x)) return df ================================================ FILE: tushare/stock/macro_vars.py ================================================ # -*- coding:utf-8 -*- P_TYPE = {'http':'http://','ftp':'ftp://'} DOMAINS = {'sina':'sina.com.cn','sinahq':'sinajs.cn','ifeng':'ifeng.com'} MACRO_TYPE = ['nation','price','fininfo'] MACRO_URL = '%smoney.finance.%s/mac/api/jsonp.php/SINAREMOTECALLCALLBACK%s/MacPage_Service.get_pagedata?cate=%s&event=%s&from=0&num=%s&condition=&_=%s' GDP_YEAR_COLS = ['year','gdp','pc_gdp','gnp','pi','si','industry','cons_industry','ti','trans_industry','lbdy'] GDP_QUARTER_COLS = ['quarter','gdp','gdp_yoy','pi','pi_yoy','si','si_yoy','ti','ti_yoy'] GDP_FOR_COLS = ['year','end_for','for_rate','asset_for','asset_rate','goods_for','goods_rate'] GDP_PULL_COLS = ['year','gdp_yoy','pi','si','industry','ti'] GDP_CONTRIB_COLS = ['year','gdp_yoy','pi','si','industry','ti'] CPI_COLS = ['month','cpi'] PPI_COLS = ['month','ppiip','ppi','qm','rmi','pi','cg','food','clothing','roeu','dcg'] DEPOSIT_COLS = ['date','deposit_type','rate'] LOAN_COLS = ['date','loan_type','rate'] RRR_COLS = ['date','before','now','changed'] MONEY_SUPPLY_COLS = ['month','m2','m2_yoy','m1','m1_yoy','m0','m0_yoy','cd','cd_yoy','qm','qm_yoy','ftd','ftd_yoy','sd','sd_yoy','rests','rests_yoy'] MONEY_SUPPLY_BLA_COLS = ['year','m2','m1','m0','cd','qm','ftd','sd','rests'] GOLD_AND_FOREIGN_CURRENCY_RESERVES = ['month','gold','foreign_reserves'] def random(n=13): from random import randint start = 10**(n-1) end = (10**n)-1 return str(randint(start, end)) ================================================ FILE: tushare/stock/news_vars.py ================================================ # -*- coding:utf-8 -*- LATEST_URL = '%sroll.news.%s/interface/%s?col=43&spec=&type=&ch=03&k=&offset_page=0&offset_num=0&num=%s&asc=&page=1&r=0.%s' LATEST_COLS = ['classify','title','time','url'] LATEST_COLS_C = ['classify','title','time','url','content'] NOTICE_INFO_URL = '%s%s/corp/view/%s?stock_str=%s' NOTICE_INFO_CLS = ['title', 'type', 'date', 'url'] GUBA_SINA_URL = '%sguba.%s' GUBA_SINA_COLS = ['title', 'content', 'ptime', 'rcounts'] ================================================ FILE: tushare/stock/newsevent.py ================================================ # -*- coding:utf-8 -*- """ 新闻事件数据接口 Created on 2015/02/07 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ from tushare.stock import cons as ct from tushare.stock import news_vars as nv import pandas as pd from datetime import datetime import lxml.html from lxml import etree import re import json try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request def get_latest_news(top=None, show_content=False): """ 获取即时财经新闻 Parameters -------- top:数值,显示最新消息的条数,默认为80条 show_content:是否显示新闻内容,默认False Return -------- DataFrame classify :新闻类别 title :新闻标题 time :发布时间 url :新闻链接 content:新闻内容(在show_content为True的情况下出现) """ top = ct.PAGE_NUM[2] if top is None else top try: request = Request(nv.LATEST_URL % (ct.P_TYPE['http'], ct.DOMAINS['sina'], ct.PAGES['lnews'], top, _random())) data_str = urlopen(request, timeout=10).read() data_str = data_str.decode('GBK') data_str = data_str.split('=')[1][:-1] data_str = eval(data_str, type('Dummy', (dict,), dict(__getitem__ = lambda s, n:n))()) data_str = json.dumps(data_str) data_str = json.loads(data_str) data_str = data_str['list'] data = [] for r in data_str: rt = datetime.fromtimestamp(r['time']) rtstr = datetime.strftime(rt, "%m-%d %H:%M") arow = [r['channel']['title'], r['title'], rtstr, r['url']] if show_content: arow.append(latest_content(r['url'])) data.append(arow) df = pd.DataFrame(data, columns=nv.LATEST_COLS_C if show_content else nv.LATEST_COLS) return df except Exception as er: print(str(er)) def latest_content(url): ''' 获取即时财经新闻内容 Parameter -------- url:新闻链接 Return -------- string:返回新闻的文字内容 ''' try: html = lxml.html.parse(url) res = html.xpath('//div[@id=\"artibody\"]/p') if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr).replace(' ', '')#.replace('\n\n', '\n'). html_content = lxml.html.fromstring(sarr) content = html_content.text_content() return content except Exception as er: print(str(er)) def get_notices(code=None, date=None): ''' 个股信息地雷 Parameters -------- code:股票代码 date:信息公布日期 Return -------- DataFrame,属性列表: title:信息标题 type:信息类型 date:公告日期 url:信息内容URL ''' if code is None: return None symbol = 'sh' + code if code[:1] == '6' else 'sz' + code url = nv.NOTICE_INFO_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['ntinfo'], symbol) url = url if date is None else '%s&gg_date=%s'%(url, date) html = lxml.html.parse(url) res = html.xpath('//table[@class=\"body_table\"]/tbody/tr') data = [] for td in res: title = td.xpath('th/a/text()')[0] type = td.xpath('td[1]/text()')[0] date = td.xpath('td[2]/text()')[0] url = '%s%s%s'%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], td.xpath('th/a/@href')[0]) data.append([title, type, date, url]) df = pd.DataFrame(data, columns=nv.NOTICE_INFO_CLS) return df def notice_content(url): ''' 获取信息地雷内容 Parameter -------- url:内容链接 Return -------- string:信息内容 ''' try: html = lxml.html.parse(url) res = html.xpath('//div[@id=\"content\"]/pre/text()')[0] return res.strip() except Exception as er: print(str(er)) def guba_sina(show_content=False): """ 获取sina财经股吧首页的重点消息 Parameter -------- show_content:是否显示内容,默认False Return -------- DataFrame title, 消息标题 content, 消息内容(show_content=True的情况下) ptime, 发布时间 rcounts,阅读次数 """ from pandas.io.common import urlopen try: with urlopen(nv.GUBA_SINA_URL%(ct.P_TYPE['http'], ct.DOMAINS['sina'])) as resp: lines = resp.read() html = lxml.html.document_fromstring(lines) res = html.xpath('//ul[@class=\"list_05\"]/li[not (@class)]') heads = html.xpath('//div[@class=\"tit_04\"]') data = [] for head in heads: title = head.xpath('a/text()')[0] url = head.xpath('a/@href')[0] ds = [title] ds.extend(_guba_content(url)) data.append(ds) for row in res: title = row.xpath('a[2]/text()')[0] url = row.xpath('a[2]/@href')[0] ds = [title] ds.extend(_guba_content(url)) data.append(ds) df = pd.DataFrame(data, columns=nv.GUBA_SINA_COLS) df['rcounts'] = df['rcounts'].astype(float) return df if show_content is True else df.drop('content', axis=1) except Exception as er: print(str(er)) def _guba_content(url): try: html = lxml.html.parse(url) res = html.xpath('//div[@class=\"ilt_p\"]/p') if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr).replace(' ', '')#.replace('\n\n', '\n'). html_content = lxml.html.fromstring(sarr) content = html_content.text_content() ptime = html.xpath('//div[@class=\"fl_left iltp_time\"]/span/text()')[0] rcounts = html.xpath('//div[@class=\"fl_right iltp_span\"]/span[2]/text()')[0] reg = re.compile(r'\((.*?)\)') rcounts = reg.findall(rcounts)[0] return [content, ptime, rcounts] except Exception: return ['', '', '0'] def _random(n=16): from random import randint start = 10 ** (n - 1) end = (10 ** n) - 1 return str(randint(start, end)) ================================================ FILE: tushare/stock/ref_vars.py ================================================ # -*- coding:utf-8 -*- DP_URL = '%sapp.finance.%s/data/stock/%s?day=&page=%s' DP_163_URL = '%squotes.%s/data/caibao/%s?reportdate=%s&sort=declaredate&order=desc&page=%s' FUND_HOLDS_URL = '%squotes.%s/hs/marketdata/service/%s?host=/hs/marketdata/service/%s&page=%s&query=start:%s;end:%s&order=desc&count=60&type=query&req=%s' XSG_URL = '%sdatainterface.%s/EM_DataCenter/%s?type=FD&sty=BST&st=3&sr=true&fd=%s&stat=%s' # LHB_URL = '%sdata.%s/stock/lhb/%s.html' LHB_URL = '%sdata.%s/DataCenter_V3/stock2016/TradeDetail/pagesize=200,page=1,sortRule=-1,sortType=,startDate=%s,endDate=%s,gpfw=0,js=vardata_tab_1.html' LHB_SINA_URL = '%s%s/q/go.php/vLHBData/kind/%s/%s?last=%s&p=%s' LHB_TMP_COLS = ['SCode', 'SName', 'Chgradio', 'ZeMoney', 'Bmoney', 'Smoney', 'Ctypedes', 'Turnover'] LHB_COLS = ['code', 'name', 'pchange', 'amount', 'buy', 'sell', 'reason', 'Turnover'] NEW_STOCKS_URL = '%s%s/corp/view/%s?page=%s&cngem=0&orderBy=NetDate&orderType=desc' NEW_CBONDS_URL = '%s%s/ipo/kzz_7_1_%s.html' MAR_SH_HZ_URL = '%s%s/marketdata/tradedata/%s?jsonCallBack=jsonpCallback%s&isPagination=true&tabType=&pageHelp.pageSize=100&beginDate=%s&endDate=%s%s&_=%s' MAR_SH_HZ_REF_URL = '%s%s/market/dealingdata/overview/margin/' MAR_SH_MX_URL = '%s%s/marketdata/tradedata/%s?jsonCallBack=jsonpCallback%s&isPagination=true&tabType=mxtype&detailsDate=%s&pageHelp.pageSize=100&stockCode=%s&beginDate=%s&endDate=%s%s&_=%s' MAR_SZ_HZ_URL = '%s%s/szseWeb/%s?SHOWTYPE=EXCEL&ACTIONID=8&CATALOGID=1837_xxpl&txtDate=%s&tab2PAGENUM=1&ENCODE=1&TABKEY=tab1' MAR_SZ_MX_URL = '%s%s/szseWeb/%s?SHOWTYPE=EXCEL&ACTIONID=8&CATALOGID=1837_xxpl&txtDate=%s&tab2PAGENUM=1&ENCODE=1&TABKEY=tab2' MAR_SH_HZ_TAIL_URL = '&pageHelp.pageNo=%s&pageHelp.beginPage=%s&pageHelp.endPage=%s' TERMINATED_URL = '%s%s/%s?jsonCallBack=jsonpCallback%s&isPagination=true&sqlId=COMMON_SSE_ZQPZ_GPLB_MCJS_ZZSSGGJBXX_L&pageHelp.pageSize=50&_=%s' SUSPENDED_URL = '%s%s/%s?jsonCallBack=jsonpCallback%s&isPagination=true&sqlId=COMMON_SSE_ZQPZ_GPLB_MCJS_ZTSSGS_L&pageHelp.pageSize=50&_=%s' TOP10_HOLDERS_URL = '%swebf10.%s/SDGD/SD%sGD%s.js' TOP10_SUMM_COLS = ['quarter', 'amount', 'changed' ,'props'] TOP10_PER_COLS = ['quarter', 'name', 'hold', 'h_pro', 'sharetype', 'status'] TERMINATED_T_COLS = ['COMPANY_CODE', 'COMPANY_ABBR', 'LISTING_DATE', 'CHANGE_DATE'] LHB_KINDS = ['ggtj', 'yytj', 'jgzz', 'jgmx'] LHB_GGTJ_COLS = ['code', 'name', 'count', 'bamount', 'samount', 'net', 'bcount', 'scount'] LHB_YYTJ_COLS = ['broker', 'count', 'bamount', 'bcount', 'samount', 'scount', 'top3'] LHB_JGZZ_COLS = ['code', 'name', 'bamount', 'bcount', 'samount', 'scount', 'net'] LHB_JGMX_COLS = ['code', 'name', 'date', 'bamount', 'samount', 'type'] TERMINATED_COLS = ['code', 'name', 'oDate', 'tDate'] DP_COLS = ['report_date', 'quarter', 'code', 'name', 'plan'] DP_163_COLS = ['code', 'name', 'year', 'plan', 'report_date'] XSG_COLS = ['code', 'name', 'date', 'count', 'ratio'] QUARTS_DIC = {'1':('%s-12-31', '%s-03-31'), '2':('%s-03-31', '%s-06-30'), '3':('%s-06-30', '%s-09-30'), '4':('%s-9-30', '%s-12-31')} FUND_HOLDS_COLS = ['count', 'clast', 'date', 'ratio', 'amount', 'nums','nlast', 'name', 'code'] NEW_STOCKS_COLS = ['code', 'xcode', 'name', 'ipo_date', 'issue_date', 'amount', 'markets', 'price', 'pe', 'limit', 'funds', 'ballot'] NEW_CBONDS_COLS = ['bcode', 'bname', 'scode', 'sname', 'xcode', 'amount', 'marketprice', 'convprice', 'firstdayprice', 'ipo_date', 'issue_date', 'ballot', 'return', 'perreturn'] MAR_SH_COOKIESTR = '_gscu_1808689395=27850607moztu036' MAR_SH_HZ_COLS = ['opDate', 'rzye', 'rzmre', 'rqyl', 'rqylje', 'rqmcl', 'rzrqjyzl'] MAR_SH_MX_COLS = ['opDate', 'stockCode', 'securityAbbr', 'rzye', 'rzmre', 'rzche', 'rqyl', 'rqmcl', 'rqchl'] MAR_SZ_HZ_COLS = ['rzmre', 'rzye', 'rqmcl', 'rqyl', 'rqye', 'rzrqye'] MAR_SZ_MX_COLS = ['stockCode', 'securityAbbr', 'rzmre', 'rzye', 'rqmcl', 'rqyl', 'rqye', 'rzrqye'] MAR_SZ_HZ_MSG = 'please do not input more than a year,you can obtaining the data year by year.' MAR_SZ_HZ_MSG2 = 'start and end date all need input.' HSGT_TEMP = ['DateTime', 'GGHSMoney', 'GGSSMoney', 'HSMoney', 'SSMoney', 'NorthMoney', 'SouthSumMoney'] HSGT_COLS = ['date', 'ggt_ss', 'ggt_sz', 'hgt', 'sgt', 'north_money', 'south_money'] HSGT_REF = '%sdata.%s/hsgt/%s' HSGT_DATA = '%sdcfm.%s/EM_MutiSvcExpandInterface/api/js/get?type=HSGTZJZS&token=70f12f2f4f091e459a279469fe49eca5' ================================================ FILE: tushare/stock/reference.py ================================================ # -*- coding:utf-8 -*- """ 投资参考数据接口 Created on 2015/03/21 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ from __future__ import division from tushare.stock import cons as ct from tushare.stock import ref_vars as rv import pandas as pd import numpy as np import time import lxml.html from lxml import etree import re import json from pandas.compat import StringIO from tushare.util import dateu as du from tushare.util.netbase import Client try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request def profit_data(year=2017, top=25, retry_count=3, pause=0.001): """ 获取分配预案数据 Parameters -------- year:年份 top:取最新n条数据,默认取最近公布的25条 retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 returns ------- DataFrame code:股票代码 name:股票名称 year:分配年份 report_date:公布日期 divi:分红金额(每10股) shares:转增和送股数(每10股) """ if top == 'all': ct._write_head() df, pages = _dist_cotent(year, 0, retry_count, pause) for idx in range(1,int(pages)): df = df.append(_dist_cotent(year, idx, retry_count, pause), ignore_index=True) return df elif top <= 25: df, pages = _dist_cotent(year, 0, retry_count, pause) return df.head(top) else: if isinstance(top, int): ct._write_head() allPages = top/25+1 if top%25>0 else top/25 df, pages = _dist_cotent(year, 0, retry_count, pause) if int(allPages) < int(pages): pages = allPages for idx in range(1, int(pages)): df = df.append(_dist_cotent(year, idx, retry_count, pause), ignore_index=True) return df.head(top) else: print(ct.TOP_PARAS_MSG) def _fun_divi(x): if ct.PY3: reg = re.compile(r'分红(.*?)元', re.UNICODE) res = reg.findall(x) return 0 if len(res)<1 else float(res[0]) else: if isinstance(x, unicode): s1 = unicode('分红','utf-8') s2 = unicode('元','utf-8') reg = re.compile(r'%s(.*?)%s'%(s1, s2), re.UNICODE) res = reg.findall(x) return 0 if len(res)<1 else float(res[0]) else: return 0 def _fun_into(x): if ct.PY3: reg1 = re.compile(r'转增(.*?)股', re.UNICODE) reg2 = re.compile(r'送股(.*?)股', re.UNICODE) res1 = reg1.findall(x) res2 = reg2.findall(x) res1 = 0 if len(res1)<1 else float(res1[0]) res2 = 0 if len(res2)<1 else float(res2[0]) return res1 + res2 else: if isinstance(x, unicode): s1 = unicode('转增','utf-8') s2 = unicode('送股','utf-8') s3 = unicode('股','utf-8') reg1 = re.compile(r'%s(.*?)%s'%(s1, s3), re.UNICODE) reg2 = re.compile(r'%s(.*?)%s'%(s2, s3), re.UNICODE) res1 = reg1.findall(x) res2 = reg2.findall(x) res1 = 0 if len(res1)<1 else float(res1[0]) res2 = 0 if len(res2)<1 else float(res2[0]) return res1 + res2 else: return 0 def _dist_cotent(year, pageNo, retry_count, pause): for _ in range(retry_count): time.sleep(pause) try: if pageNo > 0: ct._write_console() html = lxml.html.parse(rv.DP_163_URL%(ct.P_TYPE['http'], ct.DOMAINS['163'], ct.PAGES['163dp'], year, pageNo)) res = html.xpath('//div[@class=\"fn_rp_list\"]/table') if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) df = pd.read_html(sarr, skiprows=[0])[0] df = df.drop(df.columns[0], axis=1) df.columns = rv.DP_163_COLS df['divi'] = df['plan'].map(_fun_divi) df['shares'] = df['plan'].map(_fun_into) df = df.drop('plan', axis=1) df['code'] = df['code'].astype(object) df['code'] = df['code'].map(lambda x : str(x).zfill(6)) pages = [] if pageNo == 0: page = html.xpath('//div[@class=\"mod_pages\"]/a') if len(page)>1: asr = page[len(page)-2] pages = asr.xpath('text()') except Exception as e: print(e) else: if pageNo == 0: return df, pages[0] if len(pages)>0 else 0 else: return df raise IOError(ct.NETWORK_URL_ERROR_MSG) def profit_divis(): ''' 获取分送送股数据 ------- Return:DataFrame code:代码 name:证券简称 year:分配年度 bshares:送股 incshares:转增股 totals:送转总数 cash:派现 plandate:预案公布日 regdate:股权登记日 exdate:除权除息日 eventproc:事件进程 ,预案或实施 anndate:公告日期 ''' ct._write_head() p = 'cfidata.aspx?sortfd=&sortway=&curpage=1&fr=content&ndk=A0A1934A1939A1957A1966A1983&xztj=&mystock=' df = _profit_divis(1, pd.DataFrame(), p) df = df.drop([3], axis=1) df.columns = ct.PROFIT_DIVIS df['code'] = df['code'].map(lambda x: str(x).zfill(6)) return df def _profit_divis(pageNo, dataArr, nextPage): ct._write_console() html = lxml.html.parse('%sdata.cfi.cn/%s'%(ct.P_TYPE['http'], nextPage)) res = html.xpath("//table[@class=\"table_data\"]/tr") if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = sarr.replace('--', '0') sarr = '%s
'%sarr df = pd.read_html(sarr, skiprows=[0])[0] dataArr = dataArr.append(df, ignore_index=True) nextPage = html.xpath('//div[@id=\"content\"]/div[2]/a[last()]/@href')[0] np = nextPage.split('&')[2].split('=')[1] if pageNo < int(np): return _profit_divis(int(np), dataArr, nextPage) else: return dataArr def forecast_data(year, quarter): """ 获取业绩预告数据 Parameters -------- year:int 年度 e.g:2014 quarter:int 季度 :1、2、3、4,只能输入这4个季度 说明:由于是从网站获取的数据,需要一页页抓取,速度取决于您当前网络速度 Return -------- DataFrame code,代码 name,名称 type,业绩变动类型【预增、预亏等】 report_date,发布日期 pre_eps,上年同期每股收益 range,业绩变动范围 """ if ct._check_input(year, quarter) is True: ct._write_head() data = _get_forecast_data(year, quarter, 1, pd.DataFrame()) df = pd.DataFrame(data, columns=ct.FORECAST_COLS) df['code'] = df['code'].map(lambda x: str(x).zfill(6)) return df def _get_forecast_data(year, quarter, pageNo, dataArr): ct._write_console() try: gparser = etree.HTMLParser(encoding='GBK') html = lxml.html.parse(ct.FORECAST_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['fd'], year, quarter, pageNo, ct.PAGE_NUM[1]), parser=gparser) res = html.xpath("//table[@class=\"list_table\"]/tr") if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = sarr.replace('--', '0') sarr = '%s
'%sarr df = pd.read_html(sarr)[0] df = df.drop([4, 5, 8], axis=1) df.columns = ct.FORECAST_COLS dataArr = dataArr.append(df, ignore_index=True) nextPage = html.xpath('//div[@class=\"pages\"]/a[last()]/@onclick') if len(nextPage)>0: pageNo = re.findall(r'\d+',nextPage[0])[0] return _get_forecast_data(year, quarter, pageNo, dataArr) else: return dataArr except Exception as e: print(e) def xsg_data(year=None, month=None, retry_count=3, pause=0.001): """ 获取限售股解禁数据 Parameters -------- year:年份,默认为当前年 month:解禁月份,默认为当前月 retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 Return ------ DataFrame code:股票代码 name:名称 date:解禁日期 count:解禁数量(万股) ratio:占总盘比率 """ year = du.get_year() if year is None else year month = du.get_month() if month is None else month for _ in range(retry_count): time.sleep(pause) try: request = Request(rv.XSG_URL%(ct.P_TYPE['http'], ct.DOMAINS['em'], ct.PAGES['emxsg'], year, month)) lines = urlopen(request, timeout = 10).read() lines = lines.decode('utf-8') if ct.PY3 else lines except Exception as e: print(e) else: da = lines[3:len(lines)-3] list = [] for row in da.split('","'): list.append([data for data in row.split(',')]) df = pd.DataFrame(list) df = df[[1, 3, 4, 5, 6]] for col in [5, 6]: df[col] = df[col].astype(float) df[5] = df[5]/10000 df[6] = df[6]*100 df[5] = df[5].map(ct.FORMAT) df[6] = df[6].map(ct.FORMAT) df.columns = rv.XSG_COLS return df raise IOError(ct.NETWORK_URL_ERROR_MSG) def fund_holdings(year, quarter, retry_count=3, pause=0.001): """ 获取基金持股数据 Parameters -------- year:年份e.g 2014 quarter:季度(只能输入1,2,3,4这个四个数字) retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 Return ------ DataFrame code:股票代码 name:名称 date:报告日期 nums:基金家数 nlast:与上期相比(增加或减少了) count:基金持股数(万股) clast:与上期相比 amount:基金持股市值 ratio:占流通盘比率 """ start,end = rv.QUARTS_DIC[str(quarter)] if quarter == 1: start = start % str(year-1) end = end%year else: start, end = start%year, end%year ct._write_head() df, pages = _holding_cotent(start, end, 0, retry_count, pause) for idx in range(1, pages): df = df.append(_holding_cotent(start, end, idx, retry_count, pause), ignore_index=True) return df def _holding_cotent(start, end, pageNo, retry_count, pause): for _ in range(retry_count): time.sleep(pause) if pageNo>0: ct._write_console() try: request = Request(rv.FUND_HOLDS_URL%(ct.P_TYPE['http'], ct.DOMAINS['163'], ct.PAGES['163fh'], ct.PAGES['163fh'], pageNo, start, end, _random(5))) lines = urlopen(request, timeout = 10).read() lines = lines.decode('utf-8') if ct.PY3 else lines lines = lines.replace('--', '0') lines = json.loads(lines) data = lines['list'] df = pd.DataFrame(data) df = df.drop(['CODE', 'ESYMBOL', 'EXCHANGE', 'NAME', 'RN', 'SHANGQIGUSHU', 'SHANGQISHIZHI', 'SHANGQISHULIANG'], axis=1) for col in ['GUSHU', 'GUSHUBIJIAO', 'SHIZHI', 'SCSTC27']: df[col] = df[col].astype(float) df['SCSTC27'] = df['SCSTC27']*100 df['GUSHU'] = df['GUSHU']/10000 df['GUSHUBIJIAO'] = df['GUSHUBIJIAO']/10000 df['SHIZHI'] = df['SHIZHI']/10000 df['GUSHU'] = df['GUSHU'].map(ct.FORMAT) df['GUSHUBIJIAO'] = df['GUSHUBIJIAO'].map(ct.FORMAT) df['SHIZHI'] = df['SHIZHI'].map(ct.FORMAT) df['SCSTC27'] = df['SCSTC27'].map(ct.FORMAT) df.columns = rv.FUND_HOLDS_COLS df = df[['code', 'name', 'date', 'nums', 'nlast', 'count', 'clast', 'amount', 'ratio']] except Exception as e: print(e) else: if pageNo == 0: return df, int(lines['pagecount']) else: return df raise IOError(ct.NETWORK_URL_ERROR_MSG) def new_stocks(retry_count=3, pause=0.001): """ 获取新股上市数据 Parameters -------- retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 Return ------ DataFrame code:股票代码 xcode:申购代码 name:名称 ipo_date:上网发行日期 issue_date:上市日期 amount:发行数量(万股) markets:上网发行数量(万股) price:发行价格(元) pe:发行市盈率 limit:个人申购上限(万股) funds:募集资金(亿元) ballot:网上中签率(%) """ data = pd.DataFrame() ct._write_head() df = _newstocks(data, 1, retry_count, pause) return df def _newstocks(data, pageNo, retry_count, pause): for _ in range(retry_count): time.sleep(pause) ct._write_console() try: html = lxml.html.parse(rv.NEW_STOCKS_URL%(ct.P_TYPE['http'],ct.DOMAINS['vsf'], ct.PAGES['newstock'], pageNo)) res = html.xpath('//table[@id=\"NewStockTable\"]/tr') if len(res) == 0: return data if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = sarr.replace('*', '') sarr = '%s
'%sarr df = pd.read_html(StringIO(sarr), skiprows=[0, 1])[0] df = df.drop([df.columns[idx] for idx in [12, 13, 14]], axis=1) df.columns = rv.NEW_STOCKS_COLS df['code'] = df['code'].map(lambda x : str(x).zfill(6)) df['xcode'] = df['xcode'].map(lambda x : str(x).zfill(6)) res = html.xpath('//table[@class=\"table2\"]/tr[1]/td[1]/a/text()') tag = '下一页' if ct.PY3 else unicode('下一页', 'utf-8') hasNext = True if tag in res else False data = data.append(df, ignore_index=True) pageNo += 1 if hasNext: data = _newstocks(data, pageNo, retry_count, pause) except Exception as ex: print(ex) else: return data def new_cbonds(default=1, retry_count=3, pause=0.001): """ 获取可转债申购列表 Parameters -------- retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 Return ------ DataFrame bcode:债券代码 bname:债券名称 scode:股票代码 sname:股票名称 xcode:申购代码 amount:发行总数(亿元) marketprice:最新市场价格 convprice:转股价格 firstdayprice:首日收盘价 ipo_date:上网发行日期 issue_date:上市日期 ballot:中签率(%) return:打新收益率(%) perreturn:每中一股收益(万元) """ data = pd.DataFrame() if default == 1: data = _newcbonds(1, retry_count, pause) else: for page in range(1, 50): df = _newcbonds(page, retry_count, pause) if df is not None: data = data.append(df, ignore_index=True) else: break return data def _newcbonds(pageNo, retry_count, pause): for _ in range(retry_count): time.sleep(pause) if pageNo != 1: ct._write_console() try: html = lxml.html.parse(rv.NEW_CBONDS_URL%(ct.P_TYPE['http'],ct.DOMAINS['sstar'], pageNo)) res = html.xpath('//table/tr') if len(res) == 0: return None if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = '%s
'%sarr df = pd.read_html(StringIO(sarr), skiprows=[0]) if len(df) < 1: return None df = df[0] df = df.drop([df.columns[14], df.columns[15]], axis=1) df.columns = rv.NEW_CBONDS_COLS df['scode'] = df['scode'].map(lambda x: str(x).zfill(6)) df['xcode'] = df['xcode'].map(lambda x: str(x).zfill(6)) except Exception as ex: print(ex) else: return df def sh_margins(start=None, end=None, retry_count=3, pause=0.001): """ 获取沪市融资融券数据列表 Parameters -------- start:string 开始日期 format:YYYY-MM-DD 为空时取去年今日 end:string 结束日期 format:YYYY-MM-DD 为空时取当前日期 retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 Return ------ DataFrame opDate:信用交易日期 rzye:本日融资余额(元) rzmre: 本日融资买入额(元) rqyl: 本日融券余量 rqylje: 本日融券余量金额(元) rqmcl: 本日融券卖出量 rzrqjyzl:本日融资融券余额(元) """ start = du.today_last_year() if start is None else start end = du.today() if end is None else end if du.diff_day(start, end) < 0: return None start, end = start.replace('-', ''), end.replace('-', '') data = pd.DataFrame() ct._write_head() df = _sh_hz(data, start=start, end=end, retry_count=retry_count, pause=pause) return df def _sh_hz(data, start=None, end=None, pageNo='', beginPage='', endPage='', retry_count=3, pause=0.001): for _ in range(retry_count): time.sleep(pause) ct._write_console() try: tail = rv.MAR_SH_HZ_TAIL_URL%(pageNo, beginPage, endPage) if pageNo == '': pageNo = 6 tail = '' else: pageNo += 5 beginPage = pageNo endPage = pageNo + 4 url = rv.MAR_SH_HZ_URL%(ct.P_TYPE['http'], ct.DOMAINS['sseq'], ct.PAGES['qmd'], _random(5), start, end, tail, _random()) ref = rv.MAR_SH_HZ_REF_URL%(ct.P_TYPE['http'], ct.DOMAINS['sse']) clt = Client(url, ref=ref, cookie=rv.MAR_SH_COOKIESTR) lines = clt.gvalue() lines = lines.decode('utf-8') if ct.PY3 else lines lines = lines[19:-1] lines = json.loads(lines) pagecount = int(lines['pageHelp'].get('pageCount')) datapage = int(pagecount/5+1 if pagecount%5>0 else pagecount/5) df = pd.DataFrame(lines['result'], columns=rv.MAR_SH_HZ_COLS) df['opDate'] = df['opDate'].map(lambda x: '%s-%s-%s'%(x[0:4], x[4:6], x[6:8])) data = data.append(df, ignore_index=True) if beginPage < datapage*5: data = _sh_hz(data, start=start, end=end, pageNo=pageNo, beginPage=beginPage, endPage=endPage, retry_count=retry_count, pause=pause) except Exception as e: print(e) else: return data raise IOError(ct.NETWORK_URL_ERROR_MSG) def sh_margin_details(date='', symbol='', start='', end='', retry_count=3, pause=0.001): """ 获取沪市融资融券明细列表 Parameters -------- date:string 明细数据日期 format:YYYY-MM-DD 默认为空'' symbol:string 标的代码,6位数字e.g.600848,默认为空 start:string 开始日期 format:YYYY-MM-DD 默认为空'' end:string 结束日期 format:YYYY-MM-DD 默认为空'' retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 Return ------ DataFrame opDate:信用交易日期 stockCode:标的证券代码 securityAbbr:标的证券简称 rzye:本日融资余额(元) rzmre: 本日融资买入额(元) rzche:本日融资偿还额(元) rqyl: 本日融券余量 rqmcl: 本日融券卖出量 rqchl: 本日融券偿还量 """ date = date if date == '' else date.replace('-', '') start = start if start == '' else start.replace('-', '') end = end if end == '' else end.replace('-', '') if (start != '') & (end != ''): date = '' data = pd.DataFrame() ct._write_head() df = _sh_mx(data, date=date, start=start, end=end, symbol=symbol, retry_count=retry_count, pause=pause) return df def _sh_mx(data, date='', start='', end='', symbol='', pageNo='', beginPage='', endPage='', retry_count=3, pause=0.001): for _ in range(retry_count): time.sleep(pause) ct._write_console() try: tail = '&pageHelp.pageNo=%s&pageHelp.beginPage=%s&pageHelp.endPage=%s'%(pageNo, beginPage, endPage) if pageNo == '': pageNo = 6 tail = '' else: pageNo += 5 beginPage = pageNo endPage = pageNo + 4 ref = rv.MAR_SH_HZ_REF_URL%(ct.P_TYPE['http'], ct.DOMAINS['sse']) clt = Client(rv.MAR_SH_MX_URL%(ct.P_TYPE['http'], ct.DOMAINS['sseq'], ct.PAGES['qmd'], _random(5), date, symbol, start, end, tail, _random()), ref=ref, cookie=rv.MAR_SH_COOKIESTR) lines = clt.gvalue() lines = lines.decode('utf-8') if ct.PY3 else lines lines = lines[19:-1] lines = json.loads(lines) pagecount = int(lines['pageHelp'].get('pageCount')) datapage = int(pagecount/5+1 if pagecount%5>0 else pagecount/5) if pagecount == 0: return data if pageNo == 6: ct._write_tips(lines['pageHelp'].get('total')) df = pd.DataFrame(lines['result'], columns=rv.MAR_SH_MX_COLS) df['opDate'] = df['opDate'].map(lambda x: '%s-%s-%s'%(x[0:4], x[4:6], x[6:8])) data = data.append(df, ignore_index=True) if beginPage < datapage*5: data = _sh_mx(data, start=start, end=end, pageNo=pageNo, beginPage=beginPage, endPage=endPage, retry_count=retry_count, pause=pause) except Exception as e: print(e) else: return data raise IOError(ct.NETWORK_URL_ERROR_MSG) def sz_margins(start=None, end=None, retry_count=3, pause=0.001): """ 获取深市融资融券数据列表 Parameters -------- start:string 开始日期 format:YYYY-MM-DD 默认为上一周的今天 end:string 结束日期 format:YYYY-MM-DD 默认为今日 retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 Return ------ DataFrame opDate:信用交易日期(index) rzmre: 融资买入额(元) rzye:融资余额(元) rqmcl: 融券卖出量 rqyl: 融券余量 rqye: 融券余量(元) rzrqye:融资融券余额(元) """ data = pd.DataFrame() if start is None and end is None: end = du.today() start = du.day_last_week() if start is None or end is None: ct._write_msg(rv.MAR_SZ_HZ_MSG2) return None try: date_range = pd.date_range(start=start, end=end, freq='B') if len(date_range)>261: ct._write_msg(rv.MAR_SZ_HZ_MSG) else: ct._write_head() for date in date_range: data = data.append(_sz_hz(str(date.date()), retry_count, pause) ) except: ct._write_msg(ct.DATA_INPUT_ERROR_MSG) else: return data def _sz_hz(date='', retry_count=3, pause=0.001): for _ in range(retry_count): time.sleep(pause) ct._write_console() try: request = Request(rv.MAR_SZ_HZ_URL%(ct.P_TYPE['http'], ct.DOMAINS['szse'], ct.PAGES['szsefc'], date)) lines = urlopen(request, timeout = 10).read() if len(lines) <= 200: return pd.DataFrame() df = pd.read_html(lines, skiprows=[0])[0] df.columns = rv.MAR_SZ_HZ_COLS df['opDate'] = date except Exception as e: print(e) else: return df raise IOError(ct.NETWORK_URL_ERROR_MSG) def sz_margin_details(date='', retry_count=3, pause=0.001): """ 获取深市融资融券明细列表 Parameters -------- date:string 明细数据日期 format:YYYY-MM-DD 默认为空'' retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 Return ------ DataFrame opDate:信用交易日期 stockCode:标的证券代码 securityAbbr:标的证券简称 rzmre: 融资买入额(元) rzye:融资余额(元) rqmcl: 融券卖出量 rqyl: 融券余量 rqye: 融券余量(元) rzrqye:融资融券余额(元) """ for _ in range(retry_count): time.sleep(pause) try: request = Request(rv.MAR_SZ_MX_URL%(ct.P_TYPE['http'], ct.DOMAINS['szse'], ct.PAGES['szsefc'], date)) lines = urlopen(request, timeout = 10).read() if len(lines) <= 200: return pd.DataFrame() df = pd.read_html(lines, skiprows=[0])[0] df.columns = rv.MAR_SZ_MX_COLS df['stockCode'] = df['stockCode'].map(lambda x:str(x).zfill(6)) df['opDate'] = date except Exception as e: print(e) else: return df raise IOError(ct.NETWORK_URL_ERROR_MSG) def top10_holders(code=None, year=None, quarter=None, gdtype='0', retry_count=3, pause=0.001): if code is None: return None else: code = ct._code_to_symbol(code) gdtype = 'LT' if gdtype == '1' else '' qdate = '' if (year is not None) & (quarter is not None): qdate = du.get_q_date(year, quarter) for _ in range(retry_count): time.sleep(pause) try: request = Request(rv.TOP10_HOLDERS_URL%(ct.P_TYPE['http'], ct.DOMAINS['gw'], gdtype, code.upper())) lines = urlopen(request, timeout = 10).read() lines = lines.decode('utf8') if ct.PY3 else lines reg = re.compile(r'= \'\[(.*?)\]\';') lines = reg.findall(lines)[0] jss = json.loads('[%s]' %lines) summ = [] data = pd.DataFrame() for row in jss: qt = row['jzrq'] if 'jzrq' in row.keys() else None hold = row['ljcy'] if 'ljcy' in row.keys() else None change = row['ljbh'] if 'ljbh' in row.keys() else None props = row['ljzb'] if 'ljzb' in row.keys() else None arow = [qt, hold, change ,props] summ.append(arow) ls = row['sdgdList'] if 'sdgdList' in row.keys() else None dlist = [] for inrow in ls: sharetype = inrow['gbxz'] name = inrow['gdmc'] hold = inrow['cgs'] h_pro = inrow['zzgs'] status = inrow['zjqk'] dlist.append([qt, name, hold, h_pro, sharetype, status]) ddata = pd.DataFrame(dlist, columns=rv.TOP10_PER_COLS) data = data.append(ddata, ignore_index=True) df = pd.DataFrame(summ, columns=rv.TOP10_SUMM_COLS) if qdate != '': df = df[df.quarter == qdate] data = data[data.quarter == qdate] except Exception as e: print(e) else: return df, data raise IOError(ct.NETWORK_URL_ERROR_MSG) def moneyflow_hsgt(): """ 获取沪深港通资金流向 return: DataFrame,单位: 百万元 -------------- date: 交易日期 ggt_ss: 港股通(沪) ggt_sz: 港股通(深) hgt: 沪港通 sgt: 深港通 north_money: 北向资金流入 south_money: 南向资金流入 """ clt = Client(rv.HSGT_DATA%(ct.P_TYPE['http'], ct.DOMAINS['em']), ref=rv.HSGT_REF%(ct.P_TYPE['http'], ct.DOMAINS['em'], ct.PAGES['index'])) content = clt.gvalue() content = content.decode('utf-8') if ct.PY3 else content js = json.loads(content) df = pd.DataFrame(js) df['DateTime'] = df['DateTime'].map(lambda x: x[0:10]) df = df.replace('-', np.NaN) df = df[rv.HSGT_TEMP] df.columns = rv.HSGT_COLS df = df.sort_values('date', ascending=False) return df def margin_detail(date=''): """ 沪深融券融券明细 Parameters --------------- date:string 日期 format:YYYY-MM-DD 或者 YYYYMMDD return DataFrame -------------- code: 证券代码 name: 证券名称 buy: 今日买入额 buy_total:融资余额 sell: 今日卖出量(股) sell_total: 融券余量(股) sell_amount: 融券余额 total: 融资融券余额(元) buy_repay: 本日融资偿还额(元) sell_repay: 本日融券偿还量 """ date = str(date).replace('-', '') df = pd.read_csv(ct.MG_URL%(ct.P_TYPE['http'], ct.DOMAINS['oss'], date[0:6], 'mx', date), dtype={'code': object}) return df def margin_target(date=''): """ 沪深融券融券标的 Parameters --------------- date:string 日期 format:YYYY-MM-DD 或者 YYYYMMDD return DataFrame -------------- code: 证券代码 name: 证券名称 long: 融资标的 short: 融券标的 """ date = str(date).replace('-', '') df = pd.read_csv(ct.MG_URL%(ct.P_TYPE['http'], ct.DOMAINS['oss'], date[0:6], 'bd', date), dtype={'code': object}) return df def margin_offset(date): """ 融资融券可充抵保证金证券 Parameters --------------- date:string 日期 format:YYYY-MM-DD 或者 YYYYMMDD return DataFrame -------------- code: 证券代码 name: 证券名称 """ date = str(date).replace('-', '') df = pd.read_csv(ct.MG_URL%(ct.P_TYPE['http'], ct.DOMAINS['oss'], date[0:6], 'cd', date), dtype={'code': object}) return df def stock_pledged(): """ 股票质押数据 return DataFrame -------------- code: 证券代码 name: 证券名称 deals: 质押次数 unrest_pledged: 无限售股质押数量(万) rest_pledged: 限售股质押数量(万) totals: 总股本 p_ratio:质押比例(%) """ df = pd.read_csv(ct.GPZY_URL%(ct.P_TYPE['http'], ct.DOMAINS['oss'], 'gpzy'), dtype={'code': object}) return df def pledged_detail(): """ 股票质押数据 return DataFrame -------------- code: 证券代码 name: 证券名称 ann_date: 公告日期 pledgor:出质人 pledgee:质权人 volume:质押数量 from_date:质押日期 end_date: 解除日期 """ df = pd.read_csv(ct.GPZY_D_URL%(ct.P_TYPE['http'], ct.DOMAINS['oss'], 'gpzy_detail'), dtype={'code': object, 'ann_date': object, 'end_date': object}) df['code'] = df['code'].map(lambda x : str(x).zfill(6)) df['end_date'] = np.where(df['end_date'] == '--', np.NaN, df['end_date']) return df def margin_zsl(date='', broker=''): """ 融资融券充抵保证金折算率 Parameters --------------- date:string 日期 format:YYYY-MM-DD 或者 YYYYMMDD broker: gtja:国泰君安 yhzq:银河证券 gfzq:广发证券 zszq:招商证券 gxzq:国信证券 swhy:申万宏源 zxjt:中信建投 zxzq:中信证券 return DataFrame -------------- code: 证券代码 name: 证券名称 ratio:比率 broker:券商代码 """ date = str(date).replace('-', '') df = pd.read_csv(ct.MG_ZSL_URL%(ct.P_TYPE['http'], ct.DOMAINS['oss'], date[0:6], broker, date), dtype={'code': object}) return df def stock_issuance(start_date='', end_date=''): """ 股票增发 Parameters --------------- start_date:string end_date:string 日期 format:YYYY-MM-DD return DataFrame -------------- code: 证券代码 name: 证券名称 type:类型,定向增发/公开增发 count:数量 price:增发价格 close:最近收盘价 issue_date:增发日期 list_date:上市日期 locked_year:锁定年数 prem:截止当前溢价(%) """ df = pd.read_csv(ct.ZF%(ct.P_TYPE['http'], ct.DOMAINS['oss'], 'zf'), dtype={'code': object}) if start_date != '' and start_date is not None: df = df[df.issue_date >= start_date] if end_date != '' and end_date is not None: df = df[df.issue_date <= start_date] df['prem'] = (df['close'] - df['price']) / df['price'] * 100 df['prem'] = df['prem'].map(ct.FORMAT) df['prem'] = df['prem'].astype(float) return df def _random(n=13): from random import randint start = 10**(n-1) end = (10**n)-1 return str(randint(start, end)) ================================================ FILE: tushare/stock/shibor.py ================================================ # -*- coding:utf-8 -*- """ 上海银行间同业拆放利率(Shibor)数据接口 Created on 2014/07/31 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ import pandas as pd import numpy as np from tushare.stock import cons as ct from tushare.util import dateu as du from tushare.util.netbase import Client from pandas.compat import StringIO def shibor_data(year=None): """ 获取上海银行间同业拆放利率(Shibor) Parameters ------ year:年份(int) Return ------ date:日期 ON:隔夜拆放利率 1W:1周拆放利率 2W:2周拆放利率 1M:1个月拆放利率 3M:3个月拆放利率 6M:6个月拆放利率 9M:9个月拆放利率 1Y:1年拆放利率 """ year = du.get_year() if year is None else year lab = ct.SHIBOR_TYPE['Shibor'] lab = lab.encode('utf-8') if ct.PY3 else lab try: clt = Client(url=ct.SHIBOR_DATA_URL%(ct.P_TYPE['http'], ct.DOMAINS['shibor'], ct.PAGES['dw'], 'Shibor', year, lab, year)) content = clt.gvalue() df = pd.read_excel(StringIO(content)) df.columns = ct.SHIBOR_COLS df['date'] = df['date'].map(lambda x: x.date()) if pd.__version__ < '0.21': df['date'] = df['date'].astype(np.datetime64) else: df['date'] = df['date'].astype('datetime64[D]') return df except: return None def shibor_quote_data(year=None): """ 获取Shibor银行报价数据 Parameters ------ year:年份(int) Return ------ date:日期 bank:报价银行名称 ON:隔夜拆放利率 ON_B:隔夜拆放买入价 ON_A:隔夜拆放卖出价 1W_B:1周买入 1W_A:1周卖出 2W_B:买入 2W_A:卖出 1M_B:买入 1M_A:卖出 3M_B:买入 3M_A:卖出 6M_B:买入 6M_A:卖出 9M_B:买入 9M_A:卖出 1Y_B:买入 1Y_A:卖出 """ year = du.get_year() if year is None else year lab = ct.SHIBOR_TYPE['Quote'] lab = lab.encode('utf-8') if ct.PY3 else lab try: clt = Client(url=ct.SHIBOR_DATA_URL%(ct.P_TYPE['http'], ct.DOMAINS['shibor'], ct.PAGES['dw'], 'Quote', year, lab, year)) content = clt.gvalue() df = pd.read_excel(StringIO(content), skiprows=[0]) # df.columns = ct.QUOTE_COLS df.columns = ct.SHIBOR_Q_COLS df['date'] = df['date'].map(lambda x: x.date()) if pd.__version__ < '0.21': df['date'] = df['date'].astype(np.datetime64) else: df['date'] = df['date'].astype('datetime64[D]') return df except: return None def shibor_ma_data(year=None): """ 获取Shibor均值数据 Parameters ------ year:年份(int) Return ------ date:日期 其它分别为各周期5、10、20均价 """ year = du.get_year() if year is None else year lab = ct.SHIBOR_TYPE['Tendency'] lab = lab.encode('utf-8') if ct.PY3 else lab try: clt = Client(url=ct.SHIBOR_DATA_URL%(ct.P_TYPE['http'], ct.DOMAINS['shibor'], ct.PAGES['dw'], 'Shibor_Tendency', year, lab, year)) content = clt.gvalue() df = pd.read_excel(StringIO(content), skiprows=[0]) df.columns = ct.SHIBOR_MA_COLS df['date'] = df['date'].map(lambda x: x.date()) if pd.__version__ < '0.21': df['date'] = df['date'].astype(np.datetime64) else: df['date'] = df['date'].astype('datetime64[D]') return df except: return None def lpr_data(year=None): """ 获取贷款基础利率(LPR) Parameters ------ year:年份(int) Return ------ date:日期 1Y:1年贷款基础利率 """ year = du.get_year() if year is None else year lab = ct.SHIBOR_TYPE['LPR'] lab = lab.encode('utf-8') if ct.PY3 else lab try: clt = Client(url=ct.SHIBOR_DATA_URL%(ct.P_TYPE['http'], ct.DOMAINS['shibor'], ct.PAGES['dw'], 'LPR', year, lab, year)) content = clt.gvalue() df = pd.read_excel(StringIO(content), skiprows=[0]) df.columns = ct.LPR_COLS df['date'] = df['date'].map(lambda x: x.date()) if pd.__version__ < '0.21': df['date'] = df['date'].astype(np.datetime64) else: df['date'] = df['date'].astype('datetime64[D]') return df except: return None def lpr_ma_data(year=None): """ 获取贷款基础利率均值数据 Parameters ------ year:年份(int) Return ------ date:日期 1Y_5:5日均值 1Y_10:10日均值 1Y_20:20日均值 """ year = du.get_year() if year is None else year lab = ct.SHIBOR_TYPE['LPR_Tendency'] lab = lab.encode('utf-8') if ct.PY3 else lab try: clt = Client(url=ct.SHIBOR_DATA_URL%(ct.P_TYPE['http'], ct.DOMAINS['shibor'], ct.PAGES['dw'], 'LPR_Tendency', year, lab, year)) content = clt.gvalue() df = pd.read_excel(StringIO(content), skiprows=[0]) df.columns = ct.LPR_MA_COLS df['date'] = df['date'].map(lambda x: x.date()) if pd.__version__ < '0.21': df['date'] = df['date'].astype(np.datetime64) else: df['date'] = df['date'].astype('datetime64[D]') return df except: return None ================================================ FILE: tushare/stock/trading.py ================================================ # -*- coding:utf-8 -*- """ 交易数据接口 Created on 2014/07/31 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ from __future__ import division import time import json import lxml.html from lxml import etree import pandas as pd import numpy as np import datetime from tushare.stock import cons as ct import re from pandas.compat import StringIO from tushare.util import dateu as du from tushare.util.formula import MA import os from tushare.util.conns import get_apis, close_apis from tushare.stock.fundamental import get_stock_basics try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request def get_hist_data(code=None, start=None, end=None, ktype='D', retry_count=3, pause=0.001): """ 获取个股历史交易记录 Parameters ------ code:string 股票代码 e.g. 600848 start:string 开始日期 format:YYYY-MM-DD 为空时取到API所提供的最早日期数据 end:string 结束日期 format:YYYY-MM-DD 为空时取到最近一个交易日数据 ktype:string 数据类型,D=日k线 W=周 M=月 5=5分钟 15=15分钟 30=30分钟 60=60分钟,默认为D retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 return ------- DataFrame 属性:日期 ,开盘价, 最高价, 收盘价, 最低价, 成交量, 价格变动 ,涨跌幅,5日均价,10日均价,20日均价,5日均量,10日均量,20日均量,换手率 """ symbol = ct._code_to_symbol(code) url = '' if ktype.upper() in ct.K_LABELS: url = ct.DAY_PRICE_URL%(ct.P_TYPE['http'], ct.DOMAINS['ifeng'], ct.K_TYPE[ktype.upper()], symbol) elif ktype in ct.K_MIN_LABELS: url = ct.DAY_PRICE_MIN_URL%(ct.P_TYPE['http'], ct.DOMAINS['ifeng'], symbol, ktype) else: raise TypeError('ktype input error.') for _ in range(retry_count): time.sleep(pause) try: request = Request(url) lines = urlopen(request, timeout = 10).read() if len(lines) < 15: #no data return None except Exception as e: print(e) else: js = json.loads(lines.decode('utf-8') if ct.PY3 else lines) cols = [] if (code in ct.INDEX_LABELS) & (ktype.upper() in ct.K_LABELS): cols = ct.INX_DAY_PRICE_COLUMNS else: cols = ct.DAY_PRICE_COLUMNS if len(js['record'][0]) == 14: cols = ct.INX_DAY_PRICE_COLUMNS df = pd.DataFrame(js['record'], columns=cols) if ktype.upper() in ['D', 'W', 'M']: df = df.applymap(lambda x: x.replace(u',', u'')) df[df==''] = 0 for col in cols[1:]: df[col] = df[col].astype(float) if start is not None: df = df[df.date >= start] if end is not None: df = df[df.date <= end] if (code in ct.INDEX_LABELS) & (ktype in ct.K_MIN_LABELS): df = df.drop('turnover', axis=1) df = df.set_index('date') df = df.sort_index(ascending = False) return df raise IOError(ct.NETWORK_URL_ERROR_MSG) def _parsing_dayprice_json(types=None, page=1): """ 处理当日行情分页数据,格式为json Parameters ------ pageNum:页码 return ------- DataFrame 当日所有股票交易数据(DataFrame) """ ct._write_console() request = Request(ct.SINA_DAY_PRICE_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['jv'], types, page)) text = urlopen(request, timeout=10).read() if text == 'null': return None reg = re.compile(r'\,(.*?)\:') text = reg.sub(r',"\1":', text.decode('gbk') if ct.PY3 else text) text = text.replace('"{symbol', '{"symbol') text = text.replace('{symbol', '{"symbol"') if ct.PY3: jstr = json.dumps(text) else: jstr = json.dumps(text, encoding='GBK') js = json.loads(jstr) df = pd.DataFrame(pd.read_json(js, dtype={'code':object}), columns=ct.DAY_TRADING_COLUMNS) df = df.drop('symbol', axis=1) # df = df.ix[df.volume > 0] return df def get_tick_data(code=None, date=None, retry_count=3, pause=0.001, src='sn'): """ 获取分笔数据 Parameters ------ code:string 股票代码 e.g. 600848 date:string 日期 format: YYYY-MM-DD retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 src : 数据源选择,可输入sn(新浪)、tt(腾讯)、nt(网易),默认sn return ------- DataFrame 当日所有股票交易数据(DataFrame) 属性:成交时间、成交价格、价格变动,成交手、成交金额(元),买卖类型 """ if (src.strip() not in ct.TICK_SRCS): print(ct.TICK_SRC_ERROR) return None symbol = ct._code_to_symbol(code) symbol_dgt = ct._code_to_symbol_dgt(code) datestr = date.replace('-', '') url = { ct.TICK_SRCS[0] : ct.TICK_PRICE_URL % (ct.P_TYPE['http'], ct.DOMAINS['sf'], ct.PAGES['dl'], date, symbol), ct.TICK_SRCS[1] : ct.TICK_PRICE_URL_TT % (ct.P_TYPE['http'], ct.DOMAINS['tt'], ct.PAGES['idx'], symbol, datestr), ct.TICK_SRCS[2] : ct.TICK_PRICE_URL_NT % (ct.P_TYPE['http'], ct.DOMAINS['163'], date[0:4], datestr, symbol_dgt) } for _ in range(retry_count): time.sleep(pause) try: if src == ct.TICK_SRCS[2]: df = pd.read_excel(url[src]) df.columns = ct.TICK_COLUMNS else: re = Request(url[src]) lines = urlopen(re, timeout=10).read() lines = lines.decode('GBK') if len(lines) < 20: return None df = pd.read_table(StringIO(lines), names=ct.TICK_COLUMNS, skiprows=[0]) except Exception as e: print(e) else: return df raise IOError(ct.NETWORK_URL_ERROR_MSG) def get_sina_dd(code=None, date=None, vol=400, retry_count=3, pause=0.001): """ 获取sina大单数据 Parameters ------ code:string 股票代码 e.g. 600848 date:string 日期 format:YYYY-MM-DD retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 return ------- DataFrame 当日所有股票交易数据(DataFrame) 属性:股票代码 股票名称 交易时间 价格 成交量 前一笔价格 类型(买、卖、中性盘) """ if code is None or len(code)!=6 or date is None: return None symbol = ct._code_to_symbol(code) vol = vol*100 for _ in range(retry_count): time.sleep(pause) try: re = Request(ct.SINA_DD % (ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['sinadd'], symbol, vol, date)) lines = urlopen(re, timeout=10).read() lines = lines.decode('GBK') if len(lines) < 100: return None df = pd.read_csv(StringIO(lines), names=ct.SINA_DD_COLS, skiprows=[0]) if df is not None: df['code'] = df['code'].map(lambda x: x[2:]) except Exception as e: print(e) else: return df raise IOError(ct.NETWORK_URL_ERROR_MSG) def get_today_ticks(code=None, retry_count=3, pause=0.001): """ 获取当日分笔明细数据 Parameters ------ code:string 股票代码 e.g. 600848 retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 return ------- DataFrame 当日所有股票交易数据(DataFrame) 属性:成交时间、成交价格、价格变动,成交手、成交金额(元),买卖类型 """ if code is None or len(code)!=6 : return None symbol = ct._code_to_symbol(code) date = du.today() for _ in range(retry_count): time.sleep(pause) try: request = Request(ct.TODAY_TICKS_PAGE_URL % (ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['jv'], date, symbol)) data_str = urlopen(request, timeout=10).read() data_str = data_str.decode('GBK') data_str = data_str[1:-1] data_str = eval(data_str, type('Dummy', (dict,), dict(__getitem__ = lambda s, n:n))()) data_str = json.dumps(data_str) data_str = json.loads(data_str) pages = len(data_str['detailPages']) data = pd.DataFrame() ct._write_head() for pNo in range(1, pages+1): data = data.append(_today_ticks(symbol, date, pNo, retry_count, pause), ignore_index=True) except Exception as er: print(str(er)) else: return data raise IOError(ct.NETWORK_URL_ERROR_MSG) def _today_ticks(symbol, tdate, pageNo, retry_count, pause): ct._write_console() for _ in range(retry_count): time.sleep(pause) try: html = lxml.html.parse(ct.TODAY_TICKS_URL % (ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['t_ticks'], symbol, tdate, pageNo )) res = html.xpath('//table[@id=\"datatbl\"]/tbody/tr') if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) sarr = '%s
'%sarr sarr = sarr.replace('--', '0') df = pd.read_html(StringIO(sarr), parse_dates=False)[0] df.columns = ct.TODAY_TICK_COLUMNS df['pchange'] = df['pchange'].map(lambda x : x.replace('%', '')) except Exception as e: print(e) else: return df raise IOError(ct.NETWORK_URL_ERROR_MSG) def get_today_all(): """ 一次性获取最近一个日交易日所有股票的交易数据 return ------- DataFrame 属性:代码,名称,涨跌幅,现价,开盘价,最高价,最低价,最日收盘价,成交量,换手率,成交额,市盈率,市净率,总市值,流通市值 """ ct._write_head() df = _parsing_dayprice_json('hs_a', 1) if df is not None: for i in range(2, ct.PAGE_NUM[1]): newdf = _parsing_dayprice_json('hs_a', i) df = df.append(newdf, ignore_index=True) df = df.append(_parsing_dayprice_json('shfxjs', 1), ignore_index=True) return df def get_realtime_quotes(symbols=None): """ 获取实时交易数据 getting real time quotes data 用于跟踪交易情况(本次执行的结果-上一次执行的数据) Parameters ------ symbols : string, array-like object (list, tuple, Series). return ------- DataFrame 实时交易数据 属性:0:name,股票名字 1:open,今日开盘价 2:pre_close,昨日收盘价 3:price,当前价格 4:high,今日最高价 5:low,今日最低价 6:bid,竞买价,即“买一”报价 7:ask,竞卖价,即“卖一”报价 8:volumn,成交量 maybe you need do volumn/100 9:amount,成交金额(元 CNY) 10:b1_v,委买一(笔数 bid volume) 11:b1_p,委买一(价格 bid price) 12:b2_v,“买二” 13:b2_p,“买二” 14:b3_v,“买三” 15:b3_p,“买三” 16:b4_v,“买四” 17:b4_p,“买四” 18:b5_v,“买五” 19:b5_p,“买五” 20:a1_v,委卖一(笔数 ask volume) 21:a1_p,委卖一(价格 ask price) ... 30:date,日期; 31:time,时间; """ symbols_list = '' if isinstance(symbols, list) or isinstance(symbols, set) or isinstance(symbols, tuple) or isinstance(symbols, pd.Series): for code in symbols: symbols_list += ct._code_to_symbol(code) + ',' else: symbols_list = ct._code_to_symbol(symbols) symbols_list = symbols_list[:-1] if len(symbols_list) > 8 else symbols_list request = Request(ct.LIVE_DATA_URL%(ct.P_TYPE['http'], ct.DOMAINS['sinahq'], _random(), symbols_list)) text = urlopen(request,timeout=10).read() text = text.decode('GBK') reg = re.compile(r'\="(.*?)\";') data = reg.findall(text) regSym = re.compile(r'(?:sh|sz|gb_)(.*?)\=') syms = regSym.findall(text) data_list = [] syms_list = [] for index, row in enumerate(data): if len(row)>1: data_list.append([astr for astr in row.split(',')]) syms_list.append(syms[index]) if len(syms_list) == 0: return None if len(data_list[0]) == 28: df = pd.DataFrame(data_list, columns=ct.US_LIVE_DATA_COLS) else: df = pd.DataFrame(data_list, columns=ct.LIVE_DATA_COLS) df = df.drop('s', axis=1) df['code'] = syms_list ls = [cls for cls in df.columns if '_v' in cls] for txt in ls: df[txt] = df[txt].map(lambda x : x[:-2]) return df def get_h_data(code, start=None, end=None, autype='qfq', index=False, retry_count=3, pause=0.001, drop_factor=True): ''' 获取历史复权数据 Parameters ------ code:string 股票代码 e.g. 600848 start:string 开始日期 format:YYYY-MM-DD 为空时取当前日期 end:string 结束日期 format:YYYY-MM-DD 为空时取去年今日 autype:string 复权类型,qfq-前复权 hfq-后复权 None-不复权,默认为qfq retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 drop_factor : bool, 默认 True 是否移除复权因子,在分析过程中可能复权因子意义不大,但是如需要先储存到数据库之后再分析的话,有该项目会更加灵活 return ------- DataFrame date 交易日期 (index) open 开盘价 high 最高价 close 收盘价 low 最低价 volume 成交量 amount 成交金额 ''' start = du.today_last_year() if start is None else start end = du.today() if end is None else end qs = du.get_quarts(start, end) qt = qs[0] ct._write_head() data = _parse_fq_data(_get_index_url(index, code, qt), index, retry_count, pause) if data is None: data = pd.DataFrame() if len(qs)>1: for d in range(1, len(qs)): qt = qs[d] ct._write_console() df = _parse_fq_data(_get_index_url(index, code, qt), index, retry_count, pause) if df is None: # 可能df为空,退出循环 break else: data = data.append(df, ignore_index = True) if len(data) == 0 or len(data[(data.date >= start) & (data.date <= end)]) == 0: return pd.DataFrame() data = data.drop_duplicates('date') if index: data = data[(data.date >= start) & (data.date <= end)] data = data.set_index('date') data = data.sort_index(ascending = False) return data if autype == 'hfq': if drop_factor: data = data.drop('factor', axis=1) data = data[(data.date >= start) & (data.date <= end)] for label in ['open', 'high', 'close', 'low']: data[label] = data[label].map(ct.FORMAT) data[label] = data[label].astype(float) data = data.set_index('date') data = data.sort_index(ascending = False) return data else: if autype == 'qfq': if drop_factor: data = data.drop('factor', axis = 1) df = _parase_fq_factor(code, start, end) df = df.drop_duplicates('date') df = df.sort_values('date', ascending = False) firstDate = data.head(1)['date'] frow = df[df.date == firstDate[0]] rt = get_realtime_quotes(code) if rt is None: return pd.DataFrame() if ((float(rt['high']) == 0) & (float(rt['low']) == 0)): preClose = float(rt['pre_close']) else: if du.is_holiday(du.today()): preClose = float(rt['price']) else: if (du.get_hour() > 9) & (du.get_hour() < 18): preClose = float(rt['pre_close']) else: preClose = float(rt['price']) rate = float(frow['factor']) / preClose data = data[(data.date >= start) & (data.date <= end)] for label in ['open', 'high', 'low', 'close']: data[label] = data[label] / rate data[label] = data[label].map(ct.FORMAT) data[label] = data[label].astype(float) data = data.set_index('date') data = data.sort_index(ascending = False) return data else: for label in ['open', 'high', 'close', 'low']: data[label] = data[label] / data['factor'] if drop_factor: data = data.drop('factor', axis=1) data = data[(data.date >= start) & (data.date <= end)] for label in ['open', 'high', 'close', 'low']: data[label] = data[label].map(ct.FORMAT) data = data.set_index('date') data = data.sort_index(ascending = False) data = data.astype(float) return data def _parase_fq_factor(code, start, end): symbol = ct._code_to_symbol(code) request = Request(ct.HIST_FQ_FACTOR_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], symbol)) text = urlopen(request, timeout=10).read() text = text[1:len(text)-1] text = text.decode('utf-8') if ct.PY3 else text text = text.replace('{_', '{"') text = text.replace('total', '"total"') text = text.replace('data', '"data"') text = text.replace(':"', '":"') text = text.replace('",_', '","') text = text.replace('_', '-') text = json.loads(text) df = pd.DataFrame({'date':list(text['data'].keys()), 'factor':list(text['data'].values())}) df['date'] = df['date'].map(_fun_except) # for null case if df['date'].dtypes == np.object: df['date'] = pd.to_datetime(df['date']) df = df.drop_duplicates('date') df['factor'] = df['factor'].astype(float) return df def _fun_except(x): if len(x) > 10: return x[-10:] else: return x def _parse_fq_data(url, index, retry_count, pause): for _ in range(retry_count): time.sleep(pause) try: request = Request(url) text = urlopen(request, timeout=10).read() text = text.decode('GBK') html = lxml.html.parse(StringIO(text)) res = html.xpath('//table[@id=\"FundHoldSharesTable\"]') if ct.PY3: sarr = [etree.tostring(node).decode('utf-8') for node in res] else: sarr = [etree.tostring(node) for node in res] sarr = ''.join(sarr) if sarr == '': return None df = pd.read_html(sarr, skiprows = [0, 1])[0] if len(df) == 0: return pd.DataFrame() if index: df.columns = ct.HIST_FQ_COLS[0:7] else: df.columns = ct.HIST_FQ_COLS if df['date'].dtypes == np.object: df['date'] = pd.to_datetime(df['date']) df = df.drop_duplicates('date') except ValueError as e: # 时间较早,已经读不到数据 return None except Exception as e: print(e) else: return df raise IOError(ct.NETWORK_URL_ERROR_MSG) def get_index(): """ 获取大盘指数行情 return ------- DataFrame code:指数代码 name:指数名称 change:涨跌幅 open:开盘价 preclose:昨日收盘价 close:收盘价 high:最高价 low:最低价 volume:成交量(手) amount:成交金额(亿元) """ request = Request(ct.INDEX_HQ_URL%(ct.P_TYPE['http'], ct.DOMAINS['sinahq'])) text = urlopen(request, timeout=10).read() text = text.decode('GBK') text = text.replace('var hq_str_sh', '').replace('var hq_str_sz', '') text = text.replace('";', '').replace('"', '').replace('=', ',') text = '%s%s'%(ct.INDEX_HEADER, text) df = pd.read_csv(StringIO(text), sep=',', thousands=',') df['change'] = (df['close'] / df['preclose'] - 1 ) * 100 df['amount'] = df['amount'] / 100000000 df['change'] = df['change'].map(ct.FORMAT) df['amount'] = df['amount'].map(ct.FORMAT4) df = df[ct.INDEX_COLS] df['code'] = df['code'].map(lambda x:str(x).zfill(6)) df['change'] = df['change'].astype(float) df['amount'] = df['amount'].astype(float) return df def _get_index_url(index, code, qt): if index: url = ct.HIST_INDEX_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], code, qt[0], qt[1]) else: url = ct.HIST_FQ_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], code, qt[0], qt[1]) return url def get_k_data(code=None, start='', end='', ktype='D', autype='qfq', index=False, retry_count=3, pause=0.001): """ 获取k线数据 --------- Parameters: code:string 股票代码 e.g. 600848 start:string 开始日期 format:YYYY-MM-DD 为空时取上市首日 end:string 结束日期 format:YYYY-MM-DD 为空时取最近一个交易日 autype:string 复权类型,qfq-前复权 hfq-后复权 None-不复权,默认为qfq ktype:string 数据类型,D=日k线 W=周 M=月 5=5分钟 15=15分钟 30=30分钟 60=60分钟,默认为D retry_count : int, 默认 3 如遇网络等问题重复执行的次数 pause : int, 默认 0 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题 return ------- DataFrame date 交易日期 (index) open 开盘价 high 最高价 close 收盘价 low 最低价 volume 成交量 amount 成交额 turnoverratio 换手率 code 股票代码 """ symbol = ct.INDEX_SYMBOL[code] if index else ct._code_to_symbol(code) url = '' dataflag = '' autype = '' if autype is None else autype if (start is not None) & (start != ''): end = du.today() if end is None or end == '' else end if ktype.upper() in ct.K_LABELS: fq = autype if autype is not None else '' if code[:1] in ('1', '5') or index: fq = '' kline = '' if autype is None else 'fq' if (start is None or start == '') & (end is None or end == ''): urls = [ct.KLINE_TT_URL%(ct.P_TYPE['http'], ct.DOMAINS['tt'], kline, fq, symbol, ct.TT_K_TYPE[ktype.upper()], start, end, fq, _random(17))] else: years = du.tt_dates(start, end) urls = [] for year in years: startdate = str(year) + '-01-01' enddate = str(year+1) + '-12-31' url = ct.KLINE_TT_URL%(ct.P_TYPE['http'], ct.DOMAINS['tt'], kline, fq+str(year), symbol, ct.TT_K_TYPE[ktype.upper()], startdate, enddate, fq, _random(17)) urls.append(url) dataflag = '%s%s'%(fq, ct.TT_K_TYPE[ktype.upper()]) elif ktype in ct.K_MIN_LABELS: urls = [ct.KLINE_TT_MIN_URL%(ct.P_TYPE['http'], ct.DOMAINS['tt'], symbol, ktype, ktype, _random(16))] dataflag = 'm%s'%ktype else: raise TypeError('ktype input error.') data = pd.DataFrame() for url in urls: data = data.append(_get_k_data(url, dataflag, symbol, code, index, ktype, retry_count, pause), ignore_index=True) if ktype not in ct.K_MIN_LABELS: if ((start is not None) & (start != '')) & ((end is not None) & (end != '')): if data.empty==False: data = data[(data.date >= start) & (data.date <= end)] return data raise IOError(ct.NETWORK_URL_ERROR_MSG) def _get_k_data(url, dataflag='', symbol='', code = '', index = False, ktype = '', retry_count=3, pause=0.001): for _ in range(retry_count): time.sleep(pause) try: request = Request(url) lines = urlopen(request, timeout = 10).read() if len(lines) < 100: #no data return None except Exception as e: print(e) else: lines = lines.decode('utf-8') if ct.PY3 else lines lines = lines.split('=')[1] reg = re.compile(r',{"nd.*?}') lines = re.subn(reg, '', lines) js = json.loads(lines[0]) dataflag = dataflag if dataflag in list(js['data'][symbol].keys()) else ct.TT_K_TYPE[ktype.upper()] if len(js['data'][symbol][dataflag]) == 0: return None if len(js['data'][symbol][dataflag][0]) == 6: df = pd.DataFrame(js['data'][symbol][dataflag], columns = ct.KLINE_TT_COLS_MINS) else: df = pd.DataFrame(js['data'][symbol][dataflag], columns = ct.KLINE_TT_COLS) df['code'] = symbol if index else code if ktype in ct.K_MIN_LABELS: df['date'] = df['date'].map(lambda x: '%s-%s-%s %s:%s'%(x[0:4], x[4:6], x[6:8], x[8:10], x[10:12])) for col in df.columns[1:6]: df[col] = df[col].astype(float) return df def get_hists(symbols, start=None, end=None, ktype='D', retry_count=3, pause=0.001): """ 批量获取历史行情数据,具体参数和返回数据类型请参考get_hist_data接口 """ df = pd.DataFrame() if isinstance(symbols, list) or isinstance(symbols, set) or isinstance(symbols, tuple) or isinstance(symbols, pd.Series): for symbol in symbols: data = get_hist_data(symbol, start=start, end=end, ktype=ktype, retry_count=retry_count, pause=pause) data['code'] = symbol df = df.append(data, ignore_index=True) return df else: return None def get_day_all(date=None): """ 获取每日收盘行情 Parameters: ------------- date:交易日期,格式:YYYY-MM-DD Return: ------------- DataFrame code 代码, name 名称, p_change 涨幅%, price 现价, change 涨跌, open 今开, high 最高, low 最低, preprice 昨收, pe 市盈(动), volratio 量比, turnover 换手%, range 振幅%%, volume 总量, selling 内盘, buying 外盘, amount 总金额, totals 总股本(万), industry 细分行业, area 地区, floats 流通股本(万), fvalues 流通市值, abvalues AB股总市值, avgprice 均价, strength 强弱度%, activity 活跃度, avgturnover 笔换手, attack 攻击波%, interval3 近3月涨幅 ,interval 近6月涨幅 """ wdate = du.last_tddate() if date is None else date wdate = wdate.replace('-', '') if wdate < '20170614': return None datepre = '' if date is None else wdate[0:4] + wdate[4:6] + '/' df = pd.read_csv(ct.ALL_DAY_FILE%(datepre, \ 'hq' if date is None else wdate), \ dtype={'code':'object'}) return df def get_dt_time(t): tstr = str(t)[:-2] tstr = tstr.replace('-', '').replace(':', '') return tstr def bar2h5(market='', date='', freq='D', asset='E', filepath=''): cons = get_apis() stks = get_stock_basics() fname = "%s%s%sbar%s.h5"%(filepath, market, date, freq) store = pd.HDFStore(fname, "a") if market in ['SH', 'SZ']: if market == 'SH': stks = stks.ix[stks.index.str[0]=='6', :] elif market == 'SZ': stks = stks.ix[stks.index.str[0]!='6', :] else: stks = '' market = 1 if market == 'SH' else 0 for stk in stks.index: symbol = '%s.SH'%stk if 'min' in freq: df = bar(stk, conn=cons, start_date=date, end_date=date, freq=freq, market=market, asset=asset) df['Time'] = df.index df['Time'] = df['Time'].apply(get_dt_time) df.index = df['Time'] df.drop(['code','Time'], axis = 1, inplace=True) df.rename(columns={'open':'OPEN'}, inplace=True) df.rename(columns={'close':'CLOSE'}, inplace=True) df.rename(columns={'low':'LOW'}, inplace=True) df.rename(columns={'high':'HIGH'}, inplace=True) df.rename(columns={'vol':'VOLUME'}, inplace=True) df.rename(columns={'amount':'TURNOVER'}, inplace=True) df.loc[:,'HIGH'] = df.loc[:,'HIGH'].astype("int64") df.loc[:,'LOW'] = df.loc[:,'LOW'].astype("int64") df.loc[:,'OPEN'] = df.loc[:,'OPEN'].astype("int64") df.loc[:,'CLOSE'] = df.loc[:,'CLOSE'].astype("int64") df.loc[:,'VOLUME'] = df.loc[:,'VOLUME'].astype("int64") df.loc[:,'TURNOVER'] = df.loc[:,'TURNOVER'].astype("int64") df.loc[:,'OPEN'] *= 10000 df.loc[:,'CLOSE'] *= 10000 df.loc[:,'HIGH'] *= 10000 df.loc[:,'LOW'] *= 10000 df.loc[:,'ASKPRICE1'] = 0 df.loc[:,'ASKPRICE2'] = 0 df.loc[:,'ASKPRICE3'] = 0 df.loc[:,'ASKPRICE4'] = 0 df.loc[:,'ASKPRICE5'] = 0 df.loc[:,'ASKPRICE6'] = 0 df.loc[:,'ASKPRICE7'] = 0 df.loc[:,'ASKPRICE8'] = 0 df.loc[:,'ASKPRICE9'] = 0 df.loc[:,'ASKPRICE10'] = 0 df.loc[:,'BIDPRICE1'] = 0 df.loc[:,'BIDPRICE2'] = 0 df.loc[:,'BIDPRICE3'] = 0 df.loc[:,'BIDPRICE4'] = 0 df.loc[:,'BIDPRICE5'] = 0 df.loc[:,'BIDPRICE6'] = 0 df.loc[:,'BIDPRICE7'] = 0 df.loc[:,'BIDPRICE8'] = 0 df.loc[:,'BIDPRICE9'] = 0 df.loc[:,'BIDPRICE10'] = 0 df.loc[:,'ASKVOL1'] = 0 df.loc[:,'ASKVOL2'] = 0 df.loc[:,'ASKVOL3'] = 0 df.loc[:,'ASKVOL4'] = 0 df.loc[:,'ASKVOL5'] = 0 df.loc[:,'ASKVOL6'] = 0 df.loc[:,'ASKVOL7'] = 0 df.loc[:,'ASKVOL8'] = 0 df.loc[:,'ASKVOL9'] = 0 df.loc[:,'ASKVOL10'] = 0 df.loc[:,'BIDVOL1'] = 0 df.loc[:,'BIDVOL2'] = 0 df.loc[:,'BIDVOL3'] = 0 df.loc[:,'BIDVOL4'] = 0 df.loc[:,'BIDVOL5'] = 0 df.loc[:,'BIDVOL6'] = 0 df.loc[:,'BIDVOL7'] = 0 df.loc[:,'BIDVOL8'] = 0 df.loc[:,'BIDVOL9'] = 0 df.loc[:,'BIDVOL10'] = 0 df.loc[:,'VWAP'] = 0.0 df.loc[:,'VOL30']=0.0 df.loc[:,'TOTAL_VOLUME']=0.0 df.loc[:,'TOTAL_TURNOVER']=0.0 df.loc[:,'INTEREST']=0.0 print(df) # if market == 1 and stk[0] == '6': # df = bar(stk, conn=cons, start_date=date, end_date=date, freq=freq, market=market, asset=asset) store[symbol] = df store.close() close_apis(cons) def bar(code, conn=None, start_date=None, end_date=None, freq='D', asset='E', market='', adj = None, ma = [], factors = [], retry_count = 3): """ BAR数据 Parameters: ------------ code:证券代码,支持股票,ETF/LOF,期货/期权,港股 con:服务器连接 ,通过ts.api()或者ts.xpi()获得 start_date:开始日期 YYYY-MM-DD/YYYYMMDD end_date:结束日期 YYYY-MM-DD/YYYYMMDD freq:支持1/5/15/30/60分钟,周/月/季/年 asset:证券类型 E:股票和交易所基金,INDEX:沪深指数,X:期货/期权/港股/中概美国/中证指数/国际指数 market:市场代码,通过ts.get_markets()获取 adj:复权类型,None不复权,qfq:前复权,hfq:后复权 ma:均线,支持自定义均线频度,如:ma5/ma10/ma20/ma60/maN factors因子数据,目前支持以下两种: vr:量比,默认不返回,返回需指定:factor=['vr'] tor:换手率,默认不返回,返回需指定:factor=['tor'] 以上两种都需要:factor=['vr', 'tor'] retry_count:网络重试次数 Return ---------- DataFrame code:代码 open:开盘close/high/low/vol成交量/amount成交额/maN均价/vr量比/tor换手率 期货(asset='X') code/open/close/high/low/avg_price:均价 position:持仓量 vol:成交总量 """ code = code.strip().upper() for _ in range(retry_count): try: if conn is None: print(ct.MSG_NOT_CONNECTED) return None api, xapi = conn ktype = freq.strip().upper() asset = asset.strip().upper() mkcode = _get_mkcode(code, asset=asset, xapi=xapi) if market == '' else market if asset in['E', 'INDEX']: func = getattr(api, ct.ASSET[asset]) else: ktype = 'XD' if ktype == 'D' else ktype func = getattr(xapi, ct.ASSET['X']) if ktype in ct.KTYPE_LOW_COLS: data = pd.DataFrame() for i in range(100): ds = func(ct.KTYPE[ktype], mkcode, code, i * 800, 800) df = api.to_df(ds) data = data.append(df) if i == 0 else df.append(data, ignore_index=True) if len(ds) < 800: break data['datetime'] = data['datetime'].apply(lambda x: str(x[0:10])) if ktype in ct.KTYPE_ARR: data = pd.DataFrame() for i in range(100): ds = func(ct.KTYPE[ktype], mkcode, code, i * 800, 800) df = api.to_df(ds) data = data.append(df) if i == 0 else df.append(data, ignore_index=True) if len(ds) < 800: break data['datetime'] = pd.to_datetime(data['datetime']) data = data.assign(code=str(code)) \ .set_index('datetime', drop=True, inplace=False) \ .drop(ct.T_DROP_COLS, axis=1)[ None if start_date == '' else start_date : None if end_date == '' else end_date] data = data.sort_index(ascending=False) if asset in['E', 'INDEX']: data = data[ct.BAR_E_COLS] if ktype in ct.KTYPE_ARR: data['vol'] = data['vol'] / 100 else: data = data[ct.BAR_X_COLS] if mkcode in [28, 29, 30, 47, 60]: data.columns = ct.BAR_X_FUTURE_COLS data = data[ct.BAR_X_FUTURE_RL_COLS] else: data = data.drop(['price', 'position'], axis=1) data.columns = ct.BAR_X_OTHER_COLS if asset == 'E': if adj is not None: df = factor_adj(code) if ktype in ct.KTYPE_LOW_COLS: data = data.merge(df, left_index=True, right_index=True) data['adj_factor'] = data['adj_factor'].fillna(method='bfill') else: def get_val(day): return df.ix[day]['adj_factor'] data['adj_factor'] = data.index.map(lambda x: get_val(str(x)[0:10])) for col in ct.BAR_E_COLS[1:5]: if adj == 'hfq': data[col] = data[col] * data['adj_factor'] else: data[col] = data[col] * data['adj_factor'] / float(df['adj_factor'][0]) data[col] = data[col].map(ct.FORMAT) data = data.drop('adj_factor', axis=1) if factors is not None and len(factors) >0 : if 'tor' in factors: df = factor_shares(code) if ktype in ct.KTYPE_LOW_COLS: data = data.merge(df, left_index=True, right_index=True) data['floats'] = data['floats'].fillna(method='bfill') else: def get_val(day): return df.ix[day]['floats'] data['floats'] = data.index.map(lambda x: get_val(str(x)[0:10])) data['tor'] = data['vol'] / data['floats'] data['tor'] = data['tor'].map(ct.FORMAT) data['tor'] = data['tor'].astype(float) data = data.drop('floats', axis=1) if 'vr' in factors: data['vol5'] = MA(data['vol'], 5) data['mean'] = data['vol5'].shift(-5) data['vr'] = (data['vol'] / data['mean']).map(ct.FORMAT) data['vr'] = data['vr'].astype(float) data = data.drop(['vol5', 'mean'], axis=1) if ma is not None and len(ma) > 0: for a in ma: if isinstance(a, int): data['ma%s'%a] = MA(data['close'], a).map(ct.FORMAT).shift(-(a-1)) data['ma%s'%a] = data['ma%s'%a].astype(float) for col in ['open', 'high', 'low', 'close']: data[col] = data[col].astype(float) data['p_change'] = data['close'].pct_change(-1) * 100 data['p_change'] = data['p_change'].map(ct.FORMAT).astype(float) return data except: return None else: data['p_change'] = data['close'].pct_change(-1) * 100 data['p_change'] = data['p_change'].map(ct.FORMAT).astype(float) return data raise IOError(ct.NETWORK_URL_ERROR_MSG) def _get_mkcode(code='', asset='E', xapi=None): mkcode = '' if asset == 'E': mkcode = ct._market_code(code) elif asset == 'INDEX': mkcode = ct._idx_market_code(code) else: if os.path.exists(ct.INST_PLK_F): mks = pd.read_pickle(ct.INST_PLK_F) else: mks = get_instrument(xapi) mks.to_pickle(ct.INST_PLK_F) mkcode = mks[mks.code == code]['market'].values[0] return mkcode def tick(code, conn=None, date='', asset='E', market='', retry_count = 3): """ tick数据 Parameters: ------------ code:证券代码,支持股票,ETF/LOF,期货/期权,港股 conn:服务器连接 ,通过ts.api()或者ts.xpi()获得 date:日期 asset:证券品种,E:沪深交易所股票和基金, INDEX:沪深交易所指数, X:其他证券品种,大致如下: 支持的扩展行情包括(asset='X'): 郑州商品期权 OZ 大连商品期权 OD 上海商品期权 OS 上海个股期权 QQ 香港指数 FH 郑州商品 QZ 大连商品 QD 上海期货 QS 香港主板 KH 香港权证 KR 开放式基金 FU 货币型基金 FB 招商理财产品 LC 招商货币产品 LB 国际指数 FW 国内宏观指标 HG 中国概念股 CH 美股知名公司 MG B股转H股 HB 股份转让 SB 股指期货 CZ 香港创业板 KG 香港信托基金 KT 国债预发行 GY 主力期货合约 MA 中证指数 ZZ 港股通 GH market:市场代码,通过ts.get_markets()获取 Return ---------- DataFrame date:日期 time:时间 price:成交价 vol:成交量 type:买卖方向,0-买入 1-卖出 2-集合竞价成交 期货 0:开仓 1:多开 -1:空开 期货多一列数据oi_change:增仓数据 """ code = code.strip().upper() date = int(date.replace('-', '')) today = int(str(du.today()).replace('-', '')) for _ in range(retry_count): try: if conn is None: print(ct.MSG_NOT_CONNECTED) return None api, xapi = conn data = pd.DataFrame() mkcode = _get_mkcode(code, asset=asset, xapi=xapi) if market == '' else market con = api if asset in['E', 'INDEX'] else xapi for i in range(200): if date == today: ds = con.get_transaction_data(market=mkcode, code=code, start=i * 300, count=300) else: ds = con.get_history_transaction_data(market=mkcode, code=code, date=date, start=i * 300, count=300) df = api.to_df(ds) data = data.append(df) if i == 0 else df.append(data, ignore_index=True) if len(ds) < 300: break if asset in['E', 'INDEX']: data['date'] = date data['date'] = data['date'].map(lambda x: '%s-%s-%s '%(str(x)[0:4], str(x)[4:6], str(x)[6:8])) data['datetime'] = data['date'] + data['time'] data = data[['datetime', 'price', 'vol', 'buyorsell']] data.columns = ['datetime', 'price', 'vol', 'type'] else: if mkcode in [31, 71]: if date == today: data = data.drop(['hour', 'minute', 'nature_name', 'zengcang', 'direction', 'second', 'nature_mark', 'nature_value'], axis=1) else: data = data.drop(['hour', 'minute', 'nature_name', 'zengcang', 'direction'], axis=1) data.loc[data.nature== 512, 'nature' ] = 2 data.loc[data.nature== 256, 'nature' ] = 1 data = data.sort_values('date') data.columns = ['date', 'price', 'vol', 'type'] elif mkcode in [28, 29, 30, 47, 60]: if date == today: data = data.drop(['hour', 'minute', 'nature', 'direction', 'second', 'nature_mark', 'nature_value'], axis=1) else: data = data.drop(['hour', 'minute', 'nature', 'direction'], axis=1) data.columns = ['date', 'price', 'vol', 'oi_change', 'type'] else: data = data.drop(['hour', 'minute', 'nature_name', 'zengcang', 'direction', 'nature'], axis=1) except Exception as e: print(e) else: return data def quotes(symbols, conn=None, asset='E', market=[], retry_count = 3): """ 获取实时快照 Parameters ------ symbols : string, array-like object (list, tuple, Series). return ------- DataFrame 实时快照,5档行情 """ for _ in range(retry_count): try: if conn is None: print(ct.MSG_NOT_CONNECTED) return None api, xapi = conn data = pd.DataFrame() if isinstance(symbols, list) or isinstance(symbols, set) or isinstance(symbols, tuple) or isinstance(symbols, pd.Series): for code in symbols: mkcode = _get_mkcode(code, asset=asset, xapi=xapi) if asset == 'E': df = api.to_df(api.get_security_quotes([(mkcode, code)])) elif asset == 'INDEX': df = api.to_df(api.get_security_quotes([(mkcode, code)])) else: df = xapi.to_df(xapi.get_instrument_quote(mkcode, code)) data = data.append(df) else: mkcode = _get_mkcode(symbols, asset=asset, xapi=xapi) if asset == 'E': data = api.to_df(api.get_security_quotes([(mkcode, symbols)])) elif asset == 'INDEX': data = api.to_df(api.get_security_quotes([(mkcode, symbols)])) else: data = xapi.to_df(xapi.get_instrument_quote(mkcode, symbols)) if asset in ['E', 'INDEX']: data = data.drop(['market', 'active1', 'active2', 'reversed_bytes0', 'reversed_bytes1', 'reversed_bytes2', 'reversed_bytes3', 'reversed_bytes4', 'reversed_bytes5', 'reversed_bytes6', 'reversed_bytes7', 'reversed_bytes8', 'reversed_bytes9'], axis=1) else: data = data.drop(['market'], axis=1) except Exception as e: print(e) else: return data raise IOError(ct.NETWORK_URL_ERROR_MSG) def get_security(api): """ 获取股票列表 """ data = [] for p in range(100): ds = api.get_security_list(0, p*1000) data += ds if len(ds) < 1000: break data = api.to_df(data) return data def reset_instrument(xapi=None): """ 重新设置本地证券列表 """ import tushare.util.conns as cs xapi = cs.xapi_x() if xapi is None else xapi data=[] for i in range(200): ds = xapi.get_instrument_info(i * 300, 300) data += ds if len(ds) < 300: break data = xapi.to_df(data) data.to_pickle(ct.INST_PLK_F) return data def get_instrument(xapi=None): """ 获取证券列表 """ import tushare.util.conns as cs xapi = cs.xapi_x() if xapi is None else xapi if xapi is None: print(ct.MSG_NOT_CONNECTED) return None data=[] for i in range(200): # range for python2/3 ds = xapi.get_instrument_info(i * 300, 300) data += ds if len(ds) < 300: break data = xapi.to_df(data) return data def get_markets(xapi=None): """ 获取市场代码 """ if xapi is None: print(ct.MSG_NOT_CONNECTED) return None data = xapi.get_markets() data = xapi.to_df(data) return data def factor_adj(code): df = pd.read_csv(ct.ADJ_FAC_URL%(ct.P_TYPE['http'], ct.DOMAINS['oss'], code)) df = df.set_index('datetime') return df def factor_shares(code): df = pd.read_csv(ct.SHS_FAC_URL%(ct.P_TYPE['http'], ct.DOMAINS['oss'], code))[['datetime', 'floats']] df = df.set_index('datetime') return df def _random(n=13): from random import randint start = 10**(n-1) end = (10**n)-1 return str(randint(start, end)) ================================================ FILE: tushare/stock/trendline.py ================================================ # -*- coding:utf-8 -*- """ 股票技术指标接口 Created on 2018/07/26 @author: Wangzili @group : ** @contact: 446406177@qq.com 所有指标中参数df为通过get_k_data获取的股票数据 """ import pandas as pd import numpy as np import itertools def ma(df, n=10): """ 移动平均线 Moving Average MA(N)=(第1日收盘价+第2日收盘价—+……+第N日收盘价)/N """ pv = pd.DataFrame() pv['date'] = df['date'] pv['v'] = df.close.rolling(n).mean() return pv def _ma(series, n): """ 移动平均 """ return series.rolling(n).mean() def md(df, n=10): """ 移动标准差 STD=S(CLOSE,N)=[∑(CLOSE-MA(CLOSE,N))^2/N]^0.5 """ _md = pd.DataFrame() _md['date'] = df.date _md["md"] = df.close.rolling(n).std(ddof=0) return _md def _md(series, n): """ 标准差MD """ return series.rolling(n).std(ddof=0) # 有时候会用ddof=1 def ema(df, n=12): """ 指数平均数指标 Exponential Moving Average 今日EMA(N)=2/(N+1)×今日收盘价+(N-1)/(N+1)×昨日EMA(N) EMA(X,N)=[2×X+(N-1)×EMA(ref(X),N]/(N+1) """ _ema = pd.DataFrame() _ema['date'] = df['date'] _ema['ema'] = df.close.ewm(ignore_na=False, span=n, min_periods=0, adjust=False).mean() return _ema def _ema(series, n): """ 指数平均数 """ return series.ewm(ignore_na=False, span=n, min_periods=0, adjust=False).mean() def macd(df, n=12, m=26, k=9): """ 平滑异同移动平均线(Moving Average Convergence Divergence) 今日EMA(N)=2/(N+1)×今日收盘价+(N-1)/(N+1)×昨日EMA(N) DIFF= EMA(N1)- EMA(N2) DEA(DIF,M)= 2/(M+1)×DIF +[1-2/(M+1)]×DEA(REF(DIF,1),M) MACD(BAR)=2×(DIF-DEA) return: osc: MACD bar / OSC 差值柱形图 DIFF - DEM diff: 差离值 dea: 讯号线 """ _macd = pd.DataFrame() _macd['date'] = df['date'] _macd['diff'] = _ema(df.close, n) - _ema(df.close, m) _macd['dea'] = _ema(_macd['diff'], k) _macd['macd'] = _macd['diff'] - _macd['dea'] return _macd def kdj(df, n=9): """ 随机指标KDJ N日RSV=(第N日收盘价-N日内最低价)/(N日内最高价-N日内最低价)×100% 当日K值=2/3前1日K值+1/3×当日RSV=SMA(RSV,M1) 当日D值=2/3前1日D值+1/3×当日K= SMA(K,M2) 当日J值=3 ×当日K值-2×当日D值 """ _kdj = pd.DataFrame() _kdj['date'] = df['date'] rsv = (df.close - df.low.rolling(n).min()) / (df.high.rolling(n).max() - df.low.rolling(n).min()) * 100 _kdj['k'] = sma(rsv, 3) _kdj['d'] = sma(_kdj.k, 3) _kdj['j'] = 3 * _kdj.k - 2 * _kdj.d return _kdj def rsi(df, n=6): """ 相对强弱指标(Relative Strength Index,简称RSI LC= REF(CLOSE,1) RSI=SMA(MAX(CLOSE-LC,0),N,1)/SMA(ABS(CLOSE-LC),N1,1)×100 SMA(C,N,M)=M/N×今日收盘价+(N-M)/N×昨日SMA(N) """ # pd.set_option('display.max_rows', 1000) _rsi = pd.DataFrame() _rsi['date'] = df['date'] px = df.close - df.close.shift(1) px[px < 0] = 0 _rsi['rsi'] = sma(px, n) / sma((df['close'] - df['close'].shift(1)).abs(), n) * 100 # def tmax(x): # if x < 0: # x = 0 # return x # _rsi['rsi'] = sma((df['close'] - df['close'].shift(1)).apply(tmax), n) / sma((df['close'] - df['close'].shift(1)).abs(), n) * 100 return _rsi def vrsi(df, n=6): """ 量相对强弱指标 VRSI=SMA(最大值(成交量-REF(成交量,1),0),N,1)/SMA(ABS((成交量-REF(成交量,1),N,1)×100% """ _vrsi = pd.DataFrame() _vrsi['date'] = df['date'] px = df['volume'] - df['volume'].shift(1) px[px < 0] = 0 _vrsi['vrsi'] = sma(px, n) / sma((df['volume'] - df['volume'].shift(1)).abs(), n) * 100 return _vrsi def boll(df, n=26, k=2): """ 布林线指标BOLL boll(26,2) MID=MA(N) 标准差MD=根号[∑(CLOSE-MA(CLOSE,N))^2/N] UPPER=MID+k×MD LOWER=MID-k×MD """ _boll = pd.DataFrame() _boll['date'] = df.date _boll['mid'] = _ma(df.close, n) _mdd = _md(df.close, n) _boll['up'] = _boll.mid + k * _mdd _boll['low'] = _boll.mid - k * _mdd return _boll def bbiboll(df, n=10, k=3): """ BBI多空布林线 bbiboll(10,3) BBI={MA(3)+ MA(6)+ MA(12)+ MA(24)}/4 标准差MD=根号[∑(BBI-MA(BBI,N))^2/N] UPR= BBI+k×MD DWN= BBI-k×MD """ # pd.set_option('display.max_rows', 1000) _bbiboll = pd.DataFrame() _bbiboll['date'] = df.date _bbiboll['bbi'] = (_ma(df.close, 3) + _ma(df.close, 6) + _ma(df.close, 12) + _ma(df.close, 24)) / 4 _bbiboll['md'] = _md(_bbiboll.bbi, n) _bbiboll['upr'] = _bbiboll.bbi + k * _bbiboll.md _bbiboll['dwn'] = _bbiboll.bbi - k * _bbiboll.md return _bbiboll def wr(df, n=14): """ 威廉指标 w&r WR=[最高值(最高价,N)-收盘价]/[最高值(最高价,N)-最低值(最低价,N)]×100% """ _wr = pd.DataFrame() _wr['date'] = df['date'] higest = df.high.rolling(n).max() _wr['wr'] = (higest - df.close) / (higest - df.low.rolling(n).min()) * 100 return _wr def bias(df, n=12): """ 乖离率 bias bias=[(当日收盘价-12日平均价)/12日平均价]×100% """ _bias = pd.DataFrame() _bias['date'] = df.date _mav = df.close.rolling(n).mean() _bias['bias'] = (np.true_divide((df.close - _mav), _mav)) * 100 # _bias["bias"] = np.vectorize(lambda x: round(Decimal(x), 4))(BIAS) return _bias def asi(df, n=5): """ 振动升降指标(累计震动升降因子) ASI # 同花顺给出的公式不完整就不贴出来了 """ _asi = pd.DataFrame() _asi['date'] = df.date _m = pd.DataFrame() _m['a'] = (df.high - df.close.shift()).abs() _m['b'] = (df.low - df.close.shift()).abs() _m['c'] = (df.high - df.low.shift()).abs() _m['d'] = (df.close.shift() - df.open.shift()).abs() _m['r'] = _m.apply(lambda x: x.a + 0.5 * x.b + 0.25 * x.d if max(x.a, x.b, x.c) == x.a else ( x.b + 0.5 * x.a + 0.25 * x.d if max(x.a, x.b, x.c) == x.b else x.c + 0.25 * x.d ), axis=1) _m['x'] = df.close - df.close.shift() + 0.5 * (df.close - df.open) + df.close.shift() - df.open.shift() _m['k'] = np.maximum(_m.a, _m.b) _asi['si'] = 16 * (_m.x / _m.r) * _m.k _asi["asi"] = _ma(_asi.si, n) return _asi def vr_rate(df, n=26): """ 成交量变异率 vr or vr_rate VR=(AVS+1/2CVS)/(BVS+1/2CVS)×100 其中: AVS:表示N日内股价上涨成交量之和 BVS:表示N日内股价下跌成交量之和 CVS:表示N日内股价不涨不跌成交量之和 """ _vr = pd.DataFrame() _vr['date'] = df['date'] _m = pd.DataFrame() _m['volume'] = df.volume _m['cs'] = df.close - df.close.shift(1) _m['avs'] = _m.apply(lambda x: x.volume if x.cs > 0 else 0, axis=1) _m['bvs'] = _m.apply(lambda x: x.volume if x.cs < 0 else 0, axis=1) _m['cvs'] = _m.apply(lambda x: x.volume if x.cs == 0 else 0, axis=1) _vr["vr"] = (_m.avs.rolling(n).sum() + 1 / 2 * _m.cvs.rolling(n).sum() ) / (_m.bvs.rolling(n).sum() + 1 / 2 * _m.cvs.rolling(n).sum()) * 100 return _vr def vr(df, n=5): """ 开市后平均每分钟的成交量与过去5个交易日平均每分钟成交量之比 量比:=V/REF(MA(V,5),1); 涨幅:=(C-REF(C,1))/REF(C,1)*100; 1)量比大于1.8,涨幅小于2%,现价涨幅在0—2%之间,在盘中选股的 选股:量比>1.8 AND 涨幅>0 AND 涨幅<2; """ _vr = pd.DataFrame() _vr['date'] = df.date _vr['vr'] = df.volume / _ma(df.volume, n).shift(1) _vr['rr'] = (df.close - df.close.shift(1)) / df.close.shift(1) * 100 return _vr def arbr(df, n=26): """ 人气意愿指标 arbr(26) N日AR=N日内(H-O)之和除以N日内(O-L)之和 其中,H为当日最高价,L为当日最低价,O为当日开盘价,N为设定的时间参数,一般原始参数日设定为26日 N日BR=N日内(H-CY)之和除以N日内(CY-L)之和 其中,H为当日最高价,L为当日最低价,CY为前一交易日的收盘价,N为设定的时间参数,一般原始参数日设定为26日。 """ _arbr = pd.DataFrame() _arbr['date'] = df.date _arbr['ar'] = (df.high - df.open).rolling(n).sum() / (df.open - df.low).rolling(n).sum() * 100 _arbr['br'] = (df.high - df.close.shift(1)).rolling(n).sum() / (df.close.shift() - df.low).rolling(n).sum() * 100 return _arbr def dpo(df, n=20, m=6): """ 区间震荡线指标 dpo(20,6) DPO=CLOSE-MA(CLOSE, N/2+1) MADPO=MA(DPO,M) """ _dpo = pd.DataFrame() _dpo['date'] = df['date'] _dpo['dpo'] = df.close - _ma(df.close, int(n / 2 + 1)) _dpo['dopma'] = _ma(_dpo.dpo, m) return _dpo def trix(df, n=12, m=20): """ 三重指数平滑平均 TRIX(12) TR= EMA(EMA(EMA(CLOSE,N),N),N),即进行三次平滑处理 TRIX=(TR-昨日TR)/ 昨日TR×100 TRMA=MA(TRIX,M) """ _trix = pd.DataFrame() _trix['date'] = df.date tr = _ema(_ema(_ema(df.close, n), n), n) _trix['trix'] = (tr - tr.shift()) / tr.shift() * 100 _trix['trma'] = _ma(_trix.trix, m) return _trix def bbi(df): """ 多空指数 BBI(3,6,12,24) BBI=(3日均价+6日均价+12日均价+24日均价)/4 """ _bbi = pd.DataFrame() _bbi['date'] = df['date'] _bbi['bbi'] = (_ma(df.close, 3) + _ma(df.close, 6) + _ma(df.close, 12) + _ma(df.close, 24)) / 4 return _bbi def mtm(df, n=6, m=5): """ 动力指标 MTM(6,5) MTM(N日)=C-REF(C,N)式中,C=当日的收盘价,REF(C,N)=N日前的收盘价;N日是只计算交易日期,剔除掉节假日。 MTMMA(MTM,N1)= MA(MTM,N1) N表示间隔天数,N1表示天数 """ _mtm = pd.DataFrame() _mtm['date'] = df.date _mtm['mtm'] = df.close - df.close.shift(n) _mtm['mtmma'] = _ma(_mtm.mtm, m) return _mtm def obv(df): """ 能量潮 On Balance Volume 多空比率净额= [(收盘价-最低价)-(最高价-收盘价)] ÷( 最高价-最低价)×V # 同花顺貌似用的下面公式 主公式:当日OBV=前一日OBV+今日成交量 1.基期OBV值为0,即该股上市的第一天,OBV值为0 2.若当日收盘价>上日收盘价,则当日OBV=前一日OBV+今日成交量 3.若当日收盘价<上日收盘价,则当日OBV=前一日OBV-今日成交量 4.若当日收盘价=上日收盘价,则当日OBV=前一日OBV """ _obv = pd.DataFrame() _obv["date"] = df['date'] # tmp = np.true_divide(((df.close - df.low) - (df.high - df.close)), (df.high - df.low)) # _obv['obvv'] = tmp * df.volume # _obv["obv"] = _obv.obvv.expanding(1).sum() / 100 _m = pd.DataFrame() _m['date'] = df.date _m['cs'] = df.close - df.close.shift() _m['v'] = df.volume _m['vv'] = _m.apply(lambda x: x.v if x.cs > 0 else (-x.v if x.cs < 0 else 0), axis=1) _obv['obv'] = _m.vv.expanding(1).sum() return _obv def cci(df, n=14): """ 顺势指标 TYP:=(HIGH+LOW+CLOSE)/3 CCI:=(TYP-MA(TYP,N))/(0.015×AVEDEV(TYP,N)) """ _cci = pd.DataFrame() _cci["date"] = df['date'] typ = (df.high + df.low + df.close) / 3 _cci['cci'] = ((typ - typ.rolling(n).mean()) / (0.015 * typ.rolling(min_periods=1, center=False, window=n).apply( lambda x: np.fabs(x - x.mean()).mean()))) return _cci def priceosc(df, n=12, m=26): """ 价格振动指数 PRICEOSC=(MA(C,12)-MA(C,26))/MA(C,12) * 100 """ _c = pd.DataFrame() _c['date'] = df['date'] man = _ma(df.close, n) _c['osc'] = (man - _ma(df.close, m)) / man * 100 return _c def sma(a, n, m=1): """ 平滑移动指标 Smooth Moving Average """ ''' # 方法一,此方法有缺陷 _sma = [] for index, value in enumerate(a): if index == 0 or pd.isna(value) or np.isnan(value): tsma = 0 else: # Y=(M*X+(N-M)*Y')/N tsma = (m * value + (n - m) * tsma) / n _sma.append(tsma) return pd.Series(_sma) ''' ''' # 方法二 results = np.nan_to_num(a).copy() # FIXME this is very slow for i in range(1, len(a)): results[i] = (m * results[i] + (n - m) * results[i - 1]) / n # results[i] = ((n - 1) * results[i - 1] + results[i]) / n # return results ''' # b = np.nan_to_num(a).copy() # return ((n - m) * a.shift(1) + m * a) / n a = a.fillna(0) b = a.ewm(min_periods=0, ignore_na=False, adjust=False, alpha=m/n).mean() return b def dbcd(df, n=5, m=16, t=76): """ 异同离差乖离率 dbcd(5,16,76) BIAS=(C-MA(C,N))/MA(C,N) DIF=(BIAS-REF(BIAS,M)) DBCD=SMA(DIF,T,1) =(1-1/T)×SMA(REF(DIF,1),T,1)+ 1/T×DIF MM=MA(DBCD,5) """ _dbcd = pd.DataFrame() _dbcd['date'] = df.date man = _ma(df.close, n) _bias = (df.close - man) / man _dif = _bias - _bias.shift(m) _dbcd['dbcd'] = sma(_dif, t) _dbcd['mm'] = _ma(_dbcd.dbcd, n) return _dbcd def roc(df, n=12, m=6): """ 变动速率 roc(12,6) ROC=(今日收盘价-N日前的收盘价)/ N日前的收盘价×100% ROCMA=MA(ROC,M) ROC:(CLOSE-REF(CLOSE,N))/REF(CLOSE,N)×100 ROCMA:MA(ROC,M) """ _roc = pd.DataFrame() _roc['date'] = df['date'] _roc['roc'] = (df.close - df.close.shift(n))/df.close.shift(n) * 100 _roc['rocma'] = _ma(_roc.roc, m) return _roc def vroc(df, n=12): """ 量变动速率 VROC=(当日成交量-N日前的成交量)/ N日前的成交量×100% """ _vroc = pd.DataFrame() _vroc['date'] = df['date'] _vroc['vroc'] = (df.volume - df.volume.shift(n)) / df.volume.shift(n) * 100 return _vroc def cr(df, n=26): """ 能量指标 CR=∑(H-PM)/∑(PM-L)×100 PM:上一交易日中价((最高、最低、收盘价的均值) H:当天最高价 L:当天最低价 """ _cr = pd.DataFrame() _cr['date'] = df.date # pm = ((df['high'] + df['low'] + df['close']) / 3).shift(1) pm = (df[['high', 'low', 'close']]).mean(axis=1).shift(1) _cr['cr'] = (df.high - pm).rolling(n).sum()/(pm - df.low).rolling(n).sum() * 100 return _cr def psy(df, n=12): """ 心理指标 PSY(12) PSY=N日内上涨天数/N×100 PSY:COUNT(CLOSE>REF(CLOSE,1),N)/N×100 MAPSY=PSY的M日简单移动平均 """ _psy = pd.DataFrame() _psy['date'] = df.date p = df.close - df.close.shift() p[p <= 0] = np.nan _psy['psy'] = p.rolling(n).count() / n * 100 return _psy def wad(df, n=30): """ 威廉聚散指标 WAD(30) TRL=昨日收盘价与今日最低价中价格最低者;TRH=昨日收盘价与今日最高价中价格最高者 如果今日的收盘价>昨日的收盘价,则今日的A/D=今日的收盘价-今日的TRL 如果今日的收盘价<昨日的收盘价,则今日的A/D=今日的收盘价-今日的TRH 如果今日的收盘价=昨日的收盘价,则今日的A/D=0 WAD=今日的A/D+昨日的WAD;MAWAD=WAD的M日简单移动平均 """ def dmd(x): if x.c > 0: y = x.close - x.trl elif x.c < 0: y = x.close - x.trh else: y = 0 return y _wad = pd.DataFrame() _wad['date'] = df['date'] _ad = pd.DataFrame() _ad['trl'] = np.minimum(df.low, df.close.shift(1)) _ad['trh'] = np.maximum(df.high, df.close.shift(1)) _ad['c'] = df.close - df.close.shift() _ad['close'] = df.close _ad['ad'] = _ad.apply(dmd, axis=1) _wad['wad'] = _ad.ad.expanding(1).sum() _wad['mawad'] = _ma(_wad.wad, n) return _wad def mfi(df, n=14): """ 资金流向指标 mfi(14) MF=TYP×成交量;TYP:当日中价((最高、最低、收盘价的均值) 如果当日TYP>昨日TYP,则将当日的MF值视为当日PMF值。而当日NMF值=0 如果当日TYP<=昨日TYP,则将当日的MF值视为当日NMF值。而当日PMF值=0 MR=∑PMF/∑NMF MFI=100-(100÷(1+MR)) """ _mfi = pd.DataFrame() _mfi['date'] = df.date _m = pd.DataFrame() _m['typ'] = df[['high', 'low', 'close']].mean(axis=1) _m['mf'] = _m.typ * df.volume _m['typ_shift'] = _m.typ - _m.typ.shift(1) _m['pmf'] = _m.apply(lambda x: x.mf if x.typ_shift > 0 else 0, axis=1) _m['nmf'] = _m.apply(lambda x: x.mf if x.typ_shift <= 0 else 0, axis=1) # _mfi['mfi'] = 100 - (100 / (1 + _m.pmf.rolling(n).sum() / _m.nmf.rolling(n).sum())) _m['mr'] = _m.pmf.rolling(n).sum() / _m.nmf.rolling(n).sum() _mfi['mfi'] = 100 * _m.mr / (1 + _m.mr) # 同花顺自己给出的公式和实际用的公式不一样,真操蛋,浪费两个小时时间 return _mfi def pvt(df): """ pvt 量价趋势指标 pvt 如果设x=(今日收盘价—昨日收盘价)/昨日收盘价×当日成交量, 那么当日PVT指标值则为从第一个交易日起每日X值的累加。 """ _pvt = pd.DataFrame() _pvt['date'] = df.date x = (df.close - df.close.shift(1)) / df.close.shift(1) * df.volume _pvt['pvt'] = x.expanding(1).sum() return _pvt def wvad(df, n=24, m=6): """ # 算法是对的,同花顺计算wvad用的n=6 威廉变异离散量 wvad(24,6) WVAD=N1日的∑ {(当日收盘价-当日开盘价)/(当日最高价-当日最低价)×成交量} MAWVAD=MA(WVAD,N2) """ _wvad = pd.DataFrame() _wvad['date'] = df.date # _wvad['wvad'] = (np.true_divide((df.close - df.open), (df.high - df.low)) * df.volume).rolling(n).sum() _wvad['wvad'] = (np.true_divide((df.close - df.open), (df.high - df.low)) * df.volume).rolling(n).sum() _wvad['mawvad'] = _ma(_wvad.wvad, m) return _wvad def cdp(df): """ 逆势操作 cdp CDP=(最高价+最低价+收盘价)/3 # 同花顺实际用的(H+L+2*c)/4 AH=CDP+(前日最高价-前日最低价) NH=CDP×2-最低价 NL=CDP×2-最高价 AL=CDP-(前日最高价-前日最低价) """ _cdp = pd.DataFrame() _cdp['date'] = df.date # _cdp['cdp'] = (df.high + df.low + df.close * 2).shift(1) / 4 _cdp['cdp'] = df[['high', 'low', 'close', 'close']].shift().mean(axis=1) _cdp['ah'] = _cdp.cdp + (df.high.shift(1) - df.low.shift()) _cdp['al'] = _cdp.cdp - (df.high.shift(1) - df.low.shift()) _cdp['nh'] = _cdp.cdp * 2 - df.low.shift(1) _cdp['nl'] = _cdp.cdp * 2 - df.high.shift(1) return _cdp def env(df, n=14): """ ENV指标 ENV(14) Upper=MA(CLOSE,N)×1.06 LOWER= MA(CLOSE,N)×0.94 """ _env = pd.DataFrame() _env['date'] = df.date _env['up'] = df.close.rolling(n).mean() * 1.06 _env['low'] = df.close.rolling(n).mean() * 0.94 return _env def mike(df, n=12): """ 麦克指标 mike(12) 初始价(TYP)=(当日最高价+当日最低价+当日收盘价)/3 HV=N日内区间最高价 LV=N日内区间最低价 初级压力线(WR)=TYP×2-LV 中级压力线(MR)=TYP+HV-LV 强力压力线(SR)=2×HV-LV 初级支撑线(WS)=TYP×2-HV 中级支撑线(MS)=TYP-HV+LV 强力支撑线(SS)=2×LV-HV """ _mike = pd.DataFrame() _mike['date'] = df.date typ = df[['high', 'low', 'close']].mean(axis=1) hv = df.high.rolling(n).max() lv = df.low.rolling(n).min() _mike['wr'] = typ * 2 - lv _mike['mr'] = typ + hv - lv _mike['sr'] = 2 * hv - lv _mike['ws'] = typ * 2 - hv _mike['ms'] = typ - hv + lv _mike['ss'] = 2 * lv - hv return _mike def vma(df, n=5): """ 量简单移动平均 VMA(5) VMA=MA(volume,N) VOLUME表示成交量;N表示天数 """ _vma = pd.DataFrame() _vma['date'] = df.date _vma['vma'] = _ma(df.volume, n) return _vma def vmacd(df, qn=12, sn=26, m=9): """ 量指数平滑异同平均 vmacd(12,26,9) 今日EMA(N)=2/(N+1)×今日成交量+(N-1)/(N+1)×昨日EMA(N) DIFF= EMA(N1)- EMA(N2) DEA(DIF,M)= 2/(M+1)×DIF +[1-2/(M+1)]×DEA(REF(DIF,1),M) MACD(BAR)=2×(DIF-DEA) """ _vmacd = pd.DataFrame() _vmacd['date'] = df.date _vmacd['diff'] = _ema(df.volume, qn) - _ema(df.volume, sn) _vmacd['dea'] = _ema(_vmacd['diff'], m) # TODO: 不能用_vmacd.diff, 不知道为什么 _vmacd['macd'] = (_vmacd['diff'] - _vmacd['dea']) return _vmacd def vosc(df, n=12, m=26): """ 成交量震荡 vosc(12,26) VOSC=(MA(VOLUME,SHORT)- MA(VOLUME,LONG))/MA(VOLUME,SHORT)×100 """ _c = pd.DataFrame() _c['date'] = df['date'] _c['osc'] = (_ma(df.volume, n) - _ma(df.volume, m)) / _ma(df.volume, n) * 100 return _c def tapi(df, n=6): """ # TODO: 由于get_k_data返回数据中没有amount,可以用get_h_data中amount,算法是正确的 加权指数成交值 tapi(6) TAPI=每日成交总值/当日加权指数=a/PI;A表示每日的成交金额,PI表示当天的股价指数即指收盘价 """ _tapi = pd.DataFrame() # _tapi['date'] = df.date _tapi['tapi'] = df.amount / df.close _tapi['matapi'] = _ma(_tapi.tapi, n) return _tapi def vstd(df, n=10): """ 成交量标准差 vstd(10) VSTD=STD(Volume,N)=[∑(Volume-MA(Volume,N))^2/N]^0.5 """ _vstd = pd.DataFrame() _vstd['date'] = df.date _vstd['vstd'] = df.volume.rolling(n).std(ddof=1) return _vstd def adtm(df, n=23, m=8): """ 动态买卖气指标 adtm(23,8) 如果开盘价≤昨日开盘价,DTM=0 如果开盘价>昨日开盘价,DTM=(最高价-开盘价)和(开盘价-昨日开盘价)的较大值 如果开盘价≥昨日开盘价,DBM=0 如果开盘价<昨日开盘价,DBM=(开盘价-最低价) STM=DTM在N日内的和 SBM=DBM在N日内的和 如果STM > SBM,ADTM=(STM-SBM)/STM 如果STM < SBM , ADTM = (STM-SBM)/SBM 如果STM = SBM,ADTM=0 ADTMMA=MA(ADTM,M) """ _adtm = pd.DataFrame() _adtm['date'] = df.date _m = pd.DataFrame() _m['cc'] = df.open - df.open.shift(1) _m['ho'] = df.high - df.open _m['ol'] = df.open - df.low _m['dtm'] = _m.apply(lambda x: max(x.ho, x.cc) if x.cc > 0 else 0, axis=1) _m['dbm'] = _m.apply(lambda x: x.ol if x.cc < 0 else 0, axis=1) _m['stm'] = _m.dtm.rolling(n).sum() _m['sbm'] = _m.dbm.rolling(n).sum() _m['ss'] = _m.stm - _m.sbm _adtm['adtm'] = _m.apply(lambda x: x.ss / x.stm if x.ss > 0 else (x.ss / x.sbm if x.ss < 0 else 0), axis=1) _adtm['adtmma'] = _ma(_adtm.adtm, m) return _adtm def mi(df, n=12): """ 动量指标 mi(12) A=CLOSE-REF(CLOSE,N) MI=SMA(A,N,1) """ _mi = pd.DataFrame() _mi['date'] = df.date _mi['mi'] = sma(df.close - df.close.shift(n), n) return _mi def micd(df, n=3, m=10, k=20): """ 异同离差动力指数 micd(3,10,20) MI=CLOSE-ref(CLOSE,1)AMI=SMA(MI,N1,1) DIF=MA(ref(AMI,1),N2)-MA(ref(AMI,1),N3) MICD=SMA(DIF,10,1) """ _micd = pd.DataFrame() _micd['date'] = df.date mi = df.close - df.close.shift(1) ami = sma(mi, n) dif = _ma(ami.shift(1), m) - _ma(ami.shift(1), k) _micd['micd'] = sma(dif, m) return _micd def rc(df, n=50): """ 变化率指数 rc(50) RC=收盘价/REF(收盘价,N)×100 ARC=EMA(REF(RC,1),N,1) """ _rc = pd.DataFrame() _rc['date'] = df.date _rc['rc'] = df.close / df.close.shift(n) * 100 _rc['arc'] = sma(_rc.rc.shift(1), n) return _rc def rccd(df, n=59, m=21, k=28): """ # TODO: 计算结果错误和同花顺不同,检查不出来为什么 异同离差变化率指数 rate of change convergence divergence rccd(59,21,28) RC=收盘价/REF(收盘价,N)×100% ARC=EMA(REF(RC,1),N,1) DIF=MA(ref(ARC,1),N1)-MA MA(ref(ARC,1),N2) RCCD=SMA(DIF,N,1) """ _rccd = pd.DataFrame() _rccd['date'] = df.date rc = df.close / df.close.shift(n) * 100 arc = sma(rc.shift(), n) dif = _ma(arc.shift(), m) - _ma(arc.shift(), k) _rccd['rccd'] = sma(dif, n) return _rccd def srmi(df, n=9): """ SRMIMI修正指标 srmi(9) 如果收盘价>N日前的收盘价,SRMI就等于(收盘价-N日前的收盘价)/收盘价 如果收盘价 0 else (x.cs/x.cp if x.cs < 0 else 0), axis=1) return _srmi def dptb(df, n=7): """ 大盘同步指标 dptb(7) DPTB=(统计N天中个股收盘价>开盘价,且指数收盘价>开盘价的天数或者个股收盘价<开盘价,且指数收盘价<开盘价)/N """ ind = ts.get_k_data("sh000001", start=df.date.iloc[0], end=df.date.iloc[-1]) sd = df.copy() sd.set_index('date', inplace=True) # 可能出现停盘等情况,所以将date设为index ind.set_index('date', inplace=True) _dptb = pd.DataFrame(index=df.date) q = ind.close - ind.open _dptb['p'] = sd.close - sd.open _dptb['q'] = q _dptb['m'] = _dptb.apply(lambda x: 1 if (x.p > 0 and x.q > 0) or (x.p < 0 and x.q < 0) else np.nan, axis=1) _dptb['jdrs'] = _dptb.m.rolling(n).count() / n _dptb.drop(columns=['p', 'q', 'm'], inplace=True) _dptb.reset_index(inplace=True) return _dptb def jdqs(df, n=20): """ 阶段强势指标 jdqs(20) JDQS=(统计N天中个股收盘价>开盘价,且指数收盘价<开盘价的天数)/(统计N天中指数收盘价<开盘价的天数) """ ind = ts.get_k_data("sh000001", start=df.date.iloc[0], end=df.date.iloc[-1]) sd = df.copy() sd.set_index('date', inplace=True) # 可能出现停盘等情况,所以将date设为index ind.set_index('date', inplace=True) _jdrs = pd.DataFrame(index=df.date) q = ind.close - ind.open _jdrs['p'] = sd.close - sd.open _jdrs['q'] = q _jdrs['m'] = _jdrs.apply(lambda x: 1 if (x.p > 0 and x.q < 0) else np.nan, axis=1) q[q > 0] = np.nan _jdrs['t'] = q _jdrs['jdrs'] = _jdrs.m.rolling(n).count() / _jdrs.t.rolling(n).count() _jdrs.drop(columns=['p', 'q', 'm', 't'], inplace=True) _jdrs.reset_index(inplace=True) return _jdrs def jdrs(df, n=20): """ 阶段弱势指标 jdrs(20) JDRS=(统计N天中个股收盘价<开盘价,且指数收盘价>开盘价的天数)/(统计N天中指数收盘价>开盘价的天数) """ ind = ts.get_k_data("sh000001", start=df.date.iloc[0], end=df.date.iloc[-1]) sd = df.copy() sd.set_index('date', inplace=True) ind.set_index('date', inplace=True) _jdrs = pd.DataFrame(index=df.date) q = ind.close - ind.open _jdrs['p'] = sd.close - sd.open _jdrs['q'] = q _jdrs['m'] = _jdrs.apply(lambda x: 1 if (x.p < 0 and x.q > 0) else np.nan, axis=1) q[q < 0] = np.nan _jdrs['t'] = q _jdrs['jdrs'] = _jdrs.m.rolling(n).count() / _jdrs.t.rolling(n).count() _jdrs.drop(columns=['p', 'q', 'm', 't'], inplace=True) _jdrs.reset_index(inplace=True) return _jdrs def zdzb(df, n=125, m=5, k=20): """ 筑底指标 zdzb(125,5,20) A=(统计N1日内收盘价>=前收盘价的天数)/(统计N1日内收盘价<前收盘价的天数) B=MA(A,N2) D=MA(A,N3) """ _zdzb = pd.DataFrame() _zdzb['date'] = df.date p = df.close - df.close.shift(1) q = p.copy() p[p < 0] = np.nan q[q >= 0] = np.nan _zdzb['a'] = p.rolling(n).count() / q.rolling(n).count() _zdzb['b'] = _zdzb.a.rolling(m).mean() _zdzb['d'] = _zdzb.a.rolling(k).mean() return _zdzb def atr(df, n=14): """ 真实波幅 atr(14) TR:MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW)) ATR:MA(TR,N) """ _atr = pd.DataFrame() _atr['date'] = df.date # _atr['tr'] = np.maximum(df.high - df.low, (df.close.shift(1) - df.low).abs()) # _atr['tr'] = np.maximum.reduce([df.high - df.low, (df.close.shift(1) - df.high).abs(), (df.close.shift(1) - df.low).abs()]) _atr['tr'] = np.vstack([df.high - df.low, (df.close.shift(1) - df.high).abs(), (df.close.shift(1) - df.low).abs()]).max(axis=0) _atr['atr'] = _atr.tr.rolling(n).mean() return _atr def mass(df, n=9, m=25): """ 梅丝线 mass(9,25) AHL=MA((H-L),N1) BHL= MA(AHL,N1) MASS=SUM(AHL/BHL,N2) H:表示最高价;L:表示最低价 """ _mass = pd.DataFrame() _mass['date'] = df.date ahl = _ma((df.high - df.low), n) bhl = _ma(ahl, n) _mass['mass'] = (ahl / bhl).rolling(m).sum() return _mass def vhf(df, n=28): """ 纵横指标 vhf(28) VHF=(N日内最大收盘价与N日内最小收盘价之前的差)/(N日收盘价与前收盘价差的绝对值之和) """ _vhf = pd.DataFrame() _vhf['date'] = df.date _vhf['vhf'] = (df.close.rolling(n).max() - df.close.rolling(n).min()) / (df.close - df.close.shift(1)).abs().rolling(n).sum() return _vhf def cvlt(df, n=10): """ 佳庆离散指标 cvlt(10) cvlt=(最高价与最低价的差的指数移动平均-前N日的最高价与最低价的差的指数移动平均)/前N日的最高价与最低价的差的指数移动平均 """ _cvlt = pd.DataFrame() _cvlt['date'] = df.date p = _ema(df.high.shift(n) - df.low.shift(n), n) _cvlt['cvlt'] = (_ema(df.high - df.low, n) - p) / p * 100 return _cvlt def up_n(df): """ 连涨天数 up_n 连续上涨天数,当天收盘价大于开盘价即为上涨一天 # 同花顺实际结果用收盘价-前一天收盘价 """ _up = pd.DataFrame() _up['date'] = df.date p = df.close - df.close.shift() p[p > 0] = 1 p[p < 0] = 0 m = [] for k, g in itertools.groupby(p): t = 0 for i in g: if k == 0: m.append(0) else: t += 1 m.append(t) # _up['p'] = p _up['up'] = m return _up def down_n(df): """ 连跌天数 down_n 连续下跌天数,当天收盘价小于开盘价即为下跌一天 """ _down = pd.DataFrame() _down['date'] = df.date p = df.close - df.close.shift() p[p > 0] = 0 p[p < 0] = 1 m = [] for k, g in itertools.groupby(p): t = 0 for i in g: if k == 0: m.append(0) else: t += 1 m.append(t) _down['down'] = m return _down def join_frame(d1, d2, column='date'): # 将两个DataFrame 按照datetime合并 return d1.join(d2.set_index(column), on=column) if __name__ == "__main__": import tushare as ts # data = ts.get_k_data("000063", start="2017-05-01") data = ts.get_k_data("601138", start="2017-05-01") # print(data) # maf = ma(data, n=[5, 10, 20]) # 将均线合并到data中 # print(join_frame(data, maf)) # data = pd.DataFrame({"close": [1,2,3,4,5,6,7,8,9,0]}) # print(ma(data)) # mdf = md(data) # print(md(data, n=26)) # print(join_frame(data, mdf)) # emaf = ema(data) # print(ema(data, 5)) # print(join_frame(data, emaf)) # print(macd(data)) # print(kdj(data)) # print(vrsi(data, 6)) # print(boll(data)) # print(bbiboll(data)) # print(wr(data)) # print(bias(data)) # print(asi(data)) # print(vr_rate(data)) # print(vr(data)) # print(arbr(data)) # print(dpo(data)) # print(trix(data)) # print(bbi(data)) # print(ts.top_list(date="2019-01-17")) # print(mtm(data)) # print(obv(data)) # print(cci(data)) # print(priceosc(data)) # print(dbcd(data)) # print(roc(data)) # print(vroc(data)) # print(cr(data)) # print(psy(data)) # print(wad(data)) # print(mfi(data)) # print(pvt(data)) # print(wvad(data)) # print(cdp(data)) # print(env(data)) # print(mike(data)) # print(vr(data)) # print(vma(data)) # print(vmacd(data)) # print(vosc(data)) # print(tapi(data)) # print(vstd(data)) # print(adtm(data)) # print(mi(data)) # print(micd(data)) # print(rc(data)) print(rccd(data)) # print(srmi(data)) # print(dptb(data)) # print(jdqs(data)) # pd.set_option('display.max_rows', 1000) # print(jdrs(data)) # print(join_frame(data, jdrs(data))) # print(data) # print(zdzb(data)) # print(atr(data)) # print(mass(data)) # print(vhf(data)) # print(cvlt(data)) # print(up_n(data)) # print(down_n(data)) ================================================ FILE: tushare/trader/__init__.py ================================================ ================================================ FILE: tushare/trader/trader.py ================================================ #!/usr/bin/env python # -*- coding:utf-8 -*- ''' Created on 2016年9月25日 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn ''' import six import pandas as pd import requests import time from threading import Thread from tushare.trader import vars as vs from tushare.trader import utils from tushare.util import upass as up from tushare.util.upass import set_broker class TraderAPI(object): """ 股票实盘交易接口 提醒:本文涉及的思路和内容仅限于量化投资及程序化交易的研究与尝试,不作为个人或机构常规程序化交易的依据, 不对实盘的交易风险和政策风险产生的影响负责,如有问题请与我联系。 投资有风险,下单须谨慎。 """ def __init__(self, broker = ''): if broker == '': return None self.broker = broker self.trade_prefix = vs.CSC_PREFIX % (vs.P_TYPE['https'], vs.DOMAINS['csc'], vs.PAGES['csclogin']) self.heart_active = True self.s = requests.session() if six.PY2: self.heart_thread = Thread(target = self.send_heartbeat) self.heart_thread.setDaemon(True) else: self.heart_thread = Thread(target = self.send_heartbeat, daemon=True) def login(self): self.s.headers.update(vs.AGENT) self.s.get(vs.CSC_PREFIX % (vs.P_TYPE['https'], vs.DOMAINS['csc'], vs.PAGES['csclogin'])) res = self.s.get(vs.V_CODE_URL%(vs.P_TYPE['https'], vs.DOMAINS['cscsh'], vs.PAGES['vimg'])) if self._login(utils.get_vcode('csc', res)) is False: print('请确认账号或密码是否正确 ,或券商服务器是否处于维护中。 ') self.keepalive() def _login(self, v_code): brokerinfo = up.get_broker(self.broker) user = brokerinfo['user'][0] login_params = dict( inputid = user, j_username = user, j_inputid = user, AppendCode = v_code, isCheckAppendCode = 'false', logined = 'false', f_tdx = '', j_cpu = '', j_password = brokerinfo['passwd'][0] ) logined = self.s.post(vs.CSC_LOGIN_ACTION % (vs.P_TYPE['https'], vs.DOMAINS['csc']), params = login_params) if logined.text.find(u'消息中心') != -1: return True return False def keepalive(self): if self.heart_thread.is_alive(): self.heart_active = True else: self.heart_thread.start() def send_heartbeat(self): while True: if self.heart_active: try: response = self.heartbeat() self.check_account_live(response) except: self.login() time.sleep(100) else: time.sleep(10) def heartbeat(self): return self.baseinfo def exit(self): self.heart_active = False def buy(self, stkcode, price=0, count=0, amount=0): """ 买入证券 params --------- stkcode:股票代码,string pricce:委托价格,int count:买入数量 amount:买入金额 """ jsonobj = utils.get_jdata(self._trading(stkcode, price, count, amount, 'B', 'buy')) res = True if jsonobj['result'] == 'true' else False return res def sell(self, stkcode, price=0, count=0, amount=0): """ 卖出证券 params --------- stkcode:股票代码,string pricce:委托价格,int count:卖出数量 amount:卖出金额 """ jsonobj = utils.get_jdata(self._trading(stkcode, price, count, amount, 'S', 'sell')) res = True if jsonobj['result'] == 'true' else False return res def _trading(self, stkcode, price, count, amount, tradeflag, tradetype): txtdata = self.s.get(vs.TRADE_CHECK_URL % (vs.P_TYPE['https'], vs.DOMAINS['csc'], vs.PAGES['tradecheck'], tradeflag, stkcode, tradetype, utils.nowtime_str())) jsonobj = utils.get_jdata(txtdata) list = jsonobj['returnList'][0] secuid = list['buysSecuid'] fundavl = list['fundavl'] stkname = list['stkname'] if secuid is not None: if tradeflag == 'B': buytype = vs.BUY count = count if count else amount // price // 100 * 100 else: buytype = vs.SELL count = count if count else amount // price tradeparams = dict( stkname = stkname, stkcode = stkcode, secuid = secuid, buytype = buytype, bsflag = tradeflag, maxstkqty = '', buycount = count, buyprice = price, _ = utils.nowtime_str() ) tradeResult = self.s.post(vs.TRADE_URL % (vs.P_TYPE['https'], vs.DOMAINS['csc'], vs.PAGES['trade']), params = tradeparams) return tradeResult return None def position(self): """ 获取持仓列表 return:DataFrame ---------------------- stkcode:证券代码 stkname:证券名称 stkqty :证券数量 stkavl :可用数量 lastprice:最新价格 costprice:成本价 income :参考盈亏(元) """ return self._get_position() def _get_position(self): self.s.headers.update(vs.AGENT) txtdata = self.s.get(vs.BASE_URL % (vs.P_TYPE['https'], vs.DOMAINS['csc'], vs.PAGES['position'])) jsonobj = utils.get_jdata(txtdata) df = pd.DataFrame(jsonobj['data'], columns=vs.POSITION_COLS) return df def entrust_list(self): """ 获取委托单列表 return:DataFrame ---------- ordersno:委托单号 stkcode:证券代码 stkname:证券名称 bsflagState:买卖标志 orderqty:委托数量 matchqty:成交数量 orderprice:委托价格 operdate:交易日期 opertime:交易时间 orderdate:下单日期 state:状态 """ txtdata = self.s.get(vs.ENTRUST_LIST_URL % (vs.P_TYPE['https'], vs.DOMAINS['csc'], vs.PAGES['entrustlist'], utils.nowtime_str())) jsonobj = utils.get_jdata(txtdata) df = pd.DataFrame(jsonobj['data'], columns=vs.ENTRUST_LIST_COLS) return df def deal_list(self, begin=None, end=None): """ 获取成交列表 params ----------- begin:开始日期 YYYYMMDD end:结束日期 YYYYMMDD return: DataFrame ----------- ordersno:委托单号 matchcode:成交编号 trddate:交易日期 matchtime:交易时间 stkcode:证券代码 stkname:证券名称 bsflagState:买卖标志 orderprice:委托价格 matchprice:成交价格 orderqty:委托数量 matchqty:成交数量 matchamt:成交金额 """ daterange = '' if (begin is None) & (end is None): selecttype = 'intraDay' else: daterange = vs.DEAL_DATE_RANGE % (begin, end) selecttype = 'all' txtdata = self.s.get(vs.DEAL_LIST_URL % (vs.P_TYPE['https'], vs.DOMAINS['csc'], vs.PAGES['deallist'], selecttype, daterange, utils.nowtime_str())) jsonobj = utils.get_jdata(txtdata) df = pd.DataFrame(jsonobj['data'], columns=vs.DEAL_LIST_COLS) return df def cancel(self, ordersno='', orderdate=''): """ 撤单 params ----------- ordersno:委托单号,多个以逗号分隔,e.g. 1866,1867 orderdata:委托日期 YYYYMMDD,多个以逗号分隔,对应委托单好 return ------------ string """ if (ordersno != '') & (orderdate != ''): params = dict( ordersno = ordersno, orderdate = orderdate, _ = utils.nowtime_str() ) result = self.s.post(vs.CANCEL_URL % (vs.P_TYPE['https'], vs.DOMAINS['csc'], vs.PAGES['cancel']), params = params) jsonobj = utils.get_jdata(result.text) return jsonobj['msgMap']['ResultSucess'] return None def baseinfo(self): """ 获取帐户基本信息 return: Series ------------- fundid:帐户ID gpsz: 股票市值 fundvalue:基金市值 jihelicai:集合理财 fundbal:帐户余额 marketvalue:总资产 fundavl:可用余额 daixiao:代销份额 otc:OTC份额 """ return self._get_baseinfo() def _get_baseinfo(self): self.s.headers.update(vs.AGENT) txtdata = self.s.get(vs.BASE_URL % (vs.P_TYPE['https'], vs.DOMAINS['csc'], vs.PAGES['baseInfo'])) jsonobj = utils.get_jdata(txtdata) stkdata = jsonobj['data']['moneytype0'] stkdata['fundid'] = jsonobj['fundid'] return pd.Series(stkdata) def check_login_status(self, return_data): if hasattr(return_data, 'get') and return_data.get('error_no') == '-1': raise NotLoginError class NotLoginError(Exception): def __init__(self, result=None): super(NotLoginError, self).__init__() self.result = result def heartbeat(self): return self.baseinfo ================================================ FILE: tushare/trader/utils.py ================================================ #!/usr/bin/env python # -*- coding:utf-8 -*- ''' Created on 2016年10月1日 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn ''' import json import time import six from tushare.trader import vars as vs def nowtime_str(): return time.time() * 1000 def get_jdata(txtdata): txtdata = txtdata.content if six.PY3: txtdata = txtdata.decode('utf-8') jsonobj = json.loads(txtdata) return jsonobj def get_vcode(broker, res): from PIL import Image import pytesseract as pt import io if broker == 'csc': imgdata = res.content img = Image.open(io.BytesIO(imgdata)) vcode = pt.image_to_string(img) return vcode ================================================ FILE: tushare/trader/vars.py ================================================ # -*- coding:utf-8 -*- """ Created on 2016/09/31 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ P_TYPE = {'http': 'http://', 'https': 'https://'} DOMAINS = { 'csc': 'newetrade.csc108.com', 'cscsh': 'newetradesh.csc108.com', 'cscbj': 'newetradebj.csc108.com' } PAGES = { 'csclogin': 'loginMain.jspx', 'baseInfo': 'main_zcgy_List.json', 'position': 'main_ccgp_list.json', 'tradecheck': 'securitybuys.json', 'trade': 'tradingTransSubmit.json', 'entrustlist': 'securityOrdersCancelListInit.json', 'cancel': 'securityOrdersCancelSubmit.json', 'deallist': 'securityBuysFindListInit.json', 'vimg': 'image.jsp' } AGENT = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko'} POSITION_COLS = ['stkcode', 'stkname', 'stkqty', 'stkavl', 'lastprice', 'costprice', 'income'] CSC_PREFIX = '%s%s/login/%s' CSC_LOGIN_ACTION = '%s%s/j_spring_security_check' BASE_URL = '%s%s/mainHomePage/%s' TRADE_CHECK_URL = '%s%s/trading/%s?bsflag=%s&stkcode=%s&buyflag=%s&price=0&_=%d' ENTRUST_LIST_URL = '%s%s/securityfind/%s?_=%s' V_CODE_URL = '%s%s/commons/%s' ENTRUST_LIST_COLS = ['ordersno', 'stkcode', 'stkname', 'bsflagState', 'orderqty', 'matchqty', 'orderprice', 'operdate', 'opertime', 'orderdate', 'state'] TRADE_URL = '%s%s/trading/%s' CANCEL_URL = '%s%s/securityfind/%s' DEAL_LIST_URL = '%s%s/securityfind/%s?selectType=%s%s&_=%d' DEAL_DATE_RANGE = '&beginDate=%s&endDate=%s' DEAL_LIST_COLS = ['ordersno', 'matchcode', 'trddate', 'matchtime', 'stkcode', 'stkname', 'bsflagState', 'orderprice', 'matchprice', 'orderqty', 'matchqty', 'matchamt'] BUY = '买入' SELL = '卖出' ================================================ FILE: tushare/util/__init__.py ================================================ ================================================ FILE: tushare/util/common.py ================================================ #!/usr/bin/env python # -*- coding:utf-8 -*- """ Created on 2015年7月31日 @author: Jimmy Liu @group: DataYes Data.dept @QQ:52799046 """ try: from httplib import HTTPSConnection except ImportError: from http.client import HTTPSConnection import urllib from tushare.util import vars as vs from tushare.stock import cons as ct class Client: httpClient = None def __init__(self , token): self.token = token self.httpClient = HTTPSConnection(vs.HTTP_URL, vs.HTTP_PORT) def __del__( self ): if self.httpClient is not None: self.httpClient.close() def encodepath(self, path): start = 0 n = len(path) re = '' i = path.find('=', start) while i != -1 : re += path[start:i+1] start = i+1 i = path.find('&', start) if(i>=0): for j in range(start, i): if(path[j] > '~'): if ct.PY3: re += urllib.parse.quote(path[j]) else: re += urllib.quote(path[j]) else: re += path[j] re += '&' start = i+1 else: for j in range(start, n): if(path[j] > '~'): if ct.PY3: re += urllib.parse.quote(path[j]) else: re += urllib.quote(path[j]) else: re += path[j] start = n i = path.find('=', start) return re def init(self, token): self.token = token def getData(self, path): result = None path='/data/v1' + path path=self.encodepath(path) try: self.httpClient.request('GET', path, headers = {"Authorization": "Bearer " + self.token}) response = self.httpClient.getresponse() if response.status == vs.HTTP_OK: result = response.read() else: result = response.read() if(path.find('.csv?') != -1): result=result.decode('GBK').encode('utf-8') return response.status, result except Exception as e: raise e return -1, result ================================================ FILE: tushare/util/conns.py ================================================ # -*- coding:utf-8 -*- """ connection for api Created on 2017/09/23 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ from pytdx.hq import TdxHq_API from pytdx.exhq import TdxExHq_API from tushare.stock import cons as ct def api(retry_count=3): for _ in range(retry_count): try: api = TdxHq_API(heartbeat=True) api.connect(ct._get_server(), ct.T_PORT) except Exception as e: print(e) else: return api raise IOError(ct.NETWORK_URL_ERROR_MSG) def xapi(retry_count=3): for _ in range(retry_count): try: api = TdxExHq_API(heartbeat=True) api.connect(ct._get_xserver(), ct.X_PORT) except Exception as e: print(e) else: return api raise IOError(ct.NETWORK_URL_ERROR_MSG) def xapi_x(retry_count=3): for _ in range(retry_count): try: api = TdxExHq_API(heartbeat=True) api.connect(ct._get_xxserver(), ct.X_PORT) except Exception as e: print(e) else: return api raise IOError(ct.NETWORK_URL_ERROR_MSG) def get_apis(): return api(), xapi() def close_apis(conn): api, xapi = conn try: api.disconnect() xapi.disconnect() except Exception as e: print(e) ================================================ FILE: tushare/util/dateu.py ================================================ # -*- coding:utf-8 -*- import datetime import time import pandas as pd from tushare.stock import cons as ct def year_qua(date): mon = date[5:7] mon = int(mon) return[date[0:4], _quar(mon)] def _quar(mon): if mon in [1, 2, 3]: return '1' elif mon in [4, 5, 6]: return '2' elif mon in [7, 8, 9]: return '3' elif mon in [10, 11, 12]: return '4' else: return None def today(): day = datetime.datetime.today().date() return str(day) def get_year(): year = datetime.datetime.today().year return year def get_month(): month = datetime.datetime.today().month return month def get_hour(): return datetime.datetime.today().hour def today_last_year(): lasty = datetime.datetime.today().date() + datetime.timedelta(-365) return str(lasty) def day_last_week(days=-7): lasty = datetime.datetime.today().date() + datetime.timedelta(days) return str(lasty) def get_now(): return time.strftime('%Y-%m-%d %H:%M:%S') def int2time(timestamp): datearr = datetime.datetime.utcfromtimestamp(timestamp) timestr = datearr.strftime("%Y-%m-%d %H:%M:%S") return timestr def diff_day(start=None, end=None): d1 = datetime.datetime.strptime(end, '%Y-%m-%d') d2 = datetime.datetime.strptime(start, '%Y-%m-%d') delta = d1 - d2 return delta.days def get_quarts(start, end): idx = pd.period_range('Q'.join(year_qua(start)), 'Q'.join(year_qua(end)), freq='Q-JAN') return [str(d).split('Q') for d in idx][::-1] def trade_cal(): ''' 交易日历 isOpen=1是交易日,isOpen=0为休市 ''' df = pd.read_csv(ct.ALL_CAL_FILE) return df def is_holiday(date): ''' 判断是否为交易日,返回True or False ''' df = trade_cal() holiday = df[df.isOpen == 0]['calendarDate'].values if isinstance(date, str): today = datetime.datetime.strptime(date, '%Y-%m-%d') if today.isoweekday() in [6, 7] or str(date) in holiday: return True else: return False def last_tddate(): today = datetime.datetime.today().date() today=int(today.strftime("%w")) if today == 0: return day_last_week(-2) else: return day_last_week(-1) def tt_dates(start='', end=''): startyear = int(start[0:4]) endyear = int(end[0:4]) dates = [d for d in range(startyear, endyear+1, 2)] return dates def _random(n=13): from random import randint start = 10**(n-1) end = (10**n)-1 return str(randint(start, end)) def get_q_date(year=None, quarter=None): dt = {'1': '-03-31', '2': '-06-30', '3': '-09-30', '4': '-12-31'} return '%s%s'%(str(year), dt[str(quarter)]) ================================================ FILE: tushare/util/formula.py ================================================ #!/usr/bin/python # -*- coding: utf-8 -*- import numpy as np import pandas as pd def EMA(DF, N): return pd.Series.ewm(DF, span=N, min_periods=N - 1, adjust=True).mean() def MA(DF, N): return pd.Series.rolling(DF, N).mean() def SMA(DF, N, M): DF = DF.fillna(0) z = len(DF) var = np.zeros(z) var[0] = DF[0] for i in range(1, z): var[i] = (DF[i] * M + var[i - 1] * (N - M)) / N for i in range(z): DF[i] = var[i] return DF def ATR(DF, N): C = DF['close'] H = DF['high'] L = DF['low'] TR1 = MAX(MAX((H - L), ABS(REF(C, 1) - H)), ABS(REF(C, 1) - L)) atr = MA(TR1, N) return atr def HHV(DF, N): return pd.Series.rolling(DF, N).max() def LLV(DF, N): return pd.Series.rolling(DF, N).min() def SUM(DF, N): return pd.Series.rolling(DF, N).sum() def ABS(DF): return abs(DF) def MAX(A, B): var = IF(A > B, A, B) return var def MIN(A, B): var = IF(A < B, A, B) return var def IF(COND, V1, V2): var = np.where(COND, V1, V2) for i in range(len(var)): V1[i] = var[i] return V1 def REF(DF, N): var = DF.diff(N) var = DF - var return var def STD(DF, N): return pd.Series.rolling(DF, N).std() def MACD(DF, FAST, SLOW, MID): EMAFAST = EMA(DF, FAST) EMASLOW = EMA(DF, SLOW) DIFF = EMAFAST - EMASLOW DEA = EMA(DIFF, MID) MACD = (DIFF - DEA) * 2 DICT = {'DIFF': DIFF, 'DEA': DEA, 'MACD': MACD} VAR = pd.DataFrame(DICT) return VAR def KDJ(DF, N, M1, M2): C = DF['close'] H = DF['high'] L = DF['low'] RSV = (C - LLV(L, N)) / (HHV(H, N) - LLV(L, N)) * 100 K = SMA(RSV, M1, 1) D = SMA(K, M2, 1) J = 3 * K - 2 * D DICT = {'KDJ_K': K, 'KDJ_D': D, 'KDJ_J': J} VAR = pd.DataFrame(DICT) return VAR def OSC(DF, N, M): # 变动速率线 C = DF['close'] OS = (C - MA(C, N)) * 100 MAOSC = EMA(OS, M) DICT = {'OSC': OS, 'MAOSC': MAOSC} VAR = pd.DataFrame(DICT) return VAR def BBI(DF, N1, N2, N3, N4): # 多空指标 C = DF['close'] bbi = (MA(C, N1) + MA(C, N2) + MA(C, N3) + MA(C, N4)) / 4 DICT = {'BBI': bbi} VAR = pd.DataFrame(DICT) return VAR def BBIBOLL(DF, N1, N2, N3, N4, N, M): # 多空布林线 bbiboll = BBI(DF, N1, N2, N3, N4) UPER = bbiboll + M * STD(bbiboll, N) DOWN = bbiboll - M * STD(bbiboll, N) DICT = {'BBIBOLL': bbiboll, 'UPER': UPER, 'DOWN': DOWN} VAR = pd.DataFrame(DICT) return VAR def PBX(DF, N1, N2, N3, N4, N5, N6): # 瀑布线 C = DF['close'] PBX1 = (EMA(C, N1) + EMA(C, 2 * N1) + EMA(C, 4 * N1)) / 3 PBX2 = (EMA(C, N2) + EMA(C, 2 * N2) + EMA(C, 4 * N2)) / 3 PBX3 = (EMA(C, N3) + EMA(C, 2 * N3) + EMA(C, 4 * N3)) / 3 PBX4 = (EMA(C, N4) + EMA(C, 2 * N4) + EMA(C, 4 * N4)) / 3 PBX5 = (EMA(C, N5) + EMA(C, 2 * N5) + EMA(C, 4 * N5)) / 3 PBX6 = (EMA(C, N6) + EMA(C, 2 * N6) + EMA(C, 4 * N6)) / 3 DICT = {'PBX1': PBX1, 'PBX2': PBX2, 'PBX3': PBX3, 'PBX4': PBX4, 'PBX5': PBX5, 'PBX6': PBX6} VAR = pd.DataFrame(DICT) return VAR def BOLL(DF, N): # 布林线 C = DF['close'] boll = MA(C, N) UB = boll + 2 * STD(C, N) LB = boll - 2 * STD(C, N) DICT = {'BOLL': boll, 'UB': UB, 'LB': LB} VAR = pd.DataFrame(DICT) return VAR def ROC(DF, N, M): # 变动率指标 C = DF['close'] roc = 100 * (C - REF(C, N)) / REF(C, N) MAROC = MA(roc, M) DICT = {'ROC': roc, 'MAROC': MAROC} VAR = pd.DataFrame(DICT) return VAR def MTM(DF, N, M): # 动量线 C = DF['close'] mtm = C - REF(C, N) MTMMA = MA(mtm, M) DICT = {'MTM': mtm, 'MTMMA': MTMMA} VAR = pd.DataFrame(DICT) return VAR def MFI(DF, N): # 资金指标 C = DF['close'] H = DF['high'] L = DF['low'] VOL = DF['vol'] TYP = (C + H + L) / 3 V1 = SUM(IF(TYP > REF(TYP, 1), TYP * VOL, 0), N) / \ SUM(IF(TYP < REF(TYP, 1), TYP * VOL, 0), N) mfi = 100 - (100 / (1 + V1)) DICT = {'MFI': mfi} VAR = pd.DataFrame(DICT) return VAR def SKDJ(DF, N, M): CLOSE = DF['close'] LOWV = LLV(DF['low'], N) HIGHV = HHV(DF['high'], N) RSV = EMA((CLOSE - LOWV) / (HIGHV - LOWV) * 100, M) K = EMA(RSV, M) D = MA(K, M) DICT = {'SKDJ_K': K, 'SKDJ_D': D} VAR = pd.DataFrame(DICT) return VAR def WR(DF, N, N1): # 威廉指标 HIGH = DF['high'] LOW = DF['low'] CLOSE = DF['close'] WR1 = 100 * (HHV(HIGH, N) - CLOSE) / (HHV(HIGH, N) - LLV(LOW, N)) WR2 = 100 * (HHV(HIGH, N1) - CLOSE) / (HHV(HIGH, N1) - LLV(LOW, N1)) DICT = {'WR1': WR1, 'WR2': WR2} VAR = pd.DataFrame(DICT) return VAR def BIAS(DF, N1, N2, N3): # 乖离率 CLOSE = DF['close'] BIAS1 = (CLOSE - MA(CLOSE, N1)) / MA(CLOSE, N1) * 100 BIAS2 = (CLOSE - MA(CLOSE, N2)) / MA(CLOSE, N2) * 100 BIAS3 = (CLOSE - MA(CLOSE, N3)) / MA(CLOSE, N3) * 100 DICT = {'BIAS1': BIAS1, 'BIAS2': BIAS2, 'BIAS3': BIAS3} VAR = pd.DataFrame(DICT) return VAR def RSI(DF, N1, N2, N3): # 相对强弱指标RSI1:SMA(MAX(CLOSE-LC,0),N1,1)/SMA(ABS(CLOSE-LC),N1,1)*100; CLOSE = DF['close'] LC = REF(CLOSE, 1) RSI1 = SMA(MAX(CLOSE - LC, 0), N1, 1) / SMA(ABS(CLOSE - LC), N1, 1) * 100 RSI2 = SMA(MAX(CLOSE - LC, 0), N2, 1) / SMA(ABS(CLOSE - LC), N2, 1) * 100 RSI3 = SMA(MAX(CLOSE - LC, 0), N3, 1) / SMA(ABS(CLOSE - LC), N3, 1) * 100 DICT = {'RSI1': RSI1, 'RSI2': RSI2, 'RSI3': RSI3} VAR = pd.DataFrame(DICT) return VAR def ADTM(DF, N, M): # 动态买卖气指标 HIGH = DF['high'] LOW = DF['low'] OPEN = DF['open'] DTM = IF(OPEN <= REF(OPEN, 1), 0, MAX( (HIGH - OPEN), (OPEN - REF(OPEN, 1)))) DBM = IF(OPEN >= REF(OPEN, 1), 0, MAX((OPEN - LOW), (OPEN - REF(OPEN, 1)))) STM = SUM(DTM, N) SBM = SUM(DBM, N) ADTM1 = IF(STM > SBM, (STM - SBM) / STM, IF(STM == SBM, 0, (STM - SBM) / SBM)) MAADTM = MA(ADTM1, M) DICT = {'ADTM': ADTM1, 'MAADTM': MAADTM} VAR = pd.DataFrame(DICT) return VAR def DDI(DF, N, N1, M, M1): # 方向标准离差指数 H = DF['high'] L = DF['low'] DMZ = IF((H + L) <= (REF(H, 1) + REF(L, 1)), 0, MAX(ABS(H - REF(H, 1)), ABS(L - REF(L, 1)))) DMF = IF((H + L) >= (REF(H, 1) + REF(L, 1)), 0, MAX(ABS(H - REF(H, 1)), ABS(L - REF(L, 1)))) DIZ = SUM(DMZ, N) / (SUM(DMZ, N) + SUM(DMF, N)) DIF = SUM(DMF, N) / (SUM(DMF, N) + SUM(DMZ, N)) ddi = DIZ - DIF ADDI = SMA(ddi, N1, M) AD = MA(ADDI, M1) DICT = {'DDI': ddi, 'ADDI': ADDI, 'AD': AD} VAR = pd.DataFrame(DICT) return VAR ================================================ FILE: tushare/util/mailmerge.py ================================================ from copy import deepcopy import re from lxml.etree import Element from lxml import etree from zipfile import ZipFile, ZIP_DEFLATED NAMESPACES = { 'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main', 'mc': 'http://schemas.openxmlformats.org/markup-compatibility/2006', 'ct': 'http://schemas.openxmlformats.org/package/2006/content-types', } CONTENT_TYPES_PARTS = ( 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml', ) CONTENT_TYPE_SETTINGS = 'application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml' class MailMerge(object): def __init__(self, file, remove_empty_tables=False): self.zip = ZipFile(file) self.parts = {} self.settings = None self._settings_info = None self.remove_empty_tables = remove_empty_tables content_types = etree.parse(self.zip.open('[Content_Types].xml')) for file in content_types.findall('{%(ct)s}Override' % NAMESPACES): type = file.attrib['ContentType' % NAMESPACES] if type in CONTENT_TYPES_PARTS: zi, self.parts[zi] = self.__get_tree_of_file(file) elif type == CONTENT_TYPE_SETTINGS: self._settings_info, self.settings = self.__get_tree_of_file(file) to_delete = [] r = re.compile(r' MERGEFIELD +"?([^ ]+?)"? +(|\\\* MERGEFORMAT )', re.I) for part in self.parts.values(): for parent in part.findall('.//{%(w)s}fldSimple/..' % NAMESPACES): for idx, child in enumerate(parent): if child.tag != '{%(w)s}fldSimple' % NAMESPACES: continue instr = child.attrib['{%(w)s}instr' % NAMESPACES] m = r.match(instr) if m is None: continue parent[idx] = Element('MergeField', name=m.group(1)) for parent in part.findall('.//{%(w)s}instrText/../..' % NAMESPACES): children = list(parent) fields = zip( [children.index(e) for e in parent.findall('{%(w)s}r/{%(w)s}fldChar[@{%(w)s}fldCharType="begin"]/..' % NAMESPACES)], [children.index(e) for e in parent.findall('{%(w)s}r/{%(w)s}fldChar[@{%(w)s}fldCharType="end"]/..' % NAMESPACES)], [e for e in parent.findall('{%(w)s}r/{%(w)s}instrText' % NAMESPACES)] ) for idx_begin, idx_end, instr in fields: m = r.match(instr.text) if m is None: continue parent[idx_begin] = Element('MergeField', name=m.group(1)) # use this so we know *where* to put the replacement instr.tag = 'MergeText' block = instr.getparent() # append the other tags in the w:r block too parent[idx_begin].extend(list(block)) to_delete += [(parent, parent[i + 1]) for i in range(idx_begin, idx_end)] for parent, child in to_delete: parent.remove(child) # Remove mail merge settings to avoid error messages when opening document in Winword if self.settings: settings_root = self.settings.getroot() mail_merge = settings_root.find('{%(w)s}mailMerge' % NAMESPACES) if mail_merge is not None: settings_root.remove(mail_merge) def __get_tree_of_file(self, file): fn = file.attrib['PartName' % NAMESPACES].split('/', 1)[1] zi = self.zip.getinfo(fn) return zi, etree.parse(self.zip.open(zi)) def write(self, file): # Replace all remaining merge fields with empty values for field in self.get_merge_fields(): self.merge(**{field: ''}) output = ZipFile(file, 'w', ZIP_DEFLATED) for zi in self.zip.filelist: if zi in self.parts: xml = etree.tostring(self.parts[zi].getroot()) output.writestr(zi.filename, xml) elif zi == self._settings_info: xml = etree.tostring(self.settings.getroot()) output.writestr(zi.filename, xml) else: output.writestr(zi.filename, self.zip.read(zi)) output.close() def get_merge_fields(self, parts=None): if not parts: parts = self.parts.values() fields = set() for part in parts: for mf in part.findall('.//MergeField'): fields.add(mf.attrib['name']) return fields def merge_pages(self, replacements): """ Duplicate template page. Creates a copy of the template for each item in the list, does a merge, and separates the them by page breaks. """ for part in self.parts.values(): root = part.getroot() tag = root.tag if tag == '{%(w)s}ftr' % NAMESPACES or tag == '{%(w)s}hdr' % NAMESPACES: continue children = [] for child in root: root.remove(child) children.append(child) for i, repl in enumerate(replacements): # Add page break in between replacements if i > 0: pagebreak = Element('{%(w)s}br' % NAMESPACES) pagebreak.attrib['{%(w)s}type' % NAMESPACES] = 'page' root.append(pagebreak) parts = [] for child in children: child_copy = deepcopy(child) root.append(child_copy) parts.append(child_copy) self.merge(parts, **repl) def merge(self, parts=None, **replacements): if not parts: parts = self.parts.values() for field, replacement in replacements.items(): if isinstance(replacement, list): self.merge_rows(field, replacement) else: for part in parts: self.__merge_field(part, field, replacement) def __merge_field(self, part, field, text): for mf in part.findall('.//MergeField[@name="%s"]' % field): children = list(mf) mf.clear() # clear away the attributes mf.tag = '{%(w)s}r' % NAMESPACES mf.extend(children) text = text if text is None else str(text) nodes = [] # preserve new lines in replacement text text = text or '' # text might be None text_parts = text.replace('\r', '').split('\n') for i, text_part in enumerate(text_parts): text_node = Element('{%(w)s}t' % NAMESPACES) text_node.text = text_part nodes.append(text_node) # if not last node add new line node if i < (len(text_parts) - 1): nodes.append(Element('{%(w)s}br' % NAMESPACES)) ph = mf.find('MergeText') if ph is not None: # add text nodes at the exact position where # MergeText was found index = mf.index(ph) for node in reversed(nodes): mf.insert(index, node) mf.remove(ph) else: mf.extend(nodes) def merge_rows(self, anchor, rows): table, idx, template = self.__find_row_anchor(anchor) if table is not None: if len(rows) > 0: del table[idx] for i, row_data in enumerate(rows): row = deepcopy(template) self.merge([row], **row_data) table.insert(idx + i, row) else: # if there is no data for a given table # we check whether table needs to be removed if self.remove_empty_tables: parent = table.getparent() parent.remove(table) def __find_row_anchor(self, field, parts=None): if not parts: parts = self.parts.values() for part in parts: for table in part.findall('.//{%(w)s}tbl' % NAMESPACES): for idx, row in enumerate(table): if row.find('.//MergeField[@name="%s"]' % field) is not None: return table, idx, row return None, None, None ================================================ FILE: tushare/util/netbase.py ================================================ # -*- coding:utf-8 -*- try: from urllib.request import urlopen, Request except ImportError: from urllib2 import urlopen, Request class Client(object): def __init__(self, url=None, ref=None, cookie=None): self._ref = ref self._cookie = cookie self._url = url self._setOpener() def _setOpener(self): request = Request(self._url) request.add_header("Accept-Language", "en-US,en;q=0.5") request.add_header("Connection", "keep-alive") # request.add_header('Referer', self._ref) if self._cookie is not None: request.add_header("Cookie", self._cookie) request.add_header("User-Agent", 'Mozilla/5.0 (Windows NT 6.1; rv:37.0) Gecko/20100101 Firefox/37.0') self._request = request def gvalue(self): values = urlopen(self._request, timeout = 10).read() return values ================================================ FILE: tushare/util/store.py ================================================ # -*- coding:utf-8 -*- """ Created on 2015/02/04 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ import pandas as pd import tushare as ts from pandas import compat import os class Store(object): def __init__(self, data=None, name=None, path=None): if isinstance(data, pd.DataFrame): self.data = data else: raise RuntimeError('data type is incorrect') self.name = name self.path = path def save_as(self, name, path, to='csv'): if name is None: name = self.name if path is None: path = self.path file_path = '%s%s%s.%s' if isinstance(name, compat.string_types) and name is not '': if (path is None) or (path == ''): file_path = '.'.join([name, to]) else: try: if os.path.exists(path) is False: os.mkdir(path) file_path = file_path%(path, '/', name, to) except: pass else: print('input error') ================================================ FILE: tushare/util/upass.py ================================================ # -*- coding:utf-8 -*- """ Created on 2015/08/24 @author: Jimmy Liu @group : waditu @contact: jimmysoa@sina.cn """ import pandas as pd import os from tushare.stock import cons as ct BK = 'bk' def set_token(token): df = pd.DataFrame([token], columns=['token']) user_home = os.path.expanduser('~') fp = os.path.join(user_home, ct.TOKEN_F_P) df.to_csv(fp, index=False) def get_token(): user_home = os.path.expanduser('~') fp = os.path.join(user_home, ct.TOKEN_F_P) if os.path.exists(fp): df = pd.read_csv(fp) return str(df.ix[0]['token']) else: print(ct.TOKEN_ERR_MSG) return None def set_broker(broker='', user='', passwd=''): df = pd.DataFrame([[broker, user, passwd]], columns=['broker', 'user', 'passwd'], dtype=object) if os.path.exists(BK): all = pd.read_csv(BK, dtype=object) if (all[all.broker == broker]['user']).any(): all = all[all.broker != broker] all = all.append(df, ignore_index=True) all.to_csv(BK, index=False) else: df.to_csv(BK, index=False) def get_broker(broker=''): if os.path.exists(BK): df = pd.read_csv(BK, dtype=object) if broker == '': return df else: return df[df.broker == broker] else: return None def remove_broker(): os.remove(BK) ================================================ FILE: tushare/util/vars.py ================================================ # -*- coding:utf-8 -*- import sys PY3 = (sys.version_info[0] >= 3) HTTP_OK = 200 HTTP_AUTHORIZATION_ERROR = 401 HTTP_URL = 'api.wmcloud.com' HTTP_PORT = 443 BOND = '/api/bond/getBond.csv?secID=%s&ticker=%s&field=%s' BONDCF = '/api/bond/getBondCf.csv?secID=%s&ticker=%s&beginDate=%s&cashTypeCD=%s&endDate=%s&field=%s' BONDCOUPON = '/api/bond/getBondCoupon.csv?secID=%s&ticker=%s&field=%s' BONDGUAR = '/api/bond/getBondGuar.csv?secID=%s&ticker=%s&guarModeCD=%s&field=%s' BONDISSUE = '/api/bond/getBondIssue.csv?secID=%s&ticker=%s&raiseModeCD=%s&field=%s' BONDOPTION = '/api/bond/getBondOption.csv?secID=%s&ticker=%s&field=%s' BONDRATING = '/api/bond/getBondRating.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' EQU = '/api/equity/getEqu.csv?equTypeCD=%s&secID=%s&ticker=%s&listStatusCD=%s&field=%s' EQUALLOT = '/api/equity/getEquAllot.csv?isAllotment=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' EQUDIV = '/api/equity/getEquDiv.csv?eventProcessCD=%s&exDivDate=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' EQUINDUSTRY = '/api/equity/getEquIndustry.csv?industry=%s&industryID=%s&industryVersionCD=%s&secID=%s&ticker=%s&intoDate=%s&field=%s' EQUIPO = '/api/equity/getEquIPO.csv?eventProcessCD=%s&secID=%s&ticker=%s&field=%s' EQUREF = '/api/equity/getEquRef.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&eventProcessCD=%s&field=%s' EQURETUD = '/api/equity/getEquRetud.csv?listStatusCD=%s&secID=%s&ticker=%s&beginDate=%s&dailyReturnNoReinvLower=%s&dailyReturnNoReinvUpper=%s&dailyReturnReinvLower=%s&dailyReturnReinvUpper=%s&endDate=%s&isChgPctl=%s&field=%s' EQUSPLITS = '/api/equity/getEquSplits.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' FUTU = '/api/future/getFutu.csv?exchangeCD=%s&secID=%s&ticker=%s&contractObject=%s&field=%s' FUTUCONVF = '/api/future/getFutuConvf.csv?secID=%s&ticker=%s&field=%s' GUARRATING = '/api/bond/getGuarRating.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' IDX = '/api/idx/getIdx.csv?secID=%s&ticker=%s&field=%s' IDXCONS = '/api/idx/getIdxCons.csv?secID=%s&ticker=%s&intoDate=%s&intoDate=%s&isNew=%s&field=%s' IDXWEIGHT = '/api/idx/getIdxCloseWeight.json?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' ISSUERRATING = '/api/bond/getIssuerRating.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' MKTEQUD = '/api/market/getMktEqud.csv?secID=%s&ticker=%s&tradeDate=%s&beginDate=%s&endDate=%s&field=%s' MKTFUTD = '/api/market/getMktFutd.csv?secID=%s&ticker=%s&tradeDate=%s&beginDate=%s&endDate=%s&field=%s' MKTIDXD = '/api/market/getMktIdxd.csv?indexID=%s&ticker=%s&tradeDate=%s&beginDate=%s&endDate=%s&field=%s' SECID = '/api/master/getSecID.csv?assetClass=%s&cnSpell=%s&partyID=%s&ticker=%s&field=%s' FUND = '/api/fund/getFund.csv?etfLof=%s&listStatusCd=%s&secID=%s&ticker=%s&category=%s&operationMode=%s&field=%s' FUNDNAV = '/api/fund/getFundNav.csv?dataDate=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' FUNDDIVM = '/api/fund/getFundDivm.csv?dataDate=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' FUNDDIV = '/api/fund/getFundDiv.csv?secID=%s&ticker=%s&adjustedType=%s&beginDate=%s&endDate=%s&field=%s' FUNDASSETS = '/api/fund/getFundAssets.csv?reportDate=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' FUNDHOLDINGS = '/api/fund/getFundHoldings.csv?reportDate=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&secType=%s&field=%s' FDMTBS = '/api/fundamental/getFdmtBS.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTBSBANK = '/api/fundamental/getFdmtBSBank.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTBSSECU = '/api/fundamental/getFdmtBSSecu.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTBSINDU = '/api/fundamental/getFdmtBSIndu.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTBSINSU = '/api/fundamental/getFdmtBSInsu.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTCF = '/api/fundamental/getFdmtCF.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTCFBANK = '/api/fundamental/getFdmtCFBank.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTCFSECU = '/api/fundamental/getFdmtCFSecu.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTCFINDU = '/api/fundamental/getFdmtCFIndu.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTCFINSU = '/api/fundamental/getFdmtCFInsu.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTIS = '/api/fundamental/getFdmtIS.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTISBANK = '/api/fundamental/getFdmtISBank.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTISSECU = '/api/fundamental/getFdmtISSecu.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTISINDU = '/api/fundamental/getFdmtISIndu.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTISINSU = '/api/fundamental/getFdmtISInsu.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTEE = '/api/fundamental/getFdmtEe.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' FDMTEF = '/api/fundamental/getFdmtEf.csv?reportType=%s&secID=%s&ticker=%s&beginDate=%s&endDate=%s&forecastType=%s&publishDateBegin=%s&publishDateEnd=%s&field=%s' TRADECAL = '/api/master/getTradeCal.csv?exchangeCD=%s&beginDate=%s&endDate=%s&field=%s' INDUSTRY = '/api/master/getIndustry.csv?industryVersion=%s&industryVersionCD=%s&industryLevel=%s&isNew=%s&field=%s' FSTTOTAL = '/api/equity/getFstTotal.csv?beginDate=%s&endDate=%s&exchangeCD=%s&field=%s' FSTDETAIL = '/api/equity/getFstDetail.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' MKTBLOCKD = '/api/market/getMktBlockd.csv?secID=%s&ticker=%s&tradeDate=%s&assetClass=%s&beginDate=%s&endDate=%s&field=%s' HKEQU = '/api/HKequity/getHKEqu.csv?listStatusCD=%s&secID=%s&ticker=%s&field=%s' HKEQUCA = '/api/HKequity/getHKEquCA.csv?secID=%s&ticker=%s&eventTypeCD=%s&field=%s' MKTREPOD = '/api/market/getMktRepod.csv?secID=%s&ticker=%s&tradeDate=%s&beginDate=%s&endDate=%s&field=%s' MKTBONDD = '/api/market/getMktBondd.csv?secID=%s&ticker=%s&tradeDate=%s&beginDate=%s&endDate=%s&field=%s' EQUSHARE = '/api/equity/getEquShare.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&partyID=%s&field=%s' REPO = '/api/bond/getRepo.csv?secID=%s&ticker=%s&field=%s' MKTHKEQUD = '/api/market/getMktHKEqud.csv?secID=%s&ticker=%s&tradeDate=%s&beginDate=%s&endDate=%s&field=%s' TICKRTSNAPSHOT = '/api/market/getTickRTSnapshot.csv?securityID=%s&field=%s' TICKRTSNAPSHOTINDEX = '/api/market/getTickRTSnapshotIndex.csv?securityID=%s&field=%s' FUTURETICKRTSNAPSHOT = '/api/market/getFutureTickRTSnapshot.csv?instrumentID=%s&field=%s' TICKRTINTRADAY = '/api/market/getTickRTIntraDay.csv?securityID=%s&endTime=%s&startTime=%s&field=%s' BARRTINTRADAY = '/api/market/getBarRTIntraDay.csv?securityID=%s&endTime=%s&startTime=%s&field=%s' BARHISTONEDAY = '/api/market/getBarHistOneDay.csv?securityID=%s&date=%s&endTime=%s&startTime=%s&field=%s' BARHISTDAYRANGE = '/api/market/getBarHistDateRange.csv?securityID=%s&startDate=%s&&endDate=%s&field=%s' FUTURETICKRTINTRADAY = '/api/market/getFutureTickRTIntraDay.csv?instrumentID=%s&endTime=%s&startTime=%s&field=%s' FUTUREBARINDAY = '/api/market/getFutureBarHistOneDay.csv?instrumentID=%s&date=%s&field=%s' FUTUREBARDATERANGE = '/api/market/getFutureBarHistDateRange.csv?instrumentID=%s&startDate=%s&endDate=%s&field=%s' STOCKFACTORSONEDAY = '/api/market/getStockFactorsOneDay.csv?tradeDate=%s&secID=%s&ticker=%s&field=%s' STOCKFACTORSDATERANGE = '/api/market/getStockFactorsDateRange.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' MKTFUNDD = '/api/market/getMktFundd.csv?secID=%s&ticker=%s&tradeDate=%s&beginDate=%s&endDate=%s&field=%s' MKTFUTMTR = '/api/market/getMktFutMTR.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' MKTFUTMSR = '/api/market/getMktFutMSR.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' MKTFUTMLR = '/api/market/getMktFutMLR.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' FUNDETFPRLIST = '/api/fund/getFundETFPRList.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' FUNDETFCONS = '/api/fund/getFundETFCons.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' FUNDRATING = '/api/fund/getFundRating.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' CHINAMACRODATA = '/api/macro/getChinaMacroData.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINAMACROINFO = '/api/macro/getChinaMacroInfo.csv?indicID=%s&indicNameAbbr=%s&parentID=%s&field=%s' GLOBALMACRODATA = '/api/macro/getGlobalMacroData.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' GLOBALMACROINFO = '/api/macro/getGlobalMacroInfo.csv?indicID=%s&indicNameAbbr=%s&parentID=%s&field=%s' INDUSTRIALDATA = '/api/macro/getIndustrialData.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDUSTRIALINFO = '/api/macro/getIndustrialInfo.csv?indicID=%s&indicNameAbbr=%s&parentID=%s&field=%s' ECOMMERCEDATA = '/api/macro/getEcommerceData.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEINFO = '/api/macro/getEcommerceInfo.csv?indicID=%s&indicNameAbbr=%s&parentID=%s&field=%s' MKTMFUTD = '/api/market/getMktMFutd.csv?contractMark=%s&contractObject=%s&mainCon=%s&tradeDate=%s&endDate=%s&startDate=%s&field=%s' CHINADATAGDP = '/api/macro/getChinaDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAECI = '/api/macro/getChinaDataECI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAPMI = '/api/macro/getChinaDataPMI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATACCI = '/api/macro/getChinaDataCCI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAECONOMISTSBOOMINDEX = '/api/macro/getChinaDataEconomistsBoomIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAINDUSTRIALBUSINESSCLIMATEINDEX = '/api/macro/getChinaDataIndustrialBusinessClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATACPI = '/api/macro/getChinaDataCPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAPPI = '/api/macro/getChinaDataPPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAINDUSTRY = '/api/macro/getChinaDataIndustry.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATARETAILSALES = '/api/macro/getChinaDataRetailSales.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATARESIDENTINCOMEEXP = '/api/macro/getChinaDataResidentIncomeExp.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAFAI = '/api/macro/getChinaDataFAI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAREALESTATE = '/api/macro/getChinaDataRealEstate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAFOREIGNTRADE = '/api/macro/getChinaDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAFDI = '/api/macro/getChinaDataFDI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAMONEYSTATISTICS = '/api/macro/getChinaDataMoneyStatistics.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAALLSYSTEMFINANCING = '/api/macro/getChinaDataAllSystemFinancing.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATALENDINGDEPOSIT = '/api/macro/getChinaDataLendingDeposit.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATACREDITFUNDSTABLE = '/api/macro/getChinaDataCreditFundsTable.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAOPENMARKETOPERATION = '/api/macro/getChinaDataOpenMarketOperation.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAEXCHANGERATE = '/api/macro/getChinaDataExchangeRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAINTERESTRATELENDINGDEPOSIT = '/api/macro/getChinaDataInterestRateLendingDeposit.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAINTERESTRATESHIBOR = '/api/macro/getChinaDataInterestRateSHIBOR.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAINTERESTRATEINTERBANKREPO = '/api/macro/getChinaDataInterestRateInterbankRepo.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAFINANCE = '/api/macro/getChinaDataFinance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CHINADATAGOLDCLOSEPRICE = '/api/macro/getChinaDataGoldClosePrice.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' USDATAGDP = '/api/macro/getUSDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' USDATAFOREIGNTRADE = '/api/macro/getUSDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' USDATAPRICEINDEX = '/api/macro/getUSDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' USDATAEMPLOYMENTUNEMPLOYMENT = '/api/macro/getUSDataEmploymentUnemployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' USDATAINTERESTRATE = '/api/macro/getUSDataInterestRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' USDATAEXCHANGERATE = '/api/macro/getUSDataExchangeRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' USDATAMONEYSUPPLY = '/api/macro/getUSDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' USDATACONSUMERCREDIT = '/api/macro/getUSDataConsumerCredit.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' USDATACLIMATEINDEX = '/api/macro/getUSDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' USDATADURABLEGOODS = '/api/macro/getUSDataDurableGoods.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' USDATAREALESTATE = '/api/macro/getUSDataRealEstate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' USDATADOMESTICTRADE = '/api/macro/getUSDataDomesticTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' EUDATAGDP = '/api/macro/getEUDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' EUDATAFOREIGNTRADE = '/api/macro/getEUDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' EUDATAPRICEINDEX = '/api/macro/getEUDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' EUDATAEMPLOYMENTUNEMPLOYMENT = '/api/macro/getEUDataEmploymentUnemployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' EUDATAINTERESTRATE = '/api/macro/getEUDataInterestRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' EUDATAEXCHANGERATE = '/api/macro/getEUDataExchangeRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' EUDATABANKING = '/api/macro/getEUDataBanking.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' EUDATACLIMATEINDEX = '/api/macro/getEUDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' EUDATAINDUSTRY = '/api/macro/getEUDataIndustry.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' EUDATARETAIL = '/api/macro/getEUDataRetail.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SWITZERLANDDATAGDP = '/api/macro/getSwitzerlandDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SWITZERLANDDATAPRICEINDEX = '/api/macro/getSwitzerlandDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SWITZERLANDDATACLIMATEINDEX = '/api/macro/getSwitzerlandDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SWITZERLANDDATAMONEYSUPPLY = '/api/macro/getSwitzerlandDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SWEDENDATAGDP = '/api/macro/getSwedenDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SWEDENDATAPRICEINDEX = '/api/macro/getSwedenDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SWEDENDATAFOREIGNTRADE = '/api/macro/getSwedenDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' KOREADATAGDP = '/api/macro/getKoreaDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' KOREADATAPRICEINDEX = '/api/macro/getKoreaDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' KOREADATAEMPLOYMENTUNEMPLOYMENT = '/api/macro/getKoreaDataEmploymentUnemployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' KOREADATAINTERESTRATES = '/api/macro/getKoreaDataInterestRates.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' KOREADATAEXCHANGERATE = '/api/macro/getKoreaDataExchangeRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' KOREADATAMONEYSUPPLY = '/api/macro/getKoreaDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' KOREADATACLIMATEINDEX = '/api/macro/getKoreaDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' KOREADATA_EXTERNALDEBT = '/api/macro/getKoreaData_ExternalDebt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' KOREADATAINDUSTRYANDSERVICE = '/api/macro/getKoreaDataIndustryandService.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' KOREADATAREALESTATE = '/api/macro/getKoreaDataRealEstate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' AUSTRALIADATAGDP = '/api/macro/getAustraliaDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' AUSTRALIADATAFOREIGNTRADE = '/api/macro/getAustraliaDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' AUSTRALIADATAPRICEINDEX = '/api/macro/getAustraliaDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' AUSTRALIADATAEMPLOYMENT = '/api/macro/getAustraliaDataEmployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' AUSTRALIADATACLIMATEINDEX = '/api/macro/getAustraliaDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ITALYDATAGDP = '/api/macro/getItalyDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ITALYDATAPAYMENTSBALANCE = '/api/macro/getItalyDataPaymentsBalance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ITALYDATAPRICEINDEX = '/api/macro/getItalyDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ITALYDATAEMPLOYMENT = '/api/macro/getItalyDataEmployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ITALYDATAFINANCE = '/api/macro/getItalyDataFinance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ITALYDATACLIMATEINDEX = '/api/macro/getItalyDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ITALYDATAINTERESTRATE = '/api/macro/getItalyDataInterestRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SPAINDATAGDP = '/api/macro/getSpainDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SPAINDATAFOREIGNTRADE = '/api/macro/getSpainDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SPAINDATAPAYMENTSBALANCE = '/api/macro/getSpainDataPaymentsBalance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SPAINDATABANKING = '/api/macro/getSpainDataBanking.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SPAINDATATRANSPORTATION = '/api/macro/getSpainDataTransportation.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SPAINDATAENERGY = '/api/macro/getSpainDataEnergy.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SPAINDATAFINANCE = '/api/macro/getSpainDataFinance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CANADADATAGDP = '/api/macro/getCanadaDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CANADADATAPAYMENTSBALANCE = '/api/macro/getCanadaDataPaymentsBalance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CANADADATAFOREIGNTRADE = '/api/macro/getCanadaDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CANADADATAPRICEINDEX = '/api/macro/getCanadaDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CANADADATABANKING = '/api/macro/getCanadaDataBanking.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CANADADATAEMPLOYMENT = '/api/macro/getCanadaDataEmployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CANADADATAMANUFACTURING = '/api/macro/getCanadaDataManufacturing.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CANADADATAREALESTATE = '/api/macro/getCanadaDataRealEstate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CANADADATACLIMATEINDEX = '/api/macro/getCanadaDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HKDATAGDP = '/api/macro/getHKDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HKDATAFOREIGNTRADE = '/api/macro/getHKDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HKDATAPRICEINDEX = '/api/macro/getHKDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HKDATAFINANCE = '/api/macro/getHKDataFinance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HKDATABANKING = '/api/macro/getHKDataBanking.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HKDATAINDUSTRY = '/api/macro/getHKDataIndustry.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HKDATACONSUMPTION = '/api/macro/getHKDataConsumption.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HKDATATHROUGHPUT = '/api/macro/getHKDataThroughput.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HKDATAEMPLOYMENT = '/api/macro/getHKDataEmployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HKDATAINTERESTRATE = '/api/macro/getHKDataInterestRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HKDATAEXCHANGERATE = '/api/macro/getHKDataExchangeRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HKDATAREALESTATE = '/api/macro/getHKDataRealEstate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HKDATATOURISM = '/api/macro/getHKDataTourism.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDIADATAGDP = '/api/macro/getIndiaDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDIADATAPAYMENTSBALANCE = '/api/macro/getIndiaDataPaymentsBalance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDIADATAPRICEINDEX = '/api/macro/getIndiaDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDIADATATOURISM = '/api/macro/getIndiaDataTourism.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDIADATAENERGY = '/api/macro/getIndiaDataEnergy.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDIADATACLIMATEINDEX = '/api/macro/getIndiaDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDIADATABANKING = '/api/macro/getIndiaDataBanking.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDIADATAINDUSTRY = '/api/macro/getIndiaDataIndustry.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDIADATAFOREIGNTRADE = '/api/macro/getIndiaDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MALAYSIADATAGDP = '/api/macro/getMalaysiaDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MALAYSIADATAPAYMENTSBALANCE = '/api/macro/getMalaysiaDataPaymentsBalance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MALAYSIADATAFOREIGNTRADE = '/api/macro/getMalaysiaDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MALAYSIADATAPRICEINDEX = '/api/macro/getMalaysiaDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MALAYSIADATAEMPLOYMENT = '/api/macro/getMalaysiaDataEmployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MALAYSIADATAINDUSTRY = '/api/macro/getMalaysiaDataIndustry.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MALAYSIADATAFINANCE = '/api/macro/getMalaysiaDataFinance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MALAYSIADATAMONEYSUPPLY = '/api/macro/getMalaysiaDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MALAYSIADATAREALESTATE = '/api/macro/getMalaysiaDataRealEstate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDONESIADATAGDP = '/api/macro/getIndonesiaDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDONESIADATAPAYMENTSBALANCE = '/api/macro/getIndonesiaDataPaymentsBalance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDONESIADATAFOREIGNTRADE = '/api/macro/getIndonesiaDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDONESIADATAPRICEINDEX = '/api/macro/getIndonesiaDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDONESIADATAINDUSTRY = '/api/macro/getIndonesiaDataIndustry.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDONESIADATAFINANCE = '/api/macro/getIndonesiaDataFinance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDONESIADATABANKING = '/api/macro/getIndonesiaDataBanking.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDONESIADATASECURITY = '/api/macro/getIndonesiaDataSecurity.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INDONESIADATATOURISM = '/api/macro/getIndonesiaDataTourism.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TURKEYDATAGDP = '/api/macro/getTurkeyDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TURKEYDATAPAYMENTSBALANCE = '/api/macro/getTurkeyDataPaymentsBalance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TURKEYDATAFOREIGNTRADE = '/api/macro/getTurkeyDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TURKEYDATAPRICEINDEX = '/api/macro/getTurkeyDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TURKEYDATAEMPLOYMENT = '/api/macro/getTurkeyDataEmployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TURKEYDATAINDUSTRY = '/api/macro/getTurkeyDataIndustry.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TURKEYDATAFINANCE = '/api/macro/getTurkeyDataFinance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TURKEYDATAMONEYSUPPLY = '/api/macro/getTurkeyDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' THAILANDDATAGDP = '/api/macro/getThailandDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' THAILANDDATAPAYMENTSBALANCE = '/api/macro/getThailandDataPaymentsBalance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' THAILANDDATAFOREIGNTRADE = '/api/macro/getThailandDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' THAILANDDATAPRICEINDEX = '/api/macro/getThailandDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' THAILANDDATAEMPLOYMENT = '/api/macro/getThailandDataEmployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' THAILANDDATAINDUSTRY = '/api/macro/getThailandDataIndustry.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' THAILANDDATAFINANCE = '/api/macro/getThailandDataFinance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' THAILANDDATACLIMATEINDEX = '/api/macro/getThailandDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' THAILANDDATAMONEYSUPPLY = '/api/macro/getThailandDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UKDATAGDP = '/api/macro/getUKDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UKDATAFOREIGNTRADE = '/api/macro/getUKDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UKDATACPI = '/api/macro/getUKDataCPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UKDATARPI = '/api/macro/getUKDataRPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UKDATAEMPLOYMENT = '/api/macro/getUKDataEmployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UKDATAMONEYSUPPLY = '/api/macro/getUKDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UKDATACONSUMERCREDIT = '/api/macro/getUKDataConsumerCredit.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UKDATACLIMATEINDEX = '/api/macro/getUKDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UKDATAFINANCE = '/api/macro/getUKDataFinance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UKDATAINDUSTRIALPI = '/api/macro/getUKDataIndustrialPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UKDATAHOUSEPI = '/api/macro/getUKDataHousePI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UKDATAINTERESTRATES = '/api/macro/getUKDataInterestRates.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UKDATAEXCHANGERATE = '/api/macro/getUKDataExchangeRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' JAPANDATAGDP = '/api/macro/getJapanDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' JAPANDATAFOREIGNTRADE = '/api/macro/getJapanDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' JAPANDATACPI = '/api/macro/getJapanDataCPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' JAPANDATAEMPLOYMENT = '/api/macro/getJapanDataEmployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' JAPANDATAMONEYSUPPLY = '/api/macro/getJapanDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' JAPANDATACLIMATEINDEX = '/api/macro/getJapanDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' JAPANDATAINDUSTRIALPI = '/api/macro/getJapanDataIndustrialPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' JAPANDATAHOUSEPI = '/api/macro/getJapanDataHousePI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' JAPANDATAINTERESTRATES = '/api/macro/getJapanDataInterestRates.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' JAPANDATAEXCHANGERATE = '/api/macro/getJapanDataExchangeRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' GERMANYDATAGDP = '/api/macro/getGermanyDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' GERMANYDATAFOREIGNTRADE = '/api/macro/getGermanyDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' GERMANYDATACPI = '/api/macro/getGermanyDataCPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' GERMANYDATAPPI = '/api/macro/getGermanyDataPPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' GERMANYDATAIMPORTEXPORTPI = '/api/macro/getGermanyDataImportExportPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' GERMANYDATAEMPLOYMENT = '/api/macro/getGermanyDataEmployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' GERMANYDATAMONEYSUPPLY = '/api/macro/getGermanyDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' GERMANYDATACLIMATEINDEX = '/api/macro/getGermanyDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' GERMANYDATAFINANCE = '/api/macro/getGermanyDataFinance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' GERMANYDATAINDUSTRIALPI = '/api/macro/getGermanyDataIndustrialPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' GERMANYDATAREALESTATE = '/api/macro/getGermanyDataRealEstate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' GERMANYDATADOMESTICTRADE = '/api/macro/getGermanyDataDomesticTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' GERMANYDATAINTERESTRATES = '/api/macro/getGermanyDataInterestRates.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FRANCEDATAFINANCE = '/api/macro/getFranceDataFinance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FRANCEDATAGDP = '/api/macro/getFranceDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FRANCEDATAFOREIGNTRADE = '/api/macro/getFranceDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FRANCEDATACPI = '/api/macro/getFranceDataCPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FRANCEDATAPPI = '/api/macro/getFranceDataPPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FRANCEDATAIMPORTPI = '/api/macro/getFranceDataImportPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FRANCEDATAEMPLOYMENT = '/api/macro/getFranceDataEmployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FRANCEDATAMONEYSUPPLY = '/api/macro/getFranceDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FRANCEDATACLIMATEINDEX = '/api/macro/getFranceDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FRANCEDATAINDUSTRIALPI = '/api/macro/getFranceDataIndustrialPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FRANCEDATADOMESTICTRADE = '/api/macro/getFranceDataDomesticTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FRANCEDATAINTERESTRATES = '/api/macro/getFranceDataInterestRates.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATAGDP = '/api/macro/getTaiwanDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATAEXTERNALDEBT = '/api/macro/getTaiwanDataExternalDebt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATAFOREIGNTRADE = '/api/macro/getTaiwanDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATACPI = '/api/macro/getTaiwanDataCPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATAIMPORTEXPORTPI = '/api/macro/getTaiwanDataImportExportPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATAEMPLOYMENT = '/api/macro/getTaiwanDataEmployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATAMONEYSUPPLY = '/api/macro/getTaiwanDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATALENDINGDEPOSIT = '/api/macro/getTaiwanDataLendingDeposit.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATARESERVEFUND = '/api/macro/getTaiwanDataReserveFund.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATACLIMATEINDEX = '/api/macro/getTaiwanDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATAFINANCE = '/api/macro/getTaiwanDataFinance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATAINDUSTRIALPI = '/api/macro/getTaiwanDataIndustrialPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATAREALESTATE = '/api/macro/getTaiwanDataRealEstate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATATOURISM = '/api/macro/getTaiwanDataTourism.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATACROSSSTRAITTRADE = '/api/macro/getTaiwanDataCrossStraitTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATABUSINESSANDECONOMY = '/api/macro/getTaiwanDataBusinessandEconomy.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATAINTERESTRATES = '/api/macro/getTaiwanDataInterestRates.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TAIWANDATAEXCHANGERATE = '/api/macro/getTaiwanDataExchangeRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MACAODATAGDP = '/api/macro/getMacaoDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MACAODATAPRICEINDEX = '/api/macro/getMacaoDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MACAODATAEMPLOYMENT = '/api/macro/getMacaoDataEmployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MACAODATAMONEYSUPPLY = '/api/macro/getMacaoDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MACAODATAFOREIGNEXCHANGERESERVES = '/api/macro/getMacaoDataForeignExchangeReserves.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MACAODATATOURISM = '/api/macro/getMacaoDataTourism.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MACAODATAGAMINGINDUSTRY = '/api/macro/getMacaoDataGamingIndustry.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MACAODATAINTERESTRATES = '/api/macro/getMacaoDataInterestRates.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MACAODATAEXCHANGERATE = '/api/macro/getMacaoDataExchangeRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' RUSSIADATAGDP = '/api/macro/getRussiaDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' RUSSIADATAFOREIGNTRADE = '/api/macro/getRussiaDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' RUSSIADATACPI = '/api/macro/getRussiaDataCPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' RUSSIADATAMONEYSUPPLY = '/api/macro/getRussiaDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' RUSSIADATACLIMATEINDEX = '/api/macro/getRussiaDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' RUSSIADATAINTERESTRATES = '/api/macro/getRussiaDataInterestRates.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' RUSSIADATAEXCHANGERATE = '/api/macro/getRussiaDataExchangeRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BRAZILDATAGDP = '/api/macro/getBrazilDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BRAZILDATAFOREIGNTRADE = '/api/macro/getBrazilDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BRAZILDATAPRICEINDEX = '/api/macro/getBrazilDataPriceIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BRAZILDATAEMPLOYMENT = '/api/macro/getBrazilDataEmployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BRAZILDATAMONEYSUPPLY = '/api/macro/getBrazilDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BRAZILDATACLIMATEINDEX = '/api/macro/getBrazilDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BRAZILDATARETAILSALE = '/api/macro/getBrazilDataRetailSale.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BRAZILDATAINTERESTRATES = '/api/macro/getBrazilDataInterestRates.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BRAZILDATAEXCHANGERATE = '/api/macro/getBrazilDataExchangeRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SOUTHAFRICADATAGDP = '/api/macro/getSouthAfricaDataGDP.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SOUTHAFRICADATAEMPLOYMENTUNEMPLOYMENT = '/api/macro/getSouthAfricaDataEmploymentUnemployment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SOUTHAFRICADATAFOREIGNTRADE = '/api/macro/getSouthAfricaDataForeignTrade.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SOUTHAFRICADATACPI = '/api/macro/getSouthAfricaDataCPI.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SOUTHAFRICADATAMONEYSUPPLY = '/api/macro/getSouthAfricaDataMoneySupply.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SOUTHAFRICADATACLIMATEINDEX = '/api/macro/getSouthAfricaDataClimateIndex.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SOUTHAFRICADATAINDUSTRY = '/api/macro/getSouthAfricaDataIndustry.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SOUTHAFRICADATAREALESTATE = '/api/macro/getSouthAfricaDataRealEstate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SOUTHAFRICADATARETAILSALES = '/api/macro/getSouthAfricaDataRetailSales.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SOUTHAFRICADATAINTERESTRATES = '/api/macro/getSouthAfricaDataInterestRates.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SOUTHAFRICADATAEXCHANGERATE = '/api/macro/getSouthAfricaDataExchangeRate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' AGRICDATAPRICE = '/api/macro/getAgricDataPrice.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' AGRICDATAOUTPV = '/api/macro/getAgricDataOutpV.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' AGRICDATAWASDE = '/api/macro/getAgricDataWASDE.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' AGRICDATAIMPTEXPT = '/api/macro/getAgricDataImptExpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FOODBVGDATAPRICE = '/api/macro/getFoodBvgDataPrice.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FOODBVGDATASALESOUTPUT = '/api/macro/getFoodBvgDataSalesOutput.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FOODBVGDATAIMPTEXPT = '/api/macro/getFoodBvgDataImptExpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' COMMTRADEDATATRSCG = '/api/macro/getCommTradeDataTRSCG.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' COMMTRADEDATASALES50LARGEEN = '/api/macro/getCommTradeDataSales50LargeEn.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' COMMTRADEDATAINDEXKEYCIRCEN = '/api/macro/getCommTradeDataIndexKeyCircEn.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CATERTOURDATATRSCG = '/api/macro/getCaterTourDataTRSCG.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CATERTOURDATAHOTELSOPER = '/api/macro/getCaterTourDataHotelsOper.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CATERTOURDATANEWHOTEL = '/api/macro/getCaterTourDataNewHotel.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CATERTOURDATAINBOUNDTOUR = '/api/macro/getCaterTourDataInboundTour.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BIOMEDICINEDATASALESOUTPUT = '/api/macro/getBioMedicineDataSalesOutput.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BIOMEDICINEDATAIMPTEXPT = '/api/macro/getBioMedicineDataImptExpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' PETROCHEMDATAPRICE = '/api/macro/getPetrochemDataPrice.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' PETROCHEMDATASALESOUTPUT = '/api/macro/getPetrochemDataSalesOutput.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' PETROCHEMDATAIMPTEXPT = '/api/macro/getPetrochemDataImptExpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CLOTHTEXDATAPRICE = '/api/macro/getClothTexDataPrice.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CLOTHTEXDATASALESOUTPUT = '/api/macro/getClothTexDataSalesOutput.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CLOTHTEXDATACOTTONWASDE = '/api/macro/getClothTexDataCottonWASDE.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' CLOTHTEXDATAIMPTEXPT = '/api/macro/getClothTexDataImptExpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' LIGHTMANUFDATAPRICE = '/api/macro/getLightManufDataPrice.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' LIGHTMANUFDATASALESOUTPUT = '/api/macro/getLightManufDataSalesOutput.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' LIGHTMANUFDATAIMPTEXPT = '/api/macro/getLightManufDataImptExpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MININGDATAPRICE = '/api/macro/getMiningDataPrice.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MININGDATAOUTPSALESTRANSP = '/api/macro/getMiningDataOutpSalesTransp.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MININGDATAIMPTEXPT = '/api/macro/getMiningDataImptExpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FERMETALDATAPRICE = '/api/macro/getFerMetalDataPrice.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FERMETALDATASALESOUTPUT = '/api/macro/getFerMetalDataSalesOutput.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' FERMETALDATAIMPTEXPT = '/api/macro/getFerMetalDataImptExpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' NONFERMETALDATAPRICE = '/api/macro/getNonferMetalDataPrice.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' NONFERMETALDATASALESOUTPUT = '/api/macro/getNonferMetalDataSalesOutput.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' NONFERMETALDATAIMPTEXPT = '/api/macro/getNonferMetalDataImptExpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' DELIVERYEQDATAPRICE = '/api/macro/getDeliveryEqDataPrice.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' DELIVERYEQDATASALESOUTPUT = '/api/macro/getDeliveryEqDataSalesOutput.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' DELIVERYEQDATAIMPTEXPT = '/api/macro/getDeliveryEqDataImptExpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TRAFFICTRANSDATARAILWAY = '/api/macro/getTrafficTransDataRailway.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TRAFFICTRANSDATAROAD = '/api/macro/getTrafficTransDataRoad.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TRAFFICTRANSDATAWATERWAY = '/api/macro/getTrafficTransDataWaterway.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' TRAFFICTRANSDATAAIR = '/api/macro/getTrafficTransDataAir.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UTILINDUSTRYDATAPOWER = '/api/macro/getUtilIndustryDataPower.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UTILINDUSTRYDATAWATER = '/api/macro/getUtilIndustryDataWater.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UTILINDUSTRYDATAGAS = '/api/macro/getUtilIndustryDataGas.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' UTILINDUSTRYDATAENVIRPROT = '/api/macro/getUtilIndustryDataEnvirProt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ELECCOMPDATAPRICE = '/api/macro/getElecCompDataPrice.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ELECCOMPDATASALESOUTPUT = '/api/macro/getElecCompDataSalesOutput.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ELECCOMPDATAIMPTEXPT = '/api/macro/getElecCompDataImptExpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INFOEQPTDATAPRICE = '/api/macro/getInfoEqptDataPrice.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INFOEQPTDATASALESOUTPUT = '/api/macro/getInfoEqptDataSalesOutput.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INFOEQPTDATAIMPTEXPT = '/api/macro/getInfoEqptDataImptExpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HOUSEHOLDAPLSDATASALESOUTPUT = '/api/macro/getHouseholdAplsDataSalesOutput.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' HOUSEHOLDAPLSDATAIMPTEXPT = '/api/macro/getHouseholdAplsDataImptExpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INFOSERVDATASOFTWARE = '/api/macro/getInfoServDataSoftware.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INFOSERVDATACOMM = '/api/macro/getInfoServDataComm.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INFOSERVDATAINTERNET = '/api/macro/getInfoServDataInternet.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' REALESTDATAPRICE = '/api/macro/getRealEstDataPrice.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' REALESTDATAINVESTDVPT = '/api/macro/getRealEstDataInvestDvpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' REALESTDATALAND = '/api/macro/getRealEstDataLand.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' REALESTDATASALES = '/api/macro/getRealEstDataSales.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BLDGMATERDATAPRICE = '/api/macro/getBldgMaterDataPrice.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BLDGMATERDATASALESOUTPUT = '/api/macro/getBldgMaterDataSalesOutput.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MCHNREQPTDATASALESOUTPUT = '/api/macro/getMchnrEqptDataSalesOutput.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' MCHNREQPTDATAIMPTEXPT = '/api/macro/getMchnrEqptDataImptExpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BANKDATAASSETSLIABILITIES = '/api/macro/getBankDataAssetsLiabilities.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' BANKDATANONPERFORMINGLOANS = '/api/macro/getBankDataNonPerformingLoans.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' SECURITIESDATAOPERINDIC = '/api/macro/getSecuritiesDataOperIndic.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INSDATAPREMPRYINSURANCE = '/api/macro/getInsDataPremPryInsurance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INSDATACLAIMPAYMENT = '/api/macro/getInsDataClaimPayment.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INSDATAFUNDBALANCE = '/api/macro/getInsDataFundBalance.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' INSDATAASSETS = '/api/macro/getInsDataAssets.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAYILI = '/api/macro/getEcommerceDataYili.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAGUANGMING = '/api/macro/getEcommerceDataGuangming.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATACHENGDELOLO = '/api/macro/getEcommerceDataChengDeLolo.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAQIAQIA = '/api/macro/getEcommerceDataQiaqia.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAVVGROUP = '/api/macro/getEcommerceDataVVGroup.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAJINFENGWINE = '/api/macro/getEcommerceDataJinfengWine.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAGUYUELONGSHAN = '/api/macro/getEcommerceDataGuyueLongshan.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATASHANXIFENJIU = '/api/macro/getEcommerceDataShanxiFenjiu.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAZHANGYUA = '/api/macro/getEcommerceDataZhangyuA.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAMOGAO = '/api/macro/getEcommerceDataMogao.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAKEMENNOODLEMFG = '/api/macro/getEcommerceDataKemenNoodleMFG.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAJINZIHAM = '/api/macro/getEcommerceDataJinziHam.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATALOTUS = '/api/macro/getEcommerceDataLotus.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATABEIYINMATE = '/api/macro/getEcommerceDataBeiyinMate.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAQINGDAOHAIER = '/api/macro/getEcommerceDataQingdaoHaier.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATATCLGROUP = '/api/macro/getEcommerceDataTCLGroup.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAMIDEAGROUP = '/api/macro/getEcommerceDataMideaGroup.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAWHIRLPOOL = '/api/macro/getEcommerceDataWhirlpool.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAJOYOUNG = '/api/macro/getEcommerceDataJoyoung.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAVATTI = '/api/macro/getEcommerceDataVatti.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATASUPOR = '/api/macro/getEcommerceDataSupor.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAKONKA = '/api/macro/getEcommerceDataKonka.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATACHANGHONG = '/api/macro/getEcommerceDataChanghong.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATALITTLESWAN = '/api/macro/getEcommerceDataLittleSwan.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAMEILING = '/api/macro/getEcommerceDataMeiling.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAZTE = '/api/macro/getEcommerceDataZTE.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATADATANGTELECOM = '/api/macro/getEcommerceDataDatangTelecom.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATABIRD = '/api/macro/getEcommerceDataBird.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATADAHUATECHNOLOGY = '/api/macro/getEcommerceDataDahuaTechnology.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATATSINGHUATONGFANG = '/api/macro/getEcommerceDataTsinghuaTongfang.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAHEDY = '/api/macro/getEcommerceDataHedy.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAHADAY = '/api/macro/getEcommerceDataHaday.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAYANJINGBEER = '/api/macro/getEcommerceDataYanjingBeer.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAMAIQUER = '/api/macro/getEcommerceDataMaiquer.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATACITICGUOANWINE = '/api/macro/getEcommerceDataCiticGuoanWine.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAQINGQINGBARLEYWINE = '/api/macro/getEcommerceDataQingqingBarleyWine.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAHAOXIANGNI = '/api/macro/getEcommerceDataHaoxiangni.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAFULINGZHACAI = '/api/macro/getEcommerceDataFulingZhacai.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAHUANGSHANGHUANG = '/api/macro/getEcommerceDataHuangshanghuang.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAHAINANYEDAO = '/api/macro/getEcommerceDataHainanYedao.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATASHUANGTAFOOD = '/api/macro/getEcommerceDataShuangtaFood.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAJIUGUILIQUOR = '/api/macro/getEcommerceDataJiuguiLiquor.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATABLACKSESAME = '/api/macro/getEcommerceDataBlackSesame.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAKINGSLUCK = '/api/macro/getEcommerceDataKingsLuck.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATALAOBAIGANLIQUOR = '/api/macro/getEcommerceDataLaobaiganLiquor.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATASHUANGHUIDVPT = '/api/macro/getEcommerceDataShuanghuiDvpt.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' OPT = '/api/options/getOpt.csv?contractStatus=%s&optID=%s&secID=%s&ticker=%s&varSecID=%s&varticker=%s&field=%s' MKTOPTD = '/api/market/getMktOptd.csv?optID=%s&secID=%s&ticker=%s&tradeDate=%s&beginDate=%s&endDate=%s&field=%s' SOCIALDATAXQ = '/api/subject/getSocialDataXQ.csv?beginDate=%s&endDate=%s&ticker=%s&field=%s' SOCIALDATAXQBYTICKER = '/api/subject/getSocialDataXQByTicker.csv?ticker=%s&field=%s' SOCIALDATAXQBYDATE = '/api/subject/getSocialDataXQByDate.csv?statisticsDate=%s&field=%s' OPTVAR = '/api/options/getOptVar.csv?exchangeCD=%s&secID=%s&ticker=%s&contractType=%s&exerType=%s&field=%s' NEWSINFO = '/api/subject/getNewsInfo.csv?newsID=%s&field=%s' NEWSINFOBYTIME = '/api/subject/getNewsInfoByTime.csv?newsPublishDate=%s&beginTime=%s&endTime=%s&field=%s' NEWSCONTENT = '/api/subject/getNewsContent.csv?newsID=%s&field=%s' NEWSCONTENTBYTIME = '/api/subject/getNewsContentByTime.csv?newsPublishDate=%s&beginTime=%s&endTime=%s&field=%s' COMPANYBYNEWS = '/api/subject/getCompanyByNews.csv?newsID=%s&field=%s' NEWSBYCOMPANY = '/api/subject/getNewsByCompany.csv?partyID=%s&beginDate=%s&endDate=%s&field=%s' TICKERSBYNEWS = '/api/subject/getTickersByNews.csv?newsID=%s&field=%s' NEWSBYTICKERS = '/api/subject/getNewsByTickers.csv?secID=%s&secShortName=%s&ticker=%s&beginDate=%s&endDate=%s&exchangeCD=%s&field=%s' MKTEQUDADJ = '/api/market/getMktEqudAdj.csv?secID=%s&ticker=%s&tradeDate=%s&beginDate=%s&endDate=%s&field=%s' MKTADJF = '/api/market/getMktAdjf.csv?secID=%s&ticker=%s&field=%s' OPTIONTICKRTSNAPSHOT = '/api/market/getOptionTickRTSnapshot.csv?optionId=%s&field=%s' FUTUREBARRTINTRADAY = '/api/market/getFutureBarRTIntraDay.csv?instrumentID=%s&endTime=%s&startTime=%s&field=%s' MKTFUTDVOL = '/api/market/getMktFutdVol.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' THEMESCONTENT = '/api/subject/getThemesContent.csv?isMain=%s&themeID=%s&themeName=%s&themeSource=%s&field=%s' TICKERSBYTHEMES = '/api/subject/getTickersByThemes.csv?themeID=%s&themeName=%s&beginDate=%s&endDate=%s&isNew=%s&field=%s' THEMESTICKERSINSERT = '/api/subject/getThemesTickersInsert.csv?themeID=%s&themeName=%s&beginDate=%s&endDate=%s&field=%s' THEMESTICKERSDELETE = '/api/subject/getThemesTickersDelete.csv?themeID=%s&themeName=%s&beginDate=%s&endDate=%s&field=%s' THEMESBYTICKERS = '/api/subject/getThemesByTickers.csv?secID=%s&secShortName=%s&ticker=%s&beginDate=%s&endDate=%s&exchangeCD=%s&field=%s' THEMESPERIOD = '/api/subject/getThemesPeriod.csv?isLatest=%s&themeID=%s&themeName=%s&field=%s' ACTIVETHEMES = '/api/subject/getActiveThemes.csv?date=%s&field=%s' THEMESSIMILARITY = '/api/subject/getThemesSimilarity.csv?themeID=%s&themeName=%s&field=%s' THEMESHEAT = '/api/subject/getThemesHeat.csv?themeID=%s&themeName=%s&beginDate=%s&endDate=%s&field=%s' SECTORTHEMESBYTICKERS = '/api/subject/getSectorThemesByTickers.csv?secID=%s&secShortName=%s&ticker=%s&beginDate=%s&endDate=%s&exchangeCD=%s&field=%s' WEBTHEMESBYTICKERS = '/api/subject/getWebThemesByTickers.csv?secID=%s&secShortName=%s&ticker=%s&beginDate=%s&endDate=%s&exchangeCD=%s&field=%s' MKTEQUDLATELY = '/api/market/getMktEqudLately.csv?field=%s' FDMTISLATELY = '/api/fundamental/getFdmtISLately.csv?field=%s' NEWSHEATINDEX = '/api/subject/getNewsHeatIndex.csv?beginDate=%s&endDate=%s&exchangeCD=%s&secID=%s&secShortName=%s&ticker=%s&field=%s' NEWSSENTIMENTINDEX = '/api/subject/getNewsSentimentIndex.csv?beginDate=%s&endDate=%s&exchangeCD=%s&secID=%s&secShortName=%s&ticker=%s&field=%s' SECTYPEREL = '/api/master/getSecTypeRel.csv?secID=%s&ticker=%s&typeID=%s&field=%s' REPORTBYTICKER = '/api/subject/getReportByTicker.csv?ticker=%s&beginDate=%s&endDate=%s&field=%s' REPORTBYCATEGORY = '/api/subject/getReportByCategory.csv?beginDate=%s&Category=%s&endDate=%s&field=%s' REPORTCONTENT = '/api/subject/getReportContent.csv?ticker=%s&beginDate=%s&endDate=%s&field=%s' MKTLIMIT = '/api/market/getMktLimit.csv?secID=%s&ticker=%s&tradeDate=%s&field=%s' ECOMMERCEDATAWULIANGYE = '/api/macro/getEcommerceDataWuliangye.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAGREE = '/api/macro/getEcommerceDataGree.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAHISENSEELECTRIC = '/api/macro/getEcommerceDataHisenseElectric.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAHISENSE = '/api/macro/getEcommerceDataHisense.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAJIAJIAFOOD = '/api/macro/getEcommerceDataJiajiaFood.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAROBAM = '/api/macro/getEcommerceDataRobam.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAASD = '/api/macro/getEcommerceDataASD.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAMACRO = '/api/macro/getEcommerceDataMacro.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAELECPRO = '/api/macro/getEcommerceDataElecpro.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATASANGLEJIN = '/api/macro/getEcommerceDataSanglejin.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAHOMA = '/api/macro/getEcommerceDataHoma.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATALONGDAMEAT = '/api/macro/getEcommerceDataLongdaMeat.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATABYHEALTH = '/api/macro/getEcommerceDataByHealth.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAHAIXIN = '/api/macro/getEcommerceDataHaixin.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAVANWARD = '/api/macro/getEcommerceDataVanward.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAMEIDA = '/api/macro/getEcommerceDataMeida.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAHENGSHUNVINEGARINDUSTRY = '/api/macro/getEcommerceDataHengshunVinegarindustry.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATASHUIJINGFANG = '/api/macro/getEcommerceDataShuijingfang.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATACHUNLAN = '/api/macro/getEcommerceDataChunlan.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAYILITE = '/api/macro/getEcommerceDataYilite.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAHUANGSHI = '/api/macro/getEcommerceDataHuangshi.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAYANGHE = '/api/macro/getEcommerceDataYanghe.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATASANYUAN = '/api/macro/getEcommerceDataSanyuan.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATATUOPAISHEDE = '/api/macro/getEcommerceDataTuopaiShede.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAKUAIJISHAN = '/api/macro/getEcommerceDataKuaijishan.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATATONGHUA = '/api/macro/getEcommerceDataTonghua.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAKWEICHOWMOUTAIGROUP = '/api/macro/getEcommerceDataKweichowMoutaiGroup.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATATSINGTAO = '/api/macro/getEcommerceDataTsingTao.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ACTIVETHEMESINSERT = '/api/subject/getActiveThemesInsert.csv?beginDate=%s&endDate=%s&isLatest=%s&themeSource=%s&field=%s' ACTIVETHEMESDELETE = '/api/subject/getActiveThemesDelete.csv?beginDate=%s&endDate=%s&isLatest=%s&themeSource=%s&field=%s' EQUINFO = '/api/master/getEquInfo.csv?ticker=%s&field=%s' SECTIPS = '/api/market/getSecTips.csv?tipsTypeCD=%s&field=%s' THEMESCLUSTER = '/api/subject/getThemesCluster.csv?isMain=%s&themeID=%s&themeName=%s&field=%s' THEMESBYNEWS = '/api/subject/getThemesByNews.csv?insertDate=%s&insertDate=%s&newsID=%s&beginTime=%s&endTime=%s&field=%s' BARRTINTRADAYONEMINUTE = '/api/market/getBarRTIntraDayOneMinute.csv?time=%s&field=%s' EQURTRANK = '/api/market/getEquRTRank.csv?desc=%s&exchangeCD=%s&field=%s' ECOMMERCEDATAGUJING = '/api/macro/getEcommerceDataGujing.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATALUZHOULAOJIAO = '/api/macro/getEcommerceDataLuzhouLaojiao.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATASHANGHAIMALING = '/api/macro/getEcommerceDataShanghaiMaling.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATABLACKCATTLEFOOD = '/api/macro/getEcommerceDataBlackCattleFood.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATADELISI = '/api/macro/getEcommerceDataDelisi.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATASTARLAKEBIOSCIENCE = '/api/macro/getEcommerceDataStarLakeBioscience.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAJONJEEHITECH = '/api/macro/getEcommerceDataJonjeeHiTech.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATACRSANJIU = '/api/macro/getEcommerceDataCRSanjiu.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAJIUZHITANG = '/api/macro/getEcommerceDataJiuzhitang.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAFUANNA = '/api/macro/getEcommerceDataFuanna.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATALUOLAI = '/api/macro/getEcommerceDataLuolai.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAGUIRENNIAO = '/api/macro/getEcommerceDataGuirenniao.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATABAOXINIAO = '/api/macro/getEcommerceDataBaoxiniao.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATALAOFENGXIANG = '/api/macro/getEcommerceDataLaofengxiang.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAFIYTAA = '/api/macro/getEcommerceDataFiytaA.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAGOLDLEAFJEWELRY = '/api/macro/getEcommerceDataGoldleafJewelry.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATACOMIXGROUP = '/api/macro/getEcommerceDataComixGroup.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAYAOJIPLAYINGCARD = '/api/macro/getEcommerceDataYaojiPlayingCard.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAMGSTATIONERY = '/api/macro/getEcommerceDataMGStationery.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATACS = '/api/macro/getEcommerceDataCS.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAEDIFIER = '/api/macro/getEcommerceDataEdifier.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAHIKVISION = '/api/macro/getEcommerceDataHikVision.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATASOLAREAST = '/api/macro/getEcommerceDataSolareast.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATACHIGO = '/api/macro/getEcommerceDataChigo.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' ECOMMERCEDATAAUCMA = '/api/macro/getEcommerceDataAucma.csv?indicID=%s&indicName=%s&beginDate=%s&endDate=%s&field=%s' THEMESBYNEWSCOMPANYREL = '/api/subject/getThemesByNewsCompanyRel.csv?insertDate=%s&insertDate=%s&newsID=%s&beginTime=%s&endTime=%s&field=%s' THEMESINSERTDB = '/api/subject/getThemesInsertDB.csv?beginDate=%s&endDate=%s&themeSource=%s&field=%s' THEMESBYNEWSLF = '/api/subject/getThemesByNewsLF.csv?insertDate=%s&insertDate=%s&newsID=%s&beginTime=%s&endTime=%s&field=%s' THEMESBYNEWSMF = '/api/subject/getThemesByNewsMF.csv?insertDate=%s&insertDate=%s&newsID=%s&beginTime=%s&endTime=%s&field=%s' INDUSTRYTICKRTSNAPSHOT = '/api/market/getIndustryTickRTSnapshot.csv?securityID=%s&field=%s' NEWSINFOBYINSERTTIME = '/api/subject/getNewsInfoByInsertTime.csv?newsInsertDate=%s&beginTime=%s&endTime=%s&field=%s' NEWSCONTENTBYINSERTTIME = '/api/subject/getNewsContentByInsertTime.csv?newsInsertDate=%s&beginTime=%s&endTime=%s&field=%s' SECTYPEREGIONREL = '/api/master/getSecTypeRegionRel.csv?secID=%s&ticker=%s&typeID=%s&field=%s' SECTYPE = '/api/master/getSecType.csv?field=%s' SECTYPEREGION = '/api/master/getSecTypeRegion.csv?field=%s' SOCIALDATAGUBA = '/api/subject/getSocialDataGuba.csv?beginDate=%s&endDate=%s&ticker=%s&field=%s' SOCIALTHEMEDATAGUBA = '/api/subject/getSocialThemeDataGuba.csv?beginDate=%s&endDate=%s&themeID=%s&field=%s' FUNDSHARESCHG = '/api/fund/getFundSharesChg.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' THEMESBYNEWSTIME = '/api/subject/getThemesByNewsTime.csv?publishBeginTime=%s&publishEndTime=%s&field=%s' THEMESBYNEWSTIMECOMPANYREL = '/api/subject/getThemesByNewsTimeCompanyRel.csv?publishBeginTime=%s&publishEndTime=%s&field=%s' THEMESBYNEWSTIMELF = '/api/subject/getThemesByNewsTimeLF.csv?publishBeginTime=%s&publishEndTime=%s&field=%s' THEMESBYNEWSTIMEMF = '/api/subject/getThemesByNewsTimeMF.csv?publishBeginTime=%s&publishEndTime=%s&field=%s' MKTFUNDDADJAF = '/api/market/getMktFunddAdjAf.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' REPORTCONTENTBYID = '/api/subject/getReportContentByID.csv?reportID=%s&field=%s' THEMESBYNEWS2 = '/api/subject/getThemesByNews2.csv?insertBeginTime=%s&insertEndTime=%s&newsID=%s&field=%s' THEMESBYNEWSTIME2 = '/api/subject/getThemesByNewsTime2.csv?publishBeginTime=%s&publishEndTime=%s&field=%s' SYSCODE = '/api/master/getSysCode.csv?codeTypeID=%s&valueCD=%s&field=%s' FUNDLEVERAGEINFO = '/api/fund/getFundLeverageInfo.csv?exchangeCDLeverage=%s&secID=%s&ticker=%s&field=%s' SECST = '/api/equity/getSecST.csv?secID=%s&ticker=%s&beginDate=%s&endDate=%s&field=%s' DERIV = '/api/IV/getDerIv.csv?beginDate=%s&endDate=%s&optID=%s&SecID=%s&field=%s' DERIVHV = '/api/IV/getDerIvHv.csv?beginDate=%s&endDate=%s&SecID=%s&period=%s&field=%s' DERIVINDEX = '/api/IV/getDerIvIndex.csv?beginDate=%s&endDate=%s&SecID=%s&period=%s&field=%s' DERIVIVPDELTA = '/api/IV/getDerIvIvpDelta.csv?beginDate=%s&endDate=%s&SecID=%s&delta=%s&period=%s&field=%s' DERIVPARAM = '/api/IV/getDerIvParam.csv?beginDate=%s&endDate=%s&SecID=%s&expDate=%s&field=%s' DERIVRAWDELTA = '/api/IV/getDerIvRawDelta.csv?beginDate=%s&endDate=%s&SecID=%s&delta=%s&period=%s&field=%s' DERIVSURFACE = '/api/IV/getDerIvSurface.csv?beginDate=%s&endDate=%s&SecID=%s&contractType=%s&field=%s' ================================================ FILE: whats_new.md ================================================ 0.4.5 ------- - get_today_all接口增加实时PE、PB和流通市值等 - 修改财务数据问题 - get_h_data前复权数据bug修复(白天获取) 0.4.2 -------- - 新增电影票房数据 - 修复部分bug 0.4.1 ---------- - 新增sina大单数据 - 修改当日分笔bug - 深市融资融券数据修复 0.3.9 --------- - 加入通联数据期权隐含波动率数据 - 修复指数成份股接口 0.3.8 ------- - 完成通联数据SDK v0.2.0开发 - 沪深300成份股和权重接口问题修复 - 其它bug的修复 - 通联数据API文档发布 0.3.5 ------- - 部分代码修正 - 新增通联数据SDK0.1版 0.3.4 ------- - 新增‘龙虎榜’模块 1. 每日龙虎榜列表 1. 个股上榜统计 1. 营业部上榜统计 1. 龙虎榜机构席位追踪 1. 龙虎榜机构席位成交明细 - 修改get\_h\_data数据类型为float - 修改get_index接口遗漏的open列 - 合并GitHub上提交的bug修复 0.3.1 ------- - 修复get\_h\_data的bug - 修改get\_stock\_basics数据获取方式 0.2.9 --------- - 新增上海银行间同业拆放利率模块 1. 银行间同业拆放利率(Shibor) 1. Shibor银行报价数据 1. Shibor均值数据 1. 贷款基础利率(LPR) 1. 贷款基础利率均值数据 - 基本面模块接口优化 - 历史某一阶段的前复权数据bug修复 0.2.8 --------- 1. 新增大盘指数实时行情列表 1. 新增大盘指数历史行情数据(全部) 1. 新增终止上市公司列表(退市) 1. 新增暂停上市公司列表 1. 修正融资融券明细无日期的缺陷 1. 修正get\_h\_data部分bug 0.2.6 ----------- 1. 新增沪市融资融券列表 1. 新增沪市融资融券明细列表 1. 新增深市融资融券列表 1. 新增深市融资融券明细列表 1. 修正复权数据数据源出现null造成异常问题(对大约300个股票有影响) 0.2.5 ----------- 1. 完成python2.x和python3.x兼容性支持 1. 部分算法优化和代码重构 1. 新增中证500成份股 1. 新增当日分笔交易明细 1. 修正分配预案(高送转)bug 0.2.3 ----------- 1. “新浪股吧”消息和热度 1. 新股数据 1. 修正“基本面”模块中数据重复的问题 1. 修正历史数据缺少一列column(数据来源问题)的bug 1. 新增期货模块(实验)by @ideaplat 0.2.2 -------- 对前复权数据接口的bug进行了修改(pandas v0.14版本在使用时报错) 0.2.1 -------- 1、增加‘投资参考’数据模块 - 分配预案 - 业绩预告 - 限售股解禁 - 基金持股 2、将“业绩预告”挪到了‘投资参考’模块中 3、对历史复权方法中的代码进行了修改 0.2.0 -------- 1、新增新闻事件模块 - 即时财经新闻 - 个股信息地雷 2、新增指数成份股和权重分类 - 沪深300成份股和权重 - 上证50成份股列表 3、修改get\_hist_data()接口 - 修改数值型数据的dtype为float 4、新增历史复权数据接口get\_h_data - 前复权(默认) - 后复权 - 不复权