├── .gitignore
├── .idea
└── inspectionProfiles
│ ├── Project_Default.xml
│ └── profiles_settings.xml
├── README.md
├── docs
├── zipline_arch.graphml
└── zipline_arch.png
├── setup.py
├── test
├── test_cn_squant2_run.py
└── test_cn_squant2_run_text.py
└── zipline_cn_databundle
├── __init__.py
├── all_stocks.py
├── index_list
└── __init__.py
├── loader.py
├── squant_source.py
├── tdx
├── __init__.py
└── reader.py
├── tushare_source.py
└── yahoo.py
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/python,pycharm
3 |
4 | ### Python ###
5 | # Byte-compiled / optimized / DLL files
6 | __pycache__/
7 | *.py[cod]
8 | *$py.class
9 |
10 | # C extensions
11 | *.so
12 |
13 | # Distribution / packaging
14 | .Python
15 | env/
16 | build/
17 | develop-eggs/
18 | dist/
19 | downloads/
20 | eggs/
21 | .eggs/
22 | lib/
23 | lib64/
24 | parts/
25 | sdist/
26 | var/
27 | *.egg-info/
28 | .installed.cfg
29 | *.egg
30 |
31 | # PyInstaller
32 | # Usually these files are written by a python script from a template
33 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
34 | *.manifest
35 | *.spec
36 |
37 | # Installer logs
38 | pip-log.txt
39 | pip-delete-this-directory.txt
40 |
41 | # Unit test / coverage reports
42 | htmlcov/
43 | .tox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *,cover
50 | .hypothesis/
51 |
52 | # Translations
53 | *.mo
54 | *.pot
55 |
56 | # Django stuff:
57 | *.log
58 | local_settings.py
59 |
60 | # Flask stuff:
61 | instance/
62 | .webassets-cache
63 |
64 | # Scrapy stuff:
65 | .scrapy
66 |
67 | # Sphinx documentation
68 | docs/_build/
69 |
70 | # PyBuilder
71 | target/
72 |
73 | # IPython Notebook
74 | .ipynb_checkpoints
75 |
76 | # pyenv
77 | .python-version
78 |
79 | # celery beat schedule file
80 | celerybeat-schedule
81 |
82 | # dotenv
83 | .env
84 |
85 | # virtualenv
86 | venv/
87 | ENV/
88 |
89 | # Spyder project settings
90 | .spyderproject
91 |
92 | # Rope project settings
93 | .ropeproject
94 |
95 |
96 | ### PyCharm ###
97 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
98 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
99 |
100 | # User-specific stuff:
101 | .idea/workspace.xml
102 | .idea/tasks.xml
103 | .idea/dictionaries
104 | .idea/vcs.xml
105 | .idea/jsLibraryMappings.xml
106 |
107 | # Sensitive or high-churn files:
108 | .idea/dataSources.ids
109 | .idea/dataSources.xml
110 | .idea/dataSources.local.xml
111 | .idea/sqlDataSources.xml
112 | .idea/dynamic.xml
113 | .idea/uiDesigner.xml
114 |
115 | # Gradle:
116 | .idea/gradle.xml
117 | .idea/libraries
118 |
119 | # Mongo Explorer plugin:
120 | .idea/mongoSettings.xml
121 |
122 | ## File-based project format:
123 | *.iws
124 |
125 | ## Plugin-specific files:
126 |
127 | # IntelliJ
128 | /out/
129 |
130 | # mpeltonen/sbt-idea plugin
131 | .idea_modules/
132 |
133 | # JIRA plugin
134 | atlassian-ide-plugin.xml
135 |
136 | # Crashlytics plugin (for Android Studio and IntelliJ)
137 | com_crashlytics_export_strings.xml
138 | crashlytics.properties
139 | crashlytics-build.properties
140 | fabric.properties
141 |
142 | ### PyCharm Patch ###
143 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
144 |
145 | # *.iml
146 | # modules.xml
147 | # .idea/misc.xml
148 | # *.ipr
149 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Equtity Data bundle of chinese exchange market for Zipline
2 | =======
3 |
4 |
5 | Installation
6 | -----
7 |
8 | ```
9 | pip install zipline-cn-databundle
10 | ```
11 | or
12 |
13 | ```
14 | python setup.py install
15 | ```
16 |
17 | Usage
18 | ----
19 |
20 | We need Re-Implement All Features instead of old ways
21 |
22 | Working in progress!!!!
23 |
24 | ### Others
25 |
26 | #### Get All Stocks info in Chinese Market
27 |
28 | ```
29 |
30 | get_all_stocks()
31 |
32 | ```
33 |
34 | returns infomations in pandas format
35 |
36 | ```
37 | name industry area pe outstanding totals totalAssets \
38 | code
39 | 601997 N贵银 银行 贵州 9.11 50000.00 229859.19 28492688.00
40 | 000972 中基健康 食品 新疆 0.00 77128.35 77128.35 229892.13
41 | 601011 宝泰隆 焦炭加工 黑龙江 1240.98 130874.56 136750.00 794420.81
42 | ....
43 | ```
--------------------------------------------------------------------------------
/docs/zipline_arch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rainx/zipline_cn_databundle/92ba9258ebdf836180651cea1365ebcbd585e60d/docs/zipline_arch.png
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup, find_packages
2 |
3 | setup(
4 | name = "zipline-cn-databundle",
5 | version = "0.5",
6 | author= 'RainX',
7 | description='ingest zipline databundle source for chinese market',
8 | packages = find_packages(),
9 | install_requires=[
10 | 'pandas-datareader',
11 | ],
12 | entry_points={
13 | 'console_scripts': [
14 | 'zipline-cn-databundle-update=zipline_cn_databundle:zipline_cn_databundle_update',
15 | 'gen-all-index-benchmark-data=zipline_cn_databundle.index_list.__init__:gen_data',
16 | ]
17 | }
18 | )
19 |
20 |
--------------------------------------------------------------------------------
/test/test_cn_squant2_run.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | from zipline.data.bundles import register
3 | from zipline_cn_databundle.squant_source import squant_bundle
4 | import pandas as pd
5 | import os
6 |
7 | from zipline.api import (
8 | schedule_function,
9 | symbol,
10 | order_target_percent,
11 | date_rules,
12 | record
13 | )
14 | import re
15 | from zipline.algorithm import TradingAlgorithm
16 | from zipline.finance.trading import TradingEnvironment
17 | from zipline.utils.calendars import get_calendar, register_calendar
18 | from zipline.finance import trading
19 | from zipline.utils.factory import create_simulation_parameters
20 | from zipline.data.bundles.core import load
21 | from zipline.data.data_portal import DataPortal
22 |
23 | from zipline_cn_databundle.loader import load_market_data
24 |
25 | # register SHSZ
26 |
27 | from cn_stock_holidays.zipline.default_calendar import shsz_calendar
28 |
29 |
30 | bundle = 'cn_squant'
31 |
32 | start_session_str = '2011-01-05'
33 |
34 | register(
35 | bundle,
36 | squant_bundle,
37 | "SHSZ",
38 | pd.Timestamp(start_session_str, tz='utc'),
39 | pd.Timestamp('2016-10-31', tz='utc')
40 | )
41 |
42 |
43 | bundle_data = load(
44 | bundle,
45 | os.environ,
46 | None,
47 | )
48 |
49 | prefix, connstr = re.split(
50 | r'sqlite:///',
51 | str(bundle_data.asset_finder.engine.url),
52 | maxsplit=1,
53 | )
54 |
55 | env = trading.environment = TradingEnvironment(asset_db_path=connstr,
56 | trading_calendar=shsz_calendar,
57 | bm_symbol='000001.SS',
58 | load=load_market_data)
59 |
60 |
61 | first_trading_day = \
62 | bundle_data.equity_minute_bar_reader.first_trading_day
63 | data = DataPortal(
64 | env.asset_finder, shsz_calendar,
65 | first_trading_day=first_trading_day,
66 | equity_minute_reader=bundle_data.equity_minute_bar_reader,
67 | equity_daily_reader=bundle_data.equity_daily_bar_reader,
68 | adjustment_reader=bundle_data.adjustment_reader,
69 | )
70 |
71 |
72 | def initialize(context):
73 | schedule_function(handle_daily_data, date_rules.every_day())
74 |
75 | def handle_daily_data(context, data):
76 | sym = symbol('000001.SZ')
77 |
78 | # 计算均线
79 | short_mavg = data.history(sym, 'close', 5, '1d').mean()
80 | long_mavg = data.history(sym, 'close', 10, '1d').mean()
81 |
82 | # 交易逻辑
83 | if short_mavg > long_mavg:
84 | # 满仓
85 | order_target_percent(sym, 1)
86 | elif short_mavg < long_mavg:
87 | # 清仓
88 | order_target_percent(sym, 0)
89 |
90 | # Save values for later inspection
91 | record(价格=data.current(sym, 'price'),
92 | short_mavg=short_mavg,
93 | long_mavg=long_mavg)
94 |
95 | def analyze(context, perf):
96 | fig = plt.figure(figsize=(14,13))
97 | ax1 = fig.add_subplot(211)
98 | perf.portfolio_value.plot(ax=ax1, grid=True)
99 | ax1.set_ylabel('portfolio value in $')
100 |
101 | ax2 = fig.add_subplot(212)
102 | perf['GOOG'].plot(ax=ax2)
103 | perf[['short_mavg', 'long_mavg']].plot(ax=ax2)
104 |
105 | perf_trans = perf.ix[[t != [] for t in perf.transactions]]
106 | buys = perf_trans.ix[[t[0]['amount'] > 0 for t in perf_trans.transactions]]
107 | sells = perf_trans.ix[
108 | [t[0]['amount'] < 0 for t in perf_trans.transactions]]
109 | ax2.plot(buys.index, perf.short_mavg.ix[buys.index],
110 | '^', markersize=4, color='m')
111 | ax2.plot(sells.index, perf.short_mavg.ix[sells.index],
112 | 'v', markersize=4, color='k')
113 | ax2.set_ylabel('price in $')
114 | plt.legend(loc=0)
115 | plt.show()
116 | plt.imsave("output.png")
117 |
118 |
119 | if __name__ == '__main__':
120 | sim_params = create_simulation_parameters(
121 | start=pd.to_datetime(start_session_str + " 00:00:00").tz_localize("Asia/Shanghai"),
122 | end=pd.to_datetime("2012-01-01 00:00:00").tz_localize("Asia/Shanghai"),
123 | data_frequency="daily", emission_rate="daily", trading_calendar=shsz_calendar)
124 |
125 | algor_obj = TradingAlgorithm(initialize=initialize,
126 | handle_data=None,
127 | sim_params=sim_params,
128 | env=trading.environment,
129 | trading_calendar=shsz_calendar)
130 | # not use run method of TradingAlgorithm
131 | #perf_manual = algor_obj.run(data)
132 | #perf_manual.to_pickle('/tmp/perf.pickle')
133 |
134 | algor_obj.data_portal = data
135 | algor_obj._assets_from_source = \
136 | algor_obj.trading_environment.asset_finder.retrieve_all(
137 | algor_obj.trading_environment.asset_finder.sids
138 | )
139 | algor_obj.perf_tracker = None
140 | import demjson
141 | import pickle
142 | import pprint
143 | try:
144 | perfs = []
145 | for perf in algor_obj.get_generator():
146 | perfs.append(perf)
147 | print('-' * 40)
148 | try:
149 | print(demjson.encode(perf))
150 | except Exception as e:
151 | pprint.pprint(e)
152 | print('-' * 40)
153 |
154 | pickle.dump(perfs, open('/tmp/raw_perfs.pickle', 'wb'))
155 | daily_stats = algor_obj._create_daily_stats(perfs)
156 | print('*' * 40)
157 | print('daily_stats')
158 | print('*' * 40)
159 | print(daily_stats)
160 | daily_stats.to_pickle('/tmp/perf.pickle')
161 | finally:
162 | algor_obj.data_portal = None
163 |
--------------------------------------------------------------------------------
/test/test_cn_squant2_run_text.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | from zipline.data.bundles import register
3 | from zipline_cn_databundle.squant_source import squant_bundle
4 | import pandas as pd
5 | import os
6 |
7 | from zipline.api import (
8 | schedule_function,
9 | symbol,
10 | order_target_percent,
11 | date_rules,
12 | record
13 | )
14 | import re
15 | from zipline.algorithm import TradingAlgorithm
16 | from zipline.finance.trading import TradingEnvironment
17 | from zipline.utils.calendars import get_calendar, register_calendar
18 | from zipline.finance import trading
19 | from zipline.utils.factory import create_simulation_parameters
20 | from zipline.data.bundles.core import load
21 | from zipline.data.data_portal import DataPortal
22 |
23 | from zipline_cn_databundle.loader import load_market_data
24 |
25 | # register SHSZ
26 |
27 | from cn_stock_holidays.zipline.default_calendar import shsz_calendar
28 |
29 |
30 | bundle = 'cn_squant'
31 |
32 | start_session_str = '2011-01-05'
33 |
34 | register(
35 | bundle,
36 | squant_bundle,
37 | "SHSZ",
38 | pd.Timestamp(start_session_str, tz='utc'),
39 | pd.Timestamp('2016-10-31', tz='utc')
40 | )
41 |
42 |
43 | bundle_data = load(
44 | bundle,
45 | os.environ,
46 | None,
47 | )
48 |
49 | prefix, connstr = re.split(
50 | r'sqlite:///',
51 | str(bundle_data.asset_finder.engine.url),
52 | maxsplit=1,
53 | )
54 |
55 | env = trading.environment = TradingEnvironment(asset_db_path=connstr,
56 | trading_calendar=shsz_calendar,
57 | bm_symbol='000001.SS',
58 | load=load_market_data)
59 |
60 |
61 | first_trading_day = \
62 | bundle_data.equity_minute_bar_reader.first_trading_day
63 | data = DataPortal(
64 | env.asset_finder, shsz_calendar,
65 | first_trading_day=first_trading_day,
66 | equity_minute_reader=bundle_data.equity_minute_bar_reader,
67 | equity_daily_reader=bundle_data.equity_daily_bar_reader,
68 | adjustment_reader=bundle_data.adjustment_reader,
69 | )
70 |
71 |
72 | strategy = """
73 | from zipline.api import (
74 | schedule_function,
75 | symbol,
76 | order_target_percent,
77 | date_rules,
78 | record
79 | )
80 |
81 | def initialize(context):
82 | schedule_function(handle_daily_data, date_rules.every_day())
83 |
84 | def handle_daily_data(context, data):
85 | sym = symbol('000001.SZ')
86 |
87 | # 计算均线
88 | short_mavg = data.history(sym, 'close', 5, '1d').mean()
89 | long_mavg = data.history(sym, 'close', 10, '1d').mean()
90 |
91 | # 交易逻辑
92 | if short_mavg > long_mavg:
93 | # 满仓
94 | order_target_percent(sym, 1)
95 | elif short_mavg < long_mavg:
96 | # 清仓
97 | order_target_percent(sym, 0)
98 |
99 | # Save values for later inspection
100 | record(价格=data.current(sym, 'price'),
101 | short_mavg=short_mavg,
102 | long_mavg=long_mavg)
103 | """
104 |
105 | def analyze(context, perf):
106 | fig = plt.figure(figsize=(14,13))
107 | ax1 = fig.add_subplot(211)
108 | perf.portfolio_value.plot(ax=ax1, grid=True)
109 | ax1.set_ylabel('portfolio value in $')
110 |
111 | ax2 = fig.add_subplot(212)
112 | perf['GOOG'].plot(ax=ax2)
113 | perf[['short_mavg', 'long_mavg']].plot(ax=ax2)
114 |
115 | perf_trans = perf.ix[[t != [] for t in perf.transactions]]
116 | buys = perf_trans.ix[[t[0]['amount'] > 0 for t in perf_trans.transactions]]
117 | sells = perf_trans.ix[
118 | [t[0]['amount'] < 0 for t in perf_trans.transactions]]
119 | ax2.plot(buys.index, perf.short_mavg.ix[buys.index],
120 | '^', markersize=4, color='m')
121 | ax2.plot(sells.index, perf.short_mavg.ix[sells.index],
122 | 'v', markersize=4, color='k')
123 | ax2.set_ylabel('price in $')
124 | plt.legend(loc=0)
125 | plt.show()
126 | plt.imsave("output.png")
127 |
128 |
129 | if __name__ == '__main__':
130 | sim_params = create_simulation_parameters(
131 | start=pd.to_datetime(start_session_str + " 00:00:00").tz_localize("Asia/Shanghai"),
132 | end=pd.to_datetime("2012-01-01 00:00:00").tz_localize("Asia/Shanghai"),
133 | data_frequency="daily", emission_rate="daily", trading_calendar=shsz_calendar)
134 |
135 | algor_obj = TradingAlgorithm(script=strategy,
136 | sim_params=sim_params,
137 | env=trading.environment,
138 | trading_calendar=shsz_calendar)
139 | # not use run method of TradingAlgorithm
140 | #perf_manual = algor_obj.run(data)
141 | #perf_manual.to_pickle('/tmp/perf.pickle')
142 |
143 | algor_obj.data_portal = data
144 | algor_obj._assets_from_source = \
145 | algor_obj.trading_environment.asset_finder.retrieve_all(
146 | algor_obj.trading_environment.asset_finder.sids
147 | )
148 | algor_obj.perf_tracker = None
149 | import demjson
150 | import pickle
151 | import pprint
152 | try:
153 | perfs = []
154 | for perf in algor_obj.get_generator():
155 | perfs.append(perf)
156 | print('-' * 40)
157 | try:
158 | print(demjson.encode(perf))
159 | except Exception as e:
160 | pprint.pprint(perf)
161 | print('-' * 40)
162 |
163 | pickle.dump(perfs, open('/tmp/raw_perfs.pickle', 'wb'))
164 | daily_stats = algor_obj._create_daily_stats(perfs)
165 | print('*' * 40)
166 | print('daily_stats')
167 | print('*' * 40)
168 | print(daily_stats)
169 | daily_stats.to_pickle('/tmp/perf.pickle')
170 | finally:
171 | algor_obj.data_portal = None
172 |
--------------------------------------------------------------------------------
/zipline_cn_databundle/__init__.py:
--------------------------------------------------------------------------------
1 | from .yahoo import (
2 | register_cn_bundle_from_yahoo,
3 | get_all_yahoo_stock_names,
4 | check_code,
5 | get_filtered_symbols,
6 | zipline_cn_databundle_update,
7 | )
8 |
9 | from .all_stocks import (
10 | get_all_stocks,
11 | )
--------------------------------------------------------------------------------
/zipline_cn_databundle/all_stocks.py:
--------------------------------------------------------------------------------
1 | """
2 | Get all stock name
3 | """
4 |
5 | import requests
6 | from io import StringIO
7 | import pandas as pd
8 | import os
9 | import shutil
10 | import sys
11 |
12 | ALL_STOCKS_URL = 'http://218.244.146.57/static/all.csv'
13 |
14 |
15 | def get_cache_dir():
16 | home_path = os.path.expanduser('~')
17 | cache_dir = os.path.join(home_path, '.zipline_cn_databundle')
18 |
19 | if not os.path.isdir(cache_dir):
20 | os.makedirs(cache_dir)
21 | return cache_dir
22 |
23 | def get_cache_path():
24 | cache_dir = get_cache_dir()
25 | return os.path.join(cache_dir, 'all_stocks.csv')
26 |
27 | def get_all_stocks(cache=True):
28 | """
29 | used idea from tushare
30 | :return: data frame of stock list
31 | """
32 | cache_path = get_cache_path()
33 |
34 | #use cache
35 | if cache and os.path.isfile(cache_path):
36 | df = pd.read_csv(cache_path, dtype={'code': 'object'})
37 | df = df.set_index('code')
38 | return df
39 |
40 | response = requests.get(ALL_STOCKS_URL)
41 | text = response.content
42 | text = text.decode('GBK')
43 | text = text.replace('--', '')
44 | df = pd.read_csv(StringIO(text), dtype={'code': 'object'})
45 | df = df.set_index('code')
46 | # write to cache
47 | with open(cache_path, 'wb') as f:
48 | f.write(text.encode('utf-8'))
49 |
50 | return df
51 |
52 |
53 |
54 | if __name__ == '__main__':
55 | print(get_all_stocks(True))
--------------------------------------------------------------------------------
/zipline_cn_databundle/index_list/__init__.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | from io import StringIO
3 | import click
4 | import os
5 | import sys
6 |
7 | JSON_DATA = """
8 | [
9 | {"name": "上证指数", "symbol": "000001.XSHG"},
10 | {"name": "A股指数", "symbol": "000002.XSHG"},
11 | {"name": "B股指数", "symbol": "000003.XSHG"},
12 | {"name": "工业指数", "symbol": "000004.XSHG"},
13 | {"name": "商业指数", "symbol": "000005.XSHG"},
14 | {"name": "地产指数", "symbol": "000006.XSHG"},
15 | {"name": "公用指数", "symbol": "000007.XSHG"},
16 | {"name": "综合指数", "symbol": "000008.XSHG"},
17 | {"name": "上证380", "symbol": "000009.XSHG"},
18 | {"name": "上证180", "symbol": "000010.XSHG"},
19 | {"name": "基金指数", "symbol": "000011.XSHG"},
20 | {"name": "国债指数", "symbol": "000012.XSHG"},
21 | {"name": "上证企业债指数", "symbol": "000013.XSHG"},
22 | {"name": "红利指数", "symbol": "000015.XSHG"},
23 | {"name": "上证50", "symbol": "000016.XSHG"},
24 | {"name": "新综指", "symbol": "000017.XSHG"},
25 | {"name": "180金融", "symbol": "000018.XSHG"},
26 | {"name": "治理指数", "symbol": "000019.XSHG"},
27 | {"name": "中型综指", "symbol": "000020.XSHG"},
28 | {"name": "180治理", "symbol": "000021.XSHG"},
29 | {"name": "上证公司债指数", "symbol": "000022.XSHG"},
30 | {"name": "180基建", "symbol": "000025.XSHG"},
31 | {"name": "180资源", "symbol": "000026.XSHG"},
32 | {"name": "180运输", "symbol": "000027.XSHG"},
33 | {"name": "180成长", "symbol": "000028.XSHG"},
34 | {"name": "180价值", "symbol": "000029.XSHG"},
35 | {"name": "180R成长", "symbol": "000030.XSHG"},
36 | {"name": "180R价值", "symbol": "000031.XSHG"},
37 | {"name": "上证能源", "symbol": "000032.XSHG"},
38 | {"name": "上证材料", "symbol": "000033.XSHG"},
39 | {"name": "上证工业", "symbol": "000034.XSHG"},
40 | {"name": "上证可选", "symbol": "000035.XSHG"},
41 | {"name": "上证消费", "symbol": "000036.XSHG"},
42 | {"name": "上证医药", "symbol": "000037.XSHG"},
43 | {"name": "上证金融", "symbol": "000038.XSHG"},
44 | {"name": "上证信息", "symbol": "000039.XSHG"},
45 | {"name": "上证电信", "symbol": "000040.XSHG"},
46 | {"name": "上证公用", "symbol": "000041.XSHG"},
47 | {"name": "上证央企", "symbol": "000042.XSHG"},
48 | {"name": "超大盘", "symbol": "000043.XSHG"},
49 | {"name": "上证中盘", "symbol": "000044.XSHG"},
50 | {"name": "上证小盘", "symbol": "000045.XSHG"},
51 | {"name": "上证中小", "symbol": "000046.XSHG"},
52 | {"name": "上证全指", "symbol": "000047.XSHG"},
53 | {"name": "责任指数", "symbol": "000048.XSHG"},
54 | {"name": "上证民企", "symbol": "000049.XSHG"},
55 | {"name": "50等权", "symbol": "000050.XSHG"},
56 | {"name": "180等权", "symbol": "000051.XSHG"},
57 | {"name": "50基本", "symbol": "000052.XSHG"},
58 | {"name": "180基本", "symbol": "000053.XSHG"},
59 | {"name": "上证海外", "symbol": "000054.XSHG"},
60 | {"name": "上证地企", "symbol": "000055.XSHG"},
61 | {"name": "上证国企", "symbol": "000056.XSHG"},
62 | {"name": "全指成长", "symbol": "000057.XSHG"},
63 | {"name": "全指价值", "symbol": "000058.XSHG"},
64 | {"name": "全R成长", "symbol": "000059.XSHG"},
65 | {"name": "全R价值", "symbol": "000060.XSHG"},
66 | {"name": "沪企债30", "symbol": "000061.XSHG"},
67 | {"name": "上证沪企", "symbol": "000062.XSHG"},
68 | {"name": "上证周期", "symbol": "000063.XSHG"},
69 | {"name": "非周期", "symbol": "000064.XSHG"},
70 | {"name": "上证龙头", "symbol": "000065.XSHG"},
71 | {"name": "上证商品", "symbol": "000066.XSHG"},
72 | {"name": "上证新兴", "symbol": "000067.XSHG"},
73 | {"name": "上证资源", "symbol": "000068.XSHG"},
74 | {"name": "消费80", "symbol": "000069.XSHG"},
75 | {"name": "能源等权", "symbol": "000070.XSHG"},
76 | {"name": "材料等权", "symbol": "000071.XSHG"},
77 | {"name": "工业等权", "symbol": "000072.XSHG"},
78 | {"name": "可选等权", "symbol": "000073.XSHG"},
79 | {"name": "消费等权", "symbol": "000074.XSHG"},
80 | {"name": "医药等权", "symbol": "000075.XSHG"},
81 | {"name": "金融等权", "symbol": "000076.XSHG"},
82 | {"name": "信息等权", "symbol": "000077.XSHG"},
83 | {"name": "电信等权", "symbol": "000078.XSHG"},
84 | {"name": "公用等权", "symbol": "000079.XSHG"},
85 | {"name": "上证流通", "symbol": "000090.XSHG"},
86 | {"name": "沪财中小", "symbol": "000091.XSHG"},
87 | {"name": "资源50", "symbol": "000092.XSHG"},
88 | {"name": "180分层", "symbol": "000093.XSHG"},
89 | {"name": "上证上游", "symbol": "000094.XSHG"},
90 | {"name": "上证中游", "symbol": "000095.XSHG"},
91 | {"name": "上证下游", "symbol": "000096.XSHG"},
92 | {"name": "高端装备", "symbol": "000097.XSHG"},
93 | {"name": "上证F200", "symbol": "000098.XSHG"},
94 | {"name": "上证F300", "symbol": "000099.XSHG"},
95 | {"name": "上证F500", "symbol": "000100.XSHG"},
96 | {"name": "5年信用", "symbol": "000101.XSHG"},
97 | {"name": "沪投资品", "symbol": "000102.XSHG"},
98 | {"name": "沪消费品", "symbol": "000103.XSHG"},
99 | {"name": "380能源", "symbol": "000104.XSHG"},
100 | {"name": "380材料", "symbol": "000105.XSHG"},
101 | {"name": "380工业", "symbol": "000106.XSHG"},
102 | {"name": "380可选", "symbol": "000107.XSHG"},
103 | {"name": "380消费", "symbol": "000108.XSHG"},
104 | {"name": "380医药", "symbol": "000109.XSHG"},
105 | {"name": "380金融", "symbol": "000110.XSHG"},
106 | {"name": "380信息", "symbol": "000111.XSHG"},
107 | {"name": "380电信", "symbol": "000112.XSHG"},
108 | {"name": "380公用", "symbol": "000113.XSHG"},
109 | {"name": "持续产业", "symbol": "000114.XSHG"},
110 | {"name": "380等权", "symbol": "000115.XSHG"},
111 | {"name": "信用100", "symbol": "000116.XSHG"},
112 | {"name": "380成长", "symbol": "000117.XSHG"},
113 | {"name": "380价值", "symbol": "000118.XSHG"},
114 | {"name": "380R成长", "symbol": "000119.XSHG"},
115 | {"name": "380R价值", "symbol": "000120.XSHG"},
116 | {"name": "医药主题", "symbol": "000121.XSHG"},
117 | {"name": "农业主题", "symbol": "000122.XSHG"},
118 | {"name": "180动态", "symbol": "000123.XSHG"},
119 | {"name": "180稳定", "symbol": "000125.XSHG"},
120 | {"name": "消费50", "symbol": "000126.XSHG"},
121 | {"name": "380基本", "symbol": "000128.XSHG"},
122 | {"name": "180波动", "symbol": "000129.XSHG"},
123 | {"name": "380波动", "symbol": "000130.XSHG"},
124 | {"name": "上证高新", "symbol": "000131.XSHG"},
125 | {"name": "上证100", "symbol": "000132.XSHG"},
126 | {"name": "上证150", "symbol": "000133.XSHG"},
127 | {"name": "上证银行", "symbol": "000134.XSHG"},
128 | {"name": "180高贝", "symbol": "000135.XSHG"},
129 | {"name": "180低贝", "symbol": "000136.XSHG"},
130 | {"name": "380高贝", "symbol": "000137.XSHG"},
131 | {"name": "380低贝", "symbol": "000138.XSHG"},
132 | {"name": "上证转债", "symbol": "000139.XSHG"},
133 | {"name": "380动态", "symbol": "000141.XSHG"},
134 | {"name": "380稳定", "symbol": "000142.XSHG"},
135 | {"name": "优势资源", "symbol": "000145.XSHG"},
136 | {"name": "优势制造", "symbol": "000146.XSHG"},
137 | {"name": "优势消费", "symbol": "000147.XSHG"},
138 | {"name": "消费领先", "symbol": "000148.XSHG"},
139 | {"name": "180红利", "symbol": "000149.XSHG"},
140 | {"name": "380红利", "symbol": "000150.XSHG"},
141 | {"name": "上国红利", "symbol": "000151.XSHG"},
142 | {"name": "上央红利", "symbol": "000152.XSHG"},
143 | {"name": "上民红利", "symbol": "000153.XSHG"},
144 | {"name": "市值百强", "symbol": "000155.XSHG"},
145 | {"name": "上证环保", "symbol": "000158.XSHG"},
146 | {"name": "上证沪股通指数", "symbol": "000159.XSHG"},
147 | {"name": "上证一带一路主题指数", "symbol": "000160.XSHG"},
148 | {"name": "上证中国制造2025主题指数", "symbol": "000161.XSHG"},
149 | {"name": "上证互联网+主题指数", "symbol": "000162.XSHG"},
150 | {"name": "沪深300", "symbol": "000300.XSHG"},
151 | {"name": "资源80", "symbol": "000801.XSHG"},
152 | {"name": "500沪市", "symbol": "000802.XSHG"},
153 | {"name": "300波动", "symbol": "000803.XSHG"},
154 | {"name": "500波动", "symbol": "000804.XSHG"},
155 | {"name": "A股资源", "symbol": "000805.XSHG"},
156 | {"name": "消费服务", "symbol": "000806.XSHG"},
157 | {"name": "食品饮料", "symbol": "000807.XSHG"},
158 | {"name": "医药生物", "symbol": "000808.XSHG"},
159 | {"name": "细分农业", "symbol": "000809.XSHG"},
160 | {"name": "细分能源", "symbol": "000810.XSHG"},
161 | {"name": "细分有色", "symbol": "000811.XSHG"},
162 | {"name": "细分机械", "symbol": "000812.XSHG"},
163 | {"name": "细分化工", "symbol": "000813.XSHG"},
164 | {"name": "细分医药", "symbol": "000814.XSHG"},
165 | {"name": "细分食品", "symbol": "000815.XSHG"},
166 | {"name": "细分地产", "symbol": "000816.XSHG"},
167 | {"name": "兴证海峡", "symbol": "000817.XSHG"},
168 | {"name": "细分金融", "symbol": "000818.XSHG"},
169 | {"name": "有色金属", "symbol": "000819.XSHG"},
170 | {"name": "煤炭指数", "symbol": "000820.XSHG"},
171 | {"name": "300红利", "symbol": "000821.XSHG"},
172 | {"name": "500红利", "symbol": "000822.XSHG"},
173 | {"name": "中证800有色金属指数", "symbol": "000823.XSHG"},
174 | {"name": "国企红利", "symbol": "000824.XSHG"},
175 | {"name": "央企红利", "symbol": "000825.XSHG"},
176 | {"name": "民企红利", "symbol": "000826.XSHG"},
177 | {"name": "中证环保", "symbol": "000827.XSHG"},
178 | {"name": "300高贝", "symbol": "000828.XSHG"},
179 | {"name": "300低贝", "symbol": "000829.XSHG"},
180 | {"name": "500高贝", "symbol": "000830.XSHG"},
181 | {"name": "500低贝", "symbol": "000831.XSHG"},
182 | {"name": "中证转债", "symbol": "000832.XSHG"},
183 | {"name": "中高企债", "symbol": "000833.XSHG"},
184 | {"name": "创业价值", "symbol": "000838.XSHG"},
185 | {"name": "浙企综指", "symbol": "000839.XSHG"},
186 | {"name": "浙江民企", "symbol": "000840.XSHG"},
187 | {"name": "800医药", "symbol": "000841.XSHG"},
188 | {"name": "800等权", "symbol": "000842.XSHG"},
189 | {"name": "300动态", "symbol": "000843.XSHG"},
190 | {"name": "300稳定", "symbol": "000844.XSHG"},
191 | {"name": "ESG100", "symbol": "000846.XSHG"},
192 | {"name": "中证腾安价值100指数", "symbol": "000847.XSHG"},
193 | {"name": "沪深300非银行金融指数", "symbol": "000849.XSHG"},
194 | {"name": "沪深300有色金属指数", "symbol": "000850.XSHG"},
195 | {"name": "中证百度百发策略100指数", "symbol": "000851.XSHG"},
196 | {"name": "中证1000指数", "symbol": "000852.XSHG"},
197 | {"name": "中证申万一带一路主题投资指数", "symbol": "000853.XSHG"},
198 | {"name": "央视财经500指数", "symbol": "000855.XSHG"},
199 | {"name": "小康指数", "symbol": "000901.XSHG"},
200 | {"name": "中证流通", "symbol": "000902.XSHG"},
201 | {"name": "中证100", "symbol": "000903.XSHG"},
202 | {"name": "中证200", "symbol": "000904.XSHG"},
203 | {"name": "中证500", "symbol": "000905.XSHG"},
204 | {"name": "中证800", "symbol": "000906.XSHG"},
205 | {"name": "中证700", "symbol": "000907.XSHG"},
206 | {"name": "300能源", "symbol": "000908.XSHG"},
207 | {"name": "300材料", "symbol": "000909.XSHG"},
208 | {"name": "300工业", "symbol": "000910.XSHG"},
209 | {"name": "300可选", "symbol": "000911.XSHG"},
210 | {"name": "300消费", "symbol": "000912.XSHG"},
211 | {"name": "300医药", "symbol": "000913.XSHG"},
212 | {"name": "300金融", "symbol": "000914.XSHG"},
213 | {"name": "300信息", "symbol": "000915.XSHG"},
214 | {"name": "300电信", "symbol": "000916.XSHG"},
215 | {"name": "300公用", "symbol": "000917.XSHG"},
216 | {"name": "300成长", "symbol": "000918.XSHG"},
217 | {"name": "300价值", "symbol": "000919.XSHG"},
218 | {"name": "300R成长", "symbol": "000920.XSHG"},
219 | {"name": "300R价值", "symbol": "000921.XSHG"},
220 | {"name": "中证红利", "symbol": "000922.XSHG"},
221 | {"name": "公司债", "symbol": "000923.XSHG"},
222 | {"name": "基本面50", "symbol": "000925.XSHG"},
223 | {"name": "中证央企", "symbol": "000926.XSHG"},
224 | {"name": "央企100", "symbol": "000927.XSHG"},
225 | {"name": "中证能源", "symbol": "000928.XSHG"},
226 | {"name": "中证材料", "symbol": "000929.XSHG"},
227 | {"name": "中证工业", "symbol": "000930.XSHG"},
228 | {"name": "中证可选", "symbol": "000931.XSHG"},
229 | {"name": "中证消费", "symbol": "000932.XSHG"},
230 | {"name": "中证医药", "symbol": "000933.XSHG"},
231 | {"name": "中证金融", "symbol": "000934.XSHG"},
232 | {"name": "中证信息", "symbol": "000935.XSHG"},
233 | {"name": "中证电信", "symbol": "000936.XSHG"},
234 | {"name": "中证公用", "symbol": "000937.XSHG"},
235 | {"name": "中证民企", "symbol": "000938.XSHG"},
236 | {"name": "民企200", "symbol": "000939.XSHG"},
237 | {"name": "财富大盘", "symbol": "000940.XSHG"},
238 | {"name": "新能源", "symbol": "000941.XSHG"},
239 | {"name": "内地消费", "symbol": "000942.XSHG"},
240 | {"name": "内地基建", "symbol": "000943.XSHG"},
241 | {"name": "内地资源", "symbol": "000944.XSHG"},
242 | {"name": "内地运输", "symbol": "000945.XSHG"},
243 | {"name": "内地金融", "symbol": "000946.XSHG"},
244 | {"name": "内地银行", "symbol": "000947.XSHG"},
245 | {"name": "内地地产", "symbol": "000948.XSHG"},
246 | {"name": "内地农业", "symbol": "000949.XSHG"},
247 | {"name": "300基建", "symbol": "000950.XSHG"},
248 | {"name": "300银行", "symbol": "000951.XSHG"},
249 | {"name": "300地产", "symbol": "000952.XSHG"},
250 | {"name": "中证地企", "symbol": "000953.XSHG"},
251 | {"name": "地企100", "symbol": "000954.XSHG"},
252 | {"name": "中证国企", "symbol": "000955.XSHG"},
253 | {"name": "国企200", "symbol": "000956.XSHG"},
254 | {"name": "300运输", "symbol": "000957.XSHG"},
255 | {"name": "创业成长", "symbol": "000958.XSHG"},
256 | {"name": "银河99", "symbol": "000959.XSHG"},
257 | {"name": "中证龙头", "symbol": "000960.XSHG"},
258 | {"name": "中证上游", "symbol": "000961.XSHG"},
259 | {"name": "中证中游", "symbol": "000962.XSHG"},
260 | {"name": "中证下游", "symbol": "000963.XSHG"},
261 | {"name": "中证新兴", "symbol": "000964.XSHG"},
262 | {"name": "基本200", "symbol": "000965.XSHG"},
263 | {"name": "基本400", "symbol": "000966.XSHG"},
264 | {"name": "基本600", "symbol": "000967.XSHG"},
265 | {"name": "300周期", "symbol": "000968.XSHG"},
266 | {"name": "300非周", "symbol": "000969.XSHG"},
267 | {"name": "ESG40", "symbol": "000970.XSHG"},
268 | {"name": "等权90", "symbol": "000971.XSHG"},
269 | {"name": "300沪市", "symbol": "000972.XSHG"},
270 | {"name": "技术领先", "symbol": "000973.XSHG"},
271 | {"name": "中证800金融指数", "symbol": "000974.XSHG"},
272 | {"name": "钱江30", "symbol": "000975.XSHG"},
273 | {"name": "新华金牛", "symbol": "000976.XSHG"},
274 | {"name": "内地低碳", "symbol": "000977.XSHG"},
275 | {"name": "医药100", "symbol": "000978.XSHG"},
276 | {"name": "大宗商品", "symbol": "000979.XSHG"},
277 | {"name": "中证超大", "symbol": "000980.XSHG"},
278 | {"name": "300分层", "symbol": "000981.XSHG"},
279 | {"name": "500等权", "symbol": "000982.XSHG"},
280 | {"name": "智能资产", "symbol": "000983.XSHG"},
281 | {"name": "300等权", "symbol": "000984.XSHG"},
282 | {"name": "中证全指", "symbol": "000985.XSHG"},
283 | {"name": "全指能源", "symbol": "000986.XSHG"},
284 | {"name": "全指材料", "symbol": "000987.XSHG"},
285 | {"name": "全指工业", "symbol": "000988.XSHG"},
286 | {"name": "全指可选", "symbol": "000989.XSHG"},
287 | {"name": "全指消费", "symbol": "000990.XSHG"},
288 | {"name": "全指医药", "symbol": "000991.XSHG"},
289 | {"name": "全指金融", "symbol": "000992.XSHG"},
290 | {"name": "全指信息", "symbol": "000993.XSHG"},
291 | {"name": "全指电信", "symbol": "000994.XSHG"},
292 | {"name": "全指公用", "symbol": "000995.XSHG"},
293 | {"name": "领先行业", "symbol": "000996.XSHG"},
294 | {"name": "大消费", "symbol": "000997.XSHG"},
295 | {"name": "中证TMT", "symbol": "000998.XSHG"},
296 | {"name": "证两岸三地500指数", "symbol": "000999.XSHG"},
297 | {"name": "深证成指", "symbol": "399001.XSHE"},
298 | {"name": "深成指R", "symbol": "399002.XSHE"},
299 | {"name": "成份B指", "symbol": "399003.XSHE"},
300 | {"name": "深证100R", "symbol": "399004.XSHE"},
301 | {"name": "中小板指", "symbol": "399005.XSHE"},
302 | {"name": "创业板指", "symbol": "399006.XSHE"},
303 | {"name": "深证300", "symbol": "399007.XSHE"},
304 | {"name": "中小300", "symbol": "399008.XSHE"},
305 | {"name": "深证200", "symbol": "399009.XSHE"},
306 | {"name": "深证700", "symbol": "399010.XSHE"},
307 | {"name": "深证1000", "symbol": "399011.XSHE"},
308 | {"name": "创业300", "symbol": "399012.XSHE"},
309 | {"name": "深市精选", "symbol": "399013.XSHE"},
310 | {"name": "深证中小创新指数", "symbol": "399015.XSHE"},
311 | {"name": "新指数", "symbol": "399100.XSHE"},
312 | {"name": "中小板综", "symbol": "399101.XSHE"},
313 | {"name": "创业板综合指数", "symbol": "399102.XSHE"},
314 | {"name": "乐富指数", "symbol": "399103.XSHE"},
315 | {"name": "深证综指", "symbol": "399106.XSHE"},
316 | {"name": "深证A指", "symbol": "399107.XSHE"},
317 | {"name": "深证B指", "symbol": "399108.XSHE"},
318 | {"name": "农林指数", "symbol": "399231.XSHE"},
319 | {"name": "采矿指数", "symbol": "399232.XSHE"},
320 | {"name": "制造指数", "symbol": "399233.XSHE"},
321 | {"name": "水电指数", "symbol": "399234.XSHE"},
322 | {"name": "建筑指数", "symbol": "399235.XSHE"},
323 | {"name": "批零指数", "symbol": "399236.XSHE"},
324 | {"name": "运输指数", "symbol": "399237.XSHE"},
325 | {"name": "餐饮指数", "symbol": "399238.XSHE"},
326 | {"name": "IT指数", "symbol": "399239.XSHE"},
327 | {"name": "金融指数", "symbol": "399240.XSHE"},
328 | {"name": "地产指数", "symbol": "399241.XSHE"},
329 | {"name": "商务指数", "symbol": "399242.XSHE"},
330 | {"name": "科研指数", "symbol": "399243.XSHE"},
331 | {"name": "公共指数", "symbol": "399244.XSHE"},
332 | {"name": "文化指数", "symbol": "399248.XSHE"},
333 | {"name": "综企指数", "symbol": "399249.XSHE"},
334 | {"name": "深证中高等级信用债指数", "symbol": "399298.XSHE"},
335 | {"name": "深证中低等级信用债指数", "symbol": "399299.XSHE"},
336 | {"name": "沪深300", "symbol": "399300.XSHE"},
337 | {"name": "深信用债", "symbol": "399301.XSHE"},
338 | {"name": "深公司债", "symbol": "399302.XSHE"},
339 | {"name": "国证2000", "symbol": "399303.XSHE"},
340 | {"name": "基金指数", "symbol": "399305.XSHE"},
341 | {"name": "深证ETF", "symbol": "399306.XSHE"},
342 | {"name": "深证转债", "symbol": "399307.XSHE"},
343 | {"name": "国证50", "symbol": "399310.XSHE"},
344 | {"name": "国证1000", "symbol": "399311.XSHE"},
345 | {"name": "国证300", "symbol": "399312.XSHE"},
346 | {"name": "巨潮100", "symbol": "399313.XSHE"},
347 | {"name": "巨潮大盘", "symbol": "399314.XSHE"},
348 | {"name": "巨潮中盘", "symbol": "399315.XSHE"},
349 | {"name": "巨潮小盘", "symbol": "399316.XSHE"},
350 | {"name": "国证A指", "symbol": "399317.XSHE"},
351 | {"name": "巨潮B股指数", "symbol": "399318.XSHE"},
352 | {"name": "资源优势", "symbol": "399319.XSHE"},
353 | {"name": "国证服务", "symbol": "399320.XSHE"},
354 | {"name": "国证红利", "symbol": "399321.XSHE"},
355 | {"name": "国证治理", "symbol": "399322.XSHE"},
356 | {"name": "深证红利", "symbol": "399324.XSHE"},
357 | {"name": "成长40", "symbol": "399326.XSHE"},
358 | {"name": "深证治理", "symbol": "399328.XSHE"},
359 | {"name": "深证100", "symbol": "399330.XSHE"},
360 | {"name": "深证创新", "symbol": "399332.XSHE"},
361 | {"name": "中小板R", "symbol": "399333.XSHE"},
362 | {"name": "深证央企", "symbol": "399335.XSHE"},
363 | {"name": "深证民营", "symbol": "399337.XSHE"},
364 | {"name": "深证科技", "symbol": "399339.XSHE"},
365 | {"name": "深证责任", "symbol": "399341.XSHE"},
366 | {"name": "深证300R", "symbol": "399344.XSHE"},
367 | {"name": "深证成长", "symbol": "399346.XSHE"},
368 | {"name": "深证价值", "symbol": "399348.XSHE"},
369 | {"name": "皖江30", "symbol": "399350.XSHE"},
370 | {"name": "深报指数", "symbol": "399351.XSHE"},
371 | {"name": "深报综指", "symbol": "399352.XSHE"},
372 | {"name": "国证物流", "symbol": "399353.XSHE"},
373 | {"name": "长三角", "symbol": "399355.XSHE"},
374 | {"name": "珠三角", "symbol": "399356.XSHE"},
375 | {"name": "环渤海", "symbol": "399357.XSHE"},
376 | {"name": "泰达指数", "symbol": "399358.XSHE"},
377 | {"name": "国证基建", "symbol": "399359.XSHE"},
378 | {"name": "国证装备", "symbol": "399360.XSHE"},
379 | {"name": "国证商业", "symbol": "399361.XSHE"},
380 | {"name": "国证民营", "symbol": "399362.XSHE"},
381 | {"name": "计算机指", "symbol": "399363.XSHE"},
382 | {"name": "中金消费", "symbol": "399364.XSHE"},
383 | {"name": "国证农业", "symbol": "399365.XSHE"},
384 | {"name": "国证大宗", "symbol": "399366.XSHE"},
385 | {"name": "巨潮地产", "symbol": "399367.XSHE"},
386 | {"name": "国证军工", "symbol": "399368.XSHE"},
387 | {"name": "CBN-兴全", "symbol": "399369.XSHE"},
388 | {"name": "国证成长", "symbol": "399370.XSHE"},
389 | {"name": "国证价值", "symbol": "399371.XSHE"},
390 | {"name": "大盘成长", "symbol": "399372.XSHE"},
391 | {"name": "大盘价值", "symbol": "399373.XSHE"},
392 | {"name": "中盘成长", "symbol": "399374.XSHE"},
393 | {"name": "中盘价值", "symbol": "399375.XSHE"},
394 | {"name": "小盘成长", "symbol": "399376.XSHE"},
395 | {"name": "小盘价值", "symbol": "399377.XSHE"},
396 | {"name": "南方低碳", "symbol": "399378.XSHE"},
397 | {"name": "国证基金", "symbol": "399379.XSHE"},
398 | {"name": "国证ETF", "symbol": "399380.XSHE"},
399 | {"name": "1000能源", "symbol": "399381.XSHE"},
400 | {"name": "1000材料", "symbol": "399382.XSHE"},
401 | {"name": "1000工业", "symbol": "399383.XSHE"},
402 | {"name": "1000可选", "symbol": "399384.XSHE"},
403 | {"name": "1000消费", "symbol": "399385.XSHE"},
404 | {"name": "1000医药", "symbol": "399386.XSHE"},
405 | {"name": "1000金融", "symbol": "399387.XSHE"},
406 | {"name": "1000信息", "symbol": "399388.XSHE"},
407 | {"name": "国证通信", "symbol": "399389.XSHE"},
408 | {"name": "1000公用", "symbol": "399390.XSHE"},
409 | {"name": "投资时钟", "symbol": "399391.XSHE"},
410 | {"name": "国证新兴", "symbol": "399392.XSHE"},
411 | {"name": "国证地产", "symbol": "399393.XSHE"},
412 | {"name": "国证医药", "symbol": "399394.XSHE"},
413 | {"name": "国证有色", "symbol": "399395.XSHE"},
414 | {"name": "国证食品", "symbol": "399396.XSHE"},
415 | {"name": "OCT文化", "symbol": "399397.XSHE"},
416 | {"name": "绩效指数", "symbol": "399398.XSHE"},
417 | {"name": "中经GDP", "symbol": "399399.XSHE"},
418 | {"name": "大中盘", "symbol": "399400.XSHE"},
419 | {"name": "中小盘", "symbol": "399401.XSHE"},
420 | {"name": "周期100", "symbol": "399402.XSHE"},
421 | {"name": "防御100", "symbol": "399403.XSHE"},
422 | {"name": "大盘低波", "symbol": "399404.XSHE"},
423 | {"name": "大盘高贝", "symbol": "399405.XSHE"},
424 | {"name": "中盘低波", "symbol": "399406.XSHE"},
425 | {"name": "中盘高贝", "symbol": "399407.XSHE"},
426 | {"name": "小盘低波", "symbol": "399408.XSHE"},
427 | {"name": "小盘高贝", "symbol": "399409.XSHE"},
428 | {"name": "苏州率先", "symbol": "399410.XSHE"},
429 | {"name": "红利100", "symbol": "399411.XSHE"},
430 | {"name": "国证新能", "symbol": "399412.XSHE"},
431 | {"name": "国证转债", "symbol": "399413.XSHE"},
432 | {"name": "I100", "symbol": "399415.XSHE"},
433 | {"name": "I300", "symbol": "399416.XSHE"},
434 | {"name": "国证新能源汽车指数", "symbol": "399417.XSHE"},
435 | {"name": "国证国家安全指数", "symbol": "399418.XSHE"},
436 | {"name": "国证高铁指数", "symbol": "399419.XSHE"},
437 | {"name": "国证保险证券指数", "symbol": "399420.XSHE"},
438 | {"name": "中关村50指数", "symbol": "399423.XSHE"},
439 | {"name": "国证德高行专利领先指数", "symbol": "399427.XSHE"},
440 | {"name": "国证定向增发指数", "symbol": "399428.XSHE"},
441 | {"name": "新丝路指数", "symbol": "399429.XSHE"},
442 | {"name": "国证银行行业指数", "symbol": "399431.XSHE"},
443 | {"name": "国证汽车与汽车零配件行业指数", "symbol": "399432.XSHE"},
444 | {"name": "国证交通运输行业指数", "symbol": "399433.XSHE"},
445 | {"name": "国证传媒行业指数", "symbol": "399434.XSHE"},
446 | {"name": "国证农牧渔产品行业指数", "symbol": "399435.XSHE"},
447 | {"name": "国证煤炭行业指数", "symbol": "399436.XSHE"},
448 | {"name": "国证证券行业指数", "symbol": "399437.XSHE"},
449 | {"name": "国证电力公用事业行业指数", "symbol": "399438.XSHE"},
450 | {"name": "国证石油天然气行业指数", "symbol": "399439.XSHE"},
451 | {"name": "国证黑色金属行业指数", "symbol": "399440.XSHE"},
452 | {"name": "国证生物医药指数", "symbol": "399441.XSHE"},
453 | {"name": "企债指数", "symbol": "399481.XSHE"},
454 | {"name": "央视50", "symbol": "399550.XSHE"},
455 | {"name": "央视创新", "symbol": "399551.XSHE"},
456 | {"name": "央视成长", "symbol": "399552.XSHE"},
457 | {"name": "央视回报", "symbol": "399553.XSHE"},
458 | {"name": "央视治理", "symbol": "399554.XSHE"},
459 | {"name": "央视责任", "symbol": "399555.XSHE"},
460 | {"name": "央视生态", "symbol": "399556.XSHE"},
461 | {"name": "央视文化", "symbol": "399557.XSHE"},
462 | {"name": "中小成长", "symbol": "399602.XSHE"},
463 | {"name": "中小价值", "symbol": "399604.XSHE"},
464 | {"name": "创业板R", "symbol": "399606.XSHE"},
465 | {"name": "科技100", "symbol": "399608.XSHE"},
466 | {"name": "TMT50", "symbol": "399610.XSHE"},
467 | {"name": "中创100R", "symbol": "399611.XSHE"},
468 | {"name": "中创100", "symbol": "399612.XSHE"},
469 | {"name": "深证能源", "symbol": "399613.XSHE"},
470 | {"name": "深证材料", "symbol": "399614.XSHE"},
471 | {"name": "深证工业", "symbol": "399615.XSHE"},
472 | {"name": "深证可选", "symbol": "399616.XSHE"},
473 | {"name": "深证消费", "symbol": "399617.XSHE"},
474 | {"name": "深证医药", "symbol": "399618.XSHE"},
475 | {"name": "深证金融", "symbol": "399619.XSHE"},
476 | {"name": "深证信息", "symbol": "399620.XSHE"},
477 | {"name": "深证电信", "symbol": "399621.XSHE"},
478 | {"name": "深证公用", "symbol": "399622.XSHE"},
479 | {"name": "中小基础", "symbol": "399623.XSHE"},
480 | {"name": "中创400", "symbol": "399624.XSHE"},
481 | {"name": "中创500", "symbol": "399625.XSHE"},
482 | {"name": "中创成长", "symbol": "399626.XSHE"},
483 | {"name": "中创价值", "symbol": "399627.XSHE"},
484 | {"name": "700成长", "symbol": "399628.XSHE"},
485 | {"name": "700价值", "symbol": "399629.XSHE"},
486 | {"name": "1000成长", "symbol": "399630.XSHE"},
487 | {"name": "1000价值", "symbol": "399631.XSHE"},
488 | {"name": "深100EW", "symbol": "399632.XSHE"},
489 | {"name": "深300EW", "symbol": "399633.XSHE"},
490 | {"name": "中小板EW", "symbol": "399634.XSHE"},
491 | {"name": "创业板EW", "symbol": "399635.XSHE"},
492 | {"name": "深证装备", "symbol": "399636.XSHE"},
493 | {"name": "深证地产", "symbol": "399637.XSHE"},
494 | {"name": "深证环保", "symbol": "399638.XSHE"},
495 | {"name": "深证大宗", "symbol": "399639.XSHE"},
496 | {"name": "创业基础", "symbol": "399640.XSHE"},
497 | {"name": "深证新兴", "symbol": "399641.XSHE"},
498 | {"name": "中小新兴", "symbol": "399642.XSHE"},
499 | {"name": "创业新兴", "symbol": "399643.XSHE"},
500 | {"name": "深证时钟", "symbol": "399644.XSHE"},
501 | {"name": "100低波", "symbol": "399645.XSHE"},
502 | {"name": "深消费50", "symbol": "399646.XSHE"},
503 | {"name": "深医药50", "symbol": "399647.XSHE"},
504 | {"name": "深证GDP", "symbol": "399648.XSHE"},
505 | {"name": "中小红利", "symbol": "399649.XSHE"},
506 | {"name": "中小治理", "symbol": "399650.XSHE"},
507 | {"name": "中小责任", "symbol": "399651.XSHE"},
508 | {"name": "中创高新", "symbol": "399652.XSHE"},
509 | {"name": "深证龙头", "symbol": "399653.XSHE"},
510 | {"name": "深证文化", "symbol": "399654.XSHE"},
511 | {"name": "深证绩效", "symbol": "399655.XSHE"},
512 | {"name": "100绩效", "symbol": "399656.XSHE"},
513 | {"name": "300绩效", "symbol": "399657.XSHE"},
514 | {"name": "中小绩效", "symbol": "399658.XSHE"},
515 | {"name": "深成指EW", "symbol": "399659.XSHE"},
516 | {"name": "中创EW", "symbol": "399660.XSHE"},
517 | {"name": "深证低波", "symbol": "399661.XSHE"},
518 | {"name": "深证高贝", "symbol": "399662.XSHE"},
519 | {"name": "中小低波", "symbol": "399663.XSHE"},
520 | {"name": "中小高贝", "symbol": "399664.XSHE"},
521 | {"name": "中创低波", "symbol": "399665.XSHE"},
522 | {"name": "中创高贝", "symbol": "399666.XSHE"},
523 | {"name": "创业板G", "symbol": "399667.XSHE"},
524 | {"name": "创业板V", "symbol": "399668.XSHE"},
525 | {"name": "深证农业", "symbol": "399669.XSHE"},
526 | {"name": "深周期50", "symbol": "399670.XSHE"},
527 | {"name": "深防御50", "symbol": "399671.XSHE"},
528 | {"name": "深红利50", "symbol": "399672.XSHE"},
529 | {"name": "创业板50", "symbol": "399673.XSHE"},
530 | {"name": "深A医药卫生指数", "symbol": "399674.XSHE"},
531 | {"name": "深A软件与互联网指数", "symbol": "399675.XSHE"},
532 | {"name": "深A医药卫生等权指数", "symbol": "399676.XSHE"},
533 | {"name": "深A软件与互联网等权指数", "symbol": "399677.XSHE"},
534 | {"name": "深证次新股指数", "symbol": "399678.XSHE"},
535 | {"name": "深证200指数", "symbol": "399679.XSHE"},
536 | {"name": "深成能源行业指数", "symbol": "399680.XSHE"},
537 | {"name": "深成原材料行业指数", "symbol": "399681.XSHE"},
538 | {"name": "深成工业行业指数", "symbol": "399682.XSHE"},
539 | {"name": "深成可选消费行业指数", "symbol": "399683.XSHE"},
540 | {"name": "深成主要消费行业指数", "symbol": "399684.XSHE"},
541 | {"name": "深成医药卫生行业指数", "symbol": "399685.XSHE"},
542 | {"name": "深成金融地产行业指数", "symbol": "399686.XSHE"},
543 | {"name": "深成信息技术行业指数", "symbol": "399687.XSHE"},
544 | {"name": "深成电信业务行业指数", "symbol": "399688.XSHE"},
545 | {"name": "深成公用事业行业指数", "symbol": "399689.XSHE"},
546 | {"name": "深证F60", "symbol": "399701.XSHE"},
547 | {"name": "深证F120", "symbol": "399702.XSHE"},
548 | {"name": "深证F200", "symbol": "399703.XSHE"},
549 | {"name": "深证上游", "symbol": "399704.XSHE"},
550 | {"name": "深证中游", "symbol": "399705.XSHE"},
551 | {"name": "深证下游", "symbol": "399706.XSHE"},
552 | {"name": "中证申万证券行业指数", "symbol": "399707.XSHE"},
553 | {"name": "500深市", "symbol": "399802.XSHE"},
554 | {"name": "中证工业4.0指数", "symbol": "399803.XSHE"},
555 | {"name": "中证体育产业指数", "symbol": "399804.XSHE"},
556 | {"name": "中证互联网金融指数", "symbol": "399805.XSHE"},
557 | {"name": "中证环境治理指数", "symbol": "399806.XSHE"},
558 | {"name": "中证高铁产业指数", "symbol": "399807.XSHE"},
559 | {"name": "中证新能源指数", "symbol": "399808.XSHE"},
560 | {"name": "中证方正富邦保险主题指数", "symbol": "399809.XSHE"},
561 | {"name": "中证申万传媒行业投资指数", "symbol": "399810.XSHE"},
562 | {"name": "中证申万电子行业投资指数", "symbol": "399811.XSHE"},
563 | {"name": "中证养老产业指数", "symbol": "399812.XSHE"},
564 | {"name": "中证国防安全指数", "symbol": "399813.XSHE"},
565 | {"name": "中证大农业指数", "symbol": "399814.XSHE"},
566 | {"name": "中证阿拉善生态主题100指数", "symbol": "399817.XSHE"},
567 | {"name": "中证南方小康产业指数", "symbol": "399901.XSHE"},
568 | {"name": "中证100指数", "symbol": "399903.XSHE"},
569 | {"name": "中证中盘200指数", "symbol": "399904.XSHE"},
570 | {"name": "中证500", "symbol": "399905.XSHE"},
571 | {"name": "中证中小盘700指数", "symbol": "399907.XSHE"},
572 | {"name": "沪深300能源指数", "symbol": "399908.XSHE"},
573 | {"name": "沪深300原材料指数", "symbol": "399909.XSHE"},
574 | {"name": "沪深300工业指数", "symbol": "399910.XSHE"},
575 | {"name": "沪深300可选消费指数", "symbol": "399911.XSHE"},
576 | {"name": "沪深300主要消费指数", "symbol": "399912.XSHE"},
577 | {"name": "沪深300医药卫生指数", "symbol": "399913.XSHE"},
578 | {"name": "沪深300金融地产指数", "symbol": "399914.XSHE"},
579 | {"name": "沪深300信息技术指数", "symbol": "399915.XSHE"},
580 | {"name": "沪深300电信业务指数", "symbol": "399916.XSHE"},
581 | {"name": "沪深300公用事业指数", "symbol": "399917.XSHE"},
582 | {"name": "沪深300成长指数", "symbol": "399918.XSHE"},
583 | {"name": "沪深300价值指数", "symbol": "399919.XSHE"},
584 | {"name": "沪深300相对成长指数", "symbol": "399920.XSHE"},
585 | {"name": "中证红利指数", "symbol": "399922.XSHE"},
586 | {"name": "中证锐联基本面50指数", "symbol": "399925.XSHE"},
587 | {"name": "中证中央企业综合指数", "symbol": "399926.XSHE"},
588 | {"name": "中证中央企业100指数", "symbol": "399927.XSHE"},
589 | {"name": "中证能源指数", "symbol": "399928.XSHE"},
590 | {"name": "中证原材料指数", "symbol": "399929.XSHE"},
591 | {"name": "中证工业指数", "symbol": "399930.XSHE"},
592 | {"name": "中证可选消费指数", "symbol": "399931.XSHE"},
593 | {"name": "中证主要消费指数", "symbol": "399932.XSHE"},
594 | {"name": "中证医药卫生指数", "symbol": "399933.XSHE"},
595 | {"name": "中证金融地产指数", "symbol": "399934.XSHE"},
596 | {"name": "中证信息技术指数", "symbol": "399935.XSHE"},
597 | {"name": "中证电信业务指数", "symbol": "399936.XSHE"},
598 | {"name": "中证公用事业指数", "symbol": "399937.XSHE"},
599 | {"name": "中证民营企业综合指数", "symbol": "399938.XSHE"},
600 | {"name": "中证民营企业200指数", "symbol": "399939.XSHE"},
601 | {"name": "中证内地新能源主题指数", "symbol": "399941.XSHE"},
602 | {"name": "中证内地消费主题指数", "symbol": "399942.XSHE"},
603 | {"name": "中证内地基建主题指数", "symbol": "399943.XSHE"},
604 | {"name": "中证内地资源主题指数", "symbol": "399944.XSHE"},
605 | {"name": "中证内地运输主题指数", "symbol": "399945.XSHE"},
606 | {"name": "中证内地金融主题指数", "symbol": "399946.XSHE"},
607 | {"name": "中证内地银行主题指数", "symbol": "399947.XSHE"},
608 | {"name": "中证内地地产主题指数", "symbol": "399948.XSHE"},
609 | {"name": "中证内地农业主题指数", "symbol": "399949.XSHE"},
610 | {"name": "沪深300基建主题指数", "symbol": "399950.XSHE"},
611 | {"name": "沪深300银行指数", "symbol": "399951.XSHE"},
612 | {"name": "沪深300地产指数", "symbol": "399952.XSHE"},
613 | {"name": "中证地方国有企业综合指数", "symbol": "399953.XSHE"},
614 | {"name": "中证地方国有企业100指数", "symbol": "399954.XSHE"},
615 | {"name": "中证国有企业200指数", "symbol": "399956.XSHE"},
616 | {"name": "沪深300运输指数", "symbol": "399957.XSHE"},
617 | {"name": "中证创业成长指数", "symbol": "399958.XSHE"},
618 | {"name": "军工指数", "symbol": "399959.XSHE"},
619 | {"name": "中证龙头企业指数", "symbol": "399960.XSHE"},
620 | {"name": "中证上游资源产业指数", "symbol": "399961.XSHE"},
621 | {"name": "中证中游制造产业指数", "symbol": "399962.XSHE"},
622 | {"name": "中证下游消费与服务产业指数", "symbol": "399963.XSHE"},
623 | {"name": "中证新兴产业指数", "symbol": "399964.XSHE"},
624 | {"name": "800地产", "symbol": "399965.XSHE"},
625 | {"name": "800非银", "symbol": "399966.XSHE"},
626 | {"name": "中证军工", "symbol": "399967.XSHE"},
627 | {"name": "沪深300周期行业指数", "symbol": "399968.XSHE"},
628 | {"name": "沪深300非周期行业指数", "symbol": "399969.XSHE"},
629 | {"name": "中证移动互联网指数", "symbol": "399970.XSHE"},
630 | {"name": "中证传媒指数", "symbol": "399971.XSHE"},
631 | {"name": "300深市", "symbol": "399972.XSHE"},
632 | {"name": "中证国防指数", "symbol": "399973.XSHE"},
633 | {"name": "中证国有企业改革指数", "symbol": "399974.XSHE"},
634 | {"name": "中证全指证券公司指数(四级行业)", "symbol": "399975.XSHE"},
635 | {"name": "中证新能源汽车指数", "symbol": "399976.XSHE"},
636 | {"name": "中证内地低碳经济主题指数", "symbol": "399977.XSHE"},
637 | {"name": "中证医药100指数", "symbol": "399978.XSHE"},
638 | {"name": "中证大宗商品股票指数", "symbol": "399979.XSHE"},
639 | {"name": "中证超级大盘指数", "symbol": "399980.XSHE"},
640 | {"name": "中证500等权重指数", "symbol": "399982.XSHE"},
641 | {"name": "沪深300地产等权重指数", "symbol": "399983.XSHE"},
642 | {"name": "中证银行指数", "symbol": "399986.XSHE"},
643 | {"name": "中证酒指数", "symbol": "399987.XSHE"},
644 | {"name": "中证医疗指数", "symbol": "399989.XSHE"},
645 | {"name": "中证煤炭等权指数", "symbol": "399990.XSHE"},
646 | {"name": "中证一带一路主题指数", "symbol": "399991.XSHE"},
647 | {"name": "中证万得并购重组指数", "symbol": "399992.XSHE"},
648 | {"name": "中证万得生物科技指数", "symbol": "399993.XSHE"},
649 | {"name": "中证信息安全主题指数", "symbol": "399994.XSHE"},
650 | {"name": "中证基建工程指数", "symbol": "399995.XSHE"},
651 | {"name": "中证智能家居指数", "symbol": "399996.XSHE"},
652 | {"name": "中证白酒指数", "symbol": "399997.XSHE"},
653 | {"name": "中证煤炭指数", "symbol": "399998.XSHE"}
654 | ]
655 | """
656 |
657 |
658 | def get_list(style='yahoo'):
659 | df = pd.read_json(StringIO(JSON_DATA))
660 |
661 | if style == 'yahoo':
662 | df.symbol = df.symbol.apply(lambda x: str(x).replace('XSHG', 'SS').replace('XSHE', 'SZ'))
663 |
664 | return df
665 |
666 | @click.command()
667 | @click.argument("outputdir")
668 | def gen_data(outputdir):
669 | """
670 | gen all ticker data result to output dir
671 | """
672 |
673 | if not os.path.isdir(outputdir):
674 | raise Exception("Please Provide a valid output dir path")
675 |
676 |
677 |
678 | df = get_list('yahoo')
679 | for s in df.symbol:
680 |
681 | outputfile = os.path.join(outputdir, '%s_benchmark.csv' % str(s).upper())
682 |
683 | """
684 | zhikuang-squant is a private command of RainX
685 | """
686 | click.echo("generate file or %s " % s)
687 | cmd = 'zhikuang-squant gen_zipline_benchmark_file -s %s -o %s' % (s, outputfile)
688 | # click.echo(cmd)
689 | os.system(cmd)
690 | click.echo("done! in path : %s" % outputfile)
691 |
692 | if __name__ == "__main__":
693 | gen_data()
694 |
--------------------------------------------------------------------------------
/zipline_cn_databundle/loader.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2016 Quantopian, Inc.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | import os
16 |
17 | import logbook
18 | import pandas as pd
19 | import pytz
20 | from six import iteritems
21 | from .index_list import get_list
22 |
23 | from zipline.utils.paths import (
24 | cache_root,
25 | data_root,
26 | )
27 | import pandas as pd
28 |
29 | from cn_stock_holidays.zipline.default_calendar import shsz_calendar
30 |
31 | from cn_treasury_curve.data import get_zipline_format
32 | import requests
33 | import shutil
34 |
35 | logger = logbook.Logger('Loader')
36 |
37 | ONE_HOUR = pd.Timedelta(hours=1)
38 |
39 |
40 | def last_modified_time(path):
41 | """
42 | Get the last modified time of path as a Timestamp.
43 | """
44 | return pd.Timestamp(os.path.getmtime(path), unit='s', tz='UTC')
45 |
46 |
47 | def get_data_filepath(name):
48 | """
49 | Returns a handle to data file.
50 |
51 | Creates containing directory, if needed.
52 | """
53 | dr = data_root()
54 |
55 | if not os.path.exists(dr):
56 | os.makedirs(dr)
57 |
58 | return os.path.join(dr, name)
59 |
60 |
61 | def get_cache_filepath(name):
62 | cr = cache_root()
63 | if not os.path.exists(cr):
64 | os.makedirs(cr)
65 |
66 | return os.path.join(cr, name)
67 |
68 |
69 | def get_benchmark_filename(symbol):
70 | return "%s_benchmark.csv" % symbol
71 |
72 |
73 | def has_data_for_dates(series_or_df, first_date, last_date):
74 | """
75 | Does `series_or_df` have data on or before first_date and on or after
76 | last_date?
77 | """
78 | dts = series_or_df.index
79 | if not isinstance(dts, pd.DatetimeIndex):
80 | raise TypeError("Expected a DatetimeIndex, but got %s." % type(dts))
81 | first, last = dts[[0, -1]]
82 | #ignore first date check
83 | return last >= last_date
84 |
85 |
86 | def load_market_data(trading_day=None, trading_days=None, bm_symbol='000001.SS', trading_day_before=2):
87 | """
88 | Load benchmark returns and treasury yield curves for the given calendar and
89 | benchmark symbol.
90 |
91 | Benchmarks are downloaded as a Series from Yahoo Finance. Treasury curves
92 | are US Treasury Bond rates and are downloaded from 'www.federalreserve.gov'
93 | by default. For Canadian exchanges, a loader for Canadian bonds from the
94 | Bank of Canada is also available.
95 |
96 | Results downloaded from the internet are cached in
97 | ~/.zipline/data. Subsequent loads will attempt to read from the cached
98 | files before falling back to redownload.
99 |
100 | Parameters
101 | ----------
102 | trading_day : pandas.CustomBusinessDay, optional
103 | A trading_day used to determine the latest day for which we
104 | expect to have data. Defaults to an NYSE trading day.
105 | trading_days : pd.DatetimeIndex, optional
106 | A calendar of trading days. Also used for determining what cached
107 | dates we should expect to have cached. Defaults to the NYSE calendar.
108 | bm_symbol : str, optional
109 | Symbol for the benchmark index to load. Defaults to '^GSPC', the Yahoo
110 | ticker for the S&P 500.
111 |
112 | trading_day_before : int, optional
113 | Trading day before is 2 default
114 |
115 | Returns
116 | -------
117 | (benchmark_returns, treasury_curves) : (pd.Series, pd.DataFrame)
118 |
119 | Notes
120 | -----
121 |
122 | Both return values are DatetimeIndexed with values dated to midnight in UTC
123 | of each stored date. The columns of `treasury_curves` are:
124 |
125 | '1month', '3month', '6month',
126 | '1year','2year','3year','5year','7year','10year','20year','30year'
127 | """
128 | if trading_day is None:
129 | trading_day = shsz_calendar.trading_day
130 | if trading_days is None:
131 | trading_days = shsz_calendar.all_sessions
132 |
133 | first_date = trading_days[0]
134 | now = pd.Timestamp.utcnow()
135 |
136 | # We expect to have benchmark and treasury data that's current up until
137 | # **two** full trading days prior to the most recently completed trading
138 | # day.
139 | # Example:
140 | # On Thu Oct 22 2015, the previous completed trading day is Wed Oct 21.
141 | # However, data for Oct 21 doesn't become available until the early morning
142 | # hours of Oct 22. This means that there are times on the 22nd at which we
143 | # cannot reasonably expect to have data for the 21st available. To be
144 | # conservative, we instead expect that at any time on the 22nd, we can
145 | # download data for Tuesday the 20th, which is two full trading days prior
146 | # to the date on which we're running a test.
147 |
148 | # We'll attempt to download new data if the latest entry in our cache is
149 | # before this date.
150 | last_date = trading_days[trading_days.get_loc(now, method='ffill') - trading_day_before]
151 |
152 | br = ensure_benchmark_data(
153 | bm_symbol,
154 | first_date,
155 | last_date,
156 | now,
157 | # We need the trading_day to figure out the close prior to the first
158 | # date so that we can compute returns for the first date.
159 | trading_day,
160 | )
161 | tc = ensure_treasury_data(
162 | bm_symbol,
163 | first_date,
164 | last_date,
165 | now,
166 | )
167 | benchmark_returns = br[br.index.slice_indexer(first_date, last_date)]
168 | treasury_curves = tc[tc.index.slice_indexer(first_date, last_date)]
169 | return benchmark_returns, treasury_curves
170 |
171 |
172 | def ensure_benchmark_data(symbol, first_date, last_date, now, trading_day):
173 | """
174 | Ensure we have benchmark data for `symbol` from `first_date` to `last_date`
175 |
176 | Parameters
177 | ----------
178 | symbol : str
179 | The symbol for the benchmark to load.
180 | first_date : pd.Timestamp
181 | First required date for the cache.
182 | last_date : pd.Timestamp
183 | Last required date for the cache.
184 | now : pd.Timestamp
185 | The current time. This is used to prevent repeated attempts to
186 | re-download data that isn't available due to scheduling quirks or other
187 | failures.
188 | trading_day : pd.CustomBusinessDay
189 | A trading day delta. Used to find the day before first_date so we can
190 | get the close of the day prior to first_date.
191 |
192 | We attempt to download data unless we already have data stored at the data
193 | cache for `symbol` whose first entry is before or on `first_date` and whose
194 | last entry is on or after `last_date`.
195 |
196 | If we perform a download and the cache criteria are not satisfied, we wait
197 | at least one hour before attempting a redownload. This is determined by
198 | comparing the current time to the result of os.path.getmtime on the cache
199 | path.
200 | """
201 | path = get_data_filepath(get_benchmark_filename(symbol))
202 |
203 | # If the path does not exist, it means the first download has not happened
204 | # yet, so don't try to read from 'path'.
205 | if os.path.exists(path):
206 | try:
207 | data = pd.Series.from_csv(path).tz_localize('UTC')
208 | if has_data_for_dates(data, first_date, last_date):
209 | return data
210 |
211 | # Don't re-download if we've successfully downloaded and written a
212 | # file in the last hour.
213 | last_download_time = last_modified_time(path)
214 | if (now - last_download_time) <= ONE_HOUR:
215 | logger.warn(
216 | "Refusing to download new benchmark data because a "
217 | "download succeeded at %s." % last_download_time
218 | )
219 | return data
220 |
221 | except (OSError, IOError, ValueError) as e:
222 | # These can all be raised by various versions of pandas on various
223 | # classes of malformed input. Treat them all as cache misses.
224 | logger.info(
225 | "Loading data for {path} failed with error [{error}].".format(
226 | path=path, error=e,
227 | )
228 | )
229 | logger.info(
230 | "Cache at {path} does not have data from {start} to {end}.\n"
231 | "Downloading benchmark data for '{symbol}'.",
232 | start=first_date,
233 | end=last_date,
234 | symbol=symbol,
235 | path=path,
236 | )
237 |
238 | try:
239 |
240 | symbol_list = get_list().symbol.values
241 |
242 | if str(symbol).upper() in symbol_list:
243 | get_url = 'https://raw.githubusercontent.com/rainx/cn_index_benchmark_for_zipline/master/data/%s_benchmark.csv' % str(symbol).upper()
244 | print("fetch data via url : %s " % get_url)
245 | response = requests.get(get_url)
246 | with open(path, 'wb') as fileobj:
247 | fileobj.write(response.content)
248 | print("length of response is : %s" % len(response.content))
249 | data = pd.Series.from_csv(path).tz_localize('UTC')
250 | else:
251 | #logger.exception('your bm_symbol not in existing symbol list')
252 | raise Exception('your bm_symbol not in existing symbol list')
253 | except (OSError, IOError):
254 | logger.exception('failed to cache the new benchmark returns')
255 | raise
256 | if not has_data_for_dates(data, first_date, last_date):
257 | logger.warn("Still don't have expected data after redownload!")
258 | return data
259 |
260 |
261 | def ensure_treasury_data(bm_symbol, first_date, last_date, now):
262 | """
263 | Ensure we have treasury data from treasury module associated with
264 | `bm_symbol`.
265 |
266 | Parameters
267 | ----------
268 | bm_symbol : str
269 | Benchmark symbol for which we're loading associated treasury curves.
270 | first_date : pd.Timestamp
271 | First date required to be in the cache.
272 | last_date : pd.Timestamp
273 | Last date required to be in the cache.
274 | now : pd.Timestamp
275 | The current time. This is used to prevent repeated attempts to
276 | re-download data that isn't available due to scheduling quirks or other
277 | failures.
278 |
279 | We attempt to download data unless we already have data stored in the cache
280 | for `module_name` whose first entry is before or on `first_date` and whose
281 | last entry is on or after `last_date`.
282 |
283 | If we perform a download and the cache criteria are not satisfied, we wait
284 | at least one hour before attempting a redownload. This is determined by
285 | comparing the current time to the result of os.path.getmtime on the cache
286 | path.
287 | """
288 | filename = "cn_treasury_curves.csv"
289 |
290 | path = get_data_filepath(filename)
291 |
292 | # If the path does not exist, it means the first download has not happened
293 | # yet, so don't try to read from 'path'.
294 | if os.path.exists(path):
295 | try:
296 | data = pd.DataFrame.from_csv(path).tz_localize('UTC')
297 | if has_data_for_dates(data, first_date, last_date):
298 | return data
299 |
300 | # Don't re-download if we've successfully downloaded and written a
301 | # file in the last hour.
302 | last_download_time = last_modified_time(path)
303 | if (now - last_download_time) <= ONE_HOUR:
304 | logger.warn(
305 | "Refusing to download new treasury data because a "
306 | "download succeeded at %s." % last_download_time
307 | )
308 | return data
309 |
310 | except (OSError, IOError, ValueError) as e:
311 | # These can all be raised by various versions of pandas on various
312 | # classes of malformed input. Treat them all as cache misses.
313 | logger.info(
314 | "Loading data for {path} failed with error [{error}].".format(
315 | path=path, error=e,
316 | )
317 | )
318 |
319 | try:
320 | data = get_zipline_format()
321 | data.to_csv(path)
322 | #reload it and convert to UTC tz
323 | data = pd.DataFrame.from_csv(path).tz_localize('UTC')
324 | except (OSError, IOError):
325 | logger.exception('failed to cache treasury data')
326 | if not has_data_for_dates(data, first_date, last_date):
327 | logger.warn("Still don't have expected data after redownload!")
328 | return data
--------------------------------------------------------------------------------
/zipline_cn_databundle/squant_source.py:
--------------------------------------------------------------------------------
1 | from squant.data.stock import file_parser
2 | from squant.zipline.datasource import get_symbol_list
3 | import os
4 | import datetime
5 | from .tdx.reader import TdxReader, TdxFileNotFoundException
6 | import pandas as pd
7 |
8 | """
9 | Squant is a private library that parse the data from our private source
10 |
11 | That read data from binary files
12 |
13 | via RainX
14 |
15 | ipython 3 only
16 | """
17 |
18 |
19 | # 需要设定沪深文件目录
20 | CQCX_SH = os.environ.get("CQCX_SH")
21 | CQCX_SZ = os.environ.get("CQCX_SZ")
22 |
23 | TDX_DIR = os.environ.get("TDX_DIR")
24 |
25 | if not CQCX_SH or not CQCX_SZ:
26 | raise Exception("need set cqcx file on CQCX_SH CQCX_SZ")
27 |
28 | if not os.path.isfile(CQCX_SH) \
29 | or not os.path.isfile(CQCX_SZ):
30 | raise Exception("setting CQCX_SH, CQCX_SZ path is not correct")
31 |
32 |
33 | if not TDX_DIR:
34 | raise Exception("Please Setting TDX data dir")
35 |
36 | CQCX_LIST = (CQCX_SH, CQCX_SZ)
37 |
38 | def load_splits_and_dividends():
39 | """
40 | 获取所有除权出息的信息, 根据zipline平台的特点,忽略配股信息
41 | :return:
42 | """
43 |
44 | splits = {}
45 | dividends = {}
46 |
47 | for CQCX in CQCX_LIST:
48 | cqcx_data = file_parser.get_cqcx(CQCX.encode("utf-8"))
49 | for row in cqcx_data:
50 | code = str(row['stock']).zfill(6)
51 | # sgVal 送股数,每1000股送股数
52 | if row['sgVal'] != 0:
53 | if code not in splits.keys():
54 | splits[code] = []
55 | splits[code].append({
56 | 'effective_date' : int_to_date(row['date']),
57 | 'ratio' : 1000 / (1000 + row['sgVal']),
58 | })
59 |
60 | if row['pxVal'] != 0:
61 | if code not in dividends.keys():
62 | dividends[code] = []
63 | dividends[code].append({
64 | 'amount' : row['pxVal'] / 1000,
65 | 'ex_date' : int_to_date(row['date']),
66 | })
67 |
68 |
69 | return splits, dividends
70 |
71 |
72 | def zipline_splits_and_dividends(symbol_map):
73 | raw_splits, raw_dividends = load_splits_and_dividends()
74 | splits = []
75 | dividends = []
76 | for sid, code in symbol_map.iteritems():
77 | if code in raw_splits:
78 | split = pd.DataFrame(data=raw_splits[code])
79 | split['sid'] = sid
80 | split.index = split['effective_date'] = pd.DatetimeIndex(split['effective_date'])
81 | splits.append(split)
82 | if code in raw_dividends:
83 | dividend = pd.DataFrame(data = raw_dividends[code])
84 | dividend['sid'] = sid
85 | dividend['record_date'] = dividend['declared_date'] = dividend['pay_date'] = pd.NaT
86 | dividend.index = dividend['ex_date'] = pd.DatetimeIndex(dividend['ex_date'])
87 | dividends.append(dividend)
88 | return splits, dividends
89 |
90 | def int_to_date(d):
91 | d = str(d)
92 | return datetime.date(int(d[:4]), int(d[4:6]), int(d[6:]))
93 |
94 |
95 | def squant_bundle(environ,
96 | asset_db_writer,
97 | minute_bar_writer,
98 | daily_bar_writer,
99 | adjustment_writer,
100 | calendar,
101 | start_session,
102 | end_session,
103 | cache,
104 | show_progress,
105 | output_dir):
106 |
107 | tdx_reader = TdxReader(TDX_DIR)
108 |
109 | symbol_df = get_symbol_list()
110 | # 只保留未停牌的
111 | symbol_df = symbol_df[symbol_df['status'] == False]
112 |
113 | # 由于meta,split,dividend 和 行情数据源不同,所以有可能会不同,所以我们这里统一根据
114 |
115 | symbol_map = symbol_df.simplesymbol
116 |
117 | # 更新日期信息
118 | def update_start_and_end_date(s):
119 | start_date = start_session.replace(tzinfo=None)
120 | end_date = end_session.replace(tzinfo=None)
121 | if s.start_date < start_date:
122 | s.start_date = start_date
123 | if s.end_date == pd.Timestamp('1900-01-01') or s.end_date is pd.NaT:
124 | s.end_date = end_date
125 | return s
126 | symbol_df = symbol_df.apply(func=update_start_and_end_date, axis=1)
127 |
128 |
129 | # 写入基础信息
130 | asset_db_writer.write(symbol_df)
131 | # 写入数据文件
132 | daily_bar_writer.write(get_hist_data(symbol_df, symbol_map, tdx_reader, start_session, end_session, calendar),
133 | show_progress=show_progress)
134 | # split and diviends
135 | splits, dividends = zipline_splits_and_dividends(symbol_map)
136 |
137 | # hack for tdx data , for tdx source for shenzhen market, we can not get data before 1991-12-23
138 | splits_df = pd.concat(splits, ignore_index=True)
139 | dividends_df = pd.concat(dividends, ignore_index=True)
140 |
141 | splits_df= splits_df.loc[splits_df['effective_date'] > start_session]
142 | dividends_df = dividends_df.loc[dividends_df['ex_date'] > start_session]
143 | adjustment_writer.write(
144 | splits=splits_df,
145 | dividends=dividends_df,
146 | )
147 |
148 | def get_hist_data(symbol_df, symbol_map, tdx_reader, start_session, end_session, calendar):
149 | for sid, index in symbol_map.iteritems():
150 | exchagne = ''
151 | if symbol_df.loc[sid]['exchange'] == 'SZSE':
152 | exchagne = 'sz'
153 | elif symbol_df.loc[sid]['exchange'] == 'SSE':
154 | exchagne = 'sh'
155 |
156 | try:
157 | history = tdx_reader.get_df(index, exchagne)
158 |
159 | #print('max-min for %s is %s : %s', (index, history.index[0], history.index[-1]))
160 | # 去除没有报价信息的内容
161 | if history.index[0] > pd.Timestamp((end_session.date())):
162 | continue
163 | except TdxFileNotFoundException as e:
164 | #print('symbol %s file no found, ignore it ' % index)
165 | continue
166 | # history.to_pickle('/tmp/debug.pickle')
167 |
168 | #reindex
169 | sessions = calendar.sessions_in_range(start_session, end_session)
170 |
171 | history = history.reindex(
172 | sessions.tz_localize(None),
173 | copy=False,
174 | ).fillna(0.0)
175 |
176 | yield sid, history.sort_index()
177 | pass
178 |
179 | if __name__ == '__main__':
180 |
181 | import tushare as ts
182 | import pandas as pd
183 |
184 | ts_symbols = ts.get_stock_basics()
185 |
186 |
187 | symbols = []
188 |
189 |
190 | # 获取股票数据
191 | i = 0
192 | total = len(ts_symbols)
193 | for index, row in ts_symbols.iterrows():
194 | i = i +1
195 | if i > 10:
196 | break
197 |
198 | srow = {}
199 | srow['t'] = 1
200 | srow['symbol'] = index
201 | srow['asset_name'] = row['name']
202 | symbols.append(srow)
203 |
204 | df_symbols = pd.DataFrame(data=symbols).sort_values('symbol')
205 | symbol_map = pd.DataFrame.copy(df_symbols.symbol)
206 |
207 | raw_splits, raw_dividends = load_splits_and_dividends()
208 |
209 | splits = []
210 | dividends = []
211 | for sid, code in symbol_map.iteritems():
212 | if code in raw_splits:
213 | split = pd.DataFrame(data=raw_splits[code])
214 | split['sid'] = sid
215 | split.index = split['effective_date'] = pd.DatetimeIndex(split['effective_date'])
216 | splits.append(split)
217 | if code in raw_dividends:
218 | dividend = pd.DataFrame(data = raw_dividends[code])
219 | dividend['sid'] = sid
220 | dividend['record_date'] = dividend['declared_date'] = dividend['pay_date'] = pd.NaT
221 | dividend.index = dividend['ex_date'] = pd.DatetimeIndex(dividend['ex_date'])
222 | dividends.append(dividend)
223 |
224 | print(pd.concat(splits, ignore_index=True))
225 | print(pd.concat(dividends, ignore_index=True))
226 |
--------------------------------------------------------------------------------
/zipline_cn_databundle/tdx/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rainx/zipline_cn_databundle/92ba9258ebdf836180651cea1365ebcbd585e60d/zipline_cn_databundle/tdx/__init__.py
--------------------------------------------------------------------------------
/zipline_cn_databundle/tdx/reader.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | import os
3 | import numpy as np
4 |
5 | import struct
6 | """
7 | 读取通达信数据
8 | """
9 |
10 |
11 | class TdxFileNotFoundException(Exception):
12 | pass
13 |
14 | class TdxReader:
15 |
16 | def __init__(self, vipdoc_path):
17 | self.vipdoc_path = vipdoc_path
18 |
19 | def get_kline_by_code(self, code, exchange):
20 | fname = os.path.join(self.vipdoc_path, exchange)
21 | fname = os.path.join(fname, 'lday')
22 | fname = os.path.join(fname, '%s%s.day' % (exchange, code))
23 | return self.parse_data_by_file(fname)
24 |
25 | def parse_data_by_file(self, fname):
26 |
27 | if not os.path.isfile(fname):
28 | raise TdxFileNotFoundException('no tdx kline data, pleaes check path %s', fname)
29 |
30 | with open(fname, 'rb') as f:
31 | content = f.read()
32 | return self.unpack_records(' 10:
71 | break
72 |
73 | srow = {}
74 | # 获取历史报价信息
75 | click.echo("正在获取代码%s(%s)的历史行情信息 (%d/%d)" % (index, row['name'], i, total))
76 | histories[index] = ts.get_hist_data(index)
77 | srow['start_date'] = histories[index].index[-1]
78 | srow['end_date'] = histories[index].index[0]
79 | srow['symbol'] = index
80 | srow['asset_name'] = row['name']
81 | symbols.append(srow)
82 |
83 | df_symbols = pd.DataFrame(data=symbols).sort_values('symbol')
84 | symbol_map = pd.DataFrame.copy(df_symbols.symbol)
85 |
86 | # fix the symbol exchange info
87 | df = df_symbols.apply(func=convert_symbol_series, axis=1)
88 |
89 |
90 | return df, histories, symbol_map
91 |
92 |
93 | def symbol_to_exchange(symbol):
94 | isymbol = int(symbol)
95 | if (isymbol>=600000):
96 | return symbol + ".SS", "SSE"
97 | else:
98 | return symbol + ".SZ", "SZSE"
99 |
100 | def convert_symbol_series(s):
101 | symbol, e = symbol_to_exchange(s['symbol'])
102 | s['symbol'] = symbol
103 | s['exchange'] = e
104 | return s
105 |
106 | def get_hist_data(symbol_map, histories, start_session, end_session):
107 | for sid, index in symbol_map.iteritems():
108 | history = histories[index]
109 |
110 | """
111 | writer needs format with
112 | [index], open, close, high, low, volume
113 |
114 | so we do not need to change the format from tushare
115 |
116 | but we need resort it
117 | """
118 | yield sid, history.sort_index()
119 |
120 | if __name__ == '__main__':
121 | df_symbols, histories, symbol_map = get_basic_info()
122 | print(df_symbols)
123 |
124 | """
125 | for h,df in histories.items():
126 | print(df)
127 | """
128 |
--------------------------------------------------------------------------------
/zipline_cn_databundle/yahoo.py:
--------------------------------------------------------------------------------
1 | from zipline.data.bundles import register, yahoo_equities
2 | import requests
3 | import os
4 | from pandas_datareader.data import DataReader
5 |
6 | """
7 | For ingest chinese history day bar from Yahoo
8 |
9 | From both Shenzhen And Shanghai Stock Exchange
10 | """
11 |
12 | from .all_stocks import get_all_stocks, get_cache_dir
13 |
14 |
15 | def get_all_yahoo_stock_names(cache=True):
16 |
17 | if cache==False:
18 | print('Get All Stock List.....')
19 | all_stocks = get_all_stocks(cache=cache)
20 |
21 | return [full_code(code) for code in all_stocks.index]
22 |
23 | def full_code(code):
24 | if int(code[0]) >= 6:
25 | return "%s.SS" % code
26 | else:
27 | return '%s.SZ' % code
28 |
29 | def register_cn_bundle_from_yahoo(name, cache=True):
30 | """
31 | register a new bundle of stocks from chinese market from yahoo
32 | :param name: the name of bundle
33 | :return: register result
34 | """
35 | symbol_list = get_filtered_symbols(cache)
36 |
37 | return register(
38 | name,
39 | yahoo_equities(dict(list(zip(symbol_list, symbol_list)))),
40 | )
41 |
42 | def check_code(code):
43 | """
44 | XXX: used check_data_reader instead
45 | :param code:
46 | :return:
47 | """
48 | checkurl = r'http://finance.yahoo.com/_finance_doubledown/api/resource/searchassist;gossipConfig=%7B%22url%22%3A%7B%22host%22%3A%22s.yimg.com%22%2C%22path%22%3A%22%2Fxb%2Fv6%2Ffinance%2Fautocomplete%22%2C%22query%22%3A%7B%22appid%22%3A%22yahoo.com%22%2C%22nresults%22%3A10%2C%22output%22%3A%22yjsonp%22%2C%22region%22%3A%22US%22%2C%22lang%22%3A%22en-US%22%7D%2C%22protocol%22%3A%22https%22%7D%2C%22isJSONP%22%3Atrue%2C%22queryKey%22%3A%22query%22%2C%22resultAccessor%22%3A%22ResultSet.Result%22%2C%22suggestionTitleAccessor%22%3A%22symbol%22%2C%22suggestionMeta%22%3A%5B%22symbol%22%2C%22name%22%2C%22exch%22%2C%22type%22%2C%22exchDisp%22%2C%22typeDisp%22%5D%7D;searchTerm={{CODE}}?bkt=3E0%2507canary&dev_info=0&device=desktop&intl=us&lang=en-US&partner=none®ion=US&site=finance&tz=America%2FLos_Angeles&ver=0.101.302&returnMeta=true'
49 | referer = 'http://finance.yahoo.com/'
50 |
51 | url = checkurl.replace('{{CODE}}', code)
52 |
53 | response = requests.get(url, headers={
54 | 'Referer' : 'http://finance.yahoo.com/',
55 | 'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36',
56 | })
57 | try:
58 | data = response.json()
59 | items = data['data']['items']
60 |
61 | if len(items) > 0:
62 | for item in items:
63 | if item['symbol'].upper() == code.upper():
64 | print('.')
65 | return True
66 |
67 | except Exception as e:
68 | print(str(e))
69 | return False
70 |
71 | print('x')
72 | return False
73 |
74 | def check_data_reader(code):
75 | try:
76 | DataReader(code, 'yahoo')
77 | except:
78 | print('%s ok!' % code)
79 | return False
80 | print('%s not ok!' % code)
81 | return True
82 |
83 | def get_filtered_symbols(cache=True):
84 | cache_dir = get_cache_dir()
85 | file_path = os.path.join(cache_dir, 'symbols.txt')
86 |
87 | if cache and os.path.isfile(file_path):
88 | with open(file_path, 'r') as f:
89 | content = f.read()
90 | if content:
91 | return content.split("\n")
92 |
93 | symbols = get_all_yahoo_stock_names(cache)
94 |
95 | if cache==False:
96 | print('Check availablity from Yahoo...')
97 | filtered_symbols = list(filter(check_data_reader, symbols))
98 | print('cache output to %s' % file_path)
99 | with open(file_path, 'w') as f:
100 | f.write("\n".join(filtered_symbols))
101 | print('done!')
102 | return filtered_symbols
103 |
104 | def zipline_cn_databundle_update():
105 | print('Start to fetch data and update cache')
106 | get_filtered_symbols(cache=False)
--------------------------------------------------------------------------------