siat 3.7.1__py3-none-any.whl → 3.7.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/event_study.py CHANGED
@@ -43,6 +43,7 @@ if __name__=='__main__':
43
43
  start='2024-3-1'; end='2024-4-30'
44
44
  event_window=[1,1] #事件发生时股市已经收盘,故检测下一个交易日的股市反应
45
45
  market_index='000001.SS' #贵州茅台在上交所上市,故使用上证综合指数
46
+ RF=0
46
47
 
47
48
  #测试组2
48
49
  ticker=['600519.SS','399997.SZ']
@@ -51,6 +52,7 @@ if __name__=='__main__':
51
52
  start='2024-3-1'; end='2024-3-30'
52
53
  event_window=[1,2]
53
54
  market_index='000300.SS'
55
+ RF="market model"
54
56
 
55
57
  #共同部分
56
58
  post_event_days=7
@@ -58,7 +60,6 @@ if __name__=='__main__':
58
60
  early_response_days=-2
59
61
  estimation_window_days=-365
60
62
 
61
- RF=0
62
63
  ret_type="Daily Adj Ret%"
63
64
  ticker_type='stock' #贵州茅台为股票
64
65
  facecolor="whitesmoke"
@@ -91,12 +92,12 @@ if __name__=='__main__':
91
92
  def event_study(ticker,event_date, \
92
93
  start='MRM',end='today', \
93
94
  event_window=[0,0], \
94
- post_event_days=7, \
95
+ post_event_days=0, \
95
96
  method='CAPM', \
96
97
  early_response_days=-2, \
97
98
  estimation_window_days=-365, \
98
99
  market_index='000300.SS', \
99
- RF=0, \
100
+ RF="market index", \
100
101
  ret_type="Daily Adj Ret%", \
101
102
  ticker_type='auto', \
102
103
  facecolor="whitesmoke",show_AR='auto',loc='best'):
