回答編集履歴

5

誤字

2020/02/11 03:58

投稿

gusachan3
gusachan3

スコア16

test CHANGED
@@ -64,7 +64,7 @@
64
64
 
65
65
  # データの保存場所を指定
66
66
 
67
- # この場合は、C:/Users/s-sug/Anaconda3/linear_regression/ を読み書きする
67
+ # この場合は、C:/Users/hoge/Anaconda3/linear_regression/ を読み書きする
68
68
 
69
69
 
70
70
 

4

字句の校正

2020/02/11 03:58

投稿

gusachan3
gusachan3

スコア16

test CHANGED
@@ -40,7 +40,7 @@
40
40
 
41
41
  追記)
42
42
 
43
- エラーが出たの、tqdm, datetime のインポート表記を変更・追加をしました。
43
+ エラーが出た箇所の、tqdm, datetime のインポート表記を変更・追加をしました。
44
44
 
45
45
  ```Python3
46
46
 

3

コードの追加

2020/02/11 02:51

投稿

gusachan3
gusachan3

スコア16

test CHANGED
@@ -38,13 +38,261 @@
38
38
 
39
39
  Notebook を再起動したときは各ブロックのimport したライブラリを、[run] ボタンでリロードしてますか。一応、写経したコードを貼っておきます。
40
40
 
41
+ 追記)
42
+
43
+ エラーが出たので、tqdm, datetime のインポート表記を変更・追加をしました。
44
+
41
45
  ```Python3
42
46
 
