siat 3.7.29__py3-none-any.whl → 3.8.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- siat/allin.py +2 -0
- siat/common.py +19 -1
- siat/economy2.py +976 -0
- siat/grafix.py +128 -35
- siat/sector_china.py +50 -19
- siat/stock.py +1 -1
- siat/translate.py +280 -5
- {siat-3.7.29.dist-info → siat-3.8.2.dist-info}/METADATA +1 -1
- {siat-3.7.29.dist-info → siat-3.8.2.dist-info}/RECORD +12 -11
- {siat-3.7.29.dist-info → siat-3.8.2.dist-info}/LICENSE +0 -0
- {siat-3.7.29.dist-info → siat-3.8.2.dist-info}/WHEEL +0 -0
- {siat-3.7.29.dist-info → siat-3.8.2.dist-info}/top_level.txt +0 -0
siat/economy2.py
ADDED
@@ -0,0 +1,976 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""
|
3
|
+
本模块功能:宏观经济基本面分析
|
4
|
+
所属工具包:证券投资分析工具SIAT
|
5
|
+
SIAT:Security Investment Analysis Tool
|
6
|
+
创建日期:2025年3月9日
|
7
|
+
最新修订日期:2025年3月10日
|
8
|
+
作者:王德宏 (WANG Dehong, Peter)
|
9
|
+
作者单位:北京外国语大学国际商学院
|
10
|
+
版权所有:王德宏
|
11
|
+
用途限制:仅限研究与教学使用,不可商用!商用需要额外授权。
|
12
|
+
特别声明:作者不对使用本工具进行证券投资导致的任何损益负责!
|
13
|
+
"""
|
14
|
+
#==============================================================================
|
15
|
+
#关闭所有警告
|
16
|
+
import warnings; warnings.filterwarnings('ignore')
|
17
|
+
from siat.grafix import *
|
18
|
+
from siat.common import *
|
19
|
+
from siat.translate import *
|
20
|
+
#==============================================================================
|
21
|
+
import pandas as pd
|
22
|
+
from pandas_datareader import wb
|
23
|
+
import requests
|
24
|
+
|
25
|
+
#==============================================================================
|
26
|
+
if __name__=='__main__':
|
27
|
+
key_words='GDP per capita'
|
28
|
+
top=5; note=False
|
29
|
+
|
30
|
+
indicator_wb(key_words='GDP',top=10,note=False)
|
31
|
+
|
32
|
+
def find_economic_indicator(key_words='GDP',top=10, \
|
33
|
+
note=False,translate=False,source='wb'):
|
34
|
+
"""
|
35
|
+
===========================================================================
|
36
|
+
功能:查找宏观经济指标代码
|
37
|
+
参数:
|
38
|
+
key_words:关键词,支持多关键词,使用空格隔开,默认'GDP'
|
39
|
+
top:显示最相似的若干个指标,默认10
|
40
|
+
note:是否显示指标的描述,默认否False
|
41
|
+
translate:是否调用AI大模型进行翻译,若翻译可能影响反应速度,默认否False
|
42
|
+
source:信息来源,默认'wb'
|
43
|
+
|
44
|
+
注意:有时网络可能拒绝访问,可以换个时段再次进行访问
|
45
|
+
"""
|
46
|
+
if source=='wb':
|
47
|
+
df=indicator_wb(key_words=key_words,top=top,note=note,translate=translate)
|
48
|
+
else:
|
49
|
+
print(" Sorry, the source option currently only supports wb (World Bank)")
|
50
|
+
|
51
|
+
return
|
52
|
+
|
53
|
+
def indicator_wb(key_words='GDP',top=20,note=False,translate=False):
|
54
|
+
"""
|
55
|
+
============================================================================
|
56
|
+
功能:在WB/IMF/FRED数据库中查找宏观经济指标的代码
|
57
|
+
参数:
|
58
|
+
key_words:可包括多个关键词,使用空格隔开,不区分大小写
|
59
|
+
top:输出相似度最高的,默认5个
|
60
|
+
note:是否显示每个指标的注释,默认False
|
61
|
+
|
62
|
+
输出:基于文本相似度,输出可能的指标代码及其简介
|
63
|
+
|
64
|
+
返回值:可能的指标代码及其简介
|
65
|
+
"""
|
66
|
+
|
67
|
+
# 拆分关键词字符串为列表
|
68
|
+
words_list=key_words.split(' ')
|
69
|
+
|
70
|
+
# 循环查找每个关键词,并合成
|
71
|
+
df=None
|
72
|
+
for word in words_list:
|
73
|
+
try:
|
74
|
+
df_tmp=wb.search(word)
|
75
|
+
except:
|
76
|
+
print(" Sorry, data source rejected connection, try again later")
|
77
|
+
return None
|
78
|
+
|
79
|
+
# 合并
|
80
|
+
if df is None:
|
81
|
+
df=df_tmp
|
82
|
+
else:
|
83
|
+
df=pd.concat([df,df_tmp])
|
84
|
+
|
85
|
+
# 去重
|
86
|
+
df.drop_duplicates(subset=['id'],keep='first',inplace=True)
|
87
|
+
|
88
|
+
# 去掉名称中的逗号、左右括号、美元符号和百分号,以免降低模糊匹配度
|
89
|
+
import re
|
90
|
+
#df['name2']=df['name'].apply(lambda x: re.sub('[(),$%]', '', x))
|
91
|
+
df['name2']=df['name'].apply(lambda x: re.sub('[(),]', '', x))
|
92
|
+
|
93
|
+
# 匹配相似度
|
94
|
+
df2=fuzzy_search_wb(df,key_words=key_words,column='name2',top=top)
|
95
|
+
|
96
|
+
# 遍历输出
|
97
|
+
if len(df2)==0:
|
98
|
+
print(f"Sorry, no indicator found with key words: {key_words}")
|
99
|
+
return None
|
100
|
+
|
101
|
+
#print('') #空一行
|
102
|
+
for row in df2.itertuples():
|
103
|
+
|
104
|
+
print(f"{row.id}",end=': ')
|
105
|
+
if not translate:
|
106
|
+
print(f"{row.name}",end='')
|
107
|
+
else:
|
108
|
+
print(f"{row.name}[{lang_auto2(row.name)}]",end='')
|
109
|
+
if row.unit != '':
|
110
|
+
print(f", unit: {row.unit}")
|
111
|
+
else:
|
112
|
+
print('')
|
113
|
+
if note:
|
114
|
+
if row.sourceNote != '':
|
115
|
+
print(f"{row.sourceNote}")
|
116
|
+
if translate:
|
117
|
+
print(f"{lang_auto2(row.sourceNote)}")
|
118
|
+
print('') #空一行
|
119
|
+
|
120
|
+
return df2
|
121
|
+
|
122
|
+
#==============================================================================
|
123
|
+
if __name__=='__main__':
|
124
|
+
key_words='GDP per capita'
|
125
|
+
column='name'
|
126
|
+
top=10
|
127
|
+
|
128
|
+
def fuzzy_search_wb(df,key_words='GDP per capita',column='name',top=10):
|
129
|
+
"""
|
130
|
+
===========================================================================
|
131
|
+
功能:给定key_words,模糊搜索df的column字段,列出匹配度最高的10个指标及其解释
|
132
|
+
参数:
|
133
|
+
df:wb.search产生的指标集
|
134
|
+
column:需要搜索的字段名,默认'id'
|
135
|
+
key_words:需要匹配的关键词组,默认'GDP'
|
136
|
+
top:列出模糊匹配度最高的若干个指标,默认10
|
137
|
+
|
138
|
+
输出:无
|
139
|
+
返回:指标列表
|
140
|
+
"""
|
141
|
+
|
142
|
+
# 将关键词组和列中的每个值都转换为小写单词集合
|
143
|
+
def normalize_text(text):
|
144
|
+
return set(text.lower().split())
|
145
|
+
|
146
|
+
# 应用函数并比较集合
|
147
|
+
df["normalized_"+column] = df[column].apply(normalize_text)
|
148
|
+
key_words_set = normalize_text(key_words)
|
149
|
+
|
150
|
+
# 计算相似度(基于集合的交集和并集)
|
151
|
+
def calculate_similarity(text_set, key_words_set):
|
152
|
+
intersection = text_set.intersection(key_words_set)
|
153
|
+
union = text_set.union(key_words_set)
|
154
|
+
return len(intersection) / len(union)
|
155
|
+
|
156
|
+
df["similarity"] = df["normalized_"+column].apply(lambda x: calculate_similarity(x, key_words_set))
|
157
|
+
|
158
|
+
# 按相似度降序
|
159
|
+
df.sort_values(['similarity'], ascending = False, inplace=True)
|
160
|
+
|
161
|
+
df2=df[['id','name','unit','sourceNote']].head(top)
|
162
|
+
|
163
|
+
return df2
|
164
|
+
|
165
|
+
#==============================================================================
|
166
|
+
if __name__ =="__main__":
|
167
|
+
indicator="NY.GDP.MKTP.KN"
|
168
|
+
indicator="6.0.GDP_current"
|
169
|
+
indicator="XYZ123"
|
170
|
+
|
171
|
+
indicator_name_wb(indicator)
|
172
|
+
|
173
|
+
def indicator_name_wb(indicator='NY.GDP.MKTP.KN'):
|
174
|
+
"""
|
175
|
+
===========================================================================
|
176
|
+
功能:抓取World Bank网页上指标的名称
|
177
|
+
indicator:WB指标名称,默认'NY.GDP.MKTP.KN'
|
178
|
+
"""
|
179
|
+
|
180
|
+
# 构造 API 请求 URL
|
181
|
+
url = f"https://api.worldbank.org/v2/indicator/{indicator}?format=json"
|
182
|
+
|
183
|
+
# 发送请求
|
184
|
+
response = requests.get(url)
|
185
|
+
data = response.json()
|
186
|
+
|
187
|
+
# 提取指标名称
|
188
|
+
try:
|
189
|
+
indicator_name = data[1][0]['name']
|
190
|
+
except:
|
191
|
+
indicator_name = ''
|
192
|
+
|
193
|
+
return indicator_name
|
194
|
+
|
195
|
+
|
196
|
+
#==============================================================================
|
197
|
+
if __name__ =="__main__":
|
198
|
+
ticker='CN'; show_name=True
|
199
|
+
check_country_code('ZWE',show_name=True)
|
200
|
+
check_country_code('ZAF',show_name=True)
|
201
|
+
check_country_code('cn',show_name=True)
|
202
|
+
|
203
|
+
def check_country_code(ticker='CN',show_name=False):
|
204
|
+
"""
|
205
|
+
===========================================================================
|
206
|
+
功能:检查国家代码是否支持
|
207
|
+
ticker:国家代码
|
208
|
+
show_name:是否显示国家名称,默认否False
|
209
|
+
|
210
|
+
返回值:若国家代码在列表中,True;否则,False
|
211
|
+
"""
|
212
|
+
country_codes=wb.country_codes
|
213
|
+
|
214
|
+
elements_to_remove = ['all','ALL','All']
|
215
|
+
country_code_list = [x for x in country_codes if x not in elements_to_remove]
|
216
|
+
|
217
|
+
result=False
|
218
|
+
if ticker in country_code_list:
|
219
|
+
result=True
|
220
|
+
|
221
|
+
if show_name:
|
222
|
+
if result:
|
223
|
+
indicator='NY.GDP.MKTP.KN'
|
224
|
+
df=economy_indicator_wb(ticker=ticker,indicator=indicator, \
|
225
|
+
start='2000',graph=False)
|
226
|
+
if not (df is None):
|
227
|
+
if len(df) >= 1:
|
228
|
+
country_name=df['country'].values[0]
|
229
|
+
print(f"Country code {ticker} refers to {country_name}")
|
230
|
+
else:
|
231
|
+
print(f"Country code {ticker} found, but its name not found")
|
232
|
+
else:
|
233
|
+
print(f"Found country code {ticker}, but its name not found")
|
234
|
+
else:
|
235
|
+
print(f"Country code {ticker} not found")
|
236
|
+
|
237
|
+
return result
|
238
|
+
|
239
|
+
|
240
|
+
#==============================================================================
|
241
|
+
if __name__ =="__main__":
|
242
|
+
ticker='CN'
|
243
|
+
indicator="NY.GDP.MKTP.KN"
|
244
|
+
indicator="GC.XPN.TOTL.GD.ZS"
|
245
|
+
|
246
|
+
start='2010'; end='2025'; power=3
|
247
|
+
|
248
|
+
zeroline=False
|
249
|
+
attention_value=''; attention_value_area=''
|
250
|
+
attention_point=''; attention_point_area=''
|
251
|
+
average_value=False
|
252
|
+
datatag=False; graph=True
|
253
|
+
mark_top=True; mark_bottom=True; mark_end=True
|
254
|
+
facecolor='whitesmoke';loc='best'
|
255
|
+
|
256
|
+
|
257
|
+
df=economy_indicator_wb(ticker,indicator,start,end,power=3)
|
258
|
+
|
259
|
+
def economy_indicator_wb(ticker='CN',indicator='NY.GDP.MKTP.KN', \
|
260
|
+
start='L10Y',end='today',translate=False, \
|
261
|
+
zeroline=False, \
|
262
|
+
attention_value='',attention_value_area='', \
|
263
|
+
attention_point='',attention_point_area='', \
|
264
|
+
average_value=False, \
|
265
|
+
datatag=False,power=0,graph=True, \
|
266
|
+
mark_top=True,mark_bottom=True,mark_end=True, \
|
267
|
+
facecolor='whitesmoke',loc='best',maxticks=30):
|
268
|
+
"""
|
269
|
+
===========================================================================
|
270
|
+
功能:绘制一个国家的一个宏观经济指标走势
|
271
|
+
参数:
|
272
|
+
ticker:国家编码,两位,默认'CN'
|
273
|
+
indicator:宏观经济指标,默认GDP (constant LCU),即本币不变价格GDP
|
274
|
+
start:开始日期,默认近十年
|
275
|
+
end:结束日期,默认当前日期
|
276
|
+
zeroline:是否绘制零线,默认False
|
277
|
+
attention_value:纵轴关注值或其列表,默认无''
|
278
|
+
attention_value_area:纵轴关注值区间强调,默认无''
|
279
|
+
attention_point:横轴关注值或其列表,默认无''
|
280
|
+
attention_point_area:横轴关注值区间强调,默认无''
|
281
|
+
average_value:是否绘制均值线,默认否False
|
282
|
+
datatag:是否标记折线中的各个数据点的数值,默认否False
|
283
|
+
power:是否绘制趋势线,默认否0
|
284
|
+
graph:是否绘图,默认是True
|
285
|
+
mark_top, mark_bottom, mark_end:是否标记最高、最低和末端点:默认是True
|
286
|
+
facecolor:背景颜色,默认'whitesmoke'
|
287
|
+
loc:图例位置,默认自动'best'
|
288
|
+
|
289
|
+
输出:图形
|
290
|
+
返回值:数据表
|
291
|
+
"""
|
292
|
+
# 检测指标是否存在,并取得指标名称
|
293
|
+
indicator_name=indicator_name_wb(indicator)
|
294
|
+
if indicator_name == '':
|
295
|
+
print(f" #Error(economy_indicator_wb): no indicator found for {indicator}")
|
296
|
+
return None
|
297
|
+
|
298
|
+
# 日期具体化
|
299
|
+
start,end=start_end_preprocess(start,end)
|
300
|
+
|
301
|
+
# 下载数据
|
302
|
+
try:
|
303
|
+
pricedf=wb.download(indicator=indicator,country=ticker,start=start,end=end)
|
304
|
+
except:
|
305
|
+
print(f" #Error(economy_indicator_wb): either {indicator} deprecated or {ticker} does not exist")
|
306
|
+
return None
|
307
|
+
|
308
|
+
# 是否返回None
|
309
|
+
if pricedf is None:
|
310
|
+
print(f" #Error(economy_indicator_wb): no data found on {indicator} for {ticker}")
|
311
|
+
return None
|
312
|
+
# 是否返回空的数据表
|
313
|
+
if len(pricedf) == 0:
|
314
|
+
print(f" #Error(economy_indicator_wb): zero data found on {indicator} for {ticker}")
|
315
|
+
return None
|
316
|
+
# 是否返回数据表但内容均为NaN
|
317
|
+
if pricedf[indicator].isnull().all():
|
318
|
+
print(f" #Error(economy_indicator_wb): all empty data found on {indicator} for {ticker}")
|
319
|
+
return None
|
320
|
+
|
321
|
+
pricedf.reset_index(inplace=True)
|
322
|
+
pricedf.set_index('year',inplace=True)
|
323
|
+
pricedf.rename(columns={indicator:indicator_name},inplace=True)
|
324
|
+
country=pricedf['country'].values[0]
|
325
|
+
pricedf.sort_index(inplace=True)
|
326
|
+
#pricedf.drop(columns='country',inplace=True)
|
327
|
+
|
328
|
+
erdf3=pricedf
|
329
|
+
|
330
|
+
# 换算数量单位
|
331
|
+
ind_max=erdf3[indicator_name].max(); ind_min=erdf3[indicator_name].min()
|
332
|
+
ind_median=erdf3[indicator_name].median()
|
333
|
+
|
334
|
+
kilo=1000; million=kilo * 1000; billion=million * 1000
|
335
|
+
trillion=billion * 1000; quadrillion=trillion * 1000
|
336
|
+
|
337
|
+
if ind_median > quadrillion:
|
338
|
+
unit=text_lang('单位:千万亿','in Quadrillions'); unit_amount=quadrillion
|
339
|
+
elif ind_median > trillion:
|
340
|
+
unit=text_lang('单位:万亿','in Trillions'); unit_amount=trillion
|
341
|
+
elif ind_median > billion:
|
342
|
+
unit=text_lang('单位:十亿','in Billions'); unit_amount=billion
|
343
|
+
elif ind_median > million:
|
344
|
+
unit=text_lang('单位:百万','in Millions'); unit_amount=million
|
345
|
+
elif ind_median > kilo:
|
346
|
+
unit=text_lang('单位:千','in Thousands'); unit_amount=kilo
|
347
|
+
else:
|
348
|
+
unit=''; unit_amount=1
|
349
|
+
|
350
|
+
erdf3['unit']=unit
|
351
|
+
|
352
|
+
if unit != '':
|
353
|
+
erdf3[indicator_name]=erdf3[indicator_name].apply(lambda x: round(x/unit_amount,2))
|
354
|
+
|
355
|
+
# 绘图
|
356
|
+
if not graph:
|
357
|
+
return erdf3
|
358
|
+
|
359
|
+
# 判断是否绘制零线
|
360
|
+
if ind_max * ind_min <0:
|
361
|
+
zeroline=True
|
362
|
+
|
363
|
+
titletxt1=text_lang("经济趋势分析","Economic Trend Analysis")
|
364
|
+
titletxt=titletxt1+': '+country+', '+indicator_name
|
365
|
+
if unit != '':
|
366
|
+
titletxt=titletxt+', '+unit
|
367
|
+
|
368
|
+
import datetime; todaydt = datetime.date.today()
|
369
|
+
sourcetxt=text_lang("数据来源:WB/IMF/FRED","Data source: World Bank")
|
370
|
+
footnote=sourcetxt+', '+str(todaydt)
|
371
|
+
collabel=indicator_name
|
372
|
+
|
373
|
+
ylabeltxt=indicator_name
|
374
|
+
|
375
|
+
# 为避免绘图出错,对空值进行插值
|
376
|
+
erdf3.interpolate(method='linear',limit_direction='both',inplace=True)
|
377
|
+
|
378
|
+
# 翻译:挪到绘图函数中
|
379
|
+
"""
|
380
|
+
if translate:
|
381
|
+
ylabeltxt=lang_auto2(ylabeltxt)
|
382
|
+
titletxt=lang_auto2(titletxt)
|
383
|
+
"""
|
384
|
+
try:
|
385
|
+
plot_line(erdf3,indicator_name,collabel,ylabeltxt,titletxt,footnote,datatag=datatag, \
|
386
|
+
power=power,zeroline=zeroline, \
|
387
|
+
average_value=average_value, \
|
388
|
+
attention_value=attention_value,attention_value_area=attention_value_area, \
|
389
|
+
attention_point=attention_point,attention_point_area=attention_point_area, \
|
390
|
+
mark_top=mark_top,mark_bottom=mark_bottom,mark_end=mark_end, \
|
391
|
+
facecolor=facecolor,loc=loc,maxticks=30,translate=translate)
|
392
|
+
except Exception as e:
|
393
|
+
# 捕获所有异常
|
394
|
+
print(f"Error:{e}")
|
395
|
+
print("Details:")
|
396
|
+
import traceback
|
397
|
+
traceback.print_exc()
|
398
|
+
|
399
|
+
return erdf3
|
400
|
+
|
401
|
+
|
402
|
+
#==============================================================
|
403
|
+
if __name__ =="__main__":
|
404
|
+
ticker='CN'
|
405
|
+
indicator=['NY.GDP.MKTP.CN','NY.GDP.MKTP.KN','NY.GDP.MKTP.CD','XYZ']
|
406
|
+
start='2010'
|
407
|
+
end='2025'
|
408
|
+
|
409
|
+
attention_value=''; attention_value_area=''
|
410
|
+
attention_point=''; attention_point_area=''
|
411
|
+
band_area=''
|
412
|
+
graph=True
|
413
|
+
smooth=True
|
414
|
+
loc='best'
|
415
|
+
facecolor='whitesmoke'
|
416
|
+
date_range=False
|
417
|
+
date_freq=False
|
418
|
+
annotate=False
|
419
|
+
annotate_value=False
|
420
|
+
mark_top=True; mark_bottom=True; mark_end=True
|
421
|
+
maxticks=30
|
422
|
+
|
423
|
+
df=economy_mindicators_wb(ticker,measures,fromdate,todate)
|
424
|
+
|
425
|
+
def economy_mindicators_wb(ticker='CN',indicator=['NY.GDP.MKTP.CN','NY.GDP.MKTP.KN'], \
|
426
|
+
start='L10Y',end='today', \
|
427
|
+
attention_value='',attention_value_area='', \
|
428
|
+
attention_point='',attention_point_area='', \
|
429
|
+
band_area='', \
|
430
|
+
graph=True,smooth=False,loc='best',facecolor='whitesmoke', \
|
431
|
+
date_range=False,date_freq=False, \
|
432
|
+
annotate=False,annotate_value=False, \
|
433
|
+
mark_top=False,mark_bottom=False,mark_end=False, \
|
434
|
+
maxticks=30,translate=False):
|
435
|
+
"""
|
436
|
+
===========================================================================
|
437
|
+
功能:单个国家,多个宏观经济指标对比
|
438
|
+
主要参数:
|
439
|
+
ticker:国家代码,默认'CN'
|
440
|
+
indicator:指标代码列表,默认['NY.GDP.MKTP.CN','NY.GDP.MKTP.KN']
|
441
|
+
start:开始日期,默认'L10Y'
|
442
|
+
end:截止日期,默认'today'
|
443
|
+
attention_value:纵轴关注值或其列表,默认无''
|
444
|
+
attention_value_area:纵轴关注值区间强调,默认无''
|
445
|
+
attention_point:横轴关注值或其列表,默认无''
|
446
|
+
attention_point_area:横轴关注值区间强调,默认无''
|
447
|
+
band_area:两条曲线之间强调,默认无''
|
448
|
+
graph:是否绘图,默认True
|
449
|
+
loc:图例位置,默认自动'best'
|
450
|
+
facecolor:画布背景颜色,默认'whitesmoke'
|
451
|
+
annotate:是否在曲线末端标注,默认否False
|
452
|
+
annotate_value:是否标注曲线末端值,默认否False
|
453
|
+
mark_top, mark_bottom, mark_end:是否标注最大、最小、末端值,默认否
|
454
|
+
maxticks=30:限制横轴刻度最大数量
|
455
|
+
|
456
|
+
date_range=False:指定开始结束日期绘图
|
457
|
+
date_freq=False:指定横轴日期间隔,例如'D'、'2D'、'W'、'M'等,横轴一般不超过25个标注,否则会重叠
|
458
|
+
|
459
|
+
输出:图形
|
460
|
+
返回值:数据表
|
461
|
+
"""
|
462
|
+
DEBUG=False
|
463
|
+
|
464
|
+
measures=indicator
|
465
|
+
fromdate,todate=start_end_preprocess(start,end)
|
466
|
+
|
467
|
+
#处理ticker,允许1个
|
468
|
+
if isinstance(ticker,list):
|
469
|
+
if len(ticker) >= 1:
|
470
|
+
ticker=ticker[0]
|
471
|
+
else:
|
472
|
+
print(" #Error(economy_mindicators_wb): need at least 1 country to continue")
|
473
|
+
return None
|
474
|
+
|
475
|
+
#处理measures,允许多个
|
476
|
+
if isinstance(measures,str):
|
477
|
+
measures=[measures]
|
478
|
+
|
479
|
+
#屏蔽函数内print信息输出的类
|
480
|
+
import os, sys
|
481
|
+
class HiddenPrints:
|
482
|
+
def __enter__(self):
|
483
|
+
self._original_stdout = sys.stdout
|
484
|
+
sys.stdout = open(os.devnull, 'w')
|
485
|
+
|
486
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
487
|
+
sys.stdout.close()
|
488
|
+
sys.stdout = self._original_stdout
|
489
|
+
|
490
|
+
df=pd.DataFrame(); have_data=False
|
491
|
+
indicator_list=[]; unit_list=[]
|
492
|
+
for m in measures:
|
493
|
+
print(f" Searching indicator {m} ... ...")
|
494
|
+
|
495
|
+
with HiddenPrints():
|
496
|
+
dftmp=economy_indicator_wb(ticker=ticker,indicator=m, \
|
497
|
+
start=fromdate,end=todate, \
|
498
|
+
graph=False)
|
499
|
+
if dftmp is None:
|
500
|
+
print(f" #Warning(economy_mindicators_wb): none found for {m} with {ticker}")
|
501
|
+
continue
|
502
|
+
#return None
|
503
|
+
if len(dftmp) ==0:
|
504
|
+
print(f" #Warning(economy_mindicators_wb): empty record found on {m} for {ticker}")
|
505
|
+
continue
|
506
|
+
#return None
|
507
|
+
|
508
|
+
have_data=True
|
509
|
+
|
510
|
+
country=dftmp['country'].values[0]
|
511
|
+
unit=dftmp['unit'].values[0]
|
512
|
+
unit_list=unit_list+[unit]
|
513
|
+
dftmp.drop(columns=['country','unit'],inplace=True)
|
514
|
+
indicator_name=list(dftmp)[0]
|
515
|
+
|
516
|
+
if m in band_area:
|
517
|
+
band_area = [indicator_name if x == m else x for x in band_area]
|
518
|
+
|
519
|
+
indicator_list=indicator_list+[indicator_name]
|
520
|
+
|
521
|
+
if len(df)==0:
|
522
|
+
df=dftmp
|
523
|
+
else:
|
524
|
+
df=pd.merge(df,dftmp,left_index=True,right_index=True)
|
525
|
+
|
526
|
+
if not graph: return df
|
527
|
+
|
528
|
+
if not have_data:
|
529
|
+
#print(f" #Error(economy_mindicators_wb): no record found on {indicator} for {ticker}")
|
530
|
+
return None
|
531
|
+
|
532
|
+
# 绘图
|
533
|
+
titletxt=text_lang("经济趋势分析","Economic Trend Analysis")+': '+country
|
534
|
+
|
535
|
+
y_label=text_lang('经济指标',"Economic Indicator")
|
536
|
+
import datetime; todaydt = datetime.date.today()
|
537
|
+
footnote2=text_lang("数据来源:WB/IMF/FRED","Data source: World Bank")+', '+str(todaydt)
|
538
|
+
|
539
|
+
one_unit=False
|
540
|
+
if len(set(unit_list)) == 1: one_unit=True
|
541
|
+
if one_unit:
|
542
|
+
x_label=footnote2
|
543
|
+
if unit != '':
|
544
|
+
titletxt=titletxt+', '+unit
|
545
|
+
else:
|
546
|
+
#footnote1='The units of '+str(indicator_list)+' are '+str(unit_list)+' respectively'
|
547
|
+
footnote1=text_lang('注:','Notes: '); indicator_list_len=len(indicator_list)
|
548
|
+
for ind in indicator_list:
|
549
|
+
pos=indicator_list.index(ind)
|
550
|
+
footnote1=footnote1+ind+' '+unit_list[pos]
|
551
|
+
if (pos < indicator_list_len - 1):
|
552
|
+
if (pos+1) % 2 != 0:
|
553
|
+
footnote1=footnote1+', '
|
554
|
+
else:
|
555
|
+
footnote1=footnote1+'\n'
|
556
|
+
|
557
|
+
x_label=footnote1+'\n'+footnote2
|
558
|
+
|
559
|
+
axhline_value=0; axhline_label=''
|
560
|
+
above_zero=0; below_zero=0
|
561
|
+
for c in list(df):
|
562
|
+
c_max=df[c].max(); c_min=df[c].min()
|
563
|
+
try:
|
564
|
+
if c_max>0 or c_min>0: above_zero+=1
|
565
|
+
if c_max<0 or c_min<0: below_zero+=1
|
566
|
+
except: continue
|
567
|
+
|
568
|
+
if above_zero>0 and below_zero>0: #有正有负
|
569
|
+
if DEBUG:
|
570
|
+
print("DEBUG: draw axhline=0")
|
571
|
+
axhline_value=0
|
572
|
+
axhline_label=text_lang('零线',"Zeroline")
|
573
|
+
|
574
|
+
# 为避免绘图出错,对空值进行插值
|
575
|
+
df.interpolate(method='linear',limit_direction='both',inplace=True)
|
576
|
+
|
577
|
+
draw_lines2(df,y_label,x_label,axhline_value,axhline_label,titletxt, \
|
578
|
+
data_label=False,resample_freq='1D',smooth=smooth, \
|
579
|
+
date_range=date_range,date_freq=date_freq,date_fmt='%Y-%m-%d', \
|
580
|
+
attention_value=attention_value,attention_value_area=attention_value_area, \
|
581
|
+
attention_point=attention_point,attention_point_area=attention_point_area, \
|
582
|
+
annotate=annotate,annotate_value=annotate_value, \
|
583
|
+
mark_top=mark_top,mark_bottom=mark_bottom,mark_end=mark_end,facecolor=facecolor, \
|
584
|
+
band_area=band_area,loc=loc,maxticks=maxticks,translate=translate)
|
585
|
+
|
586
|
+
return df
|
587
|
+
|
588
|
+
|
589
|
+
#==============================================================================
|
590
|
+
if __name__ =="__main__":
|
591
|
+
tickers=['CN','US','JP']
|
592
|
+
indicator='NY.GDP.MKTP.PP.CD'
|
593
|
+
start='L20Y'; end='today'
|
594
|
+
|
595
|
+
attention_value=''; attention_value_area=''
|
596
|
+
attention_point=''; attention_point_area=''
|
597
|
+
axhline_value=0; axhline_label=''
|
598
|
+
preprocess='none'; linewidth=1.5
|
599
|
+
scaling_option='start'
|
600
|
+
plus_sign=False
|
601
|
+
graph=True; loc='best'; facecolor='whitesmoke'
|
602
|
+
annotate=False; annotate_value=False
|
603
|
+
smooth=True
|
604
|
+
mark_top=True; mark_bottom=True; mark_end=False
|
605
|
+
maxticks=30
|
606
|
+
|
607
|
+
|
608
|
+
|
609
|
+
def economy_mtickers_wb(ticker=['CN','US','JP'],indicator='NY.GDP.MKTP.PP.CD', \
|
610
|
+
start='L15Y',end='today', \
|
611
|
+
attention_value='',attention_value_area='', \
|
612
|
+
attention_point='',attention_point_area='', \
|
613
|
+
axhline_value=0,axhline_label='', \
|
614
|
+
preprocess='none',linewidth=1.5, \
|
615
|
+
scaling_option='start', \
|
616
|
+
plus_sign=False, \
|
617
|
+
graph=True,facecolor='whitesmoke', \
|
618
|
+
band_area='',loc='best', \
|
619
|
+
annotate=False,annotate_value=False, \
|
620
|
+
smooth=False, \
|
621
|
+
mark_top=True,mark_bottom=True,mark_end=False, \
|
622
|
+
maxticks=30,translate=False):
|
623
|
+
"""
|
624
|
+
===========================================================================
|
625
|
+
功能:比较并绘制多个国家的单宏观经济指标曲线
|
626
|
+
主要参数:
|
627
|
+
ticker:国家代码,默认['CN','US','JP']
|
628
|
+
indicator:宏观经济指标,默认'NY.GDP.MKTP.PP.CD',即GDP PPP
|
629
|
+
start:开始日期,默认'L20Y'
|
630
|
+
end:截止日期,默认'today'
|
631
|
+
attention_value:纵轴关注值或其列表,默认无''
|
632
|
+
attention_value_area:纵轴关注区间强调,默认无''
|
633
|
+
attention_point:横轴关注值或其列表,默认无''
|
634
|
+
attention_point_area:横轴关注区间强调,默认无''
|
635
|
+
preprocess:数据预处理,默认无'none'
|
636
|
+
linewidth:曲线宽度,默认1.5
|
637
|
+
scaling_option:数据缩放方法,默认'start'
|
638
|
+
plus_sign:在缩放处理时,纵轴刻度是否带加减号,默认否False
|
639
|
+
graph:是否绘图,默认是True
|
640
|
+
loc:图例位置,默认自动处理'best'
|
641
|
+
facecolor:画布背景颜色,默认'whitesmoke'
|
642
|
+
annotate:是否标注曲线末端,默认否False
|
643
|
+
annotate_value:是否标注曲线末端数值,默认否False
|
644
|
+
mark_top:是否标注最大值,默认是True
|
645
|
+
mark_bottom:是否标注最小值,默认是True
|
646
|
+
mark_end:是否标注曲线末端值,默认否False
|
647
|
+
maxticks:设定横轴刻度数量最大值,默认30
|
648
|
+
|
649
|
+
注意:
|
650
|
+
ticker中须含有2个及以上国家代码,
|
651
|
+
indicator为单一指标,
|
652
|
+
axhline_label不为空时绘制水平线
|
653
|
+
|
654
|
+
preprocess:是否对绘图数据进行预处理,仅适用于指标数量级差异较大的数据,
|
655
|
+
不适用于比例、比率和百分比等数量级较为一致的指标。
|
656
|
+
standardize: 标准化处理,(x - mean(x))/std(x)
|
657
|
+
normalize: 归一化处理,(x - min(x))/(max(x) - min(x))
|
658
|
+
logarithm: 对数处理,np.log(x)
|
659
|
+
scaling:缩放处理,五种选项scaling_option
|
660
|
+
(mean均值,min最小值,start开始值,percentage相对每条曲线起点值的百分比,
|
661
|
+
change%相对每条曲线起点值变化的百分比)
|
662
|
+
change%方式的图形更接近于持有收益率(Exp Ret%),设为默认的缩放方式。
|
663
|
+
|
664
|
+
"""
|
665
|
+
DEBUG=False
|
666
|
+
|
667
|
+
tickers=ticker; measure=indicator
|
668
|
+
start,end=start_end_preprocess(start,end)
|
669
|
+
|
670
|
+
tickers=upper_ticker(tickers)
|
671
|
+
if not isinstance(tickers,list):
|
672
|
+
tickers=[tickers]
|
673
|
+
|
674
|
+
# 去掉重复代码:有必要,重复代码将导致后续处理出错KeyError: 0!
|
675
|
+
tickers=list(set(tickers))
|
676
|
+
|
677
|
+
if isinstance(measure,list):
|
678
|
+
measure=measure[0]
|
679
|
+
|
680
|
+
#屏蔽函数内print信息输出的类
|
681
|
+
import os, sys
|
682
|
+
class HiddenPrints:
|
683
|
+
def __enter__(self):
|
684
|
+
self._original_stdout = sys.stdout
|
685
|
+
sys.stdout = open(os.devnull, 'w')
|
686
|
+
|
687
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
688
|
+
sys.stdout.close()
|
689
|
+
sys.stdout = self._original_stdout
|
690
|
+
|
691
|
+
#循环获取指标
|
692
|
+
#import pandas as pd
|
693
|
+
#from functools import reduce
|
694
|
+
|
695
|
+
dfs=pd.DataFrame(); have_data=False
|
696
|
+
country_list=[]; unit_list=[]
|
697
|
+
for t in tickers:
|
698
|
+
print(f" Looking indicator info for {t} ... ...")
|
699
|
+
with HiddenPrints():
|
700
|
+
df_tmp=economy_indicator_wb(ticker=t,indicator=measure, \
|
701
|
+
start=start,end=end,graph=False)
|
702
|
+
if df_tmp is None:
|
703
|
+
print(f" #Warning(economy_mticker_wb): indicator info not found for {t}")
|
704
|
+
continue
|
705
|
+
if len(df_tmp)==0:
|
706
|
+
print(f" #Warning(economy_mticker_wb): zero info found for {t} between {start} and {end}")
|
707
|
+
continue
|
708
|
+
|
709
|
+
have_data=True
|
710
|
+
|
711
|
+
country=df_tmp['country'].values[0]
|
712
|
+
country_list=country_list+[country]
|
713
|
+
unit=df_tmp['unit'].values[0]
|
714
|
+
unit_list=unit_list+[unit]
|
715
|
+
df_tmp.drop(columns=['country','unit'],inplace=True)
|
716
|
+
indicator_name=list(df_tmp)[0]
|
717
|
+
|
718
|
+
if t in band_area:
|
719
|
+
band_area = [country if x == t else x for x in band_area]
|
720
|
+
|
721
|
+
df_tmp.rename(columns={indicator_name:country},inplace=True)
|
722
|
+
|
723
|
+
if len(dfs)==0:
|
724
|
+
dfs=df_tmp
|
725
|
+
else:
|
726
|
+
dfs=pd.concat([dfs,df_tmp],axis=1,join='outer')
|
727
|
+
|
728
|
+
if dfs is None:
|
729
|
+
print(f" #Error(economy_mticker_wb): no records found for {measure}")
|
730
|
+
return None
|
731
|
+
if len(dfs)==0:
|
732
|
+
print(" #Error(economy_mticker_wb): zero records found for {measure}")
|
733
|
+
return None
|
734
|
+
|
735
|
+
# 若不绘图则返回原始数据
|
736
|
+
if not graph: return dfs
|
737
|
+
|
738
|
+
if not have_data:
|
739
|
+
#print(f" #Error(economy_mticker_wb): no record found on {indicator} for {ticker}")
|
740
|
+
return None
|
741
|
+
|
742
|
+
# 绘图
|
743
|
+
titletxt=text_lang("经济趋势分析","Economic Trend Analysis")+': '+indicator_name
|
744
|
+
y_label=indicator_name
|
745
|
+
|
746
|
+
import datetime; todaydt = datetime.date.today()
|
747
|
+
footnote2=text_lang("数据来源:WB/IMF/FRED","Data source: World Bank")+', '+str(todaydt)
|
748
|
+
|
749
|
+
one_unit=False
|
750
|
+
if len(set(unit_list)) == 1: one_unit=True
|
751
|
+
if one_unit:
|
752
|
+
x_label=footnote2
|
753
|
+
else:
|
754
|
+
footnote1=text_lang('注:','Notes: '); country_list_len=len(country_list)
|
755
|
+
for ind in country_list:
|
756
|
+
pos=country_list.index(ind)
|
757
|
+
footnote1=footnote1+ind+' '+unit_list[pos]
|
758
|
+
if (pos < country_list_len - 1):
|
759
|
+
if (pos+1) % 2 != 0:
|
760
|
+
footnote1=footnote1+', '
|
761
|
+
else:
|
762
|
+
footnote1=footnote1+'\n'
|
763
|
+
|
764
|
+
x_label=footnote1+'\n'+footnote2
|
765
|
+
|
766
|
+
if preprocess == 'scaling' and scaling_option == 'change%':
|
767
|
+
title_txt2=text_lang("增减幅度%","Change%")
|
768
|
+
titletxt=titletxt+', '+title_txt2
|
769
|
+
axhline_value=0
|
770
|
+
axhline_label="零线"
|
771
|
+
else:
|
772
|
+
if one_unit and unit != '':
|
773
|
+
titletxt=titletxt+', '+unit
|
774
|
+
|
775
|
+
# 为避免出错,对空值进行插值
|
776
|
+
dfs.interpolate(method='linear',limit_direction='both',inplace=True)
|
777
|
+
# 标准化处理
|
778
|
+
try:
|
779
|
+
dfs2,axhline_label,x_label,y_label,plus_sign=df_preprocess(dfs,measure, \
|
780
|
+
axhline_label=axhline_label,x_label=x_label,y_label=y_label, \
|
781
|
+
preprocess=preprocess,scaling_option=scaling_option)
|
782
|
+
except:
|
783
|
+
print(" #Error(economy_mticker_wb): preprocess failed, returning dfs for further check")
|
784
|
+
return dfs
|
785
|
+
|
786
|
+
if DEBUG:
|
787
|
+
print("DEBUG: dfs2=",list(dfs2))
|
788
|
+
|
789
|
+
above_zero=0; below_zero=0
|
790
|
+
for c in list(dfs2):
|
791
|
+
c_max=dfs2[c].max(); c_min=dfs2[c].min()
|
792
|
+
try:
|
793
|
+
if c_max>0 or c_min>0: above_zero+=1
|
794
|
+
if c_max<0 or c_min<0: below_zero+=1
|
795
|
+
except: continue
|
796
|
+
|
797
|
+
if DEBUG:
|
798
|
+
print("DEBUG: above_zero=",above_zero,'below_zero=',below_zero)
|
799
|
+
|
800
|
+
if above_zero>0 and below_zero>0: #有正有负
|
801
|
+
if axhline_label=='':
|
802
|
+
axhline_label='零线'
|
803
|
+
|
804
|
+
draw_lines(dfs2,y_label,x_label,axhline_value,axhline_label,titletxt, \
|
805
|
+
data_label=False,resample_freq='D',smooth=smooth,linewidth=linewidth, \
|
806
|
+
band_area=band_area,loc=loc, \
|
807
|
+
attention_value=attention_value,attention_value_area=attention_value_area, \
|
808
|
+
attention_point=attention_point,attention_point_area=attention_point_area, \
|
809
|
+
annotate=annotate,annotate_value=annotate_value,plus_sign=plus_sign, \
|
810
|
+
mark_top=mark_top,mark_bottom=mark_bottom,mark_end=mark_end,facecolor=facecolor, \
|
811
|
+
maxticks=30,translate=translate)
|
812
|
+
|
813
|
+
return dfs2
|
814
|
+
|
815
|
+
#==============================================================================
|
816
|
+
|
817
|
+
|
818
|
+
def economy_trend2(ticker='CN',indicator='NY.GDP.MKTP.KN', \
|
819
|
+
start='L10Y',end='today',translate=False, \
|
820
|
+
attention_value='',attention_value_area='', \
|
821
|
+
attention_point='',attention_point_area='', \
|
822
|
+
mark_top=False,mark_bottom=False,mark_end=False, \
|
823
|
+
graph=True,facecolor='whitesmoke',loc='best',maxticks=30, \
|
824
|
+
|
825
|
+
zeroline=False,average_value=False, \
|
826
|
+
datatag=False,power=0, \
|
827
|
+
|
828
|
+
annotate=False,annotate_value=False,smooth=False, \
|
829
|
+
|
830
|
+
band_area='',date_range=False,date_freq=False, \
|
831
|
+
|
832
|
+
axhline_value=0,axhline_label='', \
|
833
|
+
preprocess='none',linewidth=1.5, \
|
834
|
+
scaling_option='start', \
|
835
|
+
plus_sign=False, \
|
836
|
+
):
|
837
|
+
"""
|
838
|
+
功能:分析宏观经济指标,支持单国家单指标、多国家单指标、单国家多指标
|
839
|
+
主要公共参数:
|
840
|
+
ticker:国家编码,两位或三位ISO编码,默认'CN'
|
841
|
+
indicator:宏观经济指标,默认GDP (constant LCU),即本币不变价格GDP
|
842
|
+
start:开始日期,默认近十年
|
843
|
+
end:结束日期,默认当前日期
|
844
|
+
attention_value:纵轴关注值或其列表,默认无''
|
845
|
+
attention_value_area:纵轴关注值区间强调,默认无''
|
846
|
+
attention_point:横轴关注值或其列表,默认无''
|
847
|
+
attention_point_area:横轴关注值区间强调,默认无''
|
848
|
+
graph:是否绘图,默认是True
|
849
|
+
mark_top, mark_bottom, mark_end:是否标记最高、最低和末端点:默认是True
|
850
|
+
facecolor:背景颜色,默认'whitesmoke'
|
851
|
+
loc:图例位置,默认自动'best'
|
852
|
+
|
853
|
+
仅支持单国家单指标的参数:
|
854
|
+
zeroline:是否绘制零线,默认False
|
855
|
+
average_value:是否绘制均值线,默认否False
|
856
|
+
datatag:是否标记折线中的各个数据点的数值,默认否False
|
857
|
+
power:是否绘制趋势线,默认否0
|
858
|
+
|
859
|
+
支持多国家单指标、单国家多指标的参数:
|
860
|
+
annotate:是否在曲线末端标注,默认否False
|
861
|
+
annotate_value:是否标注曲线末端值,默认否False
|
862
|
+
|
863
|
+
仅支持单国家多指标的参数:
|
864
|
+
band_area:两条曲线之间强调,默认无''
|
865
|
+
date_range:指定开始结束日期绘图,默认False
|
866
|
+
date_freq:指定横轴日期间隔,默认False。
|
867
|
+
可指定'D'、'2D'、'W'、'M'等,横轴一般不超过25个标注,否则会重叠
|
868
|
+
|
869
|
+
仅支持多国家单指标的参数:
|
870
|
+
preprocess:数据预处理,默认无'none'
|
871
|
+
scaling_option:数据缩放方法,默认'start',仅当preprocess为非'none'时有效
|
872
|
+
plus_sign:在缩放处理时,纵轴刻度是否带加减号,默认否False
|
873
|
+
linewidth:曲线宽度,默认1.5
|
874
|
+
|
875
|
+
输出:绘图
|
876
|
+
返回值:数据表
|
877
|
+
|
878
|
+
其他:套壳函数
|
879
|
+
"""
|
880
|
+
# 判断ticker个数
|
881
|
+
ticker_num=0
|
882
|
+
if isinstance(ticker,str):
|
883
|
+
ticker_num=1
|
884
|
+
ticker=ticker.upper()
|
885
|
+
if not check_country_code(ticker=ticker,show_name=False):
|
886
|
+
print(f" #Warning(economy_trend2): country code {ticker} not found")
|
887
|
+
return None
|
888
|
+
|
889
|
+
if isinstance(ticker,list):
|
890
|
+
ticker=[x.upper() for x in ticker]
|
891
|
+
for t in ticker:
|
892
|
+
if not check_country_code(ticker=t,show_name=False):
|
893
|
+
ticker.remove(t)
|
894
|
+
print(f" #Warning(economy_trend2): country code {t} not found")
|
895
|
+
if len(ticker)==0:
|
896
|
+
return None
|
897
|
+
|
898
|
+
if len(ticker)==1:
|
899
|
+
ticker_num=1
|
900
|
+
ticker=ticker[0]
|
901
|
+
else:
|
902
|
+
ticker_num=len(ticker)
|
903
|
+
|
904
|
+
# 判断indicator个数
|
905
|
+
indicator_num=0
|
906
|
+
if isinstance(indicator,str): indicator_num=1
|
907
|
+
if isinstance(indicator,list):
|
908
|
+
if len(indicator)==1:
|
909
|
+
indicator_num=1
|
910
|
+
indicator=indicator[0]
|
911
|
+
else:
|
912
|
+
indicator_num=len(indicator)
|
913
|
+
|
914
|
+
# 单国家+单指标
|
915
|
+
if ticker_num==1 and indicator_num==1:
|
916
|
+
df=economy_indicator_wb(ticker=ticker,indicator=indicator, \
|
917
|
+
start=start,end=end,translate=translate, \
|
918
|
+
attention_value=attention_value, \
|
919
|
+
attention_value_area=attention_value_area, \
|
920
|
+
attention_point=attention_point, \
|
921
|
+
attention_point_area=attention_point_area, \
|
922
|
+
mark_top=mark_top,mark_bottom=mark_bottom,mark_end=mark_end, \
|
923
|
+
graph=graph,facecolor=facecolor,loc=loc,maxticks=maxticks, \
|
924
|
+
|
925
|
+
power=power,average_value=average_value, \
|
926
|
+
zeroline=zeroline,datatag=datatag)
|
927
|
+
return df
|
928
|
+
|
929
|
+
# 多国家:仅使用第一个指标
|
930
|
+
if ticker_num > 1:
|
931
|
+
df=economy_mtickers_wb(ticker=ticker,indicator=indicator, \
|
932
|
+
start=start,end=end,translate=translate, \
|
933
|
+
attention_value=attention_value, \
|
934
|
+
attention_value_area=attention_value_area, \
|
935
|
+
attention_point=attention_point, \
|
936
|
+
attention_point_area=attention_point_area, \
|
937
|
+
mark_top=mark_top,mark_bottom=mark_bottom,mark_end=mark_end, \
|
938
|
+
graph=graph,loc=loc,facecolor=facecolor,maxticks=maxticks, \
|
939
|
+
band_area=band_area, \
|
940
|
+
annotate=annotate,annotate_value=annotate_value,smooth=smooth, \
|
941
|
+
|
942
|
+
preprocess=preprocess,scaling_option=scaling_option, \
|
943
|
+
plus_sign=plus_sign,linewidth=linewidth, \
|
944
|
+
axhline_value=axhline_value,axhline_label=axhline_label)
|
945
|
+
return df
|
946
|
+
|
947
|
+
# 单国家:使用多个指标
|
948
|
+
if ticker_num == 1 and indicator_num > 1:
|
949
|
+
df=economy_mindicators_wb(ticker=ticker,indicator=indicator, \
|
950
|
+
start=start,end=end,translate=translate, \
|
951
|
+
attention_value=attention_value, \
|
952
|
+
attention_value_area=attention_value_area, \
|
953
|
+
attention_point=attention_point, \
|
954
|
+
attention_point_area=attention_point_area, \
|
955
|
+
mark_top=mark_top,mark_bottom=mark_bottom,mark_end=mark_end, \
|
956
|
+
graph=graph,facecolor=facecolor,loc=loc,maxticks=maxticks, \
|
957
|
+
|
958
|
+
annotate=annotate,annotate_value=annotate_value,smooth=smooth, \
|
959
|
+
|
960
|
+
band_area=band_area, \
|
961
|
+
date_range=date_range,date_freq=date_freq)
|
962
|
+
return df
|
963
|
+
|
964
|
+
print(" #Warning: need at least 1 country and at leats 1 indicator")
|
965
|
+
|
966
|
+
return None
|
967
|
+
|
968
|
+
|
969
|
+
#==============================================================================
|
970
|
+
#==============================================================================
|
971
|
+
#==============================================================================
|
972
|
+
#==============================================================================
|
973
|
+
#==============================================================================
|
974
|
+
#==============================================================================
|
975
|
+
#==============================================================================
|
976
|
+
|