siat 2.13.23__py3-none-any.whl → 2.13.40__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 CHANGED
@@ -263,6 +263,26 @@ if __name__ =="__main__":
263
263
  start='2020-1-1'; end='2022-12-20'
264
264
  result,startpd,endpd=check_period(start,end)
265
265
 
266
+ #==============================================================================
267
+ if __name__ =="__main__":
268
+ start_date = "2022-1-1"
269
+ end_date = "2022-1-31"
270
+ result = calculate_days(start_date, end_date)
271
+ print("日期间隔天数为:", result)
272
+
273
+ def calculate_days(start_date, end_date):
274
+
275
+ _,start_date1=check_date2(start_date)
276
+ _,end_date1=check_date2(end_date)
277
+
278
+ from datetime import date
279
+ start = date.fromisoformat(start_date1)
280
+ end = date.fromisoformat(end_date1)
281
+
282
+ delta = (end - start).days + 1
283
+ return delta
284
+
285
+
266
286
  #==============================================================================
267
287
  def date_adjust(basedate, adjust=0):
268
288
  """
@@ -2360,5 +2380,174 @@ def fix_package(file='stooq.py',package='pandas_datareader'):
2360
2380
 
2361
2381
  #==============================================================================
2362
2382
  #==============================================================================
2383
+
2384
+ def df_preprocess(dfs,measure,axhline_label,x_label,y_label,lang='Chinese', \
2385
+ preprocess='scaling',scaling_option='start'):
2386
+ """
2387
+ 功能:对于dfs中的数据进行预处理变换,以便克服数量级压制现象更好地展现多条曲线的趋势
2388
+ """
2389
+ plus_sign=False
2390
+
2391
+ preprocess1=preprocess.lower()
2392
+ #预处理方法:标准化,正态化,对数,缩放
2393
+ preplist=['standardize','normalize','logarithm','scaling']
2394
+ if preprocess1 in preplist:
2395
+ dfs2=dfs.copy(deep=True)
2396
+
2397
+ collist=list(dfs2)
2398
+ meanlist=[]
2399
+ for c in collist:
2400
+
2401
+ # 去掉缺失值
2402
+ #dfs2[c].dropna(inplace=True)
2403
+
2404
+ if preprocess1 == 'standardize': #标准化
2405
+ cmean=dfs2[c].mean()
2406
+ cstd=dfs2[c].std()
2407
+ dfs2[c]=dfs2[c].apply(lambda x: (x-cmean)/cstd)
2408
+
2409
+ if preprocess1 == 'normalize': #正态化
2410
+ cmax=dfs2[c].max()
2411
+ cmin=dfs2[c].min()
2412
+ dfs2[c]=dfs2[c].apply(lambda x: (x-cmin)/(cmax-cmin))
2413
+
2414
+ if preprocess1 == 'logarithm': #取对数
2415
+ import numpy as np
2416
+ dfs2[c]=dfs2[c].apply(lambda x: np.log(x) if x>0 else (0 if x==0 else -np.log(-x)))
2417
+
2418
+ if preprocess1 == 'scaling': #缩放
2419
+ #缩放选项:均值,最小值,起点值,相对起点值的百分数(起点值为100),
2420
+ #相对起点值变化的百分数(起点值为0)
2421
+ scalinglist=['mean','min','start','percentage','change%']
2422
+ if not (scaling_option in scalinglist):
2423
+ print(" #Error(compare_msecurity): invalid scaling option",scaling_option)
2424
+ print(" Valid scaling option:",scalinglist)
2425
+ return None
2426
+ if scaling_option == 'mean':
2427
+ cmean=dfs2[c].mean() #使用均值
2428
+ if lang == 'English':
2429
+ scalingOptionText='mean value'
2430
+ else:
2431
+ scalingOptionText='均值'
2432
+ if scaling_option == 'min':
2433
+ cmean=dfs2[c].min() #使用最小值
2434
+ if lang == 'English':
2435
+ scalingOptionText='min value'
2436
+ else:
2437
+ scalingOptionText='最小值'
2438
+ #if scaling_option == 'start':
2439
+ if scaling_option in ['start','percentage','change%']:
2440
+ # 从头寻找第一个非空数值
2441
+ import numpy as np
2442
+ for n in range(0,len(dfs2)):
2443
+ if np.isnan(dfs2[c][n]):
2444
+ continue
2445
+ else:
2446
+ cmean=dfs2[c][n] #使用第一个非空值
2447
+ break
2448
+
2449
+ if lang == 'English':
2450
+ scalingOptionText='starting value'
2451
+ else:
2452
+ scalingOptionText='起点值'
2453
+
2454
+ meanlist=meanlist+[cmean]
2455
+
2456
+ #print(cmean,cstd,dfs2[c])
2457
+
2458
+ if (preprocess1 == 'scaling') and ('Exp Ret' not in measure):
2459
+ # 加上后一个条件是为了防止出现division by zero错误
2460
+ if len(meanlist)==0:
2461
+ return None
2462
+
2463
+ if scaling_option not in ['percentage','change%']:
2464
+ meanlistmin=min(meanlist)
2465
+ meanlist2= [x / meanlistmin for x in meanlist]
2466
+
2467
+ for c in collist:
2468
+ pos=collist.index(c)
2469
+ cfactor=meanlist2[pos]
2470
+ #dfs2[c]=dfs2[c].apply(lambda x: x/cfactor)
2471
+ dfs2[c]=dfs2[c].apply(lambda x: x/abs(cfactor))
2472
+ elif scaling_option == 'percentage': #相对起点值的百分数(起点值为100)
2473
+ for c in collist:
2474
+ pos=collist.index(c)
2475
+ cfactor=meanlist[pos]
2476
+ #dfs2[c]=dfs2[c].apply(lambda x: round(x/cfactor*100,2))
2477
+ #dfs2[c]=dfs2[c].apply(lambda x: round(x/abs(cfactor)*100,4))
2478
+ dfs2[c]=dfs2[c].apply(lambda x: x/abs(cfactor)*100)
2479
+ elif scaling_option == 'change%': #相对起点值变化的百分数(起点值为0)
2480
+ plus_sign=True
2481
+ for c in collist:
2482
+ pos=collist.index(c)
2483
+ cfactor=meanlist[pos]
2484
+ #dfs2[c]=dfs2[c].apply(lambda x: round((x/cfactor-1)*100,4))
2485
+ dfs2[c]=dfs2[c].apply(lambda x: (x/cfactor-1)*100)
2486
+
2487
+ #设置中英文的脚注和纵轴标记
2488
+ if lang == 'English':
2489
+ if preprocess1 == 'standardize':
2490
+ std_notes="Note: for ease of comparison, data are standardized "
2491
+ measure_suffix='(standardized)'
2492
+ if preprocess1 == 'normalize':
2493
+ std_notes="Note: for ease of comparison, data are normalized"
2494
+ measure_suffix='(normalized)'
2495
+ if preprocess1 == 'logarithm':
2496
+ std_notes="Note: for ease of comparison, data are logarithmed"
2497
+ measure_suffix='(logarithmed)'
2498
+ if preprocess1 == 'scaling':
2499
+ if scaling_option == 'mean':
2500
+ std_notes="Note: for ease of comparison, data are scaled by mean value"
2501
+ measure_suffix='(scaling by mean)'
2502
+ elif scaling_option == 'min':
2503
+ std_notes="Note: for ease of comparison, data are scaled by min value"
2504
+ measure_suffix='(scaling by min)'
2505
+ elif scaling_option == 'start':
2506
+ std_notes="Note: for ease of comparison, data are scaled by starting value"
2507
+ measure_suffix='(scaling by start)'
2508
+ elif scaling_option == 'percentage':
2509
+ std_notes="Note: for ease of comparison, data are in percentage of starting value"
2510
+ measure_suffix='(in prcentage%)'
2511
+ elif scaling_option == 'change%':
2512
+ std_notes="Note: for ease of comparison, data are in change % of starting value"
2513
+ measure_suffix='(change %)'
2514
+ else:
2515
+ if preprocess1 == 'standardize':
2516
+ std_notes="注意:为突出变化趋势,对数据进行了标准化处理"
2517
+ measure_suffix='(标准化处理后)'
2518
+ if preprocess1 == 'normalize':
2519
+ std_notes="注意:为突出变化趋势,对数据进行了归一化处理"
2520
+ measure_suffix='(归一化处理后)'
2521
+ if preprocess1 == 'logarithm':
2522
+ std_notes="注意:为突出变化趋势,对数据进行了对数处理"
2523
+ measure_suffix='(对数处理后)'
2524
+ if preprocess1 == 'scaling':
2525
+ if scaling_option == 'mean':
2526
+ std_notes="注意:为突出变化趋势,按均值对原始数据进行了比例缩放"
2527
+ measure_suffix='(按均值比例缩放后,非原值)'
2528
+ elif scaling_option == 'min':
2529
+ std_notes="注意:为突出变化趋势,按最小值对原始数据进行了比例缩放"
2530
+ measure_suffix='(按最小值比例缩放后,非原值)'
2531
+ elif scaling_option == 'start':
2532
+ std_notes="注意:为突出变化趋势,按起点值对原始数据进行了比例缩放"
2533
+ measure_suffix='(按起点值比例缩放后,非原值)'
2534
+ elif scaling_option == 'percentage':
2535
+ std_notes="注释:为突出变化趋势,期间起点数值=100%,其他数值为相对百分比"
2536
+ measure_suffix='(相对百分数%)'
2537
+ elif scaling_option == 'change%':
2538
+ std_notes="注释:为突出变化趋势,图中数值为相对期间起点的增减百分比"
2539
+ measure_suffix='(增/减%)'
2540
+ axhline_label='零线' #可以在security_trend中使用critical_value选项指定水平线位置,默认0
2541
+ #axhline_value=0
2542
+
2543
+ if 'Exp Ret' not in measure:
2544
+ x_label=std_notes+'\n'+x_label
2545
+ y_label=y_label+measure_suffix
2546
+
2547
+ else:
2548
+ dfs2=dfs
2549
+
2550
+ #返回内容
2551
+ return dfs2,axhline_label,x_label,y_label,plus_sign
2363
2552
  #==============================================================================
2364
2553
 
siat/grafix.py CHANGED
@@ -1087,7 +1087,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1087
1087
  xy=(x_end, y_end),
1088
1088
  xytext=(x_end, y_end),fontsize=9)
1089
1089
  """
