tushare 1.4.5__tar.gz → 1.4.17__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- tushare-1.4.17/PKG-INFO +107 -0
- {tushare-1.4.5 → tushare-1.4.17}/setup.py +25 -9
- {tushare-1.4.5 → tushare-1.4.17}/tushare/__init__.py +2 -2
- {tushare-1.4.5 → tushare-1.4.17}/tushare/pro/client.py +3 -2
- tushare-1.4.17/tushare/pro/data_pro.py +395 -0
- tushare-1.4.17/tushare/pro/llm.py +118 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/rtq.py +25 -23
- {tushare-1.4.5 → tushare-1.4.17}/tushare/subs/model/tick.py +128 -128
- {tushare-1.4.5 → tushare-1.4.17}/tushare/subs/ts_subs/subscribe.py +25 -5
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/format_stock_code.py +19 -19
- tushare-1.4.17/tushare.egg-info/PKG-INFO +107 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare.egg-info/SOURCES.txt +1 -0
- tushare-1.4.17/tushare.egg-info/requires.txt +7 -0
- tushare-1.4.5/PKG-INFO +0 -87
- tushare-1.4.5/tushare/pro/data_pro.py +0 -215
- tushare-1.4.5/tushare.egg-info/PKG-INFO +0 -87
- tushare-1.4.5/tushare.egg-info/requires.txt +0 -12
- {tushare-1.4.5 → tushare-1.4.17}/LICENSE +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/README.md +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/setup.cfg +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/bond/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/bond/bonds.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/coins/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/coins/market.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/data/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/fund/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/fund/cons.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/fund/nav.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/futures/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/futures/cons.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/futures/domestic.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/futures/domestic_cons.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/futures/intlfutures.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/internet/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/internet/boxoffice.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/internet/caixinnews.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/internet/indexes.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/pro/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/billboard.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/classifying.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/cons.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/fundamental.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/globals.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/histroy_divide.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/indictor.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/macro.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/macro_vars.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/minsdata.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/news_vars.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/newsevent.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/ref_vars.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/reference.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/rtq_vars.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/shibor.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/stock/trading.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/subs/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/subs/ht_subs/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/subs/ht_subs/covert.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/subs/ht_subs/subscribe.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/subs/model/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/subs/model/min.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/subs/tgw_subs/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/subs/tgw_subs/convert.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/subs/tgw_subs/login.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/subs/tgw_subs/subscribe.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/subs/ts_subs/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/trader/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/trader/trader.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/trader/utils.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/trader/vars.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/common.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/conns.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/dateu.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/form_date.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/formula.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/mailmerge.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/netbase.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/protobuf/__init__.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/protobuf/funcs.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/protobuf/response_pb2.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/store.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/upass.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/vars.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare/util/verify_token.py +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare.egg-info/dependency_links.txt +0 -0
- {tushare-1.4.5 → tushare-1.4.17}/tushare.egg-info/top_level.txt +0 -0
tushare-1.4.17/PKG-INFO
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: tushare
|
3
|
+
Version: 1.4.17
|
4
|
+
Summary: A utility for crawling historical and Real-time Quotes data of China stocks
|
5
|
+
Home-page: https://tushare.pro
|
6
|
+
Author: Jimmy Liu
|
7
|
+
Author-email: waditu@163.com
|
8
|
+
License: BSD
|
9
|
+
Keywords: Global Financial Data
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
11
|
+
Classifier: Programming Language :: Python :: 3.6
|
12
|
+
Classifier: Programming Language :: Python :: 3.7
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
16
|
+
Classifier: License :: OSI Approved :: BSD License
|
17
|
+
Description-Content-Type: text/plain
|
18
|
+
License-File: LICENSE
|
19
|
+
Requires-Dist: pandas
|
20
|
+
Requires-Dist: requests
|
21
|
+
Requires-Dist: lxml
|
22
|
+
Requires-Dist: simplejson
|
23
|
+
Requires-Dist: bs4
|
24
|
+
Requires-Dist: websocket-client>=0.57.0
|
25
|
+
Requires-Dist: tqdm
|
26
|
+
|
27
|
+
|
28
|
+
TuShare
|
29
|
+
===============
|
30
|
+
|
31
|
+
.. image:: https://api.travis-ci.org/waditu/tushare.png?branch=master
|
32
|
+
:target: https://travis-ci.org/waditu/tushare
|
33
|
+
|
34
|
+
.. image:: https://badge.fury.io/py/tushare.png
|
35
|
+
:target: http://badge.fury.io/py/tushare
|
36
|
+
|
37
|
+
* easy to use as most of the data returned are pandas DataFrame objects
|
38
|
+
* can be easily saved as csv, excel or json files
|
39
|
+
* can be inserted into MySQL or Mongodb
|
40
|
+
|
41
|
+
Target Users
|
42
|
+
--------------
|
43
|
+
|
44
|
+
* financial market analyst of China
|
45
|
+
* learners of financial data analysis with pandas/NumPy
|
46
|
+
* people who are interested in China financial data
|
47
|
+
|
48
|
+
Installation
|
49
|
+
--------------
|
50
|
+
|
51
|
+
pip install tushare
|
52
|
+
|
53
|
+
Upgrade
|
54
|
+
---------------
|
55
|
+
|
56
|
+
pip install tushare --upgrade
|
57
|
+
|
58
|
+
Quick Start
|
59
|
+
--------------
|
60
|
+
|
61
|
+
::
|
62
|
+
|
63
|
+
import tushare as ts
|
64
|
+
|
65
|
+
ts.get_hist_data('600848')
|
66
|
+
|
67
|
+
return::
|
68
|
+
|
69
|
+
open high close low volume p_change ma5
|
70
|
+
date
|
71
|
+
2012-01-11 6.880 7.380 7.060 6.880 14129.96 2.62 7.060
|
72
|
+
2012-01-12 7.050 7.100 6.980 6.900 7895.19 -1.13 7.020
|
73
|
+
2012-01-13 6.950 7.000 6.700 6.690 6611.87 -4.01 6.913
|
74
|
+
2012-01-16 6.680 6.750 6.510 6.480 2941.63 -2.84 6.813
|
75
|
+
2012-01-17 6.660 6.880 6.860 6.460 8642.57 5.38 6.822
|
76
|
+
2012-01-18 7.000 7.300 6.890 6.880 13075.40 0.44 6.788
|
77
|
+
2012-01-19 6.690 6.950 6.890 6.680 6117.32 0.00 6.770
|
78
|
+
2012-01-20 6.870 7.080 7.010 6.870 6813.09 1.74 6.832
|
79
|
+
|
80
|
+
|
81
|
+
Log
|
82
|
+
--------------
|
83
|
+
1.4.17
|
84
|
+
-------
|
85
|
+
- 修复 920 开头更改是北交所
|
86
|
+
-------
|
87
|
+
1.4.14
|
88
|
+
-------
|
89
|
+
- 修复 realtime_list (爬虫版)
|
90
|
+
- 修复dc CLOSE和PRE_CLOSE收盘和昨收 字段命名问题
|
91
|
+
-------
|
92
|
+
1.4.6
|
93
|
+
-------
|
94
|
+
- 修复 realtime_quote 实时盘口TICK快照(爬虫版)
|
95
|
+
- 修复dc OPEN和LOW 值相反问题
|
96
|
+
1.4.0
|
97
|
+
-------
|
98
|
+
- 增加 银河证券实时行情数据入口
|
99
|
+
1.3.9
|
100
|
+
-------
|
101
|
+
- realtime_quote 实时盘口TICK快照(爬虫版)
|
102
|
+
- 修复dc 指数和股票数据抓取问题
|
103
|
+
- 将数字类型统一转换成 float类型
|
104
|
+
1.2.73
|
105
|
+
-------
|
106
|
+
- 支持华泰实时数据15SECOND
|
107
|
+
|
@@ -64,6 +64,19 @@ return::
|
|
64
64
|
|
65
65
|
Log
|
66
66
|
--------------
|
67
|
+
1.4.17
|
68
|
+
-------
|
69
|
+
- 修复 920 开头更改是北交所
|
70
|
+
-------
|
71
|
+
1.4.14
|
72
|
+
-------
|
73
|
+
- 修复 realtime_list (爬虫版)
|
74
|
+
- 修复dc CLOSE和PRE_CLOSE收盘和昨收 字段命名问题
|
75
|
+
-------
|
76
|
+
1.4.6
|
77
|
+
-------
|
78
|
+
- 修复 realtime_quote 实时盘口TICK快照(爬虫版)
|
79
|
+
- 修复dc OPEN和LOW 值相反问题
|
67
80
|
1.4.0
|
68
81
|
-------
|
69
82
|
- 增加 银河证券实时行情数据入口
|
@@ -78,20 +91,23 @@ Log
|
|
78
91
|
|
79
92
|
"""
|
80
93
|
|
94
|
+
|
81
95
|
def read_install_requires():
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
96
|
+
reqs = [
|
97
|
+
'pandas',
|
98
|
+
'requests',
|
99
|
+
'lxml',
|
100
|
+
'simplejson',
|
101
|
+
'bs4',
|
102
|
+
'websocket-client>=0.57.0',
|
103
|
+
'tqdm'
|
104
|
+
]
|
105
|
+
return reqs
|
90
106
|
|
91
107
|
|
92
108
|
setup(
|
93
109
|
name='tushare',
|
94
|
-
version='1.4.
|
110
|
+
version='1.4.17',
|
95
111
|
description='A utility for crawling historical and Real-time Quotes data of China stocks',
|
96
112
|
# long_description=read("README.rst"),
|
97
113
|
long_description=long_desc,
|
@@ -2,7 +2,7 @@
|
|
2
2
|
import codecs
|
3
3
|
import os
|
4
4
|
|
5
|
-
__version__ = '1.4.
|
5
|
+
__version__ = '1.4.16'
|
6
6
|
__author__ = 'Jimmy Liu'
|
7
7
|
|
8
8
|
"""
|
@@ -78,7 +78,7 @@ from tushare.stock.shibor import (shibor_data, shibor_quote_data,
|
|
78
78
|
"""
|
79
79
|
for tushare pro api
|
80
80
|
"""
|
81
|
-
from tushare.pro.data_pro import (pro_api, pro_bar, subs, ht_subs)
|
81
|
+
from tushare.pro.data_pro import (pro_api, pro_bar, subs, ht_subs, pro_bar_vip)
|
82
82
|
|
83
83
|
"""
|
84
84
|
for LHB
|
@@ -17,7 +17,8 @@ import requests
|
|
17
17
|
class DataApi:
|
18
18
|
|
19
19
|
__token = ''
|
20
|
-
__http_url = 'http://api.waditu.com'
|
20
|
+
__http_url = 'http://api.waditu.com/dataapi'
|
21
|
+
# __http_url = 'http://127.0.0.1:8000/dataapi'
|
21
22
|
|
22
23
|
def __init__(self, token, timeout=30):
|
23
24
|
"""
|
@@ -37,7 +38,7 @@ class DataApi:
|
|
37
38
|
'fields': fields
|
38
39
|
}
|
39
40
|
|
40
|
-
res = requests.post(self.__http_url, json=req_params, timeout=self.__timeout)
|
41
|
+
res = requests.post(f"{self.__http_url}/{api_name}", json=req_params, timeout=self.__timeout)
|
41
42
|
if res:
|
42
43
|
result = json.loads(res.text)
|
43
44
|
if result['code'] != 0:
|
@@ -0,0 +1,395 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
"""
|
3
|
+
pro init
|
4
|
+
Created on 2018/07/01
|
5
|
+
@author: Jimmy Liu
|
6
|
+
@group : https://tushare.pro
|
7
|
+
@contact: jimmysoa@sina.cn
|
8
|
+
"""
|
9
|
+
from __future__ import division
|
10
|
+
import datetime
|
11
|
+
from tushare.pro import client
|
12
|
+
from tushare.util import upass
|
13
|
+
from tushare.util.formula import MA
|
14
|
+
|
15
|
+
PRICE_COLS = ['open', 'close', 'high', 'low', 'pre_close']
|
16
|
+
FORMAT = lambda x: '%.2f' % x
|
17
|
+
FREQS = {'D': '1DAY',
|
18
|
+
'W': '1WEEK',
|
19
|
+
'Y': '1YEAR',
|
20
|
+
}
|
21
|
+
FACT_LIST = {
|
22
|
+
'tor': 'turnover_rate',
|
23
|
+
'turnover_rate': 'turnover_rate',
|
24
|
+
'vr': 'volume_ratio',
|
25
|
+
'volume_ratio': 'volume_ratio',
|
26
|
+
'pe': 'pe',
|
27
|
+
'pe_ttm': 'pe_ttm',
|
28
|
+
}
|
29
|
+
def pro_api(token='', timeout=30):
|
30
|
+
"""
|
31
|
+
初始化pro API,第一次可以通过ts.set_token('your token')来记录自己的token凭证,临时token可以通过本参数传入
|
32
|
+
"""
|
33
|
+
if token == '' or token is None:
|
34
|
+
token = upass.get_token()
|
35
|
+
if token is not None and token != '':
|
36
|
+
pro = client.DataApi(token=token, timeout=timeout)
|
37
|
+
return pro
|
38
|
+
else:
|
39
|
+
raise Exception('api init error.')
|
40
|
+
|
41
|
+
|
42
|
+
def pro_bar(ts_code='', api=None, start_date='', end_date='', freq='D', asset='E',
|
43
|
+
exchange='',
|
44
|
+
adj = None,
|
45
|
+
ma = [],
|
46
|
+
factors = None,
|
47
|
+
adjfactor = False,
|
48
|
+
offset = None,
|
49
|
+
limit = None,
|
50
|
+
fields = '',
|
51
|
+
contract_type = '',
|
52
|
+
retry_count = 3):
|
53
|
+
"""
|
54
|
+
BAR数据
|
55
|
+
Parameters:
|
56
|
+
------------
|
57
|
+
ts_code:证券代码,支持股票,ETF/LOF,期货/期权,港股,数字货币
|
58
|
+
start_date:开始日期 YYYYMMDD
|
59
|
+
end_date:结束日期 YYYYMMDD
|
60
|
+
freq:支持1/5/15/30/60分钟,周/月/季/年
|
61
|
+
asset:证券类型 E:股票和交易所基金,I:沪深指数,C:数字货币,FT:期货 FD:基金/O期权/H港股/CB可转债
|
62
|
+
exchange:市场代码,用户数字货币行情
|
63
|
+
adj:复权类型,None不复权,qfq:前复权,hfq:后复权
|
64
|
+
ma:均线,支持自定义均线频度,如:ma5/ma10/ma20/ma60/maN
|
65
|
+
offset:开始行数(分页功能,从第几行开始取数据)
|
66
|
+
limit: 本次提取数据行数
|
67
|
+
factors因子数据,目前支持以下两种:
|
68
|
+
vr:量比,默认不返回,返回需指定:factor=['vr']
|
69
|
+
tor:换手率,默认不返回,返回需指定:factor=['tor']
|
70
|
+
以上两种都需要:factor=['vr', 'tor']
|
71
|
+
retry_count:网络重试次数
|
72
|
+
|
73
|
+
Return
|
74
|
+
----------
|
75
|
+
DataFrame
|
76
|
+
code:代码
|
77
|
+
open:开盘close/high/low/vol成交量/amount成交额/maN均价/vr量比/tor换手率
|
78
|
+
|
79
|
+
期货(asset='FT')
|
80
|
+
code/open/close/high/low/avg_price:均价 position:持仓量 vol:成交总量
|
81
|
+
"""
|
82
|
+
if (ts_code=='' or ts_code is None) and (adj is not None):
|
83
|
+
print('提取复权行情必须输入ts_code参数')
|
84
|
+
return
|
85
|
+
if len(freq.strip())>=3:
|
86
|
+
freq = freq.strip().lower()
|
87
|
+
else:
|
88
|
+
freq = freq.strip().upper() if asset != 'C' else freq.strip().lower()
|
89
|
+
|
90
|
+
if 'min' not in freq:
|
91
|
+
today= datetime.datetime.today().date()
|
92
|
+
today = str(today)[0:10]
|
93
|
+
start_date = '' if start_date is None else start_date
|
94
|
+
end_date = today if end_date == '' or end_date is None else end_date
|
95
|
+
start_date = start_date.replace('-', '')
|
96
|
+
end_date = end_date.replace('-', '')
|
97
|
+
ts_code = ts_code.strip().upper() if asset != 'C' else ts_code.strip().lower()
|
98
|
+
asset = asset.strip().upper()
|
99
|
+
api = api if api is not None else pro_api()
|
100
|
+
for _ in range(retry_count):
|
101
|
+
try:
|
102
|
+
if asset == 'E':
|
103
|
+
if freq == 'D':
|
104
|
+
data = api.daily(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
105
|
+
if factors is not None and len(factors) >0 :
|
106
|
+
ds = api.daily_basic(ts_code=ts_code, start_date=start_date, end_date=end_date)[['trade_date', 'turnover_rate', 'volume_ratio']]
|
107
|
+
ds = ds.set_index('trade_date')
|
108
|
+
data = data.set_index('trade_date')
|
109
|
+
data = data.merge(ds, left_index=True, right_index=True)
|
110
|
+
data = data.reset_index()
|
111
|
+
if ('tor' in factors) and ('vr' not in factors):
|
112
|
+
data = data.drop('volume_ratio', axis=1)
|
113
|
+
if ('vr' in factors) and ('tor' not in factors):
|
114
|
+
data = data.drop('turnover_rate', axis=1)
|
115
|
+
if freq == 'W':
|
116
|
+
data = api.weekly(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
117
|
+
if freq == 'M':
|
118
|
+
data = api.monthly(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
119
|
+
if 'min' in freq:
|
120
|
+
data = api.stk_mins(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
121
|
+
data['trade_date'] = data['trade_time'].map(lambda x: x.replace('-', '')[0:8])
|
122
|
+
data['pre_close'] = data['close'].shift(-1)
|
123
|
+
if adj is not None:
|
124
|
+
fcts = api.adj_factor(ts_code=ts_code, start_date=start_date, end_date=end_date)[['trade_date', 'adj_factor']]
|
125
|
+
if fcts.shape[0] == 0:
|
126
|
+
return None
|
127
|
+
data = data.set_index('trade_date', drop=False).merge(fcts.set_index('trade_date'), left_index=True, right_index=True, how='left')
|
128
|
+
if 'min' in freq:
|
129
|
+
data = data.sort_values('trade_time', ascending=False)
|
130
|
+
data['adj_factor'] = data['adj_factor'].fillna(method='bfill')
|
131
|
+
for col in PRICE_COLS:
|
132
|
+
if adj == 'hfq':
|
133
|
+
data[col] = data[col] * data['adj_factor']
|
134
|
+
if adj == 'qfq':
|
135
|
+
data[col] = data[col] * data['adj_factor'] / float(fcts['adj_factor'][0])
|
136
|
+
data[col] = data[col].map(FORMAT)
|
137
|
+
data[col] = data[col].astype(float)
|
138
|
+
if adjfactor is False:
|
139
|
+
data = data.drop('adj_factor', axis=1)
|
140
|
+
if 'min' not in freq:
|
141
|
+
data['change'] = data['close'] - data['pre_close']
|
142
|
+
data['pct_chg'] = data['change'] / data['pre_close'] * 100
|
143
|
+
data['pct_chg'] = data['pct_chg'].map(lambda x: FORMAT(x)).astype(float)
|
144
|
+
else:
|
145
|
+
data = data.drop(['trade_date', 'pre_close'], axis=1)
|
146
|
+
else:
|
147
|
+
data['pre_close'] = data['close'].shift(-1)
|
148
|
+
data['change'] = data['close'] - data['pre_close']
|
149
|
+
data['pct_chg'] = data['change'] / data['pre_close'] * 100
|
150
|
+
data['pct_chg'] = data['pct_chg'].map(lambda x: FORMAT(x)).astype(float)
|
151
|
+
elif asset == 'I':
|
152
|
+
if freq == 'D':
|
153
|
+
data = api.index_daily(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
154
|
+
if freq == 'W':
|
155
|
+
data = api.index_weekly(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
156
|
+
if freq == 'M':
|
157
|
+
data = api.index_monthly(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
158
|
+
if 'min' in freq:
|
159
|
+
data = api.stk_mins(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
160
|
+
elif asset == 'FT':
|
161
|
+
if freq == 'D':
|
162
|
+
data = api.fut_daily(ts_code=ts_code, start_date=start_date, end_date=end_date, exchange=exchange, offset=offset, limit=limit)
|
163
|
+
if 'min' in freq:
|
164
|
+
data = api.ft_mins(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
165
|
+
elif asset == 'O':
|
166
|
+
if freq == 'D':
|
167
|
+
data = api.opt_daily(ts_code=ts_code, start_date=start_date, end_date=end_date, exchange=exchange, offset=offset, limit=limit)
|
168
|
+
if 'min' in freq:
|
169
|
+
data = api.opt_mins(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
170
|
+
elif asset == 'CB':
|
171
|
+
if freq == 'D':
|
172
|
+
data = api.cb_daily(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
173
|
+
elif asset == 'FD':
|
174
|
+
if freq == 'D':
|
175
|
+
data = api.fund_daily(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
176
|
+
if 'min' in freq:
|
177
|
+
data = api.stk_mins(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
178
|
+
if asset == 'C':
|
179
|
+
if freq == 'd':
|
180
|
+
freq = 'daily'
|
181
|
+
elif freq == 'w':
|
182
|
+
freq = 'week'
|
183
|
+
data = api.coinbar(exchange=exchange, symbol=ts_code, freq=freq, start_dae=start_date, end_date=end_date,
|
184
|
+
contract_type=contract_type)
|
185
|
+
if ma is not None and len(ma) > 0:
|
186
|
+
for a in ma:
|
187
|
+
if isinstance(a, int):
|
188
|
+
data['ma%s'%a] = MA(data['close'], a).map(FORMAT).shift(-(a-1))
|
189
|
+
data['ma%s'%a] = data['ma%s'%a].astype(float)
|
190
|
+
data['ma_v_%s'%a] = MA(data['vol'], a).map(FORMAT).shift(-(a-1))
|
191
|
+
data['ma_v_%s'%a] = data['ma_v_%s'%a].astype(float)
|
192
|
+
data = data.reset_index(drop=True)
|
193
|
+
except Exception as e:
|
194
|
+
print(e)
|
195
|
+
else:
|
196
|
+
if fields is not None and fields != '':
|
197
|
+
f_list = [col.strip() for col in fields.split(',')]
|
198
|
+
data = data[f_list]
|
199
|
+
return data
|
200
|
+
raise IOError('ERROR.')
|
201
|
+
|
202
|
+
def pro_api(token='', timeout=30):
|
203
|
+
"""
|
204
|
+
初始化pro API,第一次可以通过ts.set_token('your token')来记录自己的token凭证,临时token可以通过本参数传入
|
205
|
+
"""
|
206
|
+
if token == '' or token is None:
|
207
|
+
token = upass.get_token()
|
208
|
+
if token is not None and token != '':
|
209
|
+
pro = client.DataApi(token=token, timeout=timeout)
|
210
|
+
return pro
|
211
|
+
else:
|
212
|
+
raise Exception('api init error.')
|
213
|
+
|
214
|
+
|
215
|
+
def pro_bar_vip(ts_code='', api=None, start_date='', end_date='', freq='D', asset='E',
|
216
|
+
exchange='',
|
217
|
+
adj = None,
|
218
|
+
ma = [],
|
219
|
+
factors = None,
|
220
|
+
adjfactor = False,
|
221
|
+
offset = None,
|
222
|
+
limit = None,
|
223
|
+
fields = '',
|
224
|
+
contract_type = '',
|
225
|
+
retry_count = 3):
|
226
|
+
"""
|
227
|
+
BAR数据
|
228
|
+
Parameters:
|
229
|
+
------------
|
230
|
+
ts_code:证券代码,支持股票,ETF/LOF,期货/期权,港股,数字货币
|
231
|
+
start_date:开始日期 YYYYMMDD
|
232
|
+
end_date:结束日期 YYYYMMDD
|
233
|
+
freq:支持1/5/15/30/60分钟,周/月/季/年
|
234
|
+
asset:证券类型 E:股票和交易所基金,I:沪深指数,C:数字货币,FT:期货 FD:基金/O期权/H港股/CB可转债
|
235
|
+
exchange:市场代码,用户数字货币行情
|
236
|
+
adj:复权类型,None不复权,qfq:前复权,hfq:后复权
|
237
|
+
ma:均线,支持自定义均线频度,如:ma5/ma10/ma20/ma60/maN
|
238
|
+
offset:开始行数(分页功能,从第几行开始取数据)
|
239
|
+
limit: 本次提取数据行数
|
240
|
+
factors因子数据,目前支持以下两种:
|
241
|
+
vr:量比,默认不返回,返回需指定:factor=['vr']
|
242
|
+
tor:换手率,默认不返回,返回需指定:factor=['tor']
|
243
|
+
以上两种都需要:factor=['vr', 'tor']
|
244
|
+
retry_count:网络重试次数
|
245
|
+
|
246
|
+
Return
|
247
|
+
----------
|
248
|
+
DataFrame
|
249
|
+
code:代码
|
250
|
+
open:开盘close/high/low/vol成交量/amount成交额/maN均价/vr量比/tor换手率
|
251
|
+
|
252
|
+
期货(asset='FT')
|
253
|
+
code/open/close/high/low/avg_price:均价 position:持仓量 vol:成交总量
|
254
|
+
"""
|
255
|
+
if (ts_code=='' or ts_code is None) and (adj is not None):
|
256
|
+
print('提取复权行情必须输入ts_code参数')
|
257
|
+
return
|
258
|
+
if len(freq.strip())>=3:
|
259
|
+
freq = freq.strip().lower()
|
260
|
+
else:
|
261
|
+
freq = freq.strip().upper() if asset != 'C' else freq.strip().lower()
|
262
|
+
|
263
|
+
if 'min' not in freq:
|
264
|
+
today= datetime.datetime.today().date()
|
265
|
+
today = str(today)[0:10]
|
266
|
+
start_date = '' if start_date is None else start_date
|
267
|
+
end_date = today if end_date == '' or end_date is None else end_date
|
268
|
+
start_date = start_date.replace('-', '')
|
269
|
+
end_date = end_date.replace('-', '')
|
270
|
+
ts_code = ts_code.strip().upper() if asset != 'C' else ts_code.strip().lower()
|
271
|
+
asset = asset.strip().upper()
|
272
|
+
api = api if api is not None else pro_api()
|
273
|
+
for _ in range(retry_count):
|
274
|
+
try:
|
275
|
+
if asset == 'E':
|
276
|
+
if freq == 'D':
|
277
|
+
data = api.daily_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
278
|
+
if factors is not None and len(factors) >0 :
|
279
|
+
ds = api.daily_basic_vip(ts_code=ts_code, start_date=start_date, end_date=end_date)[['trade_date', 'turnover_rate', 'volume_ratio']]
|
280
|
+
ds = ds.set_index('trade_date')
|
281
|
+
data = data.set_index('trade_date')
|
282
|
+
data = data.merge(ds, left_index=True, right_index=True)
|
283
|
+
data = data.reset_index()
|
284
|
+
if ('tor' in factors) and ('vr' not in factors):
|
285
|
+
data = data.drop('volume_ratio', axis=1)
|
286
|
+
if ('vr' in factors) and ('tor' not in factors):
|
287
|
+
data = data.drop('turnover_rate', axis=1)
|
288
|
+
if freq == 'W':
|
289
|
+
data = api.weekly_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
290
|
+
if freq == 'M':
|
291
|
+
data = api.monthly_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
292
|
+
if 'min' in freq:
|
293
|
+
data = api.stk_mins_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
294
|
+
data['trade_date'] = data['trade_time'].map(lambda x: x.replace('-', '')[0:8])
|
295
|
+
data['pre_close'] = data['close'].shift(-1)
|
296
|
+
if adj is not None:
|
297
|
+
fcts = api.adj_factor_vip(ts_code=ts_code, start_date=start_date, end_date=end_date)[['trade_date', 'adj_factor']]
|
298
|
+
if fcts.shape[0] == 0:
|
299
|
+
return None
|
300
|
+
data = data.set_index('trade_date', drop=False).merge(fcts.set_index('trade_date'), left_index=True, right_index=True, how='left')
|
301
|
+
if 'min' in freq:
|
302
|
+
data = data.sort_values('trade_time', ascending=False)
|
303
|
+
data['adj_factor'] = data['adj_factor'].fillna(method='bfill')
|
304
|
+
for col in PRICE_COLS:
|
305
|
+
if adj == 'hfq':
|
306
|
+
data[col] = data[col] * data['adj_factor']
|
307
|
+
if adj == 'qfq':
|
308
|
+
data[col] = data[col] * data['adj_factor'] / float(fcts['adj_factor'][0])
|
309
|
+
data[col] = data[col].map(FORMAT)
|
310
|
+
data[col] = data[col].astype(float)
|
311
|
+
if adjfactor is False:
|
312
|
+
data = data.drop('adj_factor', axis=1)
|
313
|
+
if 'min' not in freq:
|
314
|
+
data['change'] = data['close'] - data['pre_close']
|
315
|
+
data['pct_chg'] = data['change'] / data['pre_close'] * 100
|
316
|
+
data['pct_chg'] = data['pct_chg'].map(lambda x: FORMAT(x)).astype(float)
|
317
|
+
else:
|
318
|
+
data = data.drop(['trade_date', 'pre_close'], axis=1)
|
319
|
+
else:
|
320
|
+
data['pre_close'] = data['close'].shift(-1)
|
321
|
+
data['change'] = data['close'] - data['pre_close']
|
322
|
+
data['pct_chg'] = data['change'] / data['pre_close'] * 100
|
323
|
+
data['pct_chg'] = data['pct_chg'].map(lambda x: FORMAT(x)).astype(float)
|
324
|
+
elif asset == 'I':
|
325
|
+
if freq == 'D':
|
326
|
+
data = api.index_daily_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
327
|
+
if freq == 'W':
|
328
|
+
data = api.index_weekly_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
329
|
+
if freq == 'M':
|
330
|
+
data = api.index_monthly_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
331
|
+
if 'min' in freq:
|
332
|
+
data = api.stk_mins_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
333
|
+
elif asset == 'FT':
|
334
|
+
if freq == 'D':
|
335
|
+
data = api.fut_daily_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, exchange=exchange, offset=offset, limit=limit)
|
336
|
+
if 'min' in freq:
|
337
|
+
data = api.ft_mins_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
338
|
+
elif asset == 'O':
|
339
|
+
if freq == 'D':
|
340
|
+
data = api.opt_daily_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, exchange=exchange, offset=offset, limit=limit)
|
341
|
+
if 'min' in freq:
|
342
|
+
data = api.opt_mins_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
343
|
+
elif asset == 'CB':
|
344
|
+
if freq == 'D':
|
345
|
+
data = api.cb_daily_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
346
|
+
elif asset == 'FD':
|
347
|
+
if freq == 'D':
|
348
|
+
data = api.fund_daily_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
349
|
+
if 'min' in freq:
|
350
|
+
data = api.stk_mins_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
351
|
+
if asset == 'C':
|
352
|
+
if freq == 'd':
|
353
|
+
freq = 'daily'
|
354
|
+
elif freq == 'w':
|
355
|
+
freq = 'week'
|
356
|
+
data = api.coinbar(exchange=exchange, symbol=ts_code, freq=freq, start_dae=start_date, end_date=end_date,
|
357
|
+
contract_type=contract_type)
|
358
|
+
if ma is not None and len(ma) > 0:
|
359
|
+
for a in ma:
|
360
|
+
if isinstance(a, int):
|
361
|
+
data['ma%s'%a] = MA(data['close'], a).map(FORMAT).shift(-(a-1))
|
362
|
+
data['ma%s'%a] = data['ma%s'%a].astype(float)
|
363
|
+
data['ma_v_%s'%a] = MA(data['vol'], a).map(FORMAT).shift(-(a-1))
|
364
|
+
data['ma_v_%s'%a] = data['ma_v_%s'%a].astype(float)
|
365
|
+
data = data.reset_index(drop=True)
|
366
|
+
except Exception as e:
|
367
|
+
print(e)
|
368
|
+
else:
|
369
|
+
if fields is not None and fields != '':
|
370
|
+
f_list = [col.strip() for col in fields.split(',')]
|
371
|
+
data = data[f_list]
|
372
|
+
return data
|
373
|
+
raise IOError('ERROR.')
|
374
|
+
|
375
|
+
|
376
|
+
def subs(token=''):
|
377
|
+
if token == '' or token is None:
|
378
|
+
token = upass.get_token()
|
379
|
+
|
380
|
+
from tushare.subs.ts_subs.subscribe import TsSubscribe
|
381
|
+
app = TsSubscribe(token=token)
|
382
|
+
return app
|
383
|
+
|
384
|
+
|
385
|
+
def ht_subs(username, password):
|
386
|
+
from tushare.subs.ht_subs.subscribe import InsightSubscribe
|
387
|
+
app = InsightSubscribe(username, password)
|
388
|
+
return app
|
389
|
+
|
390
|
+
|
391
|
+
if __name__ == '__main__':
|
392
|
+
# upass.set_token('')
|
393
|
+
pro = pro_api()
|
394
|
+
df = pro_bar(ts_code='688539.SH', adj='qfq')
|
395
|
+
print(df)
|