siat 3.1.6__py3-none-any.whl → 3.1.12__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/fund_china.py CHANGED
@@ -20,18 +20,23 @@ from siat.translate import *
20
20
  from siat.grafix import *
21
21
  from siat.bond_base import *
22
22
  #==============================================================================
23
- def compare_fund_holding_china(ticker,quarters,rank=10):
23
+ def compare_fund_holding_china(ticker,quarters,rank=10,font_size='14px'):
24
24
  """
25
25
  功能:套壳函数fund_stock_holding_compare_china
26
26
  """
27
27
  if len(quarters) < 2:
28
28
  print(" #Warning(compare_fund_holding_china): need 2 quarters to compare at",quarters)
29
29
  return None
30
+ """
30
31
  if quarters[0] >= quarters[1]:
31
32
  print(" #Warning(compare_fund_holding_china):",quarters[0],"is supposed to be earlier than",quarters[1])
32
33
  return None
33
-
34
- df=fund_stock_holding_compare_china(fund=ticker,quarter1=quarters[0],quarter2=quarters[1],rank=rank)
34
+ """
35
+ #保证较早的季度排在前面
36
+ quarters.sort()
37
+
38
+ df=fund_stock_holding_compare_china(fund=ticker,quarter1=quarters[0],quarter2=quarters[1], \
39
+ rank=rank,font_size=font_size)
35
40
 
36
41
  return df
37
42
 
@@ -43,13 +48,18 @@ if __name__=='__main__':
43
48
  df=fund_stock_holding_compare_china(fund,quarter1,quarter2,rank=10)
44
49
 
45
50
  #比较两个季度之间的基金持仓变化
46
- def fund_stock_holding_compare_china(fund,quarter1,quarter2,rank=10):
51
+ def fund_stock_holding_compare_china(fund,quarter1,quarter2,rank=10, \
52
+ font_size='14px'):
47
53
  """
48
54
  功能:基金fund在两个季度quarter1和quarter2的持仓股票对比(股数和金额),前rank名股票
49
55
  参数:
50
56
  fund,str,基金代码;
51
57
  quarter1,str,靠前的季度, 格式为 'YYYYQ1',例如: '2021Q2';
52
58
  quarter2,str,靠后的季度, 格式为 'YYYYQ1',例如: '2021Q2';
59
+
60
+ 注意:监管仅要求基金披露前十大重仓股,因此其持仓比例之和一般小于100%;若大于100%,
61
+ 则为基金以其净资产作为抵押加了杠杆融资,买进更多成份股,导致成份股总价值(基金总资产)超过了基金的净资产。
62
+ 基金总资产 = 基金负债 + 基金净资产
53
63
  """
54
64
  print("Searching fund holding info, which may take time, please wait ...\n")
55
65
 
@@ -112,6 +122,7 @@ def fund_stock_holding_compare_china(fund,quarter1,quarter2,rank=10):
112
122
 
113
123
  df1 = df1[['股票代码', '股票名称','持股数','持仓市值','占净值比例']]
114
124
  df1 = df1.rename(columns={'持股数':s1_share,'持仓市值':s1_value,'占净值比例':s1_ratio})
125
+ num1=len(df1)
115
126
 
116
127
  df2 =data[data['季度']==s2]
117
128
  if len(df2)==0:
@@ -120,6 +131,7 @@ def fund_stock_holding_compare_china(fund,quarter1,quarter2,rank=10):
120
131
 
121
132
  df2 = df2[['股票代码', '股票名称','持股数','持仓市值','占净值比例']]
122
133
  df2 = df2.rename(columns={'持股数':s2_share,'持仓市值':s2_value,'占净值比例':s2_ratio})
134
+ num2=len(df2)
123
135
 
124
136
  df_merge = pd.merge(df1,df2,on=['股票代码','股票名称'],how='outer')
125
137
 
@@ -196,16 +208,17 @@ def fund_stock_holding_compare_china(fund,quarter1,quarter2,rank=10):
196
208
  # 替换空值
197
209
  df.fillna('---')
198
210
  """
199
- print("===== 中国基金持仓股票分析:"+name+','+s1+"对比"+s2,"(按后者持仓比例高低排列,"+order+str(rank)+"名股票) =====\n")
211
+ print("===== 中国基金持仓股票分析:"+name+','+s1+"对比"+s2,"(按后者持仓比例高低排列,"+order+str(rank)+"名重仓股) =====\n")
200
212
  print(df.to_string(index=False))
201
213
  import datetime; today = datetime.date.today()
202
214
  print("\n*** 注:持股数为万股,持仓市值为万元,持仓比例为占基金资产净值比例%,包括A股与非A股")
203
215
  print(" 数据来源:天天基金/东方财富, 期间持仓股票总计"+str(len(df_merge))+"只,",today)
204
216
  """
205
- titletxt="基金持仓转移矩阵:"+name+''+s1+"对比"+s2+"(按后者持仓比例降序排列,"+order+str(rank)+"名成份证券)"
217
+ titletxt="基金持仓转移明细:"+name+'基金,'+s1+"对比"+s2+"(按后者持仓比例降序排列,"+order+str(rank)+"名重仓股)"
206
218
 
207
- footnote1="【注】持仓数为万股,持仓市值为万元,持仓比例为占基金资产净值比例%;"
208
- footnote2="期间内(曾经)持仓证券数合计"+str(len(df_merge))+"只"+'\n'
219
+ footnote1="【注】持仓数单位为万股,持仓市值单位为万元,持仓比例为成份股价值为占基金资产净值%(以最新期间为准列示)\n"
220
+ #footnote2=s1+'/'+s2+"期末持仓证券数"+str(num1)+'/'+str(num2)+"只"+'\n'
221
+ footnote2='监管仅要求披露前十大重仓股,其持仓比例之和一般小于100%;若大于100%则为基金加了杠杆,总资产多于净资产\n'
209
222
  import datetime; todaydt = datetime.date.today()
210
223
  footnote9="数据来源:天天基金/东方财富,"+str(todaydt)+"统计"
211
224
  footnote=footnote1+footnote2+footnote9
@@ -227,21 +240,27 @@ def fund_stock_holding_compare_china(fund,quarter1,quarter2,rank=10):
227
240
  df=df[collist1]
228
241
  """
229
242
  df.replace(0,'---',inplace=True); df.replace('0','---',inplace=True)
243
+
244
+ #确定表格字体大小
245
+ titile_font_size=font_size
246
+ heading_font_size=data_font_size=str(int(font_size.replace('px',''))-2)+'px'
230
247
 
231
248
  df_display_CSS(df,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=2, \
232
249
  first_col_align='center',second_col_align='left', \
233
250
  last_col_align='right',other_col_align='right', \
234
- titile_font_size='14px',heading_font_size='12px', \
235
- data_font_size='12px')
251
+ titile_font_size=titile_font_size, \
252
+ heading_font_size=heading_font_size, \
253
+ data_font_size=data_font_size)
236
254
 
237
255
  return df_merge
238
256
 
239
257
  #==============================================================================
240
- def fund_holding_china(ticker,rank=10,pastyears=2):
258
+ def fund_holding_china(ticker,rank=10,pastyears=2,reverse=False,font_size='16px'):
241
259
  """