1090
- if annotate_value:
1090
+ if annotate_value: #在标记曲线名称的同时标记其末端数值
1091
1091
  plt.annotate(text=c+':'+str(round(y_end,2)),
1092
1092
  xy=(x_end, y_end),
1093
1093
  xytext=(x_end, y_end),fontsize=9)
@@ -1147,7 +1147,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1147
1147
  data_label=False,resample_freq='6H',smooth=True, \
1148
1148
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
1149
1149
  colorlist=[],lslist=[],lwlist=[], \
1150
- band_area='',loc='best'):
1150
+ band_area='',loc='best',annotate=False,annotate_value=False):
1151
1151
  """
1152
1152
  函数功能:根据df的内容绘制折线图
1153
1153
  输入参数:
@@ -1219,6 +1219,22 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1219
1219
  plt.text(a,b+0.02,str(round(b,2)), \
1220
1220
  ha='center',va='bottom',fontsize=7)
1221
1221
 
1222
+ #曲线末端标记
1223
+ if annotate:
1224
+ df_end=df.tail(1)
1225
+ y_end = df_end[c].min() # 末端的y坐标
1226
+ x_end = df_end[c].idxmin() # 末端值的x坐标
1227
+
1228
+ if annotate_value: #在标记曲线名称的同时标记其末端数值
1229
+ plt.annotate(text=c+':'+str(round(y_end,2)),
1230
+ xy=(x_end, y_end),
1231
+ xytext=(x_end, y_end),fontsize=9)
1232
+ else:
1233
+ plt.annotate(text=c,
1234
+ xy=(x_end, y_end),
1235
+ xytext=(x_end, y_end),fontsize=ylabel_txt_size)
1236
+
1237
+
1222
1238
  #绘制带状区域
1223
1239
  if band_area != '' and isinstance(band_area,list) and len(band_area)>=2:
1224
1240
  plt.fill_between(df.index,df[band_area[0]],df[band_area[1]],alpha=0.5,label='')
@@ -1238,7 +1254,9 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1238
1254
  plt.title(title_txt,fontweight='bold',fontsize=title_txt_size)
1239
1255
  plt.gcf().autofmt_xdate() # 优化标注(自动倾斜)
1240
1256
 
1241
- plt.legend(loc=loc,fontsize=legend_txt_size)
1257
+ if not annotate:
1258
+ plt.legend(loc=loc,fontsize=legend_txt_size)
1259
+
1242
1260
  plt.show()
1243
1261
 
1244
1262
  return
@@ -1432,8 +1432,8 @@ def compare_1security_mrar(ticker,rar_names,start,end, \
1432
1432
 
1433
1433
  import datetime; today = datetime.date.today()
1434
1434
  y_label="风险调整收益指标"
1435
- x_label="数据来源: 新浪/stooq/Yahoo,"+str(today)
1436
- title_txt="比较证券的多种风险调整收益滚动指标:"+codetranslate(tickers[0])
1435
+ x_label="数据来源: 综合新浪/stooq/Yahoo,"+str(today)
1436
+ title_txt="证券风险调整收益滚动指标:"+codetranslate(tickers[0])
1437
1437
 
1438
1438
  # 是否绘图
1439
1439
  if graph:
siat/security_trend.py CHANGED
@@ -136,6 +136,8 @@ def security_trend(ticker,indicator='Close', \
136
136
  fromdate=date_adjust(todate,adjust=-31*37-16)
137
137
  elif start in ['l5y']: # 近五年以来
138
138
  fromdate=date_adjust(todate,adjust=-31*61-16)
139
+ elif start in ['l8y']: # 近八年以来
140
+ fromdate=date_adjust(todate,adjust=-31*97-16)
139
141
  elif start in ['l10y']: # 近十年以来
140
142
  fromdate=date_adjust(todate,adjust=-31*121-16)
141
143
  elif start in ['ytd']: # 今年以来
@@ -223,7 +225,7 @@ def security_trend(ticker,indicator='Close', \
223
225
  ]
224
226
 
225
227
  indicator_list2=['treynor','sharpe','sortino','alpha','Treynor','Sharpe','Sortino','Alpha']
226
- indicator_list3=['pe','pb','mv','PE','PB','MV','Pe','Pb','Mv']
228
+ indicator_list3=['pe','pb','mv','PE','PB','MV','Pe','Pb','Mv','ROE','roe','Roe']
227
229
 
228
230
  # 是否属于支持的指标
229
231
  for m in measures:
@@ -235,7 +237,7 @@ def security_trend(ticker,indicator='Close', \
235
237
  printlist(indicator_list3,numperline=5,beforehand=' ',separator=' ')
236
238
  return None
237
239
 
238
- # 不能同时支持indicator_list1、indicator_list2和indicator_list3的指标
240
+ # 不能同时支持indicator_list1、indicator_list2和indicator_list3的指标,即不能跨组比较
239
241
  indicator_group1=False
240
242
  indicator_group2=False
241
243
  indicator_group3=False
@@ -244,13 +246,19 @@ def security_trend(ticker,indicator='Close', \
244
246
  for m in measures:
245
247
  if m in indicator_list3:
246
248
  list_group3=1
247
- indicator_group3=True
249
+ indicator_group3=True
250
+ measures = [x.upper() for x in measures]
251
+
248
252
  if m in indicator_list2:
249
253
  list_group2=1
250
254
  indicator_group2=True
255
+ measures = [x.lower() for x in measures]
256
+
251
257
  if m in indicator_list1:
252
258
  list_group1=1
253
259
  indicator_group1=True
260
+ measures = [x.title() for x in measures]
261
+ measures = [x.replace('Lpsd','LPSD') if 'Lpsd' in x else x for x in measures]
254
262
 
255
263
  if list_group1+list_group2+list_group3 >= 2:
256
264
  print(" #Error(security_trend): cannot support in different indicator groups together for",measures)
@@ -345,11 +353,13 @@ def security_trend(ticker,indicator='Close', \
345
353
  annotate=annotate)
346
354
  return df
347
355
 
348
- # 情形8:估值指标PE/PB/MV
356
+ # 情形8:估值指标PE/PB/MV/ROE
349
357
  if indicator_group3:
350
358
  df=security_valuation(tickers=tickers,indicators=measures,start=fromdate,end=todate, \
351
- twinx=twinx,loc1=loc1,loc2=loc2, \
352
- graph=graph,annotate=annotate)
359
+ preprocess=preprocess,scaling_option=scaling_option, \
360
+ twinx=twinx,loc1=loc1,loc2=loc2, \
361
+ graph=graph,annotate=annotate,
362
+ )
353
363
  return df
354
364
 
355
365
  # 其他未预料情形
siat/stock.py CHANGED
@@ -792,7 +792,7 @@ def security_mindicators(ticker,measures,fromdate,todate, \
792
792
 
793
793
  y_label='证券指标'
794
794
  import datetime; today = datetime.date.today()
795
- x_label="数据来源:新浪/东方财富/stooq/雅虎财经,"+str(today)
795
+ x_label="数据来源:综合新浪/东方财富/stooq/雅虎财经,"+str(today)
796
796
 
797
797
  axhline_value=0
798
798
  axhline_label=''
@@ -808,7 +808,8 @@ def security_mindicators(ticker,measures,fromdate,todate, \
808
808
  """
