siat 3.4.17__py3-none-any.whl → 3.4.32__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/common.py +2 -2
- siat/economy.py +157 -21
- siat/grafix.py +15 -14
- siat/sector_china.py +154 -28
- siat/translate.py +9 -1
- siat-3.4.32.dist-info/LICENSE +7 -0
- {siat-3.4.17.dist-info → siat-3.4.32.dist-info}/METADATA +25 -21
- {siat-3.4.17.dist-info → siat-3.4.32.dist-info}/RECORD +10 -9
- {siat-3.4.17.dist-info → siat-3.4.32.dist-info}/WHEEL +0 -0
- {siat-3.4.17.dist-info → siat-3.4.32.dist-info}/top_level.txt +0 -0
siat/common.py
CHANGED
@@ -2461,7 +2461,7 @@ if __name__=='__main__':
|
|
2461
2461
|
alist=['NIO','LI','XPEV','TSLA']
|
2462
2462
|
print_list(alist)
|
2463
2463
|
|
2464
|
-
def print_list(alist,leading_blanks=1):
|
2464
|
+
def print_list(alist,leading_blanks=1,end='\n'):
|
2465
2465
|
"""
|
2466
2466
|
功能:打印一个字符串列表,不带引号,节省空间
|
2467
2467
|
"""
|
@@ -2469,7 +2469,7 @@ def print_list(alist,leading_blanks=1):
|
|
2469
2469
|
|
2470
2470
|
for i in alist:
|
2471
2471
|
print(i,end=' ')
|
2472
|
-
print('
|
2472
|
+
print(end,end='')
|
2473
2473
|
|
2474
2474
|
return
|
2475
2475
|
|
siat/economy.py
CHANGED
@@ -197,7 +197,8 @@ if __name__=='__main__':
|
|
197
197
|
|
198
198
|
|
199
199
|
|
200
|
-
def economy_trend(start,end,scope='China',factor='GDP',datatag=False,power=0,
|
200
|
+
def economy_trend(start,end,scope='China',factor='GDP',datatag=False,power=0, \
|
201
|
+
zeroline=False,yline=999,facecolor='papayawhip'):
|
201
202
|
"""
|
202
203
|
功能:绘制宏观经济指标,单线,有趋势线
|
203
204
|
"""
|
@@ -222,7 +223,26 @@ def economy_trend(start,end,scope='China',factor='GDP',datatag=False,power=0,zer
|
|
222
223
|
footnote='单位: '+list(ds['units'])[0]+', '+list(ds['freq'])[0]+ \
|
223
224
|
'\n数据来源: OECD|IMF|WB|FRED, '+str(today)
|
224
225
|
ds.dropna(inplace=True)
|
225
|
-
|
226
|
+
|
227
|
+
if factor in ['GNP Ratio','GNI Ratio']:
|
228
|
+
ylabeltxt='GNP(GNI)/GDP'
|
229
|
+
if yline==999:
|
230
|
+
yline=1 #绘制y=1的水平线
|
231
|
+
if factor in ['Currency Value','Constant CPI']:
|
232
|
+
ylabeltxt=ectranslate(factor)
|
233
|
+
if yline==999:
|
234
|
+
yline=100 #绘制y=100的水平线
|
235
|
+
|
236
|
+
if yline !=999:
|
237
|
+
zeroline=yline
|
238
|
+
if power==0:
|
239
|
+
power=3
|
240
|
+
|
241
|
+
plot_line(ds,'VALUE',ectranslate(factor), \
|
242
|
+
ylabeltxt=ylabeltxt,titletxt=titletxt,footnote=footnote,datatag=datatag, \
|
243
|
+
power=power,zeroline=zeroline, \
|
244
|
+
mark_top=False,mark_bottom=False,mark_end=False, \
|
245
|
+
facecolor=facecolor)
|
226
246
|
|
227
247
|
return ds
|
228
248
|
|
@@ -236,16 +256,26 @@ if __name__=='__main__':
|
|
236
256
|
|
237
257
|
#==============================================================================
|
238
258
|
if __name__=='__main__':
|
259
|
+
#测试1
|
239
260
|
tickers=['China','USA']
|
240
261
|
measures='M2 GoB'
|
241
262
|
measures='GNI'
|
263
|
+
|
264
|
+
#测试2
|
265
|
+
tickers=['China','USA']
|
266
|
+
measures='Constant CPI'
|
267
|
+
measures='Currency Value'
|
268
|
+
|
269
|
+
|
270
|
+
|
242
271
|
fromdate='1999-12-1'
|
243
272
|
todate='2022-4-1'
|
244
273
|
power=0; twinx=False; loc1='upper left'; loc2='lower right'
|
245
274
|
|
246
275
|
|
247
276
|
def compare_economy(tickers,measures,fromdate,todate,power=0,twinx=False, \
|
248
|
-
|
277
|
+
yline=999, \
|
278
|
+
loc1='upper left',loc2='lower right',facecolor='papayawhip'):
|
249
279
|
"""
|
250
280
|
功能:对比绘制折线图:一个国家的两种测度,或两个国家的同一个测度。
|
251
281
|
输入:
|
@@ -260,6 +290,10 @@ def compare_economy(tickers,measures,fromdate,todate,power=0,twinx=False, \
|
|
260
290
|
输出:绘制经济指标折线图,手动指定是否使用单轴或双轴坐标。
|
261
291
|
返回:无
|
262
292
|
"""
|
293
|
+
DEBUG=False
|
294
|
+
if DEBUG:
|
295
|
+
print("DEBUG: tickers =",tickers,"\b, measures =",measures)
|
296
|
+
|
263
297
|
#检查日期期间的合理性
|
264
298
|
valid,_,_=check_period(fromdate,todate)
|
265
299
|
if not valid:
|
@@ -354,15 +388,21 @@ def compare_economy(tickers,measures,fromdate,todate,power=0,twinx=False, \
|
|
354
388
|
source_txt+str(today)
|
355
389
|
|
356
390
|
if lang == 'Chinese':
|
391
|
+
"""
|
357
392
|
plot_line2(df1,ectranslate(ticker1),'VALUE',ectranslate(measure1), \
|
358
393
|
df2,ectranslate(ticker1),'VALUE',ectranslate(measure2), \
|
359
394
|
ylabeltxt,titletxt,footnote, \
|
360
395
|
power=power,twinx=twinx,loc1=loc1,loc2=loc2)
|
396
|
+
"""
|
397
|
+
plot_line2(df1,ticker1,'VALUE',ectranslate(measure1), \
|
398
|
+
df2,ticker1,'VALUE',ectranslate(measure2), \
|
399
|
+
ylabeltxt,titletxt,footnote, \
|
400
|
+
power=power,twinx=twinx,loc1=loc1,loc2=loc2,facecolor=facecolor)
|
361
401
|
else:
|
362
402
|
plot_line2(df1,ticker1,'VALUE',measure1, \
|
363
403
|
df2,ticker1,'VALUE',measure2, \
|
364
404
|
ylabeltxt,titletxt,footnote, \
|
365
|
-
power=power,twinx=twinx,loc1=loc1,loc2=loc2)
|
405
|
+
power=power,twinx=twinx,loc1=loc1,loc2=loc2,facecolor=facecolor)
|
366
406
|
|
367
407
|
elif (security_num >= 2) and (measure_num >= 1):
|
368
408
|
#双国家+单个测度指标
|
@@ -402,13 +442,15 @@ def compare_economy(tickers,measures,fromdate,todate,power=0,twinx=False, \
|
|
402
442
|
#绘制双国家单指标对比图
|
403
443
|
ylabeltxt=ectranslate(measure1)
|
404
444
|
#这里的GNP指标实际上是GNP vs GDP的百分比
|
405
|
-
yline=999 #默认不绘制水平线
|
445
|
+
#yline=999 #默认不绘制水平线
|
406
446
|
if measure1 in ['GNP Ratio','GNI Ratio']:
|
407
447
|
ylabeltxt='GNP(GNI)/GDP'
|
408
|
-
yline
|
448
|
+
if yline==999:
|
449
|
+
yline=1 #绘制y=1的水平线
|
409
450
|
if measure1 in ['Currency Value','Constant CPI']:
|
410
451
|
ylabeltxt=ectranslate(measure1)
|
411
|
-
yline
|
452
|
+
if yline==999:
|
453
|
+
yline=100 #绘制y=100的水平线
|
412
454
|
|
413
455
|
if lang == 'Chinese':
|
414
456
|
titletxt=ectranslate(list(df1['name'])[0])+'趋势对比:'+ \
|
@@ -425,15 +467,21 @@ def compare_economy(tickers,measures,fromdate,todate,power=0,twinx=False, \
|
|
425
467
|
source_txt+str(today)
|
426
468
|
|
427
469
|
if lang == 'Chinese':
|
470
|
+
"""
|
428
471
|
plot_line2(df1,ectranslate(ticker1),'VALUE',ectranslate(measure1), \
|
429
472
|
df2,ectranslate(ticker2),'VALUE',ectranslate(measure1), \
|
430
473
|
ylabeltxt,titletxt,footnote, \
|
431
474
|
power=power,twinx=twinx,yline=yline,loc1=loc1,loc2=loc2)
|
475
|
+
"""
|
476
|
+
plot_line2(df1,ticker1,'VALUE',measure1, \
|
477
|
+
df2,ticker2,'VALUE',measure1, \
|
478
|
+
ylabeltxt,titletxt,footnote, \
|
479
|
+
power=power,twinx=twinx,yline=yline,loc1=loc1,loc2=loc2,facecolor=facecolor)
|
432
480
|
else:
|
433
481
|
plot_line2(df1,ticker1,'VALUE',measure1, \
|
434
482
|
df2,ticker2,'VALUE',measure1, \
|
435
483
|
ylabeltxt,titletxt,footnote, \
|
436
|
-
power=power,twinx=twinx,yline=yline,loc1=loc1,loc2=loc2)
|
484
|
+
power=power,twinx=twinx,yline=yline,loc1=loc1,loc2=loc2,facecolor=facecolor)
|
437
485
|
|
438
486
|
else:
|
439
487
|
print(" #Error(compare_economy): no idea on what to compare")
|
@@ -711,7 +759,7 @@ def fred_factor_codes():
|
|
711
759
|
['Italy','Current GDP','Annual','Gross Domestic Product','MKTGDPITA646NWDB','Current USD, Not Seasonally Adjusted'],
|
712
760
|
['Cambodia','Current GDP','Annual','Gross Domestic Product','MKTGDPKHA646NWDB','Current USD, Not Seasonally Adjusted'],
|
713
761
|
|
714
|
-
# Real GDP at Constant National Prices:不变价格GDP
|
762
|
+
# Real GDP at Constant National Prices:不变价格GDP,年度指标,百万元,2017年基准,未经季节性调整。扣除通胀因素,扣除汇率变化因素
|
715
763
|
['India','Constant GDP','Annual','Real GDP at Constant National Prices','RGDPNAINA666NRUG','2017 USD Millions, Not Seasonally Adjusted'],
|
716
764
|
['China','Constant GDP','Annual','Real GDP at Constant National Prices','RGDPNACNA666NRUG','2017 USD Millions, Not Seasonally Adjusted'],
|
717
765
|
['Japan','Constant GDP','Annual','Real GDP at Constant National Prices','RGDPNAJPA666NRUG','2017 USD Millions, Not Seasonally Adjusted'],
|
@@ -1027,11 +1075,12 @@ def fred_factor_codes():
|
|
1027
1075
|
#==============================================================================
|
1028
1076
|
#==============================================================================
|
1029
1077
|
if __name__ =="__main__":
|
1030
|
-
fromdate='
|
1031
|
-
todate='
|
1078
|
+
fromdate='2024-1-1'
|
1079
|
+
todate='2024-8-31'
|
1032
1080
|
df=pmi_china(fromdate,todate)
|
1081
|
+
loc='best'; facecolor='papayawhip'
|
1033
1082
|
|
1034
|
-
def pmi_china(fromdate,todate,loc='
|
1083
|
+
def pmi_china(fromdate,todate,date_range=True,loc='best',facecolor='papayawhip'):
|
1035
1084
|
"""
|
1036
1085
|
功能:绘制中国的PMI指数制造业/非制造业单线图
|
1037
1086
|
"""
|
@@ -1072,6 +1121,7 @@ def pmi_china(fromdate,todate,loc='lower center'):
|
|
1072
1121
|
df2['制造业PMI']=df2['制造业-指数'].astype('float')
|
1073
1122
|
df2['非制造业PMI']=df2['非制造业-指数'].astype('float')
|
1074
1123
|
|
1124
|
+
"""
|
1075
1125
|
#绘图:制造业
|
1076
1126
|
ticker1=ticker2='PMI'
|
1077
1127
|
colname2="benchmark"
|
@@ -1087,7 +1137,7 @@ def pmi_china(fromdate,todate,loc='lower center'):
|
|
1087
1137
|
titletxt="中国采购经理人指数PMI:制造业"
|
1088
1138
|
plot_line2(df2,ticker1,colname1,label1, \
|
1089
1139
|
df2,ticker2,colname2,label2, \
|
1090
|
-
ylabeltxt,titletxt,footnote,loc1=loc)
|
1140
|
+
ylabeltxt,titletxt,footnote,loc1=loc,facecolor=facecolor)
|
1091
1141
|
|
1092
1142
|
#绘图:非制造业
|
1093
1143
|
colname1="非制造业PMI"
|
@@ -1095,13 +1145,24 @@ def pmi_china(fromdate,todate,loc='lower center'):
|
|
1095
1145
|
titletxt="中国采购经理人指数PMI:非制造业"
|
1096
1146
|
plot_line2(df2,ticker1,colname1,label1, \
|
1097
1147
|
df2,ticker2,colname2,label2, \
|
1098
|
-
ylabeltxt,titletxt,footnote,loc1=loc)
|
1148
|
+
ylabeltxt,titletxt,footnote,loc1=loc,facecolor=facecolor)
|
1099
1149
|
"""
|
1150
|
+
titletxt="中国采购经理人指数PMI"
|
1151
|
+
ticker1=ticker2='PMI'
|
1152
|
+
colname1="制造业PMI"; label1="制造业"
|
1153
|
+
colname2="非制造业PMI"; label2="非制造业"
|
1154
|
+
ylabeltxt=''
|
1155
|
+
|
1156
|
+
import datetime
|
1157
|
+
today=datetime.date.today()
|
1158
|
+
footnote="数据来源:东方财富,"+str(today)
|
1159
|
+
|
1100
1160
|
plot2_line2(df2,ticker1,colname1,label1, \
|
1101
1161
|
df2,ticker2,colname2,label2, \
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1162
|
+
yline=50, \
|
1163
|
+
ylabeltxt=ylabeltxt,titletxt=titletxt,footnote=footnote,loc1=loc, \
|
1164
|
+
date_range=date_range,date_fmt='%Y-%m',facecolor=facecolor)
|
1165
|
+
|
1105
1166
|
#返回数据
|
1106
1167
|
return df2
|
1107
1168
|
|
@@ -1168,13 +1229,13 @@ def internal_growth_rate_df(df0,fieldlist=['VALUE','scope','factor','freq','name
|
|
1168
1229
|
if lang == 'Chinese':
|
1169
1230
|
print('从'+date0+'至'+date1+':')
|
1170
1231
|
if freq != 'Annual':
|
1171
|
-
print(' '+ectranslate(scope)+ectranslate(factor)+'的'+ectranslate(freq)+'
|
1172
|
-
print(' '+ectranslate(scope)+ectranslate(factor)+'
|
1232
|
+
print(' '+ectranslate(scope)+ectranslate(factor)+'的'+ectranslate(freq)+'均环比复合增长率:',round(item_gr*100.0,4),'\b%')
|
1233
|
+
print(' '+ectranslate(scope)+ectranslate(factor)+'的年均复合增长率:',round(annual_gr*100.0,4),'\b%')
|
1173
1234
|
else:
|
1174
1235
|
print('From '+date0+' to '+date1+':')
|
1175
1236
|
if freq != 'Annual':
|
1176
|
-
print(' '+scope+', '+factor+' mom growth rate:',round(item_gr*100.0,4),'\b%')
|
1177
|
-
print(' '+scope+', '+factor+' yoy growth rate:',round(annual_gr*100.0,4),'\b%')
|
1237
|
+
print(' '+scope+', '+factor+' mom compound growth rate:',round(item_gr*100.0,4),'\b%')
|
1238
|
+
print(' '+scope+', '+factor+' yoy compound growth rate:',round(annual_gr*100.0,4),'\b%')
|
1178
1239
|
|
1179
1240
|
return
|
1180
1241
|
|
@@ -1204,6 +1265,81 @@ def internal_growth_rate(rvar,fieldlist=['VALUE','scope','factor','freq','name',
|
|
1204
1265
|
if __name__ =="__main__":
|
1205
1266
|
internal_growth_rate(df)
|
1206
1267
|
#==============================================================================
|
1268
|
+
if __name__ =="__main__":
|
1269
|
+
ticker='China'
|
1270
|
+
indicator='GDP'
|
1271
|
+
|
1272
|
+
|
1273
|
+
def macro_trend(ticker,indicator,start='L10Y',end='today', \
|
1274
|
+
power=0,twinx=False,attention_value=999,zeroline=False, \
|
1275
|
+
datatag=False,date_range=False, \
|
1276
|
+
loc1='best',loc2='best',facecolor='papayawhip'):
|
1277
|
+
"""
|
1278
|
+
功能:套壳函数,compare_economy, economy_trend
|
1279
|
+
"""
|
1280
|
+
|
1281
|
+
# 处理日期
|
1282
|
+
fromdate,todate=start_end_preprocess(start,end)
|
1283
|
+
|
1284
|
+
# 判断ticker个数
|
1285
|
+
if isinstance(ticker,str):
|
1286
|
+
ticker_num=1
|
1287
|
+
if isinstance(ticker,list):
|
1288
|
+
ticker_num=len(ticker)
|
1289
|
+
if ticker_num==1:
|
1290
|
+
ticker=ticker[0]
|
1291
|
+
|
1292
|
+
# 判断indicator个数
|
1293
|
+
if isinstance(indicator,str):
|
1294
|
+
indicator_num=1
|
1295
|
+
if isinstance(indicator,list):
|
1296
|
+
indicator_num=len(indicator)
|
1297
|
+
if indicator_num==1:
|
1298
|
+
indicator=indicator[0]
|
1299
|
+
|
1300
|
+
# 是否PMI
|
1301
|
+
if ticker_num==1 and indicator_num==1:
|
1302
|
+
if indicator.upper()=='PMI' and ticker.title()=='China':
|
1303
|
+
df=pmi_china(fromdate=fromdate,todate=todate, \
|
1304
|
+
date_range=date_range,loc=loc1,facecolor=facecolor)
|
1305
|
+
|
1306
|
+
return df
|
1307
|
+
|
1308
|
+
# 双ticker或者双indicator
|
1309
|
+
if ticker_num>=2 or indicator_num>=2:
|
1310
|
+
if 'YoY PPI' in indicator:
|
1311
|
+
attention_value=0
|
1312
|
+
|
1313
|
+
df=compare_economy(tickers=ticker,measures=indicator, \
|
1314
|
+
fromdate=fromdate,todate=todate, \
|
1315
|
+
power=power,twinx=twinx, \
|
1316
|
+
yline=attention_value, \
|
1317
|
+
loc1=loc1,loc2=loc2,facecolor=facecolor)
|
1318
|
+
# 计算增长率
|
1319
|
+
# 有inf/nan错误,未找出原因,先避开
|
1320
|
+
if not 'YoY PPI' in indicator:
|
1321
|
+
internal_growth_rate(df)
|
1322
|
+
return df
|
1323
|
+
|
1324
|
+
# 单ticker且单indicator
|
1325
|
+
if ticker_num==1 and indicator_num==1:
|
1326
|
+
if 'YoY PPI' in indicator:
|
1327
|
+
attention_value=0
|
1328
|
+
|
1329
|
+
df=economy_trend(start=fromdate,end=todate,scope=ticker,factor=indicator, \
|
1330
|
+
datatag=datatag,power=power, \
|
1331
|
+
zeroline=zeroline,yline=attention_value,facecolor=facecolor)
|
1332
|
+
# 计算增长率
|
1333
|
+
# 有inf/nan错误,未找出原因,先避开
|
1334
|
+
if not 'YoY PPI' in indicator:
|
1335
|
+
internal_growth_rate(df)
|
1336
|
+
|
1337
|
+
return df
|
1338
|
+
|
1339
|
+
print(" #Warning(macro_trend): puzzled on what to for",ticker,"with",indicator)
|
1340
|
+
return None
|
1341
|
+
|
1342
|
+
|
1207
1343
|
#==============================================================================
|
1208
1344
|
#==============================================================================
|
1209
1345
|
|
siat/grafix.py
CHANGED
@@ -119,7 +119,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
119
119
|
resample_freq='H',loc='best', \
|
120
120
|
date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
|
121
121
|
mark_top=True,mark_bottom=True,mark_end=True, \
|
122
|
-
|
122
|
+
facecolor='whitesmoke'):
|
123
123
|
"""
|
124
124
|
功能:绘制折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
|
125
125
|
假定:数据表有索引,且已经按照索引排序
|
@@ -128,7 +128,8 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
128
128
|
mark_top,mark_bottom:是否标记最高最低点
|
129
129
|
输出:折线图
|
130
130
|
返回值:无
|
131
|
-
|
131
|
+
注意1:需要日期类型作为df索引
|
132
|
+
注意2:date_freq不为False时,必须设置date_range=True,否则无法完成日期设置!
|
132
133
|
"""
|
133
134
|
|
134
135
|
#空值判断
|
@@ -296,7 +297,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
296
297
|
ylabeltxt=ylabeltxt.replace('收盘价','单位净值')
|
297
298
|
|
298
299
|
plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
|
299
|
-
plt.xlabel(footnote,fontsize=xlabel_txt_size)
|
300
|
+
plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
|
300
301
|
plt.title(titletxt,fontweight='bold',fontsize=title_txt_size)
|
301
302
|
|
302
303
|
plt.show()
|
@@ -560,7 +561,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
|
|
560
561
|
plt.gca().set_facecolor("whitesmoke")
|
561
562
|
|
562
563
|
plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
|
563
|
-
plt.xlabel(footnote,fontsize=xlabel_txt_size)
|
564
|
+
plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
|
564
565
|
plt.title(titletxt,fontweight='bold',fontsize=title_txt_size)
|
565
566
|
plt.show()
|
566
567
|
plt.close()
|
@@ -749,7 +750,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
|
|
749
750
|
plt.gca().set_facecolor("whitesmoke")
|
750
751
|
|
751
752
|
plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
|
752
|
-
plt.xlabel(footnote,fontsize=xlabel_txt_size)
|
753
|
+
plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
|
753
754
|
plt.title(titletxt,fontweight='bold',fontsize=title_txt_size)
|
754
755
|
plt.show()
|
755
756
|
plt.close()
|
@@ -877,7 +878,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
|
|
877
878
|
label2txt=ticker_name(ticker2,ticker_type_list[1])+"("+trend_txt+")"
|
878
879
|
ax2.plot(df2.index, f(df2.id),"c--", label=label2txt,linewidth=1)
|
879
880
|
|
880
|
-
ax.set_xlabel(footnote,fontsize=xlabel_txt_size)
|
881
|
+
ax.set_xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
|
881
882
|
|
882
883
|
if ticker1 == '':
|
883
884
|
label1txt=label1
|
@@ -1019,7 +1020,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
|
|
1019
1020
|
label1txt=ticker_name(ticker1,ticker_type_list[0])+"("+trend_txt+")"
|
1020
1021
|
ax.plot(df1.index, f(df1.id),"r--", label=label1txt,linewidth=1)
|
1021
1022
|
|
1022
|
-
ax.set_xlabel(footnote,fontsize=xlabel_txt_size)
|
1023
|
+
ax.set_xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
|
1023
1024
|
|
1024
1025
|
if ticker1 == '':
|
1025
1026
|
label1txt=label1
|
@@ -1307,7 +1308,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1307
1308
|
|
1308
1309
|
x_label_t=ectranslate(x_label)
|
1309
1310
|
if x_label != "":
|
1310
|
-
plt.xlabel(x_label_t,fontweight='bold',fontsize=xlabel_txt_size)
|
1311
|
+
plt.xlabel(x_label_t,fontweight='bold',fontsize=xlabel_txt_size,ha='center')
|
1311
1312
|
#图示标题
|
1312
1313
|
plt.title(title_txt,fontweight='bold',fontsize=title_txt_size)
|
1313
1314
|
|
@@ -1541,7 +1542,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1541
1542
|
#坐标轴标记
|
1542
1543
|
plt.ylabel(y_label,fontweight='bold',fontsize=ylabel_txt_size)
|
1543
1544
|
if x_label != "":
|
1544
|
-
plt.xlabel(x_label,fontweight='bold',fontsize=xlabel_txt_size)
|
1545
|
+
plt.xlabel(x_label,fontweight='bold',fontsize=xlabel_txt_size,ha='center')
|
1545
1546
|
#图示标题
|
1546
1547
|
plt.title(title_txt,fontweight='bold',fontsize=title_txt_size)
|
1547
1548
|
plt.gcf().autofmt_xdate() # 优化标注(自动倾斜)
|
@@ -1579,7 +1580,7 @@ def plot_barh(df,colname,titletxt,footnote,datatag=True, \
|
|
1579
1580
|
|
1580
1581
|
plt.barh(df.index,df[colname],align='center',color=colors,alpha=0.8)
|
1581
1582
|
coltxt=ectranslate(colname)
|
1582
|
-
plt.xlabel(footnote,fontsize=xlabel_txt_size)
|
1583
|
+
plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
|
1583
1584
|
plt.title(titletxt,fontweight='bold',fontsize=title_txt_size)
|
1584
1585
|
|
1585
1586
|
#xmin=int(min(df[colname]))
|
@@ -1784,7 +1785,7 @@ def plot_2lines(df01,colname1,label1, \
|
|
1784
1785
|
plt.axvline(x=vline,ls=":",c="black")
|
1785
1786
|
|
1786
1787
|
plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
|
1787
|
-
plt.xlabel(footnote,fontsize=xlabel_txt_size)
|
1788
|
+
plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
|
1788
1789
|
plt.legend(loc='best',fontsize=legend_txt_size)
|
1789
1790
|
|
1790
1791
|
plt.gcf().autofmt_xdate() # 优化标注(自动倾斜)
|
@@ -2007,7 +2008,7 @@ def plot_norm(mu,sd,graph='pdf',obs_num=100,facecolor='whitesmoke'):
|
|
2007
2008
|
wid1=5*sd+mu
|
2008
2009
|
wid2=1*sd+mu
|
2009
2010
|
plt.xticks(np.arange(-wid,wid1,wid2))
|
2010
|
-
plt.xlabel('分位点',fontsize=xlabel_txt_size) #x轴文本
|
2011
|
+
plt.xlabel('分位点',fontsize=xlabel_txt_size,ha='center') #x轴文本
|
2011
2012
|
plt.yticks(np.arange(0,0.45,0.05))
|
2012
2013
|
plt.ylabel('概率密度',fontsize=ylabel_txt_size) #y轴文本
|
2013
2014
|
|
@@ -2015,7 +2016,7 @@ def plot_norm(mu,sd,graph='pdf',obs_num=100,facecolor='whitesmoke'):
|
|
2015
2016
|
wid1=3.5*sd+mu
|
2016
2017
|
wid2=0.5*sd+mu
|
2017
2018
|
plt.xticks(np.arange(-wid,wid1,wid2))
|
2018
|
-
plt.xlabel('分位点',fontsize=xlabel_txt_size) #x轴文本
|
2019
|
+
plt.xlabel('分位点',fontsize=xlabel_txt_size,ha='center') #x轴文本
|
2019
2020
|
plt.yticks(np.arange(0,1.1,0.1))
|
2020
2021
|
plt.ylabel('累积概率密度',fontsize=ylabel_txt_size) #y轴文本
|
2021
2022
|
|
@@ -2026,7 +2027,7 @@ def plot_norm(mu,sd,graph='pdf',obs_num=100,facecolor='whitesmoke'):
|
|
2026
2027
|
plt.yticks(np.arange(-wid,wid1,wid2))
|
2027
2028
|
plt.ylabel('分位点',fontsize=ylabel_txt_size) #y轴文本
|
2028
2029
|
plt.xticks(np.arange(0,1.1,0.1))
|
2029
|
-
plt.xlabel('累积概率密度',fontsize=xlabel_txt_size) #x轴文本
|
2030
|
+
plt.xlabel('累积概率密度',fontsize=xlabel_txt_size,ha='center') #x轴文本
|
2030
2031
|
|
2031
2032
|
plt.title('正态分布示意图: $\mu$=%.1f, $\sigma$=%.1f'%(mu,sd),fontweight='bold',fontsize=title_txt_size) #标题
|
2032
2033
|
plt.tight_layout()
|
siat/sector_china.py
CHANGED
@@ -151,13 +151,24 @@ def sector_list_china(indicator="新浪行业"):
|
|
151
151
|
#==============================================================================
|
152
152
|
if __name__=='__main__':
|
153
153
|
sector_name="房地产"
|
154
|
+
sector_name="房"
|
155
|
+
sector_name="煤炭"
|
156
|
+
sector_name="华为"
|
157
|
+
|
158
|
+
indicator='新浪行业'
|
154
159
|
indicator="启明星行业"
|
155
160
|
indicator="地域"
|
156
161
|
indicator="行业"
|
157
162
|
|
158
|
-
sector_name="煤炭"
|
159
163
|
sector_code_china(sector_name)
|
160
164
|
|
165
|
+
def sector_code_sina(sector_name):
|
166
|
+
"""
|
167
|
+
功能:套壳sector_code_china
|
168
|
+
"""
|
169
|
+
sector_code_china(sector_name)
|
170
|
+
return
|
171
|
+
|
161
172
|
def sector_code_china(sector_name):
|
162
173
|
"""
|
163
174
|
功能:查找行业、板块名称对应的板块代码
|
@@ -175,26 +186,45 @@ def sector_code_china(sector_name):
|
|
175
186
|
dfi['label']=dfi['label'].apply(lambda x: x.strip())
|
176
187
|
|
177
188
|
try:
|
178
|
-
sector_code=list(dfi[dfi['板块']==sector_name]['label'])[0]
|
189
|
+
#sector_code=list(dfi[dfi['板块']==sector_name]['label'])[0]
|
190
|
+
dfi['match']=dfi['板块'].apply(lambda x: 1 if sector_name in x else 0)
|
191
|
+
found=found+dfi['match'].sum()
|
192
|
+
|
193
|
+
sector_code=list(dfi[dfi['match']==1]['label'])
|
194
|
+
sector_name1=list(dfi[dfi['match']==1]['板块'])
|
195
|
+
|
179
196
|
#记录找到的板块分类
|
180
197
|
indicator=i
|
181
|
-
#记录找到的板块概述
|
182
|
-
dff=dfi[dfi['板块']==sector_name]
|
183
198
|
|
184
|
-
if found > 0: print(" ")
|
199
|
+
#if found > 0: print(" ")
|
185
200
|
if indicator == "行业": indicator = "证监会行业"
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
201
|
+
|
202
|
+
if len(sector_code)>0:
|
203
|
+
"""
|
204
|
+
print("行业/板块名称:",sector_name1)
|
205
|
+
#print_list(sector_name1,leading_blanks=1)
|
206
|
+
|
207
|
+
print("行业/板块代码:",sector_code,end='')
|
208
|
+
#print_list(sector_code,leading_blanks=1)
|
209
|
+
|
210
|
+
print("("+indicator+"分类)\n")
|
211
|
+
"""
|
212
|
+
print("行业/板块名称:",end='')
|
213
|
+
print_list(sector_name1,leading_blanks=1)
|
214
|
+
|
215
|
+
print("行业/板块代码:",end='')
|
216
|
+
print_list(sector_code,leading_blanks=1,end='')
|
217
|
+
print("("+indicator+"分类)\n")
|
218
|
+
|
219
|
+
|
190
220
|
except:
|
191
221
|
# 无意义,仅为调试
|
192
|
-
|
222
|
+
pass
|
193
223
|
continue
|
194
224
|
|
195
225
|
#未找到板块代码
|
196
226
|
if found==0:
|
197
|
-
print("
|
227
|
+
print("*** Sorry, no sector name found for",sector_name)
|
198
228
|
return
|
199
229
|
|
200
230
|
return
|
@@ -220,6 +250,13 @@ if __name__=='__main__':
|
|
220
250
|
indicator="行业"
|
221
251
|
num=10
|
222
252
|
|
253
|
+
def sector_rank_sina(indicator="涨跌幅",category="新浪行业",rank=5):
|
254
|
+
"""
|
255
|
+
功能:套壳sector_rank_china
|
256
|
+
"""
|
257
|
+
df=sector_rank_china(comp=indicator,indicator=category,num=rank)
|
258
|
+
return df
|
259
|
+
|
223
260
|
def sector_rank_china(comp="涨跌幅",indicator="新浪行业",num=10):
|
224
261
|
"""
|
225
262
|
功能:按照比较指标降序排列
|
@@ -233,14 +270,14 @@ def sector_rank_china(comp="涨跌幅",indicator="新浪行业",num=10):
|
|
233
270
|
#complist=["涨跌幅","成交量","平均价格","公司家数"]
|
234
271
|
complist=["涨跌幅","平均价格","公司家数"]
|
235
272
|
if comp not in complist:
|
236
|
-
print("#
|
237
|
-
print("Supported measurements:",complist)
|
273
|
+
print(" #Warning(sector_rank_china): unsupported measurement",comp)
|
274
|
+
print(" Supported measurements:",complist)
|
238
275
|
return None
|
239
276
|
|
240
277
|
indicatorlist=["新浪行业","概念","地域","启明星行业","行业"]
|
241
278
|
if indicator not in indicatorlist:
|
242
|
-
print("#
|
243
|
-
print("Supported sectoring method:",indicatorlist)
|
279
|
+
print(" #Warning(sector_list_china): unsupported sectoring method",indicator)
|
280
|
+
print(" Supported sectoring method:",indicatorlist)
|
244
281
|
return None
|
245
282
|
|
246
283
|
import akshare as ak
|
@@ -252,9 +289,9 @@ def sector_rank_china(comp="涨跌幅",indicator="新浪行业",num=10):
|
|
252
289
|
df['label']=df['label'].apply(lambda x: x.strip())
|
253
290
|
|
254
291
|
except:
|
255
|
-
print("#
|
256
|
-
print("Possible reason: data source is self-updating.")
|
257
|
-
print("Solution: have a breath of fresh air and try later.")
|
292
|
+
print(" #Warning(sector_rank_china): data source tentatively unavailable for",indicator)
|
293
|
+
print(" Possible reason: data source is self-updating.")
|
294
|
+
print(" Solution: have a breath of fresh air and try later.")
|
258
295
|
return None
|
259
296
|
|
260
297
|
df.dropna(inplace=True)
|
@@ -322,12 +359,18 @@ def sector_rank_china(comp="涨跌幅",indicator="新浪行业",num=10):
|
|
322
359
|
|
323
360
|
#处理空记录
|
324
361
|
if len(df3) == 0:
|
325
|
-
print("#
|
326
|
-
print("Possible reason: data source is self-updating.")
|
327
|
-
print("Solution: have a breath of fresh air and try later.")
|
362
|
+
print(" #Warning(sector_rank_china):data source tentatively unavailable for",comp,indicator)
|
363
|
+
print(" Possible reason: data source is self-updating.")
|
364
|
+
print(" Solution: have a breath of fresh air and try later.")
|
328
365
|
return
|
329
366
|
|
330
367
|
df3.index=df3.index + 1
|
368
|
+
|
369
|
+
df3_collist=list(df3)
|
370
|
+
df3['序号']=df3.index
|
371
|
+
df3=df3[['序号']+df3_collist]
|
372
|
+
|
373
|
+
"""
|
331
374
|
print("\n===== 中国股票市场:板块"+comp+"排行榜(按照"+indtag+"分类) =====")
|
332
375
|
if num > 0:
|
333
376
|
print(df3.head(num))
|
@@ -339,6 +382,23 @@ def sector_rank_china(comp="涨跌幅",indicator="新浪行业",num=10):
|
|
339
382
|
footnote1="*注:代表个股是指板块中涨幅最高或跌幅最低的股票"
|
340
383
|
print(footnote1)
|
341
384
|
print(" 板块数:",len(df),"\b, 数据来源:新浪财经,",today,"\b(信息为上个交易日)")
|
385
|
+
"""
|
386
|
+
if num > 0:
|
387
|
+
df4=df3.head(num)
|
388
|
+
else:
|
389
|
+
df4=df3.tail(-num)
|
390
|
+
|
391
|
+
titletxt="中国股票市场:板块"+comp+"排行榜(按照"+indtag+"分类)"
|
392
|
+
import datetime; stoday = datetime.date.today()
|
393
|
+
footnote1="注:代表个股是指板块中涨幅最高或跌幅最低的股票\n"
|
394
|
+
footnote2="板块总数"+str(len(df))+",数据来源:新浪财经,"+str(stoday)+"(截至昨日)"
|
395
|
+
footnote=footnote1+footnote2
|
396
|
+
|
397
|
+
df_display_CSS(df4,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=2, \
|
398
|
+
first_col_align='center',second_col_align='left', \
|
399
|
+
last_col_align='left',other_col_align='right', \
|
400
|
+
titile_font_size='16px',heading_font_size='15px', \
|
401
|
+
data_font_size='15px')
|
342
402
|
|
343
403
|
return df3
|
344
404
|
|
@@ -349,6 +409,14 @@ if __name__=='__main__':
|
|
349
409
|
|
350
410
|
num=10
|
351
411
|
|
412
|
+
def sector_detail_sina(sector="new_dlhy",indicator="涨跌幅",rank=5):
|
413
|
+
"""
|
414
|
+
功能:套壳sector_detail_china
|
415
|
+
"""
|
416
|
+
df=sector_detail_china(sector=sector,comp=indicator,num=rank)
|
417
|
+
return df
|
418
|
+
|
419
|
+
|
352
420
|
def sector_detail_china(sector="new_dlhy",comp="涨跌幅",num=10):
|
353
421
|
"""
|
354
422
|
功能:按照板块内部股票的比较指标降序排列
|
@@ -458,6 +526,11 @@ def sector_detail_china(sector="new_dlhy",comp="涨跌幅",num=10):
|
|
458
526
|
pd.set_option('display.unicode.east_asian_width', True)
|
459
527
|
|
460
528
|
df3.index=df3.index + 1
|
529
|
+
|
530
|
+
df3_collist=list(df3)
|
531
|
+
df3['序号']=df3.index
|
532
|
+
df3=df3[['序号']+df3_collist]
|
533
|
+
"""
|
461
534
|
print("\n=== 中国股票市场:"+sector_name+"板块,成份股排行榜(按照"+comp+") ===\n")
|
462
535
|
if num > 0:
|
463
536
|
print(df3.head(num))
|
@@ -469,7 +542,29 @@ def sector_detail_china(sector="new_dlhy",comp="涨跌幅",num=10):
|
|
469
542
|
footnote1="\n 注:市值的单位是亿元人民币, "
|
470
543
|
print(footnote1+"板块内成份股个数:",len(df))
|
471
544
|
print(" 数据来源:新浪财经,",today,"\b(信息为上个交易日)")
|
472
|
-
|
545
|
+
"""
|
546
|
+
if num > 0:
|
547
|
+
df4=df3.head(num)
|
548
|
+
else:
|
549
|
+
df4=df3.tail(-num)
|
550
|
+
|
551
|
+
titletxt="中国股票市场:"+sector_name+"板块,成份股排行榜(基于"+comp+")"
|
552
|
+
|
553
|
+
import datetime; stoday = datetime.date.today()
|
554
|
+
if "流通市值" in df3_collist:
|
555
|
+
footnote1="市值单位:亿元,板块成份股:"+str(len(df))+'\n'
|
556
|
+
footnote2="数据来源:新浪财经,"+str(stoday)+"(截至昨日)"
|
557
|
+
else:
|
558
|
+
footnote1="板块成份股:"+str(len(df))+','
|
559
|
+
footnote2="数据来源:新浪财经,"+str(stoday)+"(截至昨日)"
|
560
|
+
footnote=footnote1+footnote2
|
561
|
+
|
562
|
+
df_display_CSS(df4,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=2, \
|
563
|
+
first_col_align='center',second_col_align='left', \
|
564
|
+
last_col_align='right',other_col_align='right', \
|
565
|
+
titile_font_size='16px',heading_font_size='15px', \
|
566
|
+
data_font_size='15px')
|
567
|
+
|
473
568
|
return df2
|
474
569
|
|
475
570
|
#==============================================================================
|
@@ -481,6 +576,13 @@ if __name__=='__main__':
|
|
481
576
|
sector="yysw"
|
482
577
|
sector="xyz"
|
483
578
|
|
579
|
+
def sector_position_sina(ticker,sector="new_dlhy"):
|
580
|
+
"""
|
581
|
+
功能:套壳sector_position_china
|
582
|
+
"""
|
583
|
+
df=sector_position_china(ticker=ticker,sector=sector)
|
584
|
+
return df
|
585
|
+
|
484
586
|
def sector_position_china(ticker,sector="new_dlhy"):
|
485
587
|
"""
|
486
588
|
功能:查找一只股票在板块内的百分数位置
|
@@ -547,7 +649,10 @@ def sector_position_china(ticker,sector="new_dlhy"):
|
|
547
649
|
#确定比较范围
|
548
650
|
complist=['changepercent','turnoverratio','settlement','per','pb','nmc','mktcap']
|
549
651
|
compnames=['涨跌幅%','换手率%','收盘价(元)','市盈率','市净率','流通市值(亿元)','总市值(亿元)']
|
550
|
-
compdf=pd.DataFrame(columns=['指标名称','指标数值','
|
652
|
+
compdf=pd.DataFrame(columns=['指标名称','指标数值','板块分位数%','板块中位数','板块最小值','板块最大值'])
|
653
|
+
|
654
|
+
from scipy.stats import percentileofscore
|
655
|
+
|
551
656
|
for c in complist:
|
552
657
|
v=list(sdf[c])[0]
|
553
658
|
vlist=list(set(list(df[c])))
|
@@ -557,10 +662,11 @@ def sector_position_china(ticker,sector="new_dlhy"):
|
|
557
662
|
vmedian=round(np.median(vlist),2)
|
558
663
|
|
559
664
|
pos=vlist.index(v)
|
560
|
-
pct=round((pos+1)/len(vlist)*100,2)
|
665
|
+
#pct=round((pos+1)/len(vlist)*100,2)
|
666
|
+
pct=percentileofscore(vlist,v)
|
561
667
|
|
562
668
|
s=pd.Series({'指标名称':compnames[complist.index(c)], \
|
563
|
-
'指标数值':v,'
|
669
|
+
'指标数值':v,'板块分位数%':pct,'板块中位数':vmedian, \
|
564
670
|
'板块最小值':vmin,'板块最大值':vmax})
|
565
671
|
try:
|
566
672
|
compdf=compdf.append(s,ignore_index=True)
|
@@ -568,7 +674,7 @@ def sector_position_china(ticker,sector="new_dlhy"):
|
|
568
674
|
compdf=compdf._append(s,ignore_index=True)
|
569
675
|
|
570
676
|
compdf.reset_index(drop=True,inplace=True)
|
571
|
-
|
677
|
+
"""
|
572
678
|
print("\n======= 股票在所属行业/板块的位置分析 =======")
|
573
679
|
print("股票: "+sname+" ("+ticker+")")
|
574
680
|
print("所属行业/板块:"+sector_name+" ("+sector+", "+indicator+"分类)")
|
@@ -586,7 +692,23 @@ def sector_position_china(ticker,sector="new_dlhy"):
|
|
586
692
|
today = datetime.date.today()
|
587
693
|
print('') #空一行
|
588
694
|
print("注:板块内成份股个数:",len(df),"\b, 数据来源:新浪财经,",today,"\b(信息为上个交易日)")
|
589
|
-
|
695
|
+
"""
|
696
|
+
if indicator=="行业": indicator="证监会行业"
|
697
|
+
|
698
|
+
titletxt="上市公司地位分析:"+sname+","+sector_name+"行业/板块("+indicator+"分类)"
|
699
|
+
import datetime; stoday = datetime.date.today()
|
700
|
+
footnote1=""
|
701
|
+
footnote2="成分股总数:"+str(len(df))+",数据来源:新浪财经,"+str(stoday)+"(截至昨日)"
|
702
|
+
footnote=footnote1+footnote2
|
703
|
+
|
704
|
+
print("") #空一行
|
705
|
+
df_display_CSS(compdf,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=2, \
|
706
|
+
first_col_align='left',second_col_align='right', \
|
707
|
+
last_col_align='right',other_col_align='right', \
|
708
|
+
titile_font_size='16px',heading_font_size='15px', \
|
709
|
+
data_font_size='15px')
|
710
|
+
|
711
|
+
|
590
712
|
return df,compdf
|
591
713
|
|
592
714
|
|
@@ -3564,7 +3686,11 @@ def stock_peers_sw(ticker):
|
|
3564
3686
|
try:
|
3565
3687
|
print_industry_component_sw(iname=hangye)
|
3566
3688
|
except:
|
3567
|
-
print("
|
3689
|
+
print("\n #Warning(stock_peers_sw): failed to search peers for",ticker)
|
3690
|
+
print(" Possible solutions:")
|
3691
|
+
print(" 1. If siat is outdated, uninstall and then reinstall")
|
3692
|
+
print(" 2. Try upgrade pandas and akshare if outdated")
|
3693
|
+
print(" 3. If anaconda is outdated, uninstall and install a newer one")
|
3568
3694
|
|
3569
3695
|
return
|
3570
3696
|
|
siat/translate.py
CHANGED
@@ -3266,6 +3266,10 @@ def ticker1_name(ticker,ticker_type='auto'):
|
|
3266
3266
|
"""
|
3267
3267
|
功能:翻译单个证券名称:股票,基金,债券,投资组合
|
3268
3268
|
"""
|
3269
|
+
DEBUG=False
|
3270
|
+
if DEBUG:
|
3271
|
+
print("DEBUG: ticker=",ticker)
|
3272
|
+
|
3269
3273
|
#投资组合
|
3270
3274
|
if isinstance(ticker,dict):
|
3271
3275
|
return portfolio_name(ticker)
|
@@ -3282,7 +3286,11 @@ def ticker1_name(ticker,ticker_type='auto'):
|
|
3282
3286
|
return tname
|
3283
3287
|
"""
|
3284
3288
|
tname=codetranslate(ticker)
|
3285
|
-
if tname != ticker: #翻译成功,注意证券代码与其名称相同的情形,例如IBM
|
3289
|
+
if tname != ticker or ticker in ["IBM"]: #翻译成功,注意证券代码与其名称相同的情形,例如IBM
|
3290
|
+
return tname
|
3291
|
+
|
3292
|
+
tname=ectranslate(ticker)
|
3293
|
+
if tname != ticker:
|
3286
3294
|
return tname
|
3287
3295
|
|
3288
3296
|
symbol=ticker1_cvt2yahoo(ticker)
|
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright 2024 WANG Dehong
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software (siat) and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -1,12 +1,13 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: siat
|
3
|
-
Version: 3.4.
|
3
|
+
Version: 3.4.32
|
4
4
|
Summary: Securities Investment Analysis Tools (siat)
|
5
5
|
Home-page: https://pypi.org/project/siat/
|
6
6
|
Author: Prof. WANG Dehong, International Business School, Beijing Foreign Studies University
|
7
7
|
Author-email: wdehong2000@163.com
|
8
8
|
License: Copyright (C) WANG Dehong, 2024. For educational purpose only!
|
9
9
|
Description-Content-Type: text/markdown
|
10
|
+
License-File: LICENSE
|
10
11
|
Requires-Dist: pandas-datareader
|
11
12
|
Requires-Dist: yfinance
|
12
13
|
Requires-Dist: tqdm
|
@@ -35,18 +36,18 @@ Requires-Dist: itables
|
|
35
36
|
Requires-Dist: py-trans
|
36
37
|
Requires-Dist: bottleneck
|
37
38
|
|
38
|
-
<center><font size=6>Welcome to SIAT
|
39
39
|
|
40
40
|
# What is siat?
|
41
|
-
siat is a Python plug-in for security investment analysis,
|
41
|
+
siat is a Python 3 plug-in for security investment analysis, primarily designed for teaching and learning purposes in universities for undergraduate and postgraduate programs.
|
42
42
|
|
43
|
-
|
44
|
-
# Version
|
43
|
+
siat is recommended to run in Jupyter Notebook or Jupyter Lab, and most of its results are in the forms of figures and/or tables.
|
44
|
+
# Version naming
|
45
45
|
Version structure: X.Y.Z
|
46
46
|
|
47
47
|
X is the major version for architecture upgrade only.
|
48
|
-
Y is the functional version for functional
|
48
|
+
Y is the functional version for functional enhancements.
|
49
49
|
Z is the minor version just for bug fixing.
|
50
|
+
|
50
51
|
# Quick examples of using siat
|
51
52
|
|
52
53
|
|
@@ -68,7 +69,7 @@ set_language("English")
|
|
68
69
|
# Simple way: show Apple's stock price in recent month
|
69
70
|
apple=security_trend("AAPL")
|
70
71
|
```
|
71
|
-
You may expect
|
72
|
+
You may expect more information, such as price trend in a recent year (MRY), with the high/low point, current price and average price, like below:
|
72
73
|
|
73
74
|
```python
|
74
75
|
apple=security_trend("AAPL", start="MRY",
|
@@ -85,7 +86,7 @@ Since there is a major stock split for NVidia in 2024 by 1:10, it is necessary t
|
|
85
86
|
comp=security_trend(['AAPL','MSFT','NVDA'],
|
86
87
|
start='MRQ',
|
87
88
|
indicator='Adj Close',
|
88
|
-
preprocess='scaling',
|
89
|
+
preprocess='scaling', #use scaling drawing method to avoid loss of details
|
89
90
|
mark_top=True, mark_bottom=True,
|
90
91
|
annotate=True, annotate_value=True)
|
91
92
|
```
|
@@ -94,8 +95,7 @@ comp=security_trend(['AAPL','MSFT','NVDA'],
|
|
94
95
|
|
95
96
|
|
96
97
|
```python
|
97
|
-
#
|
98
|
-
|
98
|
+
# security_technical only supports 4 popular technical indicators: MACD, Bollinger, KDJ and RSI.
|
99
99
|
apple=security_technical("AAPL",
|
100
100
|
technical="Bollinger",
|
101
101
|
start="MRQ",
|
@@ -107,15 +107,15 @@ apple=security_technical("AAPL",
|
|
107
107
|
|
108
108
|
|
109
109
|
```python
|
110
|
-
#
|
111
|
-
|
110
|
+
# security_technical2 supports up to 14 popular technical indicators.
|
111
|
+
# security_technical2 uses a simplied drawing method (Dehong graph) to avoid trypophobia [藢tr瑟p蓹u'f蓹蕣bj蓹]
|
112
112
|
apple=security_technical2("AAPL",
|
113
113
|
technical="CCI",
|
114
114
|
start="MRM",
|
115
115
|
loc1="upper left", loc2="lower right")
|
116
116
|
```
|
117
117
|
|
118
|
-
# What security
|
118
|
+
# What security products does siat support?
|
119
119
|
1. Public company profile: world-wide
|
120
120
|
2. Stock & stock market index: world-wide
|
121
121
|
3. Stock valuation: primarily in China (mainland and HK) and the U.S.
|
@@ -131,13 +131,13 @@ apple=security_technical2("AAPL",
|
|
131
131
|
13. Cash flow statement: in China mainland (full function) and world-wide (basic function)
|
132
132
|
14. DuPont Identity: world-wide
|
133
133
|
15. Sector trend and valuation: primarily in China
|
134
|
-
# What analytical
|
134
|
+
# What analytical methods does siat support?
|
135
135
|
1. Trend analysis
|
136
136
|
2. Panel comparation
|
137
137
|
3. Return analysis: rolling returns, holding period returns
|
138
138
|
4. Risk analysis: rolling volatility, holding period volatility, LPSD
|
139
139
|
5. Technical analysis: more than 15 indicators
|
140
|
-
6. Risk-adjusted return:
|
140
|
+
6. Risk-adjusted return: Sharpe ratio, Sortino ratio, Treynor ratio, Jensen alpha
|
141
141
|
7. Portfolio optimization: four risk-adjusted returns
|
142
142
|
8. CAPM beta trend
|
143
143
|
9. Beta adjustments: simple adjustment, Scholes-Williams, Dimson
|
@@ -163,11 +163,15 @@ The main data sources siat uses:
|
|
163
163
|
7. IMF
|
164
164
|
8. Shanghai Stock Exchange
|
165
165
|
9. Shenzhen Stock Exchange
|
166
|
-
10.
|
167
|
-
11.
|
168
|
-
12.
|
169
|
-
|
170
|
-
|
166
|
+
10. Hong Kong Stock Exchange
|
167
|
+
11. Beijing Stock Exchange
|
168
|
+
12. Tokyo Stock Exchange
|
169
|
+
13. London Stock Exchange
|
170
|
+
14. New York Stock Exchange
|
171
|
+
15. NASDAQ
|
172
|
+
16. Sustainalytics
|
173
|
+
|
174
|
+
Thanks the above websites for their valuable data!
|
171
175
|
# How to install siat?
|
172
176
|
The author strongly recommends using siat together with Jupyter Notebook or Jupyter Lab in Anaconda.
|
173
177
|
In order to install siat for the very first time, open a Jupyter Notebook, and type in the following command:
|
@@ -202,7 +206,7 @@ pip install --upgrade siat https://mirrors.aliyun.com/pypi/simple/
|
|
202
206
|
*** Warning
|
203
207
|
1. The pip command itself may need upgrade as well.
|
204
208
|
2. The pip command sometimes may have conflicts with some vpn programs.
|
205
|
-
If in this case, try quit vpn program, and try again.
|
209
|
+
If in this case, try quit vpn program first, and try again.
|
206
210
|
# Are there more detailed case studies on using siat?
|
207
211
|
YES!
|
208
212
|
|
@@ -18,7 +18,7 @@ siat/capm_beta.py,sha256=cxXdRVBQBllhbfz1LeTJAIWvyRYhW54nhtNUXv4HwS0,29063
|
|
18
18
|
siat/capm_beta2.py,sha256=lUuCPVSxebkA2yye1PXu1V2Jd2UKEwD_kIA25DCIDTs,29750
|
19
19
|
siat/capm_beta_test.py,sha256=ImR0c5mc4hIl714XmHztdl7qg8v1E2lycKyiqnFj6qs,1745
|
20
20
|
siat/cmat_commons.py,sha256=Nj9Kf0alywaztVoMVeVVL_EZk5jRERJy8R8kBw88_Tg,38116
|
21
|
-
siat/common.py,sha256=
|
21
|
+
siat/common.py,sha256=O9-IYeP7z1KHO2YFr-auc_HzBf78nPb-1LY3byb5Avo,151723
|
22
22
|
siat/compare_cross.py,sha256=3iP9TH2h3w27F2ARZc7FjKcErYCzWRc-TPiymOyoVtw,24171
|
23
23
|
siat/compare_cross_test.py,sha256=xra5XYmQGEtfIZL2h-GssdH2hLdFIhG3eoCrkDrL3gY,3473
|
24
24
|
siat/concepts_iwencai.py,sha256=m1YEDtECRT6FqtzlKm91pt2I9d3Z_XoP59BtWdRdu8I,3061
|
@@ -28,7 +28,7 @@ siat/cryptocurrency.py,sha256=IjQTzqTkdp19aS0PrD15nU3-tfCJHyzt0oBd5nWvwk8,27449
|
|
28
28
|
siat/cryptocurrency_test.py,sha256=3AikTNJ7j-HwLGLIYEfyXZ3bLVuLeru9mwiwHQi2SdA,2669
|
29
29
|
siat/derivative.py,sha256=qV8n09799eqLc26ojR6vN5n_X-xd7rGwdYjgq-wBih8,41483
|
30
30
|
siat/economy-20230125.py,sha256=vxZZlPnLkh7SpGMVEPLwxjt0yYLSVmdZrO-s2NYLyoM,73848
|
31
|
-
siat/economy.py,sha256=
|
31
|
+
siat/economy.py,sha256=ijMAVA5ydghbQDgNDDdz8fz9NPd2eq90RzpJSRGWz5c,78638
|
32
32
|
siat/economy_test.py,sha256=6vjNlPz7W125pJb7simCddobSEp3jmLIMvVkLRZ7zW8,13339
|
33
33
|
siat/esg.py,sha256=GMhaonIKtvOK83rhpQUH5aJt2OL3HQBSVfD__Yw-0oo,19040
|
34
34
|
siat/esg_test.py,sha256=Z9m6GUt8O7oHZSEG9aDYpGdvvrv2AiRJdHTiU6jqmZ0,2944
|
@@ -60,7 +60,7 @@ siat/future_china.py,sha256=F-HsIf2Op8Z22RzTjet1g8COzldgnMjFNSXsAkeGyWo,17595
|
|
60
60
|
siat/future_china_test.py,sha256=BrSzmDVaOHki6rntOtosmRn-6dkfOBuLulJNqh7MOpc,1163
|
61
61
|
siat/global_index_test.py,sha256=hnFp3wqqzzL-kAP8mgxDZ54Bd5Ijf6ENi5YJlGBgcXw,2402
|
62
62
|
siat/google_authenticator.py,sha256=ZUbZR8OW0IAKDbcYtlqGqIpZdERpFor9NccFELxg9yI,1637
|
63
|
-
siat/grafix.py,sha256=
|
63
|
+
siat/grafix.py,sha256=HwtDRINvpfiWcrXsR5h6Ghvspitww5xRvP2eS4UfDFw,87465
|
64
64
|
siat/grafix_test.py,sha256=kXvcpLgQNO7wd30g_bWljLj5UH7bIVI0_dUtXbfiKR0,3150
|
65
65
|
siat/holding_risk.py,sha256=G3wpaewAKF9CwEqRpr4khyuDu9SU2EGyQUHdk7cmHOA,30693
|
66
66
|
siat/holding_risk_test.py,sha256=FRlw_9wFG98BYcg_cSj95HX5WZ1TvkGaOUdXD7-V86s,474
|
@@ -94,7 +94,7 @@ siat/risk_evaluation.py,sha256=I6B3gty-t--AkDCO0tKF-291YfpnF-IkXcFjqNKCt9I,76286
|
|
94
94
|
siat/risk_evaluation_test.py,sha256=YEXM96gKzTfwN4U61AS4Rr1tV7KgUvn4rRC6f3iMw9s,3731
|
95
95
|
siat/risk_free_rate.py,sha256=ZMr4cHikPvXvywr54gGqiI3Nvb69am6tq3zj2hwzANE,12384
|
96
96
|
siat/risk_free_rate_test.py,sha256=CpmhUf8aEAEZeNu4gvWP2Mz2dLoIgBX5bI41vfUBEr8,4285
|
97
|
-
siat/sector_china.py,sha256=
|
97
|
+
siat/sector_china.py,sha256=A2252BymgpV1LEdZ4DU6SJue7ZMrW4GU8fBfhuqp09w,137485
|
98
98
|
siat/sector_china_test.py,sha256=1wq7ef8Bb_L8F0h0W6FvyBrIcBTEbrTV7hljtpj49U4,5843
|
99
99
|
siat/security_price.py,sha256=2oHskgiw41KMGfqtnA0i2YjNNV6cYgtlUK0j3YeuXWs,29185
|
100
100
|
siat/security_price2.py,sha256=Y4suVC-4koUSI_n8kY0l0y4lo_CTcoeM_kwTHiIFzyM,26291
|
@@ -131,7 +131,7 @@ siat/transaction_test.py,sha256=Z8g1LJCN4-mnUByXMUMoFmN0t105cbmsz2QmvSuIkbU,1858
|
|
131
131
|
siat/translate-20230125.py,sha256=NPPSXhT38s5t9fzMvl_fvi4ckSB73ThLmZetVI-xGdU,117953
|
132
132
|
siat/translate-20230206.py,sha256=-vtI125WyaJhmPotOpDAmclt_XnYVaWU9ByLWZ6FyYE,118133
|
133
133
|
siat/translate-20230215.py,sha256=TJgtPE3n8IjljmZ4Pefy8dmHoNdFF-1zpML6BhA9FKE,121657
|
134
|
-
siat/translate.py,sha256=
|
134
|
+
siat/translate.py,sha256=un7Fqe1v35MXsja5exZgjmLzrZtt66NARZIGlyFuGGU,218747
|
135
135
|
siat/translate_20240606.py,sha256=63IyHWEU3Uz9mjwyuAX3fqY4nUMdwh0ICQAgmgPXP7Y,215121
|
136
136
|
siat/universal_test.py,sha256=CDAOffW1Rvs-TcNN5giWVvHMlch1w4dp-w5SIV9jXL0,3936
|
137
137
|
siat/valuation.py,sha256=NKfeZMdDJOW42oLVHob6eSVBXUqlN1OCnnzwyGAst8c,48855
|
@@ -139,7 +139,8 @@ siat/valuation_china.py,sha256=EkZQaVkoBjM0c4MCNbaX-bMnlG0e3FXeaWczZDnkptU,67784
|
|
139
139
|
siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
|
140
140
|
siat/var_model_validation.py,sha256=R0caWnuZarrRg9939hxh3vJIIpIyPfvelYmzFNZtPbo,14910
|
141
141
|
siat/yf_name.py,sha256=9U_XfEeMlS3TrCrO3Bww21nuFgghbnO-cqDJMhQWqew,16193
|
142
|
-
siat-3.4.
|
143
|
-
siat-3.4.
|
144
|
-
siat-3.4.
|
145
|
-
siat-3.4.
|
142
|
+
siat-3.4.32.dist-info/LICENSE,sha256=NTEMMROY9_4U1szoKC3N2BLHcDd_o5uTgqdVH8tbApw,1071
|
143
|
+
siat-3.4.32.dist-info/METADATA,sha256=-WEvTLN8wDtXLa77mhBGt9tMIXvoxwAfku48zsdom0s,8010
|
144
|
+
siat-3.4.32.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
145
|
+
siat-3.4.32.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
|
146
|
+
siat-3.4.32.dist-info/RECORD,,
|
File without changes
|
File without changes
|