242
260
  功能:套壳函数fund_stock_holding_rank_china
243
261
  """
244
- df,data=fund_stock_holding_rank_china(fund=ticker,rank=rank,year_num=pastyears)
262
+ df,data=fund_stock_holding_rank_china(fund=ticker,rank=rank,year_num=pastyears, \
263
+ reverse=reverse,font_size=font_size)
245
264
 
246
265
  return df,data
247
266
 
@@ -253,8 +272,10 @@ if __name__=='__main__':
253
272
  df=fund_stock_holding_rank_china(fund,year_num=2)
254
273
 
255
274
  # 获取单只基金的十大股票名称信息
256
- def fund_stock_holding_rank_china(fund,rank=10,year_num=2):
275
+ def fund_stock_holding_rank_china(fund,rank=10,year_num=2, \
276
+ reverse=False,font_size='16px'):
257
277
  """
278
+ 基金的成份股持仓转移矩阵
258
279
  比较股票型基金fund近year_num年持仓的前10大股票排名变化
259
280
  """
260
281
  print("Searching fund stock holding info, which takes time, please wait ...\n")
@@ -373,21 +394,27 @@ def fund_stock_holding_rank_china(fund,rank=10,year_num=2):
373
394
  name=get_fund_name_china2(fund)
374
395
 
375
396
  #print("=== 基金持仓股票排行分析:"+name+",按照占净值比例高低排列 ===\n")
376
- titletxt="基金持仓转移详情:"+name+",按照占净值比例降序排列,前"+str(rank)+"名成份证券"
397
+ titletxt="基金持仓转移矩阵:"+name+"基金,按照占净值比例降序排列,前"+str(rank)+"名重仓股"
377
398
  import datetime; todaydt = datetime.date.today()
378
399
  #print("\n*** 注:包括A股与非A股。持股结构:股票简称(占净值比例%,持股数万股),",str(todaydt))
379
400
  footnote="【注】持仓结构:证券简称(占净值比例%,持仓数万股),"+str(todaydt)+"统计"
380
401
 
381
- #最新的日期方前面
382
- collist=list(df)
383
- collist.sort(reverse=True)
384
- df=df[collist]
402
+ if reverse:
403
+ #最新的日期放前面
404
+ collist=list(df)
405
+ collist.sort(reverse=True)
406
+ df=df[collist]
407
+
408
+ #确定表格字体大小
409
+ titile_font_size=font_size
410
+ heading_font_size=data_font_size=str(int(font_size.replace('px',''))-1)+'px'
385
411
 
386
412
  df_display_CSS(df,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=3, \
387
413
  first_col_align='center',second_col_align='left', \
388
414
  last_col_align='left',other_col_align='left', \
389
- titile_font_size='16px',heading_font_size='15px', \
390
- data_font_size='15px')
415
+ titile_font_size=titile_font_size, \
416
+ heading_font_size=heading_font_size, \
417
+ data_font_size=data_font_size)
391
418
 
392
419
  """
393
420
  alignlist=['center']+['left']*(len(list(df))-1)
