実験用ブログ

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

ガントチャート

2020-01-30 07:44:15 | 勉強
Option Explicit□□□□□□□□□□□□□□ '変数の宣言を強制する

'*-------------------------------------------------*
' 共通変数
'*-------------------------------------------------*
Dim gOldStatusBar As String
Dim gOldZoomValue As Integer□□□□□□□□'Excel2007ではZoom値が50%や100%でない場合オブジェクト描画位置がズレるバグがあるため一時的に100%にしておき後で元に戻す
Dim gChartStartX As Double□□□□□□□□ '線表開始位置のX座標
Dim gDateChartStart As Date□□□□□□□□ '進捗表全体の開始日
Dim gDateChartEnd As Date□□□□□□□□ '進捗表全体の終了日
Dim gChartCellWidthPerPoint As Double□□ 'セルの幅(ポイント単位):Range.Widthで取得のみ可能(設定はできない)
Dim gChartLineLastPoint(1) As Double□□□□'前回の点:Lineの始点(X座標,Y座標)
Dim gChartLineNewPoint(1) As Double□□□□ '新しい点:Lineの終点(X座標,Y座標)
Dim gObjectLineNo As Integer

'*-------------------------------------------------*
' 共通定数
'*-------------------------------------------------*
Const X As Integer = 0
Const Y As Integer = 1
Const STATUSBAR_WAIT As String = "しばらくお待ちください..."
Const NAME_HEADER_LINE As String = "ProgressChartLine"
Const NAME_HEADER_PLAN_SQR As String = "PlanSquare"
Const NAME_HEADER_ACHV_SQR As String = "AchievementSquare"
Const CLM_WORK_ITEM_NAME As Integer = 2
Const CLM_STICK_COLOR As Integer = 3
Const CLM_DATE_START As Integer = 4
Const CLM_DATE_END As Integer = 5
Const CLM_PROGRESS_RATE As Integer = 6
Const CLM_CHART_START As Integer = 7
Const CHART_CELL_WIDTH As Double = 1.88□□ 'セルの幅(標準フォントの半角文字の幅単位):Range.ColumnWidthで取得/設定とも可能
Const CHART_CELL_HEIGHT As Double = 13.5□□'セルの高さ:Range.Height(取得のみ)、Range.RowHeight(取得/設定)で共通の単位

'***************************************************
' 進捗管理ツール
' 作成日 : 2009/01/25~2009/2/xx
' メイン関数
'***************************************************
Sub ProgressChartMain()
□□Dim rowPos As Integer
□□Dim clmPos As Integer
□□Dim chartStartRow As Integer□□□□□□'線表開始行
□□Dim chartEndRow As Integer□□□□□□ '線表終了行
□□Dim dateToday As Date□□□□□□□□ '今日の日付
□□Dim workItemDateStart As Date□□□□ 'rosPos行目の作業項目の開始日
□□Dim workItemDateEnd As Date□□□□□□ 'rosPos行目の作業項目の終了日
□□Dim workItemProgressRate As Double□□ 'rosPos行目の作業項目の進捗率
□□Dim sh As Object

□□Call StartUp
□□Call ClearAllObject
□□Call SetStileOfSheet

□□'各データの検出
□□For rowPos = 1 To 1000□□□□□□□□ '無限ループに陥らないために1000で打ち止めにする
□□□□If Cells(rowPos, CLM_DATE_START).Value = "開始日" And Cells(rowPos, CLM_DATE_END).Value = "終了日" Then
□□□□□□'進捗表全体の開始日と終了日の取得
□□□□□□gDateChartStart = Cells(rowPos + 1, CLM_DATE_START).Value
□□□□□□gDateChartEnd = Cells(rowPos + 1, CLM_DATE_END).Value

□□□□□□'線表開始行の取得
□□□□□□chartStartRow = rowPos + 2
□□□□□□
□□□□ElseIf Cells(rowPos, CLM_WORK_ITEM_NAME).Value = "全体進捗" Then
□□□□□□'線表終了行の取得
□□□□□□chartEndRow = rowPos
□□□□□□Exit For
□□□□End If
□□Next

□□'線表開始位置のX座標の取得
□□gChartStartX = Range(Columns(1), Columns(CLM_CHART_START - 1)).Width
□□'今日の日付の取得
□□dateToday = Date

