土日を除いた営業日ごとのカレンダーで考える


目次

  1. 概要
  2. 営業日を調べる
  3. 今年の営業日カレンダーを作る
  4. 営業日カレンダーにデータを書き込む

概要

 土日を除いた月の営業日数別に時系列データを解析したい

営業日を調べる

dataの読み込み

1.py
import pandas as pd
import numpy as np
import datetime
day_df = pd.read_pickle("mypath.pickle")

営業日(月曜から金曜)までの月ごとの日数を調べるクラスの作製

2.py
class businessday(pd.core.frame.DataFrame):
    def cal_bdate_all(self):
        def cal_bdate(x):
            #月日数を7で割った商と余りを出す
            q,mod = divmod(x.day,7)
            #dayofweekは月曜が1日曜が7
            a = mod-2 if mod-x.dayofweek>2 else mod
            if x.dayofweek>5:
                return 0
            return a+q*5
        self.index.bd = self.index.map(cal_bdate)
        return self.index.bd


作ったクラスを適応

3.py
bd  = businessday(day_df)
bd.cal_bdate_all()

用意したデータの編集と営業日の追加

4.py
x=pd.DataFrame(columns=['month','day','%up','num'])
for a in range(1,12+1):
    for b in range(1,23+1):
        f = day_df[(day_df.index.month==a) & (bd.index.bd==b)]
        g = f['close']-f['open']
        if g.size>0:
            h= g[g>0].size/g.size
        else:
            h = -1
        tmp_se = pd.Series( [ a,b,h,g.size ], index=x.columns )
        x = x.append(tmp_se, ignore_index=True)

2021年の営業日カレンダーを作る

5.py
calendar =  pd.date_range('2021-01-01', '2021-12-31', freq='D')

class calendar_businessday(pd.core.indexes.datetimes.DatetimeIndex):
    def cal_bdate_all(self):
        def cal_bdate(x):
            q,mod = divmod(x.day,7)
            a = mod-2 if mod-x.dayofweek>2 else mod
            if x.dayofweek>4:
                return 0
            return a+q*5
        self.bd = self.map(cal_bdate)
        return self.bd

cal = calendar_businessday(calendar)
cal.cal_bdate_all()

営業日カレンダーにデータを書き込む

カレンダーにデータを挿入

6.py

e = pd.DataFrame(data = cal.bd,index = cal,columns=['bd'])
e['%up']  =0
e['num']  =0

for a in range(1,12+1):
    for b in range(1,23+1):
        e.loc[(e.index.bd==b) & (e.index.month==a),'%up']=x.loc[(x.day==b) & (x.month==a),'%up'].values
        e.loc[(e.index.bd==b) & (e.index.month==a),'num']=x.loc[(x.day==b) & (x.month==a),'num'].values

保存

7.py
from pathlib import Path

path = "mypath"
dir = Path(path)
dir.mkdir(parents=True, exist_ok=True)
for a in range(1,12+1):
    s= path+str(a)+".pickle"
    d = path+str(a)+".csv"
    x[x.index.month==a].to_pickle(s)
    x[x.index.month==a].to_csv(d)

できたこと

カレンダーを作ってデータを挿入すること。

未達成なこと

今回はカレンダ―作成に年のデータが必要だったので2024年を適当に取ったがこれをなくしたい。クラスを作るか2次元配列で表すのが早そう。ただそうすると日時計算はできなくなるのが難点。まあいらないかな・・・

参考

pandas.Timestamp
Python クラスについて
Pythonの三項演算子(条件演算子)でif文を一行で書く
関数内関数
pandas.Seriesのmapメソッドで列の要素を置換pandas.Seriesのmapメソッドで列の要素を置換
Pandasのデータに関数を適用させるapply、applymap、mapの使い方
Pythonのdivmodで割り算の商と余りを同時に取得

課題

ほぼ同じクラスを2つ作ってしまった。。。