809
809
  draw_lines2(df1,y_label,x_label,axhline_value,axhline_label,title_txt, \
810
810
  data_label=False,resample_freq='6H',smooth=smooth, \
811
- date_range=date_range,date_freq=date_freq,date_fmt='%Y-%m-%d')
811
+ date_range=date_range,date_freq=date_freq,date_fmt='%Y-%m-%d', \
812
+ annotate=annotate,annotate_value=False)
812
813
 
813
814
  return df1
814
815
 
@@ -1497,7 +1498,9 @@ def compare_msecurity(tickers,measure,start,end, \
1497
1498
  standardize: 标准化处理,(x - mean(x))/std(x)
1498
1499
  normalize: 归一化处理,(x - min(x))/(max(x) - min(x))
1499
1500
  logarithm: 对数处理,np.log(x)
1500
- scaling:缩放处理,三种选项scaling_option(mean均值,min最小值,start开始值)
1501
+ scaling:缩放处理,五种选项scaling_option
1502
+ (mean均值,min最小值,start开始值,percentage相对每条曲线起点值的百分比,
1503
+ change%相对每条曲线起点值变化的百分比)
1501
1504
  start方式的图形更接近于持有收益率(Exp Ret%),设为默认的缩放方式。
1502
1505
 
1503
1506
  """
@@ -1662,9 +1665,14 @@ def compare_msecurity(tickers,measure,start,end, \
1662
1665
  x_label="数据来源: 综合新浪/东方财富/雅虎财经/stooq/FRED/OECD,"+str(today)
1663
1666
  #title_txt="比较多只证券产品的指标走势"
1664
1667
  #title_txt="趋势分析"
1665
- title_txt="趋势分析:"+y_label
1668
+ title_txt="指标趋势分析:"+y_label
1666
1669
 
1667
1670
  # 标准化处理
1671
+ dfs2,axhline_label,x_label,y_label,plus_sign=df_preprocess(dfs,measure, \
1672
+ axhline_label=axhline_label,x_label=x_label,y_label=y_label,lang=lang, \
1673
+ preprocess=preprocess,scaling_option=scaling_option)
1674
+
1675
+ """
1668
1676
  preprocess1=preprocess.lower()
1669
1677
  preplist=['standardize','normalize','logarithm','scaling']
1670
1678
  if preprocess1 in preplist:
@@ -1818,6 +1826,7 @@ def compare_msecurity(tickers,measure,start,end, \
1818
1826
 
1819
1827
  else:
1820
1828
  dfs2=dfs
1829
+ """
1821
1830
 
1822
1831
  # 填充非交易日的缺失值,使得绘制的曲线连续
1823
1832
  dfs2.fillna(axis=0,method='ffill',inplace=True)
siat/stock_technical.py CHANGED
@@ -1928,9 +1928,9 @@ def security_bollinger(ticker,fromdate,todate,boll_days=20, \
1928
1928
  #==============================================================================
1929
1929
  #==============================================================================
1930
1930
  if __name__ =="__main__":
1931
- ticker='600519.SS'
1932
- start='2023-1-1'
1933
- end='2023-6-25'
1931
+ ticker='600809.SS'
1932
+ start='2013-11-06'
1933
+ end='2024-02-29'
1934
1934
  boll_years=7
1935
1935
  graph=True
1936
1936
  smooth=False
@@ -1938,6 +1938,8 @@ if __name__ =="__main__":
1938
1938
  date_range=False
1939
1939
  date_freq=False
1940
1940
  annotate=False
1941
+
1942
+ indicator='PE'
1941
1943
 
1942
1944
  def security_Bubble(ticker,start='default',end='default',boll_years=7, \
1943
1945
  indicator='MV', \
@@ -1949,14 +1951,14 @@ def security_Bubble(ticker,start='default',end='default',boll_years=7, \
1949
1951
 
1950
1952
  #=========== 日期转换与检查
1951
1953
  # 检查日期:截至日期
1952
- import datetime as dt; today=dt.date.today()
1954
+ import datetime as dt; todaydt=dt.date.today()
1953
1955
  if end in ['default','today']:
1954
- end=today
1956
+ end=todaydt
1955
1957
  else:
1956
1958
  validdate,end=check_date2(end)
1957
1959
  if not validdate:
1958
1960
  print(" #Warning(security_Bubble): invalid date for",end)
1959
- end=today
1961
+ end=todaydt
1960
1962
 
1961
1963
  # 检查日期:开始日期
1962
1964
  if start in ['default']:
@@ -2003,6 +2005,8 @@ def security_bubble(ticker,fromdate,todate,boll_years=7, \
2003
2005
  indicatorname='市盈率'
2004
2006
  elif indicator.lower()=='pb':
2005
2007
  indicatorname='市净率'
2008
+ elif indicator.lower()=='roe':
2009
+ indicatorname='净资产回报率'
2006
2010
  else:
2007
2011
  print(" #Error(security_bubble): unsupported valuation indicator for",indicator)
2008
2012
  return None
@@ -2020,23 +2024,31 @@ def security_bubble(ticker,fromdate,todate,boll_years=7, \
2020
2024
  return None
2021
2025
 
2022
2026
  # 滚动均值与标准差
2023
- #注意:A股估值数据为周频,港股/美股/波兰股为日频
2027
+ #注意:A股估值数据为非日频,港股/美股/波兰股为日频
2028
+ day0=pricedf.index[0].strftime("%Y-%m-%d")
2029
+ day1=pricedf.index[-1].strftime("%Y-%m-%d")
2030
+ day_diff=calculate_days(day0,day1)
2031
+ annualTradeDays=len(pricedf) / (day_diff/365)
2032
+ #boll_days=int(boll_years*annualTradeDays+0.5)
2033
+ boll_days=int(boll_years*annualTradeDays)
2034
+ """
2024
2035
  _,_,suffix=split_prefix_suffix(ticker)
2025
2036
  if suffix in ['SS','SZ','BJ']:
2026
- boll_days=boll_years*52
2037
+ boll_days=int(boll_years*annualTradeDays)
2027
2038
  else:
2028
2039
  boll_days=boll_years*252
2040
+ """
2041
+ if boll_days >= len(pricedf):
2042
+ boll_years=int(len(pricedf)/annualTradeDays)
2043
+ boll_days=int(boll_years*annualTradeDays)
2029
2044
 
2030
- if boll_days >= len(val):
2031
- boll_years=int(len(val)/252)
2032
- boll_days=boll_years*252
2033
-
2034
- record_left=len(val)-boll_days
2045
+ record_left=len(pricedf)-boll_days
2035
2046
 
2036
2047
  if record_left < 65:#一个季度
2037
2048
  boll_years=boll_years-1
2038
- boll_days=boll_years*252
2039
- record_left=len(val)-boll_days
2049
+ #boll_days=boll_years*252
2050
+ boll_days=int(boll_years*annualTradeDays)
2051
+ record_left=len(pricedf)-boll_days
2040
2052
 
2041
2053
  pricedf_left=pricedf.tail(record_left)
2042
2054
  start_left=pricedf_left.index[0].strftime('%Y-%m-%d')
@@ -2060,11 +2072,11 @@ def security_bubble(ticker,fromdate,todate,boll_years=7, \
2060
2072
 
2061
2073
  y_label=indicatorname
2062
2074
  import datetime; today = datetime.date.today()
2063
- x_label="数据来源:新浪/东方财富/stooq/雅虎财经,"+str(today)+",估值前置窗口期"+str(boll_years)+"年"
2075
+ x_label="数据来源:综合新浪/东方财富/stooq/雅虎财经,"+str(today)+",估值前置窗口期"+str(boll_years)+"年"
2064
2076
 
2065
2077
  axhline_value=0
2066
2078
  axhline_label=''
2067
- title_txt="证券估值布林带:"+codetranslate(ticker)
2079
+ title_txt="证券指标布林带:"+codetranslate(ticker)
2068
2080
 
2069
2081
  """
2070
2082
  draw_lines(df1,y_label,x_label,axhline_value,axhline_label,title_txt, \
@@ -2085,7 +2097,9 @@ def security_bubble(ticker,fromdate,todate,boll_years=7, \
2085
2097
  #==============================================================================
2086
2098
  if __name__ =="__main__":
2087
2099
  ticker='600519.SS'
2100
+ ticker='600809.SS'
2088
2101
  start='MRH'
2102
+ start='L10Y'
2089
2103
  end='default'
2090
2104
 
2091
2105
  start='2023-1-1'
@@ -2093,7 +2107,8 @@ if __name__ =="__main__":
2093
2107
 
2094
2108
  boll_years=7
2095
2109
  technical='MV'
2096
-
2110
+ technical='Bollinger'
2111
+ indicator='PE'
2097
2112
 
2098
2113
  def security_technical(ticker,start='default',end='default', \
2099
2114
  MA_days=[5,20],EMA_days=[5,20], \
@@ -2102,7 +2117,7 @@ def security_technical(ticker,start='default',end='default', \
2102
2117
  KDJ_days=[9,3,3],matypes=[0,0],KDJ_lines=[20,50,80], \
2103
2118
  boll_days=20,boll_years=7, \
2104
2119
  resample_freq='6H',smooth=True,linewidth=1.5, \
2105
- loc1='lower left',loc2='lower right', \
2120
+ loc1='best',loc2='best', \
2106
2121
  graph=['ALL'],printout=True, \
2107
2122
  date_range=False,date_freq=False,annotate=False, \
2108
2123
  technical=['MACD'],indicator='Close'):
@@ -2138,6 +2153,8 @@ def security_technical(ticker,start='default',end='default', \
2138
2153
  fromdate=date_adjust(todate,adjust=-31*37-16)
2139
2154
  elif start in ['l5y']: # 近五年以来
2140
2155
  fromdate=date_adjust(todate,adjust=-31*61-16)
2156
+ elif start in ['l8y']: # 近八年以来
2157
+ fromdate=date_adjust(todate,adjust=-31*97-16)
2141
2158
  elif start in ['l10y']: # 近十年以来
2142
2159
  fromdate=date_adjust(todate,adjust=-31*121-16)
2143
2160
  elif start in ['ytd']: # 今年以来
@@ -2154,7 +2171,10 @@ def security_technical(ticker,start='default',end='default', \
2154
2171
  else:
2155
2172
  technical1=technical
2156
2173
 
2157
- technical_list=['MACD','RSI','KDJ','Bollinger']
2174
+ technical_list=['MACD','RSI','KDJ','Bollinger']
2175
+ technical1 = [x.upper() for x in technical1]
2176
+ technical1 = [x.replace('BOLLINGER','Bollinger') if 'BOLLINGER' in x else x for x in technical1]
2177
+
2158
2178
  for t in technical1:
2159
2179
  if t not in technical_list:
2160
2180
  print(" Warning(security_technical): unsupported technical pattern",t)
@@ -2166,7 +2186,10 @@ def security_technical(ticker,start='default',end='default', \
2166
2186
  else:
2167
2187
  indicator1=indicator
2168
2188
 
2169
- indicator_list1=['MV','PE','PB','Close']
2189
+ indicator_list1=['MV','PE','PB','Close','ROE']
2190
+ indicator1 = [x.upper() for x in indicator1]
2191
+ indicator1 = [x.replace('CLOSE','Close') if 'CLOSE' in x else x for x in indicator1]
2192
+
2170
2193
  for t in indicator1:
2171
2194
  if t not in indicator_list1:
2172
2195
  print(" Warning(security_technical): unsupported Bollinger indicator",t)
@@ -2222,7 +2245,12 @@ def security_technical(ticker,start='default',end='default', \
2222
2245
  indicator='PB', \
2223
2246
  graph=True,smooth=smooth,loc=loc1, \
2224
2247
  date_range=date_range,date_freq=date_freq,annotate=annotate)
2225
-
2248
+
2249
+ if 'Bollinger' in technical1 and 'ROE' in indicator1:
2250
+ df=security_Bubble(ticker=ticker,start=fromdate,end=todate,boll_years=boll_years, \
2251
+ indicator='ROE', \
2252
+ graph=True,smooth=smooth,loc=loc1, \
2253
+ date_range=date_range,date_freq=date_freq,annotate=annotate)
2226
2254
  return df
2227
2255
 
2228
2256
 
siat/translate.py CHANGED
@@ -1374,7 +1374,7 @@ def codetranslate0(code):
1374
1374
  # 白酒行业
1375
1375
  ['603589.SS','口子窖'],['000568.SZ','泸州老窖'],['000858.SZ','五粮液'],
1376
1376
  ['600519.SS','贵州茅台'],['000596.SZ','古井贡酒'],['000799.SZ','酒鬼酒'],
1377
- ['600809.SS','山西汾酒'],['600779.SS','水井坊'],
1377
+ ['600809.SS','山西汾酒'],['600779.SS','水井坊'],['600559.SS','老白干酒'],
1378
1378
 
1379
1379
  # 房地产行业
1380
1380
  ['000002.SZ','万科A'],['600048.SS','保利发展'],['600340.SS','华夏幸福'],
siat/valuation.py CHANGED
@@ -708,6 +708,7 @@ def funddb_name(code):
708
708
  #==============================================================================
709
709
 
710
710
  if __name__=='__main__':
711
+ tickers='AAPL'
711
712
  tickers='PZU.PL'
712
713
  tickers='JD'
713
714
  tickers='NIO'
@@ -723,6 +724,7 @@ if __name__=='__main__':
723
724
  indicators='PE'
724
725
  indicators=['pe','pb']
725
726
  indicators=['pe','pb','mv']
727
+ indicators='ROE'
726
728
 
727
729
  start='2023-1-1'; end='2023-11-30'
728
730
 
@@ -753,12 +755,24 @@ def get_valuation(tickers,indicators,start,end):
753
755
  else:
754
756
  indicators1=indicators
755
757
 
758
+ #处理ROE,赋值indicators2,保留indicators1
759
+ ROE_flag=False
760
+ if 'ROE' in indicators1:
761
+ ROE_flag=True
762
+ indicators2=indicators1.copy() #注意:若不加copy,则仅为指针赋值,两者将联动
763
+ indicators2.remove('ROE')
764
+ if 'PE' not in indicators2:
765
+ indicators2=indicators2+['PE']
766
+ if 'PB' not in indicators2:
767
+ indicators2=indicators2+['PB']
768
+
756
769
  # 百度股市百事通不支持指数估值,遇到指数代码需要先转为名称获取韭圈儿估值数据
770
+ """
757
771
  tickers1=[]
758
772
  for t in tickers:
759
773
  t1=funddb_name(t)
760
774
  tickers1=tickers1+[t1]
761
-
775
+ """
762
776
  df=None
763
777
  for t in tickers1:
764
778
  print(" Searchng valuation info for",t,"......")
@@ -768,17 +782,27 @@ def get_valuation(tickers,indicators,start,end):
768
782
 
769
783
  gotit=False
770
784
  # A股或港股?
771
- if not gotit and (result and suffix in ['SS','SZ','BJ','HK']):
772
- dft=get_stock_valuation_cn_hk(t1,indicators1,start,end)
785
+ if not gotit and (result and suffix in ['SS','SZ','BJ','HK']):
786
+ if ROE_flag:
787
+ dft=get_stock_valuation_cn_hk(t1,indicators2,start,end)
788
+ dft['ROE']=dft.apply(lambda x: x['PB']/x['PE'],axis=1)
789
+ dft=dft[indicators1]
790
+ else:
791
+ dft=get_stock_valuation_cn_hk(t1,indicators1,start,end)
773
792
  if dft is not None: gotit=True
774
793
 
775
794
  # 波兰股?
776
795
  if not gotit and (result and suffix in ['PL','WA']):
777
- dft=get_stock_valuation_pl(t1,indicators1,start,end)
796
+ if ROE_flag:
797
+ dft=get_stock_valuation_pl(t1,indicators2,start,end)
798
+ dft['ROE']=dft.apply(lambda x: x['PB']/x['PE'],axis=1)
799
+ dft=dft[indicators1]
800
+ else:
801
+ dft=get_stock_valuation_pl(t1,indicators1,start,end)
778
802
  if dft is not None: gotit=True
779
803
 
780
- # 申万指数代码?
781
- if not gotit and (result and suffix in ['SW']):
804
+ # 申万指数代码?可能没有机会走到这里!
805
+ if not gotit and (result and suffix in ['SW']) and not ROE_flag:
782
806
  #dft=get_index_valuation_funddb(t1,indicators1,start,end)
783
807
  indicator1=indicators1[0]
784
808
  dft0=industry_valuation_history_sw(industry=t1,
@@ -796,13 +820,23 @@ def get_valuation(tickers,indicators,start,end):
796
820
 
797
821
  # 美股?
798
822
  if not gotit and (not result and (is_alphanumeric(prefix) or '^' in prefix)):
799
- dft=get_stock_valuation_us(t1,indicators1,start,end)
823
+ if ROE_flag:
824
+ dft=get_stock_valuation_us(t1,indicators2,start,end)
825
+ dft['ROE']=dft.apply(lambda x: x['PB']/x['PE'],axis=1)
826
+ dft=dft[indicators1]
827
+ else:
828
+ dft=get_stock_valuation_us(t1,indicators1,start,end)
800
829
  if dft is not None: gotit=True
801
830
 
802
831
  # 行业指数名称?
803
832
  if not gotit and (not result):
804
- dft=get_index_valuation_funddb(t1,indicators1,start,end)
805
- if dft is not None: gotit=True
833
+ if ROE_flag:
834
+ dft=get_index_valuation_funddb(t1,indicators2,start,end)
835
+ dft['ROE']=dft.apply(lambda x: x['PB']/x['PE'],axis=1)
836
+ dft=dft[indicators1]
837
+ else:
838
+ dft=get_index_valuation_funddb(t1,indicators1,start,end)
839
+ if dft is not None: gotit=True
806
840
 
807
841
  if not gotit:
808
842
  print(" #Warning(get_valuation): failed to retrieve info for",t1)
@@ -879,8 +913,18 @@ if __name__=='__main__':
879
913
  indicators=['PE','PB','MV']
880
914
  start='2023-1-1'; end='2023-11-30'
881
915
  loc1='best'
916
+
917
+ tickers=['AAPL','MSFT']
918
+ indicators='ROE'
919
+ indicators='PE'
920
+ indicators='PB'
921
+ start='2023-1-1'; end='2023-12-31'
922
+ loc1='best'
923
+
924
+ val=security_valuation(tickers,indicators,start,end)
882
925
 
883
926
  def security_valuation(tickers,indicators,start,end, \
927
+ preprocess='none',scaling_option='start', \
884
928
  twinx=False,loc1='best',loc2='best', \
885
929
  graph=True,annotate=False):
886
930
  """
@@ -942,8 +986,8 @@ def security_valuation(tickers,indicators,start,end, \
942
986
 
943
987
  return df
944
988
 
945
- # 绘制双线: 一只证券,两个指标。允许twinx双轴绘图,twinx曲线容易误导走势
946
- if name_num == 1 and indicator_num == 2:
989
+ # 绘制双线: 一只证券,两个指标。twinx双轴绘图,注意twinx曲线容易误导走势
990
+ if name_num == 1 and indicator_num == 2 and twinx:
947
991
  t=names1[0]
948
992
  i1=indicators1[0]; i2=indicators1[1]
949
993
  df2_1=df[i1]; df2_2=df[i2]
@@ -974,8 +1018,8 @@ def security_valuation(tickers,indicators,start,end, \
974
1018
  color1='red',color2='blue')
975
1019
  return df
976
1020
 
977
- # 绘制双线: 两只证券,一个指标。允许twinx双轴绘图
978
- if name_num == 2 and indicator_num == 1:
1021
+ # 绘制双线: 两只证券,一个指标。twinx双轴绘图
1022
+ if name_num == 2 and indicator_num == 1 and twinx:
979
1023
  t1=names1[0]; t2=names1[1]
980
1024
  i=indicators1[0]
981
1025
  df2_1=pd.DataFrame(df[i,t1])[i]; df2_2=pd.DataFrame(df[i,t2])[i]
@@ -1010,8 +1054,9 @@ def security_valuation(tickers,indicators,start,end, \
1010
1054
 
1011
1055
  return df
1012
1056
 
1057
+ lang=check_language()
1013
1058
  # 绘制多线:多只证券,一个指标。简单多线绘图
1014
- if name_num > 2 and indicator_num == 1:
1059
+ if name_num >= 2 and indicator_num == 1 and not twinx:
1015
1060
  i=indicators1[0]
1016
1061
  df2=df[i]
1017
1062
 
@@ -1024,17 +1069,23 @@ def security_valuation(tickers,indicators,start,end, \
1024
1069
  footnote9="数据来源: 综合baidu/stooq/funddb/swhysc,"+str(todaydt)
1025
1070
  footnote=footnote1+'\n'+footnote9
1026
1071
 
1027
- ylabeltxt=i
1028
-
1029
- draw_lines(df2,y_label=ylabeltxt,x_label=footnote, \
1030
- axhline_value=0,axhline_label='', \
1072
+ #ylabeltxt=i
1073
+ ylabeltxt=ectranslate(i)
1074
+
1075
+ # 标准化处理
1076
+ dfs2,axhline_label,x_label,y_label,plus_sign=df_preprocess(df2,measure=indicators1, \
1077
+ axhline_label='',x_label=footnote,y_label=ylabeltxt,lang=lang, \
1078
+ preprocess=preprocess,scaling_option=scaling_option)
1079
+
1080
+ draw_lines(dfs2,y_label=y_label,x_label=x_label, \
1081
+ axhline_value=0,axhline_label=axhline_label, \
1031
1082
  title_txt=titletxt,data_label=False, \
1032
- resample_freq='D',loc=loc1,annotate=annotate)
1083
+ resample_freq='D',loc=loc1,annotate=annotate,plus_sign=plus_sign)
1033
1084
 
1034
1085
  return df
1035
1086
 
1036
1087
  # 绘制多线:一只证券,多个指标。简单多线绘图
1037
- if name_num == 1 and indicator_num > 2:
1088
+ if name_num == 1 and indicator_num >= 2 and not twinx:
1038
1089
  t=names1[0]
1039
1090
  df2=None
1040
1091
  for i in indicators1:
@@ -1045,20 +1096,31 @@ def security_valuation(tickers,indicators,start,end, \
1045
1096
  df2=dft
1046
1097
  else:
1047
1098
  df2=pd.merge(df2,dft,left_index=True,right_index=True)
1099
+
1100
+ df2.rename(columns={i:ectranslate(i)},inplace=True)
1048
1101
 
1049
1102
  titletxt="证券估值走势:"+t
1050
1103
 
1051
- footnote1="注:PE为市盈率,PB为市净率,MV为总市值(十亿交易所所在地货币单位)"
1104
+ footnote1=''
1105
+ if 'MV' in indicators1:
1106
+ footnote1="注:市值金额:十亿,当地货币单位"
1107
+
1052
1108
  todaydt = datetime.date.today()
1053
- footnote9="数据来源: baidu/stooq/funddb/swhysc,"+str(todaydt)
1109
+ footnote9="数据来源: 综合baidu/stooq/funddb/swhysc,"+str(todaydt)
1054
1110
  footnote=footnote1+'\n'+footnote9
1055
1111
 
1056
- ylabeltxt=''
1112
+ #ylabeltxt=''
1113
+ ylabeltxt="估值"
1057
1114
 
1058
- draw_lines(df2,y_label=ylabeltxt,x_label=footnote, \
1059
- axhline_value=0,axhline_label='', \
1115
+ # 标准化处理
1116
+ dfs2,axhline_label,x_label,y_label,plus_sign=df_preprocess(df2,measure=indicators1, \
1117
+ axhline_label='',x_label=footnote,y_label=ylabeltxt,lang=lang, \
1118
+ preprocess=preprocess,scaling_option=scaling_option)
1119
+
1120
+ draw_lines(dfs2,y_label=y_label,x_label=x_label, \
1121
+ axhline_value=0,axhline_label=axhline_label, \
1060
1122
  title_txt=titletxt,data_label=False, \
1061
- resample_freq='D',loc=loc1,annotate=annotate)
1123
+ resample_freq='D',loc=loc1,annotate=annotate,plus_sign=plus_sign)
1062
1124
 
1063
1125
  return df
1064
1126
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: siat
3
- Version: 2.13.23
3
+ Version: 2.13.40
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
@@ -15,7 +15,7 @@ siat/bond_test.py,sha256=yUOFw7ddGU-kb1rJdnsjkJWziDNgUR7OLDA7F7Ub91A,5246
15
15
  siat/capm_beta.py,sha256=cqbmfM4mrq73Ub0bq5QjWJjmJHj9x7-dSqbmNxnEj7k,28946
16
16
  siat/capm_beta_test.py,sha256=ImR0c5mc4hIl714XmHztdl7qg8v1E2lycKyiqnFj6qs,1745
17
17
  siat/cmat_commons.py,sha256=Nj9Kf0alywaztVoMVeVVL_EZk5jRERJy8R8kBw88_Tg,38116
18
- siat/common.py,sha256=QOKGCaxREeCtHjvQZPNIFmBRgMyBeUA4A-gUJSYFHi0,81947
18
+ siat/common.py,sha256=cESZRjjRx7ki1_YhZ_Kz1EhZ8zpHpgrGCf6kPz6YKsY,91337
19
19
  siat/compare_cross.py,sha256=-MZzxmX8_9oFZ7X0IcR51w87EWwssbitiw-BcmHMFzQ,26228
20
20
  siat/compare_cross_test.py,sha256=xra5XYmQGEtfIZL2h-GssdH2hLdFIhG3eoCrkDrL3gY,3473
21
21
  siat/concepts_iwencai.py,sha256=m1YEDtECRT6FqtzlKm91pt2I9d3Z_XoP59BtWdRdu8I,3061
@@ -57,7 +57,7 @@ siat/future_china.py,sha256=F-HsIf2Op8Z22RzTjet1g8COzldgnMjFNSXsAkeGyWo,17595
57
57
  siat/future_china_test.py,sha256=BrSzmDVaOHki6rntOtosmRn-6dkfOBuLulJNqh7MOpc,1163
58
58
  siat/global_index_test.py,sha256=hnFp3wqqzzL-kAP8mgxDZ54Bd5Ijf6ENi5YJlGBgcXw,2402
59
59
  siat/google_authenticator.py,sha256=ZUbZR8OW0IAKDbcYtlqGqIpZdERpFor9NccFELxg9yI,1637
60
- siat/grafix.py,sha256=q8hUC6Hr1jcEiIDSlPixC5Tar58HeThcJhhM3xvGrEs,69751
60
+ siat/grafix.py,sha256=nVzC8u5StHV6ZiyaGXv6L4z5DNZmVjTMFiZ6bKuJGTM,70560
61
61
  siat/grafix_test.py,sha256=kXvcpLgQNO7wd30g_bWljLj5UH7bIVI0_dUtXbfiKR0,3150
62
62
  siat/holding_risk.py,sha256=Dh4zXEw-0hnbMNorbsRS142C8mUzq4NhFjYnauWu5tc,30548
63
63
  siat/holding_risk_test.py,sha256=FRlw_9wFG98BYcg_cSj95HX5WZ1TvkGaOUdXD7-V86s,474
@@ -81,7 +81,7 @@ siat/option_pricing_test.py,sha256=eeorV5Ja5vjlRXnP6fWJHetGU5Vb8SnLopkC6RV3GfA,2
81
81
  siat/option_sina_api_test.py,sha256=dn-k_wrQnAaNKHoROvWJEc7lqlU0bwiV2Aa4usWAFGM,5908
82
82
  siat/proxy_test.py,sha256=erQJrmGs2X46z8Gb1h-7GYQ0rTUcaR8dxHExWoBz2eM,2610
83
83
  siat/quandl_test.py,sha256=EcPoXnLuqzPl5dKyVEZi3j3PJZFpsnU_iNPhLWC9p-A,1552
84
- siat/risk_adjusted_return.py,sha256=CLFm2Y8dYM7kJODxGhoPIo3vOo3KzHSFbLIeZLsiRRM,54678
84
+ siat/risk_adjusted_return.py,sha256=mr0ngMceyS_fWBlluHT2S9JsKJng46dDN93AoiMsirg,54669
85
85
  siat/risk_adjusted_return_test.py,sha256=m_VHL5AtT74cJv5i7taTeTfnkX48y0AFJk5phawyYWg,3416
86
86
  siat/risk_evaluation.py,sha256=dijrOZOFSlsHKUfTIRmSu9z9-b2vAyXcBnVcXxOtshw,76033
87
87
  siat/risk_evaluation_test.py,sha256=YEXM96gKzTfwN4U61AS4Rr1tV7KgUvn4rRC6f3iMw9s,3731
@@ -92,10 +92,10 @@ siat/sector_china_test.py,sha256=1wq7ef8Bb_L8F0h0W6FvyBrIcBTEbrTV7hljtpj49U4,584
92
92
  siat/security_price.py,sha256=2oHskgiw41KMGfqtnA0i2YjNNV6cYgtlUK0j3YeuXWs,29185
93
93
  siat/security_prices.py,sha256=kGBAqHwmN_iupBZ6v3AUrRHjCSNxP09sz2nlBSVyaHs,76950
94
94
  siat/security_prices_test.py,sha256=OEphoJ87NPKoNow1QA8EU_5MUYrJF-qKoWKNapVfZNI,10779
95
- siat/security_trend.py,sha256=rWYjeR-KONBdJB7Va96gVieci2bOIxkc87rvqxZ80P4,15367
95
+ siat/security_trend.py,sha256=DQ9hwAioTg0R_9XTqT5jywLWSmMK1GAvOtiPJVFQPZA,15911
96
96
  siat/setup.py,sha256=up65rQGLmTBkhtaMLowjoQXYmIsnycnm4g1SYmeQS6o,1335
97
97
  siat/shenwan index history test.py,sha256=JCVAzOSEldHalhSFa3pqD8JI_8_djPMQOxpkuYU-Esg,1418
98
- siat/stock.py,sha256=LsRAj1yLQ3PK53IG9cigMmG9UWuwitst_6bUGohhbDw,140379
98
+ siat/stock.py,sha256=1tUAzgcfouhyeA5TElytICgyhUmsgKz5p3N8xVuoAc8,140831
99
99
  siat/stock_advice_linear.py,sha256=-twT7IGP-NEplkL1WPSACcNJjggRB2j4mlAQCkzOAuo,31655
100
100
  siat/stock_base.py,sha256=uISvbRyOGy8p9QREA96CVydgflBkn5L3OXOGKl8oanc,1312
101
101
  siat/stock_china.py,sha256=B1hbZCxJuE5GVvGGmf_rSmQodYHmEFuyiDrUvxHhg4w,83969
@@ -106,7 +106,7 @@ siat/stock_list_china_test.py,sha256=gv14UwMMvkZqtb6G7DCTSuehIwVHuVwu7w60p6gyHoo
106
106
  siat/stock_prices_kneighbors.py,sha256=WfZvo5EyeBsm-T37zDj7Sl9dPSRq5Bx4JxIJ9IUum6s,36738
107
107
  siat/stock_prices_linear.py,sha256=-OUKRr27L2aStQgJSlJOrJ4gay_G7P-m-7t7cU2Yoqk,13991
108
108
  siat/stock_profile.py,sha256=npinIwxgfgHeV8tpXrzLBrPUWKMZGL2-xA96ve-H2wM,25329
109
- siat/stock_technical.py,sha256=_zIFO4SHGjgXn3WJBAx8AoemEzI-EUJr0XRCxxSCjsg,94740
109
+ siat/stock_technical.py,sha256=mlyJ5D9S4a6aSwMnQLKVs0H1BHB17AUVNiN700j2lXU,96131
110
110
  siat/stock_test.py,sha256=E9YJAvOw1VEGJSDI4IZuEjl0tGoisOIlN-g9UqA_IZE,19475
111
111
  siat/stooq.py,sha256=dOc_S5HLrYg48YAKTCs1eX8UTJOOkPM8qLL2KupqlLY,2470
112
112
  siat/temp.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
@@ -120,13 +120,13 @@ siat/transaction_test.py,sha256=Z8g1LJCN4-mnUByXMUMoFmN0t105cbmsz2QmvSuIkbU,1858
120
120
  siat/translate-20230125.py,sha256=NPPSXhT38s5t9fzMvl_fvi4ckSB73ThLmZetVI-xGdU,117953
121
121
  siat/translate-20230206.py,sha256=-vtI125WyaJhmPotOpDAmclt_XnYVaWU9ByLWZ6FyYE,118133
122
122
  siat/translate-20230215.py,sha256=TJgtPE3n8IjljmZ4Pefy8dmHoNdFF-1zpML6BhA9FKE,121657
123
- siat/translate.py,sha256=UExBdxIRL1ZvOYJ0tXrKcmUcZa2L8R7mckEHPh7-cV8,166925
123
+ siat/translate.py,sha256=GWIw0q8jEYDAEYs9CsqNtn_ELZdcG0BOB_af-X7Svok,166954
124
124
  siat/universal_test.py,sha256=CDAOffW1Rvs-TcNN5giWVvHMlch1w4dp-w5SIV9jXL0,3936
125
- siat/valuation.py,sha256=BdpVFKHX4zTGgJFeGmPqhwUee_JKWBZRqB1ab8yV4ek,44491
125
+ siat/valuation.py,sha256=7_jBnthig4kAWrE4iAQ2vOKAkhnFsvXi8lDdAC0kWZY,47105
126
126
  siat/valuation_china.py,sha256=oEQRrktJNHiOG1mJSQN1aSSQAQrwrg-ppIHyNVjMjNg,67603
127
127
  siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
128
128
  siat/var_model_validation.py,sha256=zB_Skk_tmzIR15l6oAW3am4HBGVIG-eZ8gJhCdXZ8Qw,14859
129
- siat-2.13.23.dist-info/METADATA,sha256=sUCES5BTNPw6ypuRsXqd7NYdcQVbieEtbxvJHNpqFWg,1449
130
- siat-2.13.23.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
131
- siat-2.13.23.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
132
- siat-2.13.23.dist-info/RECORD,,
129
+ siat-2.13.40.dist-info/METADATA,sha256=oG28X3x3gKvkVFui0pCHMW8Suiv80F-MLjEJzLwIiBA,1449
130
+ siat-2.13.40.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
131
+ siat-2.13.40.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
132
+ siat-2.13.40.dist-info/RECORD,,
File without changes