概述

这是一篇对于《投资者情绪与债券风险溢价》论文的SAS复现。所有的包括数据、论文、回归结果、完整代码都放到了Github仓库

论文

在仓库里,点击Laborda and Olmo 2014 .pdf即可阅读。论文的内容是讨论投资者情绪与债券风险溢价的关系,简单讲就是利用投资者情绪的数据,宏观经济数据和债券风险溢价数据作回归。

数据

所有的数据都在sentiment文件夹内。

代码

注意使用代码运行的时候先修改第一行的数据路径为你保存数据的路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
/*You need to change the directory of the lib to replicate the project*/
%let Project = sentiment/;

/*A sas format of Fama_Bliss*/
data Fama_Bliss;
infile "&Project/Fama_Bliss_price.txt" FIRSTOBS=2;
input date YYMMDD8. price1 price2 price3 price4 price5;
if _n_ > 1;
format date YYMMDD10.;
run;

/**********************/
/*For counting y_t^(n)*/
/**********************/
%macro county;
%do i = 1 %to 5;
data y_&i (keep = date y_&i);
set Fama_Bliss;
y_&i = - (1/&i)*log(price&i);
run;

%if &i = 1 %then %do;
data y_all;
set y_&i;
run;
%end;

%else %do;
data y_all;
merge y_all y_&i;
by date;
run;
%end;

%end;

%mend county;
%county;


/*****************************/
/*For counting f_t^{n to n+1}*/
/*****************************/
%macro countf;
%do i = 1 %to 4;
%let iplus = %eval(&i+1);
data f_&i (keep = date f_&i);
set Fama_Bliss;
f_&i = price&i - price&iplus;
run;

%if &i = 1 %then %do;
data f_all;
set f_&i;
run;
%end;

%else %do;
data f_all;
merge f_all f_&i;
by date;
run;
%end;

%end;

%mend countf;
%countf;


/**************************/
/*For counting r_{t+1}^{n}*/
/**************************/
%macro countr;
%do i = 1 %to 4;
%let iplus = %eval(&i+1);
data r_&i (keep = date r_&iplus);
set Fama_Bliss;
price_lag&iplus = lag(price&iplus);
r_&iplus = price&i - price_lag&iplus;
run;

%if &i = 1 %then %do;
data r_all;
set r_&i;
run;
%end;

%else %do;
data r_all;
merge r_all r_&i;
by date;
run;
%end;

%end;

%mend countr;
%countr;


/***************************/
/*For counting rx_{t+1}^{n}*/
/***************************/
/*Need merge first*/
data Fama_Bliss_all;
merge Fama_Bliss r_all y_all f_all;
by date;
run;

%macro countrx;
%do i = 1 %to 4;
%let iplus = %eval(&i+1);
data rx_&i (keep = date rx_&iplus);
set Fama_Bliss_all;
y_lag_1 = lag (y_1);
rx_&iplus = r_&iplus - y_lag_1;
run;

%if &i = 1 %then %do;
data rx_all;
set rx_&i;
run;
%end;

%else %do;
data rx_all;
merge rx_all rx_&i;
by date;
run;
%end;

%end;

%mend countrx;
%countrx;


/*******************/
/*For counting rxba*/
/*******************/
data rxba (keep = rxba date);
set rx_all;
rxba = 1/4 * (rx_2 + rx_3 + rx_4 + rx_5);
run;


/*******************/
/*For counting CP_t*/
/*******************/
/*Merge data first*/
data Fama_Bliss_all;
merge Fama_Bliss_all rxba;
by date;
y_lag_1 = lag (y_1);
f_lag_1 = lag (f_1);
f_lag_2 = lag (f_2);
f_lag_3 = lag (f_3);
f_lag_4 = lag (f_4);
run;

data for_reg;
set Fama_Bliss_all(Firstobs=2);
run;
/*REG and get the fit value*/
proc model data = for_reg outparms=CP_t;
parm b0-b5;
rxba = b0 + b1 * y_lag_1 + b2 * f_lag_1 + b3 * f_lag_2 + b4 * f_lag_3 + b5 * f_lag_4;
fit rxba;
run;
/*Get the Fitted Value*/
data CP_t;
set CP_t;
merge_temp = 1;
run;