siat/markowitz2.py CHANGED
@@ -152,8 +152,12 @@ def cumulative_returns_plot(retgroup,name_list="",titletxt="投资组合策略
152
152
 
153
153
  if xlabeltxt=="":
154
154
  #取出观察期
155
- hstart0=retgroup.index[0]; hstart=str(hstart0.date())
156
- hend0=retgroup.index[-1]; hend=str(hend0.date())
155
+ hstart0=retgroup.index[0]
156
+ #hstart=str(hstart0.date())
157
+ hstart=str(hstart0)
158
+ hend0=retgroup.index[-1]
159
+ #hend=str(hend0.date())
160
+ hend=str(hend0)
157
161
 
158
162
  lang = check_language()
159
163
  import datetime as dt; stoday=dt.date.today()
@@ -227,31 +231,41 @@ def portfolio_hpr(portfolio,thedate,pastyears=1, \
227
231
  if __name__=='__main__':
228
232
  Market={'Market':('US','^GSPC')}
229
233
  Market={'Market':('US','^GSPC','我的组合001')}
230
- Stocks1={'AAPL':.3,'MSFT':.15,'AMZN':.15,'FB':.01,'GOOG':.01}
234
+ Stocks1={'AAPL':.3,'MSFT':.15,'AMZN':.15,'GOOG':.01}
231
235
  Stocks2={'XOM':.02,'JNJ':.02,'JPM':.01,'TSLA':.3,'SBUX':.03}
232
236
  portfolio=dict(Market,**Stocks1,**Stocks2)
233
237
 
234
238
  ticker_name(portfolio)
235
239
 
236
- thedate='2023-2-17'
240
+ portfolio=dict(Market,**Stocks1)
241
+ thedate='2024-5-30'
237
242
  pastyears=1
238
- rate_period='1Y'
239
- rate_type='shibor'
240
- RF=0.01795
241
- printout=True
243
+ printout=True
244
+ graph=True
245
+
246
+ pf_info=portfolio_build(portfolio,'2024-5-30')
242
247
 
243
248
  """
244
249
  def portfolio_cumret(portfolio,thedate,pastyears=1, \
245
250
  RF=0, \
246
251
  printout=True,graph=True):
247
252
  """
248
- def portfolio_build(portfolio,thedate,pastyears=1, \
249
- RF=0, \
250
- printout=True,graph=True):
253
+ def portfolio_build(portfolio,thedate='default',pastyears=1, \
254
+ printout=True,graph=False):
251
255
  """
252
256
  功能:收集投资组合成份股数据,绘制收益率趋势图,并与等权和期间内交易额加权策略组合比较
253
- 注意:使用手动输入RF
257
+ 注意:此处无需RF,待到优化策略时再指定
258
+ printout=True控制获取股价时是否逐个显示
254
259
  """
260
+ import datetime
261
+ stoday = datetime.date.today()
262
+ if thedate=='default':
263
+ thedate=str(stoday)
264
+ else:
265
+ if not check_date(adate):
266
+ print(" #Warning(portfolio_build): invalid date",thedate)
267
+ return None
268
+
255
269
  print("\n Searching for portfolio info, which may take time ...")
256
270
  # 解构投资组合
257
271
  scope,_,tickerlist,sharelist0=decompose_portfolio(portfolio)
@@ -271,13 +285,13 @@ def portfolio_build(portfolio,thedate,pastyears=1, \
271
285
  # 计算历史数据的开始日期
272
286
  start=get_start_date(thedate,pastyears)
273
287
 
274
- #处理无风险利率,根据手动输入的RF构造rf_df以便后续改动量较小
288
+ #处理无风险利率,不再需要,但为兼容考虑仍保留,根据手动输入的RF构造rf_df以便后续改动量较小
275
289
  import pandas as pd
276
- date_series = pd.date_range(start=start, end=thedate, freq='D')
290
+ date_series = pd.date_range(start=start,end=thedate,freq='D')
277
291
  rf_df=pd.DataFrame(index=date_series)
278
292
  rf_df['date']=rf_df.index
279
293
  rf_df['date']=rf_df['date'].apply(lambda x: x.strftime('%Y-%m-%d'))
280
- rf_df['RF']=RF
294
+ rf_df['RF']=RF=0
281
295
  rf_df['rf_daily']=RF/365
282
296
  """
283
297
  #一次性获得无风险利率,传递给后续函数,避免后续每次获取,耗费时间
@@ -308,19 +322,32 @@ def portfolio_build(portfolio,thedate,pastyears=1, \
308
322
  #prices=get_prices(tickerlist,start,thedate)
309
323
 
310
324
  if printout:
311
- prices=get_prices_simple(tickerlist,start,thedate) #有待改造?
325
+ #prices=get_prices_simple(tickerlist,start,thedate) #有待改造?
326
+ #债券优先
327
+ prices,found=get_price_mticker(tickerlist,start,thedate, \
328
+ adjust='',source='auto',ticker_type='bond',fill=False)
312
329
  else:
313
330
  with HiddenPrints():
314
- prices=get_prices_simple(tickerlist,start,thedate) #有待改造?
315
- ntickers=len(list(prices['Close']))
316
- nrecords=len(prices)
331
+ #prices=get_prices_simple(tickerlist,start,thedate) #有待改造?
332
+ prices,found=get_price_mticker(tickerlist,start,thedate, \
333
+ adjust='',source='auto',ticker_type='bond',fill=False)
334
+
335
+ if found == 'Found':
336
+ ntickers=len(list(prices['Close']))
337
+ nrecords=len(prices)
317
338
  #print(" Successfully retrieved",ntickers,"stocks with",nrecords,"record(s) respectively")
318
- print(" Successfully retrieved prices of",ntickers,"stocks for",pname)
339
+ print(" Successfully retrieved prices of",ntickers,"securities for",pname)
340
+
341
+ if ntickers != len(tickerlist):
342
+ print(" However, failed to access some securities, unable to build portfolio",pname)
343
+ return None
319
344
 
320
- if prices is None:
345
+ #if prices is None:
346
+ if found == 'None':
321
347
  print(" #Error(portfolio_build): failed to get portfolio prices",pname)
322
348
  return None
323
- if len(prices) == 0:
349
+ #if len(prices) == 0:
350
+ if found == 'Empty':
324
351
  print(" #Error(portfolio_build): retrieved empty prices for",pname)
325
352
  return None
326
353
  #..........................................................................
@@ -367,9 +394,9 @@ def portfolio_build(portfolio,thedate,pastyears=1, \
367
394
  plt.gca().set_facecolor('whitesmoke')
368
395
 
369
396
  plt.legend(); plt.show(); plt.close()
370
- #..........................................................................
371
-
372
- # 计算原投资组合的持有收益率,并绘图
397
+ #..........................................................................
398
+
399
+ # 计算原投资组合的持有收益率,并绘图
373
400
  name_list=["Portfolio"]
374
401
  label_list=[pname]
375
402
 
@@ -475,8 +502,8 @@ def portfolio_correlate(pf_info):
475
502
  pname=portfolio_name(portfolio)
476
503
 
477
504
  #取出观察期
478
- hstart0=stock_return.index[0]; hstart=str(hstart0.date())
479
- hend0=stock_return.index[-1]; hend=str(hend0.date())
505
+ hstart0=stock_return.index[0]; hstart=str(hstart0)
506
+ hend0=stock_return.index[-1]; hend=str(hend0)
480
507
 
481
508
  sr=stock_return.copy()
482
509
  collist=list(sr)
@@ -523,8 +550,8 @@ def portfolio_covar(pf_info):
523
550
  pname=portfolio_name(portfolio)
524
551
 
525
552
  #取出观察期
526
- hstart0=stock_return.index[0]; hstart=str(hstart0.date())
527
- hend0=stock_return.index[-1]; hend=str(hend0.date())
553
+ hstart0=stock_return.index[0]; hstart=str(hstart0)
554
+ hend0=stock_return.index[-1]; hend=str(hend0)
528
555
 
529
556
  # 计算协方差矩阵
530
557
  cov_mat = stock_return.cov()
@@ -584,8 +611,12 @@ def portfolio_expectation_universal(pname,member_returns,portfolio_weights,membe
584
611
  """
585
612
 
586
613
  #观察期
587
- hstart0=member_returns.index[0]; hstart=str(hstart0.date())
588
- hend0=member_returns.index[-1]; hend=str(hend0.date())
614
+ hstart0=member_returns.index[0]
615
+ #hstart=str(hstart0.date())
616
+ hstart=str(hstart0)
617
+ hend0=member_returns.index[-1]
618
+ #hend=str(hend0.date())
619
+ hend=str(hend0)
589
620
  tickerlist=list(member_returns)
590
621
 
591
622
  #合成投资组合的历史收益率,按行横向加权求和
@@ -623,7 +654,7 @@ def portfolio_expectation_universal(pname,member_returns,portfolio_weights,membe
623
654
  print(" ***投资组合持仓策略***")
624
655
  print_tickerlist_sharelist(tickerlist,portfolio_weights,4)
625
656
 
626
- print(" *来源:Sina/EM/stooq,"+str(stoday))
657
+ print(" *来源:Sina/EM/stooq,"+str(stoday)+"统计")
627
658
  else:
628
659
  print("\n ======= Investment Portfolio: Return and Risk =======")
629
660
  print(" Investment portfolio:",pname)
@@ -703,7 +734,7 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='whitesmoke'):
703
734
  #以pname组合作为基准
704
735
  import numpy as np
705
736
  mean_return_pname=pr[pname].mean(axis=0)
706
- annual_return_pname=round(((1 + mean_return_pname)**252 - 1)*100,2)
737
+ annual_return_pname=round(((1 + mean_return_pname)**252 - 1)*100,4)
707
738
  """
708
739
  if annual_return_pname > 0:
709
740
  pct_style=True #百分比模式
@@ -713,22 +744,23 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='whitesmoke'):
713
744
  pct_style=False
714
745
 
715
746
  std_return_pname=pr[pname].std(axis=0)
716
- annual_std_pname= round((std_return_pname*np.sqrt(252))*100,2)
747
+ annual_std_pname= round((std_return_pname*np.sqrt(252))*100,4)
717
748
 
718
749
  import pandas as pd
719
750
  #prr=pd.DataFrame(columns=["名称","年化收益率","收益率变化","年化标准差","标准差变化","收益/风险"])
720
- prr=pd.DataFrame(columns=["名称","年化收益率%","收益率变化","年化标准差%","标准差变化","收益/风险"])
751
+ #prr=pd.DataFrame(columns=["名称","年化收益率%","收益率变化","年化标准差%","标准差变化","收益/风险"])
752
+ prr=pd.DataFrame(columns=["名称","年化收益率%","收益率变化","年化标准差%","标准差变化","收益率/标准差"])
721
753
  cols=list(pr)
722
754
  for c in cols:
723
755
 
724
756
  #年化收益率:按列求均值
725
757
  mean_return=pr[c].mean(axis=0)
726
- annual_return = round(((1 + mean_return)**252 - 1)*100,2)
758
+ annual_return = round(((1 + mean_return)**252 - 1)*100,4)
727
759
 
728
760
  if pct_style:
729
- return_chg=round((annual_return - annual_return_pname) / annual_return_pname * 100,2)
761
+ return_chg=round((annual_return - annual_return_pname) / annual_return_pname * 100,4)
730
762
  else:
731
- return_chg=round((annual_return - annual_return_pname),2)
763
+ return_chg=round((annual_return - annual_return_pname),4)
732
764
 
733
765
  #收益率变化
734
766
  if return_chg==0:
@@ -746,14 +778,15 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='whitesmoke'):
746
778
 
747
779
  #年化标准差
748
780
  std_return=pr[c].std(axis=0)
749
- annual_std = round((std_return*np.sqrt(252))*100,2)
781
+ annual_std = round((std_return*np.sqrt(252))*100,4)
750
782
 
751
- sharpe_ratio=round(annual_return / annual_std,2)
783
+ #sharpe_ratio=round(annual_return / annual_std,2)
784
+ sharpe_ratio=round((annual_return) / annual_std,4)
752
785
 
753
786
  if pct_style:
754
- std_chg=round((annual_std - annual_std_pname) / annual_std_pname * 100,1)
787
+ std_chg=round((annual_std - annual_std_pname) / annual_std_pname * 100,4)
755
788
  else:
756
- std_chg=round((annual_std - annual_std_pname),2)
789
+ std_chg=round((annual_std - annual_std_pname),4)
757
790
 
758
791
  #标准差变化
759
792
  if std_chg==0:
@@ -771,7 +804,7 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='whitesmoke'):
771
804
 
772
805
  row=pd.Series({"名称":c,"年化收益率%":annual_return, \
773
806
  "收益率变化":return_chg_str, \
774
- "年化标准差%":annual_std,"标准差变化":std_chg_str,"收益/风险":sharpe_ratio})
807
+ "年化标准差%":annual_std,"标准差变化":std_chg_str,"收益率/标准差":sharpe_ratio})
775
808
  try:
776
809
  prr=prr.append(row,ignore_index=True)
777
810
  except:
@@ -790,7 +823,7 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='whitesmoke'):
790
823
  #prr2=prr[["名称","收益排名","风险排名","年化收益率","年化标准差","收益率变化","标准差变化","收益/风险"]]
791
824
  prr2=prr[["名称","收益排名","年化收益率%","收益率变化", \
792
825
  "风险排名","年化标准差%","标准差变化", \
793
- "收益/风险"]]
826
+ "收益率/标准差"]]
794
827
  prr2.sort_values(by="年化收益率%",ascending=False,inplace=True)
795
828
  #prr2.reset_index(inplace=True)
796
829
 
@@ -816,7 +849,7 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='whitesmoke'):
816
849
  prr2.rename(columns={'名称':'投资组合名称/策略'},inplace=True)
817
850
  for c in list(prr2):
818
851
  try:
819
- prr2[c]=prr2[c].apply(lambda x: str(round(x,2)) if isinstance(x,float) else str(x))
852
+ prr2[c]=prr2[c].apply(lambda x: str(round(x,4)) if isinstance(x,float) else str(x))
820
853
  except: pass
821
854
 
822
855
  titletxt='投资组合策略排名:平衡收益与风险'
@@ -829,6 +862,14 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='whitesmoke'):
829
862
  from IPython.display import display
830
863
  display(dispf)
831
864
  """
865
+
866
+ df_display_CSS(prr2,titletxt=titletxt,footnote='',facecolor='papayawhip',decimals=4, \
867
+ first_col_align='left',second_col_align='center', \
868
+ last_col_align='right',other_col_align='right', \
869
+ titile_font_size='16px',heading_font_size='15px', \
870
+ data_font_size='15px')
871
+
872
+ """
832
873
  print(' ') #空一行
833
874
 
834
875
  disph=prr2.style.hide() #不显示索引列
@@ -853,7 +894,7 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='whitesmoke'):
853
894
  display(dispf2)
854
895
 
855
896
  print('') #空一行
856
-
897
+ """
857
898
  return prr2
858
899
 
859
900
  if __name__=='__main__':
@@ -910,12 +951,12 @@ def portfolio_ranks_en(portfolio_returns,pname):
910
951
  std_return=pr[c].std(axis=0)
911
952
  annual_std = std_return*np.sqrt(252)
912
953
 
913
- sharpe_ratio=round(annual_return / annual_std,2)
954
+ sharpe_ratio=round(annual_return / annual_std,4)
914
955
 
915
956
  if pct_style:
916
- std_chg=round((annual_std - annual_std_pname) / annual_std_pname *100,1)
957
+ std_chg=round((annual_std - annual_std_pname) / annual_std_pname *100,4)
917
958
  else:
918
- std_chg=round((annual_std - annual_std_pname),5)
959
+ std_chg=round((annual_std - annual_std_pname),4)
919
960
  if std_chg==0:
920
961
  std_chg_str="base"
921
962
  elif std_chg > 0:
@@ -982,8 +1023,8 @@ def portfolio_eset(pf_info,simulation=50000):
982
1023
  _,_,tickerlist,_=decompose_portfolio(portfolio)
983
1024
 
984
1025
  #取出观察期
985
- hstart0=stock_return.index[0]; hstart=str(hstart0.date())
986
- hend0=stock_return.index[-1]; hend=str(hend0.date())
1026
+ hstart0=stock_return.index[0]; hstart=str(hstart0)
1027
+ hend0=stock_return.index[-1]; hend=str(hend0)
987
1028
 
988
1029
  #获得成份股个数
989
1030
  numstocks=len(tickerlist)
@@ -1098,8 +1139,8 @@ def portfolio_es_sharpe(pf_info,simulation=1000,RF=0):
1098
1139
  scope,_,tickerlist,_=decompose_portfolio(portfolio)
1099
1140
 
1100
1141
  #取出观察期
1101
- hstart0=stock_return0.index[0]; hstart=str(hstart0.date())
1102
- hend0=stock_return0.index[-1]; hend=str(hend0.date())
1142
+ hstart0=stock_return0.index[0]; hstart=str(hstart0)
1143
+ hend0=stock_return0.index[-1]; hend=str(hend0)
1103
1144
 
1104
1145
  import pandas as pd
1105
1146
  #处理无风险利率
@@ -1192,8 +1233,8 @@ def portfolio_es_sortino(pf_info,simulation=1000,RF=0):
1192
1233
  scope,_,tickerlist,_=decompose_portfolio(portfolio)
1193
1234
 
1194
1235
  #取出观察期
1195
- hstart0=stock_return0.index[0]; hstart=str(hstart0.date())
1196
- hend0=stock_return0.index[-1]; hend=str(hend0.date())
1236
+ hstart0=stock_return0.index[0]; hstart=str(hstart0)
1237
+ hend0=stock_return0.index[-1]; hend=str(hend0)
1197
1238
 
1198
1239
  import pandas as pd
1199
1240
  #处理无风险利率
@@ -1292,8 +1333,8 @@ def portfolio_es_alpha(pf_info,simulation=1000,RF=0):
1292
1333
  scope,mktidx,tickerlist,_=decompose_portfolio(portfolio)
1293
1334
 
1294
1335
  #取出观察期
1295
- hstart0=stock_return0.index[0]; hstart=str(hstart0.date())
1296
- hend0=stock_return0.index[-1]; hend=str(hend0.date())
1336
+ hstart0=stock_return0.index[0]; hstart=str(hstart0)
1337
+ hend0=stock_return0.index[-1]; hend=str(hend0)
1297
1338
 
1298
1339
  #计算市场指数的收益率
1299
1340
  import pandas as pd
@@ -1408,8 +1449,8 @@ def portfolio_es_treynor(pf_info,simulation=1000,RF=0):
1408
1449
  scope,mktidx,tickerlist,_=decompose_portfolio(portfolio)
1409
1450
 
1410
1451
  #取出观察期
1411
- hstart0=stock_return0.index[0]; hstart=str(hstart0.date())
1412
- hend0=stock_return0.index[-1]; hend=str(hend0.date())
1452
+ hstart0=stock_return0.index[0]; hstart=str(hstart0)
1453
+ hend0=stock_return0.index[-1]; hend=str(hend0)
1413
1454
 
1414
1455
  #计算市场指数的收益率
1415
1456
  import pandas as pd
@@ -1588,6 +1629,31 @@ def RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
1588
1629
 
1589
1630
  return
1590
1631
  #==============================================================================
1632
+ #==============================================================================
1633
+ if __name__=='__main__':
1634
+ pname="MSR组合"
1635
+ modify_portfolio_name(pname)
1636
+
1637
+ def modify_portfolio_name(pname):
1638
+ """
1639
+ 功能:将原来的类似于MSR组合修改为更易懂的名称,仅供打印时使用
1640
+ """
1641
+ pclist=['等权重组合','交易额加权组合','MSR组合','GMVS组合','MSO组合','GML组合', \
1642
+ 'MAR组合','GMBA组合', 'MTR组合','GMBT组合']
1643
+
1644
+ pclist1=['等权重组合','交易额加权组合', \
1645
+ '最佳夏普比率组合(MSR)','夏普比率最小风险组合(GMVS)', \
1646
+ '最佳索替诺比率组合(MSO)','索替诺比率最小风险组合(GML)', \
1647
+ '最佳阿尔法指标组合(MAR)','阿尔法指标最小风险组合(GMBA)', \
1648
+ '最佳特雷诺比率组合(MTR)','特雷诺比率最小风险组合(GMBT)']
1649
+
1650
+ if pname not in pclist:
1651
+ return pname
1652
+
1653
+ pos=pclist.index(pname)
1654
+
1655
+ return pclist1[pos]
1656
+
1591
1657
  #==============================================================================
1592
1658
  def cvt_portfolio_name(pname,portfolio_returns):
1593
1659
  """
@@ -1601,8 +1667,16 @@ def cvt_portfolio_name(pname,portfolio_returns):
1601
1667
 
1602
1668
  lang=check_language()
1603
1669
  if lang == "Chinese":
1670
+ """
1604
1671
  pclist=[pname,'等权重组合','交易额加权组合','MSR组合','GMVS组合','MSO组合','GML组合', \
1605
1672
  'MAR组合','GMBA组合', 'MTR组合','GMBT组合']
1673
+ """
1674
+ pclist=[pname,'等权重组合','交易额加权组合', \
1675
+ '最佳夏普比率组合(MSR)','夏普比率最小风险组合(GMVS)', \
1676
+ '最佳索替诺比率组合(MSO)','索替诺比率最小风险组合(GML)', \
1677
+ '最佳阿尔法指标组合(MAR)','阿尔法指标最小风险组合(GMBA)', \
1678
+ '最佳特雷诺比率组合(MTR)','特雷诺比率最小风险组合(GMBT)']
1679
+
1606
1680
  else:
1607
1681
  pclist=[pname,'Equal-weight','Amount-weight','MSR','GMVS','MSO','GML', \
1608
1682
  'MAR','GMBA', 'MTR','GMBT']
@@ -1621,7 +1695,7 @@ def cvt_portfolio_name(pname,portfolio_returns):
1621
1695
 
1622
1696
  #==============================================================================
1623
1697
 
1624
- def portfolio_optimize_sharpe(es_info,RF=0,graph=True):
1698
+ def portfolio_optimize_sharpe(es_info,graph=True):
1625
1699
  """
1626
1700
  功能:计算投资组合的最高夏普比率组合,并绘图
1627
1701
  MSR: Maximium Sharpe Rate, 最高夏普指数方案
@@ -1697,7 +1771,7 @@ if __name__=='__main__':
1697
1771
 
1698
1772
  #==============================================================================
1699
1773
 
1700
- def portfolio_optimize_sortino(es_info,RF=0,graph=True):
1774
+ def portfolio_optimize_sortino(es_info,graph=True):
1701
1775
  """
1702
1776
  功能:计算投资组合的最高索替诺比率组合,并绘图
1703
1777
  MSO: Maximium Sortino ratio, 最高索替诺比率方案
@@ -1745,7 +1819,7 @@ if __name__=='__main__':
1745
1819
 
1746
1820
  #==============================================================================
1747
1821
 
1748
- def portfolio_optimize_alpha(es_info,RF=0,graph=True):
1822
+ def portfolio_optimize_alpha(es_info,graph=True):
1749
1823
  """
1750
1824
  功能:计算投资组合的最高詹森阿尔法组合,并绘图
1751
1825
  MAR: Maximium Alpha Ratio, 最高阿尔法指数方案
@@ -1791,7 +1865,7 @@ if __name__=='__main__':
1791
1865
 
1792
1866
  #==============================================================================
1793
1867
 
1794
- def portfolio_optimize_treynor(es_info,RF=0,graph=True):
1868
+ def portfolio_optimize_treynor(es_info,graph=True):
1795
1869
  """
1796
1870
  功能:计算投资组合的最高特雷诺比率组合,并绘图
1797
1871
  MTR: Maximium Treynor Ratio, 最高特雷诺指数方案
@@ -1851,8 +1925,8 @@ def portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk,
1851
1925
  pname=portfolio_name(portfolio)
1852
1926
 
1853
1927
  #取出观察期
1854
- hstart0=StockReturns.index[0]; hstart=str(hstart0.date())
1855
- hend0=StockReturns.index[-1]; hend=str(hend0.date())
1928
+ hstart0=StockReturns.index[0]; hstart=str(hstart0)
1929
+ hend0=StockReturns.index[-1]; hend=str(hend0)
1856
1930
 
1857
1931
  #识别并计算指数..........................................................
1858
1932
  if col_ratio in ['Alpha']:
@@ -1932,12 +2006,16 @@ if __name__=='__main__':
1932
2006
  ratio='treynor'
1933
2007
  simulation=1000
1934
2008
  simulation=50000
2009
+
2010
+ RF=0
2011
+ graph=True;hirar_return=False;lorisk=True
1935
2012
 
1936
- def portfolio_optimize(pf_info,ratio='sharpe',simulation=50000,RF=0, \
1937
- graph=True,MSR_return=False,GMVS=True):
2013
+ def portfolio_optimize(pf_info,ratio='sharpe',simulation=10000,RF=0, \
2014
+ graph=True,hirar_return=False,lorisk=True):
1938
2015
  """
1939
2016
  功能:集成式投资组合优化策略
1940
- 注意:实验发现RF对于结果的影响极其微小难以观察,默认设为不使用无风险利率调整收益
2017
+ 注意:实验发现RF较小时对于结果的影响极其微小难以观察,默认设为不使用无风险利率调整收益
2018
+ 但RF较大时对于结果的影响明显变大,已经不能忽略!
1941
2019
  """
1942
2020
 
1943
2021
  ratio_list=['treynor','sharpe','sortino','alpha']
@@ -1956,11 +2034,16 @@ def portfolio_optimize(pf_info,ratio='sharpe',simulation=50000,RF=0, \
1956
2034
  es_info=eval(func_es)(pf_info=pf_info,simulation=simulation,RF=RF)
1957
2035
 
1958
2036
 
1959
- #寻找比率最优点:最大夏普比率策略MSR和最小风险策略GMV
2037
+ #寻找比率最优点:最大比率策略和最小风险策略
1960
2038
  func_optimize="portfolio_optimize_"+ratio
2039
+ """
1961
2040
  name_hiret,hiret_weights,name_lorisk,lorisk_weights,portfolio_returns= \
1962
2041
  eval(func_optimize)(es_info=es_info,RF=RF,graph=graph)
1963
-
2042
+ """
2043
+ name_hiret,hiret_weights,name_lorisk,lorisk_weights,portfolio_returns= \
2044
+ eval(func_optimize)(es_info=es_info,graph=graph)
2045
+
2046
+
1964
2047
  lang = check_language()
1965
2048
  if lang == 'Chinese':
1966
2049
  zhuhe_txt='组合'
@@ -1974,11 +2057,11 @@ def portfolio_optimize(pf_info,ratio='sharpe',simulation=50000,RF=0, \
1974
2057
  ylabeltxt="Holding Return"
1975
2058
 
1976
2059
  #打印投资组合构造和业绩表现
1977
- hi_name=name_hiret+zhuhe_txt
1978
- lo_name=name_lorisk+zhuhe_txt
2060
+ hi_name=modify_portfolio_name(name_hiret+zhuhe_txt)
2061
+ lo_name=modify_portfolio_name(name_lorisk+zhuhe_txt)
1979
2062
  portfolio_expectation(hi_name,pf_info,hiret_weights)
1980
2063
 
1981
- if MSR_return:
2064
+ if hirar_return:
1982
2065
  scope,mktidx,tickerlist,_=decompose_portfolio(portfolio)
1983
2066
  hwdf=pd.DataFrame(hiret_weights)
1984
2067
  hwdft=hwdf.T
@@ -1993,7 +2076,7 @@ def portfolio_optimize(pf_info,ratio='sharpe',simulation=50000,RF=0, \
1993
2076
  Market={'Market':(scope,mktidx,pname)}
1994
2077
  portfolio_new=dict(Market,**stocks_new)
1995
2078
 
1996
- if GMVS:
2079
+ if lorisk:
1997
2080
  portfolio_expectation(lo_name,pf_info,lorisk_weights)
1998
2081
 
1999
2082
  #现有投资组合的排名
@@ -2011,7 +2094,7 @@ def portfolio_optimize(pf_info,ratio='sharpe',simulation=50000,RF=0, \
2011
2094
  if graph:
2012
2095
  portfolio_expret_plot(portfolio_returns,name_list,titletxt=titletxt,ylabeltxt=ylabeltxt)
2013
2096
 
2014
- if MSR_return:
2097
+ if hirar_return:
2015
2098
  return portfolio_new
2016
2099
  else:
2017
2100
  return
siat/sector_china.py CHANGED
@@ -3033,38 +3033,149 @@ def industry_scan_china(sw_level='F', \
3033
3033
 
3034
3034
  return df2
3035
3035
 
3036
+
3037
+ #==============================================================================
3038
+ if __name__=='__main__':
3039
+ ticker='600791.SS'
3040
+ ticker='东阿阿胶'
3041
+
3042
+ contains_chinese(ticker)
3043
+
3044
+ def contains_chinese(text):
3045
+ """
3046
+ 功能:判断字符串是否含有汉字
3047
+ """
3048
+ import re
3049
+ return re.search(r'[\u4e00-\u9fff]', text) is not None
3050
+
3036
3051
  #==============================================================================
3037
3052
  if __name__=='__main__':
3038
3053
  ticker='600791.SS'
3054
+
3055
+ ticker=['600791.SS','东阿阿胶']
3056
+ level='1'
3057
+
3039
3058
  find_industry_sw(ticker)
3040
3059
 
3041
- def find_industry_sw(ticker):
3060
+ def find_industry_sw(ticker,level='1',ticker_order=True):
3042
3061
  """
3043
- 功能:寻找一只股票所属的申万行业,细分行业
3062
+ 功能:寻找一只股票所属的申万行业
3044
3063
  """
3045
- ticker6=ticker[:6]
3064
+ print(" Searching shenwan industries for securities ... ...")
3065
+
3066
+ if isinstance(ticker,str):
3067
+ ticker=[ticker]
3068
+
3069
+ tickerlist=[]
3070
+ for t in ticker:
3071
+ if not contains_chinese(t):
3072
+ tt=t[:6]
3073
+ tickerlist=tickerlist+[tt]
3074
+ else:
3075
+ tickerlist=tickerlist+[t]
3046
3076
 
3047
3077
  import akshare as ak
3048
- #df3 = ak.sw_index_third_info()
3049
- df2 = ak.sw_index_second_info()
3050
- df2['industry_code']=df2['行业代码'].apply(lambda x: x[:6])
3051
- industry_list=list(df2['industry_code'])
3078
+ if level == '3':
3079
+ df = ak.sw_index_third_info()
3080
+ elif level == '2':
3081
+ df = ak.sw_index_second_info()
3082
+ else:
3083
+ df = ak.sw_index_first_info()
3084
+
3085
+ df['industry_code']=df['行业代码'].apply(lambda x: x[:6])
3086
+ industry_list=list(df['industry_code'])
3087
+
3088
+ import pandas as pd; import random; import time
3089
+ result=pd.DataFrame(columns=['序号','证券名称','证券代码','行业名称','行业代码'])
3052
3090
 
3053
3091
  for i in industry_list:
3054
- cdf = ak.index_component_sw(i)
3055
- component_list=list(cdf)
3092
+ print_progress_percent2(i,industry_list,steps=10,leading_blanks=2)
3093
+
3094
+ iname=df[df['industry_code']==i]['行业名称'].values[0]
3095
+
3096
+ try:
3097
+ cdf = ak.index_component_sw(i)
3098
+ except:
3099
+ print(" #Warning(find_industry_sw): server banned this ip becos of too many requests")
3100
+ print(" Solution: change to another ip or another computer, or try a few hours later.")
3101
+ return
3102
+ """
3103
+ component_list=list(cdf['证券代码'])
3056
3104
 
3057
3105
  if ticker6 in component_list:
3058
3106
  stock_name=cdf[cdf["证券代码"]==ticker6]['证券名称'].values[0]
3059
- print("股票:",ticker,",",stock_name)
3107
+ print("\n\n股票代码:"+ticker+","+stock_name)
3060
3108
 
3061
3109
  isi=i+'.SI'
3062
- industry_name=df3[df3[行业代码]==isi]['行业名称'].values[0]
3063
- print("申万三级行业代码:",i+".SW",",",industry_name)
3110
+ industry_name=df[df['行业代码']==isi]['行业名称'].values[0]
3111
+ print("申万"+str(level)+"级行业代码:"+i+".SW,"+industry_name)
3064
3112
 
3065
3113
  break
3114
+ """
3115
+ for t in tickerlist:
3116
+ torder=tickerlist.index(t)+1
3117
+
3118
+ if not contains_chinese(t):
3119
+ dft=cdf[cdf['证券代码']==t]
3120
+ if len(dft)==0: continue
3121
+ else:
3122
+ tname=cdf[cdf['证券代码']==t]['证券名称'].values[0]
3123
+ s=pd.Series({'序号':torder,'证券名称':tname,'证券代码':t,'行业名称':iname,'行业代码':i})
3124
+ try:
3125
+ result=result.append(s,ignore_index=True)
3126
+ except:
3127
+ result=result._append(s,ignore_index=True)
3128
+ else:
3129
+ dft=cdf[cdf['证券名称']==t]
3130
+ if len(dft)==0: continue
3131
+ else:
3132
+ tcode=cdf[cdf['证券名称']==t]['证券代码'].values[0]
3133
+ s=pd.Series({'序号':torder,'证券名称':t,'证券代码':tcode,'行业名称':iname,'行业代码':i})
3134
+ try:
3135
+ result=result.append(s,ignore_index=True)
3136
+ except:
3137
+ result=result._append(s,ignore_index=True)
3138
+
3139
+ #是否都找到了?
3140
+ if len(result) == len(tickerlist): break
3066
3141
 
3067
- return
3142
+ #生成随机数睡眠,试图防止被反爬虫,不知是否管用!
3143
+ random_int=random.randint(1,5)
3144
+ time.sleep(random_int)
3145
+
3146
+ #排序
3147
+ if not ticker_order:
3148
+ #按行业代码排序
3149
+ result.sort_values(by='行业代码',inplace=True)
3150
+ else:
3151
+ #按ticker顺序排序
3152
+ result.sort_values(by='序号',inplace=True)
3153
+ """
3154
+ if contains_chinese(tickerlist[0]):
3155
+ result.sort_values(by='证券名称',key=lambda x: x.map(dict(zip(tickerlist,range(len(tickerlist))))))
3156
+ else:
3157
+ result.sort_values(by='证券代码',key=lambda x: x.map(dict(zip(tickerlist,range(len(tickerlist))))))
3158
+ """
3159
+ #result.reset_index(drop=True,inplace=True)
3160
+
3161
+ #显示结果
3162
+ titletxt="证券所属行业:申万"+str(level)+"级行业"
3163
+ import datetime; todaydt = datetime.date.today()
3164
+ footnote="数据来源:申万宏源,"+str(todaydt)+"统计"
3165
+ """
3166
+ collist=list(result)
3167
+ result['序号']=result.index+1
3168
+ result=result[['序号']+collist]
3169
+ """
3170
+ print('')
3171
+ df_display_CSS(result,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=2, \
3172
+ first_col_align='center',second_col_align='left', \
3173
+ last_col_align='left',other_col_align='left', \
3174
+ titile_font_size='16px',heading_font_size='15px', \
3175
+ data_font_size='15px')
3176
+
3177
+ return result
3178
+
3068
3179
  #==============================================================================
3069
3180
  #==============================================================================
3070
3181
  #==============================================================================
siat/stock_technical.py CHANGED
@@ -2009,7 +2009,7 @@ def security_bollinger(ticker,fromdate,todate,boll_days=20, \
2009
2009
  print(" #Error(security_bollinger): price info not found for",ticker)
2010
2010
  return None
2011
2011
  if found not in ['Found']:
2012
- print(" #Error(): ticker info either inaccessible or not found for",ticker)
2012
+ print(" #Error(security_bollinger): ticker info either inaccessible or not found for",ticker)
2013
2013
  return None
2014
2014
 
2015
2015
  # 滚动均值与标准差
@@ -2045,7 +2045,7 @@ def security_bollinger(ticker,fromdate,todate,boll_days=20, \
2045
2045
  data_label=False,resample_freq='6H',smooth=smooth, \
2046
2046
  date_range=date_range,date_freq=date_freq,date_fmt='%Y-%m-%d', \
2047
2047
  colorlist=colorlist,lslist=lslist,lwlist=lwlist, \
2048
- band_area=['上(压力)线','下(支撑)线'],mark_end=mark_end)
2048
+ band_area=['上(压力)线','下(支撑)线'],mark_end=mark_end,loc=loc)
2049
2049
 
2050
2050
  return df1
2051
2051
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: siat
3
- Version: 3.1.6
3
+ Version: 3.1.12
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
@@ -52,7 +52,7 @@ siat/financials_test.py,sha256=HJ3CPo_Xckz2wXi3AEP6ZNWCF1Duc1pLi0Y10USiImc,23829
52
52
  siat/fred_test.py,sha256=KF50ssSbsfpa_kT6iuomD0vG4eXztAcOasZxg1OGX5w,1201
53
53
  siat/fund.py,sha256=wMDORsCBV8ZXfgwbtq-0bu3qqWY66dHnbqgllW0gWCo,24637
54
54
  siat/fund_china.pickle,sha256=QI3IjV46EeJ5ryO3xocmByc-6b_6_nDxgcXDhBHzop0,2380915
55
- siat/fund_china.py,sha256=Sa9_s1A_dTT_sBu_pYYw2WaNZF0MIrNy-5X2FO4Lm00,97528
55
+ siat/fund_china.py,sha256=5ZgF4G9GFQa7hPufqol-qDg_EZj8CtmYd0UR9L2zIDI,99025
56
56
  siat/fund_china_test.py,sha256=-Bh6m0J0GPpIbYXx-H2vpzJoNFI6pE2C2jVPa8DazgE,6649
57
57
  siat/fund_test.py,sha256=V4ADb8Gsp8gyeFTwcgRsJBpnUih_O-Q2V1ILc5oKjK8,1116
58
58
  siat/future_china.py,sha256=F-HsIf2Op8Z22RzTjet1g8COzldgnMjFNSXsAkeGyWo,17595
@@ -66,7 +66,7 @@ siat/holding_risk_test.py,sha256=FRlw_9wFG98BYcg_cSj95HX5WZ1TvkGaOUdXD7-V86s,474
66
66
  siat/local_debug_test.py,sha256=CDAOffW1Rvs-TcNN5giWVvHMlch1w4dp-w5SIV9jXL0,3936
67
67
  siat/market_china.py,sha256=nabx24qm7N51OafTrwUw542pNeFJ3JaQ1wqyv-nLN5I,37883
68
68
  siat/markowitz.py,sha256=c06gCRhMABnrb30F-npJsKVv8nFfEoNNR3bzrkMCyGg,97406
69
- siat/markowitz2.py,sha256=dBjxbb4K3jQkehzNLj8lQQXmkSAgE8Zs5_wDZLLvaEM,100759
69
+ siat/markowitz2.py,sha256=r8lqLhp0MrswkaPeLMEQvk4b5qC_Wc8U04PlJ45Y9o4,104269
70
70
  siat/markowitz_ccb_test.py,sha256=xBkkoaNHdq9KSUrNuHGgKTdNYUvgi84kNYcf719eoyE,1593
71
71
  siat/markowitz_ef_test.py,sha256=wjNlICkgRIqnonPeSIHo4Mu2GRtb9dr21wDt2kMNEcI,4032
72
72
  siat/markowitz_old.py,sha256=Lf7O_4QWT8RsdkHiUyc_7kKY3eZjKDtFR89Fz3pwYnY,33046
@@ -91,7 +91,7 @@ siat/risk_evaluation.py,sha256=I6B3gty-t--AkDCO0tKF-291YfpnF-IkXcFjqNKCt9I,76286
91
91
  siat/risk_evaluation_test.py,sha256=YEXM96gKzTfwN4U61AS4Rr1tV7KgUvn4rRC6f3iMw9s,3731
92
92
  siat/risk_free_rate.py,sha256=ZMr4cHikPvXvywr54gGqiI3Nvb69am6tq3zj2hwzANE,12384
93
93
  siat/risk_free_rate_test.py,sha256=CpmhUf8aEAEZeNu4gvWP2Mz2dLoIgBX5bI41vfUBEr8,4285
94
- siat/sector_china.py,sha256=zbN8MdQJi84femJFB9vxu1XgfPPCWGH7SPV44EjZCNI,113475
94
+ siat/sector_china.py,sha256=o8t4amM6NKGwYiT4N1Vqb3UdDpky_JY_jQwL-Q2Ygd8,117754
95
95
  siat/sector_china_test.py,sha256=1wq7ef8Bb_L8F0h0W6FvyBrIcBTEbrTV7hljtpj49U4,5843
96
96
  siat/security_price.py,sha256=2oHskgiw41KMGfqtnA0i2YjNNV6cYgtlUK0j3YeuXWs,29185
97
97
  siat/security_price2.py,sha256=kuYh0V5cqclkM6MjZUd-N361fv3oxGVVerYINuTzZrE,24622
@@ -112,7 +112,7 @@ siat/stock_list_china_test.py,sha256=gv14UwMMvkZqtb6G7DCTSuehIwVHuVwu7w60p6gyHoo
112
112
  siat/stock_prices_kneighbors.py,sha256=WfZvo5EyeBsm-T37zDj7Sl9dPSRq5Bx4JxIJ9IUum6s,36738
113
113
  siat/stock_prices_linear.py,sha256=-OUKRr27L2aStQgJSlJOrJ4gay_G7P-m-7t7cU2Yoqk,13991
114
114
  siat/stock_profile.py,sha256=B3eIwzEmiCqiCaxIlhfdEPsQBoW1PFOe1hkiY3mVF6Y,26038
115
- siat/stock_technical.py,sha256=c9kv_ih1BxxBGk2bcfkFUfKxy3I4_1jNFfoYMk-j0gY,112833
115
+ siat/stock_technical.py,sha256=YGfvsV5Uu9xaZgJO7dwl1FsvszwX3jsGyJxqJgNamQk,112859
116
116
  siat/stock_test.py,sha256=E9YJAvOw1VEGJSDI4IZuEjl0tGoisOIlN-g9UqA_IZE,19475
117
117
  siat/stooq.py,sha256=dOc_S5HLrYg48YAKTCs1eX8UTJOOkPM8qLL2KupqlLY,2470
118
118
  siat/temp.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
@@ -132,7 +132,7 @@ siat/valuation.py,sha256=NKfeZMdDJOW42oLVHob6eSVBXUqlN1OCnnzwyGAst8c,48855
132
132
  siat/valuation_china.py,sha256=Tde2LzPDQy3Z7xOQQDw4ckQMPdROp_z0-GjFE6Z5_lI,67639
133
133
  siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
134
134
  siat/var_model_validation.py,sha256=f-oDewg7bPzyNanz_Y_jLH68NowAA3gXFehW_weKGG0,14898
135
- siat-3.1.6.dist-info/METADATA,sha256=7I1oTuPz1RUF3cmw1c0t_zAdexvckE9P8x9U5sCp16c,1447
136
- siat-3.1.6.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
137
- siat-3.1.6.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
138
- siat-3.1.6.dist-info/RECORD,,
135
+ siat-3.1.12.dist-info/METADATA,sha256=rgKgLVsy_yr30SZbLNHZCCzjVMz2_TOVSuGIV2HVOAM,1448
136
+ siat-3.1.12.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
137
+ siat-3.1.12.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
138
+ siat-3.1.12.dist-info/RECORD,,
File without changes