質問編集履歴
3
タイトルの変更
test
CHANGED
@@ -1 +1 @@
|
|
1
|
-
Pythonで日本株のスクリーニング
|
1
|
+
Pythonで日本株のスクリーニング 株価
|
test
CHANGED
File without changes
|
2
誤りの修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -24,19 +24,33 @@
|
|
24
24
|
|
25
25
|
# Variables
|
26
26
|
|
27
|
+
tickers = si.tickers_sp500()
|
28
|
+
|
29
|
+
tickers = [item.replace(".", "-") for item in tickers] # Yahoo Finance uses dashes instead of dots
|
30
|
+
|
31
|
+
index_name = '^GSPC' # S&P 500
|
32
|
+
|
27
33
|
start_date = datetime.datetime.now() - datetime.timedelta(days=365)
|
28
34
|
|
29
35
|
end_date = datetime.date.today()
|
30
36
|
|
37
|
+
exportList = pd.DataFrame(columns=['Stock', "RS_Rating", "50 Day MA", "150 Day Ma", "200 Day MA", "52 Week Low", "52 week High"])
|
38
|
+
|
39
|
+
returns_multiples = []
|
40
|
+
|
31
41
|
|
32
42
|
|
33
43
|
# Index Returns
|
34
44
|
|
35
|
-
index_df = pdr.get_data_yahoo(
|
45
|
+
index_df = pdr.get_data_yahoo(index_name, start_date, end_date)
|
46
|
+
|
47
|
+
index_df['Percent Change'] = index_df['Adj Close'].pct_change()
|
48
|
+
|
49
|
+
index_return = (index_df['Percent Change'] + 1).cumprod()[-1]
|
36
50
|
|
37
51
|
```
|
38
52
|
|
39
|
-
|
53
|
+
si.tickers_sp500()でS&P500の全銘柄の株価データは入手できます。このような方法ですべての日経採用銘柄の株価データを入手したいとき、どのようなコードを書けばよいのでしょうか?いろいろなサイトで調べたのですが、日本株の場合一括で株価データを入手する手段が見当たりませんでした。
|
40
54
|
|
41
55
|
ちなみに以下のトレンド解析プログラムで米国株をスクリーニングしています。
|
42
56
|
|
1
プログラム全貌の追加
test
CHANGED
File without changes
|
test
CHANGED
@@ -37,3 +37,211 @@
|
|
37
37
|
```
|
38
38
|
|
39
39
|
これでS&P500の全銘柄の1年分の株価データは入手できるのですが、^GSPCの部分を^N225に変更しても日本株の株価データが入手できません。すべての日経採用銘柄の株価データを入手したいとき、どのようなコードを書けばよいのでしょうか?いろいろなサイトで調べたのですが、日本株の場合一括で株価データを入手する手段が見当たりませんでした。
|
40
|
+
|
41
|
+
ちなみに以下のトレンド解析プログラムで米国株をスクリーニングしています。
|
42
|
+
|
43
|
+
```ここに言語を入力
|
44
|
+
|
45
|
+
# Imports
|
46
|
+
|
47
|
+
from pandas_datareader import data as pdr
|
48
|
+
|
49
|
+
from yahoo_fin import stock_info as si
|
50
|
+
|
51
|
+
from pandas import ExcelWriter
|
52
|
+
|
53
|
+
import yfinance as yf
|
54
|
+
|
55
|
+
import pandas as pd
|
56
|
+
|
57
|
+
import datetime
|
58
|
+
|
59
|
+
import time
|
60
|
+
|
61
|
+
yf.pdr_override()
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
# Variables
|
66
|
+
|
67
|
+
tickers = si.tickers_sp500()
|
68
|
+
|
69
|
+
tickers = [item.replace(".", "-") for item in tickers] # Yahoo Finance uses dashes instead of dots
|
70
|
+
|
71
|
+
index_name = '^GSPC' # S&P 500
|
72
|
+
|
73
|
+
start_date = datetime.datetime.now() - datetime.timedelta(days=365)
|
74
|
+
|
75
|
+
end_date = datetime.date.today()
|
76
|
+
|
77
|
+
exportList = pd.DataFrame(columns=['Stock', "RS_Rating", "50 Day MA", "150 Day Ma", "200 Day MA", "52 Week Low", "52 week High"])
|
78
|
+
|
79
|
+
returns_multiples = []
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
# Index Returns
|
84
|
+
|
85
|
+
index_df = pdr.get_data_yahoo(index_name, start_date, end_date)
|
86
|
+
|
87
|
+
index_df['Percent Change'] = index_df['Adj Close'].pct_change()
|
88
|
+
|
89
|
+
index_return = (index_df['Percent Change'] + 1).cumprod()[-1]
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
# Find top 30% performing stocks (relative to the S&P 500)
|
94
|
+
|
95
|
+
for ticker in tickers:
|
96
|
+
|
97
|
+
# Download historical data as CSV for each stock (makes the process faster)
|
98
|
+
|
99
|
+
df = pdr.get_data_yahoo(ticker, start_date, end_date)
|
100
|
+
|
101
|
+
df.to_csv(f'{ticker}.csv')
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
# Calculating returns relative to the market (returns multiple)
|
106
|
+
|
107
|
+
df['Percent Change'] = df['Adj Close'].pct_change()
|
108
|
+
|
109
|
+
stock_return = (df['Percent Change'] + 1).cumprod()[-1]
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
returns_multiple = round((stock_return / index_return), 2)
|
114
|
+
|
115
|
+
returns_multiples.extend([returns_multiple])
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
print (f'Ticker: {ticker}; Returns Multiple against S&P 500: {returns_multiple}\n')
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
# Creating dataframe of only top 30%
|
124
|
+
|
125
|
+
rs_df = pd.DataFrame(list(zip(tickers, returns_multiples)), columns=['Ticker', 'Returns_multiple'])
|
126
|
+
|
127
|
+
rs_df['RS_Rating'] = rs_df.Returns_multiple.rank(pct=True) * 100
|
128
|
+
|
129
|
+
rs_df = rs_df[rs_df.RS_Rating >= rs_df.RS_Rating.quantile(.70)]
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
# Checking Minervini conditions of top 30% of stocks in given list
|
134
|
+
|
135
|
+
rs_stocks = rs_df['Ticker']
|
136
|
+
|
137
|
+
for stock in rs_stocks:
|
138
|
+
|
139
|
+
try:
|
140
|
+
|
141
|
+
df = pd.read_csv(f'{stock}.csv', index_col=0)
|
142
|
+
|
143
|
+
sma = [50, 150, 200]
|
144
|
+
|
145
|
+
for x in sma:
|
146
|
+
|
147
|
+
df["SMA_"+str(x)] = round(df['Adj Close'].rolling(window=x).mean(), 2)
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
# Storing required values
|
152
|
+
|
153
|
+
currentClose = df["Adj Close"][-1]
|
154
|
+
|
155
|
+
moving_average_50 = df["SMA_50"][-1]
|
156
|
+
|
157
|
+
moving_average_150 = df["SMA_150"][-1]
|
158
|
+
|
159
|
+
moving_average_200 = df["SMA_200"][-1]
|
160
|
+
|
161
|
+
low_of_52week = round(min(df["Low"][-260:]), 2)
|
162
|
+
|
163
|
+
high_of_52week = round(max(df["High"][-260:]), 2)
|
164
|
+
|
165
|
+
RS_Rating = round(rs_df[rs_df['Ticker']==stock].RS_Rating.tolist()[0])
|
166
|
+
|
167
|
+
|
168
|
+
|
169
|
+
try:
|
170
|
+
|
171
|
+
moving_average_200_20 = df["SMA_200"][-20]
|
172
|
+
|
173
|
+
except Exception:
|
174
|
+
|
175
|
+
moving_average_200_20 = 0
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
# Condition 1: Current Price > 150 SMA and > 200 SMA
|
180
|
+
|
181
|
+
condition_1 = currentClose > moving_average_150 > moving_average_200
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
# Condition 2: 150 SMA and > 200 SMA
|
186
|
+
|
187
|
+
condition_2 = moving_average_150 > moving_average_200
|
188
|
+
|
189
|
+
|
190
|
+
|
191
|
+
# Condition 3: 200 SMA trending up for at least 1 month
|
192
|
+
|
193
|
+
condition_3 = moving_average_200 > moving_average_200_20
|
194
|
+
|
195
|
+
|
196
|
+
|
197
|
+
# Condition 4: 50 SMA> 150 SMA and 50 SMA> 200 SMA
|
198
|
+
|
199
|
+
condition_4 = moving_average_50 > moving_average_150 > moving_average_200
|
200
|
+
|
201
|
+
|
202
|
+
|
203
|
+
# Condition 5: Current Price > 50 SMA
|
204
|
+
|
205
|
+
condition_5 = currentClose > moving_average_50
|
206
|
+
|
207
|
+
|
208
|
+
|
209
|
+
# Condition 6: Current Price is at least 30% above 52 week low
|
210
|
+
|
211
|
+
condition_6 = currentClose >= (1.3*low_of_52week)
|
212
|
+
|
213
|
+
|
214
|
+
|
215
|
+
# Condition 7: Current Price is within 25% of 52 week high
|
216
|
+
|
217
|
+
condition_7 = currentClose >= (.75*high_of_52week)
|
218
|
+
|
219
|
+
|
220
|
+
|
221
|
+
# If all conditions above are true, add stock to exportList
|
222
|
+
|
223
|
+
if(condition_1 and condition_2 and condition_3 and condition_4 and condition_5 and condition_6 and condition_7):
|
224
|
+
|
225
|
+
exportList = exportList.append({'Stock': stock, "RS_Rating": RS_Rating ,"50 Day MA": moving_average_50, "150 Day Ma": moving_average_150, "200 Day MA": moving_average_200, "52 Week Low": low_of_52week, "52 week High": high_of_52week}, ignore_index=True)
|
226
|
+
|
227
|
+
print (stock + " made the Minervini requirements")
|
228
|
+
|
229
|
+
except Exception as e:
|
230
|
+
|
231
|
+
print (e)
|
232
|
+
|
233
|
+
print(f"Could not gather data on {stock}")
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
exportList = exportList.sort_values(by='RS_Rating', ascending=False)
|
238
|
+
|
239
|
+
print('\n', exportList)
|
240
|
+
|
241
|
+
writer = ExcelWriter("ScreenOutput.xlsx")
|
242
|
+
|
243
|
+
exportList.to_excel(writer, "Sheet1")
|
244
|
+
|
245
|
+
writer.save()
|
246
|
+
|
247
|
+
```
|