□□'最初(上部)の線を引く
□□Call DrawLine(ChangeDateToX(dateToday), _
□□□□□□□□Range(Rows(1), Rows(chartStartRow - 4)).Height, _
□□□□□□□□ChangeDateToX(dateToday), _
□□□□□□□□Range(Rows(1), Rows(chartStartRow - 2)).Height + CHART_CELL_HEIGHT / 2)

□□'線表の描画
□□For rowPos = chartStartRow To chartEndRow - 1
□□□□'作業項目がない場合
□□□□If Cells(rowPos, CLM_DATE_START).Value = "" Or _
□□□□□□Cells(rowPos, CLM_DATE_END).Value = "" Or _
□□□□□□Cells(rowPos, CLM_PROGRESS_RATE).Value = "" Then
□□□□□□
□□□□□□'ポイントをTodayとしてLineを描画する
□□□□□□Call DrawLine(gChartLineLastPoint(X), _
□□□□□□□□□□□□gChartLineLastPoint(Y), _
□□□□□□□□□□□□ChangeDateToX(dateToday), _
□□□□□□□□□□□□gChartLineLastPoint(Y) + CHART_CELL_HEIGHT)

□□□□'作業項目がある場合
□□□□Else

□□□□□□'rowPos行目の作業項目の開始日の取得
□□□□□□'(進捗表全体の開始日よりも前の場合は表からはみ出ないように補正する)
□□□□□□workItemDateStart = MaxDate(gDateChartStart, Cells(rowPos, CLM_DATE_START).Value)
□□
□□□□□□'rowPos行目の作業項目の終了日の取得
□□□□□□'(進捗表全体の終了日よりも後の場合は表からはみ出ないように補正する)
□□□□□□workItemDateEnd = MinDate(gDateChartEnd, Cells(rowPos, CLM_DATE_END).Value)
□□
□□□□□□'rowPos行目の作業項目の進捗率の取得
□□□□□□workItemProgressRate = Cells(rowPos, CLM_PROGRESS_RATE).Value

□□□□□□'予定を描画する
□□□□□□Set sh = ActiveSheet
□□□□□□With sh.Shapes.AddShape(msoShapeRectangle, _
□□□□□□□□□□□□□□□□□□ChangeDateToX(workItemDateStart) - 3, _
□□□□□□□□□□□□□□□□□□Range(Rows(1), Rows(rowPos - 1)).Height + 2, _
□□□□□□□□□□□□□□□□□□ChangeDateToX(workItemDateEnd) - ChangeDateToX(workItemDateStart) + 3, _
□□□□□□□□□□□□□□□□□□CHART_CELL_HEIGHT - 4)
□□□□□□□□.Name = NAME_HEADER_PLAN_SQR & Str(gObjectLineNo)
□□□□□□□□.Fill.ForeColor.RGB = Cells(rowPos, CLM_STICK_COLOR).Interior.Color
□□□□□□□□.Line.Weight = 1.5
□□□□□□End With

□□□□□□'実績を描画する
□□□□□□With sh.Shapes.AddShape(msoShapeRectangle, _
□□□□□□□□□□□□□□□□□□ChangeDateToX(workItemDateStart) - 3, _
□□□□□□□□□□□□□□□□□□Range(Rows(1), Rows(rowPos - 1)).Height + 5, _
□□□□□□□□□□□□□□□□□□(ChangeDateToX(workItemDateEnd) - ChangeDateToX(workItemDateStart) + 3) * workItemProgressRate, _
□□□□□□□□□□□□□□□□□□CHART_CELL_HEIGHT - 9)
□□□□□□□□.Name = NAME_HEADER_ACHV_SQR & Str(gObjectLineNo)
□□□□□□□□.Fill.ForeColor.RGB = RGB(63, 63, 63)
□□□□□□□□.Line.Weight = 0
□□□□□□End With

