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 +207 -81
- {siat-3.7.1.dist-info → siat-3.7.2.dist-info}/METADATA +1 -1
- {siat-3.7.1.dist-info → siat-3.7.2.dist-info}/RECORD +6 -6
- {siat-3.7.1.dist-info → siat-3.7.2.dist-info}/LICENSE +0 -0
- {siat-3.7.1.dist-info → siat-3.7.2.dist-info}/WHEEL +0 -0
- {siat-3.7.1.dist-info → siat-3.7.2.dist-info}/top_level.txt +0 -0
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=
|
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=
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
-
|
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
|
-
|
244
|
-
|
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
|
-
|
253
|
-
|
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'
|
310
|
+
if method_type=='market':
|
258
311
|
for t in ticker_name(ticker,ticker_type):
|
259
|
-
|
260
|
-
|
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
|
-
|
318
|
+
try:
|
319
|
+
df_ret[t+'_AR']=df_ret[t] - df_ret[t+"_predicted"]
|
320
|
+
except: continue
|
321
|
+
|
263
322
|
else: #按CAPM计算
|
264
|
-
|
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
|
-
|
274
|
-
|
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
|
-
|
277
|
-
|
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
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
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
|
-
|
292
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
310
|
-
|
311
|
-
|
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
|
347
|
-
method_name="
|
348
|
-
elif
|
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
|
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
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
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=
|
383
|
-
|
384
|
-
|
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
|
-
|
475
|
-
|
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]+","
|
@@ -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=
|
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.
|
145
|
-
siat-3.7.
|
146
|
-
siat-3.7.
|
147
|
-
siat-3.7.
|
148
|
-
siat-3.7.
|
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
|
File without changes
|