配当や株主優待の権利付き最終日はいつか?
株主の権利確定日を示したカレンダーはどうやって作るのか?
『権利日のカレンダーを作る手順』と『プログラムのコード例』を書きました。
なぜ権利日のカレンダーを作るのか?
Excelの日付に権利日を表示したかったから
1つは、Excelの表に『権利付き最終日、権利落ち日、権利確定日、株式市場の休日』などを表示したかったからです。
具体的には、Pythonで作った『権利日カレンダーのCSV』を『Excel VBA』で読み込んで、日付に『権利日関係の情報』を追加しようと思いました。
そうして出来たExcelの画面がこちらです。
セルのコメントに『第N曜日』と『権利日』を追加しています。
Excelに『第N曜日』と『権利日』を表示した例
ほかにも、株価予想や業績予想などの計算で、権利日をパラメータの1つにする目的がありました。
ところで、わざわざ自分で作らなくても、直近の権利日カレンダーなら証券会社のサイトで公開されています。
なぜ自分で作ろうと思ったのか?
『株価や業績の推移』を『広く過去や未来まで』分析しようとすると、直近のカレンダーだけでは足りなかったんですね。
そこで、広い範囲のカレンダーを得るために、自分で定義を調べて作る必要が出てきました。
どうしても自分で分析したかったので、頑張ってカレンダー生成プログラムを書きました。
以下、カレンダー作りの解説とコード例です。
権利日カレンダーはどうやって作るのか?
権利日カレンダーを作るには、事前にほかの色々なカレンダーが必要になります。
なぜ、ほかの各種カレンダーが必要なのか?
各種カレンダーが必要になる流れ
まず、『権利日』の定義が必要です。
株式の売買では、決済処理に時間を要するために、権利付き最終日と権利確定日が離れています。
その間隔は、証券取引所の営業日でカウントするので、『営業日』の定義が必要になります。
営業日は取引所の休業日の定義から決まるのですが、休業日の定義には『休日・祝日』と『第N曜日』が登場します。
カレンダーの作成手順
そういうわけで、これらの流れを逆にたどって以下の順にカレンダーを作り、最後に目的の権利日カレンダーを作ることになりました。
- 第N曜日のカレンダー(Python辞書)を作る。
- 休日・祝日のカレンダー(Python辞書)を作る。
- 営業日のカレンダー(Python辞書)を作る。
- 権利日のカレンダー(Python辞書)を作る。
権利日カレンダーまでの道のりは長いですね。
実際、カレンダーを作りあげるのは大変でした。
カレンダーの日付計算は難しい
なぜか?
カレンダーというのは月によって日数が変わったり、うるう年(leap year, リープイヤー)で日数が変わったりするからです。
さらに、休日や祝日などは、事前に計算出来るものと、出来ないものがあります。
『地球の自転や公転周期という曖昧さ』と『人の都合で決めたお休みの曖昧さ』の相乗効果(シナジー効果)で、カレンダー計算が大変なものになっていたんですね。
そういった面倒な準備の先に、権利日カレンダーが存在していました。
目的のカレンダーを1発で求めるような便利な計算式は無かったです。
では、どうすればいいのか?
for文で日付を進めながら、1日ずつ定義に当てはめて各種カレンダーを作っていきます。
休日の定義や営業日(休業日)の定義は公開されていますので、それで判定関数を作ってカレンダーを作っていきます。
正確なカレンダーはどうやって維持するのか?
正確な権利日カレンダーを維持するには、カレンダー作りに使うリストや定義の更新をチェックして、メンテナンスしていくアプローチが必要になります。
『第N曜日』だけは不変(ふへん)の定義と思われますが、『休日・祝日』、『営業日』、『権利日』の定義は時々変わります。
なので、それぞれの1次情報源を毎年チェックして、変更があればプログラムに反映するといった作業が発生します。ちょっと大変です。
定義の1次情報源はどこか?
自分が調べた限りでは、以下の通りです。
- 内閣府のサイトで公開されている祝日リスト
- 証券取引所のサイトで公開されている市場の休日定義
- 日本証券業協会のサイトで公開されている決済期間の定義
直近1年間の権利日カレンダーなら、各種定義が出揃っているので、十分に正確なカレンダーが作れます。
過去のカレンダーについては、これまでに使用された定義を各所から集めて作ります。
未来のカレンダーについては、現在の定義を当てはめて作ります。
こうして、過去・現在・未来の権利日カレンダーを作ることができます。
Python コード例
main 関数
プログラムの一番上の部分です。
権利日カレンダーの生成に必要な辞書を揃えて行って、最後にカレンダーを作っています。
途中で各種辞書をCSVに保存していますが、これらはデバッグ用です。内容をチェックしたらコメントアウトしてしまいます。
最終的に活用するのは、最後に作る権利日カレンダーのCSV (04_calendar_jp.csv) だけです。
"""create_calendar.py"""
# 株式カレンダー作成
from os.path import join as os_join
from os.path import isdir as os_isdir
from datetime import datetime as datetime_datetime
from datetime import date as datetime_date
from datetime import timedelta as datetime_timedelta
DATETIME_TIMEDELTA_DAY_1 = datetime_timedelta(days=1)
DATETIME_TIMEDELTA_DAYS_2 = datetime_timedelta(days=2)
from dateutil.relativedelta import relativedelta
from collections import OrderedDict
from operator import itemgetter
from csv import writer as csv_writer
from csv import reader as csv_reader
def main():
"""main関数"""
# データフォルダを設定
# (用途)
# ・祝日リストのCSVを入れておく
# ・各種辞書のCSVを保存(デバッグ用)
data_dir = r'(どこかにフォルダを用意してフォルダパスを指定)'
if not os_isdir(data_dir):
print('Error データフォルダが存在しません')
print('data_dir: %s' % data_dir)
print('(何もせずに終了)')
return
# 計算対象の期間を設定
# (時刻情報は使わないので date型 を使っています)
period = (
datetime_date(1950, 1, 1),
datetime_date(2050, 12, 31),
)
# 第N曜日の辞書を作成
weekdays = create_weekdays_dict(period[0], period[1])
# 辞書を『リストに変換 & 日付の昇順にソート』してCSVに保存
weekdays_file = os_join(data_dir, '01_weekdays.csv')
weekdays_head = [['日付', '曜日', '第N曜日']]
weekdays_data = sorted(weekdays.values(), key=itemgetter(0), reverse=False)
save_to_csv(weekdays_file, weekdays_head + weekdays_data, 'utf-8-sig', '\n')
# 祝日の辞書を作成
holidays_file = os_join(data_dir, 'holidays_jp.csv') # 祝日リストのCSV
holidays = create_holidays_dict(holidays_file, 'utf-8-sig')
# 東京証券取引所(tse)の営業日の辞書を作成
tse_days = get_tse_days(period[0], period[1], weekdays, holidays)
# 辞書を『リストに変換 & 日付の昇順にソート』してCSVに保存
tse_days_file = os_join(data_dir, '02_tse_days.csv')
tse_head = [['日付', '営業状態']]
tse_datas = sorted(tse_days.values(), key=itemgetter(0), reverse=False)
save_to_csv(tse_days_file, tse_head + tse_datas, 'utf-8-sig', '\n')
# 権利日(権利付最終日、権利落日、権利確定日)の辞書を作成。
rights_days = create_rights_days_dict(period[0], period[1], holidays, tse_days)
# 辞書を『リストに変換 & 日付の昇順にソート』してCSVに保存
rights_days_file = os_join(data_dir, '03_rights_days.csv')
rights_head = [['日付', '権利関係']]
rights_datas = sorted(rights_days.values(), key=itemgetter(0), reverse=False)
save_to_csv(rights_days_file, rights_head + rights_datas, 'utf-8-sig', '\n')
# カレンダーの辞書を作成
dates = create_calendar_dict(period[0], period[1], weekdays, holidays, tse_days, rights_days)
# 辞書を『リストに変換 & 日付の昇順にソート』してCSVに保存
dates_file = os_join(data_dir, '04_calendar_jp.csv')
dates_head = [['日付', '第N', '曜日', '祝日', '東証', '権利関係']]
dates_datas = sorted(dates.values(), key=itemgetter(0), reverse=False)
save_to_csv(dates_file, dates_head + dates_datas, 'utf-8-sig', '\n')
return
def save_to_csv(file, datas, encoding, lineterminator='\n'):
"""listをcsvに保存"""
with open(file, 'w', encoding=encoding, newline='') as f:
w = csv_writer(f, delimiter=',', lineterminator=lineterminator)
w.writerows(datas)
return
# (カレンダー計算に必要な関数群)
if __name__ == '__main__':
main()
第N曜日の辞書を作る関数
日本のカレンダーで欠かせないのが、『第2土曜日』といった概念です。
休日や祝日の定義で頻繁に登場しますので、第N曜日を求めるための辞書が必要になります。
それを作る関数です。
事前に、Pythonライブラリの『python-dateutil (パイソン デート ユーティル)』をインストールしておきます。
このライブラリの『relativedelta (リレーティブ デルタ)』が、月ごとの日数の違いや閏年(うるうどし)の帳じり合わせをしてくれます。
def create_weekdays_dict(date_start, date_end):
"""第N曜日の辞書を作成"""
# 休日定義では『第2土曜日が休み』といった表現が登場します。
# そこで、何年何月何日は第N曜日であるという辞書が必要。
# 辞書の作り方は、for文で月ごとに曜日を数えるアプローチが簡単。
# ここでは、『月初(げっしょ)』から『月末(げつまつ)』まで
# 各曜日の出現回数を数えて、辞書に追加していきます。
# 月初から月末まで数えていく方法なので、開始日と終了日に関係なく、
# 月初と月末の日付が必要になります。
# 開始日の月の月初(げっしょ)を取得
t_start = datetime_date(
year=date_start.year,
month=date_start.month,
day=1,
)
# 終了日の月の月末(げつまつ)を取得
# ところで、月末が『何日か?』は月や閏年か否かによって異なる。
# 月末はどうやって求めるのか?
# 月末とは、翌月の1日(ついたち)から、1日(いちにち)引いた日である。
# だが、何日後が翌月なのかも、月や閏年か否かによって異なる。
# そのあたりのカレンダー計算には python-dateutil の実装が使える。
# python-dateutil の dateutil.relativedelta を使って月末を求める。
t_end = datetime_date(
year=date_end.year,
month=date_end.month,
day=1,
) + relativedelta(
months=1,
days=-1,
)
# 日数を取得
n_days = (t_end - t_start).days + 1
# 辞書を作成
weekdays = OrderedDict()
# weekdayカウンタの初期値を取得する関数
get_counter_zero = lambda : [0, 0, 0, 0, 0, 0, 0]
# 要素番号と曜日の対応は以下の通り
# [0]月 [1]火 [2]水 [3]木 [4]金 [5]土 [6]日
# date.weekday()が月曜に0を返すのでこうなっています
# 最初のカウンタを作成
w = get_counter_zero()
# for文で月ごとに曜日を数える
for n_day in range(0, n_days):
# 開始日から日付を進める
t = t_start + datetime_timedelta(days=n_day)
# 月初なら新しいweekdayカウンタを取得
if t.day == 1:
w = get_counter_zero()
# 曜日を取得
t_weekday = t.weekday()
# 対応する曜日に+1
w[t_weekday] += 1
# 日付はまだ辞書に入ってないはず
assert t not in weekdays
# 日付をキーにして辞書に(日付, 曜日, 第N曜日)のタプルを追加
weekdays[t] = (t, t_weekday, w[t_weekday])
return weekdays
休日・祝日の辞書を作る関数
事前に作っておいた休日・祝日リストのCSVを読み込んで、辞書を作る関数です。
コードのコメントに休日・祝日リストの作り方を書きました。
以下、コード例です。
def create_holidays_dict(file, encoding):
"""祝日の辞書を作成"""
# 事前に日本の祝日リストをCSVにまとめておきます。
# それを読み込んで祝日の辞書を作ります。
# では、祝日リストはどうやって作るのか?
# 過去の祝日リストは各種情報サイトを参考に作ります。
# 直近の祝日リストは内閣府のサイトにCSVがあります。
# 未来の祝日リストは最新の祝日の定義から計算で求めます。
# ご自身の目的に合うように、これらを組み合わせて
# 祝日のCSVを作っておきます。
# 一番重要な直近の祝日リストを内閣府が公開しているので、
# 十分実用的な祝日リストが作れます。
# 正確さを求めるなら、内閣府の祝日リストを毎年取り込めばOKです。
# 以下は、既に用意したCSVから祝日辞書を作るコードです。
# 辞書を作成
holidays_dict = OrderedDict()
datetime_strptime = datetime_datetime.strptime
with open(file, 'r', encoding=encoding, newline='') as f:
# CSVのフォーマット例
# [0] [0]年月日 [1]祝日名
# [1] [0]1950-01-01 [1]元日
# [2] ...
# 最初のラベル行を読み捨てる
next(csv_reader(f))
# 日付と祝日名の辞書を作成
for c in csv_reader(f):
# 日付列をdatetime型に変換 & 時刻情報は不要なのでdate型に変換
t = datetime_strptime(c[0], '%Y-%m-%d').date()
# 日付はまだ辞書に入ってないはず
assert t not in holidays_dict
# 日付をキーにして辞書に祝日名を追加
holidays_dict[t] = c[1]
return holidays_dict
東証の営業日の辞書を作る関数
東京証券取引所の休業日の定義は、内国株の売買制度『取引時間・休業日の変遷』のページにありました。
一応、書かれていた過去の定義をすべてコードに起こしました。ですが、実際には2009年以降の定義だけで十分でした。あまり古い日付に出番はなかったです。
def get_tse_days(t_start, t_end, weekdays, holidays):
"""東京証券取引所(tse)の営業日の辞書を作成"""
# 東証の営業日の辞書はどうやって作るのか?
# 東証のサイトで『取引時間・休業日の変遷』が公開されている。
# このPDFに休業日の定義が載っているので、これを使って作る。
# 具体的には、定義の数だけ判定関数を作って、
# 判定結果を辞書に追加していく。
# 東証の『営業状態』を定義 (営業日に1を設定)
# 半休日は半日だけ『営業』しているので、営業日扱いにしています。
tse_none = None # 未対応の日付(エラー時に設定)
tse_close = 0 # 休日(クローズ)
tse_open = 1 # 営業日(半休日を含む)
# 日付定義
date_20091230 = datetime_date(2009, 12, 30)
date_19890201 = datetime_date(1989, 2, 1)
date_19860801 = datetime_date(1986, 8, 1)
date_19830801 = datetime_date(1983, 8, 1)
date_19791001 = datetime_date(1979, 10, 1)
# date_19730423 = datetime_date(1973, 4, 23)
date_19490401 = datetime_date(1949, 4, 1)
# 1973年04月23日 の定義は省略。
# 1973年に振替休日が制定されてたことを受けて
# 休業日の定義に振替休日が追加されているが、実際に
# 判定関数を作ってみたら 1949年04月01日 の関数と
# 全く同じになったため。
# 日数を取得
n_days = (t_end - t_start).days + 1
# 辞書を作成
stock_exchanges_days = OrderedDict()
# 日付を判定関数にかけて営業状態を辞書に追加
for n_day in range(0, n_days):
# 開始日から日付を進める
t = t_start + datetime_timedelta(days=n_day)
# 日付に応じて判定関数にかける
if t >= date_20091230:
tse_day = get_tse_20091230(t, weekdays, holidays, tse_open, tse_close)
elif t >= date_19890201:
tse_day = get_tse_19890201(t, weekdays, holidays, tse_open, tse_close)
elif t >= date_19860801:
tse_day = get_tse_19860801(t, weekdays, holidays, tse_open, tse_close)
elif t >= date_19830801:
tse_day = get_tse_19830801(t, weekdays, holidays, tse_open, tse_close)
elif t >= date_19791001:
tse_day = get_tse_19791001(t, weekdays, holidays, tse_open, tse_close)
elif t >= date_19490401:
tse_day = get_tse_19490401_19730423(t, weekdays, holidays, tse_open, tse_close)
else:
# 未対応の日付
tse_day = tse_none
# 日付はまだ辞書に入ってないはず
assert t not in stock_exchanges_days
# 日付をキーにして辞書に(日付, 営業状態)のタプルを追加
stock_exchanges_days[t] = (t, tse_day)
return stock_exchanges_days
def get_tse_20091230(t, weekdays, holidays, tse_open, tse_close):
"""2009年12月30日~"""
if t in holidays:
return tse_close
if t.weekday() == 5:
return tse_close # 土曜日
if t.weekday() == 6:
return tse_close # 日曜日
if t.month == 12:
if t.day == 31:
return tse_close # 大晦日
if t.month == 1:
#if t.day == 1:
# return tse_close # 年始3日間 (正月はholidaysで判定済み)
if t.day == 2:
return tse_close # 年始3日間
if t.day == 3:
return tse_close # 年始3日間
return tse_open
def get_tse_19890201(t, weekdays, holidays, tse_open, tse_close):
"""1989年2月1日~"""
if t in holidays:
return tse_close
if t.weekday() == 5:
return tse_close # 土曜日
if t.weekday() == 6:
return tse_close # 日曜日
if t.month == 12:
if t.day == 31:
return tse_close # 大晦日
if t.month == 1:
#if t.day == 1:
# return tse_close # 年始3日間 (正月はholidaysで判定済み)
if t.day == 2:
return tse_close # 年始3日間
if t.day == 3:
return tse_close # 年始3日間
return tse_open
def get_tse_19860801(t, weekdays, holidays, tse_open, tse_close):
"""1986年8月1日~"""
if t in holidays:
return tse_close
if t.weekday() == 5:
if weekdays[t][2] == 2:
return tse_close # 第2土曜日
if weekdays[t][2] == 3:
return tse_close # 第3土曜日
if t.weekday() == 6:
return tse_close # 日曜日
if t.month == 12:
if t.day == 29:
return tse_close # 年末3日間
if t.day == 30:
return tse_close # 年末3日間
if t.day == 31:
return tse_close # 年末3日間 大晦日
if t.month == 1:
#if t.day == 1:
# return tse_close # 年始3日間 (正月はholidaysで判定済み)
if t.day == 2:
return tse_close # 年始3日間
if t.day == 3:
return tse_close # 年始3日間
return tse_open
def get_tse_19830801(t, weekdays, holidays, tse_open, tse_close):
"""1983年8月1日~"""
if t in holidays:
return tse_close
if t.weekday() == 5:
if weekdays[t][2] == 2:
return tse_close # 第2土曜日
if t.weekday() == 6:
return tse_close # 日曜日
if t.month == 12:
if t.day == 29:
return tse_close # 年末3日間
if t.day == 30:
return tse_close # 年末3日間
if t.day == 31:
return tse_close # 年末3日間 大晦日
if t.month == 1:
#if t.day == 1:
# return tse_close # 年始3日間 (正月はholidaysで判定済み)
if t.day == 2:
return tse_close # 年始3日間
if t.day == 3:
return tse_close # 年始3日間
return tse_open
def get_tse_19791001(t, weekdays, holidays, tse_open, tse_close):
"""1979年10月1日~"""
if t in holidays:
return tse_close
if t.weekday() == 5:
if weekdays[t][2] == 3:
return tse_close # 第3土曜日
if t.weekday() == 6:
return tse_close # 日曜日
if t.month == 12:
if t.day == 29:
return tse_close # 年末3日間
if t.day == 30:
return tse_close # 年末3日間
if t.day == 31:
return tse_close # 年末3日間 大晦日
if t.month == 1:
#if t.day == 1:
# return tse_close # 年始3日間 (正月はholidaysで判定済み)
if t.day == 2:
return tse_close # 年始3日間
if t.day == 3:
return tse_close # 年始3日間
return tse_open
def get_tse_19490401_19730423(t, weekdays, holidays, tse_open, tse_close):
"""1949年4月1日~ 1973年4月23日~"""
if t in holidays:
return tse_close
if t.weekday() == 6:
return tse_close # 日曜日
if t.month == 12:
if t.day == 29:
return tse_close # 年末3日間
if t.day == 30:
return tse_close # 年末3日間
if t.day == 31:
return tse_close # 年末3日間 大晦日
if t.month == 1:
#if t.day == 1:
# return tse_close # 年始3日間 (正月はholidaysで判定済み)
if t.day == 2:
return tse_close # 年始3日間
if t.day == 3:
return tse_close # 年始3日間
return tse_open
権利日の辞書を作る関数
いよいよ権利日を求めるところです。
権利日とは『権利付き最終日、権利落ち日、権利確定日』などのことです。
権利日関係の日付は、月末から逆算して見つけていきます。
証券会社などのサイトを見ると、そのようなアプローチで調べる旨が書かれていましたので、そのようにしています。
一部の上場企業では、株主優待などの権利日を月末以外に設定しているケースがあります。
こういった権利日は、完全に個別対応になると思います。以下のコード例でも対応していません。
さて、コード例に注意点があります。
以下、コード例です。
def create_rights_days_dict(t_start, t_end, holidays, tse_days):
"""権利日(権利付最終日、権利落日、権利確定日)の辞書を作成。"""
# 辞書を作成
rights_days = OrderedDict()
# 月数を取得
date_delta = relativedelta(t_end, t_start)
n_months = date_delta.years * 12 + date_delta.months + 2
for n_month in range(0, n_months):
# 月を進める
d = t_start + relativedelta(months=n_month)
# 月末を取得
month_end = d + relativedelta(months=1, days=-1)
if month_end < t_start:
continue
elif month_end > t_end:
continue
# [権利確定日(けんりかくていび)を取得]
# 初期値に『月末』を設定
vesting_date = month_end
# 初期値から1日ずつ遡って条件に合う日を探す
vesting_date = get_rights_date(vesting_date, t_start, t_end, holidays, tse_days)
# 権利確定日が見つかったら日付をキーにして辞書に追加
if vesting_date:
rights_days[vesting_date] = (vesting_date, '権利確定日')
else:
# ここは実行されないはず
print('Error 権利確定日(vesting_date) が見つからなかった %s' % d)
continue
# [権利落日(けんりおちび)を取得]
# 初期値に『権利確定日』の『2日前 ※注』を設定
# ※注 この『2日』は決済期間によるもの。
# もし、過去分まで正確に計算するなら、
# 『株式等の決済期間短縮化』で調べて、
# 時期ごとに決済期間を変える必要があります。
# また、決済の高速化で日数が2日⇒1日に短縮される予定。
ex_rights_date = vesting_date - DATETIME_TIMEDELTA_DAYS_2
# 初期値から1日ずつ遡って条件に合う日を探す
ex_rights_date = get_rights_date(ex_rights_date, t_start, t_end, holidays, tse_days)
# 権利落日が見つかったら日付をキーにして辞書に追加
if ex_rights_date:
rights_days[ex_rights_date] = (ex_rights_date, '権利落日')
else:
# ここは実行されないはず
print('Error 権利落日(ex_rights_date) が見つからなかった %s' % d)
continue
# [権利付最終日(けんりつきさいしゅうび)を取得]
# 初期値に『権利落日』の『1日前』を設定
rights_date = ex_rights_date - DATETIME_TIMEDELTA_DAY_1
# 初期値から1日ずつ遡って条件に合う日を探す
rights_date = get_rights_date(rights_date, t_start, t_end, holidays, tse_days)
# 権利付最終日が見つかったら日付をキーにして辞書に追加
if rights_date:
rights_days[rights_date] = (rights_date, '権利付最終日')
else:
# ここは実行されないはず
print('Error 権利付最終日(rights_date) が見つからなかった %s' % d)
continue
return rights_days
def get_rights_date(t_date, t_start, t_end, holidays, tse_days):
"""日付をさかのぼって最初に現れる営業日を取得"""
# なぜ、『日付をさかのぼって最初に現れる営業日』を求めるのか?
# 権利付最終日、権利落ち日、権利確定日の間に休日をはさむ場合に対応するためです。
# 何日後が何の権利日か?という通常の定義に加えて、
# 営業日をさかのぼる処理を加えることで、休日を考慮した処理を実現しています。
# 営業日で数えながらさかのぼって求める根拠は?
# これは、各証券会社のサイトに、
# 『権利を得るには、権利確定日から数えて N営業日前 までに株式を保有する必要がある』
# などと書かれているからです。
# これを手順に直すと、日付は『営業日』で数えながらさかのぼる、となります。
# 営業日とは何の営業日?
# 株式を売買できる営業日のことです。
# 当プログラムでは『東証の営業日』を使っています。
# なお、PTS市場などは権利関係の日付が異なる場合があります。
# 日付の初期値を設定
t = t_date
# 月末を除いた最大30日間をさかのぼって調べる。
for n in range(0, 31):
# 日付が東証の休日辞書にあるか?
if t in tse_days:
# その日付は東証の休日か?
if tse_days[t][1] == 0:
# 東証が休日
t = t - DATETIME_TIMEDELTA_DAY_1
continue
# 東証の営業日が現れたのでブレーク
break
else:
# ここは実行されないはず
print('Error 平日が見つからなかった t:%s date:%s start:%s end:%s' % (
str(t), str(t_date), str(t_start), str(t_end)))
return None
# 日付の範囲チェック
if t < t_start:
# 範囲外
return None
elif t > t_end:
# 範囲外
return None
return t
権利日カレンダーを作る関数
ここまでに準備した辞書を使って、実際にカレンダーを作る関数です。
def create_calendar_dict(t_start, t_end, weekdays, holidays, tse_days, rights_days):
"""カレンダーの辞書を作成"""
# ここまでに準備した辞書を使ってカレンダーを作ります
# weekdays: 第N曜日の辞書
# holidays: 祝日の辞書
# tse_days: 東証の休日辞書
# rights_days: 権利日の辞書
# 曜日が数字のままだと見づらいので、漢字リストを用意。
youbi_list = ('月', '火', '水', '木', '金', '土', '日')
# 日数を取得
n_days = (t_end - t_start).days + 1
# カレンダー辞書を作成
dates = OrderedDict()
# 東証の営業状態が数字のままだと見づらいので、名前辞書を用意。
tse_days_dict = {None: '', 0: 'close', 1: 'open'}
# 開始日から1日ずつ進めてカレンダーを作る
for n_day in range(n_days):
# 日付を進める
t = t_start + datetime_timedelta(days=n_day)
# 辞書に
# ('日付', '第N', '曜日', '祝日', '東証', '権利関係')
# のタプルを追加
dates[t] = (
t.strftime('%Y/%m/%d'),
weekdays[t][2],
youbi_list[t.weekday()],
holidays[t] if t in holidays else '',
tse_days_dict[tse_days[t][1]],
rights_days[t][1] if t in rights_days else '',
)
return dates
以上です
(株価分析や銘柄分析プログラムを作る時の参考になれば幸いです)