□□□□□□'進捗率に応じたLineを描画する
□□□□□□If workItemProgressRate <= 0 Then
□□□□□□□□gChartLineNewPoint(X) = ChangeDateToX(MinDate(workItemDateStart, dateToday))
□□□□□□ElseIf workItemProgressRate >= 1 Then
□□□□□□□□gChartLineNewPoint(X) = ChangeDateToX(MaxDate(workItemDateEnd, dateToday))
□□□□□□Else
'□□□□□□□□gChartLineNewPoint(X) = ChangeDateToX(workItemDateStart + WorksheetFunction.RoundDown((workItemDateEnd - workItemDateStart) * workItemProgressRate, 0))
□□□□□□□□ gChartLineNewPoint(X) = ChangeDateToX(workItemDateStart) + (ChangeDateToX(workItemDateEnd) - ChangeDateToX(workItemDateStart)) * workItemProgressRate
□□□□□□End If
□□□□□□Call DrawLine(gChartLineLastPoint(X), _
□□□□□□□□□□□□gChartLineLastPoint(Y), _
□□□□□□□□□□□□gChartLineNewPoint(X), _
□□□□□□□□□□□□gChartLineLastPoint(Y) + CHART_CELL_HEIGHT)
□□□□End If
□□Next
□□
□□'最後(下部)の線を引く
□□Call DrawLine(gChartLineLastPoint(X), _
□□□□□□□□gChartLineLastPoint(Y), _
□□□□□□□□ChangeDateToX(dateToday), _
□□□□□□□□gChartLineLastPoint(Y) + CHART_CELL_HEIGHT / 2)

'□□Selection.ShapeRange.Group
'□□ActiveSheet.Shapes.Range(Array(5, 6)).Group
'□□ActiveSheet.Shapes(chartLineNameArray(0)).Select
'□□ActiveSheet.Shapes.Range(chartLineNameArray(1)).Select
'□□Selection.Group.Name = "aaa"

□□Call ShutDown

End Sub

'***************************************************
' マクロ開始処理
'***************************************************
Sub StartUp()
□□'ステータスバーの表示を変更する
□□gOldStatusBar = Application.DisplayStatusBar
□□Application.DisplayStatusBar = True
□□Application.StatusBar = STATUSBAR_WAIT

□□'画面を停止する
□□Application.ScreenUpdating = False

□□'ズーム値を一時的に100%にする
□□gOldZoomValue = ActiveWindow.Zoom
□□ActiveWindow.Zoom = 100

□□'グローバル変数の初期化
□□gObjectLineNo = 0
End Sub

'***************************************************
' マクロ終了処理
'***************************************************
Sub ShutDown()
□□'スクロールバーをセットする
□□ActiveWindow.ScrollColumn = 1
□□ActiveWindow.ScrollRow = 1

□□'カーソル位置をセットする
□□Cells(1, 1).Select

□□'ズーム値を一時的に100%にする
□□ActiveWindow.Zoom = gOldZoomValue

□□'画面の停止を解除する
□□Application.ScreenUpdating = True

□□'ステータスバーの表示を元に戻す
□□Application.StatusBar = False
□□Application.DisplayStatusBar = gOldStatusBar
End Sub

'***************************************************
' シートの体裁整え
'***************************************************
Sub SetStileOfSheet()
□□'列の幅と行の高さを整える(セルの幅は標準フォントの半角文字単位で設定する)
□□Range(Columns(CLM_CHART_START), Columns(CLM_CHART_START).End(xlToRight)).ColumnWidth = CHART_CELL_WIDTH
□□Range(Rows(1), Rows(1).End(xlDown)).RowHeight = CHART_CELL_HEIGHT

□□'セルの幅をポイント単位で取得する
□□gChartCellWidthPerPoint = Columns(CLM_CHART_START).Width
End Sub

'***************************************************
' オブジェクトの削除
'***************************************************
Sub ClearAllObject()
□□Dim sh As Object

□□'"Bottun 1"を除き、シート内のオブジェクトを全て削除する
□□For Each sh In ActiveSheet.Shapes
'□□□□If sh.Name <> "Button 1" Then
□□□□If Left(sh.Name, Len(NAME_HEADER_LINE)) = NAME_HEADER_LINE Or _
□□□□□□Left(sh.Name, Len(NAME_HEADER_PLAN_SQR)) = NAME_HEADER_PLAN_SQR Or _
□□□□□□Left(sh.Name, Len(NAME_HEADER_ACHV_SQR)) = NAME_HEADER_ACHV_SQR Then
□□□□□□sh.Delete
□□□□End If
□□Next
End Sub

'***************************************************
' 日付をx座標に変換する
'***************************************************
Function ChangeDateToX(InputDate As Date) As Double
□□Dim OutputX As Double
□□
□□If InputDate < gDateChartStart Then
□□□□InputDate = gDateChartStart
□□ElseIf InputDate > gDateChartEnd Then
□□□□InputDate = gDateChartEnd
□□End If
□□OutputX = gChartStartX _
□□□□□□ + ((Year(InputDate) - Year(gDateChartStart)) * 36 _
□□□□□□ + (Month(InputDate) - Month(gDateChartStart)) * 3 _
□□□□□□ + WorksheetFunction.RoundDown(Day(InputDate) / 10, 0) _
□□□□□□ + 0.5) * gChartCellWidthPerPoint