data for_reg;
set for_reg;
merge_temp = 1;
run;

data fit;
merge CP_t for_reg;
by merge_temp;
run;

data CP(keep=CP date);
set fit;
CP = b0 + b1 * y_lag_1 + b2 * f_lag_1 + b3 * f_lag_2 + b4 * f_lag_3 + b5 * f_lag_4;
if CP = . then delete;
run;


/*************/
/*Counting LN*/
/*************/
proc import datafile = "&Project/Updated_LN_Macro_Factors_2018AUG.xlsx"
OUT = LN
DBMS = xlsx replace;
run;
/*Change the date to be month*/
data rxba;
set rxba;
year = year (date);
month = month (date);
run;

data LN;
set LN;
year = year (data);
month = month (data);
run;
/*Merge and calculate LN*/
data for_reg;
merge LN(in = a) rxba(in = b);
by year month;
if a=1 and b=1;
run;
data for_reg;
set for_reg;
F1_lag = lag (F1);
F13_lag = lag (F13);
F3_lag = lag (F3);
F4_lag = lag (F4);
F8_lag = lag (F8);
run;
proc model data = for_reg outparms=LN_t;
parm b0-b5;
rxba = b0 + b1 * F1_lag + b2 * F13_lag + b3 * F3_lag + b4 * F4_lag + b5 * F8_lag;
fit rxba;
run;
/*Get the Fitted Value*/
data LN_t;
set LN_t;
merge_temp = 1;
run;

data for_reg;
set for_reg;
merge_temp = 1;
run;

data fit;
merge LN_t for_reg;
by merge_temp;
run;

data LN(keep=LN year month);
set fit;
LN = b0 + b1 * F1_lag + b2 * F13_lag + b3 * F3_lag + b4 * F4_lag + b5 * F8_lag;
if LN = . then delete;
run;

data CP (keep = CP year month);
set CP;
year = year (date);
month = month (date);
run;

/*************/
/*Counting BW*/
/*************/

proc import datafile = "&Project/Copy of Investor_Sentiment_Data_20160331_POST.xlsx"
OUT = BW
DBMS = xlsx replace;
Sheet = DATA;
run;

data BW;
set BW;
month = mod(yearmo,100);
year = (yearmo - month ) / 100;
run;

data BW;
merge BW(in=a) rxba(in=b);
by year month;
if a = 1 and b = 1;
run;

data for_reg;
set BW;
deltaSent = dif(SENT);
SENT = lag(SENT);
SENT2 = lag(SENT2);
deltaSent = lag(deltaSent);
run;

proc model data = for_reg outparms=BW_t;
parm b0-b3;
rxba = b0 + b1 * SENT + b2 * SENT2 + b3 * deltaSENT;
fit rxba;
run;
/*Get the Fitted Value*/
data BW_t;
set BW_t;
merge_temp = 1;
run;

data for_reg;
set for_reg;
merge_temp = 1;
run;

data fit;
merge BW_t for_reg;
by merge_temp;
run;

data BW(keep=BW year month);
set fit;
BW = b0 + b1 * SENT + b2 * SENT2 + b3 * deltaSENT;
if BW = . then delete;
run;


/******************/
/*Final Regression*/
/******************/
data rx_all;
set rx_all;
year = year (date);
month = month (date);
run;

data final(drop = date);
merge CP(in = a) BW(in = b) LN(in = c) rx_all(in = d);
by year month;
if a = 1 and b = 1 and c = 1 and d = 1;
run;

%macro predict;
%do i = 2 %to 5;
proc reg data = final outest = rx_predict_&i;
model rx_&i = CP BW LN;
run;

%if i=2 %then %do;
data rx_predict_all;
set rx_predict_&i;
run;
%end;
%else %do;
data rx_predict_all;
set rx_predict_all rx_predict_&i;
run;
%end;
%end;
%mend predict;
%predict;

proc export data=rx_predict_all
outfile="&Project/rx_predict_all.csv";
run;

结果

最后的结果是在sentiment文件夹生成一个rx_predict.csv,我也将我跑出来的结果放在了仓库根目录里,如果两者相同的话,说明跑成功了。中间的回归过程的结果太长了,可以参阅这里

这里简单挑一个回归放一下中间结果。

中间结果