import urllib.request
import urllib.parse
import pandas as pd
import numpy as np
import datetime # 現在日取得表
import os # ファイル操作用
import time # スリープ用
import sys # コマンドライン引数取得用
import re # 正規表現用
"""
■■■ 関数定義
"""
"""
WEBサイト「株式投資メモ」からCSVファイルをダウンロードする
"""
def download(code, year):
url = 'https://kabuoji3.com/stock/file.php'
params = urllib.parse.urlencode({'code': code, 'year': year}).encode('utf-8')
request = urllib.request.Request(url, params)
response = urllib.request.urlopen(request)
if 200 != response.getcode():
print('[ERROR] ダウンロード失敗 [URL] ' + url + ' [HTTP Status Code] ' + response.getcode())
return(false)
csv = response.read()
return(csv.decode('shift-jis'))
"""
■■■ メイン処理
"""
"""
コマンドライン引数の取得・バリデーションチェック
"""
args = sys.argv
if 2 > len(args):
print('[ERROR] 引数に証券コードを指定してください')
print('例)python download.py 9999')
exit()
code = args[1]
year_start = 2000
year_end = datetime.date.today().year
if 2 < len(args):
pattern1 = '[0-9]{4}-[0-9]{4}'
matcher1 = re.compile(pattern1)
pattern2 = '[0-9]{4}-'
matcher2 = re.compile(pattern2)
pattern3 = '-[0-9]{4}'
matcher3 = re.compile(pattern3)
pattern4 = '[0-9]{4}'
matcher4 = re.compile(pattern4)
result1 = matcher1.match(args[2])
result2 = matcher2.match(args[2])
result3 = matcher3.match(args[2])
result4 = matcher4.match(args[2])
if result1:
y = result1.group().split('-')
year_start = y[0]
year_end = y[1]
elif result2:
year_start = result2.group()[:4]
elif result3:
year_end = result3.group()[1:]
elif result4:
year_start = result4.group()
year_end = result4.group()
else:
print('[ERROR] 第2引数は、省略しない場合、西暦を指定してください(範囲指定可)')
print('例)python download.py 9999 2000-2019')
exit()
if int(year_start) > int(year_end) or datetime.date.today().year < int(year_end):
print('[ERROR] 第2引数の西暦指定が不正です [Start] ' + str(year_start) + ' [End] ' + str(year_end))
exit()
if not os.path.exists('data'):
os.mkdir('data')
if not os.path.exists('data/' + str(code)):
os.mkdir('data/' + str(code))
"""
年毎の株価データのCSVファイルをダウンロードして保存
"""
years = list(range(int(year_start), int(year_end) + 1))
for year in years:
filepath = 'data/' + str(code) + '/' + str(code) + '_' + str(year) + '.csv'
if os.path.exists(filepath):
if year == datetime.date.today().year:
# 現在年の場合は最新を再取得する
os.remove(filepath)
else:
continue
data = download(code, year)
if data == False:
exit()
with open(filepath, 'w') as saveFile:
saveFile.write(data)
print('[INFO] CSVファイルダウンロード成功 [FILE] ' + filepath)
# サイトに負荷を掛けないように間隔を開けてリクエストする
time.sleep(3)
"""
年毎の株価データのCSVファイルを読み込み、1つの配列に結合
"""
years = list(range(int(year_start), int(year_end) + 1))
df_all = pd.DataFrame
for year in years:
filepath = 'data/' + str(code) + '/' + str(code) + '_' + str(year) + '.csv'
df = pd.read_csv(filepath,
header=1,
index_col=0,
encoding="shift-jis")
if df_all.empty:
df_all = df
else:
df_all = pd.concat([df_all, df])
# indexを振り直す
df_all = df_all.reset_index()
# 型を指定
df_all['日付'] = df_all['日付'].astype(np.datetime64)
df_all['高値'] = df_all['高値'].astype(np.float32)
df_all['安値'] = df_all['安値'].astype(np.float32)
df_all['終値'] = df_all['終値'].astype(np.float32)
df_all['終値調整値'] = df_all['終値調整値'].astype(np.float32)
"""
前処理①:欠損値があれば補完する
"""
missing_value_count = df_all.isnull().values.sum()
if missing_value_count == 0:
print('[INFO] 欠損値はありません')
else:
print('[INFO] 欠損値を穴埋めします(欠損値:' + str(missing_value_count) + '個)')
df_all.fillna(method='ffill') # 欠損値を前の値で置き換える
"""
前処理②:株式分割・株式併合によるズレを調整する
"""
adjust_count = 0
for index, row in df_all.iterrows():
if row['終値'] != row['終値調整値']:
# 終値に調整が入っている場合、それを元に他の値も調整する
adjust_count = adjust_count + 1
df_all.at[index, '高値'] = row['高値'] * row['終値調整値'] / row['終値']
df_all.at[index, '安値'] = row['安値'] * row['終値調整値'] / row['終値']
df_all.at[index, '終値'] = row['終値調整値']
df_all.at[index, '出来高'] = row['出来高'] * row['終値'] / row['終値調整値']
else:
df_all.at[index, '終値'] = row['終値調整値']
if adjust_count == 0:
print('[INFO] 株式分割・株式併合によるズレはありません')
else:
print('[INFO] 株式分割・株式併合によるズレを調整しました')
"""
前処理③:不要な列を削除
"""
df_all = df_all.drop('始値', axis=1)
df_all = df_all.drop('終値調整値', axis=1)
"""
連結と前処理を行った全株価データをCSVファイルに保存
"""
filepath = 'data/' + str(code) + '_all.csv'
df_all.to_csv(filepath,
index=False,
encoding="shift-jis")
print('[INFO] 株価データ取得完了 [FILE] ' + filepath)
import urllib.parse
import pandas as pd
import numpy as np
import datetime # 現在日取得表
import os # ファイル操作用
import time # スリープ用
import sys # コマンドライン引数取得用
import re # 正規表現用
"""
■■■ 関数定義
"""
"""
WEBサイト「株式投資メモ」からCSVファイルをダウンロードする
"""
def download(code, year):
url = 'https://kabuoji3.com/stock/file.php'
params = urllib.parse.urlencode({'code': code, 'year': year}).encode('utf-8')
request = urllib.request.Request(url, params)
response = urllib.request.urlopen(request)
if 200 != response.getcode():
print('[ERROR] ダウンロード失敗 [URL] ' + url + ' [HTTP Status Code] ' + response.getcode())
return(false)
csv = response.read()
return(csv.decode('shift-jis'))
"""
■■■ メイン処理
"""
"""
コマンドライン引数の取得・バリデーションチェック
"""
args = sys.argv
if 2 > len(args):
print('[ERROR] 引数に証券コードを指定してください')
print('例)python download.py 9999')
exit()
code = args[1]
year_start = 2000
year_end = datetime.date.today().year
if 2 < len(args):
pattern1 = '[0-9]{4}-[0-9]{4}'
matcher1 = re.compile(pattern1)
pattern2 = '[0-9]{4}-'
matcher2 = re.compile(pattern2)
pattern3 = '-[0-9]{4}'
matcher3 = re.compile(pattern3)
pattern4 = '[0-9]{4}'
matcher4 = re.compile(pattern4)
result1 = matcher1.match(args[2])
result2 = matcher2.match(args[2])
result3 = matcher3.match(args[2])
result4 = matcher4.match(args[2])
if result1:
y = result1.group().split('-')
year_start = y[0]
year_end = y[1]
elif result2:
year_start = result2.group()[:4]
elif result3:
year_end = result3.group()[1:]
elif result4:
year_start = result4.group()
year_end = result4.group()
else:
print('[ERROR] 第2引数は、省略しない場合、西暦を指定してください(範囲指定可)')
print('例)python download.py 9999 2000-2019')
exit()
if int(year_start) > int(year_end) or datetime.date.today().year < int(year_end):
print('[ERROR] 第2引数の西暦指定が不正です [Start] ' + str(year_start) + ' [End] ' + str(year_end))
exit()
if not os.path.exists('data'):
os.mkdir('data')
if not os.path.exists('data/' + str(code)):
os.mkdir('data/' + str(code))
"""
年毎の株価データのCSVファイルをダウンロードして保存
"""
years = list(range(int(year_start), int(year_end) + 1))
for year in years:
filepath = 'data/' + str(code) + '/' + str(code) + '_' + str(year) + '.csv'
if os.path.exists(filepath):
if year == datetime.date.today().year:
# 現在年の場合は最新を再取得する
os.remove(filepath)
else:
continue
data = download(code, year)
if data == False:
exit()
with open(filepath, 'w') as saveFile:
saveFile.write(data)
print('[INFO] CSVファイルダウンロード成功 [FILE] ' + filepath)
# サイトに負荷を掛けないように間隔を開けてリクエストする
time.sleep(3)
"""
年毎の株価データのCSVファイルを読み込み、1つの配列に結合
"""
years = list(range(int(year_start), int(year_end) + 1))
df_all = pd.DataFrame
for year in years:
filepath = 'data/' + str(code) + '/' + str(code) + '_' + str(year) + '.csv'
df = pd.read_csv(filepath,
header=1,
index_col=0,
encoding="shift-jis")
if df_all.empty:
df_all = df
else:
df_all = pd.concat([df_all, df])
# indexを振り直す
df_all = df_all.reset_index()
# 型を指定
df_all['日付'] = df_all['日付'].astype(np.datetime64)
df_all['高値'] = df_all['高値'].astype(np.float32)
df_all['安値'] = df_all['安値'].astype(np.float32)
df_all['終値'] = df_all['終値'].astype(np.float32)
df_all['終値調整値'] = df_all['終値調整値'].astype(np.float32)
"""
前処理①:欠損値があれば補完する
"""
missing_value_count = df_all.isnull().values.sum()
if missing_value_count == 0:
print('[INFO] 欠損値はありません')
else:
print('[INFO] 欠損値を穴埋めします(欠損値:' + str(missing_value_count) + '個)')
df_all.fillna(method='ffill') # 欠損値を前の値で置き換える
"""
前処理②:株式分割・株式併合によるズレを調整する
"""
adjust_count = 0
for index, row in df_all.iterrows():
if row['終値'] != row['終値調整値']:
# 終値に調整が入っている場合、それを元に他の値も調整する
adjust_count = adjust_count + 1
df_all.at[index, '高値'] = row['高値'] * row['終値調整値'] / row['終値']
df_all.at[index, '安値'] = row['安値'] * row['終値調整値'] / row['終値']
df_all.at[index, '終値'] = row['終値調整値']
df_all.at[index, '出来高'] = row['出来高'] * row['終値'] / row['終値調整値']
else:
df_all.at[index, '終値'] = row['終値調整値']
if adjust_count == 0:
print('[INFO] 株式分割・株式併合によるズレはありません')
else:
print('[INFO] 株式分割・株式併合によるズレを調整しました')
"""
前処理③:不要な列を削除
"""
df_all = df_all.drop('始値', axis=1)
df_all = df_all.drop('終値調整値', axis=1)
"""
連結と前処理を行った全株価データをCSVファイルに保存
"""
filepath = 'data/' + str(code) + '_all.csv'
df_all.to_csv(filepath,
index=False,
encoding="shift-jis")
print('[INFO] 株価データ取得完了 [FILE] ' + filepath)