47
+ from IPython.core.display import display
48
+
49
+
50
+
51
+ from os import path
52
+
53
+ import re
54
+
55
+ import pandas as pd
56
+
57
+ import numpy as np
58
+
59
+ from tqdm.notebook import tqdm
60
+
61
+ import datetime
62
+
63
+
64
+
65
+ # データの保存場所を指定
66
+
67
+ # この場合は、C:/Users/s-sug/Anaconda3/linear_regression/ を読み書きする
68
+
69
+
70
+
71
+ WORK_DIR = 'C:/Users/hoge/Anaconda3/linear_regression/'
72
+
43
- DATA_DIR = 'C:/Users/hoge/Anaconda3/linear_regression/data/' # (パスは適宜変えてください)
73
+ DATA_DIR = 'C:/Users/hoge/Anaconda3/linear_regression/data/'
44
-
74
+
45
- DATA_CHAPTER1 = 'C:/Users/hoge/Anaconda3/data/download_data/' # (パスは適宜変えてください)
75
+ DATA_CHAPTER1 = 'C:/Users/hoge/Anaconda3/data/download_data/'
76
+
77
+
78
+
46
-
79
+ daily_data = pd.read_pickle(f"{DATA_CHAPTER1}daily_data.pickle")
80
+
81
+
82
+
47
-
83
+ # 銘柄ごとに計算するため、証券コード(SC)で集計する
84
+
85
+ groups = daily_data.groupby('SC')
86
+
87
+
88
+
89
+ data_set = []
90
+
91
+ for security, values in tqdm(groups):
92
+
93
+ # 全体の10%以上の取引日で取引のない銘柄は無視する
94
+
95
+ if values['株価'].isnull().sum() > values.shape[0]*0.1:
96
+
97
+ continue
98
+
99
+
100
+
101
+ # 一時的に market_value 列を作って計算する
102
+
103
+ # 証券コード(SC)1、2 は株価指数を表しているので、単純に指数値を入れる
104
+
105
+ if security in {1, 2}:
106
+
107
+ values = values.assign(market_value = lambda x: x['株価'])
108
+
109
+ else:
110
+
111
+ values = values.assign(market_value = lambda x: x['時価総額(百万円)'])
112
+
113
+
114
+
115
+ # calculation return
116
+
117
+ values = values.sort_values('日時') # 時系列でソート
118
+
119
+ values['収益率'] = values['market_value'].pct_change() # 変化率の計算
120
+
121
+ values.drop(columns = ['market_value']) # 一時的な列を削除
122
+
123
+ data_set.append(values)
124
+
125
+
126
+
127
+ daily_data_adj = pd.concat(data_set) # 銘柄ごとに計算したものを結合
128
+
129
+
130
+
131
+ # 極端な値を外れ値として削除。ここでは上下 0.1% を外れ値とする
132
+
133
+ threshold = 0.001
134
+
135
+
136
+
137
+ lower = daily_data_adj['収益率'].quantile(threshold)
138
+
139
+ upper = daily_data_adj['収益率'].quantile(1-threshold)
140
+
141
+
142
+
143
+ daily_data_adj = daily_data_adj[
144
+
145
+ (lower < daily_data_adj['収益率']) & (daily_data_adj['収益率'] < upper)
146
+
147
+ ].copy()
148
+
149
+
150
+
151
+ #############################################################
152
+
153
+
154
+
155
+ jgb_path = f'{DATA_DIR}risk_free_rate/jgbcm_all.csv'
156
+
157
+ risk_free_rate = pd.read_csv(
158
+
159
+ jgb_path,
160
+
161
+ skiprows=1,
162
+
163
+ usecols=['基準日', '10年'],
164
+
165
+ parse_dates=['基準日'],
166
+
167
+ encoding='sjis',
168
+
169
+ index_col=['基準日'],
170
+
171
+ na_values='-'
172
+
173
+ )
174
+
175
+
176
+
177
+ risk_free_rate = risk_free_rate['10年'].apply(
178
+
179
+ # 半年複利(%表記)を日時対数収益率に変換
180
+
181
+ lambda x: np.log(1 + 0.01 * 0.5 * x) / 125
182
+
183
+ ).apply(
184
+
185
+ # 単利へ変換
186
+
187
+ lambda x: np.exp(x) -1
188
+
189
+ )
190
+
191
+ risk_free_rate.rename('安全資産利子率', inplace=True)
192
+
193
+ risk_free_rate.index.rename('日時', inplace=True)
194
+
195
+
196
+
197
+ risk_free_rate = pd.DataFrame(risk_free_rate)
198
+
199
+
200
+
201
+ # 出力して結果を確認
202
+
203
+ display(risk_free_rate.dropna().head())
204
+
205
+
206
+
207
+ ############################################################
208
+
209
+
210
+
211
+ stock_return_and_risk_free_return = pd.merge(
212
+
213
+ daily_data_adj[daily_data_adj['SC'] > 2],
214
+
215
+ risk_free_rate, on='日時'
216
+
217
+ )
218
+
219
+
220
+
221
+ # SC と日時を index にする
222
+
223
+ stock_return_and_risk_free_return.set_index(
224
+
225
+ ['SC', '日時'],
226
+
227
+ verify_integrity=True,
228
+
229
+ inplace=True
230
+
231
+ )
232
+
233
+ # 出力して結果を確認
234
+
235
+ display(stock_return_and_risk_free_return.head())
236
+
237
+
238
+
239
+ ############################################################
240
+
241
+
242
+
243
+ # 日時で集計
244
+
245
+ group_by_date = stock_return_and_risk_free_return.groupby('日時')
246
+
247
+
248
+
249
+ data_with_market_returns = []
250
+
251
+ for date, values in tqdm(group_by_date):
252
+
253
+ sum_of_market_capital = values['時価総額(百万円)'].sum()
254
+
255
+ values = values.assign(
256
+
257
+ # retuen がすべて null なら null にする
258
+
259
+ 市場収益率 = lambda x: (
260
+
261
+ x['収益率'] * (x['時価総額(百万円)'] / sum_of_market_capital)
262
+
263
+ ).sum(
264
+
265
+ min_count=1
266
+
267
+ )
268
+
269
+ )
270
+
271
+ data_with_market_returns.append(values)
272
+
273
+
274
+
275
+ data_with_market_returns = pd.concat(data_with_market_returns)
276
+
277
+
278
+
279
+ display(data_with_market_returns.head())
280
+
281
+
282
+
283
+ ############################################################
284
+
285
+ data_with_excess_returns = data_with_market_returns.assign(
286
+
287
+ 超過収益率 = lambda x: x['収益率'] -x['安全資産利子率'],
288
+
289
+ 市場超過収益率 = lambda x: x['市場収益率'] -x['安全資産利子率']
290
+
291
+ )
292
+
293
+
294
+
295
+ ###########################################################
48
296
 
49
297
  # 扱いやすくするために index を通常の列に戻す
50
298
 

2

コードの追加

2020/02/11 02:48

投稿

gusachan3
gusachan3

スコア16

test CHANGED
@@ -33,3 +33,185 @@
33
33
  temporary_list.append(aligned)
34
34
 