@@ -125,12 +126,15 @@ def event_study(ticker,event_date, \
125
126
  默认在事件窗口开始日期+提前反应天数前的365个自然日(约250个交易日)。
126
127
  market_index:当method为CAPM时,用于计算市场收益率。默认中国市场采用000300.SS。
127
128
  注意:需要根据不同市场采取不同的市场指数,例如香港市场为恒生指数,美国市场为标普500指数等。
129
+ RF:默认使用市场模型"market index",无需指定;可直接指定具体数值;
130
+ 也可指定特定指标,例如一年期中国国债收益率"1YCNY.B"或一年期美债收益率"1YUSY.B"等。
128
131
  ticker_type:显式指明ticker的证券类型,当siat误判其类型(中国内地股票/债券/基金)时使用,默认'auto'。
129
132
  facecolor:显式指定绘图背景颜色,默认"whitesmoke"。
130
133
  show_AR:是否绘图时绘制异常收益率AR,默认'auto'(单个ticker时绘制,多个时不绘制),也可指定True/False强行绘制/不绘制。
131
134
  """
132
135
 
133
136
  DEBUG=False
137
+ DEBUG2=False
134
138
 
135
139
  #=====事件研究各个日期的计算与调整===========================================
136
140
  if isinstance(event_date,str):
@@ -142,23 +146,35 @@ def event_study(ticker,event_date, \
142
146
  return None
143
147
  event_date.sort() #升序排序
144
148
 
145
- #事件窗口日期计算与调整
149
+ #事件窗口日期:遇到周末需要调整,提前或顺延至最近的工作日
146
150
  event_window_new=event_window.copy() #列表的普通赋值仅为指针,新列表的改动也会影响原列表
147
151
  adjust_start=0
148
152
  event_window_start=date_adjust(event_date[0],adjust=event_window[0])
149
153
  if week_day(event_window_start) == 5: #周六
150
- adjust_start=2
154
+ if event_window[0] >= 0:
155
+ adjust_start=2
156
+ else:
157
+ adjust_start=-1
151
158
  elif week_day(event_window_start) == 6: #周日
152
- adjust_start=1
159
+ if event_window[0] >= 0:
160
+ adjust_start=1
161
+ else:
162
+ adjust_start=-2
153
163
  event_window_start=date_adjust(event_window_start,adjust=adjust_start)
154
164
  event_window_new[0]=event_window[0]+adjust_start
155
165
 
156
166
  adjust_end=0
157
167
  event_window_end=date_adjust(event_window_start,adjust=event_window[1]-event_window[0])
158
168
  if week_day(event_window_end) == 5: #周六
159
- adjust_end=2
169
+ if event_window[1] >= 0:
170
+ adjust_end=2
171
+ else:
172
+ adjust_end=-1
160
173
  elif week_day(event_window_end) == 6: #周日
161
- adjust_end=1
174
+ if event_window[1] >= 0:
175
+ adjust_end=1
176
+ else:
177
+ adjust_end=-2
162
178
  event_window_end=date_adjust(event_window_end,adjust=adjust_end)
163
179
  event_window_new[1]=event_window[1]+adjust_start+adjust_end
164
180
 
@@ -167,9 +183,9 @@ def event_study(ticker,event_date, \
167
183
  print(" DEBUG: event window is between {0} to {1}".format(event_window_start,event_window_end))
168
184
 
169
185
  if event_window_new != event_window:
170
- print(" #Notice: event window adjusted to {} because of crossing weekend".format(event_window_new))
186
+ print(" #Notice: event window adjusted from {0} to {1} because of weekend".format(event_window,event_window_new))
171
187
 
172
- #事件后窗口日期的计算与调整
188
+ #事件后窗口日期
173
189
  post_event_start=date_adjust(event_window_end,adjust=0)
174
190
  if week_day(post_event_start) == 5: #周六
175
191
  post_event_start=date_adjust(post_event_start,adjust=2)
@@ -189,7 +205,7 @@ def event_study(ticker,event_date, \
189
205
  print(" DEBUG: post event window is between {0} to {1}".format(post_event_start,post_event_end))
190
206
 
191
207
 
192
- #事件窗口前日期计算与调整
208
+ #事件窗口前日期
193
209
  event_eve_date=date_adjust(event_window_start,adjust=-1)
194
210
  if week_day(event_eve_date) == 5: #周六
195
211
  event_eve_date=date_adjust(event_eve_date,adjust=-1)
@@ -199,7 +215,7 @@ def event_study(ticker,event_date, \
199
215
  if DEBUG:
200
216
  print(" DEBUG: event eve is on {}".format(event_eve_date))
201
217
 
202
- #提前反应日期计算与调整
218
+ #提前反应日期
203
219
  early_response_date=date_adjust(event_date[0],adjust=early_response_days)
204
220
  if week_day(early_response_date) == 5: #周六
205
221
  early_response_date=date_adjust(early_response_date,adjust=-1)
@@ -211,7 +227,10 @@ def event_study(ticker,event_date, \
211
227
 
212
228
  #估计窗口日期的计算
213
229
  est_window_end=date_adjust(early_response_date,adjust=-1)
214
- est_window_start=date_adjust(est_window_end,adjust=estimation_window_days)
230
+ est_window_start=date_adjust(est_window_end,adjust=estimation_window_days)
231
+ if DEBUG:
232
+ print(" DEBUG: regression period starts from {0} to {1}".format(est_window_start,est_window_end))
233
+
215
234
 
216
235
  #=====判断ticker是否为指数,调整预期收益率计算方法============================
217
236
  if isinstance(ticker,str):
@@ -223,45 +242,85 @@ def event_study(ticker,event_date, \
223
242
  return None
224
243
 
225
244
  if market_index in ticker:
226
- print(" #Warning(event_study): market_index {0} in ticker {1}, removed from ticker".format(market_index,ticker))
245
+ print(" #Warning(event_study): market_index {0} duplicated in and removed from ticker {1}".format(market_index,ticker))
227
246
  ticker.remove(market_index)
228
247
 
229
- tname=ticker_name(ticker[0],ticker_type)
248
+ #tname=ticker_name(ticker[0],ticker_type)
230
249
  #检查ticker是否为指数或国债收益率
231
250
  """
232
251
  if ("指数" in tname or "index" in tname.lower()) or ("收益率" in tname or "yield" in tname.lower()):
233
252
  if not ("random" in method.lower() or "walk" in method.lower()):
234
253
  print(" #Notice: check the applicability of ticker {0}, method {1} with market index {2}".format(ticker[0],method,market_index))
235
254
  """
255
+
236
256
  #=====获取证券价格和/或相关指数数据==========================================
237
- if 'capm' in method.lower() or 'market' in method.lower() or 'index' in method.lower():
257
+ #基于CAPM获取数据
258
+ if 'capm' in method.lower():
259
+ method_type="capm"
260
+ if isinstance(RF,int) or isinstance(RF,float):
261
+ #RF为具体数值
262
+ RF_type="value"
263
+ df_ret=compare_msecurity(tickers=ticker+[market_index],measure=ret_type, \
264
+ start=est_window_start,end=end, \
265
+ ticker_type=ticker_type, \
266
+ graph=False)
267
+
268
+ elif "market" in (str(RF)).lower() or "index" in (str(RF)).lower():
269
+ #RF通过市场模型计算,无需指定
270
+ RF_type="model"
271
+ df_ret=compare_msecurity(tickers=ticker+[market_index],measure=ret_type, \
272
+ start=est_window_start,end=end, \
273
+ ticker_type=ticker_type, \
274
+ graph=False)
275
+ else:
276
+ #指定RF代码,例如1YCNY.B
277
+ RF_type="code"
278
+ df_ret=compare_msecurity(tickers=ticker+[market_index,RF],measure=ret_type, \
279
+ start=est_window_start,end=end, \
280
+ ticker_type=ticker_type, \
281
+ graph=False)
282
+
283
+ #基于市场指数获取数据
284
+ elif 'market' in method.lower() or 'index' in method.lower():
285
+ method_type="market"
238
286
  df_ret=compare_msecurity(tickers=ticker+[market_index],measure=ret_type, \
239
287
  start=est_window_start,end=end, \
240
288
  ticker_type=ticker_type, \
241
289
  graph=False)
242
- """
243
- for t in ticker+[market_index]:
244
- df_ret.rename(columns={ticker_name(t,ticker_type):t},inplace=True)
245
- """
246
- if 'random' in method.lower() or 'walk' in method.lower():
290
+
291
+ elif 'random' in method.lower() or 'walk' in method.lower():
292
+ method_type="random"
247
293
  df_ret=compare_msecurity(tickers=ticker,measure=ret_type, \
248
294
  start=est_window_start,end=end, \
249
295
  ticker_type=ticker_type, \
250
296
  graph=False)
251
297
  for t in ticker_name(ticker,ticker_type):
252
- #df_ret.rename(columns={ticker_name(t,ticker_type):t},inplace=True)
253
- df_ret[t+"_predicted"]=df_ret[t].shift(1)
298
+ try:
299
+ df_ret[t+"_predicted"]=df_ret[t].shift(1)
300
+ except:
301
+ #print(" #Warning(event_study): info not found for ticker {}".format(t))
302
+ continue
303
+
304
+ else:
305
+ print(" #Warning(event_study): unexpected type of AR method {}".format(method))
306
+ return None
254
307
 
255
308
  #=====计算异常收益率AR=====
256
309
  df_cols=list(df_ret)
257
- if 'market' in method.lower() or 'index' in method.lower():
310
+ if method_type=='market':
258
311
  for t in ticker_name(ticker,ticker_type):
259
- df_ret[t+'_AR']=df_ret[t]-df_ret[ticker_name(market_index)]
260
- elif 'random' in method.lower() or 'walk' in method.lower():
312
+ try:
313
+ df_ret[t+'_AR']=df_ret[t] - df_ret[ticker_name(market_index)]
314
+ except: continue
315
+
316
+ elif method_type=='random':
261
317
  for t in ticker_name(ticker,ticker_type):
262
- df_ret[t+'_AR']=df_ret[t]-df_ret[t+"_predicted"]
318
+ try:
319
+ df_ret[t+'_AR']=df_ret[t] - df_ret[t+"_predicted"]
320
+ except: continue
321
+
263
322
  else: #按CAPM计算
264
- #回归CAPM
323
+ #CAPM回归期间数据
265
324
  est_window_startpd=pd.to_datetime(est_window_start)
266
325
  est_window_endpd =pd.to_datetime(est_window_end)
267
326
  df_reg=df_ret[(df_ret.index >=est_window_startpd) & (df_ret.index <=est_window_endpd)].copy()
@@ -270,49 +329,107 @@ def event_study(ticker,event_date, \
270
329
  df_reg=df_reg.replace([np.nan, None], np.nan).dropna()
271
330
 
272
331
  import statsmodels.api as sm
273
- X=df_reg[ticker_name(market_index)] - RF #无截距项回归,需要RF
274
- beta_dict={}
332
+ if RF_type=="value":
333
+ if not ("%" in ret_type): #注意:RF不是百分比
334
+ X=df_reg[ticker_name(market_index)] - RF #无截距项回归,指定RF具体数值
335
+ else:
336
+ X=df_reg[ticker_name(market_index)] - RF*100.0
337
+
338
+ elif RF_type=="model":
339
+ X=df_reg[ticker_name(market_index)]
340
+ X=sm.add_constant(X) #有截距项回归,基于市场模型
341
+ else: #RF_type=="code"
342
+ if not ("%" in ret_type): #注意:1YCNY.B数值是百分比%
343
+ X=df_reg[ticker_name(market_index)] - df_reg[ticker_name(RF)]/100.0
344
+ else:
345
+ X=df_reg[ticker_name(market_index)] - df_reg[ticker_name(RF)]
346
+
347
+ if DEBUG:
348
+ print(" DEBUG: method_type={0}, RF_type={1}".format(method_type,RF_type))
349
+
350
+ #CAPM回归
351
+ beta_dict={}; intercept_dict={}; pvalue_dict={}
275
352
  for t in ticker_name(ticker,ticker_type):
276
- y=df_reg[t] - RF
277
- model = sm.OLS(y,X) #定义回归模型R-Rf=beta(Rm-Rf),X可为多元矩阵
353
+ try:
354
+ if RF_type=="value":
355
+ if not ("%" in ret_type): #注意:RF不是百分比
356
+ y=df_reg[t] - RF
357
+ else:
358
+ y=df_reg[t] - RF*100.0
359
+
360
+ elif RF_type=="model":
361
+ y=df_reg[t]
362
+
363
+ else: #RF_type=="code"
364
+ if not ("%" in ret_type): #注意:1YCNY.B数值是百分比%
365
+ y=df_reg[t] - df_reg[ticker_name(RF)]/100.0
366
+ else:
367
+ y=df_reg[t] - df_reg[ticker_name(RF)]
368
+ except: continue
369
+
370
+ model = sm.OLS(y,X) #定义回归模型y=X
278
371
  results = model.fit() #进行OLS回归
279
- beta=results.params[0] #提取回归系数
280
372
 
281
- beta_dict[t] = beta
282
-
283
- #有截距回归,无需RF
284
- #from scipy import stats
285
- #(beta,alpha,r_value,p_value,std_err)=stats.linregress(df_reg[market_index],df_reg[ticker])
286
-
287
- if DEBUG:
288
- print(" DEBUG: RF={0}, beta={1}".format(RF,beta_dict))
373
+ #提取回归系数,详细信息见results.summary()
374
+ intercept=results.params[0]
375
+ beta=results.params[1]; pvalue=results.pvalues[1]
376
+
377
+ beta_dict[t] = beta; intercept_dict[t] = intercept; pvalue_dict[t] = pvalue;
378
+ if DEBUG:
379
+ print(" DEBUG: {0}, intercept={1}, beta={2}, pvalue={3}".format(t,round(intercept,4),round(beta,4),round(pvalue,4)))
289
380
 
381
+ #计算收益率预期和AR
290
382
  for t in ticker_name(ticker,ticker_type):
291
- df_ret[t+"_predicted"]=(df_ret[ticker_name(market_index)] - RF)*beta_dict[t] + RF
292
- df_ret[t+"_AR"]=df_ret[t]-df_ret[t+"_predicted"]
383
+ try:
384
+ if RF_type=="value":
385
+ RF_text=str(round(RF*100.0,4))[:6]+'%'
386
+ if not ("%" in ret_type): #注意:RF不是百分比
387
+ df_ret[t+"_predicted"]=(df_ret[ticker_name(market_index)] - RF)*beta_dict[t] + RF
388
+ else:
389
+ df_ret[t+"_predicted"]=(df_ret[ticker_name(market_index)] - RF*100.0)*beta_dict[t] + RF*100.0
390
+
391
+ elif RF_type=="model":
392
+ RF_text="基于市场模型回归"
393
+ df_ret[t+"_predicted"]=df_ret[ticker_name(market_index)]*beta_dict[t] + intercept_dict[t]
394
+
395
+ else: #RF_type=="code"
396
+ RF_text=ticker_name(RF)
397
+ df_ret[t+"_predicted"]=(df_ret[ticker_name(market_index)] - df_ret[ticker_name(RF)])*beta_dict[t] + df_ret[ticker_name(RF)]
398
+
399
+ df_ret[t+"_AR"]=df_ret[t] - df_ret[t+"_predicted"]
400
+ except: continue
293
401
 
294
- #=====计算CAR=====
402
+ if DEBUG2:
403
+ print(" DEBUG: RF_type={0}, RF_text={1}".format(RF_type,RF_text))
404
+
405
+ #=====计算CAR==============================================================
295
406
  for t in ticker_name(ticker,ticker_type):
296
- df_ret[t+"_CAR"]=0
407
+ try:
408
+ df_ret[t+"_CAR"]=0
409
+ except: continue
410
+
297
411
  event_window_startpd=pd.to_datetime(event_window_start)
298
412
  event_window_endpd=pd.to_datetime(event_window_end)
299
413
  post_event_endpd=pd.to_datetime(post_event_end)
300
-
301
414
  startpd=pd.to_datetime(start); endpd=pd.to_datetime(end)
302
- #df_ret_event=df_ret[(df_ret.index >=event_window_startpd) & (df_ret.index <=post_event_endpd)]
415
+
416
+ #计算CAR
303
417
  df_ret_event=df_ret[(df_ret.index >=event_window_startpd) & (df_ret.index <=endpd)]
304
418
  for t in ticker_name(ticker,ticker_type):
305
- df_ret_event[t+'_CAR'] = df_ret_event[t+'_AR'].cumsum()
419
+ try:
420
+ df_ret_event[t+'_CAR'] = df_ret_event[t+'_AR'].cumsum()
421
+ except: continue
306
422
 
423
+ #合成事件前期间
307
424
  df_ret_before_event=df_ret[(df_ret.index >=startpd) & (df_ret.index < event_window_startpd)]
308
425
  for t in ticker_name(ticker,ticker_type):
309
- df_ret_before_event[t+'_CAR']=np.nan
310
-
311
- #df_ret_after_event=df_ret[(df_ret.index >post_event_endpd)]
312
- #df_ret_after_event['CAR']=np.nan
426
+ try:
427
+ df_ret_before_event[t+'_CAR']=np.nan
428
+ except: continue
313
429
 
314
- #df_show=pd.concat([df_ret_before_event,df_ret_event,df_ret_after_event])
315
430
  df_show=pd.concat([df_ret_before_event,df_ret_event])
431
+
432
+ #是否显示AR:默认单证券显示,多证券不显示
316
433
  df_show_cols=[]
317
434
  for c in list(df_show):
318
435
  if show_AR=='auto':
@@ -339,24 +456,24 @@ def event_study(ticker,event_date, \
339
456
 
340
457
  y_label="收益率%"
341
458
 
342
-
459
+ #横轴注释
343
460
  footnote1="首事件日{0},事件窗口{1},事件后窗口天数{2},市场提前反应天数{3}".format(event_date[0],event_window_new,post_event_days,early_response_days)
344
461
  footnote2="收益率类型:"+ectranslate(ret_type)
345
462
 
346
- if "market" in method.lower() or "index" in method.lower():
347
- method_name="市场指数"
348
- elif "random" in method.lower() or "walk" in method.lower():
349
- method_name="随机漫步"
463
+ if method_type == "market":
464
+ method_name="市场指数基准"
465
+ elif method_type == "random":
466
+ method_name="随机漫步模型"
350
467
  else:
351
- method_name="CAPM"
468
+ method_name="CAPM模型"
352
469
 
353
470
  footnote3=",收益率预期方法:"+method_name
354
- if not ('random' in method.lower() or 'walk' in method.lower()):
471
+ if not method_type == "random":
355
472
  footnote4=',市场指数:'+ticker_name(market_index)
356
473
  else:
357
474
  footnote4=''
358
475
 
359
- #显著性检验:异于零的t检验
476
+ #显著性检验:异于零的t检验,事件窗口
360
477
  df_event_window=df0[(df0.index >=event_window_start) & (df0.index <=event_window_end)]
361
478
  footnote5="事件窗口CAR的p值:"
362
479
  for c in list(df_event_window):
@@ -371,19 +488,23 @@ def event_study(ticker,event_date, \
371
488
  footnote5=footnote5+c[:-4]+str(p_value)[:6]+","
372
489
  footnote5=footnote5.strip(",")
373
490
 
374
- df_post_event_window=df0[(df0.index >event_window_end) & (df0.index <=post_event_end)]
375
- footnote6="事件后窗口CAR的p值:"
376
- for c in list(df_post_event_window):
377
- if 'CAR' in c.upper():
378
- if len(df_post_event_window[c])==1:
379
- if abs(df_post_event_window[c].values[0]) > 0.01:
380
- p_value=0.0
491
+ #显著性检验:异于零的t检验,事件后窗口
492
+ if post_event_days == 0:
493
+ footnote6=''
494
+ else:
495
+ df_post_event_window=df0[(df0.index >event_window_end) & (df0.index <=post_event_end)]
496
+ footnote6="事件后窗口CAR的p值:"
497
+ for c in list(df_post_event_window):
498
+ if 'CAR' in c.upper():
499
+ if len(df_post_event_window[c])==1:
500
+ if abs(df_post_event_window[c].values[0]) > 0.01:
501
+ p_value=0.0
502
+ else:
503
+ p_value=1.0
381
504
  else:
382
- p_value=1.0
383
- else:
384
- p_value=ttest(df_post_event_window[c],0)
385
- footnote6=footnote6+c[:-4]+str(p_value)[:6]+","
386
- footnote6=footnote6.strip(",")
505
+ p_value=ttest(df_post_event_window[c],0)
506
+ footnote6=footnote6+c[:-4]+str(p_value)[:6]+","
507
+ footnote6=footnote6.strip(",")
387
508
 
388
509
  footnote7="数据来源:Sina/EM/Yahoo/Stooq/SWHY,"+stoday
389
510
 
@@ -467,20 +588,25 @@ def event_study(ticker,event_date, \
467
588
  event_text="事件日"+str(pos+1)
468
589
  df1["事件标记"]=df1.apply(lambda x: event_text if x["日期"]==d else x["事件标记"],axis=1)
469
590
 
470
- event_text=",事件窗口开始日"
591
+ #event_text=",事件窗口开始日"
592
+ event_text="\n事件窗开始"
471
593
  df1["事件标记"]=df1.apply(lambda x: x["事件标记"]+event_text if x["日期"]==event_window_start else x["事件标记"],axis=1)
472
- event_text=",事件窗口结束日"
594
+ #event_text=",事件窗口结束日"
595
+ event_text="\n事件窗结束"
473
596
  df1["事件标记"]=df1.apply(lambda x: x["事件标记"]+event_text if x["日期"]==event_window_end else x["事件标记"],axis=1)
474
- event_text="事件后窗口结束日"
475
- df1["事件标记"]=df1.apply(lambda x: x["事件标记"]+event_text if x["日期"]==post_event_end else x["事件标记"],axis=1)
597
+
598
+ #event_text=",事件后窗口结束日"
599
+ if post_event_end > event_window_end:
600
+ event_text="\n事件后窗结束"
601
+ df1["事件标记"]=df1.apply(lambda x: x["事件标记"]+event_text if x["日期"]==post_event_end else x["事件标记"],axis=1)
476
602
 
477
- event_text=",事件窗口"
603
+ event_text="\n事件窗"
478
604
  df1["事件标记"]=df1.apply(lambda x: x["事件标记"]+event_text if (x["日期"] > event_window_start) and (x["日期"] < event_window_end) else x["事件标记"],axis=1)
479
605
 
480
- event_text=",事件后窗口"
606
+ event_text="\n事件后窗"
481
607
  df1["事件标记"]=df1.apply(lambda x: x["事件标记"]+event_text if (x["日期"] > event_window_end) and (x["日期"] < post_event_end) else x["事件标记"],axis=1)
482
608
 
483
- df1["事件标记"]=df1["事件标记"].apply(lambda x: x.strip(''))
609
+ df1["事件标记"]=df1["事件标记"].apply(lambda x: x.strip('\n'))
484
610
 
485
611
  #显示表格
486
612
  df0_list=list(df0)
@@ -489,7 +615,7 @@ def event_study(ticker,event_date, \
489
615
  #title_txt=title_txt+",窗口收益率"
490
616
 
491
617
  if "CAPM" in method.upper():
492
- footnotex="CAPM回归期间:{0}至{1}".format(est_window_start,est_window_end)
618
+ footnotex="CAPM回归期间:{0}至{1},无风险收益率RF:{2}".format(est_window_start,est_window_end,RF_text)
493
619
  footnotey="CAPM贝塔系数:"
494
620
  for k in beta_dict:
495
621
  footnotey=footnotey+k+str(round(beta_dict[k],4))[:6]+","
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: siat
3
- Version: 3.7.1
3
+ Version: 3.7.2
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
@@ -32,7 +32,7 @@ siat/economy.py,sha256=ijMAVA5ydghbQDgNDDdz8fz9NPd2eq90RzpJSRGWz5c,78638
32
32
  siat/economy_test.py,sha256=6vjNlPz7W125pJb7simCddobSEp3jmLIMvVkLRZ7zW8,13339
33
33
  siat/esg.py,sha256=GMhaonIKtvOK83rhpQUH5aJt2OL3HQBSVfD__Yw-0oo,19040
34
34
  siat/esg_test.py,sha256=Z9m6GUt8O7oHZSEG9aDYpGdvvrv2AiRJdHTiU6jqmZ0,2944
35
- siat/event_study.py,sha256=GCZSMGOAxthVEcRVv9eerIX4RYT_9cnnR6PvIx2mMXE,23833
35
+ siat/event_study.py,sha256=HLfgXyr2a5GJZaHiQOlydkgx7DVdlbzThrL3bw8cEQs,29061
36
36
  siat/exchange_bond_china.pickle,sha256=zDqdPrFacQ0nqjP_SuF6Yy87EgijIRsFvFroW7FAYYY,1265092
37
37
  siat/fama_french.py,sha256=aUTC-67t_CEPbLk4u79woW_zfZ7OCP6Fo4z5EdWCSkQ,48051
38
38
  siat/fama_french_test.py,sha256=M4O23lBKsJxhWHRluwCb3l7HSEn3OFTjzGMpehcevRg,4678
@@ -141,8 +141,8 @@ siat/valuation_china.py,sha256=CVp1IwIsF3Om0J29RGkyxZLt4n9Ug-ua_RKhLwL9fUQ,69624
141
141
  siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
142
142
  siat/var_model_validation.py,sha256=R0caWnuZarrRg9939hxh3vJIIpIyPfvelYmzFNZtPbo,14910
143
143
  siat/yf_name.py,sha256=r0Q67cSMMlfebEkI9h9pdGlJCooEq7hw_3M5IUs4cSI,20081
144
- siat-3.7.1.dist-info/LICENSE,sha256=NTEMMROY9_4U1szoKC3N2BLHcDd_o5uTgqdVH8tbApw,1071
145
- siat-3.7.1.dist-info/METADATA,sha256=QEq7a5uvfG4GBQLwJDP2ARnKHjAG-4T_A16Bp45lBZc,8009
146
- siat-3.7.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
147
- siat-3.7.1.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
148
- siat-3.7.1.dist-info/RECORD,,
144
+ siat-3.7.2.dist-info/LICENSE,sha256=NTEMMROY9_4U1szoKC3N2BLHcDd_o5uTgqdVH8tbApw,1071
145
+ siat-3.7.2.dist-info/METADATA,sha256=oZuRuVwB5c3XwvB-P0hRuRo1vWlf549Va29ZO0sE230,8009
146
+ siat-3.7.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
147
+ siat-3.7.2.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
148
+ siat-3.7.2.dist-info/RECORD,,
File without changes
File without changes