□□ChangeDateToX = OutputX
End Function

'***************************************************
' 線を引く
'***************************************************
Sub DrawLine(InputStartX As Double, InputStartY As Double, InputEndX As Double, InputEndY As Double)
□□Dim sh As Object

□□Set sh = ActiveSheet.Shapes.AddLine(InputStartX, InputStartY, InputEndX, InputEndY)
□□With sh
□□□□.Name = NAME_HEADER_LINE & Str(gObjectLineNo)
□□□□.Line.Weight = 2.25
□□□□.Line.ForeColor.RGB = vbRed
□□End With
□□gChartLineLastPoint(X) = InputEndX
□□gChartLineLastPoint(Y) = InputEndY
□□gObjectLineNo = gObjectLineNo + 1
End Sub

'***************************************************
' 日付を比較して大きい方を返す
'***************************************************
Function MaxDate(InputDate1 As Date, InputDate2 As Date) As Date
□□Dim OutputDate As Date
□□
□□If InputDate1 > InputDate2 Then
□□□□OutputDate = InputDate1
□□Else
□□□□OutputDate = InputDate2
□□End If
□□MaxDate = OutputDate
End Function

'***************************************************
' 日付を比較して小さい方を返す
'***************************************************
Function MinDate(InputDate1 As Date, InputDate2 As Date) As Date
□□Dim OutputDate As Date
□□
□□If InputDate1 < InputDate2 Then
□□□□OutputDate = InputDate1
□□Else
□□□□OutputDate = InputDate2
□□End If
□□MinDate = OutputDate
End Function






株価取得

2020-01-08 03:13:25 | 勉強
import requests
import zipfile
import pandas as pd
from datetime import datetime, date, timedelta
import os
import sys



"""
URLを指定してカレントディレクトリにファイルをダウンロードする
"""
def download_file(url):
□□filename = url.split('/')[-1]
□□r = requests.get(url, stream=True)
□□with open(filename, 'wb') as f:
□□□□for chunk in r.iter_content(chunk_size=1024):
□□□□□□if chunk:
□□□□□□□□f.write(chunk)
□□□□□□□□f.flush()
□□□□return filename
□□
□□# ファイルが開けなかった場合は False を返す
□□return False



"""
ファイル名を指定してzipファイルをカレントディレクトリに展開する
"""
def zip_extract(filename):
□□target_directory = '.'
□□zfile = zipfile.ZipFile(filename)
□□zfile.extractall(target_directory)



"""
CSVファイルを読みこみ必要な株価データを取得する
"""
def get_kabuka_list(csv_filename, codes):
□□df = pd.read_csv(csv_filename,
□□□□□□□□□□ header=None,
□□□□□□□□□□ index_col=0,
□□□□□□□□□□ encoding="shift-jis")
□□
□□# 指定した証券コードの行に絞り込む
□□# 1: 証券コード
□□# 9: 取引所名
□□df = df[df[1].isin(codes) & (df[9] == "東証1部")]
□□
□□# 必要なカラムのみに絞り込む
□□# 1: 証券コード
□□# 5: 高値
□□# 6: 安値
□□# 7: 終値
□□# 8: 出来高
□□df = df[[1, 5, 6, 7, 8]].rename(columns={1:'code', 5:'高値', 6:'安値', 7:'終値', 8:'出来高'})

□□return(df)



"""
指定した日付のzipファイル名を取得
"""
def get_filename(date):
□□yymmdd = datetime.strftime(date, '%Y%m%d')[-6:]
□□filename = "T" + yymmdd + ".zip"
□□return(filename)



"""
指定した日付のURLを取得
"""
def get_url(date):
□□yyyy = datetime.strftime(date, '%Y')
□□yy_mm = datetime.strftime(date, '%Y_%m')[-5:]
□□yymmdd = datetime.strftime(date, '%Y%m%d')[-6:]
□□url = "http://mujinzou.com/k_data/" + yyyy + "/" + yy_mm + "/T" + yymmdd + ".zip"
□□return(url)



