siat 3.4.37__py3-none-any.whl → 3.5.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- siat/common.py +230 -0
- siat/fund_china.py +5 -2
- siat/grafix.py +15 -2
- siat/risk_adjusted_return2.py +50 -40
- siat/sector_china.py +351 -114
- siat/security_price2.py +1 -0
- siat/security_prices.py +44 -11
- siat/security_trend2.py +17 -8
- siat/stock.py +88 -36
- siat/stock_technical.py +6 -6
- siat/translate.py +411 -161
- siat/translate_241003_keep.py +4300 -0
- siat/valuation.py +21 -7
- siat/valuation_china.py +54 -18
- {siat-3.4.37.dist-info → siat-3.5.2.dist-info}/METADATA +1 -1
- {siat-3.4.37.dist-info → siat-3.5.2.dist-info}/RECORD +19 -18
- {siat-3.4.37.dist-info → siat-3.5.2.dist-info}/WHEEL +1 -1
- {siat-3.4.37.dist-info → siat-3.5.2.dist-info}/LICENSE +0 -0
- {siat-3.4.37.dist-info → siat-3.5.2.dist-info}/top_level.txt +0 -0
siat/common.py
CHANGED
@@ -4126,6 +4126,236 @@ def firstLetterUpper(text):
|
|
4126
4126
|
return utext
|
4127
4127
|
|
4128
4128
|
#==============================================================================
|
4129
|
+
if __name__ == '__main__':
|
4130
|
+
string = "Hello, Welcome to this New World!"
|
4131
|
+
words = ["Hello", "World"]
|
4132
|
+
|
4133
|
+
contains_any(string, words)
|
4134
|
+
|
4135
|
+
def contains_any(string, words):
|
4136
|
+
# 定义一个函数,检查字符串string是否包含列表words中的任何元素
|
4137
|
+
return any(word in string for word in words)
|
4138
|
+
|
4139
|
+
#==============================================================================
|
4140
|
+
if __name__ == '__main__':
|
4141
|
+
swcy = ['宁德时代(300750.SZ)',
|
4142
|
+
'东方财富(300059.SZ)',
|
4143
|
+
'阳光电源(300274.SZ)',
|
4144
|
+
'迈瑞医疗(300760.SZ)',
|
4145
|
+
'中际旭创(300308.SZ)',
|
4146
|
+
'汇川技术(300124.SZ)',
|
4147
|
+
'温氏股份(300498.SZ)',
|
4148
|
+
'新易盛(300502.SZ)',
|
4149
|
+
'爱尔眼科(300015.SZ)',
|
4150
|
+
'亿纬锂能(300014.SZ)',
|
4151
|
+
'三环集团(300408.SZ)',
|
4152
|
+
'智飞生物(300122.SZ)',
|
4153
|
+
'同花顺(300033.SZ)',]
|
4154
|
+
sw50 = ['贵州茅台(600519.SS)',
|
4155
|
+
'宁德时代(300750.SZ)',
|
4156
|
+
'中国平安(601318.SS)',
|
4157
|
+
'美的集团(000333.SZ)',
|
4158
|
+
'招商银行(600036.SS)',
|
4159
|
+
'五粮液(000858.SZ)',
|
4160
|
+
'紫金矿业(601899.SS)',
|
4161
|
+
'比亚迪(002594.SZ)',
|
4162
|
+
'中信证券(600030.SS)',
|
4163
|
+
'东方财富(300059.SZ)',]
|
4164
|
+
lists=[swcy,sw50]
|
4165
|
+
|
4166
|
+
list2_intersection(swcy,sw50)
|
4167
|
+
|
4168
|
+
def list2_intersection(list1,list2):
|
4169
|
+
#寻找两个列表的共同元素
|
4170
|
+
result=[]
|
4171
|
+
for i in list1:
|
4172
|
+
if i in list2:
|
4173
|
+
result=result+[i]
|
4174
|
+
|
4175
|
+
return result
|
4176
|
+
|
4177
|
+
if __name__ == '__main__':
|
4178
|
+
list1 = [1,2,3,4,5,6,7,8,9,10]
|
4179
|
+
list2 = [4,5,6,7,8,9,10,11,12]
|
4180
|
+
list3 = [5,6,7,8,9,10,11,12,13]
|
4181
|
+
|
4182
|
+
lists = [list1,list2,list3]
|
4183
|
+
numberPerLine=5; printout=True; return_result=False
|
4184
|
+
|
4185
|
+
list_intersection(lists)
|
4186
|
+
|
4187
|
+
list_intersection([swcy,sw50])
|
4188
|
+
|
4189
|
+
def list_intersection(lists=[],numberPerLine=5,printout=True,return_result=False):
|
4190
|
+
# 求多个列表的共同元素,即其交集,通过转化为集合求得。注意集合是无序的,谨慎使用!
|
4191
|
+
|
4192
|
+
if len(lists)==0:
|
4193
|
+
print(" #Warning(list_intersection): no list found for intersection")
|
4194
|
+
if return_result: return []
|
4195
|
+
else: return
|
4196
|
+
|
4197
|
+
if len(lists)==1:
|
4198
|
+
if return_result: return lists[0]
|
4199
|
+
else: return
|
4200
|
+
|
4201
|
+
list1=lists[0]; list2=lists[1]
|
4202
|
+
result=list2_intersection(list1,list2)
|
4203
|
+
|
4204
|
+
for l in lists[2:]:
|
4205
|
+
result=list2_intersection(result,l)
|
4206
|
+
|
4207
|
+
"""
|
4208
|
+
#貌似也没问题
|
4209
|
+
result=[]
|
4210
|
+
for l in lists:
|
4211
|
+
if result==[]:
|
4212
|
+
result=l
|
4213
|
+
else:
|
4214
|
+
result=list2_intersection(result,l)
|
4215
|
+
"""
|
4216
|
+
|
4217
|
+
if len(result) == 0:
|
4218
|
+
if printout:
|
4219
|
+
print(" #Warning(list_intersection): intersection result is empty")
|
4220
|
+
if return_result: return result
|
4221
|
+
else: return
|
4222
|
+
else:
|
4223
|
+
if printout:
|
4224
|
+
prompt_text=text_lang("\n*** 交集成份:","\n*** Intersection result: ")
|
4225
|
+
|
4226
|
+
if len(result) < numberPerLine:
|
4227
|
+
print(prompt_text,end='')
|
4228
|
+
for e in result:
|
4229
|
+
print(e,end=' ')
|
4230
|
+
print('')
|
4231
|
+
else:
|
4232
|
+
print(prompt_text+str(len(result)),end='')
|
4233
|
+
printInLine_md(result,numberPerLine=numberPerLine,colalign="center")
|
4234
|
+
|
4235
|
+
if return_result: return result
|
4236
|
+
else: return
|
4237
|
+
|
4238
|
+
#==============================================================================
|
4239
|
+
if __name__ == '__main__':
|
4240
|
+
hpr=3.17
|
4241
|
+
years=20
|
4242
|
+
|
4243
|
+
annual_return1(hpr,years)
|
4244
|
+
|
4245
|
+
def annual_return1(hpr,years):
|
4246
|
+
"""
|
4247
|
+
功能:计算年均复合增长率,1个
|
4248
|
+
"""
|
4249
|
+
#text1="Holding period return for "+str(years)+" years: "+str(hpr*100)+'%'
|
4250
|
+
text1=str(years)+"年的持有期收益率:"+str(round(hpr*100,3))+'%'
|
4251
|
+
print(text1,end=',')
|
4252
|
+
|
4253
|
+
#text2="Annualized compound return:"
|
4254
|
+
text2="年均复合收益率:"+str(round((pow(1+hpr,1/years)-1)*100,3))+'%'
|
4255
|
+
print(text2)
|
4129
4256
|
|
4257
|
+
return
|
4258
|
+
|
4259
|
+
if __name__ == '__main__':
|
4260
|
+
hpr=3.17
|
4261
|
+
hpr=[3.17,2.5]
|
4262
|
+
years=20
|
4263
|
+
|
4264
|
+
annual_return(hpr,years)
|
4265
|
+
|
4266
|
+
def annual_return(hpr,years):
|
4267
|
+
"""
|
4268
|
+
功能:hpr可为多个
|
4269
|
+
"""
|
4270
|
+
if isinstance(hpr,float) or isinstance(hpr,int):
|
4271
|
+
hpr=[hpr]
|
4272
|
+
|
4273
|
+
for h in hpr:
|
4274
|
+
annual_return1(h,years)
|
4275
|
+
|
4276
|
+
return
|
4277
|
+
|
4278
|
+
if __name__ == '__main__':
|
4279
|
+
df=security_trend(['801811.SW','801813.SW'],
|
4280
|
+
indicator='Exp Adj Ret%',
|
4281
|
+
start='L5Y',
|
4282
|
+
annotate=True,annotate_value=True)
|
4283
|
+
|
4284
|
+
df_annual_return(df)
|
4285
|
+
|
4286
|
+
def df_annual_return(df):
|
4287
|
+
"""
|
4288
|
+
功能:计算df1中每列的年复合收益率
|
4289
|
+
"""
|
4290
|
+
|
4291
|
+
#计算年数
|
4292
|
+
date1=df.index[0]
|
4293
|
+
date2=df.index[-1]
|
4294
|
+
delta=date2-date1
|
4295
|
+
years=round(delta.days/365,2)
|
4296
|
+
months=int(delta.days/30)
|
4297
|
+
|
4298
|
+
#计算每列的年均复合增长率
|
4299
|
+
collist=list(df)
|
4300
|
+
for c in collist:
|
4301
|
+
hpr=df[c][-1]
|
4302
|
+
hpr1=hpr/100
|
4303
|
+
annual_rate=str(round((pow(1+hpr1,1/years)-1)*100,3))+'%'
|
4304
|
+
|
4305
|
+
if years >=1:
|
4306
|
+
text=c+": "+str(years)+"年持有期收益率"+str(round(hpr,3))+'%,年均复合收益率'+annual_rate
|
4307
|
+
else:
|
4308
|
+
text=c+": "+str(months)+"个月持有期收益率"+str(round(hpr,3))+'%,年均复合收益率'+annual_rate
|
4309
|
+
print(text)
|
4310
|
+
|
4311
|
+
return
|
4312
|
+
|
4313
|
+
#==============================================================================
|
4314
|
+
|
4315
|
+
|
4316
|
+
if __name__ == '__main__':
|
4317
|
+
df=security_trend("600519.SS",graph=False)
|
4318
|
+
option="save"
|
4319
|
+
|
4320
|
+
df_save(df,file="moutai")
|
4321
|
+
mt=df_restore(file="moutai")
|
4322
|
+
|
4323
|
+
def df_save(df,file="df"):
|
4324
|
+
"""
|
4325
|
+
功能:保存df数据,适用于那些需要大量时间获取的df,以便使用时可以恢复
|
4326
|
+
"""
|
4327
|
+
|
4328
|
+
if ".pkl" in file:
|
4329
|
+
file_name=file
|
4330
|
+
else:
|
4331
|
+
file_name=file+'.pkl'
|
4332
|
+
|
4333
|
+
df.to_pickle(file_name)
|
4334
|
+
print(" Data is saved in",file_name)
|
4335
|
+
|
4336
|
+
return
|
4337
|
+
|
4338
|
+
def df_restore(file):
|
4339
|
+
"""
|
4340
|
+
功能:从文件保存df数据,适用于那些需要大量时间获取的df
|
4341
|
+
"""
|
4342
|
+
|
4343
|
+
import pandas as pd
|
4344
|
+
|
4345
|
+
if ".pkl" in file:
|
4346
|
+
file_name=file
|
4347
|
+
else:
|
4348
|
+
file_name=file+'.pkl'
|
4349
|
+
|
4350
|
+
try:
|
4351
|
+
df=pd.read_pickle(file_name)
|
4352
|
+
print(" Data is restored from",file_name)
|
4353
|
+
except:
|
4354
|
+
print(" #Warning(df_dump): file not found for",file_name)
|
4355
|
+
df=None
|
4356
|
+
return df
|
4357
|
+
|
4358
|
+
|
4359
|
+
#==============================================================================
|
4130
4360
|
#==============================================================================
|
4131
4361
|
#==============================================================================
|
siat/fund_china.py
CHANGED
@@ -762,7 +762,7 @@ def get_oef_rank_china():
|
|
762
762
|
df3['基金类型']=df3['基金类型'].astype(str)
|
763
763
|
df3['净值日期']=nvdate
|
764
764
|
|
765
|
-
print("Successfully retrieved",len(df3),"
|
765
|
+
print("Successfully retrieved",len(df3),"OEF products on",nvdate)
|
766
766
|
|
767
767
|
return df3
|
768
768
|
|
@@ -864,7 +864,10 @@ def oef_rank_china2(df,fund_type='全部类型',rank=5,indicator='单位净值')
|
|
864
864
|
titletxt="中国开放式基金排名:累计净值"
|
865
865
|
|
866
866
|
if indicator == '手续费':
|
867
|
-
|
867
|
+
try:
|
868
|
+
df['手续费'] = df['手续费'].astype(str)
|
869
|
+
df.sort_values(by=['手续费'],ascending=False,inplace=True)
|
870
|
+
except: pass
|
868
871
|
#dfprint=df[['基金简称','基金代码','基金类型','手续费','申购状态','赎回状态']]
|
869
872
|
dfprint=df[['基金简称','基金代码','基金类型','手续费','单位净值']]
|
870
873
|
#print(texttranslate("\n===== 中国开放式基金排名:手续费 ====="))
|
siat/grafix.py
CHANGED
@@ -293,7 +293,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
293
293
|
print(" #Warning(plot_line): color",facecolor,"is unsupported, changed to default setting")
|
294
294
|
plt.gca().set_facecolor("whitesmoke")
|
295
295
|
|
296
|
-
if '基金' in titletxt and '收盘价' in ylabeltxt:
|
296
|
+
if '基金' in titletxt and '收盘价' in ylabeltxt and not ('基金指数' in titletxt):
|
297
297
|
ylabeltxt=ylabeltxt.replace('收盘价','单位净值')
|
298
298
|
|
299
299
|
plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
|
@@ -476,7 +476,15 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
|
|
476
476
|
plt.text(x,y+0.1,'%.2f' % y,ha='center',va='bottom',color='black')
|
477
477
|
|
478
478
|
#是否绘制水平0线
|
479
|
-
|
479
|
+
df_max=max([df1[colname1].max(),df2[colname2].max()])
|
480
|
+
df_min=min([df1[colname1].min(),df2[colname2].min()])
|
481
|
+
if df_max * df_min >=0: #同正同负
|
482
|
+
zeroline=False
|
483
|
+
else:
|
484
|
+
zeroline=True
|
485
|
+
|
486
|
+
#if zeroline and ((min(df1[colname1]) < 0) or (min(df2[colname2]) < 0)):
|
487
|
+
if zeroline:
|
480
488
|
plt.axhline(y=0,ls=":",c="black",linewidth=2)
|
481
489
|
|
482
490
|
#是否绘制水平线
|
@@ -1367,6 +1375,8 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1367
1375
|
|
1368
1376
|
band_area='':默认为空,否则为列表,第1个值为带状区域上边沿字段,第2个值为带状区域下边沿字段
|
1369
1377
|
"""
|
1378
|
+
DEBUG=False
|
1379
|
+
|
1370
1380
|
#空值判断
|
1371
1381
|
if len(df0) ==0:
|
1372
1382
|
print (" #Warning(draw_lines): no data to plot.")
|
@@ -1534,6 +1544,9 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1534
1544
|
|
1535
1545
|
#绘制水平辅助线
|
1536
1546
|
if axhline_label !="":
|
1547
|
+
if DEBUG:
|
1548
|
+
print("DEBUG: draw axhline_label=",axhline_label)
|
1549
|
+
|
1537
1550
|
if "零线" in axhline_label:
|
1538
1551
|
plt.axhline(y=axhline_value,color='black',linestyle='--',linewidth=2)
|
1539
1552
|
else:
|
siat/risk_adjusted_return2.py
CHANGED
@@ -32,11 +32,11 @@ import numpy as np
|
|
32
32
|
#==============================================================================
|
33
33
|
#==============================================================================
|
34
34
|
if __name__=='__main__':
|
35
|
+
ticker='301161.SZ'
|
35
36
|
ticker="AAPL"
|
36
37
|
ticker={'Market':('US','^SPX','中概教培组合'),'EDU':0.7,'TAL':0.3}
|
37
38
|
|
38
|
-
start="2024-1-1"
|
39
|
-
end="2024-6-30"
|
39
|
+
start="2024-1-1"; end="2024-9-30"
|
40
40
|
rar_name="sharpe"
|
41
41
|
ret_type="Annual Adj Ret%"
|
42
42
|
RF=0.055
|
@@ -75,7 +75,7 @@ def get_rolling_sharpe_sortino(ticker,start,end,rar_name="sharpe", \
|
|
75
75
|
ret_period='Quarterly'
|
76
76
|
period_days=63
|
77
77
|
else:
|
78
|
-
dateahead=(366+7*3)*2
|
78
|
+
dateahead=(366+7*3)*2 #考虑收益率滚动+标准差滚动和节假日
|
79
79
|
ret_period='Annual'
|
80
80
|
period_days=252
|
81
81
|
|
@@ -714,26 +714,27 @@ def get_expanding_treynor_alpha2(ticker,start,end,rar_name="alpha", \
|
|
714
714
|
return pretdf3
|
715
715
|
#==============================================================================
|
716
716
|
if __name__=='__main__':
|
717
|
+
ticker='301161.SZ'
|
717
718
|
ticker="600519.SS"
|
718
719
|
ticker={'Market':('US','^SPX','中概教培组合'),'EDU':0.7,'TAL':0.3}
|
719
720
|
|
720
721
|
rar_name="sharpe"
|
721
722
|
rar_name="alpha"
|
722
723
|
|
723
|
-
ret_type="
|
724
|
+
ret_type="Annual Adj Ret%"
|
725
|
+
ret_type="Monthly Adj Ret%"
|
724
726
|
ret_type="Exp Ret%"
|
725
727
|
|
726
|
-
start="2024-1-1"
|
727
|
-
end="2024-3-15"
|
728
|
+
start="2024-1-1"; end="2024-9-30"
|
728
729
|
RF=0.01759
|
729
730
|
regression_period=365
|
730
|
-
mktidx='auto'; source='auto'
|
731
|
+
mktidx='auto'; source='auto'; ticker_type='auto'
|
731
732
|
|
732
733
|
alpha1=get_rar(ticker,start,end,rar_name="alpha",ret_type="Exp Ret%",RF=0)
|
733
734
|
alpha2=get_rar(ticker,start,end,rar_name="alpha",ret_type="Exp Ret%",RF=0.01759)
|
734
735
|
|
735
736
|
|
736
|
-
def get_rar(ticker,start,end,rar_name="sharpe",ret_type="Monthly Ret%", \
|
737
|
+
def get_rar(ticker,start,end,rar_name="sharpe",ret_type="Monthly Adj Ret%", \
|
737
738
|
RF=0,regression_period=365,mktidx='auto',source='auto',ticker_type='auto'):
|
738
739
|
"""
|
739
740
|
功能:获取一只股票的收益-风险性价比指标,在指定期间内,支持股票和投资组合
|
@@ -749,6 +750,7 @@ def get_rar(ticker,start,end,rar_name="sharpe",ret_type="Monthly Ret%", \
|
|
749
750
|
ret_type_title=ret_type.title() #字符串每个单词首字母大写
|
750
751
|
rar_name_lower=rar_name.lower()
|
751
752
|
|
753
|
+
rardf=None
|
752
754
|
#判断是否扩展收益率
|
753
755
|
if 'exp' not in ret_type_lower:
|
754
756
|
if ('sharpe' in rar_name_lower) or ('sortino' in rar_name_lower):
|
@@ -780,25 +782,28 @@ def get_rar(ticker,start,end,rar_name="sharpe",ret_type="Monthly Ret%", \
|
|
780
782
|
|
781
783
|
#==============================================================================
|
782
784
|
if __name__=='__main__':
|
785
|
+
ticker="301161.SZ"
|
783
786
|
ticker="600519.SS"
|
784
787
|
ticker={'Market':('US','^SPX','中概教培组合'),'EDU':0.7,'TAL':0.3}
|
785
788
|
|
786
|
-
start="2024-1-1"
|
787
|
-
|
789
|
+
start="2024-1-1"; end="2024-9-30"
|
790
|
+
rar='sharpe'
|
788
791
|
rar=['sharpe','sortino','treynor','alpha']
|
789
|
-
|
792
|
+
|
793
|
+
ret_type="Annual Adj Ret%"
|
794
|
+
ret_type="Monthly Adj Ret%"
|
790
795
|
RF=0.01759
|
791
796
|
regression_period=365
|
792
797
|
|
793
798
|
graph=True; axhline_value=0; axhline_label=''
|
794
799
|
printout=False; sortby='tpw_mean'; trailing=20; trend_threshhold=0.001
|
795
800
|
annotate=False
|
796
|
-
mktidx='auto'; source='auto'
|
801
|
+
mktidx='auto'; source='auto'; ticker_type='auto'
|
797
802
|
|
798
|
-
rars=compare_1ticker_mrar(ticker=
|
803
|
+
rars=compare_1ticker_mrar(ticker=ticker,start=start,end=end,rar=rar,printout=True)
|
799
804
|
|
800
805
|
def compare_1ticker_mrar(ticker,start,end,rar=['sharpe','sortino','treynor','alpha'], \
|
801
|
-
ret_type="Annual Ret%",RF=0,regression_period=365, \
|
806
|
+
ret_type="Annual Adj Ret%",RF=0,regression_period=365, \
|
802
807
|
graph=True,loc1='best', \
|
803
808
|
axhline_value=0,axhline_label='',facecolor='whitesmoke', \
|
804
809
|
printout=False,sortby='tpw_mean',trailing=7,trend_threshhold=0.01, \
|
@@ -866,11 +871,11 @@ def compare_1ticker_mrar(ticker,start,end,rar=['sharpe','sortino','treynor','alp
|
|
866
871
|
|
867
872
|
df1.rename(columns={c:ectranslate(c)},inplace=True)
|
868
873
|
|
869
|
-
footnote1=text_lang("
|
874
|
+
footnote1=text_lang("评估值基于","Note: RaR based on ")+ectranslate(ret_type)
|
870
875
|
if RF !=0:
|
871
|
-
footnote2=text_lang("
|
876
|
+
footnote2=text_lang(",年化无风险利率为",", RF = ")+str(round(RF*100,4))+text_lang('%','% pa')
|
872
877
|
else:
|
873
|
-
footnote2=text_lang("
|
878
|
+
footnote2=text_lang(",不考虑年化无风险利率时。",", RF = 0 pa")
|
874
879
|
|
875
880
|
footnote3=''
|
876
881
|
if 'treynor' in rar or 'alpha' in rar:
|
@@ -879,11 +884,11 @@ def compare_1ticker_mrar(ticker,start,end,rar=['sharpe','sortino','treynor','alp
|
|
879
884
|
footnote3x=text_lang(",市场指数基于",", using ")+mktidx_text
|
880
885
|
footnote3=text_lang("\nCAPM回归期间","\nCAPM rolling ")+str(regression_period)+text_lang("个自然日"," days, ")+footnote3x
|
881
886
|
else:
|
882
|
-
footnote3=text_lang("CAPM回归期间",", CAPM rolling ")+str(regression_period)+text_lang("个自然日"," days")
|
887
|
+
footnote3=text_lang(",CAPM回归期间",", CAPM rolling ")+str(regression_period)+text_lang("个自然日"," days")
|
883
888
|
|
884
889
|
|
885
890
|
import datetime; todaydt = datetime.date.today()
|
886
|
-
footnote4=text_lang("数据来源: 综合新浪/Stooq/Yahoo,","Data source: Sina/Stooq/Yahoo, ")+str(todaydt)
|
891
|
+
footnote4=text_lang("数据来源: 综合新浪/EM/Stooq/Yahoo/SWHY,","Data source: Sina/Stooq/Yahoo, ")+str(todaydt)
|
887
892
|
if footnote3 !='':
|
888
893
|
footnotex=footnote1+footnote2+footnote3+'\n'+footnote4
|
889
894
|
else:
|
@@ -893,7 +898,7 @@ def compare_1ticker_mrar(ticker,start,end,rar=['sharpe','sortino','treynor','alp
|
|
893
898
|
if graph:
|
894
899
|
y_label=''
|
895
900
|
import datetime; todaydt = datetime.date.today()
|
896
|
-
x_label=text_lang("数据来源: 综合新浪/Stooq/Yahoo,","Data source: Sina/Stooq/Yahoo, ")+str(todaydt)
|
901
|
+
x_label=text_lang("数据来源: 综合新浪/EM/Stooq/Yahoo/SWHY,","Data source: Sina/Stooq/Yahoo, ")+str(todaydt)
|
897
902
|
title_txt=text_lang("风险调整收益:","Risk-adjusted Return: ")+tname
|
898
903
|
|
899
904
|
draw_lines(df1,y_label,x_label=footnotex, \
|
@@ -918,11 +923,13 @@ def compare_1ticker_mrar(ticker,start,end,rar=['sharpe','sortino','treynor','alp
|
|
918
923
|
sortby_txt=text_lang('按推荐标记+短期均值走势降序排列',"by Recommend + Recent Trend, Descending")
|
919
924
|
|
920
925
|
#title_txt='***** 风险调整收益评估:'+tname+','+sortby_txt+' *****'
|
921
|
-
|
926
|
+
if isinstance(rar,list) and len(rar)==1:
|
927
|
+
rar=rar[0]
|
928
|
+
title_txt=text_lang('风险调整收益评估:',"RaR Evaluation: ")+str(ectranslate(rar))+text_lang(',',', ')+sortby_txt
|
922
929
|
|
923
|
-
footnote6=text_lang('
|
930
|
+
footnote6=text_lang('期间:',"Period: ")+str(start)+text_lang('至'," to ")+str(end)+text_lang(";近期指近","\nRecent trend: ")+str(trailing)+text_lang("个交易日。趋势变化率阈值:", " days. Trend threshhold ")+str(trend_threshhold)
|
924
931
|
footnote7=text_lang("近期优先趋势和星号为风险调整收益指标加趋势等多项因素综合研判,最多五颗星","Recommend max 5 stars. RWA = Recent-priority Weighted Average")
|
925
|
-
footnotey=footnote6+footnote7+'\n'+footnotex
|
932
|
+
footnotey=footnote6+'\n'+footnote7+'\n'+footnotex
|
926
933
|
|
927
934
|
recommenddf=descriptive_statistics2(df1,title_txt,footnotey,decimals=4, \
|
928
935
|
sortby=sortby,recommend_only=True,trailing=trailing, \
|
@@ -1062,7 +1069,7 @@ def compare_mticker_1rar(ticker,start,end,rar='sharpe', \
|
|
1062
1069
|
footnote3=text_lang("CAPM回归期间","\nCAPM rolling ")+str(regression_period)+text_lang("个自然日"," days")
|
1063
1070
|
|
1064
1071
|
import datetime; todaydt = datetime.date.today()
|
1065
|
-
footnote4=text_lang("数据来源: 综合新浪/Stooq/Yahoo,","Data source: Sina/Stooq/Yahoo, ")+str(todaydt)
|
1072
|
+
footnote4=text_lang("数据来源: 综合新浪/EM/Stooq/Yahoo/SWHY,","Data source: Sina/Stooq/Yahoo, ")+str(todaydt)
|
1066
1073
|
if footnote3 !='':
|
1067
1074
|
footnotex=footnote1+footnote2+footnote3+'\n'+footnote4
|
1068
1075
|
else:
|
@@ -1098,7 +1105,7 @@ def compare_mticker_1rar(ticker,start,end,rar='sharpe', \
|
|
1098
1105
|
#title_txt='***** 风险调整收益评估:基于'+ectranslate(rar)+','+sortby_txt+' *****'
|
1099
1106
|
title_txt=text_lang('风险调整收益评估:',"RaR Evaluation: ")+rar_text+text_lang(',',', ')+sortby_txt
|
1100
1107
|
|
1101
|
-
footnote6=text_lang('
|
1108
|
+
footnote6=text_lang('期间:',"Period: ")+str(start)+text_lang('至'," to ")+str(end)+text_lang(";近期指近","\nRecent trend: ")+str(trailing)+text_lang("个交易日。趋势变化率阈值:", " trading days. Trend change threshhold: ")+str(trend_threshhold)
|
1102
1109
|
footnote7=text_lang("近期优先趋势和星号为风险调整收益指标加趋势等多项因素综合研判,最多五颗星","Recommend max 5 stars. RWA = Recent-priority Weighted Average")
|
1103
1110
|
footnotey=footnote6+'\n'+footnote7+'\n'+footnotex
|
1104
1111
|
|
@@ -1296,7 +1303,7 @@ def compare_mticker_mrar(ticker,start,end,rar=['sharpe','alpha','sortino','treyn
|
|
1296
1303
|
footnote3=text_lang("CAPM基于","CAPM using ")+mktidx_name+text_lang(",回归期间",", rolling ")+str(regression_period)+text_lang("个自然日"," days")
|
1297
1304
|
|
1298
1305
|
import datetime; todaydt = datetime.date.today()
|
1299
|
-
footnote4=text_lang("数据来源: 综合新浪/Stooq/Yahoo,","Data source: Sina/Stooq/Yahoo, ")+str(todaydt)+text_lang("统计",'')
|
1306
|
+
footnote4=text_lang("数据来源: 综合新浪/EM/Stooq/Yahoo/SWHY,","Data source: Sina/Stooq/Yahoo, ")+str(todaydt)+text_lang("统计",'')
|
1300
1307
|
if footnote3 !='':
|
1301
1308
|
footnotex=footnote1+footnote2+'\n'+footnote3+'\n'+footnote4
|
1302
1309
|
else:
|
@@ -1413,7 +1420,7 @@ def compare_1ticker_1rar_mret(ticker,start,end,rar='sharpe', \
|
|
1413
1420
|
footnote3=text_lang("CAPM回归期间","CAPM rolling ")+str(regression_period)+text_lang("个自然日"," days")
|
1414
1421
|
|
1415
1422
|
import datetime; todaydt = datetime.date.today()
|
1416
|
-
footnote4=text_lang("数据来源: 综合新浪/Stooq/Yahoo,","Data source: Sina/Stooq/Yahoo, ")+str(todaydt)
|
1423
|
+
footnote4=text_lang("数据来源: 综合新浪/EM/Stooq/Yahoo/SWHY,","Data source: Sina/Stooq/Yahoo, ")+str(todaydt)
|
1417
1424
|
if footnote3 !='':
|
1418
1425
|
footnotex=footnote1+footnote2+footnote3+'\n'+footnote4
|
1419
1426
|
else:
|
@@ -1449,9 +1456,9 @@ def compare_1ticker_1rar_mret(ticker,start,end,rar='sharpe', \
|
|
1449
1456
|
#title_txt='***** 风险调整收益评估:'+'基于'+ectranslate(rar)+','+ticker_name(ticker,ticker_type)+','+sortby_txt+' *****'
|
1450
1457
|
title_txt=text_lang('风险调整收益评估:',"RaR Evaluation: ")+ectranslate(rar)+text_lang(',',', ')+sortby_txt
|
1451
1458
|
|
1452
|
-
footnote6=text_lang('
|
1459
|
+
footnote6=text_lang('期间:',"Period: ")+str(start)+text_lang('至'," to ")+str(end)+text_lang(";近期指近","\nRecent trend: ")+str(trailing)+text_lang("个交易日。趋势变化率阈值:", " days. Trend threshhold ")+str(trend_threshhold)
|
1453
1460
|
footnote7=text_lang("近期优先趋势和星号为风险调整收益指标加趋势等多项因素综合研判,最多五颗星","Recommend max 5 stars. RWA = Recent-priority Weighted Average")
|
1454
|
-
footnotey=footnote6+footnote7+'\n'+footnotex
|
1461
|
+
footnotey=footnote6+'\n'+footnote7+'\n'+footnotex
|
1455
1462
|
|
1456
1463
|
#删除含有Nan的行
|
1457
1464
|
df1.dropna(inplace=True)
|
@@ -1557,7 +1564,7 @@ def compare_1ticker_1rar_1ret_mRF(ticker,start,end,rar='sharpe', \
|
|
1557
1564
|
footnote3="贝塔系数回归期间"+str(regression_period)+"个自然日"
|
1558
1565
|
|
1559
1566
|
import datetime; todaydt = datetime.date.today()
|
1560
|
-
footnote4=text_lang("数据来源: 综合新浪/Stooq/Yahoo,","Data source: Sina/Stooq/Yahoo, ")+str(todaydt)
|
1567
|
+
footnote4=text_lang("数据来源: 综合新浪/EM/Stooq/Yahoo/SWHY,","Data source: Sina/Stooq/Yahoo, ")+str(todaydt)
|
1561
1568
|
if footnote3 !='':
|
1562
1569
|
footnotex=footnote1+footnote3+'\n'+footnote4
|
1563
1570
|
else:
|
@@ -1593,7 +1600,7 @@ def compare_1ticker_1rar_1ret_mRF(ticker,start,end,rar='sharpe', \
|
|
1593
1600
|
#title_txt='***** 风险调整收益评估:'+'基于'+ectranslate(rar)+','+ticker_name(ticker,ticker_type)+','+sortby_txt+' *****'
|
1594
1601
|
title_txt=text_lang('风险调整收益评估:',"RaR Evaluation: ")+ectranslate(rar)+text_lang(',',', ')+sortby_txt
|
1595
1602
|
|
1596
|
-
footnote6=text_lang('
|
1603
|
+
footnote6=text_lang('期间:',"Period: ")+str(start)+text_lang('至'," to ")+str(end)+text_lang(";近期指近","\nRecent trend: ")+str(trailing)+text_lang("个交易日。趋势变化率阈值:", " days. Trend threshhold ")+str(trend_threshhold)
|
1597
1604
|
footnote7=text_lang("近期优先趋势和星号为风险调整收益指标加趋势等多项因素综合研判,最多五颗星","Recommend max 5 stars. RWA = Recent-priority Weighted Average")
|
1598
1605
|
footnotey=footnote6+footnote7+'\n'+footnotex
|
1599
1606
|
|
@@ -1610,18 +1617,20 @@ def compare_1ticker_1rar_1ret_mRF(ticker,start,end,rar='sharpe', \
|
|
1610
1617
|
# 合成函数
|
1611
1618
|
#==============================================================================
|
1612
1619
|
if __name__=='__main__':
|
1620
|
+
ticker="301161.SZ"
|
1613
1621
|
ticker="600519.SS"
|
1614
1622
|
ticker=["600519.SS","000858.SZ"]
|
1615
1623
|
ticker={'Market':('US','^SPX','中概教培组合'),'EDU':0.7,'TAL':0.3}
|
1616
1624
|
|
1617
|
-
start="2024-1-1"
|
1618
|
-
end="2024-3-22"
|
1625
|
+
start="2024-1-1"; end="2024-9-30"
|
1619
1626
|
|
1627
|
+
rar='sharpe'
|
1620
1628
|
rar='alpha'
|
1621
1629
|
rar=['sharpe','alpha']
|
1622
1630
|
|
1623
|
-
ret_type="
|
1624
|
-
ret_type=
|
1631
|
+
ret_type="Monthly Adj Ret%"
|
1632
|
+
ret_type="Annual Adj Ret%"
|
1633
|
+
ret_type=["Monthly Adj Ret%","Annual Adj Ret%"]
|
1625
1634
|
|
1626
1635
|
RF=0.01759
|
1627
1636
|
RF=[0.005,0.01759,0.05]
|
@@ -1631,13 +1640,13 @@ if __name__=='__main__':
|
|
1631
1640
|
graph=True; axhline_value=0; axhline_label=''
|
1632
1641
|
printout=False; sortby='tpw_mean'; trailing=5; trend_threshhold=0.001
|
1633
1642
|
annotate=False
|
1634
|
-
|
1635
|
-
|
1636
|
-
rars=compare_rar_security(ticker,start,end,rar,ret_type,RF,printout=True)
|
1637
|
-
|
1643
|
+
mark_top=True; mark_bottom=True; mark_end=True
|
1644
|
+
mktidx='auto'; source='auto'; ticker_type='auto'
|
1638
1645
|
|
1646
|
+
rars=compare_rar_security(ticker,start,end,rar,ret_type,RF,
|
1647
|
+
mark_top=True,mark_bottom=True,mark_end=True,
|
1648
|
+
printout=True)
|
1639
1649
|
|
1640
|
-
rars=compare_rar_security(ticker,start,end,rar,ret_type,RF,printout=True)
|
1641
1650
|
|
1642
1651
|
def compare_rar_security(ticker,start,end,rar='sharpe', \
|
1643
1652
|
ret_type="Annual Adj Ret%", \
|
@@ -1772,6 +1781,7 @@ def compare_rar_security(ticker,start,end,rar='sharpe', \
|
|
1772
1781
|
printout=printout,sortby=sortby, \
|
1773
1782
|
trailing=trailing,trend_threshhold=trend_threshhold, \
|
1774
1783
|
annotate=annotate,annotate_value=annotate, \
|
1784
|
+
mark_top=mark_top,mark_bottom=mark_bottom,mark_end=mark_end, \
|
1775
1785
|
mktidx=mktidx,source=source, \
|
1776
1786
|
ticker_type=ticker_type,facecolor=facecolor)
|
1777
1787
|
|