実験用ブログ

・勉強したことをメモしておく

株価データ取得

2019-10-12 20:41:30 | 勉強
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)


波の合成

2019-10-08 07:24:20 | 勉強
SynthesizeAnalyseWave

メモ

株価変動の分解と合成
元の株価変動を、以下の4つの★に分解する

★ A : 元値の75日平均
  B : 元値 - A
★ C : Bの25日平均
  D : B - C
★ E : Dの5日平均
★ F : D - E(最終的な日足の値)

# 配列計算
import pandas as pd
import numpy

# グラフ描画
import matplotlib as mpl
import matplotlib.pyplot as plt

csv_data = pd.read_csv('./4719_all.csv',
header=0,
encoding="shift-jis")

"""
N日平均を求め、列追加する.
値がNaNとなった行(先頭からN-1行)は削除する.

Parameters
----------
df : pandas.DataFrame
target_column : N日平均を求める列
result_column : 計算結果の列
days : 平均を求める日数(N)
"""
def appendAverageColumn(df, target_column, result_column, days):
df[result_column] = df[target_column].rolling(window=days).mean()
return(df[days-1:])


# debug OK
# print(csv_data) # => [2386 rows x 7 columns]
# print(appendAverageColumn(csv_data, '終値調整値', 'A', 75)) # => [2312 rows x 8 columns]

"""
(列1 - 列2)の差を求め、列追加する.

Parameters
----------
df : pandas.DataFrame
column1 : 減算される列
column2 : 減算する列
result_column : 計算結果の列
"""
def appendDiffColumn(df, column1, column2, result_column):
df2 = df.copy()
df2[result_column] = df2.loc[:,[column2, column1]].astype('float32').diff(axis=1).loc[:,[column1]]
return(df2)

# debug OK
# df2 = appendAverageColumn(csv_data, '終値調整値', 'A', 75)
# print(df2) # => [2312 rows x 8 columns]
# print(appendDiffColumn(df2, '終値調整値', 'A', 'B')) # => [2312 rows x 9 columns]


def analyse4waves(df, days1, days2, days3):
appendAverageColumn(df, '終値調整値', result_column, days)


すごろくメモ5

2019-02-20 01:57:46 | 勉強
Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)

Sub テスト()
ActiveSheet.Shapes("メッセージエリア").Select
For i = 1 To 30
Selection.ShapeRange.ScaleWidth 1.05, msoFalse, msoScaleFromMiddle
Sleep 5
DoEvents
Next i
Sleep 100
DoEvents
For i = 1 To 30
Selection.ShapeRange.ScaleWidth 0.95, msoFalse, msoScaleFromMiddle
Sleep 5
DoEvents
Next i
Cells(1, 1).Select
End Sub

すごろくメモ4

2019-02-03 21:13:03 | 勉強
Dim currentWeek As String
currentWeek = ""

'先週までの集計
lastWeekScore = 0
For currentRow = 16 To lastRow
tmpWeek = ActiveSheet.Cells(currentRow, 12)
If tmpWeek <> "" Then
ret = Filter(weekList, tmpWeek)
If UBound(ret) <> -1 Then
currentWeek = tmpWeek
End If
End If

'今週の行に到達したところで、先週までの集計は終了
If currentWeek = week Then
Exit For
End If

'第1週に到達したところから集計開始(第1週より上の行はスキップ)
If currentWeek <> "" Then
lastWeekScore = lastWeekScore + ActiveSheet.Cells(currentRow, scoreClm).Value
End If
Next currentRow

'今週の集計
thisWeekScore = 0
For currentRow = currentRow To lastRow
tmpWeek = ActiveSheet.Cells(currentRow, 12)
If tmpWeek <> "" Then
ret = Filter(weekList, tmpWeek)
If UBound(ret) <> -1 Then
currentWeek = tmpWeek
End If
End If

'今週の行が終わったところで、今週の集計は終了
If currentWeek <> week Then
lastWeekScore = lastWeekScore + ActiveSheet.Cells(currentRow, scoreClm).Value
End If
Next currentRow
MsgBox lastWeekScore


すごろくメモ3

2019-01-31 23:12:49 | 勉強

Sub 進む_Click()
'キャラクタを取得
With DropDowns("ドロップ 11")
person = .List(.ListIndex)
End With

'集計
'選択した人の列を取得
clm = 0
For i = 12 To 30
If person = ActiveSheet.Cells(16, i).Value Then
clm = i
Exit For
End If
Next i
MsgBox clm

'最終行を取得
last_row_flame = ActiveSheet.Cells(Rows.Count, 14).End(xlUp).Row
last_row_person = ActiveSheet.Cells(Rows.Count, clm).End(xlUp).Row
MsgBox (last_row_flame & "aaa" & last_row_person)


' Call キャラクタ_進む("icon_yuki")
End Sub