"""
本処理
"""
root_dir = ".."
code_list = "4719,6702"
codes = code_list.split(",")
yesterday = datetime.today() - timedelta(days=1)

# ダウンロードする
zip_filename = get_filename(yesterday)
if (os.path.exists(zip_filename)):
□□os.remove(zip_filename)
url = get_url(yesterday)
zip_filename = download_file(url)
if (zip_filename == False):
□□print("ダウンロード失敗")
□□sys.exit()

# zipファイルを展開する
csv_filename = zip_filename.replace(".zip", ".csv")
if (os.path.exists(csv_filename)):
□□os.remove(csv_filename)
zip_extract(zip_filename)

# 昨日の株価データのcsvファイルを読み込む
df = get_kabuka_list(csv_filename, codes)

# 各csvファイルの末尾に昨日の株価を追記する
for code in codes:
□□# 昨日の株価データから当該証券コードの行のみを抜き出す
□□record = df[df["code"] == int(code)][['高値', '安値', '終値', '出来高']]
□□row = datetime.strftime(yesterday, '%Y-%m-%d') + "," + str(record['高値'][0]) + "," + str(record['安値'][0]) + "," + str(record['終値'][0]) + "," + str(record['出来高'][0])
□□
□□# csvファイルの存在チェック
□□path = root_dir + "/data/" + code + "_all.csv"
□□if (not os.path.exists(path)):
□□□□print("追記対象のcsvファイルがない")
□□□□sys.exit()
□□
□□# 現状のcsvファイルの末尾の日付を判定する
□□current_csv = pd.read_csv(path,
□□□□□□□□□□□□□□ header=0,
□□□□□□□□□□□□□□ index_col=None,
□□□□□□□□□□□□□□ encoding="shift-jis")
□□last_date = datetime.strptime(current_csv[-1:].iat[0, 0], "%Y-%m-%d").date()
□□if (last_date < yesterday.date()):
□□□□# csvファイルの末尾に追記する
□□□□with open(path, 'a', encoding="shift-jis", newline="\r\n") as f:
□□□□□□print(row, file=f)

# ダウンロードしたファイルを削除する
os.remove(zip_filename)
os.remove(csv_filename)


バックアップ世代管理

2019-12-10 01:57:57 | 勉強
import os
import shutil
import datetime as dt
import glob

import const



def backup():
# 現在日を取得
today = dt.date.today()
yyyymmdd = today.strftime('%Y%m%d')
target = const.root_dir + "/model_" + yyyymmdd

# 既に現在日のバックアップが存在する場合は末尾に連番を付ける
if os.path.exists(target):
save_flg = False
for i in range(1, 1000):
target_000 = target + "_" + str(i).zfill(3)
if not os.path.exists(target_000):
target = target_000
save_flg = True
break
if not save_flg:
raise Exception("これ以上バックアップできません")

# バックアップを作成
shutil.copytree(const.root_dir + "/model", target)



def remove_old():
# 現在日を取得
today = dt.datetime.today()

# バックアップの一覧を取得し、現在日より30日古ければ削除する
model_path = const.root_dir + "/model_*"
model_list = glob.glob(model_path)
for model in model_list:
yyyymmdd = os.path.basename(model)[6:14]
target_date = dt.datetime.strptime(yyyymmdd, '%Y%m%d')
if today > target_date + dt.timedelta(days=30):
print("古くなったバックアップを削除します file=" + model)
shutil.rmtree(model)


python arrange weight test

2019-10-19 13:31:11 | 勉強
data_np = df["終値"].copy().to_numpy().reshape(1,approach_days)

for i in range(approach_days):
data_np[0, i] = data_np[0, i] / (approach_days - i)

python pandas select test

2019-10-18 00:25:27 | 勉強
# 配列計算
import pandas as pd
import numpy as np
import datetime as dt

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

df = pd.read_csv('data/1234_all.csv',
header=0,
encoding="shift-jis")

# 型を指定
df['日付'] = df['日付'].astype(np.datetime64)
df['高値'] = df['高値'].astype(np.float32)
df['安値'] = df['安値'].astype(np.float32)
df['終値'] = df['終値'].astype(np.float32)


start = '20120309'
today = '20120313'
days = 10
approach_days = 50

df = df[df['日付'] < dt.datetime(int(today[0:4]), int(today[4:6]), int(today[6:8]))]
df = df[-approach_days:]