siat 2.13.30__py3-none-any.whl → 2.13.41__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 +189 -0
- siat/security_trend.py +16 -6
- siat/stock.py +35 -10
- siat/stock_technical.py +50 -22
- siat/translate.py +3 -1
- siat/valuation.py +76 -20
- {siat-2.13.30.dist-info → siat-2.13.41.dist-info}/METADATA +1 -1
- {siat-2.13.30.dist-info → siat-2.13.41.dist-info}/RECORD +10 -10
- {siat-2.13.30.dist-info → siat-2.13.41.dist-info}/WHEEL +0 -0
- {siat-2.13.30.dist-info → siat-2.13.41.dist-info}/top_level.txt +0 -0
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/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
|
-
|
352
|
-
|
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
@@ -1498,7 +1498,9 @@ def compare_msecurity(tickers,measure,start,end, \
|
|
1498
1498
|
standardize: 标准化处理,(x - mean(x))/std(x)
|
1499
1499
|
normalize: 归一化处理,(x - min(x))/(max(x) - min(x))
|
1500
1500
|
logarithm: 对数处理,np.log(x)
|
1501
|
-
scaling
|
1501
|
+
scaling:缩放处理,五种选项scaling_option
|
1502
|
+
(mean均值,min最小值,start开始值,percentage相对每条曲线起点值的百分比,
|
1503
|
+
change%相对每条曲线起点值变化的百分比)
|
1502
1504
|
start方式的图形更接近于持有收益率(Exp Ret%),设为默认的缩放方式。
|
1503
1505
|
|
1504
1506
|
"""
|
@@ -1663,9 +1665,14 @@ def compare_msecurity(tickers,measure,start,end, \
|
|
1663
1665
|
x_label="数据来源: 综合新浪/东方财富/雅虎财经/stooq/FRED/OECD,"+str(today)
|
1664
1666
|
#title_txt="比较多只证券产品的指标走势"
|
1665
1667
|
#title_txt="趋势分析"
|
1666
|
-
title_txt="
|
1668
|
+
title_txt="指标趋势分析:"+y_label
|
1667
1669
|
|
1668
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
|
+
"""
|
1669
1676
|
preprocess1=preprocess.lower()
|
1670
1677
|
preplist=['standardize','normalize','logarithm','scaling']
|
1671
1678
|
if preprocess1 in preplist:
|
@@ -1819,6 +1826,7 @@ def compare_msecurity(tickers,measure,start,end, \
|
|
1819
1826
|
|
1820
1827
|
else:
|
1821
1828
|
dfs2=dfs
|
1829
|
+
"""
|
1822
1830
|
|
1823
1831
|
# 填充非交易日的缺失值,使得绘制的曲线连续
|
1824
1832
|
dfs2.fillna(axis=0,method='ffill',inplace=True)
|
@@ -2536,7 +2544,7 @@ def stock_info(symbol):
|
|
2536
2544
|
if result & (suffix=='HK'):
|
2537
2545
|
symbol=prefix[-4:]+'.'+suffix
|
2538
2546
|
|
2539
|
-
from yahooquery import Ticker
|
2547
|
+
from yahooquery import Ticker #如果出现类似于{'AAPL': 'Invalid Cookie'}错误,则需要升级
|
2540
2548
|
stock = Ticker(symbol)
|
2541
2549
|
|
2542
2550
|
"""
|
@@ -2551,6 +2559,7 @@ def stock_info(symbol):
|
|
2551
2559
|
shareHolderRightRisk:股权风险
|
2552
2560
|
"""
|
2553
2561
|
try:
|
2562
|
+
#如果出现类似于{'AAPL': 'Invalid Cookie'}错误,则需要升级yahooquery
|
2554
2563
|
adict=stock.asset_profile
|
2555
2564
|
except:
|
2556
2565
|
print(" #Error(stock_info): failed to get the profile of",symbol)
|
@@ -2558,7 +2567,7 @@ def stock_info(symbol):
|
|
2558
2567
|
return None
|
2559
2568
|
|
2560
2569
|
if adict[symbol] == 'Invalid Cookie':
|
2561
|
-
print(" #Error(stock_info): failed in retrieving info of",symbol)
|
2570
|
+
print(" #Error(stock_info): failed in retrieving info of",symbol,"\b. Try upgrade yahooquery and do again")
|
2562
2571
|
return None
|
2563
2572
|
|
2564
2573
|
keylist=list(adict[symbol].keys())
|
@@ -3178,11 +3187,11 @@ if __name__=='__main__':
|
|
3178
3187
|
|
3179
3188
|
#==============================================================================
|
3180
3189
|
|
3181
|
-
def stock_snapshot(ticker='AAPL'):
|
3190
|
+
def stock_snapshot(ticker='AAPL',info_type="all"):
|
3182
3191
|
"""
|
3183
|
-
|
3192
|
+
功能:打印指定选项,套壳函数get_stock_profile
|
3184
3193
|
"""
|
3185
|
-
print("
|
3194
|
+
print(" Connecting to Yahoo Finance ... ...")
|
3186
3195
|
typelist=['basic',
|
3187
3196
|
'officers',
|
3188
3197
|
'fin_rates',
|
@@ -3190,10 +3199,23 @@ def stock_snapshot(ticker='AAPL'):
|
|
3190
3199
|
'market_rates',
|
3191
3200
|
'risk_general',
|
3192
3201
|
'risk_esg']
|
3193
|
-
|
3194
|
-
|
3202
|
+
|
3203
|
+
if info_type.lower() !="all" and info_type.lower() in typelist:
|
3204
|
+
info=get_stock_profile(ticker,info_type=info_type)
|
3205
|
+
return
|
3206
|
+
|
3207
|
+
if info_type.lower() =="all":
|
3208
|
+
for t in typelist:
|
3209
|
+
info=get_stock_profile(ticker,info_type=t)
|
3210
|
+
|
3211
|
+
if info is None:
|
3212
|
+
break
|
3213
|
+
return
|
3214
|
+
else:
|
3215
|
+
print(" #Error(stock_snapshot): unsupported info type",info_type)
|
3216
|
+
print(" Supporting",typelist)
|
3217
|
+
return
|
3195
3218
|
|
3196
|
-
return
|
3197
3219
|
|
3198
3220
|
def security_snapshot(ticker='AAPL'):
|
3199
3221
|
"""
|
@@ -3210,6 +3232,9 @@ def security_snapshot(ticker='AAPL'):
|
|
3210
3232
|
for t in typelist:
|
3211
3233
|
info=get_stock_profile(ticker,info_type=t)
|
3212
3234
|
|
3235
|
+
if info is None:
|
3236
|
+
break
|
3237
|
+
|
3213
3238
|
return
|
3214
3239
|
#==============================================================================
|
3215
3240
|
if __name__=='__main__':
|
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='
|
1932
|
-
start='
|
1933
|
-
end='
|
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;
|
1954
|
+
import datetime as dt; todaydt=dt.date.today()
|
1953
1955
|
if end in ['default','today']:
|
1954
|
-
end=
|
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=
|
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*
|
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
|
-
|
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
|
-
|
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="
|
2075
|
+
x_label="数据来源:综合新浪/东方财富/stooq/雅虎财经,"+str(today)+",估值前置窗口期"+str(boll_years)+"年"
|
2064
2076
|
|
2065
2077
|
axhline_value=0
|
2066
2078
|
axhline_label=''
|
2067
|
-
title_txt="
|
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='
|
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','华夏幸福'],
|
@@ -1611,6 +1611,8 @@ def codetranslate0(code):
|
|
1611
1611
|
['CLPUSD=X','智利比索/美元汇率'],['CLPUSD','智利比索/美元汇率'],
|
1612
1612
|
['BRLUSD=X','巴西雷亚尔/美元汇率'],['BRLUSD','巴西雷亚尔/美元汇率'],
|
1613
1613
|
|
1614
|
+
['INRTUS.M','美联储基准利率'],['USDCNY','美元/人民币汇率'],
|
1615
|
+
|
1614
1616
|
['EUR_I','STOOQ欧元指数'],
|
1615
1617
|
['EURUSD=X','欧元/美元汇率'],['EURUSD','欧元/美元汇率'],
|
1616
1618
|
['GBPUSD=X','英镑/美元汇率'],['GBPUSD','英镑/美元汇率'],
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
805
|
-
|
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,7 +986,7 @@ def security_valuation(tickers,indicators,start,end, \
|
|
942
986
|
|
943
987
|
return df
|
944
988
|
|
945
|
-
# 绘制双线:
|
989
|
+
# 绘制双线: 一只证券,两个指标。twinx双轴绘图,注意twinx曲线容易误导走势
|
946
990
|
if name_num == 1 and indicator_num == 2 and twinx:
|
947
991
|
t=names1[0]
|
948
992
|
i1=indicators1[0]; i2=indicators1[1]
|
@@ -974,7 +1018,7 @@ def security_valuation(tickers,indicators,start,end, \
|
|
974
1018
|
color1='red',color2='blue')
|
975
1019
|
return df
|
976
1020
|
|
977
|
-
# 绘制双线:
|
1021
|
+
# 绘制双线: 两只证券,一个指标。twinx双轴绘图
|
978
1022
|
if name_num == 2 and indicator_num == 1 and twinx:
|
979
1023
|
t1=names1[0]; t2=names1[1]
|
980
1024
|
i=indicators1[0]
|
@@ -1010,6 +1054,7 @@ def security_valuation(tickers,indicators,start,end, \
|
|
1010
1054
|
|
1011
1055
|
return df
|
1012
1056
|
|
1057
|
+
lang=check_language()
|
1013
1058
|
# 绘制多线:多只证券,一个指标。简单多线绘图
|
1014
1059
|
if name_num >= 2 and indicator_num == 1 and not twinx:
|
1015
1060
|
i=indicators1[0]
|
@@ -1024,12 +1069,18 @@ 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
|
-
|
1030
|
-
|
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
|
|
@@ -1058,13 +1109,18 @@ def security_valuation(tickers,indicators,start,end, \
|
|
1058
1109
|
footnote9="数据来源: 综合baidu/stooq/funddb/swhysc,"+str(todaydt)
|
1059
1110
|
footnote=footnote1+'\n'+footnote9
|
1060
1111
|
|
1061
|
-
ylabeltxt=''
|
1112
|
+
#ylabeltxt=''
|
1113
|
+
ylabeltxt="估值"
|
1062
1114
|
|
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)
|
1063
1119
|
|
1064
|
-
draw_lines(
|
1065
|
-
axhline_value=0,axhline_label=
|
1120
|
+
draw_lines(dfs2,y_label=y_label,x_label=x_label, \
|
1121
|
+
axhline_value=0,axhline_label=axhline_label, \
|
1066
1122
|
title_txt=titletxt,data_label=False, \
|
1067
|
-
resample_freq='D',loc=loc1,annotate=annotate)
|
1123
|
+
resample_freq='D',loc=loc1,annotate=annotate,plus_sign=plus_sign)
|
1068
1124
|
|
1069
1125
|
return df
|
1070
1126
|
|
@@ -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=
|
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
|
@@ -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=
|
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
|
98
|
+
siat/stock.py,sha256=ejCrOoslRzhjA7wNHsLggYw3fWiL-3r3G0PSF06OHw8,141510
|
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=
|
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=
|
123
|
+
siat/translate.py,sha256=aOn3GVMkdFcKvbL0T5gRn-uPA6vj93BCITkyn30H9SA,167047
|
124
124
|
siat/universal_test.py,sha256=CDAOffW1Rvs-TcNN5giWVvHMlch1w4dp-w5SIV9jXL0,3936
|
125
|
-
siat/valuation.py,sha256=
|
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.
|
130
|
-
siat-2.13.
|
131
|
-
siat-2.13.
|
132
|
-
siat-2.13.
|
129
|
+
siat-2.13.41.dist-info/METADATA,sha256=7kf2jAQHnIJBJCds9iDD_kpmdGfSZzUvZMzL3B-vIF0,1449
|
130
|
+
siat-2.13.41.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
|
131
|
+
siat-2.13.41.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
|
132
|
+
siat-2.13.41.dist-info/RECORD,,
|
File without changes
|
File without changes
|