35
35
  ```
36
+
37
+
38
+
39
+ Notebook を再起動したときは各ブロックのimport したライブラリを、[run] ボタンでリロードしてますか。一応、写経したコードを貼っておきます。
40
+
41
+ ```Python3
42
+
43
+ DATA_DIR = 'C:/Users/hoge/Anaconda3/linear_regression/data/' # (パスは適宜変えてください)
44
+
45
+ DATA_CHAPTER1 = 'C:/Users/hoge/Anaconda3/data/download_data/' # (パスは適宜変えてください)
46
+
47
+
48
+
49
+ # 扱いやすくするために index を通常の列に戻す
50
+
51
+ temporary_data_excess_returns = data_with_excess_returns.reset_index()
52
+
53
+
54
+
55
+ # read financial data
56
+
57
+ financial_data = pd.read_pickle(
58
+
59
+ f'{DATA_CHAPTER1}financial_data_all.pickle'
60
+
61
+ )
62
+
63
+
64
+
65
+ # 利用しない列を削除
66
+
67
+ financial_data.drop(
68
+
69
+ columns=['発行済株式数', '日時'],
70
+
71
+ inplace=True
72
+
73
+ )
74
+
75
+
76
+
77
+ # 決算発表日の株価データとマージできるように、株価データに決算発表日を張る
78
+
79
+ group_by_security = temporary_data_excess_returns.groupby('SC')
80
+
81
+
82
+
83
+ temporary_list = []
84
+
85
+ for security, values in tqdm(group_by_security):
86
+
87
+
88
+
89
+ # 財務データから決算発表日を取得
90
+
91
+ # 例: array(
92
+
93
+ # ['2016-05-11T00:00:00.000000000', '2017-05-T00:00:00.000000000'],
94
+
95
+ # dtype='datetime64[ns]'
96
+
97
+ # )
98
+
99
+ announcement_dates = financial_data[
100
+
101
+ '決算発表日(本決算)'
102
+
103
+ ][
104
+
105
+ financial_data.SC == security
106
+
107
+ ].dropna().unique()
108
+
109
+
110
+
111
+ # 古いソートにして np.array に戻す
112
+
113
+ announcement_dates = pd.Series(announcement_dates).sort_values().values
114
+
115
+
116
+
117
+ # 収益率データの「日時」が含まれる決算期を意味するカテゴリカル変数を作る
118
+
119
+ # 例:「日時」が 2016-05-11 より前 → 欠損値、
120
+
121
+ #   「日時」が 2016-05-11 ~ 2017-05-11 → 2016-05-11、など
122
+
123
+
124
+
125
+ aligned = values.assign(
126
+
127
+ announcement_date = lambda x: pd.cut(
128
+
129
+ x['日時'],
130
+
131
+ (
132
+
133
+ list(announcement_dates)
134
+
135
+ ) + [np.datetime64(values['日時'].max() + pd.offsets.Day())],
136
+
137
+ labels = announcement_dates,
138
+
139
+ right=False
140
+
141
+ ).astype(
142
+
143
+ np.datetime64
144
+
145
+ )
146
+
147
+ )
148
+
149
+ temporary_list.append(aligned)
150
+
151
+
152
+
153
+ temporary_data_excess_returns = pd.concat(temporary_list)
154
+
155
+ temporary_data_excess_returns.rename(
156
+
157
+ columns = {'announcement_date':'決算発表日(日時)'},
158
+
159
+ inplace=True
160
+
161
+ )
162
+
163
+ del temporary_list
164
+
165
+
166
+
167
+ # 財務データを決算発表日について一意にする
168
+
169
+ financial_data = financial_data.groupby(
170
+
171
+ ['SC', '決算発表日(本決算)']
172
+
173
+ ).first().reset_index()
174
+
175
+
176
+
177
+ excess_returns_with_financial_data = pd.merge(
178
+
179
+ temporary_data_excess_returns,
180
+
181
+ financial_data,
182
+
183
+ left_on=['SC', '名称', '決算発表日(日時)'],
184
+
185
+ right_on=['SC', '名称', '決算発表日(本決算)'],
186
+
187
+ how='left'
188
+
189
+ )
190
+
191
+
192
+
193
+ excess_returns_with_financial_data.set_index(
194
+
195
+ ['SC', '日時'],
196
+
197
+ inplace=True,
198
+
199
+ verify_integrity=True
200
+
201
+ )
202
+
203
+
204
+
205
+ del temporary_data_excess_returns
206
+
207
+
208
+
209
+ # データを pickle で保存
210
+
211
+ excess_returns_with_financial_data.to_pickle(
212
+
213
+ f'{DATA_DIR}excess_returns_with_financial_data.pickle'
214
+
215
+ )
216
+
217
+ ```

1

コード挿入

2020/02/09 12:45

投稿

gusachan3
gusachan3

スコア16

test CHANGED
@@ -3,6 +3,8 @@
3
3
  本の通りにやったらできましたよ。以下のコードが欠損してますが大丈夫ですか?
4
4
 
5
5
 
6
+
7
+ ```python3
6
8
 
7
9
  aligned = values.assign(
8
10
 
@@ -29,3 +31,5 @@
29
31
  )
30
32
 
31
33
  temporary_list.append(aligned)
34
+
35
+ ```